diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml index d71ee6e178..492f244d79 100644 --- a/charts/budibase/templates/app-service-deployment.yaml +++ b/charts/budibase/templates/app-service-deployment.yaml @@ -84,6 +84,8 @@ spec: value: {{ .Values.services.objectStore.appsBucketName | quote }} - name: GLOBAL_CLOUD_BUCKET_NAME value: {{ .Values.services.objectStore.globalBucketName | quote }} + - name: BACKUPS_BUCKET_NAME + value: {{ .Values.services.objectStore.backupsBucketName | quote }} - name: PORT value: {{ .Values.services.apps.port | quote }} {{ if .Values.services.worker.publicApiRateLimitPerSecond }} diff --git a/charts/budibase/templates/worker-service-deployment.yaml b/charts/budibase/templates/worker-service-deployment.yaml index ffcda1ab72..c72398f825 100644 --- a/charts/budibase/templates/worker-service-deployment.yaml +++ b/charts/budibase/templates/worker-service-deployment.yaml @@ -83,6 +83,8 @@ spec: value: {{ .Values.services.objectStore.appsBucketName | quote }} - name: GLOBAL_CLOUD_BUCKET_NAME value: {{ .Values.services.objectStore.globalBucketName | quote }} + - name: BACKUPS_BUCKET_NAME + value: {{ .Values.services.objectStore.backupsBucketName | quote }} - name: PORT value: {{ .Values.services.worker.port | quote }} - name: MULTI_TENANCY diff --git a/lerna.json b/lerna.json index 0ba6b7a0a6..1c116117f0 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.40-alpha.4", + "version": "2.1.11", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 44a8f2f8c9..941b4f3154 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -20,7 +20,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@budibase/types": "2.0.40-alpha.4", + "@budibase/types": "^2.1.11", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", diff --git a/packages/backend-core/src/auth.ts b/packages/backend-core/src/auth.ts index 23873b84e7..98bf17beef 100644 --- a/packages/backend-core/src/auth.ts +++ b/packages/backend-core/src/auth.ts @@ -24,10 +24,15 @@ import { } from "./middleware" import { invalidateUser } from "./cache/user" import { User } from "@budibase/types" +import { logAlert } from "./logging" // Strategies passport.use(new LocalStrategy(local.options, local.authenticate)) -passport.use(new JwtStrategy(jwt.options, jwt.authenticate)) +if (jwt.options.secretOrKey) { + passport.use(new JwtStrategy(jwt.options, jwt.authenticate)) +} else { + logAlert("No JWT Secret supplied, cannot configure JWT strategy") +} passport.serializeUser((user: User, done: any) => done(null, user)) diff --git a/packages/backend-core/src/queue/inMemoryQueue.ts b/packages/backend-core/src/queue/inMemoryQueue.ts index 80ee7362e4..88f8310f3a 100644 --- a/packages/backend-core/src/queue/inMemoryQueue.ts +++ b/packages/backend-core/src/queue/inMemoryQueue.ts @@ -1,4 +1,5 @@ import events from "events" +import { timeout } from "../../utils" /** * Bull works with a Job wrapper around all messages that contains a lot more information about @@ -27,6 +28,7 @@ class InMemoryQueue { _opts?: any _messages: any[] _emitter: EventEmitter + _runCount: number /** * The constructor the queue, exactly the same as that of Bulls. * @param {string} name The name of the queue which is being configured. @@ -38,6 +40,7 @@ class InMemoryQueue { this._opts = opts this._messages = [] this._emitter = new events.EventEmitter() + this._runCount = 0 } /** @@ -59,6 +62,7 @@ class InMemoryQueue { if (resp.then != null) { await resp } + this._runCount++ }) } @@ -122,6 +126,15 @@ class InMemoryQueue { on() { // do nothing } + + async waitForCompletion() { + const currentCount = this._runCount + let increased = false + do { + await timeout(50) + increased = this._runCount > currentCount + } while (!increased) + } } export = InMemoryQueue diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 07b54a1c6d..ab0e065c64 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": "2.0.40-alpha.4", + "version": "2.1.11", "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": "2.0.40-alpha.4", + "@budibase/string-templates": "^2.1.11", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Form/Core/Dropzone.svelte b/packages/bbui/src/Form/Core/Dropzone.svelte index 51f6eef6f9..c64e69b201 100644 --- a/packages/bbui/src/Form/Core/Dropzone.svelte +++ b/packages/bbui/src/Form/Core/Dropzone.svelte @@ -43,6 +43,7 @@ let selectedImageIdx = 0 let fileDragged = false let selectedUrl + let fileInput $: selectedImage = value?.[selectedImageIdx] ?? null $: fileCount = value?.length ?? 0 $: isImage = @@ -102,6 +103,7 @@ await deleteAttachments( value.filter((x, idx) => idx === selectedImageIdx).map(item => item.key) ) + fileInput.value = "" } selectedImageIdx = 0 } @@ -234,6 +236,7 @@ type="file" multiple accept={extensions} + bind:this={fileInput} on:change={handleFile} /> import Picker from "./Picker.svelte" - import { createEventDispatcher, onMount } from "svelte" + import { createEventDispatcher } from "svelte" export let value = [] export let id = null @@ -16,29 +16,6 @@ export let autoWidth = false const dispatch = createEventDispatcher() - const parseValues = value => { - return Array.isArray(value) - ? value.reduce((acc, entry) => { - if (typeof ele === "string" && entry.trim() === "") { - return acc - } - let processedOption = String(entry) - if (options.indexOf(processedOption) > -1) { - acc.push(processedOption) - } - return acc - }, []) - : [] - } - let loaded = false - - $: combinedValues = value ? [...value].concat(options) : [] - $: superSet = new Set(combinedValues) - - $: if (loaded && options.length != superSet.size) { - // ensure that the values being pushed in are valid. - dispatch("change", parseValues(value)) - } $: selectedLookupMap = getSelectedLookupMap(value) $: optionLookupMap = getOptionLookupMap(options) @@ -95,10 +72,6 @@ } } } - - onMount(() => { - loaded = true - }) { dispatch("pickprimary", newValue) primaryOpen = false + dispatch("closed") } const onClearPrimary = () => { @@ -92,6 +93,7 @@ if (primaryOpen) { event.stopPropagation() primaryOpen = false + dispatch("closed") } } diff --git a/packages/bbui/src/Form/PickerDropdown.svelte b/packages/bbui/src/Form/PickerDropdown.svelte index b64a4bd117..58f68a6386 100644 --- a/packages/bbui/src/Form/PickerDropdown.svelte +++ b/packages/bbui/src/Form/PickerDropdown.svelte @@ -128,5 +128,6 @@ on:blur on:focus on:keyup + on:closed /> diff --git a/packages/builder/package.json b/packages/builder/package.json index d868d3f888..4c777ebde8 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "license": "GPL-3.0", "private": true, "scripts": { @@ -71,10 +71,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.0.40-alpha.4", - "@budibase/client": "2.0.40-alpha.4", - "@budibase/frontend-core": "2.0.40-alpha.4", - "@budibase/string-templates": "2.0.40-alpha.4", + "@budibase/bbui": "^2.1.11", + "@budibase/client": "^2.1.11", + "@budibase/frontend-core": "^2.1.11", + "@budibase/string-templates": "^2.1.11", "@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/TableIntegrationMenu/IntegrationConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte index 1417de6dab..e1caa15fd0 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte @@ -44,7 +44,7 @@ // run the validation whenever the config changes $: validation.check(config) // dispatch the validation result - $: dispatch("valid", $validation.valid) + $: dispatch("valid", Object.keys($validation.errors).length === 0) let addButton diff --git a/packages/builder/src/components/integration/QueryViewer.svelte b/packages/builder/src/components/integration/QueryViewer.svelte index 87b3dee45d..e70cf8330e 100644 --- a/packages/builder/src/components/integration/QueryViewer.svelte +++ b/packages/builder/src/components/integration/QueryViewer.svelte @@ -132,7 +132,20 @@ config={integrationInfo.extra} /> {/if} - + {#key query.parameters} + { + query.parameters = e.detail.map(binding => { + return { + name: binding.name, + default: binding.value, + } + }) + }} + /> + {/key} {/if} {#if shouldShowQueryConfig} diff --git a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte index 64736e5f78..185d1876f9 100644 --- a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte +++ b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte @@ -44,14 +44,7 @@ valuePlaceholder="Default" bindings={[...userBindings]} bindingDrawerLeft="260px" - on:change={e => { - queryBindings = e.detail.map(binding => { - return { - name: binding.name, - default: binding.value, - } - }) - }} + on:change /> diff --git a/packages/builder/src/components/portal/overview/backups/ActionsRenderer.svelte b/packages/builder/src/components/portal/overview/backups/ActionsRenderer.svelte index 576cec488b..7dc302186a 100644 --- a/packages/builder/src/components/portal/overview/backups/ActionsRenderer.svelte +++ b/packages/builder/src/components/portal/overview/backups/ActionsRenderer.svelte @@ -10,7 +10,7 @@ } from "@budibase/bbui" import ConfirmDialog from "components/common/ConfirmDialog.svelte" import CreateRestoreModal from "./CreateRestoreModal.svelte" - import { createEventDispatcher } from "svelte" + import { createEventDispatcher, onMount } from "svelte" export let row @@ -49,6 +49,10 @@ async function downloadExport() { window.open(`/api/apps/${row.appId}/backups/${row._id}/file`, "_blank") } + + onMount(() => { + name = row.name + })
@@ -62,7 +66,7 @@ Delete Download {/if} - Update + Rename
@@ -100,7 +104,7 @@ title="Update Backup" warning={false} > - + diff --git a/packages/builder/src/components/portal/overview/backups/DateRenderer.svelte b/packages/builder/src/components/portal/overview/backups/DateRenderer.svelte deleted file mode 100644 index ec58c9ea07..0000000000 --- a/packages/builder/src/components/portal/overview/backups/DateRenderer.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - -
- {timeSince} - -
- - diff --git a/packages/builder/src/components/portal/overview/backups/NameRenderer.svelte b/packages/builder/src/components/portal/overview/backups/NameRenderer.svelte new file mode 100644 index 0000000000..93eda410fe --- /dev/null +++ b/packages/builder/src/components/portal/overview/backups/NameRenderer.svelte @@ -0,0 +1,8 @@ + + +{truncatedValue} diff --git a/packages/builder/src/components/portal/overview/backups/TypeRenderer.svelte b/packages/builder/src/components/portal/overview/backups/TypeRenderer.svelte index 9057a2adee..86ad0f3d4e 100644 --- a/packages/builder/src/components/portal/overview/backups/TypeRenderer.svelte +++ b/packages/builder/src/components/portal/overview/backups/TypeRenderer.svelte @@ -1,13 +1,29 @@
- {trigger} + {printTrigger(trigger)} {type}
diff --git a/packages/builder/src/constants/backend/backups.js b/packages/builder/src/constants/backend/backups.js new file mode 100644 index 0000000000..244415014c --- /dev/null +++ b/packages/builder/src/constants/backend/backups.js @@ -0,0 +1,11 @@ +export const BackupTrigger = { + MANUAL: "manual", + PUBLISH: "publish", + RESTORING: "restoring", + SCHEDULED: "scheduled", +} + +export const BackupType = { + BACKUP: "backup", + RESTORE: "restore", +} diff --git a/packages/builder/src/pages/builder/portal/_layout.svelte b/packages/builder/src/pages/builder/portal/_layout.svelte index cf9cd55b19..9a97881a44 100644 --- a/packages/builder/src/pages/builder/portal/_layout.svelte +++ b/packages/builder/src/pages/builder/portal/_layout.svelte @@ -383,10 +383,5 @@ .user-dropdown { flex: 0 1 0; } - - /* Reduce BBUI page padding */ - .content :global(> *) { - padding: calc(var(--spacing-xl) * 1.5) !important; - } } diff --git a/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte b/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte index 61e9609cc3..08cadc694e 100644 --- a/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte +++ b/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte @@ -5,9 +5,16 @@ const dispatch = createEventDispatcher() + let filter = null + $: filteredGroups = !filter + ? $groups + : $groups.filter(group => + group.name?.toLowerCase().includes(filter.toLowerCase()) + ) + $: optionSections = { groups: { - data: $groups, + data: filteredGroups, getLabel: group => group.name, getValue: group => group._id, getIcon: group => group.icon, @@ -15,21 +22,28 @@ }, } - $: appData = [{ id: "", role: "" }] - $: onChange = selected => { const { detail } = selected - if (!detail) return + if (!detail || Object.keys(detail).length == 0) { + dispatch("change", null) + return + } const groupSelected = $groups.find(x => x._id === detail) - const appIds = groupSelected?.apps || null - dispatch("change", appIds) + const appRoleIds = groupSelected?.roles + ? Object.keys(groupSelected?.roles) + : [] + dispatch("change", appRoleIds) } { + filter = null + }} /> diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 0b760c4b4a..562434eaf1 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -20,7 +20,14 @@ import { store, automationStore } from "builderStore" import { API } from "api" import { onMount } from "svelte" - import { apps, auth, admin, templates, licensing } from "stores/portal" + import { + apps, + auth, + admin, + templates, + licensing, + groups, + } from "stores/portal" import { goto } from "@roxi/routify" import AppRow from "components/start/AppRow.svelte" import { AppStatus } from "constants" @@ -59,10 +66,15 @@ $: enrichedApps = enrichApps($apps, $auth.user, sortBy) $: filteredApps = enrichedApps.filter( app => - app?.name?.toLowerCase().includes(searchTerm.toLowerCase()) && - (accessFilterList !== null ? accessFilterList.includes(app?.appId) : true) + (searchTerm + ? app?.name?.toLowerCase().includes(searchTerm.toLowerCase()) + : true) && + (accessFilterList !== null + ? accessFilterList?.includes( + `${app?.type}_${app?.tenantId}_${app?.appId}` + ) + : true) ) - $: lockedApps = filteredApps.filter(app => app?.lockedYou || app?.lockedOther) $: unlocked = lockedApps?.length === 0 $: automationErrors = getAutomationErrors(enrichedApps) @@ -231,6 +243,10 @@ // always load latest await licensing.init() + if ($licensing.groupsEnabled) { + await groups.actions.init() + } + if ($templates?.length === 0) { notifications.error( "There was a problem loading quick start templates." diff --git a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte index cc31eec348..a5c693ab1e 100644 --- a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte +++ b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte @@ -391,11 +391,7 @@ gap: var(--spacing-l); } } - @media (max-width: 640px) { - .overview-wrap :global(.content > *) { - padding: calc(var(--spacing-xl) * 1.5) !important; - } - } + .app-title { display: flex; gap: var(--spacing-m); diff --git a/packages/cli/package.json b/packages/cli/package.json index 223d6e2922..ba1d937be5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { @@ -26,9 +26,9 @@ "outputPath": "build" }, "dependencies": { - "@budibase/backend-core": "2.0.40-alpha.4", - "@budibase/string-templates": "2.0.40-alpha.4", - "@budibase/types": "2.0.40-alpha.4", + "@budibase/backend-core": "^2.1.11", + "@budibase/string-templates": "^2.1.11", + "@budibase/types": "^2.1.11", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/client/manifest.json b/packages/client/manifest.json index d8a868b6f8..0f3a095fbf 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -5037,45 +5037,6 @@ } ] }, - "grid": { - "name": "Grid (Beta)", - "icon": "ViewGrid", - "hasChildren": true, - "styles": [ - "size" - ], - "illegalChildren": ["section", "grid"], - "legalDirectChildren": [ - "container", - "tableblock", - "cardsblock", - "repeaterblock", - "formblock" - ], - "size": { - "width": 800, - "height": 400 - }, - "showEmptyState": false, - "settings": [ - { - "type": "number", - "label": "Rows", - "key": "rows", - "defaultValue": 12, - "min": 1, - "max": 32 - }, - { - "type": "number", - "label": "Columns", - "key": "cols", - "defaultValue": 12, - "min": 1, - "max": 32 - } - ] - }, "formblock": { "name": "Form Block", "icon": "Form", diff --git a/packages/client/package.json b/packages/client/package.json index e7150c6072..73513b45c8 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "2.0.40-alpha.4", - "@budibase/frontend-core": "2.0.40-alpha.4", - "@budibase/string-templates": "2.0.40-alpha.4", + "@budibase/bbui": "^2.1.11", + "@budibase/frontend-core": "^2.1.11", + "@budibase/string-templates": "^2.1.11", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/client/src/components/app/blocks/FormBlock.svelte b/packages/client/src/components/app/blocks/FormBlock.svelte index 2d2d76a2b7..3311ddd7bb 100644 --- a/packages/client/src/components/app/blocks/FormBlock.svelte +++ b/packages/client/src/components/app/blocks/FormBlock.svelte @@ -85,13 +85,8 @@ valueType: "Binding", }, ] - // If we're using an "update" form, use the real data provider. If we're - // using a create form, we just want a fake array so that our repeater - // will actually render the form, but data doesn't matter. - $: dataProvider = - actionType !== "Create" - ? `{{ literal ${safe(providerId)} }}` - : { rows: [{}] } + + $: dataProvider = `{{ literal ${safe(providerId)} }}` $: renderDeleteButton = showDeleteButton && actionType === "Update" $: renderSaveButton = showSaveButton && actionType !== "View" $: renderButtons = renderDeleteButton || renderSaveButton diff --git a/packages/client/src/components/app/forms/InnerForm.svelte b/packages/client/src/components/app/forms/InnerForm.svelte index 6b7e1a84d0..0c512bbe0f 100644 --- a/packages/client/src/components/app/forms/InnerForm.svelte +++ b/packages/client/src/components/app/forms/InnerForm.svelte @@ -128,6 +128,23 @@ return fields.find(field => get(field).name === name) } + const getDefault = (defaultValue, schema, type) => { + // Remove any values not present in the field schema + // Convert any values supplied to string + if (Array.isArray(defaultValue) && type == "array") { + return defaultValue.reduce((acc, entry) => { + let processedOption = String(entry) + let schemaOptions = schema.constraints.inclusion + if (schemaOptions.indexOf(processedOption) > -1) { + acc.push(processedOption) + } + return acc + }, []) + } else { + return defaultValue + } + } + const formApi = { registerField: ( field, @@ -153,8 +170,10 @@ table ) + const parsedDefault = getDefault(defaultValue, schema?.[field], type) + // If we've already registered this field then keep some existing state - let initialValue = Helpers.deepGet(initialValues, field) ?? defaultValue + let initialValue = Helpers.deepGet(initialValues, field) ?? parsedDefault let initialError = null let fieldId = `id-${Helpers.uuid()}` const existingField = getField(field) @@ -187,11 +206,11 @@ error: initialError, disabled: disabled || fieldDisabled || (isAutoColumn && !editAutoColumns), - defaultValue, + defaultValue: parsedDefault, validator, lastUpdate: Date.now(), }, - fieldApi: makeFieldApi(field, defaultValue), + fieldApi: makeFieldApi(field, parsedDefault), fieldSchema: schema?.[field] ?? {}, }) diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 3cb8a32d11..f7c02b45db 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "2.0.40-alpha.4", + "@budibase/bbui": "^2.1.11", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 0547cd6052..441cadb353 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index f53599a83f..9414da1a9e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -77,11 +77,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "2.0.40-alpha.4", - "@budibase/client": "2.0.40-alpha.4", - "@budibase/pro": "2.0.40-alpha.4", - "@budibase/string-templates": "2.0.40-alpha.4", - "@budibase/types": "2.0.40-alpha.4", + "@budibase/backend-core": "^2.1.11", + "@budibase/client": "^2.1.11", + "@budibase/pro": "2.1.11", + "@budibase/string-templates": "^2.1.11", + "@budibase/types": "^2.1.11", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/api/controllers/row/utils.js b/packages/server/src/api/controllers/row/utils.js index 4c837e7630..ca2ad02a30 100644 --- a/packages/server/src/api/controllers/row/utils.js +++ b/packages/server/src/api/controllers/row/utils.js @@ -82,10 +82,20 @@ exports.validate = async ({ tableId, row, table }) => { // non required MultiSelect creates an empty array, which should not throw errors errors[fieldName] = [`${fieldName} is required`] } - } else if (type === FieldTypes.JSON && typeof row[fieldName] === "string") { + } else if ( + (type === FieldTypes.ATTACHMENT || type === FieldTypes.JSON) && + typeof row[fieldName] === "string" + ) { // this should only happen if there is an error try { - JSON.parse(row[fieldName]) + const json = JSON.parse(row[fieldName]) + if (type === FieldTypes.ATTACHMENT) { + if (Array.isArray(json)) { + row[fieldName] = json + } else { + errors[fieldName] = [`Must be an array`] + } + } } catch (err) { errors[fieldName] = [`Contains invalid JSON`] } diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts index 50903bc44b..bdd9bfd4a6 100644 --- a/packages/server/src/api/controllers/static/index.ts +++ b/packages/server/src/api/controllers/static/index.ts @@ -5,7 +5,7 @@ require("svelte/register") const send = require("koa-send") const { resolve, join } = require("../../../utilities/centralPath") const uuid = require("uuid") -const { ObjectStoreBuckets, ATTACHMENT_DIR } = require("../../../constants") +const { ObjectStoreBuckets } = require("../../../constants") const { processString } = require("@budibase/string-templates") const { loadHandlebarsFile, @@ -90,7 +90,7 @@ export const uploadFile = async function (ctx: any) { return prepareUpload({ file, - s3Key: `${ctx.appId}/${ATTACHMENT_DIR}/${processedFileName}`, + s3Key: `${ctx.appId}/attachments/${processedFileName}`, bucket: ObjectStoreBuckets.APPS, }) }) diff --git a/packages/server/src/definitions/openapi.ts b/packages/server/src/definitions/openapi.ts index bb0ffb6771..b4f1ea7c1c 100644 --- a/packages/server/src/definitions/openapi.ts +++ b/packages/server/src/definitions/openapi.ts @@ -221,6 +221,7 @@ export interface components { */ type?: | "string" + | "barcodeqr" | "longform" | "options" | "number" @@ -326,6 +327,7 @@ export interface components { */ type?: | "string" + | "barcodeqr" | "longform" | "options" | "number" @@ -433,6 +435,7 @@ export interface components { */ type?: | "string" + | "barcodeqr" | "longform" | "options" | "number" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index a2bc1fd89b..9b3144c5b9 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/types/package.json b/packages/types/package.json index bb63e3a35e..31c2799b64 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase types", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/worker/package.json b/packages/worker/package.json index 13f0c0e6ba..d91df714e1 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "2.0.40-alpha.4", + "version": "2.1.11", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -36,10 +36,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "2.0.40-alpha.4", - "@budibase/pro": "2.0.40-alpha.4", - "@budibase/string-templates": "2.0.40-alpha.4", - "@budibase/types": "2.0.40-alpha.4", + "@budibase/backend-core": "^2.1.11", + "@budibase/pro": "2.1.11", + "@budibase/string-templates": "^2.1.11", + "@budibase/types": "^2.1.11", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/qa-core/src/tests/internal-api/applications/create.spec.ts b/qa-core/src/tests/internal-api/applications/create.spec.ts index 59815923cf..bd76a4a882 100644 --- a/qa-core/src/tests/internal-api/applications/create.spec.ts +++ b/qa-core/src/tests/internal-api/applications/create.spec.ts @@ -86,7 +86,6 @@ describe("Internal API - /applications endpoints", () => { // unpublish app await config.applications.unpublish(app.appId) - }) it("POST - Sync application before deployment", async () => {