diff --git a/hosting/scripts/build-target-paths.sh b/hosting/scripts/build-target-paths.sh index c974d9a304..67e1765ca8 100644 --- a/hosting/scripts/build-target-paths.sh +++ b/hosting/scripts/build-target-paths.sh @@ -4,6 +4,7 @@ echo ${TARGETBUILD} > /buildtarget.txt if [[ "${TARGETBUILD}" = "aas" ]]; then # Azure AppService uses /home for persisent data & SSH on port 2222 DATA_DIR=/home + WEBSITES_ENABLE_APP_SERVICE_STORAGE=true mkdir -p $DATA_DIR/{search,minio,couch} mkdir -p $DATA_DIR/couch/{dbs,views} chown -R couchdb:couchdb $DATA_DIR/couch/ diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh index e02b33d771..6770d27ee0 100644 --- a/hosting/single/runner.sh +++ b/hosting/single/runner.sh @@ -21,6 +21,7 @@ declare -a DOCKER_VARS=("APP_PORT" "APPS_URL" "ARCHITECTURE" "BUDIBASE_ENVIRONME # Azure App Service customisations if [[ "${TARGETBUILD}" = "aas" ]]; then DATA_DIR=/home + WEBSITES_ENABLE_APP_SERVICE_STORAGE=true /etc/init.d/ssh start else DATA_DIR=${DATA_DIR:-/data} diff --git a/lerna.json b/lerna.json index 67a59cb188..469bc51be7 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 0ce4ac5e44..76e724b77d 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", + "@budibase/types": "2.0.14-alpha.4", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 7891629de2..01e1a5f17e 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.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", + "@budibase/string-templates": "2.0.14-alpha.4", "@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/Picker.svelte b/packages/bbui/src/Form/Core/Picker.svelte index cdaf00aded..d80ca98153 100644 --- a/packages/bbui/src/Form/Core/Picker.svelte +++ b/packages/bbui/src/Form/Core/Picker.svelte @@ -19,6 +19,7 @@ export let placeholderOption = null export let options = [] export let isOptionSelected = () => false + export let isOptionEnabled = () => true export let onSelectOption = () => {} export let getOptionLabel = option => option export let getOptionValue = option => option @@ -164,6 +165,7 @@ aria-selected="true" tabindex="0" on:click={() => onSelectOption(getOptionValue(option, idx))} + class:is-disabled={!isOptionEnabled(option)} > {#if getOptionIcon(option, idx)} @@ -256,4 +258,7 @@ .spectrum-Popover :global(.spectrum-Search .spectrum-Textfield-icon) { top: 9px; } + .spectrum-Menu-item.is-disabled { + pointer-events: none; + } diff --git a/packages/bbui/src/Form/Core/Select.svelte b/packages/bbui/src/Form/Core/Select.svelte index f549f58d0c..3e15b7f6ef 100644 --- a/packages/bbui/src/Form/Core/Select.svelte +++ b/packages/bbui/src/Form/Core/Select.svelte @@ -12,6 +12,7 @@ export let getOptionValue = option => option export let getOptionIcon = () => null export let getOptionColour = () => null + export let isOptionEnabled export let readonly = false export let quiet = false export let autoWidth = false @@ -66,6 +67,7 @@ {getOptionValue} {getOptionIcon} {getOptionColour} + {isOptionEnabled} {autocomplete} {sort} isPlaceholder={value == null || value === ""} diff --git a/packages/bbui/src/Form/Select.svelte b/packages/bbui/src/Form/Select.svelte index 1b68746c5e..69126e648d 100644 --- a/packages/bbui/src/Form/Select.svelte +++ b/packages/bbui/src/Form/Select.svelte @@ -15,6 +15,7 @@ export let getOptionValue = option => extractProperty(option, "value") export let getOptionIcon = option => option?.icon export let getOptionColour = option => option?.colour + export let isOptionEnabled export let quiet = false export let autoWidth = false export let sort = false @@ -49,6 +50,7 @@ {getOptionValue} {getOptionIcon} {getOptionColour} + {isOptionEnabled} on:change={onChange} on:click /> diff --git a/packages/builder/package.json b/packages/builder/package.json index 681fa03b69..c838f05b8c 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "license": "GPL-3.0", "private": true, "scripts": { @@ -71,10 +71,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.0.14-alpha.0", - "@budibase/client": "2.0.14-alpha.0", - "@budibase/frontend-core": "2.0.14-alpha.0", - "@budibase/string-templates": "2.0.14-alpha.0", + "@budibase/bbui": "2.0.14-alpha.4", + "@budibase/client": "2.0.14-alpha.4", + "@budibase/frontend-core": "2.0.14-alpha.4", + "@budibase/string-templates": "2.0.14-alpha.4", "@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/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 21059b32dd..3fd38bddeb 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -314,7 +314,7 @@ const relatedTable = $tables.list.find( tbl => tbl._id === fieldInfo.tableId ) - if (inUse(relatedTable, fieldInfo.fieldName)) { + if (inUse(relatedTable, fieldInfo.fieldName) && !originalName) { newError.relatedName = `Column name already in use in table ${relatedTable.name}` } } diff --git a/packages/builder/src/components/portal/overview/automation/HistoryTab.svelte b/packages/builder/src/components/portal/overview/automation/HistoryTab.svelte index c676e00d2d..bd32e423c9 100644 --- a/packages/builder/src/components/portal/overview/automation/HistoryTab.svelte +++ b/packages/builder/src/components/portal/overview/automation/HistoryTab.svelte @@ -1,5 +1,5 @@ +{"is adming" + $auth.isAdmin} {#if $auth.isAdmin} { - if (license?.plan.type === PlanType.FREE) { + if (license?.plan.type === Constants.PlanType.FREE) { window.location.href = upgradeUrl } else { window.location.href = manageUrl @@ -133,7 +133,7 @@ } const setPrimaryActionText = () => { - if (license?.plan.type === PlanType.FREE) { + if (license?.plan.type === Constants.PlanType.FREE) { primaryActionText = "Upgrade" return } diff --git a/packages/cli/package.json b/packages/cli/package.json index f599eff0a5..b01d71f5d2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", - "@budibase/string-templates": "2.0.14-alpha.0", - "@budibase/types": "2.0.14-alpha.0", + "@budibase/backend-core": "2.0.14-alpha.4", + "@budibase/string-templates": "2.0.14-alpha.4", + "@budibase/types": "2.0.14-alpha.4", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/cli/src/exec.js b/packages/cli/src/exec.js index 72fd8e00eb..4df486aed6 100644 --- a/packages/cli/src/exec.js +++ b/packages/cli/src/exec.js @@ -22,6 +22,6 @@ exports.runPkgCommand = async (command, dir = "./") => { throw new Error("Must have yarn or npm installed to run build.") } const npmCmd = command === "install" ? `npm ${command}` : `npm run ${command}` - const cmd = yarn ? `yarn ${command}` : npmCmd + const cmd = yarn ? `yarn ${command} --ignore-engines` : npmCmd await exports.exec(cmd, dir) } diff --git a/packages/client/package.json b/packages/client/package.json index 27970b714e..f436d4b7b9 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", - "@budibase/frontend-core": "2.0.14-alpha.0", - "@budibase/string-templates": "2.0.14-alpha.0", + "@budibase/bbui": "2.0.14-alpha.4", + "@budibase/frontend-core": "2.0.14-alpha.4", + "@budibase/string-templates": "2.0.14-alpha.4", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/client/src/licensing/constants.js b/packages/client/src/licensing/constants.js deleted file mode 100644 index 57454bc37a..0000000000 --- a/packages/client/src/licensing/constants.js +++ /dev/null @@ -1,7 +0,0 @@ -export const PlanType = { - FREE: "free", - PRO: "pro", - TEAM: "team", - BUSINESS: "business", - ENTERPRISE: "enterprise", -} diff --git a/packages/client/src/licensing/utils.js b/packages/client/src/licensing/utils.js index efe1839ecb..effed6867f 100644 --- a/packages/client/src/licensing/utils.js +++ b/packages/client/src/licensing/utils.js @@ -1,6 +1,6 @@ import { authStore } from "../stores/auth.js" import { get } from "svelte/store" -import { PlanType } from "./constants" +import { Constants } from "@budibase/frontend-core" const getLicense = () => { const user = get(authStore) @@ -12,7 +12,7 @@ const getLicense = () => { export const isFreePlan = () => { const license = getLicense() if (license) { - return license.plan.type === PlanType.FREE + return license.plan.type === Constants.PlanType.FREE } else { // safety net - no license means free plan return true diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 557dfbd3ac..bb61f196d1 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", + "@budibase/bbui": "2.0.14-alpha.4", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js index eb7a8849a5..9a5acf8a9b 100644 --- a/packages/frontend-core/src/constants.js +++ b/packages/frontend-core/src/constants.js @@ -98,6 +98,7 @@ export const BuilderRoleDescriptions = [ export const PlanType = { FREE: "free", TEAM: "team", + PRO: "pro", BUSINESS: "business", ENTERPRISE: "enterprise", } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 399a62e11d..8cd827b27e 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index bd69773c44..599fefaf3e 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.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", - "@budibase/client": "2.0.14-alpha.0", - "@budibase/pro": "2.0.14-alpha.0", - "@budibase/string-templates": "2.0.14-alpha.0", - "@budibase/types": "2.0.14-alpha.0", + "@budibase/backend-core": "2.0.14-alpha.4", + "@budibase/client": "2.0.14-alpha.4", + "@budibase/pro": "2.0.14-alpha.4", + "@budibase/string-templates": "2.0.14-alpha.4", + "@budibase/types": "2.0.14-alpha.4", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/automations/steps/updateRow.js b/packages/server/src/automations/steps/updateRow.js index f66fcf9432..5a2c158c5f 100644 --- a/packages/server/src/automations/steps/updateRow.js +++ b/packages/server/src/automations/steps/updateRow.js @@ -66,9 +66,9 @@ exports.run = async function ({ inputs, appId, emitter }) { } const tableId = inputs.row.tableId - // clear any falsy properties so that they aren't updated + // clear any undefined, null or empty string properties so that they aren't updated for (let propKey of Object.keys(inputs.row)) { - if (!inputs.row[propKey] || inputs.row[propKey] === "") { + if (inputs.row[propKey] == null || inputs.row[propKey] === "") { delete inputs.row[propKey] } } diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 1a8387e615..e047b857b4 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1094,12 +1094,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.0.14-alpha.0.tgz#e4115967c9e37147216376bbabd622a9a13403d4" - integrity sha512-igWtifz/AFZx3kbQi7yO+dRDQX7mbY/ZCA2aRhmDIlhm3zky94XgFyG/7iPFmxh9jK+gpg1Sg3axY7vNDSX6+Q== +"@budibase/backend-core@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.0.14-alpha.4.tgz#213446a9e04385fb38ab8785742cdb8b4eaf2cac" + integrity sha512-ma1Ipst4AQVi4sx+ULs3bX9xT4eHqavCvM/BXtZzV23SOTdjJTi9wX2KWbIvAUT5xo2NgN0uRf5zf7B6CBRuXw== dependencies: - "@budibase/types" "2.0.14-alpha.0" + "@budibase/types" "2.0.14-alpha.4" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" @@ -1180,13 +1180,13 @@ svelte-flatpickr "^3.2.3" svelte-portal "^1.0.0" -"@budibase/pro@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.0.14-alpha.0.tgz#e6cb571a0a757871e9ab65555470e2c9f4fc4403" - integrity sha512-Qh0U89AfnIpBA9fE4xH8hXYp4HexYSoc6WDjlVuNI46IvGRlHaeBAsRkI8XYG8mx830fQqVeEIY1WuRUso7bOg== +"@budibase/pro@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.0.14-alpha.4.tgz#9796271365f4ffb875655f86df84a2b4111b793a" + integrity sha512-I5QIv04hfoUPEYHPkCD5L/5WU7cJurmfhjy62ZMTNbJzFzhIGDzQlOjM0MnQO5kJvGv1NWl2PQvSty1rYzXGsw== dependencies: - "@budibase/backend-core" "2.0.14-alpha.0" - "@budibase/types" "2.0.14-alpha.0" + "@budibase/backend-core" "2.0.14-alpha.4" + "@budibase/types" "2.0.14-alpha.4" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" @@ -1209,10 +1209,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.0.14-alpha.0.tgz#419ceefde9698b1918c1b41f90fc3010927acde7" - integrity sha512-20+VfYR9oIui3PDExL+3Ld0XWkrbD74CfWHS8+dYiRmW/PqUkhAT0suwpNui5OsVUn1I+9Jw0wvbitpgT5u2VQ== +"@budibase/types@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.0.14-alpha.4.tgz#37b1ff362d2551fd978e8c8153a4cec357eda0b0" + integrity sha512-l4dfMh5it1N56nc+jCtdXklrZA1cMt6WSVBoKCXBedZGpguJr18Wo/cfn1YWryuUMuSlpFVDTrlQQXCZ+ku92g== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 56d374939d..9b077a3048 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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 56e72d8266..0cda6ba689 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.0.14-alpha.0", + "version": "2.0.14-alpha.4", "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 29ab5beb57..b6a04a2801 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.14-alpha.0", + "version": "2.0.14-alpha.4", "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.14-alpha.0", - "@budibase/pro": "2.0.14-alpha.0", - "@budibase/string-templates": "2.0.14-alpha.0", - "@budibase/types": "2.0.14-alpha.0", + "@budibase/backend-core": "2.0.14-alpha.4", + "@budibase/pro": "2.0.14-alpha.4", + "@budibase/string-templates": "2.0.14-alpha.4", + "@budibase/types": "2.0.14-alpha.4", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index b159a452b9..d7532fdb50 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -291,12 +291,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.0.14-alpha.0.tgz#e4115967c9e37147216376bbabd622a9a13403d4" - integrity sha512-igWtifz/AFZx3kbQi7yO+dRDQX7mbY/ZCA2aRhmDIlhm3zky94XgFyG/7iPFmxh9jK+gpg1Sg3axY7vNDSX6+Q== +"@budibase/backend-core@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.0.14-alpha.4.tgz#213446a9e04385fb38ab8785742cdb8b4eaf2cac" + integrity sha512-ma1Ipst4AQVi4sx+ULs3bX9xT4eHqavCvM/BXtZzV23SOTdjJTi9wX2KWbIvAUT5xo2NgN0uRf5zf7B6CBRuXw== dependencies: - "@budibase/types" "2.0.14-alpha.0" + "@budibase/types" "2.0.14-alpha.4" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" @@ -327,21 +327,21 @@ uuid "8.3.2" zlib "1.0.5" -"@budibase/pro@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.0.14-alpha.0.tgz#e6cb571a0a757871e9ab65555470e2c9f4fc4403" - integrity sha512-Qh0U89AfnIpBA9fE4xH8hXYp4HexYSoc6WDjlVuNI46IvGRlHaeBAsRkI8XYG8mx830fQqVeEIY1WuRUso7bOg== +"@budibase/pro@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.0.14-alpha.4.tgz#9796271365f4ffb875655f86df84a2b4111b793a" + integrity sha512-I5QIv04hfoUPEYHPkCD5L/5WU7cJurmfhjy62ZMTNbJzFzhIGDzQlOjM0MnQO5kJvGv1NWl2PQvSty1rYzXGsw== dependencies: - "@budibase/backend-core" "2.0.14-alpha.0" - "@budibase/types" "2.0.14-alpha.0" + "@budibase/backend-core" "2.0.14-alpha.4" + "@budibase/types" "2.0.14-alpha.4" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" -"@budibase/types@2.0.14-alpha.0": - version "2.0.14-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.0.14-alpha.0.tgz#419ceefde9698b1918c1b41f90fc3010927acde7" - integrity sha512-20+VfYR9oIui3PDExL+3Ld0XWkrbD74CfWHS8+dYiRmW/PqUkhAT0suwpNui5OsVUn1I+9Jw0wvbitpgT5u2VQ== +"@budibase/types@2.0.14-alpha.4": + version "2.0.14-alpha.4" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.0.14-alpha.4.tgz#37b1ff362d2551fd978e8c8153a4cec357eda0b0" + integrity sha512-l4dfMh5it1N56nc+jCtdXklrZA1cMt6WSVBoKCXBedZGpguJr18Wo/cfn1YWryuUMuSlpFVDTrlQQXCZ+ku92g== "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" diff --git a/qa-core/README.md b/qa-core/README.md new file mode 100644 index 0000000000..b812742ab3 --- /dev/null +++ b/qa-core/README.md @@ -0,0 +1,22 @@ +# QA Core API Tests + +The QA Core API tests are a jest suite that run directly against the budibase backend APIs. + +## Auto Setup +You can run the whole test suite with one command, that spins up the budibase server and runs the jest tests: + +`yarn api:test` + +## Setup Server Only +You can also just stand up the budibase server alone. + +`yarn api:server:setup` + +## Run Tests +If you configured the server using the previous command, you can run the whole test suite by using: + +`yarn test` + +for watch mode, where the tests will run on every change: + +`yarn test:watch` \ No newline at end of file diff --git a/qa-core/package.json b/qa-core/package.json index 7cd566587e..e624b2d62d 100644 --- a/qa-core/package.json +++ b/qa-core/package.json @@ -25,7 +25,8 @@ "moduleNameMapper": { "@budibase/types": "/../packages/types/src", "@budibase/server": "/../packages/server/src", - "@budibase/backend-core": "/../packages/backend-core/src" + "@budibase/backend-core": "/../packages/backend-core/src", + "@budibase/backend-core/(.*)": "/../packages/backend-core/$1" }, "setupFiles": [ "./scripts/jestSetup.js" @@ -51,6 +52,7 @@ }, "dependencies": { "@budibase/backend-core": "^2.0.5", + "form-data": "^4.0.0", "node-fetch": "2" } } \ No newline at end of file diff --git a/qa-core/scripts/jestSetup.js b/qa-core/scripts/jestSetup.js index 8254fd6d34..77565783c3 100644 --- a/qa-core/scripts/jestSetup.js +++ b/qa-core/scripts/jestSetup.js @@ -15,3 +15,5 @@ tk.freeze(MOCK_DATE) if (!process.env.DEBUG) { global.console.log = jest.fn() // console.log are ignored in tests } + +jest.setTimeout(10000) diff --git a/qa-core/src/config/internal-api/TestConfiguration/InternalAPIClient.ts b/qa-core/src/config/internal-api/TestConfiguration/InternalAPIClient.ts index bfcbb9f4e2..dafc2b1ff2 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/InternalAPIClient.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/InternalAPIClient.ts @@ -16,9 +16,7 @@ class InternalAPIClient { constructor(appId?: string) { if (!env.BUDIBASE_SERVER_URL) { - throw new Error( - "Must set BUDIBASE_SERVER_URL env var" - ) + throw new Error("Must set BUDIBASE_SERVER_URL env var") } this.host = `${env.BUDIBASE_SERVER_URL}/api` this.appId = appId @@ -55,4 +53,4 @@ class InternalAPIClient { put = this.apiCall("PUT") } -export default InternalAPIClient \ No newline at end of file +export default InternalAPIClient diff --git a/qa-core/src/config/internal-api/TestConfiguration/applications.ts b/qa-core/src/config/internal-api/TestConfiguration/applications.ts index afee5d707a..0c51487122 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/applications.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/applications.ts @@ -1,8 +1,8 @@ -import { - Application, -} from "@budibase/server/api/controllers/public/mapping/types" +import { Application } from "@budibase/server/api/controllers/public/mapping/types" +import { App } from "@budibase/types" import { Response } from "node-fetch" import InternalAPIClient from "./InternalAPIClient" +import FormData from "form-data" export default class AppApi { api: InternalAPIClient @@ -17,9 +17,25 @@ export default class AppApi { return [response, json] } - async create( - body: any - ): Promise<[Response, Application]> { + async canRender(): Promise<[Response, boolean]> { + const response = await this.api.get("/routing/client") + const json = await response.json() + return [response, Object.keys(json.routes).length > 0] + } + + async getAppPackage(appId: string): Promise<[Response, any]> { + const response = await this.api.get(`/applications/${appId}/appPackage`) + const json = await response.json() + return [response, json] + } + + async publish(): Promise<[Response, string]> { + const response = await this.api.post("/deploy") + const json = await response.json() + return [response, json] + } + + async create(body: any): Promise<[Response, Partial]> { const response = await this.api.post(`/applications`, { body }) const json = await response.json() return [response, json] diff --git a/qa-core/src/config/internal-api/TestConfiguration/auth.ts b/qa-core/src/config/internal-api/TestConfiguration/auth.ts index 6ac53f24b6..d83c859ab3 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/auth.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/auth.ts @@ -9,11 +9,11 @@ export default class AuthApi { } async login(): Promise<[Response, any]> { - const response = await this.api.post(`/global/auth/default/login`, { + const response = await this.api.post(`/global/auth/default/login`, { body: { username: process.env.BB_ADMIN_USER_EMAIL, - password: process.env.BB_ADMIN_USER_PASSWORD - } + password: process.env.BB_ADMIN_USER_PASSWORD, + }, }) const cookie = response.headers.get("set-cookie") this.api.cookie = cookie as any diff --git a/qa-core/src/config/internal-api/TestConfiguration/index.ts b/qa-core/src/config/internal-api/TestConfiguration/index.ts index 69c7e8df96..b433fd98ea 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/index.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/index.ts @@ -13,9 +13,12 @@ export default class TestConfiguration { this.context = {} } - async beforeAll() {} + async beforeAll() { + await this.auth.login() + } async afterAll() { this.context = {} + await this.auth.logout() } } diff --git a/qa-core/src/config/internal-api/fixtures/applications.ts b/qa-core/src/config/internal-api/fixtures/applications.ts index dfad7e0b46..9076a05e1b 100644 --- a/qa-core/src/config/internal-api/fixtures/applications.ts +++ b/qa-core/src/config/internal-api/fixtures/applications.ts @@ -1,10 +1,9 @@ import generator from "../../generator" -import { - Application, -} from "@budibase/server/api/controllers/public/mapping/types" +import { Application } from "@budibase/server/api/controllers/public/mapping/types" - -const generate = (overrides: Partial = {}): Partial => ({ +const generate = ( + overrides: Partial = {} +): Partial => ({ name: generator.word(), url: `/${generator.word()}`, ...overrides, 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 a11640153c..2c934e0bd7 100644 --- a/qa-core/src/tests/internal-api/applications/create.spec.ts +++ b/qa-core/src/tests/internal-api/applications/create.spec.ts @@ -1,7 +1,9 @@ import TestConfiguration from "../../../config/internal-api/TestConfiguration" import { Application } from "@budibase/server/api/controllers/public/mapping/types" +import { db } from "@budibase/backend-core" import InternalAPIClient from "../../../config/internal-api/TestConfiguration/InternalAPIClient" import generateApp from "../../../config/internal-api/fixtures/applications" +import generator from "../../../config/generator" describe("Internal API - /applications endpoints", () => { const api = new InternalAPIClient() @@ -9,27 +11,31 @@ describe("Internal API - /applications endpoints", () => { beforeAll(async () => { await config.beforeAll() - await config.auth.login() }) afterAll(async () => { await config.afterAll() - await config.auth.logout() }) - it("POST - Can login", async () => { - const [response] = await config.auth.login() - expect(response).toHaveStatusCode(200) - }) + async function createAppFromTemplate() { + return config.applications.create({ + name: generator.word(), + url: `/${generator.word()}`, + useTemplate: "true", + templateName: "Near Miss Register", + templateKey: "app/near-miss-register", + templateFile: undefined, + }) + } it("GET - fetch applications", async () => { await config.applications.create({ ...generateApp(), - useTemplate: false + useTemplate: false, }) const [response, apps] = await config.applications.fetch() expect(response).toHaveStatusCode(200) - expect(apps.length).toBeGreaterThan(1) + expect(apps.length).toBeGreaterThanOrEqual(1) }) it("POST - Create an application", async () => { @@ -37,4 +43,45 @@ describe("Internal API - /applications endpoints", () => { expect(response).toHaveStatusCode(200) expect(app._id).toBeDefined() }) + + it("POST - Publish application", async () => { + // create app + const [response, app] = await config.applications.create(generateApp()) + expect(response).toHaveStatusCode(200) + expect(app.appId).toBeDefined() + + // publish app + config.applications.api.appId = app.appId + const [publishResponse, publish] = await config.applications.publish() + expect(publishResponse).toHaveStatusCode(200) + expect(publish).toEqual({ + _id: expect.any(String), + appUrl: app.url, + status: "SUCCESS", + }) + }) + + it("POST - Create an application from a template, publish and check it renders", async () => { + // create the app + const appName = generator.word() + const [response, app] = await createAppFromTemplate() + expect(response).toHaveStatusCode(200) + expect(app.appId).toBeDefined() + config.applications.api.appId = app.appId + + // check preview renders + const [previewResponse, previewRenders] = + await config.applications.canRender() + expect(previewResponse).toHaveStatusCode(200) + expect(previewRenders).toBe(true) + + // publish app + await config.applications.publish() + + // check published app renders + config.applications.api.appId = db.getProdAppID(app.appId) + const [publishedAppResponse, publishedAppRenders] = + await config.applications.canRender() + expect(publishedAppRenders).toBe(true) + }) }) diff --git a/qa-core/tsconfig.json b/qa-core/tsconfig.json index 028b4457f9..8cd0c30d46 100644 --- a/qa-core/tsconfig.json +++ b/qa-core/tsconfig.json @@ -14,7 +14,8 @@ "skipLibCheck": true, "paths": { "@budibase/types": ["../packages/types/src"], - "@budibase/backend-core": ["../packages/backend-core"], + "@budibase/backend-core": ["../packages/backend-core/src"], + "@budibase/backend-core/*": ["../packages/backend-core/*"], "@budibase/server/*": ["../packages/server/src/*"], } }, @@ -23,6 +24,7 @@ }, "references": [ { "path": "../packages/types" }, + { "path": "../packages/backend-core" }, ], "include": [ "src/**/*", diff --git a/qa-core/yarn.lock b/qa-core/yarn.lock index 71c3d3efe4..5b86c6084f 100644 --- a/qa-core/yarn.lock +++ b/qa-core/yarn.lock @@ -1839,6 +1839,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"