diff --git a/hosting/nginx.prod.conf.hbs b/hosting/nginx.prod.conf.hbs index ac60d367e7..f3009baf40 100644 --- a/hosting/nginx.prod.conf.hbs +++ b/hosting/nginx.prod.conf.hbs @@ -49,7 +49,7 @@ http { add_header X-Frame-Options SAMEORIGIN always; add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; - add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com; object-src 'none'; base-uri 'self'; connect-src 'self' https://api-iam.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io; font-src 'self' data https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me https://maxcdn.bootstrapcdn.com; frame-src 'self' https:; img-src http: https: data; manifest-src 'self'; media-src 'self'; worker-src 'none';" always; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com; object-src 'none'; base-uri 'self'; connect-src 'self' https://api-iam.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io ; font-src 'self' data https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me https://maxcdn.bootstrapcdn.com; frame-src 'self' https:; img-src http: https: data; manifest-src 'self'; media-src 'self'; worker-src 'none';" always; # upstreams set $apps {{ apps }}; diff --git a/lerna.json b/lerna.json index 6fc890bb42..123a56be84 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 4b1f107b40..5c073be156 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index c2681a3890..d492264098 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.0.80-alpha.2", + "@budibase/string-templates": "^1.0.81-alpha.0", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/builder/package.json b/packages/builder/package.json index cf33b7a853..e6ba5875f2 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "license": "GPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.2", - "@budibase/client": "^1.0.80-alpha.2", - "@budibase/frontend-core": "^1.0.80-alpha.2", - "@budibase/string-templates": "^1.0.80-alpha.2", + "@budibase/bbui": "^1.0.81-alpha.0", + "@budibase/client": "^1.0.81-alpha.0", + "@budibase/frontend-core": "^1.0.81-alpha.0", + "@budibase/string-templates": "^1.0.81-alpha.0", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte index 8f1218f087..0aaa2b201d 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte @@ -20,7 +20,9 @@ $goto(`./datasource/${resp._id}`) notifications.success(`Datasource updated successfully.`) } catch (err) { - notifications.error("Error saving datasource") + notifications.error(err?.message ?? "Error saving datasource") + // prevent the modal from closing + return false } } diff --git a/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte b/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte index 2a886fab0c..de50e0cfb2 100644 --- a/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte +++ b/packages/builder/src/components/design/AppPreview/CurrentItemPreview.svelte @@ -134,8 +134,9 @@ // Remove all iframe event listeners on component destroy onDestroy(() => { + window.removeEventListener("message", receiveMessage) + if (iframe.contentWindow) { - window.removeEventListener("message", receiveMessage) if (!$store.clientFeatures.messagePassing) { // Legacy - remove in later versions of BB iframe.contentWindow.removeEventListener( diff --git a/packages/cli/package.json b/packages/cli/package.json index 3a30bae908..3bdc60fb6f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { diff --git a/packages/client/package.json b/packages/client/package.json index 4bf70e4d56..33e3b2788c 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,26 +19,12 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.2", - "@budibase/frontend-core": "^1.0.80-alpha.2", - "@budibase/string-templates": "^1.0.80-alpha.2", - "@spectrum-css/button": "^3.0.3", - "@spectrum-css/card": "^3.0.3", - "@spectrum-css/divider": "^1.0.3", - "@spectrum-css/link": "^3.1.3", - "@spectrum-css/page": "^3.0.1", - "@spectrum-css/tag": "^3.1.4", - "@spectrum-css/typography": "^3.0.2", - "@spectrum-css/vars": "^3.0.1", - "apexcharts": "^3.22.1", - "dayjs": "^1.10.5", - "downloadjs": "1.4.7", + "@budibase/bbui": "^1.0.81-alpha.0", + "@budibase/frontend-core": "^1.0.81-alpha.0", + "@budibase/string-templates": "^1.0.81-alpha.0", "regexparam": "^1.3.0", "rollup-plugin-polyfill-node": "^0.8.0", "shortid": "^2.2.15", - "svelte": "^3.38.2", - "svelte-apexcharts": "^1.0.2", - "svelte-flatpickr": "^3.1.0", "svelte-spa-router": "^3.0.5" }, "devDependencies": { diff --git a/packages/client/src/components/app/forms/S3Upload.svelte b/packages/client/src/components/app/forms/S3Upload.svelte index ab66755b6e..031c49f4b4 100644 --- a/packages/client/src/components/app/forms/S3Upload.svelte +++ b/packages/client/src/components/app/forms/S3Upload.svelte @@ -81,7 +81,10 @@ loading = false return res } catch (error) { - notificationStore.actions.error(`Error uploading file: ${error}`) + notificationStore.actions.error( + `Error uploading file: ${error?.message || error}` + ) + loading = false } } diff --git a/packages/client/stats.html b/packages/client/stats.html new file mode 100644 index 0000000000..4cab61a146 --- /dev/null +++ b/packages/client/stats.html @@ -0,0 +1,2689 @@ + + + + + + + + RollUp Visualizer + + + +
+ + + + + diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 038c106042..6d0a86ff14 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "^1.0.80-alpha.2", + "@budibase/bbui": "^1.0.81-alpha.0", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/frontend-core/src/api/attachments.js b/packages/frontend-core/src/api/attachments.js index 2077c4f7ef..e2eb348f9d 100644 --- a/packages/frontend-core/src/api/attachments.js +++ b/packages/frontend-core/src/api/attachments.js @@ -1,61 +1,66 @@ -export const buildAttachmentEndpoints = API => ({ - /** - * Uploads an attachment to the server. - * @param data the attachment to upload - * @param tableId the table ID to upload to - */ - uploadAttachment: async ({ data, tableId }) => { - return await API.post({ - url: `/api/attachments/${tableId}/upload`, - body: data, - json: false, - }) - }, - - /** - * Uploads an attachment to the server as a builder user from the builder. - * @param data the data to upload - */ - uploadBuilderAttachment: async data => { - return await API.post({ - url: "/api/attachments/process", - body: data, - json: false, - }) - }, - +export const buildAttachmentEndpoints = API => { /** * Generates a signed URL to upload a file to an external datasource. * @param datasourceId the ID of the datasource to upload to * @param bucket the name of the bucket to upload to * @param key the name of the file to upload to */ - getSignedDatasourceURL: async ({ datasourceId, bucket, key }) => { + const getSignedDatasourceURL = async ({ datasourceId, bucket, key }) => { return await API.post({ url: `/api/attachments/${datasourceId}/url`, body: { bucket, key }, }) - }, + } - /** - * Uploads a file to an external datasource. - * @param datasourceId the ID of the datasource to upload to - * @param bucket the name of the bucket to upload to - * @param key the name of the file to upload to - * @param data the file to upload - */ - externalUpload: async ({ datasourceId, bucket, key, data }) => { - const { signedUrl, publicUrl } = await API.getSignedDatasourceURL({ - datasourceId, - bucket, - key, - }) - await API.put({ - url: signedUrl, - body: data, - json: false, - external: true, - }) - return { publicUrl } - }, -}) + return { + getSignedDatasourceURL, + + /** + * Uploads an attachment to the server. + * @param data the attachment to upload + * @param tableId the table ID to upload to + */ + uploadAttachment: async ({ data, tableId }) => { + return await API.post({ + url: `/api/attachments/${tableId}/upload`, + body: data, + json: false, + }) + }, + + /** + * Uploads an attachment to the server as a builder user from the builder. + * @param data the data to upload + */ + uploadBuilderAttachment: async data => { + return await API.post({ + url: "/api/attachments/process", + body: data, + json: false, + }) + }, + + /** + * Uploads a file to an external datasource. + * @param datasourceId the ID of the datasource to upload to + * @param bucket the name of the bucket to upload to + * @param key the name of the file to upload to + * @param data the file to upload + */ + externalUpload: async ({ datasourceId, bucket, key, data }) => { + console.log(API) + const { signedUrl, publicUrl } = await getSignedDatasourceURL({ + datasourceId, + bucket, + key, + }) + await API.put({ + url: signedUrl, + body: data, + json: false, + external: true, + }) + return { publicUrl } + }, + } +} diff --git a/packages/server/package.json b/packages/server/package.json index 8b4fed92bf..1df52c67de 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -71,9 +71,9 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@budibase/backend-core": "^1.0.80-alpha.2", - "@budibase/client": "^1.0.80-alpha.2", - "@budibase/string-templates": "^1.0.80-alpha.2", + "@budibase/backend-core": "^1.0.81-alpha.0", + "@budibase/client": "^1.0.81-alpha.0", + "@budibase/string-templates": "^1.0.81-alpha.0", "@bull-board/api": "^3.7.0", "@bull-board/koa": "^3.7.0", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/specs/generate.js b/packages/server/specs/generate.js index d037eb8e59..f6a055f683 100644 --- a/packages/server/specs/generate.js +++ b/packages/server/specs/generate.js @@ -17,12 +17,23 @@ const options = { }, servers: [ { - url: "http://budibase.app/api/public/v1", + url: "https://budibase.app/api/public/v1", description: "Budibase Cloud API", }, { - url: "{protocol}://{hostname}:10000/api/public/v1", + url: "{protocol}://{hostname}/api/public/v1", description: "Budibase self hosted API", + variables: { + protocol: { + default: "http", + description: + "Whether HTTP or HTTPS should be used to communicate with your Budibase instance.", + }, + hostname: { + default: "localhost:10000", + description: "The URL of your Budibase instance.", + }, + }, }, ], components: { diff --git a/packages/server/specs/openapi.json b/packages/server/specs/openapi.json index 3e68d3edca..229c82230f 100644 --- a/packages/server/specs/openapi.json +++ b/packages/server/specs/openapi.json @@ -7,12 +7,22 @@ }, "servers": [ { - "url": "http://budibase.app/api/public/v1", + "url": "https://budibase.app/api/public/v1", "description": "Budibase Cloud API" }, { - "url": "{protocol}://{hostname}:10000/api/public/v1", - "description": "Budibase self hosted API" + "url": "{protocol}://{hostname}/api/public/v1", + "description": "Budibase self hosted API", + "variables": { + "protocol": { + "default": "http", + "description": "Whether HTTP or HTTPS should be used to communicate with your Budibase instance." + }, + "hostname": { + "default": "localhost:10000", + "description": "The URL of your Budibase instance." + } + } } ], "components": { diff --git a/packages/server/specs/openapi.yaml b/packages/server/specs/openapi.yaml index 298eb73636..6dd1607ae8 100644 --- a/packages/server/specs/openapi.yaml +++ b/packages/server/specs/openapi.yaml @@ -4,10 +4,18 @@ info: description: The public API for Budibase apps and its services. version: 1.0.0 servers: - - url: http://budibase.app/api/public/v1 + - url: https://budibase.app/api/public/v1 description: Budibase Cloud API - - url: "{protocol}://{hostname}:10000/api/public/v1" + - url: "{protocol}://{hostname}/api/public/v1" description: Budibase self hosted API + variables: + protocol: + default: http + description: Whether HTTP or HTTPS should be used to communicate with your + Budibase instance. + hostname: + default: localhost:10000 + description: The URL of your Budibase instance. components: parameters: tableId: diff --git a/packages/server/src/api/controllers/table/external.js b/packages/server/src/api/controllers/table/external.js index b27eebb0c4..86d855a28e 100644 --- a/packages/server/src/api/controllers/table/external.js +++ b/packages/server/src/api/controllers/table/external.js @@ -25,7 +25,8 @@ async function makeTableRequest( operation, table, tables, - oldTable = null + oldTable = null, + renamed = null ) { const json = { endpoint: { @@ -41,6 +42,9 @@ async function makeTableRequest( if (oldTable) { json.meta.table = oldTable } + if (renamed) { + json.meta.renamed = renamed + } return makeExternalQuery(datasource, json) } @@ -160,6 +164,7 @@ function isRelationshipSetup(column) { exports.save = async function (ctx) { const table = ctx.request.body + const { _rename: renamed } = table // can't do this right now delete table.dataImport const datasourceId = getDatasourceId(ctx.request.body) @@ -241,7 +246,14 @@ exports.save = async function (ctx) { const operation = oldTable ? DataSourceOperation.UPDATE_TABLE : DataSourceOperation.CREATE_TABLE - await makeTableRequest(datasource, operation, tableToSave, tables, oldTable) + await makeTableRequest( + datasource, + operation, + tableToSave, + tables, + oldTable, + renamed + ) // update any extra tables (like foreign keys in other tables) for (let extraTable of extraTablesToUpdate) { const oldExtraTable = oldTables[extraTable.name] @@ -258,6 +270,8 @@ exports.save = async function (ctx) { ) } + // remove the rename prop + delete tableToSave._rename // store it into couch now for budibase reference datasource.entities[tableToSave.name] = tableToSave await db.put(datasource) diff --git a/packages/server/src/definitions/datasource.ts b/packages/server/src/definitions/datasource.ts index 6c8c8dc07d..2e2ad25f58 100644 --- a/packages/server/src/definitions/datasource.ts +++ b/packages/server/src/definitions/datasource.ts @@ -138,6 +138,11 @@ export interface PaginationJson { page?: string | number } +export interface RenameColumn { + old: string + updated: string +} + export interface RelationshipsJson { through?: string from?: string @@ -166,6 +171,7 @@ export interface QueryJson { meta?: { table?: Table tables?: Record + renamed: RenameColumn } extra?: { idFilter?: SearchFilters diff --git a/packages/server/src/integrations/base/sqlTable.ts b/packages/server/src/integrations/base/sqlTable.ts index b9ea7107fc..0c63b707ae 100644 --- a/packages/server/src/integrations/base/sqlTable.ts +++ b/packages/server/src/integrations/base/sqlTable.ts @@ -1,6 +1,10 @@ import { Knex, knex } from "knex" import { Table } from "../../definitions/common" -import { Operation, QueryJson } from "../../definitions/datasource" +import { + Operation, + QueryJson, + RenameColumn, +} from "../../definitions/datasource" import { breakExternalTableId } from "../utils" import SchemaBuilder = Knex.SchemaBuilder import CreateTableBuilder = Knex.CreateTableBuilder @@ -10,7 +14,8 @@ function generateSchema( schema: CreateTableBuilder, table: Table, tables: Record, - oldTable: null | Table = null + oldTable: null | Table = null, + renamed?: RenameColumn ) { let primaryKey = table && table.primary ? table.primary[0] : null const columns = Object.values(table.schema) @@ -29,7 +34,11 @@ function generateSchema( for (let [key, column] of Object.entries(table.schema)) { // skip things that are already correct const oldColumn = oldTable ? oldTable.schema[key] : null - if ((oldColumn && oldColumn.type) || (primaryKey === key && !isJunction)) { + if ( + (oldColumn && oldColumn.type) || + (primaryKey === key && !isJunction) || + renamed?.updated === key + ) { continue } switch (column.type) { @@ -81,6 +90,10 @@ function generateSchema( } } + if (renamed) { + schema.renameColumn(renamed.old, renamed.updated) + } + // need to check if any columns have been deleted if (oldTable) { const deletedColumns = Object.entries(oldTable.schema) @@ -90,6 +103,9 @@ function generateSchema( ) .map(([key]) => key) deletedColumns.forEach(key => { + if (renamed?.old === key) { + return + } if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) { schema.dropForeign(key) } @@ -114,10 +130,11 @@ function buildUpdateTable( knex: SchemaBuilder, table: Table, tables: Record, - oldTable: Table + oldTable: Table, + renamed: RenameColumn ): SchemaBuilder { return knex.alterTable(table.name, schema => { - generateSchema(schema, table, tables, oldTable) + generateSchema(schema, table, tables, oldTable, renamed) }) } @@ -167,7 +184,8 @@ class SqlTableQueryBuilder { client, json.table, json.meta.tables, - json.meta.table + json.meta.table, + json.meta.renamed ) break case Operation.DELETE_TABLE: diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 0eaeb926ce..e4cc2c49e6 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/worker/package.json b/packages/worker/package.json index 1a75358a3f..23d5fa59b9 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.0.80-alpha.2", + "version": "1.0.81-alpha.0", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -34,8 +34,8 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.0.80-alpha.2", - "@budibase/string-templates": "^1.0.80-alpha.2", + "@budibase/backend-core": "^1.0.81-alpha.0", + "@budibase/string-templates": "^1.0.81-alpha.0", "@koa/router": "^8.0.0", "@sentry/node": "^6.0.0", "@techpass/passport-openidconnect": "^0.3.0",