diff --git a/lerna.json b/lerna.json index cacd810e12..69158e38c8 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index aa65f90141..25a0509f0c 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/backend-core/src/db/tests/utils.spec.js b/packages/backend-core/src/db/tests/utils.spec.js index ebef670a81..f8b9549d46 100644 --- a/packages/backend-core/src/db/tests/utils.spec.js +++ b/packages/backend-core/src/db/tests/utils.spec.js @@ -1,61 +1,194 @@ +require("../../tests/utilities/dbConfig"); const { generateAppID, getDevelopmentAppID, getProdAppID, isDevAppID, isProdAppID, + getPlatformUrl, + getScopedConfig } = require("../utils") +const tenancy = require("../../tenancy"); +const { Configs, DEFAULT_TENANT_ID } = require("../../constants"); +const env = require("../../environment") -function getID() { - const appId = generateAppID() - const split = appId.split("_") - const uuid = split[split.length - 1] - const devAppId = `app_dev_${uuid}` - return { appId, devAppId, split, uuid } +describe("utils", () => { + describe("app ID manipulation", () => { + + function getID() { + const appId = generateAppID() + const split = appId.split("_") + const uuid = split[split.length - 1] + const devAppId = `app_dev_${uuid}` + return { appId, devAppId, split, uuid } + } + + it("should be able to generate a new app ID", () => { + expect(generateAppID().startsWith("app_")).toEqual(true) + }) + + it("should be able to convert a production app ID to development", () => { + const { appId, uuid } = getID() + expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`) + }) + + it("should be able to convert a development app ID to development", () => { + const { devAppId, uuid } = getID() + expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`) + }) + + it("should be able to convert a development ID to a production", () => { + const { devAppId, uuid } = getID() + expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`) + }) + + it("should be able to convert a production ID to production", () => { + const { appId, uuid } = getID() + expect(getProdAppID(appId)).toEqual(`app_${uuid}`) + }) + + it("should be able to confirm dev app ID is development", () => { + const { devAppId } = getID() + expect(isDevAppID(devAppId)).toEqual(true) + }) + + it("should be able to confirm prod app ID is not development", () => { + const { appId } = getID() + expect(isDevAppID(appId)).toEqual(false) + }) + + it("should be able to confirm prod app ID is prod", () => { + const { appId } = getID() + expect(isProdAppID(appId)).toEqual(true) + }) + + it("should be able to confirm dev app ID is not prod", () => { + const { devAppId } = getID() + expect(isProdAppID(devAppId)).toEqual(false) + }) + }) +}) + +const DB_URL = "http://dburl.com" +const DEFAULT_URL = "http://localhost:10000" +const ENV_URL = "http://env.com" + +const setDbPlatformUrl = async () => { + const db = tenancy.getGlobalDB() + db.put({ + _id: "config_settings", + type: Configs.SETTINGS, + config: { + platformUrl: DB_URL + } + }) } -describe("app ID manipulation", () => { - it("should be able to generate a new app ID", () => { - expect(generateAppID().startsWith("app_")).toEqual(true) +const clearSettingsConfig = async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + const db = tenancy.getGlobalDB() + try { + const config = await db.get("config_settings") + await db.remove("config_settings", config._rev) + } catch (e) { + if (e.status !== 404) { + throw e + } + } + }) +} + +describe("getPlatformUrl", () => { + describe("self host", () => { + + beforeEach(async () => { + env._set("SELF_HOST", 1) + await clearSettingsConfig() + }) + + it("gets the default url", async () => { + await tenancy.doInTenant(null, async () => { + const url = await getPlatformUrl() + expect(url).toBe(DEFAULT_URL) + }) + }) + + it("gets the platform url from the environment", async () => { + await tenancy.doInTenant(null, async () => { + env._set("PLATFORM_URL", ENV_URL) + const url = await getPlatformUrl() + expect(url).toBe(ENV_URL) + }) + }) + + it("gets the platform url from the database", async () => { + await tenancy.doInTenant(null, async () => { + await setDbPlatformUrl() + const url = await getPlatformUrl() + expect(url).toBe(DB_URL) + }) + }) }) - it("should be able to convert a production app ID to development", () => { - const { appId, uuid } = getID() - expect(getDevelopmentAppID(appId)).toEqual(`app_dev_${uuid}`) - }) - it("should be able to convert a development app ID to development", () => { - const { devAppId, uuid } = getID() - expect(getDevelopmentAppID(devAppId)).toEqual(`app_dev_${uuid}`) - }) + describe("cloud", () => { + const TENANT_AWARE_URL = "http://default.env.com" - it("should be able to convert a development ID to a production", () => { - const { devAppId, uuid } = getID() - expect(getProdAppID(devAppId)).toEqual(`app_${uuid}`) - }) + beforeEach(async () => { + env._set("SELF_HOSTED", 0) + env._set("MULTI_TENANCY", 1) + env._set("PLATFORM_URL", ENV_URL) + await clearSettingsConfig() + }) - it("should be able to convert a production ID to production", () => { - const { appId, uuid } = getID() - expect(getProdAppID(appId)).toEqual(`app_${uuid}`) - }) + it("gets the platform url from the environment without tenancy", async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + const url = await getPlatformUrl({ tenantAware: false }) + expect(url).toBe(ENV_URL) + }) + }) - it("should be able to confirm dev app ID is development", () => { - const { devAppId } = getID() - expect(isDevAppID(devAppId)).toEqual(true) - }) + it("gets the platform url from the environment with tenancy", async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + const url = await getPlatformUrl() + expect(url).toBe(TENANT_AWARE_URL) + }) + }) - it("should be able to confirm prod app ID is not development", () => { - const { appId } = getID() - expect(isDevAppID(appId)).toEqual(false) + it("never gets the platform url from the database", async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + await setDbPlatformUrl() + const url = await getPlatformUrl() + expect(url).toBe(TENANT_AWARE_URL) + }) + }) }) +}) - it("should be able to confirm prod app ID is prod", () => { - const { appId } = getID() - expect(isProdAppID(appId)).toEqual(true) - }) +describe("getScopedConfig", () => { + describe("settings config", () => { - it("should be able to confirm dev app ID is not prod", () => { - const { devAppId } = getID() - expect(isProdAppID(devAppId)).toEqual(false) + beforeEach(async () => { + env._set("SELF_HOSTED", 1) + env._set("PLATFORM_URL", "") + await clearSettingsConfig() + }) + + it("returns the platform url with an existing config", async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + await setDbPlatformUrl() + const db = tenancy.getGlobalDB() + const config = await getScopedConfig(db, { type: Configs.SETTINGS }) + expect(config.platformUrl).toBe(DB_URL) + }) + }) + + it("returns the platform url without an existing config", async () => { + await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { + const db = tenancy.getGlobalDB() + const config = await getScopedConfig(db, { type: Configs.SETTINGS }) + expect(config.platformUrl).toBe(DEFAULT_URL) + }) + }) }) -}) \ No newline at end of file +}) diff --git a/packages/backend-core/src/db/utils.js b/packages/backend-core/src/db/utils.js index 5f7bf794c2..d6eb0aa89e 100644 --- a/packages/backend-core/src/db/utils.js +++ b/packages/backend-core/src/db/utils.js @@ -9,7 +9,7 @@ const { APP_PREFIX, APP_DEV, } = require("./constants") -const { getTenantId, getGlobalDBName } = require("../tenancy") +const { getTenantId, getGlobalDBName, getGlobalDB } = require("../tenancy") const fetch = require("node-fetch") const { doWithDB, allDbs } = require("./index") const { getCouchInfo } = require("./pouch") @@ -392,9 +392,7 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) { // always provide the platform URL if (type === Configs.SETTINGS) { if (scopedConfig && scopedConfig.doc) { - scopedConfig.doc.config.platformUrl = await getPlatformUrl( - scopedConfig.doc.config - ) + scopedConfig.doc.config.platformUrl = await getPlatformUrl() } else { scopedConfig = { doc: { @@ -409,19 +407,30 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) { return scopedConfig && scopedConfig.doc } -const getPlatformUrl = async settings => { +const getPlatformUrl = async (opts = { tenantAware: true }) => { let platformUrl = env.PLATFORM_URL || "http://localhost:10000" - if (!env.SELF_HOSTED && env.MULTI_TENANCY) { + if (!env.SELF_HOSTED && env.MULTI_TENANCY && opts.tenantAware) { // cloud and multi tenant - add the tenant to the default platform url const tenantId = getTenantId() if (!platformUrl.includes("localhost:")) { platformUrl = platformUrl.replace("://", `://${tenantId}.`) } - } else { + } else if (env.SELF_HOSTED) { + const db = getGlobalDB() + // get the doc directly instead of with getScopedConfig to prevent loop + let settings + try { + settings = await db.get(generateConfigID({ type: Configs.SETTINGS })) + } catch (e) { + if (e.status !== 404) { + throw e + } + } + // self hosted - check for platform url override - if (settings && settings.platformUrl) { - platformUrl = settings.platformUrl + if (settings && settings.config && settings.config.platformUrl) { + platformUrl = settings.config.platformUrl } } diff --git a/packages/backend-core/src/middleware/passport/datasource/google.js b/packages/backend-core/src/middleware/passport/datasource/google.js index 9b8019575c..53719b8350 100644 --- a/packages/backend-core/src/middleware/passport/datasource/google.js +++ b/packages/backend-core/src/middleware/passport/datasource/google.js @@ -1,7 +1,7 @@ const google = require("../google") const { Cookies, Configs } = require("../../../constants") const { clearCookie, getCookie } = require("../../../utils") -const { getScopedConfig } = require("../../../db/utils") +const { getScopedConfig, getPlatformUrl } = require("../../../db/utils") const { doWithDB } = require("../../../db") const environment = require("../../../environment") const { getGlobalDB } = require("../../../tenancy") @@ -21,26 +21,10 @@ async function fetchGoogleCreds() { ) } -async function getPlatformUrl() { - let platformUrl = environment.PLATFORM_URL || "http://localhost:10000" - - const db = getGlobalDB() - const settings = await getScopedConfig(db, { - type: Configs.SETTINGS, - }) - - // self hosted - check for platform url override - if (settings && settings.platformUrl) { - platformUrl = settings.platformUrl - } - - return platformUrl -} - async function preAuth(passport, ctx, next) { // get the relevant config const googleConfig = await fetchGoogleCreds() - const platformUrl = await getPlatformUrl() + const platformUrl = await getPlatformUrl({ tenantAware: false }) let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback` const strategy = await google.strategyFactory(googleConfig, callbackUrl) @@ -59,7 +43,7 @@ async function preAuth(passport, ctx, next) { async function postAuth(passport, ctx, next) { // get the relevant config const config = await fetchGoogleCreds() - const platformUrl = await getPlatformUrl() + const platformUrl = await getPlatformUrl({ tenantAware: false }) let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback` const strategy = await google.strategyFactory( diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 9aa09f1621..ba51966f3c 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.164-alpha.0", + "version": "1.0.167-alpha.2", "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.164-alpha.0", + "@budibase/string-templates": "^1.0.167-alpha.2", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js index e67f1eb2a2..3e0ba92ba4 100644 --- a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js +++ b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js @@ -1,4 +1,5 @@ import filterTests from "../support/filterTests" +const interact = require('../support/interact') filterTests(['all'], () => { context("Add Multi-Option Datatype", () => { @@ -17,19 +18,19 @@ filterTests(['all'], () => { cy.navigateToFrontend() cy.wait(500) // Add data provider - cy.get(`[data-cy="category-Data"]`).click() - cy.get(`[data-cy="component-Data Provider"]`).click() - cy.get('[data-cy="dataSource-prop-control"]').click() - cy.get(".dropdown").contains("Multi Data").click() + cy.get(interact.CATEGORY_DATA).click() + cy.get(interact.COMPONENT_DATA_PROVIDER).click() + cy.get(interact.DATASOURCE_PROP_CONTROL).click() + cy.get(interact.DROPDOWN).contains("Multi Data").click() cy.wait(500) // Add Form with schema to match table cy.addComponent("Form", "Form") - cy.get('[data-cy="dataSource-prop-control"').click() - cy.get(".dropdown").contains("Multi Data").click() + cy.get(interact.DATASOURCE_PROP_CONTROL).click() + cy.get(interact.DROPDOWN).contains("Multi Data").click() cy.wait(500) // Add multi-select picker to form cy.addComponent("Form", "Multi-select Picker").then(componentId => { - cy.get('[data-cy="field-prop-control"]').type("Test Data").type("{enter}") + cy.get(interact.DATASOURCE_FIELD_CONTROL).type("Test Data").type("{enter}") cy.wait(1000) cy.getComponent(componentId).contains("Choose some options").click() // Check picker has 5 items @@ -40,7 +41,7 @@ filterTests(['all'], () => { } // Check items have been selected cy.getComponent(componentId) - .find(".spectrum-Picker-label") + .find(interact.SPECTRUM_Picker_LABEL) .contains("(5)") }) }) diff --git a/packages/builder/cypress/integration/createApp.spec.js b/packages/builder/cypress/integration/createApp.spec.js index 73f8e645c9..ce5e2bd0c2 100644 --- a/packages/builder/cypress/integration/createApp.spec.js +++ b/packages/builder/cypress/integration/createApp.spec.js @@ -123,6 +123,7 @@ filterTests(['smoke', 'all'], () => { cy.applicationInAppTable("Teds app") cy.deleteApp("Teds app") + cy.wait(2000) //Accomodate names that end in 'S' cy.updateUserInformation("Chris", "Userman") @@ -134,6 +135,7 @@ filterTests(['smoke', 'all'], () => { cy.applicationInAppTable("Chris app") cy.deleteApp("Chris app") + cy.wait(2000) cy.updateUserInformation("", "") }) diff --git a/packages/builder/cypress/integration/createUserAndRoles.spec.js b/packages/builder/cypress/integration/createUserAndRoles.spec.js index 2dbe91ce19..ac7ec1b5fd 100644 --- a/packages/builder/cypress/integration/createUserAndRoles.spec.js +++ b/packages/builder/cypress/integration/createUserAndRoles.spec.js @@ -4,6 +4,8 @@ filterTests(["smoke", "all"], () => { context("Create a User and Assign Roles", () => { before(() => { cy.login() + cy.deleteApp("Cypress Tests") + cy.createApp("Cypress Tests") }) it("should create a user", () => { @@ -52,7 +54,7 @@ filterTests(["smoke", "all"], () => { cy.get(".spectrum-Table").contains("bbuser").click() cy.wait(1000) for (let i = 0; i < 3; i++) { - cy.get(".spectrum-Table") + cy.get(".spectrum-Table", { timeout: 3000}) .eq(1) .find(".spectrum-Table-row") .eq(0) @@ -79,6 +81,7 @@ filterTests(["smoke", "all"], () => { .contains("Update role") .click({ force: true }) }) + cy.reload() } // Confirm roles exist within Configure roles table cy.wait(2000) diff --git a/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js b/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js index efb9e58c75..ff6cb91bad 100644 --- a/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js +++ b/packages/builder/cypress/integration/templates/HR/jobApplicationTracker.spec.js @@ -1,7 +1,7 @@ import filterTests from "../../../support/filterTests" filterTests(["all"], () => { - context("Job Application Functionality", () => { + context("Job Application Tracker Template Functionality", () => { const templateName = "Job Application Tracker" const templateNameParsed = templateName.toLowerCase().replace(/\s+/g, '-') @@ -14,15 +14,7 @@ filterTests(["all"], () => { } }) cy.wait(2000) - - // Template navigation - cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`) - .its("body") - .then(val => { - if (val.length > 0) { - cy.get(".spectrum-Button").contains("Templates").click({force: true}) - } - }) + cy.templateNavigation() }) it("should create and publish app with Job Application Tracker template", () => { diff --git a/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js b/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js new file mode 100644 index 0000000000..118625ac65 --- /dev/null +++ b/packages/builder/cypress/integration/templates/IT/ITTicketingSystem.spec.js @@ -0,0 +1,81 @@ +import filterTests from "../../../support/filterTests" + +filterTests(["all"], () => { + context("IT Ticketing System Template Functionality", () => { + const templateName = "IT Ticketing System" + const templateNameParsed = templateName.toLowerCase().replace(/\s+/g, '-') + + before(() => { + cy.login() + cy.deleteApp(templateName) + cy.visit(`${Cypress.config().baseUrl}/builder`, { + onBeforeLoad(win) { + cy.stub(win, 'open') + } + }) + cy.wait(2000) + cy.templateNavigation() + }) + + it("should create and publish app with IT Ticketing System template", () => { + // Select IT Ticketing System template + cy.get(".template-thumbnail-text") + .contains(templateName).parentsUntil(".template-grid").within(() => { + cy.get(".spectrum-Button").contains("Use template").click({ force: true }) + }) + + // Confirm URL matches template name + const appUrl = cy.get(".app-server") + appUrl.invoke('text').then(appUrlText => { + expect(appUrlText).to.equal(`${Cypress.config().baseUrl}/app/` + templateNameParsed) + }) + + // Create App + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button").contains("Create app").click({ force: true }) + }) + + // Publish App + cy.wait(2000) // Wait for app to generate + cy.get(".toprightnav").contains("Publish").click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button").contains("Publish").click({ force: true }) + }) + + // Verify Published app + cy.wait(2000) // Wait for App to publish and modal to appear + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get(".spectrum-Button").contains("View App").click({ force: true }) + cy.window().its('open').should('be.calledOnce') + }) + }) + + xit("should filter tickets by status", () => { + // Visit published app + cy.visit(`${Cypress.config().baseUrl}/app/` + templateNameParsed) + cy.wait(1000) + + // Tickets section + cy.get(".links").contains("Tickets").click({ force: true }) + cy.wait(1000) + + // Filter by stage - Confirm table updates + cy.get(".spectrum-Picker").contains("Filter by status").click({ force: true }) + cy.get(".spectrum-Menu").find('li').its('length').then(len => { + for (let i = 1; i < len; i++) { + cy.get(".spectrum-Menu-item").eq(i).click() + const stage = cy.get(".spectrum-Picker-label") + stage.invoke('text').then(stageText => { + if (stageText == "In progress" || stageText == "On hold" || stageText == "Triaged") { + cy.get(".placeholder").should('contain', 'No rows found') + } + else { + cy.get(".spectrum-Table-row").should('contain', stageText) + } + cy.get(".spectrum-Picker").contains(stageText).click({ force: true }) + }) + } + }) + }) + }) +}) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index fe355441b9..6655219cd7 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -524,7 +524,12 @@ Cypress.Commands.add("createAppFromScratch", appName => { .contains("Start from scratch") .click({ force: true }) cy.get(".spectrum-Modal").within(() => { - cy.get("input").eq(0).type(appName).should("have.value", appName).blur() + cy.get("input") + .eq(0) + .clear() + .type(appName) + .should("have.value", appName) + .blur() cy.get(".spectrum-ButtonGroup").contains("Create app").click() cy.wait(10000) }) @@ -638,12 +643,14 @@ Cypress.Commands.add("addDatasourceConfig", (datasource, skipFetch) => { .click({ force: true }) }) } else { + cy.intercept("**/tables").as("datasourceTables") cy.get(".spectrum-Dialog-grid").within(() => { cy.get(".spectrum-Button") .contains("Save and fetch tables") .click({ force: true }) - cy.wait(3000) }) + // Wait for tables to be fetched + cy.wait("@datasourceTables", { timeout: 60000 }) } }) @@ -664,3 +671,15 @@ Cypress.Commands.add("createRestQuery", (method, restUrl, queryPrettyName) => { .should("contain", method) .and("contain", queryPrettyName) }) + +Cypress.Commands.add("templateNavigation", () => { + // Navigates to templates section + cy.request(`${Cypress.config().baseUrl}/api/applications?status=all`) + .its("body") + .then(val => { + // Templates button needs clicked if apps already exist + if (val.length > 0) { + cy.get(".spectrum-Button").contains("Templates").click({ force: true }) + } + }) +}) diff --git a/packages/builder/cypress/support/interact.js b/packages/builder/cypress/support/interact.js index 46954227de..cff16325da 100644 --- a/packages/builder/cypress/support/interact.js +++ b/packages/builder/cypress/support/interact.js @@ -8,6 +8,14 @@ export const TEMPLATE_CATEGORY_ACTIONGROUP = ".template-category" export const TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON = ".template-category-filters .spectrum-ActionButton" export const SPECTRUM_MODAL = ".spectrum-Modal" -export const APP_NAME_INPUT = "input" // we need to update this with atribute cy-data +export const APP_NAME_INPUT = "input" // we need to update this with atribute cy-data; export const SPECTRUM_BUTTON_GROUP = ".spectrum-ButtonGroup" export const SPECTRUM_MODAL_INPUT = ".spectrum-Modal input" + +//AddMultiOptionDatatype test +export const CATEGORY_DATA = '[data-cy="category-Data"]' +export const COMPONENT_DATA_PROVIDER = '[data-cy="component-Data Provider"]' +export const DATASOURCE_PROP_CONTROL = '[data-cy="dataSource-prop-control"]' +export const DROPDOWN = ".dropdown" +export const SPECTRUM_Picker_LABEL = ".spectrum-Picker-label" +export const DATASOURCE_FIELD_CONTROL = '[data-cy="field-prop-control"]' diff --git a/packages/builder/package.json b/packages/builder/package.json index 7aed50c268..17e625b115 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "license": "GPL-3.0", "private": true, "scripts": { @@ -67,10 +67,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.164-alpha.0", - "@budibase/client": "^1.0.164-alpha.0", - "@budibase/frontend-core": "^1.0.164-alpha.0", - "@budibase/string-templates": "^1.0.164-alpha.0", + "@budibase/bbui": "^1.0.167-alpha.2", + "@budibase/client": "^1.0.167-alpha.2", + "@budibase/frontend-core": "^1.0.167-alpha.2", + "@budibase/string-templates": "^1.0.167-alpha.2", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index f154a47680..9a449ebb54 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "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 f1bb97dab8..c601ae2219 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "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": "^1.0.164-alpha.0", - "@budibase/frontend-core": "^1.0.164-alpha.0", - "@budibase/string-templates": "^1.0.164-alpha.0", + "@budibase/bbui": "^1.0.167-alpha.2", + "@budibase/frontend-core": "^1.0.167-alpha.2", + "@budibase/string-templates": "^1.0.167-alpha.2", "@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/forms/optionsParser.js b/packages/client/src/components/app/forms/optionsParser.js index e670ccb076..bd69967731 100644 --- a/packages/client/src/components/app/forms/optionsParser.js +++ b/packages/client/src/components/app/forms/optionsParser.js @@ -40,6 +40,15 @@ export const getOptions = ( // Extract custom options if (optionsSource === "custom" && customOptions) { + customOptions.forEach(option => { + if (typeof option.value === "string") { + if (option.value.toLowerCase() === "true") { + option.value = true + } else if (option.value.toLowerCase() === "false") { + option.value = false + } + } + }) return customOptions } diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index c1683eb928..72fa2e763a 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "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.164-alpha.0", + "@budibase/bbui": "^1.0.167-alpha.2", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/server/package.json b/packages/server/package.json index 6511c17397..e7ec9d4d5b 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.164-alpha.0", + "version": "1.0.167-alpha.2", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -69,10 +69,10 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@budibase/backend-core": "^1.0.164-alpha.0", - "@budibase/client": "^1.0.164-alpha.0", - "@budibase/pro": "1.0.164-alpha.0", - "@budibase/string-templates": "^1.0.164-alpha.0", + "@budibase/backend-core": "^1.0.167-alpha.2", + "@budibase/client": "^1.0.167-alpha.2", + "@budibase/pro": "1.0.167-alpha.2", + "@budibase/string-templates": "^1.0.167-alpha.2", "@bull-board/api": "^3.7.0", "@bull-board/koa": "^3.7.0", "@elastic/elasticsearch": "7.10.0", @@ -146,12 +146,14 @@ "@budibase/standard-components": "^0.9.139", "@jest/test-sequencer": "^24.8.0", "@types/apidoc": "^0.50.0", + "@types/bson": "^4.2.0", "@types/bull": "^3.15.1", "@types/google-spreadsheet": "^3.1.5", "@types/jest": "^27.4.1", "@types/koa": "^2.13.3", "@types/koa-router": "^7.4.2", "@types/lodash": "4.14.180", + "@types/mongodb": "3.6.3", "@types/node": "^15.12.4", "@types/oracledb": "^5.2.1", "@types/redis": "^4.0.11", diff --git a/packages/server/src/integrations/mongodb.ts b/packages/server/src/integrations/mongodb.ts index ae6754907b..3d851399f6 100644 --- a/packages/server/src/integrations/mongodb.ts +++ b/packages/server/src/integrations/mongodb.ts @@ -113,29 +113,20 @@ module MongoDBModule { } parseQueryParams(params: string, mode: string) { - let queryParams = params.split(/(?<=(},)).*{/g) - let group1 = queryParams[0] - let group2 = queryParams[2] - let group3 = queryParams[4] - if (group1) { - group1 = JSON.parse(group1.replace(/,+$/, "")) - } - if (group2) { - group2 = JSON.parse("{" + group2.replace(/,+$/, "")) - } - if (group3) { - group3 = JSON.parse("{" + group3.replace(/,+$/, "")) - } + let queryParams = params.split(/(?<=}),[\n\s]*(?={)/g) + let group1 = queryParams[0] ? JSON.parse(queryParams[0]) : {} + let group2 = queryParams[1] ? JSON.parse(queryParams[1]) : {} + let group3 = queryParams[2] ? JSON.parse(queryParams[2]) : {} if (mode === "update") { return { filter: group1, update: group2, - options: group3 ?? {}, + options: group3, } } return { filter: group1, - options: group2 ?? {}, + options: group2, } } diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index b5c8468769..275257c286 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1014,10 +1014,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.0.164-alpha.0": - version "1.0.164-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.164-alpha.0.tgz#80c7d76de3f643302fcb42b1857500216d405e24" - integrity sha512-mbCJnImaFVF9XuiXbUM6YNj6E0L6Mg/kUAOOMc0SCPFL7c1ugY/6tQVa/6PQPrQW13qqj6EcbOdXlZ5k5kWPQA== +"@budibase/backend-core@1.0.167-alpha.2": + version "1.0.167-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.167-alpha.2.tgz#1a8b50a1c0226f23228e1d96737856a701f39a0f" + integrity sha512-Ikj7q4tY0zbBcGExF92GkmwJ3J45bKJ/IRXiP2kDCPps0RFFvtpC04H7ZyWhE1bzoXSGphtBYLrO0h7duElrnQ== dependencies: "@techpass/passport-openidconnect" "^0.3.0" aws-sdk "^2.901.0" @@ -1091,12 +1091,12 @@ svelte-flatpickr "^3.2.3" svelte-portal "^1.0.0" -"@budibase/pro@1.0.164-alpha.0": - version "1.0.164-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.164-alpha.0.tgz#9ab6c3f94ab5c73123590a08e6283ef3fedcff98" - integrity sha512-QBvwcwKRpI43TwlzgzKLC+KAr0Tijls4G2E0tN5sjirMdUYhoeQEzBQ5URtrK8ko5BkZnCVadsA8CYGeUNcmkg== +"@budibase/pro@1.0.167-alpha.2": + version "1.0.167-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.167-alpha.2.tgz#fc50043ae80693698f944bc9f118ea587f7839fe" + integrity sha512-oOaMpvWgJDppLZt4acmrtkAgX11jLzDuKO5ZNqxeCLAMKOfg8EwgOdm+z9zqkGdObqTp/3v5uzUiI3ImJTQYPQ== dependencies: - "@budibase/backend-core" "1.0.164-alpha.0" + "@budibase/backend-core" "1.0.167-alpha.2" node-fetch "^2.6.1" "@budibase/standard-components@^0.9.139": @@ -2430,6 +2430,13 @@ "@types/connect" "*" "@types/node" "*" +"@types/bson@*", "@types/bson@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.2.0.tgz#a2f71e933ff54b2c3bf267b67fa221e295a33337" + integrity sha512-ELCPqAdroMdcuxqwMgUpifQyRoTpyYCNr1V9xKyF40VsBobsj+BbWNRvwGchMgBPGqkw655ypkjj2MEF5ywVwg== + dependencies: + bson "*" + "@types/bull@^3.15.1": version "3.15.8" resolved "https://registry.yarnpkg.com/@types/bull/-/bull-3.15.8.tgz#ae2139f94490d740b37c8da5d828ce75dd82ce7c" @@ -2651,6 +2658,14 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== +"@types/mongodb@3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.6.3.tgz#5655af409d9e32d5d5ae9a653abf3e5f9c83eb7a" + integrity sha512-6YNqGP1hk5bjUFaim+QoFFuI61WjHiHE1BNeB41TA00Xd2K7zG4lcWyLLq/XtIp36uMavvS5hoAUJ+1u/GcX2Q== + dependencies: + "@types/bson" "*" + "@types/node" "*" + "@types/node@*", "@types/node@>=13.13.4": version "17.0.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.18.tgz#3b4fed5cfb58010e3a2be4b6e74615e4847f1074" @@ -3869,6 +3884,13 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +bson@*: + version "4.6.3" + resolved "https://registry.yarnpkg.com/bson/-/bson-4.6.3.tgz#d1a9a0b84b9e84b62390811fc5580f6a8b1d858c" + integrity sha512-rAqP5hcUVJhXP2MCSNVsf0oM2OGU1So6A9pVRDYayvJ5+hygXHQApf87wd5NlhPM1J9RJnbqxIG/f8QTzRoQ4A== + dependencies: + buffer "^5.6.0" + bson@^1.1.4: version "1.1.6" resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 5e9228ea1c..b84cef777d 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.0.164-alpha.0", + "version": "1.0.167-alpha.2", "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 13f7df1257..b2e7773161 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.164-alpha.0", + "version": "1.0.167-alpha.2", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -31,9 +31,9 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.0.164-alpha.0", - "@budibase/pro": "1.0.164-alpha.0", - "@budibase/string-templates": "^1.0.164-alpha.0", + "@budibase/backend-core": "^1.0.167-alpha.2", + "@budibase/pro": "1.0.167-alpha.2", + "@budibase/string-templates": "^1.0.167-alpha.2", "@koa/router": "^8.0.0", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "^0.3.0", diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index ec7d00591b..ff3eb90007 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -293,10 +293,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.0.164-alpha.0": - version "1.0.164-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.164-alpha.0.tgz#80c7d76de3f643302fcb42b1857500216d405e24" - integrity sha512-mbCJnImaFVF9XuiXbUM6YNj6E0L6Mg/kUAOOMc0SCPFL7c1ugY/6tQVa/6PQPrQW13qqj6EcbOdXlZ5k5kWPQA== +"@budibase/backend-core@1.0.167-alpha.2": + version "1.0.167-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.167-alpha.2.tgz#1a8b50a1c0226f23228e1d96737856a701f39a0f" + integrity sha512-Ikj7q4tY0zbBcGExF92GkmwJ3J45bKJ/IRXiP2kDCPps0RFFvtpC04H7ZyWhE1bzoXSGphtBYLrO0h7duElrnQ== dependencies: "@techpass/passport-openidconnect" "^0.3.0" aws-sdk "^2.901.0" @@ -321,12 +321,12 @@ uuid "^8.3.2" zlib "^1.0.5" -"@budibase/pro@1.0.164-alpha.0": - version "1.0.164-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.164-alpha.0.tgz#9ab6c3f94ab5c73123590a08e6283ef3fedcff98" - integrity sha512-QBvwcwKRpI43TwlzgzKLC+KAr0Tijls4G2E0tN5sjirMdUYhoeQEzBQ5URtrK8ko5BkZnCVadsA8CYGeUNcmkg== +"@budibase/pro@1.0.167-alpha.2": + version "1.0.167-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.0.167-alpha.2.tgz#fc50043ae80693698f944bc9f118ea587f7839fe" + integrity sha512-oOaMpvWgJDppLZt4acmrtkAgX11jLzDuKO5ZNqxeCLAMKOfg8EwgOdm+z9zqkGdObqTp/3v5uzUiI3ImJTQYPQ== dependencies: - "@budibase/backend-core" "1.0.164-alpha.0" + "@budibase/backend-core" "1.0.167-alpha.2" node-fetch "^2.6.1" "@cspotcode/source-map-consumer@0.8.0":