From b6f8d74e010691c7707e3bc5a586a21da86a8713 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Mon, 27 Sep 2021 18:19:25 +0100 Subject: [PATCH 01/52] Cypress Testing additions and changes -Changing baseurl to be the test env -Made a few updates to existing tests/commands --New commands also added -Add Radio Button Test -Add Multi Option Datatype test -Custom Theming Properties Test --Just the one so far, more to come --- packages/builder/cypress.json | 2 +- .../addMultiOptionDatatype.spec.js | 40 ++++++++++++ .../integration/addRadioButtons.spec.js | 39 ++++++++++++ .../cypress/integration/createApp.spec.js | 2 +- .../cypress/integration/createTable.spec.js | 2 +- .../cypress/integration/createView.spec.js | 13 ++-- .../customThemingProperties.spec.js | 61 +++++++++++++++++++ packages/builder/cypress/setup.js | 2 +- packages/builder/cypress/support/commands.js | 54 +++++++++++++--- 9 files changed, 200 insertions(+), 15 deletions(-) create mode 100644 packages/builder/cypress/integration/addMultiOptionDatatype.spec.js create mode 100644 packages/builder/cypress/integration/addRadioButtons.spec.js create mode 100644 packages/builder/cypress/integration/customThemingProperties.spec.js diff --git a/packages/builder/cypress.json b/packages/builder/cypress.json index 0908f2c839..cd63e19b01 100644 --- a/packages/builder/cypress.json +++ b/packages/builder/cypress.json @@ -1,5 +1,5 @@ { - "baseUrl": "http://localhost:10001/builder/", + "baseUrl": "https://test.budi.live/builder/", "video": true, "projectId": "bmbemn", "env": { diff --git a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js new file mode 100644 index 0000000000..5d4860ccec --- /dev/null +++ b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js @@ -0,0 +1,40 @@ +context("Add Multi-Option Datatype", () => { + before(() => { + cy.login() + cy.createTestApp() + }) + + it("should create a new table, with data", () => { + cy.createTable("Multi Data") + cy.addColumn("Multi Data", "Test Data", "Multi-select", "1\n2\n3\n4\n5") + cy.addRowMultiValue(["1", "2", "3", "4", "5"]) + }) + + it ("should add form with multi select picker, containing 5 options", () => { + cy.navigateToFrontend() + cy.wait(500) + // Add data provider + cy.get(`[data-cy="category-Data Provider"]`).click() + cy.get('[data-cy="dataSource-prop-control"]').click() + cy.get(".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.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.getComponent(componentId).click() + // Check picker has 5 items + cy.getComponent(componentId).find('li').should('have.length', 5) + // Select all items + for (let i = 1; i < 6; i++) { + cy.getComponent(componentId).find('li').contains(i).click() + } + // Check items have been selected + cy.getComponent(componentId).find('.spectrum-Picker-label').contains("(5)") + }) + }) +}) \ No newline at end of file diff --git a/packages/builder/cypress/integration/addRadioButtons.spec.js b/packages/builder/cypress/integration/addRadioButtons.spec.js new file mode 100644 index 0000000000..ef16a02137 --- /dev/null +++ b/packages/builder/cypress/integration/addRadioButtons.spec.js @@ -0,0 +1,39 @@ +context("Add Radio Buttons", () => { + before(() => { + cy.login() + cy.createTestApp() + }) + +it("should add Radio Buttons options picker on form, add data, and confirm", () => { + cy.navigateToFrontend() + cy.addComponent("Form", "Form") + cy.addComponent("Form", "Options Picker").then((componentId) => { + // Provide field setting + cy.get(`[data-cy="field-prop-control"]`).type("1") + // Open dropdown and select Radio buttons + cy.get(`[data-cy="optionsType-prop-control"]`).click().then(() => { + cy.get('.spectrum-Popover').contains('Radio buttons') + .wait(500) + .click() + }) + const radioButtonsTotal = 3 + // Add values and confirm total + addRadioButtonData(radioButtonsTotal) + cy.getComponent(componentId).find('[type="radio"]') + .should('have.length', radioButtonsTotal) + }) + }) + + const addRadioButtonData = (totalRadioButtons) => { + cy.get(`[data-cy="optionsSource-prop-control"]`).click().then(() => { + cy.get('.spectrum-Popover').contains('Custom') + .wait(500) + .click() + }) + cy.addCustomSourceOptions(totalRadioButtons) + } +}) + + + + diff --git a/packages/builder/cypress/integration/createApp.spec.js b/packages/builder/cypress/integration/createApp.spec.js index 34f152b540..21732b9f3a 100644 --- a/packages/builder/cypress/integration/createApp.spec.js +++ b/packages/builder/cypress/integration/createApp.spec.js @@ -2,7 +2,7 @@ context("Create an Application", () => { it("should create a new application", () => { cy.login() cy.createTestApp() - cy.visit(`localhost:${Cypress.env("PORT")}/builder`) + cy.visit(`https://test.budi.live/builder`) cy.contains("Cypress Tests").should("exist") }) }) diff --git a/packages/builder/cypress/integration/createTable.spec.js b/packages/builder/cypress/integration/createTable.spec.js index eda72ba36d..5be32e2a18 100644 --- a/packages/builder/cypress/integration/createTable.spec.js +++ b/packages/builder/cypress/integration/createTable.spec.js @@ -38,7 +38,7 @@ context("Create a Table", () => { cy.wait(1000) cy.get(".spectrum-Modal input").type("Updated") cy.contains("Save").click() - cy.contains("RoverUpdated").should("have.text", "RoverUpdated") + cy.contains("Updated").should("have.text", "Updated") }) it("deletes a row", () => { diff --git a/packages/builder/cypress/integration/createView.spec.js b/packages/builder/cypress/integration/createView.spec.js index 3aef927e8d..aab8845836 100644 --- a/packages/builder/cypress/integration/createView.spec.js +++ b/packages/builder/cypress/integration/createView.spec.js @@ -1,3 +1,7 @@ +Cypress.on('uncaught:exception', (err, runnable) => { + return false; +}); + context("Create a View", () => { before(() => { cy.login() @@ -57,6 +61,7 @@ context("Create a View", () => { }) it("creates a stats calculation view based on age", () => { + cy.wait(1000) cy.contains("Calculate").click() cy.get(".modal-inner-wrapper").within(() => { cy.get(".spectrum-Picker-label").eq(0).click() @@ -65,7 +70,7 @@ context("Create a View", () => { cy.get(".spectrum-Picker-label").eq(1).click() cy.contains("age").click({ force: true }) - cy.contains("Save").click() + cy.get(".spectrum-Button").contains("Save").click({ force: true }) }) cy.wait(1000) @@ -126,7 +131,7 @@ context("Create a View", () => { cy.contains(".nav-item", "Test View") .find(".actions .icon") .click({ force: true }) - cy.contains("Edit").click() + cy.get(".spectrum-Menu-itemLabel").contains("Edit").click() cy.get(".modal-inner-wrapper").within(() => { cy.get("input").type(" Updated") cy.contains("Save").click() @@ -141,8 +146,8 @@ context("Create a View", () => { .click({ force: true }) cy.contains("Delete").click() cy.contains("Delete View").click() - cy.wait(1000) - cy.contains("TestView Updated").should("not.be.visible") + cy.wait(500) + cy.contains("TestView Updated").should("not.exist") }) }) diff --git a/packages/builder/cypress/integration/customThemingProperties.spec.js b/packages/builder/cypress/integration/customThemingProperties.spec.js new file mode 100644 index 0000000000..f0004b1343 --- /dev/null +++ b/packages/builder/cypress/integration/customThemingProperties.spec.js @@ -0,0 +1,61 @@ +context("Custom Theming Properties", () => { + before(() => { + cy.login() + cy.createTestApp() + cy.navigateToFrontend() + }) + + // Default Values + // Button roundness = Large + // Primary colour = Blue 600 + // Primary colour (hover) = Blue 500 + // Navigation bar background colour = Gray 100 + // Navigation bar text colour = Gray 800 + it("should reset the color property values", () => { + // Open Theme modal and change colours + cy.get(".spectrum-ActionButton-label").contains("Theme").click() + cy.get(".spectrum-Picker").contains("Large").click() + .parents() + .get(".spectrum-Menu-itemLabel").contains("None").click() + changeThemeColors() + // Reset colours + cy.get(".spectrum-Button-label").contains("Reset").click({force: true}) + // Check values have reset + checkThemeColorDefaults() + }) + + const changeThemeColors = () => { + // Changes the theme colours + cy.get(".spectrum-FieldLabel").contains("Primary color") + .parent().find(".container.svelte-z3cm5a").click() + .find('[title="Red 400"]').click() + cy.get(".spectrum-FieldLabel").contains("Primary color (hover)") + .parent().find(".container.svelte-z3cm5a").click() + .find('[title="Orange 400"]').click() + cy.get(".spectrum-FieldLabel").contains("Navigation bar background color") + .parent().find(".container.svelte-z3cm5a").click() + .find('[title="Yellow 400"]').click() + cy.get(".spectrum-FieldLabel").contains("Navigation bar text color") + .parent().find(".container.svelte-z3cm5a").click() + .find('[title="Green 400"]').click() + } + + const checkThemeColorDefaults = () => { + cy.get(".spectrum-FieldLabel").contains("Primary color") + .parent().find(".container.svelte-z3cm5a").click() + .get('[title="Blue 600"]').children().find('[aria-label="Checkmark"]') + cy.get(".spectrum-Dialog-grid").click() + cy.get(".spectrum-FieldLabel").contains("Primary color (hover)") + .parent().find(".container.svelte-z3cm5a").click() + .get('[title="Blue 500"]').children().find('[aria-label="Checkmark"]') + cy.get(".spectrum-Dialog-grid").click() + cy.get(".spectrum-FieldLabel").contains("Navigation bar background color") + .parent().find(".container.svelte-z3cm5a").click() + .get('[title="Gray 100"]').children().find('[aria-label="Checkmark"]') + cy.get(".spectrum-Dialog-grid").click() + cy.get(".spectrum-FieldLabel").contains("Navigation bar text color") + .parent().find(".container.svelte-z3cm5a").click() + .get('[title="Gray 800"]').children().find('[aria-label="Checkmark"]') + } + +}) \ No newline at end of file diff --git a/packages/builder/cypress/setup.js b/packages/builder/cypress/setup.js index 1a6f1d5b2b..e636f6aeb9 100644 --- a/packages/builder/cypress/setup.js +++ b/packages/builder/cypress/setup.js @@ -16,7 +16,7 @@ process.env.PORT = MAIN_PORT process.env.JWT_SECRET = cypressConfig.env.JWT_SECRET process.env.COUCH_URL = `leveldb://${tmpdir}/.data/` process.env.SELF_HOSTED = 1 -process.env.WORKER_URL = "http://localhost:10002/" +process.env.WORKER_URL = "https://test.budi.live/" process.env.MINIO_URL = `http://localhost:${MAIN_PORT}/` process.env.MINIO_ACCESS_KEY = "budibase" process.env.MINIO_SECRET_KEY = "budibase" diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index ea6ca81e66..f977ec01ec 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -6,8 +6,8 @@ // Cypress.Commands.add("login", () => { - cy.visit(`localhost:${Cypress.env("PORT")}/builder`) - cy.wait(500) + cy.visit(`https://test.budi.live/builder`) + cy.wait(2000) cy.url().then(url => { if (url.includes("builder/admin")) { // create admin user @@ -22,15 +22,17 @@ Cypress.Commands.add("login", () => { cy.get("input").first().type("test@test.com") cy.get('input[type="password"]').type("test") cy.get("button").first().click() + cy.wait(1000) }) } }) }) Cypress.Commands.add("createApp", name => { - cy.visit(`localhost:${Cypress.env("PORT")}/builder`) + cy.visit(`https://test.budi.live/builder`) cy.wait(500) cy.contains(/Create (new )?app/).click() + cy.wait(500) cy.get(".spectrum-Modal") .within(() => { cy.get("input").eq(0).type(name).should("have.value", name).blur() @@ -43,9 +45,9 @@ Cypress.Commands.add("createApp", name => { }) Cypress.Commands.add("deleteApp", () => { - cy.visit(`localhost:${Cypress.env("PORT")}/builder`) + cy.visit(`https://test.budi.live/builder`) cy.wait(1000) - cy.request(`localhost:${Cypress.env("PORT")}/api/applications?status=all`) + cy.request(`https://test.budi.live/api/applications?status=all`) .its("body") .then(val => { console.log(val) @@ -80,7 +82,7 @@ Cypress.Commands.add("createTable", tableName => { cy.contains(tableName).should("be.visible") }) -Cypress.Commands.add("addColumn", (tableName, columnName, type) => { +Cypress.Commands.add("addColumn", (tableName, columnName, type, multiOptions = null) => { // Select Table cy.selectTable(tableName) cy.contains(".nav-item", tableName).click() @@ -95,6 +97,11 @@ Cypress.Commands.add("addColumn", (tableName, columnName, type) => { cy.get(".spectrum-Picker-label").click() cy.contains(type).click() + // Add options for Multi-select Type + if(multiOptions !== null){ + cy.get(".spectrum-Textfield-input").eq(1).type(multiOptions) + } + cy.contains("Save Column").click() }) }) @@ -109,6 +116,19 @@ Cypress.Commands.add("addRow", values => { }) }) +Cypress.Commands.add("addRowMultiValue", values => { + cy.contains("Create row").click() + cy.get(".spectrum-Form-itemField").click().then(() => { + cy.get(".spectrum-Popover").within(() => { + for (let i = 0; i < values.length; i++) { + cy.get(".spectrum-Menu-item").eq(i).click() + } + }) + cy.get(".spectrum-Dialog-grid").click('top') + cy.get(".spectrum-ButtonGroup").contains("Create").click() + }) +}) + Cypress.Commands.add("createUser", email => { // quick hacky recorded way to create a user cy.contains("Users").click() @@ -127,7 +147,9 @@ Cypress.Commands.add("addComponent", (category, component) => { if (category) { cy.get(`[data-cy="category-${category}"]`).click() } - cy.get(`[data-cy="component-${component}"]`).click() + if (component){ + cy.get(`[data-cy="component-${component}"]`).click() + } cy.wait(1000) cy.location().then(loc => { const params = loc.pathname.split("/") @@ -149,8 +171,11 @@ Cypress.Commands.add("getComponent", componentId => { }) Cypress.Commands.add("navigateToFrontend", () => { + // Clicks on Design tab and then the Home nav item cy.wait(1000) cy.contains("Design").click() + cy.get(".spectrum-Search").type("/") + cy.get(".nav-item").contains("Home").click() }) Cypress.Commands.add("createScreen", (screenName, route) => { @@ -173,3 +198,18 @@ Cypress.Commands.add("selectTable", tableName => { cy.expandBudibaseConnection() cy.contains(".nav-item", tableName).click() }) + +Cypress.Commands.add("addCustomSourceOptions", totalOptions => { + cy.get(".spectrum-ActionButton").contains("Define Options").click().then(() => { + for (let i = 0; i < totalOptions; i++) { + // Add radio button options + cy.get(".spectrum-Button").contains("Add Option").click({force: true}).then(() => { + cy.wait(500) + cy.get("[placeholder='Label']").eq(i).type(i) + cy.get("[placeholder='Value']").eq(i).type(i) + }) + } + // Save options + cy.get(".spectrum-Button").contains("Save").click({force: true}) + }) +}) \ No newline at end of file From f443127e13a367f2c68c55216372da39dc34c98e Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Thu, 30 Sep 2021 13:52:20 +0100 Subject: [PATCH 02/52] Changing Environment I had this as the test env, changing it back to what it was previously. --- packages/builder/cypress.json | 2 +- .../cypress/integration/addMultiOptionDatatype.spec.js | 2 +- .../builder/cypress/integration/addRadioButtons.spec.js | 4 ---- packages/builder/cypress/integration/createApp.spec.js | 2 +- packages/builder/cypress/integration/createView.spec.js | 4 ---- .../cypress/integration/customThemingProperties.spec.js | 2 +- packages/builder/cypress/support/commands.js | 8 ++++---- 7 files changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/builder/cypress.json b/packages/builder/cypress.json index cd63e19b01..0908f2c839 100644 --- a/packages/builder/cypress.json +++ b/packages/builder/cypress.json @@ -1,5 +1,5 @@ { - "baseUrl": "https://test.budi.live/builder/", + "baseUrl": "http://localhost:10001/builder/", "video": true, "projectId": "bmbemn", "env": { diff --git a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js index 5d4860ccec..032d8b01b5 100644 --- a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js +++ b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js @@ -37,4 +37,4 @@ context("Add Multi-Option Datatype", () => { cy.getComponent(componentId).find('.spectrum-Picker-label').contains("(5)") }) }) -}) \ No newline at end of file +}) diff --git a/packages/builder/cypress/integration/addRadioButtons.spec.js b/packages/builder/cypress/integration/addRadioButtons.spec.js index ef16a02137..68d0a74d55 100644 --- a/packages/builder/cypress/integration/addRadioButtons.spec.js +++ b/packages/builder/cypress/integration/addRadioButtons.spec.js @@ -33,7 +33,3 @@ it("should add Radio Buttons options picker on form, add data, and confirm", () cy.addCustomSourceOptions(totalRadioButtons) } }) - - - - diff --git a/packages/builder/cypress/integration/createApp.spec.js b/packages/builder/cypress/integration/createApp.spec.js index 21732b9f3a..34f152b540 100644 --- a/packages/builder/cypress/integration/createApp.spec.js +++ b/packages/builder/cypress/integration/createApp.spec.js @@ -2,7 +2,7 @@ context("Create an Application", () => { it("should create a new application", () => { cy.login() cy.createTestApp() - cy.visit(`https://test.budi.live/builder`) + cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.contains("Cypress Tests").should("exist") }) }) diff --git a/packages/builder/cypress/integration/createView.spec.js b/packages/builder/cypress/integration/createView.spec.js index aab8845836..d7d9606cd7 100644 --- a/packages/builder/cypress/integration/createView.spec.js +++ b/packages/builder/cypress/integration/createView.spec.js @@ -1,7 +1,3 @@ -Cypress.on('uncaught:exception', (err, runnable) => { - return false; -}); - context("Create a View", () => { before(() => { cy.login() diff --git a/packages/builder/cypress/integration/customThemingProperties.spec.js b/packages/builder/cypress/integration/customThemingProperties.spec.js index f0004b1343..47cb81a8a6 100644 --- a/packages/builder/cypress/integration/customThemingProperties.spec.js +++ b/packages/builder/cypress/integration/customThemingProperties.spec.js @@ -58,4 +58,4 @@ context("Custom Theming Properties", () => { .get('[title="Gray 800"]').children().find('[aria-label="Checkmark"]') } -}) \ No newline at end of file +}) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index 3d96dd282f..90fc94ffb6 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -6,7 +6,7 @@ // Cypress.Commands.add("login", () => { - cy.visit(`https://test.budi.live/builder`) + cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.wait(2000) cy.url().then(url => { if (url.includes("builder/admin")) { @@ -29,7 +29,7 @@ Cypress.Commands.add("login", () => { }) Cypress.Commands.add("createApp", name => { - cy.visit(`https://test.budi.live/builder`) + cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.wait(500) cy.contains(/Create (new )?app/).click() cy.wait(500) @@ -48,7 +48,7 @@ Cypress.Commands.add("createApp", name => { }) Cypress.Commands.add("deleteApp", () => { - cy.visit(`https://test.budi.live/builder`) + cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.wait(1000) cy.request(`https://test.budi.live/api/applications?status=all`) .its("body") @@ -232,4 +232,4 @@ Cypress.Commands.add("addCustomSourceOptions", totalOptions => { // Save options cy.get(".spectrum-Button").contains("Save").click({force: true}) }) -}) \ No newline at end of file +}) From aea74a4d74548e2850aac4b0373250c218479023 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Thu, 30 Sep 2021 14:00:26 +0100 Subject: [PATCH 03/52] changing worker-url --- packages/builder/cypress/setup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/cypress/setup.js b/packages/builder/cypress/setup.js index e636f6aeb9..1a6f1d5b2b 100644 --- a/packages/builder/cypress/setup.js +++ b/packages/builder/cypress/setup.js @@ -16,7 +16,7 @@ process.env.PORT = MAIN_PORT process.env.JWT_SECRET = cypressConfig.env.JWT_SECRET process.env.COUCH_URL = `leveldb://${tmpdir}/.data/` process.env.SELF_HOSTED = 1 -process.env.WORKER_URL = "https://test.budi.live/" +process.env.WORKER_URL = "http://localhost:10002/" process.env.MINIO_URL = `http://localhost:${MAIN_PORT}/` process.env.MINIO_ACCESS_KEY = "budibase" process.env.MINIO_SECRET_KEY = "budibase" From f7032435627000460508bb91a1769afb96def9f4 Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Thu, 30 Sep 2021 14:09:37 +0100 Subject: [PATCH 04/52] Fixing env change that i missed in commands file --- packages/builder/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index 90fc94ffb6..0309299468 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -50,7 +50,7 @@ Cypress.Commands.add("createApp", name => { Cypress.Commands.add("deleteApp", () => { cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.wait(1000) - cy.request(`https://test.budi.live/api/applications?status=all`) + cy.request(`localhost:${Cypress.env("PORT")}/api/applications?status=all`) .its("body") .then(val => { console.log(val) From 8709fb2f0b0e6d38d2826888a15d9391d926dd94 Mon Sep 17 00:00:00 2001 From: Maurits Lourens Date: Tue, 5 Oct 2021 12:20:09 +0200 Subject: [PATCH 05/52] add a slash before the path and a questionmark before the querystring --- .../src/components/integration/index.svelte | 6 +++--- packages/server/src/integrations/rest.ts | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/builder/src/components/integration/index.svelte b/packages/builder/src/components/integration/index.svelte index 5c821d3a53..a0e1b8c1c4 100644 --- a/packages/builder/src/components/integration/index.svelte +++ b/packages/builder/src/components/integration/index.svelte @@ -17,9 +17,9 @@ $: urlDisplay = schema.urlDisplay && - `${datasource.config.url}${query.fields.path ?? ""}${ - query.fields.queryString ?? "" - }` + `${datasource.config.url}${ + query.fields.path ? "/" + query.fields.path : "" + }${query.fields.queryString ? "?" + query.fields.queryString : ""}` function updateQuery({ detail }) { query.fields[schema.type] = detail.value diff --git a/packages/server/src/integrations/rest.ts b/packages/server/src/integrations/rest.ts index d6cf71e324..9c6ece52d6 100644 --- a/packages/server/src/integrations/rest.ts +++ b/packages/server/src/integrations/rest.ts @@ -152,13 +152,17 @@ module RestModule { } } + getUrl(path: string, queryString: string): string { + return `${this.config.url}/${path}?${queryString}` + } + async create({ path = "", queryString = "", headers = {}, json = {} }) { this.headers = { ...this.config.defaultHeaders, ...headers, } - const response = await fetch(this.config.url + path + queryString, { + const response = await fetch(this.getUrl(path, queryString), { method: "POST", headers: this.headers, body: JSON.stringify(json), @@ -173,7 +177,7 @@ module RestModule { ...headers, } - const response = await fetch(this.config.url + path + queryString, { + const response = await fetch(this.getUrl(path, queryString), { headers: this.headers, }) @@ -186,7 +190,7 @@ module RestModule { ...headers, } - const response = await fetch(this.config.url + path + queryString, { + const response = await fetch(this.getUrl(path, queryString), { method: "POST", headers: this.headers, body: JSON.stringify(json), @@ -201,7 +205,7 @@ module RestModule { ...headers, } - const response = await fetch(this.config.url + path + queryString, { + const response = await fetch(this.getUrl(path, queryString), { method: "PATCH", headers: this.headers, body: JSON.stringify(json), @@ -216,7 +220,7 @@ module RestModule { ...headers, } - const response = await fetch(this.config.url + path + queryString, { + const response = await fetch(this.getUrl(path, queryString), { method: "DELETE", headers: this.headers, }) From dbf747f749da975dc56ccee6960cda9e67d04c43 Mon Sep 17 00:00:00 2001 From: Maurits Lourens Date: Tue, 5 Oct 2021 13:38:03 +0200 Subject: [PATCH 06/52] fix tests --- .../src/integrations/tests/rest.spec.js | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/packages/server/src/integrations/tests/rest.spec.js b/packages/server/src/integrations/tests/rest.spec.js index a0b12f6c17..cb69d3c38d 100644 --- a/packages/server/src/integrations/tests/rest.spec.js +++ b/packages/server/src/integrations/tests/rest.spec.js @@ -1,98 +1,100 @@ -jest.mock("node-fetch", () => jest.fn(() => ({ json: jest.fn(), text: jest.fn() }))) +jest.mock("node-fetch", () => + jest.fn(() => ({ json: jest.fn(), text: jest.fn() })) +) const fetch = require("node-fetch") const RestIntegration = require("../rest") class TestConfiguration { constructor(config = {}) { - this.integration = new RestIntegration.integration(config) + this.integration = new RestIntegration.integration(config) } } describe("REST Integration", () => { const BASE_URL = "https://myapi.com" - let config + let config beforeEach(() => { config = new TestConfiguration({ - url: BASE_URL + url: BASE_URL, }) }) it("calls the create method with the correct params", async () => { const query = { - path: "/api", - queryString: "?test=1", + path: "api", + queryString: "test=1", headers: { - Accept: "application/json" + Accept: "application/json", }, json: { - name: "test" - } + name: "test", + }, } const response = await config.integration.create(query) expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, { method: "POST", - body: "{\"name\":\"test\"}", + body: '{"name":"test"}', headers: { - Accept: "application/json" - } + Accept: "application/json", + }, }) }) it("calls the read method with the correct params", async () => { const query = { - path: "/api", - queryString: "?test=1", + path: "api", + queryString: "test=1", headers: { - Accept: "text/html" - } + Accept: "text/html", + }, } const response = await config.integration.read(query) expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, { headers: { - Accept: "text/html" - } + Accept: "text/html", + }, }) }) it("calls the update method with the correct params", async () => { const query = { - path: "/api", - queryString: "?test=1", + path: "api", + queryString: "test=1", headers: { - Accept: "application/json" + Accept: "application/json", }, json: { - name: "test" - } + name: "test", + }, } const response = await config.integration.update(query) expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, { method: "POST", - body: "{\"name\":\"test\"}", + body: '{"name":"test"}', headers: { - Accept: "application/json" - } + Accept: "application/json", + }, }) }) it("calls the delete method with the correct params", async () => { const query = { - path: "/api", - queryString: "?test=1", + path: "api", + queryString: "test=1", headers: { - Accept: "application/json" + Accept: "application/json", }, json: { - name: "test" - } + name: "test", + }, } const response = await config.integration.delete(query) expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, { method: "DELETE", headers: { - Accept: "application/json" - } + Accept: "application/json", + }, }) }) -}) \ No newline at end of file +}) From 1cd46327bf9249ea0e69dee5e6996903daa64331 Mon Sep 17 00:00:00 2001 From: Budibase Release Bot <> Date: Thu, 7 Oct 2021 22:18:59 +0000 Subject: [PATCH 07/52] v0.9.160 --- lerna.json | 2 +- packages/auth/package.json | 2 +- packages/bbui/package.json | 2 +- packages/builder/package.json | 8 ++++---- packages/cli/package.json | 2 +- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/string-templates/package.json | 2 +- packages/worker/package.json | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 510f605b3f..9c1d1db679 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.159", + "version": "0.9.160", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/auth/package.json b/packages/auth/package.json index 5af97cb10a..9c81a03a1b 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.159", + "version": "0.9.160", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index bba2722293..dfb0fcb75b 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": "0.9.159", + "version": "0.9.160", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index f09c2e9c59..856168470d 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.159", + "version": "0.9.160", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.159", - "@budibase/client": "^0.9.159", + "@budibase/bbui": "^0.9.160", + "@budibase/client": "^0.9.160", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.159", + "@budibase/string-templates": "^0.9.160", "@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 4024bf0906..5f35fb3984 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "0.9.159", + "version": "0.9.160", "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 4b1e88b2fa..a5252dcfdf 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.9.159", + "version": "0.9.160", "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": "^0.9.159", + "@budibase/bbui": "^0.9.160", "@budibase/standard-components": "^0.9.139", - "@budibase/string-templates": "^0.9.159", + "@budibase/string-templates": "^0.9.160", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" diff --git a/packages/server/package.json b/packages/server/package.json index f3fa66a595..6a9c127f67 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.9.159", + "version": "0.9.160", "description": "Budibase Web Server", "main": "src/index.js", "repository": { @@ -66,9 +66,9 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.159", - "@budibase/client": "^0.9.159", - "@budibase/string-templates": "^0.9.159", + "@budibase/auth": "^0.9.160", + "@budibase/client": "^0.9.160", + "@budibase/string-templates": "^0.9.160", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index fa2e0ae8c0..1459cd1f4d 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.9.159", + "version": "0.9.160", "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 30e7107fd3..b628591971 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "0.9.159", + "version": "0.9.160", "description": "Budibase background service", "main": "src/index.js", "repository": { @@ -27,8 +27,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.159", - "@budibase/string-templates": "^0.9.159", + "@budibase/auth": "^0.9.160", + "@budibase/string-templates": "^0.9.160", "@koa/router": "^8.0.0", "@techpass/passport-openidconnect": "^0.3.0", "aws-sdk": "^2.811.0", From 22527970b237e0cbc64f579fec1eebe42dc1c778 Mon Sep 17 00:00:00 2001 From: Budibase Release Bot <> Date: Thu, 7 Oct 2021 22:32:31 +0000 Subject: [PATCH 08/52] v0.9.161 --- lerna.json | 2 +- packages/auth/package.json | 2 +- packages/bbui/package.json | 2 +- packages/builder/package.json | 8 ++++---- packages/cli/package.json | 2 +- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/string-templates/package.json | 2 +- packages/worker/package.json | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 9c1d1db679..3b72b76b32 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.160", + "version": "0.9.161", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/auth/package.json b/packages/auth/package.json index 9c81a03a1b..2bfc50a6a3 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.160", + "version": "0.9.161", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index dfb0fcb75b..2afd4a5f30 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": "0.9.160", + "version": "0.9.161", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index 856168470d..09f6fbc1e2 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.160", + "version": "0.9.161", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.160", - "@budibase/client": "^0.9.160", + "@budibase/bbui": "^0.9.161", + "@budibase/client": "^0.9.161", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.160", + "@budibase/string-templates": "^0.9.161", "@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 5f35fb3984..8bbef74dd7 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "0.9.160", + "version": "0.9.161", "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 a5252dcfdf..c79e9d0c61 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.9.160", + "version": "0.9.161", "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": "^0.9.160", + "@budibase/bbui": "^0.9.161", "@budibase/standard-components": "^0.9.139", - "@budibase/string-templates": "^0.9.160", + "@budibase/string-templates": "^0.9.161", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" diff --git a/packages/server/package.json b/packages/server/package.json index 6a9c127f67..5c5637e229 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.9.160", + "version": "0.9.161", "description": "Budibase Web Server", "main": "src/index.js", "repository": { @@ -66,9 +66,9 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160", - "@budibase/client": "^0.9.160", - "@budibase/string-templates": "^0.9.160", + "@budibase/auth": "^0.9.161", + "@budibase/client": "^0.9.161", + "@budibase/string-templates": "^0.9.161", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 1459cd1f4d..a758d157cb 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.9.160", + "version": "0.9.161", "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 b628591971..cd8b590f4d 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "0.9.160", + "version": "0.9.161", "description": "Budibase background service", "main": "src/index.js", "repository": { @@ -27,8 +27,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160", - "@budibase/string-templates": "^0.9.160", + "@budibase/auth": "^0.9.161", + "@budibase/string-templates": "^0.9.161", "@koa/router": "^8.0.0", "@techpass/passport-openidconnect": "^0.3.0", "aws-sdk": "^2.811.0", From 417826ffed64340ce184504c7fff7e702dbc028e Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Fri, 8 Oct 2021 10:56:44 +0100 Subject: [PATCH 09/52] Update commands.js --- packages/builder/cypress/support/commands.js | 89 +++++++++++--------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index b10e7b9990..6d6f292461 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -101,29 +101,32 @@ Cypress.Commands.add("createTable", tableName => { cy.contains(tableName).should("be.visible") }) -Cypress.Commands.add("addColumn", (tableName, columnName, type, multiOptions = null) => { - // Select Table - cy.selectTable(tableName) - cy.contains(".nav-item", tableName).click() - cy.contains("Create column").click() +Cypress.Commands.add( + "addColumn", + (tableName, columnName, type, multiOptions = null) => { + // Select Table + cy.selectTable(tableName) + cy.contains(".nav-item", tableName).click() + cy.contains("Create column").click() - // Configure column - cy.get(".spectrum-Modal").within(() => { - cy.get("input").first().type(columnName).blur() + // Configure column + cy.get(".spectrum-Modal").within(() => { + cy.get("input").first().type(columnName).blur() - // Unset table display column - cy.contains("display column").click({ force: true }) - cy.get(".spectrum-Picker-label").click() - cy.contains(type).click() + // Unset table display column + cy.contains("display column").click({ force: true }) + cy.get(".spectrum-Picker-label").click() + cy.contains(type).click() - // Add options for Multi-select Type - if(multiOptions !== null){ - cy.get(".spectrum-Textfield-input").eq(1).type(multiOptions) - } + // Add options for Multi-select Type + if (multiOptions !== null) { + cy.get(".spectrum-Textfield-input").eq(1).type(multiOptions) + } - cy.contains("Save Column").click() - }) -}) + cy.contains("Save Column").click() + }) + } +) Cypress.Commands.add("addRow", values => { cy.contains("Create row").click() @@ -137,15 +140,17 @@ Cypress.Commands.add("addRow", values => { Cypress.Commands.add("addRowMultiValue", values => { cy.contains("Create row").click() - cy.get(".spectrum-Form-itemField").click().then(() => { - cy.get(".spectrum-Popover").within(() => { - for (let i = 0; i < values.length; i++) { - cy.get(".spectrum-Menu-item").eq(i).click() - } + cy.get(".spectrum-Form-itemField") + .click() + .then(() => { + cy.get(".spectrum-Popover").within(() => { + for (let i = 0; i < values.length; i++) { + cy.get(".spectrum-Menu-item").eq(i).click() + } + }) + cy.get(".spectrum-Dialog-grid").click("top") + cy.get(".spectrum-ButtonGroup").contains("Create").click() }) - cy.get(".spectrum-Dialog-grid").click('top') - cy.get(".spectrum-ButtonGroup").contains("Create").click() - }) }) Cypress.Commands.add("createUser", email => { @@ -166,7 +171,7 @@ Cypress.Commands.add("addComponent", (category, component) => { if (category) { cy.get(`[data-cy="category-${category}"]`).click() } - if (component){ + if (component) { cy.get(`[data-cy="component-${component}"]`).click() } cy.wait(1000) @@ -219,16 +224,22 @@ Cypress.Commands.add("selectTable", tableName => { }) Cypress.Commands.add("addCustomSourceOptions", totalOptions => { - cy.get(".spectrum-ActionButton").contains("Define Options").click().then(() => { - for (let i = 0; i < totalOptions; i++) { - // Add radio button options - cy.get(".spectrum-Button").contains("Add Option").click({force: true}).then(() => { - cy.wait(500) - cy.get("[placeholder='Label']").eq(i).type(i) - cy.get("[placeholder='Value']").eq(i).type(i) + cy.get(".spectrum-ActionButton") + .contains("Define Options") + .click() + .then(() => { + for (let i = 0; i < totalOptions; i++) { + // Add radio button options + cy.get(".spectrum-Button") + .contains("Add Option") + .click({ force: true }) + .then(() => { + cy.wait(500) + cy.get("[placeholder='Label']").eq(i).type(i) + cy.get("[placeholder='Value']").eq(i).type(i) + }) + } + // Save options + cy.get(".spectrum-Button").contains("Save").click({ force: true }) }) - } - // Save options - cy.get(".spectrum-Button").contains("Save").click({force: true}) - }) }) From d6818acfcf3fadef60a78d6ced3a5be4de4f787f Mon Sep 17 00:00:00 2001 From: Mitch-Budibase Date: Fri, 8 Oct 2021 11:45:54 +0100 Subject: [PATCH 10/52] Some changes for addMultiOptionDatatype --- .../cypress/integration/addMultiOptionDatatype.spec.js | 3 ++- packages/builder/cypress/support/commands.js | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js index 032d8b01b5..bc2619c53d 100644 --- a/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js +++ b/packages/builder/cypress/integration/addMultiOptionDatatype.spec.js @@ -26,7 +26,8 @@ context("Add Multi-Option Datatype", () => { // 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.getComponent(componentId).click() + cy.wait(1000) + cy.getComponent(componentId).contains("Choose some options").click() // Check picker has 5 items cy.getComponent(componentId).find('li').should('have.length', 5) // Select all items diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index 6d6f292461..c8e01435aa 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -5,6 +5,10 @@ // *********************************************** // +Cypress.on('uncaught:exception', (err, runnable) => { + return false +}) + Cypress.Commands.add("login", () => { cy.visit(`localhost:${Cypress.env("PORT")}/builder`) cy.wait(2000) From 5ffed2824e1139aa5a640a00912aa62ab5e86fd6 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Fri, 8 Oct 2021 13:13:16 +0100 Subject: [PATCH 11/52] Introduce dev modes, update contributor guide --- .github/CONTRIBUTING.md | 132 +++++++++++++++-------------- package.json | 17 ++-- packages/server/package.json | 14 +-- packages/server/scripts/account.js | 8 ++ packages/worker/package.json | 14 +-- packages/worker/scripts/account.js | 8 ++ 6 files changed, 112 insertions(+), 81 deletions(-) create mode 100644 packages/server/scripts/account.js create mode 100644 packages/worker/scripts/account.js diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 696bd18986..7abfe537e9 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,7 +2,7 @@ From opening a bug report to creating a pull request: every contribution is appreciated and welcome. If you're planning to implement a new feature or change the api please create an issue first. This way we can ensure that your precious work is not in vain. -### Not Sure Where to Start? +## Not Sure Where to Start? Budibase is a low-code web application builder that creates svelte based web applications. @@ -14,6 +14,8 @@ Budibase is a monorepo managed by [lerna](https://github.com/lerna/lerna). Lerna - **packages/server** - The budibase server. This [Koa](https://koajs.com/) app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system. +- **packages/worker** - This [Koa](https://koajs.com/) app is responsible for providing global apis for managing your budibase installation. Authentication, Users, Email, Org and Auth configs are all provided by the worker. + ## Contributor License Agreement (CLA) In order to accept your pull request, we need you to submit a CLA. You only need to do this once. If you are submitting a pull request for the first time, just submit a Pull Request and our CLA Bot will give you instructions on how to sign the CLA before merging your Pull Request. @@ -62,8 +64,6 @@ A component is the basic frontend building block of a budibase app. Component libraries are collections of components as well as the definition of their props contained in a file called `components.json`. - - ## Contributing to Budibase * Please maintain the existing code style. @@ -74,31 +74,30 @@ Component libraries are collections of components as well as the definition of t * If the project diverges from your branch, please rebase instead of merging. This makes the commit graph easier to read. -* Once your work is completed, please raise a PR against the main branch with some information about what has changed and why. +* Once your work is completed, please raise a PR against the `develop` branch with some information about what has changed and why. ### Getting Started For Contributors - -### 1. Prerequisites +#### 1. Prerequisites *yarn -* `npm install -g yarn` *jest* - `npm install -g jest` -### 2. Clone this repository +#### 2. Clone this repository `git clone https://github.com/Budibase/budibase.git` then `cd ` into your local copy. -### 3. Install and Build +#### 3. Install and Build To develop the Budibase platform you'll need [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) installed. -#### Quick method +##### Quick method `yarn setup` will check that all necessary components are installed and setup the repo for usage. -#### Manual method +##### Manual method The following commands can be executed to manually get Budibase up and running (assuming Docker/Docker Compose has been installed). @@ -108,15 +107,7 @@ The following commands can be executed to manually get Budibase up and running ( `yarn build` will build all budibase packages. -### 4. Initialising Budibase and Creating a Budibase App - -Starting up the budibase electron app should initialise budibase for you. A Budibase apps folder will have been created in `~/.budibase`. - -This is a blank apps folder, so you will need to create yourself an app, you can do this by clicking "Create New App" from the budibase builder. - -This will create a new budibase application in the `~/.budibase/` directory, and NPM install the component libraries for that application. Let's start building your app with the budibase builder! - -### 4. Running +#### 4. Running To run the budibase server and builder in dev mode (i.e. with live reloading): @@ -126,7 +117,7 @@ To run the budibase server and builder in dev mode (i.e. with live reloading): This will enable watch mode for both the builder app, server, client library and any component libraries. -### 5. Debugging using VS Code +#### 5. Debugging using VS Code To debug the budibase server and worker a VS Code launch configuration has been provided. @@ -135,75 +126,90 @@ Alternatively to start both components simultaneously select `Start Budibase`. In addition to the above, the remaining budibase components may be ran in dev mode using: `yarn dev:noserver`. -### 6. Cleanup +#### 6. Cleanup If you wish to delete all the apps created in development and reset the environment then run the following: 1. `yarn nuke:docker` will wipe all the Budibase services 2. `yarn dev` will restart all the services -## Data Storage - -When you are running locally, budibase stores data on disk using [PouchDB](https://pouchdb.com/), as well as some JSON on local files. After setting up budibase, you can find all of this data in the `~/.budibase` directory. - -A client can have one or more budibase applications. Budibase applications are stored in `~/.budibase/`. Files used by your budibase application when running are stored in the `public` directory. Everything else is dev files used for the development of your apps in the builder. - -#### Frontend - -To see the current individual JSON definitions for your pages and screens used by the builder, have a look at `~/.budibase//pages`. - -For your actual running application (not in dev), the frontend tree structure of the application (known as `clientFrontendDefinition`) is stored as JSON on disk. This is what the budibase client library reads to create your app at runtime. This can be found at `~/.budibase//public/clientFrontendDefinition.js` - -The HTML and CSS for your apps runtime pages, as well as the budibase client library JS is stored at: - -- `~/.budibase//public/main` -- `~/.budibase//public/unauthenticated` - -#### Backend +### Backend For the backend we run [Redis](https://redis.io/), [CouchDB](https://couchdb.apache.org/), [MinIO](https://min.io/) and [Envoy](https://www.envoyproxy.io/) in Docker compose. This means that to develop Budibase you will need Docker and Docker compose installed. The backend services are then ran separately as Node services with nodemon so that they can be debugged outside of Docker. -### Publishing Budibase to NPM +### Data Storage -#### Testing In Electron +When you are running locally, budibase stores data on disk using docker volumes. The volumes and the types of data associated with each are: -At budibase, we pride ourselves on giving our users a fast, native and slick local development experience. As a result, we use the electron to provide a native GUI for the budibase builder. In order to release budibase out into the wild, you should test your changes in a packaged electron application. To do this, first build budibase from the root directory. +- `redis_data` + - Sessions, email tokens +- `couchdb3_data` + - Global and app databases +- `minio_data` + - App manifest, budibase client, static assets + +### Devlopment Modes + +A combination of environment variables controls the mode that budibase runs in. +Yarn commands can be used to mimic the different modes that budibase can be ran in + +#### Self Hosted +The default mode. A single tenant installation with no usage restrictions. + +To enable this mode, use: ``` -yarn build +yarn mode:self ``` -Now everything is built, you can package up your electron application. +#### Cloud +The cloud mode, with account portal turned off. + +To enable this mode, use: ``` -cd packages/server -yarn build:electron +yarn mode:cloud ``` - -Your new electron application will be stored in `packages/server/dist/`. Open up the executable and make sure everything is working smoothly. +#### Cloud & Account +The cloud mode, with account portal turned on. This is a replica of the mode that runs at https://budibase.app -#### Publishing to NPM - -Once you are happy that your changes work in electron, you can publish all the latest versions of the monorepo packages by running: - +To enable this mode, use: ``` -yarn publishnpm +yarn mode:account ``` +### CI -from your root directory. +#### PR Job -#### CI Release +After your pr is submitted a github action (can be found at `.github/workflows/budibase_ci.yml`) will run to perform some checks against the changes such as linting, build and test. -After NPM has successfully published the budibase packages, a new tag will be pushed to master. This will kick off a github action (can be found at `.github/workflows/release.yml`) this will build and package the electron application for every OS (Windows, Mac, Linux). The binaries will be stored under the new tag on the [budibase releases page](https://github.com/Budibase/budibase/releases). +The job will run when changes are pushed to or targetted at `master` and `develop` +#### Release Develop + +To test changes before a release, a prerelease action (can be found at `.github/workflows/release-develop.yml`) will run to build and release develop versions of npm packages and docker images. On each subsequent commit to develop a new alpha version of npm packages will be created and released. + +For example: + +- `feature1` -> `develop` = `v0.9.160-alpha.1` +- `feature2` -> `develop` = `v0.9.160-alpha.0` + +The job will run when changes are pushed to `develop` +#### Release Job + +To release changes a release job (can be found at `.github/workflows/release.yml`) will run to create final versions of npm packages and docker images. + +Following the example above: + +- `develop` -> `master` = `v0.9.160` + +The job will run when changes are pushed to `master` + +#### Release Self Host Job + +To release the self hosted version of docker images, an additional job (can be found at `.github/workflows/release-selfhost.yml`) must be ran manually. This will releaae docker images to docker hub under the tag `latest` to be picked up by self hosted installations. ### Troubleshooting -Sometimes, things go wrong. This can be due to incompatible updates on the budibase platform. To clear down your development environment and start again: - -``` -rm -rf ~/.budibase -``` -Follow from **Step 3. Install and Build** in the setup guide above. You should have a fresh Budibase installation. - +Sometimes, things go wrong. This can be due to incompatible updates on the budibase platform. To clear down your development environment and start again follow **Step 6. Cleanup**, then proceed from **Step 3. Install and Build** in the setup guide above. You should have a fresh Budibase installation. ### Running tests #### End-to-end Tests diff --git a/package.json b/package.json index 3596ec7800..a3119d0d0e 100644 --- a/package.json +++ b/package.json @@ -46,12 +46,17 @@ "build:docker:production": "lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh $BUDIBASE_RELEASE_VERSION release && cd -", "build:docker:develop": "node scripts/pinVersions && lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh develop && cd -", "release:helm": "./scripts/release_helm_chart.sh", - "multi:enable": "lerna run multi:enable", - "multi:disable": "lerna run multi:disable", - "selfhost:enable": "lerna run selfhost:enable", - "selfhost:disable": "lerna run selfhost:disable", - "localdomain:enable": "lerna run localdomain:enable", - "localdomain:disable": "lerna run localdomain:disable", + "env:multi:enable": "lerna run env:multi:enable", + "env:multi:disable": "lerna run env:multi:disable", + "env:selfhost:enable": "lerna run env:selfhost:enable", + "env:selfhost:disable": "lerna run env:selfhost:disable", + "env:localdomain:enable": "lerna run env:localdomain:enable", + "env:localdomain:disable": "lerna run env:localdomain:disable", + "env:account:enable": "lerna run env:account:enable", + "env:account:disable": "lerna run env:account:disable", + "mode:self": "yarn env:selfhost:enable && yarn env:multi:disable && yarn env:account:disable", + "mode:cloud": "yarn env:selfhost:disable && yarn env:multi:enable && yarn env:account:disable", + "mode:account": "yarn mode:cloud && yarn env:account:enable", "postinstall": "husky install" } } diff --git a/packages/server/package.json b/packages/server/package.json index 1fb9e080e0..f0bc2d8f85 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -24,12 +24,14 @@ "lint": "eslint --fix src/", "lint:fix": "yarn run format && yarn run lint", "initialise": "node scripts/initialise.js", - "multi:enable": "node scripts/multiTenancy.js enable", - "multi:disable": "node scripts/multiTenancy.js disable", - "selfhost:enable": "node scripts/selfhost.js enable", - "selfhost:disable": "node scripts/selfhost.js disable", - "localdomain:enable": "node scripts/localdomain.js enable", - "localdomain:disable": "node scripts/localdomain.js disable" + "env:multi:enable": "node scripts/multiTenancy.js enable", + "env:multi:disable": "node scripts/multiTenancy.js disable", + "env:selfhost:enable": "node scripts/selfhost.js enable", + "env:selfhost:disable": "node scripts/selfhost.js disable", + "env:localdomain:enable": "node scripts/localdomain.js enable", + "env:localdomain:disable": "node scripts/localdomain.js disable", + "env:account:enable": "node scripts/account.js enable", + "env:account:disable": "node scripts/account.js disable" }, "jest": { "preset": "ts-jest", diff --git a/packages/server/scripts/account.js b/packages/server/scripts/account.js new file mode 100644 index 0000000000..69c0a94507 --- /dev/null +++ b/packages/server/scripts/account.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node +const updateDotEnv = require("update-dotenv") + +const arg = process.argv.slice(2)[0] + +updateDotEnv({ + DISABLE_ACCOUNT_PORTAL: arg === "enable" ? "" : "1", +}).then(() => console.log("Updated server!")) diff --git a/packages/worker/package.json b/packages/worker/package.json index 3efafebca8..ff4594f655 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -17,12 +17,14 @@ "dev:stack:init": "node ./scripts/dev/manage.js init", "dev:builder": "npm run dev:stack:init && nodemon src/index.js", "test": "jest --runInBand", - "multi:enable": "node scripts/multiTenancy.js enable", - "multi:disable": "node scripts/multiTenancy.js disable", - "selfhost:enable": "node scripts/selfhost.js enable", - "selfhost:disable": "node scripts/selfhost.js disable", - "localdomain:enable": "node scripts/localdomain.js enable", - "localdomain:disable": "node scripts/localdomain.js disable" + "env:multi:enable": "node scripts/multiTenancy.js enable", + "env:multi:disable": "node scripts/multiTenancy.js disable", + "env:selfhost:enable": "node scripts/selfhost.js enable", + "env:selfhost:disable": "node scripts/selfhost.js disable", + "env:localdomain:enable": "node scripts/localdomain.js enable", + "env:localdomain:disable": "node scripts/localdomain.js disable", + "env:account:enable": "node scripts/account.js enable", + "env:account:disable": "node scripts/account.js disable" }, "author": "Budibase", "license": "AGPL-3.0-or-later", diff --git a/packages/worker/scripts/account.js b/packages/worker/scripts/account.js new file mode 100644 index 0000000000..bd96f98256 --- /dev/null +++ b/packages/worker/scripts/account.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node +const updateDotEnv = require("update-dotenv") + +const arg = process.argv.slice(2)[0] + +updateDotEnv({ + DISABLE_ACCOUNT_PORTAL: arg === "enable" ? "" : "1", +}).then(() => console.log("Updated worker!")) From be3feaa01195f5276384862afd489f733d4a21d1 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Fri, 8 Oct 2021 13:22:08 +0100 Subject: [PATCH 12/52] Fix linting --- packages/builder/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index c8e01435aa..f179a24729 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -5,7 +5,7 @@ // *********************************************** // -Cypress.on('uncaught:exception', (err, runnable) => { +Cypress.on("uncaught:exception", () => { return false }) From 7a26f3769d54a14a202d8f36964844df9d7fb401 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 8 Oct 2021 18:21:40 +0100 Subject: [PATCH 13/52] Fixing some issues with cloud export/import, removing the ability to export and import your users as this was dangerous and didn't really work with passwords/SSO. --- .../admin/_components/ImportAppsModal.svelte | 5 ++- .../src/pages/builder/admin/index.svelte | 10 ++++- packages/builder/src/stores/portal/admin.js | 13 ++++++ .../server/src/api/controllers/application.js | 1 + packages/server/src/api/controllers/cloud.js | 41 ++++++++++++++----- packages/server/src/api/routes/cloud.js | 1 + .../worker/src/middleware/cloudRestricted.js | 2 +- 7 files changed, 58 insertions(+), 15 deletions(-) diff --git a/packages/builder/src/pages/builder/admin/_components/ImportAppsModal.svelte b/packages/builder/src/pages/builder/admin/_components/ImportAppsModal.svelte index 633147e910..de29e11301 100644 --- a/packages/builder/src/pages/builder/admin/_components/ImportAppsModal.svelte +++ b/packages/builder/src/pages/builder/admin/_components/ImportAppsModal.svelte @@ -1,6 +1,7 @@ @@ -73,7 +81,7 @@ > Change organisation - {:else if !cloud} + {:else if !cloud && !imported} { diff --git a/packages/builder/src/stores/portal/admin.js b/packages/builder/src/stores/portal/admin.js index ebe8294060..b9ed0f04b8 100644 --- a/packages/builder/src/stores/portal/admin.js +++ b/packages/builder/src/stores/portal/admin.js @@ -9,6 +9,7 @@ export function createAdminStore() { cloud: false, disableAccountPortal: false, accountPortalUrl: "", + importComplete: false, onboardingProgress: 0, checklist: { apps: { checked: false }, @@ -45,6 +46,17 @@ export function createAdminStore() { } } + async function checkImportComplete() { + const response = await api.get(`/api/cloud/import/complete`) + if (response.status === 200) { + const json = await response.json() + admin.update(store => { + store.importComplete = json ? json.imported : false + return store + }) + } + } + async function getEnvironment() { let multiTenancyEnabled = false let cloud = false @@ -79,6 +91,7 @@ export function createAdminStore() { return { subscribe: admin.subscribe, init, + checkImportComplete, unload, } } diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js index 6608ba0cac..e3aac8bd63 100644 --- a/packages/server/src/api/controllers/application.js +++ b/packages/server/src/api/controllers/application.js @@ -86,6 +86,7 @@ async function getAppUrlIfNotInUse(ctx) { if ( url && deployedApps[url] != null && + ctx.params != null && deployedApps[url].appId !== ctx.params.appId ) { ctx.throw(400, "App name/URL is already in use.") diff --git a/packages/server/src/api/controllers/cloud.js b/packages/server/src/api/controllers/cloud.js index aac79bb9dd..a0057d68e4 100644 --- a/packages/server/src/api/controllers/cloud.js +++ b/packages/server/src/api/controllers/cloud.js @@ -28,15 +28,18 @@ exports.exportApps = async ctx => { ctx.throw(400, "Exporting only allowed in multi-tenant cloud environments.") } const apps = await getAllApps(CouchDB, { all: true }) - const globalDBString = await exportDB(getGlobalDBName()) + const globalDBString = await exportDB(getGlobalDBName(), { + filter: doc => !doc._id.startsWith(DocumentTypes.USER), + }) let allDBs = { global: globalDBString, } for (let app of apps) { + const appId = app.appId || app._id // only export the dev apps as they will be the latest, the user can republish the apps // in their self hosted environment - if (isDevAppID(app._id)) { - allDBs[app.name] = await exportDB(app._id) + if (isDevAppID(appId)) { + allDBs[app.name] = await exportDB(appId) } } const filename = `cloud-export-${new Date().getTime()}.txt` @@ -53,16 +56,26 @@ async function getAllDocType(db, docType) { return response.rows.map(row => row.doc) } +async function hasBeenImported() { + if (!env.SELF_HOSTED || env.MULTI_TENANCY) { + return true + } + const apps = await getAllApps(CouchDB, { all: true }) + return apps.length !== 0 +} + +exports.hasBeenImported = async ctx => { + ctx.body = { + imported: await hasBeenImported(), + } +} + exports.importApps = async ctx => { if (!env.SELF_HOSTED || env.MULTI_TENANCY) { ctx.throw(400, "Importing only allowed in self hosted environments.") } - const apps = await getAllApps(CouchDB, { all: true }) - if ( - apps.length !== 0 || - !ctx.request.files || - !ctx.request.files.importFile - ) { + const beenImported = await hasBeenImported() + if (beenImported || !ctx.request.files || !ctx.request.files.importFile) { ctx.throw( 400, "Import file is required and environment must be fresh to import apps." @@ -80,11 +93,17 @@ exports.importApps = async ctx => { for (let [appName, appImport] of Object.entries(dbs)) { await createApp(appName, appImport) } - // once apps are created clean up the global db + + // if there are any users make sure to remove them let users = await getAllDocType(globalDb, DocumentTypes.USER) + let userDeletionPromises = [] for (let user of users) { - delete user.tenantId + userDeletionPromises.push(globalDb.remove(user._id, user._rev)) } + if (userDeletionPromises.length > 0) { + await Promise.all(userDeletionPromises) + } + await globalDb.bulkDocs(users) ctx.body = { message: "Apps successfully imported.", diff --git a/packages/server/src/api/routes/cloud.js b/packages/server/src/api/routes/cloud.js index 214473f43f..02b501c399 100644 --- a/packages/server/src/api/routes/cloud.js +++ b/packages/server/src/api/routes/cloud.js @@ -9,5 +9,6 @@ router .get("/api/cloud/export", authorized(BUILDER), controller.exportApps) // has to be public, only run if apps don't exist .post("/api/cloud/import", controller.importApps) + .get("/api/cloud/import/complete", controller.hasBeenImported) module.exports = router diff --git a/packages/worker/src/middleware/cloudRestricted.js b/packages/worker/src/middleware/cloudRestricted.js index 10cdeaebd4..b29093f77e 100644 --- a/packages/worker/src/middleware/cloudRestricted.js +++ b/packages/worker/src/middleware/cloudRestricted.js @@ -6,7 +6,7 @@ const { Headers } = require("@budibase/auth").constants * Ensure that the correct API key has been supplied. */ module.exports = async (ctx, next) => { - if (!env.SELF_HOSTED) { + if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { const apiKey = ctx.request.headers[Headers.API_KEY] if (apiKey !== env.INTERNAL_API_KEY) { ctx.throw(403, "Unauthorized") From 5702eb464b845d0bae71988ae23bf3a4f2591cac Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 11 Oct 2021 11:10:26 +0100 Subject: [PATCH 14/52] fix issue where automation block was not being added in the correct order --- .../AutomationBuilder/FlowChart/ActionModal.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte index acb945a96a..b076a8da86 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte @@ -4,10 +4,11 @@ import { externalActions } from "./ExternalActions" export let blockIdx + export let blockComplete + let selectedAction let actionVal let actions = Object.entries($automationStore.blockDefinitions.ACTION) - export let blockComplete const external = actions.reduce((acc, elm) => { const [k, v] = elm @@ -36,10 +37,9 @@ actionVal.stepId, actionVal ) - automationStore.actions.addBlockToAutomation(newBlock) + automationStore.actions.addBlockToAutomation(newBlock, blockIdx + 1) await automationStore.actions.save( - $automationStore.selectedAutomation?.automation, - blockIdx + $automationStore.selectedAutomation?.automation ) } From 9ea1774bcf4719c42553dae0a64499b11a5d2ef3 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Mon, 11 Oct 2021 11:14:44 +0100 Subject: [PATCH 15/52] Don't perform account deletion check when self hosted --- packages/builder/cypress/support/commands.js | 2 +- .../worker/src/api/controllers/global/users.js | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index c8e01435aa..f179a24729 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -5,7 +5,7 @@ // *********************************************** // -Cypress.on('uncaught:exception', (err, runnable) => { +Cypress.on("uncaught:exception", () => { return false }) diff --git a/packages/worker/src/api/controllers/global/users.js b/packages/worker/src/api/controllers/global/users.js index 38a814f465..1c3328ce61 100644 --- a/packages/worker/src/api/controllers/global/users.js +++ b/packages/worker/src/api/controllers/global/users.js @@ -111,14 +111,16 @@ exports.destroy = async ctx => { const db = getGlobalDB() const dbUser = await db.get(ctx.params.id) - // root account holder can't be deleted from inside budibase - const email = dbUser.email - const account = await accounts.getAccount(email) - if (account) { - if (email === ctx.user.email) { - ctx.throw(400, 'Please visit "Account" to delete this user') - } else { - ctx.throw(400, "Account holder cannot be deleted") + if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { + // root account holder can't be deleted from inside budibase + const email = dbUser.email + const account = await accounts.getAccount(email) + if (account) { + if (email === ctx.user.email) { + ctx.throw(400, 'Please visit "Account" to delete this user') + } else { + ctx.throw(400, "Account holder cannot be deleted") + } } } From 8744e50ded708ea0aeb2385f4f7edacc4cd01e76 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 11 Oct 2021 11:33:54 +0100 Subject: [PATCH 16/52] fix lint --- packages/builder/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index c8e01435aa..f179a24729 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -5,7 +5,7 @@ // *********************************************** // -Cypress.on('uncaught:exception', (err, runnable) => { +Cypress.on("uncaught:exception", () => { return false }) From eba9bd79f66a0b144620dc8513f62f3b138dfbb0 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Mon, 11 Oct 2021 11:35:07 +0100 Subject: [PATCH 17/52] enable 'add action' button when inputs completed --- .../automation/AutomationBuilder/FlowChart/FlowItem.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 0c0b79c3de..e69f5ec204 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -151,7 +151,7 @@ > {/if} {/if} diff --git a/packages/server/src/automations/triggerInfo/app.js b/packages/server/src/automations/triggerInfo/app.js index 40d1531fa0..b1b07e9d5b 100644 --- a/packages/server/src/automations/triggerInfo/app.js +++ b/packages/server/src/automations/triggerInfo/app.js @@ -22,6 +22,7 @@ exports.definition = { fields: { type: "object", description: "Fields submitted from the app frontend", + customType: "triggerSchema", }, }, required: ["fields"], diff --git a/packages/server/src/automations/triggers.js b/packages/server/src/automations/triggers.js index ae98f0e73a..f774c23123 100644 --- a/packages/server/src/automations/triggers.js +++ b/packages/server/src/automations/triggers.js @@ -81,16 +81,19 @@ exports.externalTrigger = async function ( params, { getResponses } = {} ) { - if (automation.definition != null && automation.definition.trigger != null) { - if (automation.definition.trigger.stepId === "APP") { - // values are likely to be submitted as strings, so we shall convert to correct type - const coercedFields = {} - const fields = automation.definition.trigger.inputs.fields - for (let key of Object.keys(fields)) { - coercedFields[key] = coerce(params.fields[key], fields[key]) - } - params.fields = coercedFields + if ( + automation.definition != null && + automation.definition.trigger != null && + automation.definition.trigger.stepId === definitions.APP.stepId && + !checkTestFlag(automation._id) + ) { + // values are likely to be submitted as strings, so we shall convert to correct type + const coercedFields = {} + const fields = automation.definition.trigger.inputs.fields + for (let key of Object.keys(fields)) { + coercedFields[key] = coerce(params.fields[key], fields[key]) } + params.fields = coercedFields } const data = { automation, event: params } if (getResponses) { From 8b0d0fb13b87c447c02d742b93a9ac81e2664700 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 11 Oct 2021 21:15:06 +0000 Subject: [PATCH 26/52] v0.9.160-alpha.3 --- lerna.json | 2 +- packages/auth/package.json | 2 +- packages/bbui/package.json | 2 +- packages/builder/package.json | 8 ++++---- packages/cli/package.json | 2 +- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/string-templates/package.json | 2 +- packages/worker/package.json | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 9d1df463c9..31a9b4f058 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/auth/package.json b/packages/auth/package.json index 8a902fc891..fe4e4bf377 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 9e1d4ac1d3..3e8cebb07e 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": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index 475bb5c757..4929cf085e 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.160-alpha.2", - "@budibase/client": "^0.9.160-alpha.2", + "@budibase/bbui": "^0.9.160-alpha.3", + "@budibase/client": "^0.9.160-alpha.3", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.160-alpha.2", + "@budibase/string-templates": "^0.9.160-alpha.3", "@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 992111ebe2..ea0b9bfd6f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "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 a72440e08f..368c362860 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "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": "^0.9.160-alpha.2", + "@budibase/bbui": "^0.9.160-alpha.3", "@budibase/standard-components": "^0.9.139", - "@budibase/string-templates": "^0.9.160-alpha.2", + "@budibase/string-templates": "^0.9.160-alpha.3", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" diff --git a/packages/server/package.json b/packages/server/package.json index 8c5153c2bd..3c1ce810cd 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "description": "Budibase Web Server", "main": "src/index.js", "repository": { @@ -66,9 +66,9 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160-alpha.2", - "@budibase/client": "^0.9.160-alpha.2", - "@budibase/string-templates": "^0.9.160-alpha.2", + "@budibase/auth": "^0.9.160-alpha.3", + "@budibase/client": "^0.9.160-alpha.3", + "@budibase/string-templates": "^0.9.160-alpha.3", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index bb6dda9164..28d2dc9196 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "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 75feec113e..6bce5e864e 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "0.9.160-alpha.2", + "version": "0.9.160-alpha.3", "description": "Budibase background service", "main": "src/index.js", "repository": { @@ -27,8 +27,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160-alpha.2", - "@budibase/string-templates": "^0.9.160-alpha.2", + "@budibase/auth": "^0.9.160-alpha.3", + "@budibase/string-templates": "^0.9.160-alpha.3", "@koa/router": "^8.0.0", "@techpass/passport-openidconnect": "^0.3.0", "aws-sdk": "^2.811.0", From e479ced4c88291dc574521ad1b321968084a1010 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 12 Oct 2021 11:00:49 +0100 Subject: [PATCH 27/52] fix webhook issue in automations --- .../builderStore/store/automation/Automation.js | 2 +- .../FlowChart/TestDataModal.svelte | 17 ++++++++++------- .../SetupPanel/AutomationBlockSetup.svelte | 9 +++++++++ .../automation/Shared/CreateWebhookModal.svelte | 2 -- packages/server/src/automations/triggers.js | 1 + 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/builder/src/builderStore/store/automation/Automation.js b/packages/builder/src/builderStore/store/automation/Automation.js index 49928c69a9..af0c03cb5a 100644 --- a/packages/builder/src/builderStore/store/automation/Automation.js +++ b/packages/builder/src/builderStore/store/automation/Automation.js @@ -14,7 +14,7 @@ export default class Automation { } addTestData(data) { - this.automation.testData = data + this.automation.testData = { ...this.automation.testData, ...data } } addBlock(block, idx) { diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte index 8caba9d351..3c75c9963d 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/TestDataModal.svelte @@ -5,20 +5,24 @@ import { cloneDeep } from "lodash/fp" let failedParse = null + let trigger = {} + let schemaProperties = {} + // clone the trigger so we're not mutating the reference - let trigger = cloneDeep( + $: trigger = cloneDeep( $automationStore.selectedAutomation.automation.definition.trigger ) - let schemaProperties = Object.entries(trigger.schema.outputs.properties || {}) + + // get the outputs so we can define the fields + $: schemaProperties = Object.entries(trigger?.schema?.outputs?.properties) if (!$automationStore.selectedAutomation.automation.testData) { $automationStore.selectedAutomation.automation.testData = {} } - // get the outputs so we can define the fields - // check to see if there is existing test data in the store - $: testData = $automationStore.selectedAutomation.automation.testData + $: testData = $automationStore.selectedAutomation.automation.testData || {} + // Check the schema to see if required fields have been entered $: isError = !trigger.schema.outputs.required.every( required => testData[required] @@ -41,7 +45,6 @@ showConfirmButton={true} disabled={isError} onConfirm={() => { - automationStore.actions.addTestDataToAutomation(testData) automationStore.actions.test( $automationStore.selectedAutomation?.automation, testData @@ -53,7 +56,7 @@ >
import { Icon } from "@budibase/bbui" import { automationStore } from "builderStore" - import { database } from "stores/backend" import WebhookDisplay from "./WebhookDisplay.svelte" import { ModalContent } from "@budibase/bbui" import { onMount, onDestroy } from "svelte" @@ -12,7 +11,6 @@ let schemaURL let propCount = 0 - $: instanceId = $database._id $: automation = $automationStore.selectedAutomation?.automation onMount(async () => { diff --git a/packages/server/src/automations/triggers.js b/packages/server/src/automations/triggers.js index f774c23123..e6c722ce3e 100644 --- a/packages/server/src/automations/triggers.js +++ b/packages/server/src/automations/triggers.js @@ -85,6 +85,7 @@ exports.externalTrigger = async function ( automation.definition != null && automation.definition.trigger != null && automation.definition.trigger.stepId === definitions.APP.stepId && + automation.definition.trigger.stepId === "APP" && !checkTestFlag(automation._id) ) { // values are likely to be submitted as strings, so we shall convert to correct type From 2d4bb78afc4a5a1735cf1093ee50935357bfb1e9 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 12 Oct 2021 12:20:40 +0100 Subject: [PATCH 28/52] surface schema for user in json --- .../automation/SetupPanel/RowSelector.svelte | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte index 1d54c86b4a..7bd83069e6 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte @@ -11,10 +11,22 @@ export let value export let bindings - $: table = $tables.list.find(table => table._id === value?.tableId) - $: schemaFields = Object.entries(table?.schema ?? {}) + let table + let schemaFields + + $: { + table = $tables.list.find(table => table._id === value?.tableId) + schemaFields = Object.entries(table?.schema ?? {}) + // surface the schema so the user can see it in the json + schemaFields.map(([, schema]) => { + if (!schema.autocolumn && !value[schema.name]) { + value[schema.name] = "" + } + }) + } + const onChangeTable = e => { - value = { tableId: e.detail } + value["tableId"] = e.detail dispatch("change", value) } From 5948aab953543e2248da9b0ffae501550d34dab5 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Tue, 12 Oct 2021 13:02:08 +0100 Subject: [PATCH 29/52] Cypress fix: 'RoverUpdated' -> 'Updated' in createTable.spec.js --- packages/builder/cypress/integration/createTable.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/cypress/integration/createTable.spec.js b/packages/builder/cypress/integration/createTable.spec.js index ccb9ae7929..07a3b8ac96 100644 --- a/packages/builder/cypress/integration/createTable.spec.js +++ b/packages/builder/cypress/integration/createTable.spec.js @@ -35,7 +35,7 @@ context("Create a Table", () => { cy.contains("button", "Edit").click({ force: true }) cy.wait(1000) cy.get(".spectrum-Modal input").clear() - cy.get(".spectrum-Modal input").type("RoverUpdated") + cy.get(".spectrum-Modal input").type("Updated") cy.contains("Save").click() cy.contains("Updated").should("have.text", "Updated") }) From bf31ff2848a52cb508a7238d9bf7aea6794200d8 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 12 Oct 2021 12:37:54 +0000 Subject: [PATCH 30/52] v0.9.160-alpha.4 --- lerna.json | 2 +- packages/auth/package.json | 2 +- packages/bbui/package.json | 2 +- packages/builder/package.json | 8 ++++---- packages/cli/package.json | 2 +- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/string-templates/package.json | 2 +- packages/worker/package.json | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 31a9b4f058..a571b4d473 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/auth/package.json b/packages/auth/package.json index fe4e4bf377..6f27ea3163 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 3e8cebb07e..e9fe276e40 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": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index 4929cf085e..aa8d73db09 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.160-alpha.3", - "@budibase/client": "^0.9.160-alpha.3", + "@budibase/bbui": "^0.9.160-alpha.4", + "@budibase/client": "^0.9.160-alpha.4", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.160-alpha.3", + "@budibase/string-templates": "^0.9.160-alpha.4", "@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 ea0b9bfd6f..2e959c7821 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "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 368c362860..554fc297d5 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "0.9.160-alpha.3", + "version": "0.9.160-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": "^0.9.160-alpha.3", + "@budibase/bbui": "^0.9.160-alpha.4", "@budibase/standard-components": "^0.9.139", - "@budibase/string-templates": "^0.9.160-alpha.3", + "@budibase/string-templates": "^0.9.160-alpha.4", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" diff --git a/packages/server/package.json b/packages/server/package.json index 774fe31ece..eb1c56cd2a 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "description": "Budibase Web Server", "main": "src/index.js", "repository": { @@ -68,9 +68,9 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160-alpha.3", - "@budibase/client": "^0.9.160-alpha.3", - "@budibase/string-templates": "^0.9.160-alpha.3", + "@budibase/auth": "^0.9.160-alpha.4", + "@budibase/client": "^0.9.160-alpha.4", + "@budibase/string-templates": "^0.9.160-alpha.4", "@elastic/elasticsearch": "7.10.0", "@koa/router": "8.0.0", "@sendgrid/mail": "7.1.1", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 28d2dc9196..03187b9ece 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "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 96f7974d25..a6d977e187 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "0.9.160-alpha.3", + "version": "0.9.160-alpha.4", "description": "Budibase background service", "main": "src/index.js", "repository": { @@ -29,8 +29,8 @@ "author": "Budibase", "license": "AGPL-3.0-or-later", "dependencies": { - "@budibase/auth": "^0.9.160-alpha.3", - "@budibase/string-templates": "^0.9.160-alpha.3", + "@budibase/auth": "^0.9.160-alpha.4", + "@budibase/string-templates": "^0.9.160-alpha.4", "@koa/router": "^8.0.0", "@techpass/passport-openidconnect": "^0.3.0", "aws-sdk": "^2.811.0", From 0f153c36667748c4266bab3ab66d638911e907c9 Mon Sep 17 00:00:00 2001 From: Peter Clement Date: Tue, 12 Oct 2021 14:13:33 +0100 Subject: [PATCH 31/52] add relationship selector to automation blocks --- .../src/components/automation/SetupPanel/RowSelector.svelte | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte index 7bd83069e6..3821157e51 100644 --- a/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte +++ b/packages/builder/src/components/automation/SetupPanel/RowSelector.svelte @@ -5,6 +5,7 @@ import AutomationBindingPanel from "../../common/bindings/ServerBindingPanel.svelte" import { createEventDispatcher } from "svelte" import ModalBindableInput from "components/common/bindings/ModalBindableInput.svelte" + import LinkedRowSelector from "components/common/LinkedRowSelector.svelte" import { automationStore } from "builderStore" const dispatch = createEventDispatcher() @@ -42,6 +43,8 @@ function schemaHasOptions(schema) { return !!schema.constraints?.inclusion?.length } + + $: console.log($tables.list) - import { Label, Input, Layout, Toggle, Button } from "@budibase/bbui" + import { + Label, + Input, + Layout, + Toggle, + Button, + TextArea, + } from "@budibase/bbui" import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte" import { capitalise } from "helpers" export let integration export let schema + let addButton @@ -29,6 +37,15 @@
+ {:else if schema[configKey].type === "longForm"} +
+ +