From 051f997047b4e5f65c63ea37f1e3c66e6859c4cf Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 4 Mar 2024 09:34:58 +0000 Subject: [PATCH 01/50] Add auto-refresh setting to data providers and all blocks --- packages/client/manifest.json | 168 ++++++++++++++++++ .../src/components/app/DataProvider.svelte | 23 +-- .../src/components/app/GridBlock.svelte | 2 + .../components/app/blocks/CardsBlock.svelte | 2 + .../components/app/blocks/ChartBlock.svelte | 2 + .../app/blocks/RepeaterBlock.svelte | 2 + .../components/app/blocks/RowExplorer.svelte | 5 +- .../components/app/blocks/TableBlock.svelte | 2 + 8 files changed, 193 insertions(+), 13 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 43b75ebe26..1b24136019 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4571,6 +4571,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "filter", "label": "Filtering", @@ -4937,6 +4965,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "text", "label": "Title", @@ -5404,6 +5460,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "columns", "label": "Columns", @@ -5690,6 +5774,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "searchfield", "label": "Search columns", @@ -5867,6 +5979,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "filter", "label": "Filtering", @@ -6571,6 +6711,34 @@ "key": "table", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "refresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "filter", "label": "Filtering", diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index 1c6dfb32b7..c841c07ac4 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -1,5 +1,5 @@
diff --git a/packages/client/src/components/app/GridBlock.svelte b/packages/client/src/components/app/GridBlock.svelte index 0a343cac51..fa0e66596c 100644 --- a/packages/client/src/components/app/GridBlock.svelte +++ b/packages/client/src/components/app/GridBlock.svelte @@ -18,6 +18,7 @@ export let columns = null export let onRowClick = null export let buttons = null + export let repeat = null const context = getContext("context") const component = getContext("component") @@ -108,6 +109,7 @@ {fixedRowHeight} {columnWhitelist} {schemaOverrides} + {repeat} canAddRows={allowAddRows} canEditRows={allowEditRows} canDeleteRows={allowDeleteRows} diff --git a/packages/client/src/components/app/blocks/CardsBlock.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte index 008fa7e730..baa31901ea 100644 --- a/packages/client/src/components/app/blocks/CardsBlock.svelte +++ b/packages/client/src/components/app/blocks/CardsBlock.svelte @@ -30,6 +30,7 @@ export let cardButtonOnClick export let linkColumn export let noRowsMessage + export let repeat const { fetchDatasourceSchema } = getContext("sdk") @@ -171,6 +172,7 @@ sortOrder, paginate, limit, + repeat, }} order={1} > diff --git a/packages/client/src/components/app/blocks/ChartBlock.svelte b/packages/client/src/components/app/blocks/ChartBlock.svelte index 1bbc69ce63..416c843e98 100644 --- a/packages/client/src/components/app/blocks/ChartBlock.svelte +++ b/packages/client/src/components/app/blocks/ChartBlock.svelte @@ -8,6 +8,7 @@ export let sortColumn export let sortOrder export let limit + export let repeat // Block export let chartTitle @@ -65,6 +66,7 @@ sortColumn, sortOrder, limit, + repeat, }} > {#if dataProviderId && chartType} diff --git a/packages/client/src/components/app/blocks/RepeaterBlock.svelte b/packages/client/src/components/app/blocks/RepeaterBlock.svelte index 30fbdddcdc..ffd34596ed 100644 --- a/packages/client/src/components/app/blocks/RepeaterBlock.svelte +++ b/packages/client/src/components/app/blocks/RepeaterBlock.svelte @@ -16,6 +16,7 @@ export let hAlign export let vAlign export let gap + export let repeat const component = getContext("component") @@ -34,6 +35,7 @@ sortOrder, limit, paginate, + repeat, }} > {#if $component.empty} diff --git a/packages/client/src/components/app/blocks/RowExplorer.svelte b/packages/client/src/components/app/blocks/RowExplorer.svelte index 8fadcb5006..72fdf810db 100644 --- a/packages/client/src/components/app/blocks/RowExplorer.svelte +++ b/packages/client/src/components/app/blocks/RowExplorer.svelte @@ -6,17 +6,15 @@ export let dataSource export let height - export let cardTitle export let cardSubtitle export let cardDescription export let cardImageURL export let cardSearchField - export let detailFields export let detailTitle - export let noRowsMessage + export let repeat const stateKey = generate() @@ -56,6 +54,7 @@ noValue: false, }, ], + repeat, }} styles={{ custom: ` diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 7c58f90508..2a149c2013 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -32,6 +32,7 @@ export let sidePanelSaveLabel export let sidePanelDeleteLabel export let notificationOverride + export let repeat const { fetchDatasourceSchema, API } = getContext("sdk") const component = getContext("component") @@ -230,6 +231,7 @@ sortOrder, paginate, limit: rowCount, + repeat, }} context="provider" order={1} From 3a002b3c3db078679a482305bae7a669e906c7bb Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 4 Mar 2024 09:46:10 +0000 Subject: [PATCH 02/50] Rename autorefresh setting and ensure functional in all blocks + DP --- packages/client/manifest.json | 66 +++++++++---------- .../src/components/app/DataProvider.svelte | 10 +-- .../components/app/blocks/CardsBlock.svelte | 4 +- .../components/app/blocks/ChartBlock.svelte | 4 +- .../app/blocks/RepeaterBlock.svelte | 4 +- .../components/app/blocks/RowExplorer.svelte | 4 +- .../components/app/blocks/TableBlock.svelte | 4 +- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 1b24136019..d8cfe1d489 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4574,7 +4574,7 @@ { "type": "select", "label": "Auto-refresh", - "key": "refresh", + "key": "autoRefresh", "placeholder": "Never", "options": [ { @@ -4968,7 +4968,7 @@ { "type": "select", "label": "Auto-refresh", - "key": "refresh", + "key": "autoRefresh", "placeholder": "Never", "options": [ { @@ -5463,7 +5463,7 @@ { "type": "select", "label": "Auto-refresh", - "key": "refresh", + "key": "autoRefresh", "placeholder": "Never", "options": [ { @@ -5777,7 +5777,7 @@ { "type": "select", "label": "Auto-refresh", - "key": "refresh", + "key": "autoRefresh", "placeholder": "Never", "options": [ { @@ -5982,7 +5982,7 @@ { "type": "select", "label": "Auto-refresh", - "key": "refresh", + "key": "autoRefresh", "placeholder": "Never", "options": [ { @@ -6603,6 +6603,34 @@ "key": "dataSource", "required": true }, + { + "type": "select", + "label": "Auto-refresh", + "key": "autoRefresh", + "placeholder": "Never", + "options": [ + { + "label": "10 seconds", + "value": 10 + }, + { + "label": "30 seconds", + "value": 30 + }, + { + "label": "1 minute", + "value": 60 + }, + { + "label": "5 minutes", + "value": 300 + }, + { + "label": "10 minutes", + "value": 600 + } + ] + }, { "type": "text", "label": "Height", @@ -6711,34 +6739,6 @@ "key": "table", "required": true }, - { - "type": "select", - "label": "Auto-refresh", - "key": "refresh", - "placeholder": "Never", - "options": [ - { - "label": "10 seconds", - "value": 10 - }, - { - "label": "30 seconds", - "value": 30 - }, - { - "label": "1 minute", - "value": 60 - }, - { - "label": "5 minutes", - "value": 300 - }, - { - "label": "10 minutes", - "value": 600 - } - ] - }, { "type": "filter", "label": "Filtering", diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index c841c07ac4..8f3c31c130 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -9,7 +9,7 @@ export let sortOrder export let limit export let paginate - export let refresh + export let autoRefresh const { styleable, Provider, ActionTypes, API } = getContext("sdk") const component = getContext("component") @@ -30,7 +30,7 @@ paginate, }) $: schema = sanitizeSchema($fetch.schema) - $: setUpAutoRefresh(refresh) + $: setUpAutoRefresh(autoRefresh) $: actions = [ { type: ActionTypes.RefreshDatasource, @@ -137,10 +137,10 @@ return extendedQuery } - const setUpAutoRefresh = refresh => { + const setUpAutoRefresh = autoRefresh => { clearInterval(interval) - if (refresh) { - interval = setInterval(fetch.refresh, Math.max(10000, refresh * 1000)) + if (autoRefresh) { + interval = setInterval(fetch.refresh, Math.max(10000, autoRefresh * 1000)) } } diff --git a/packages/client/src/components/app/blocks/CardsBlock.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte index baa31901ea..2457896ca2 100644 --- a/packages/client/src/components/app/blocks/CardsBlock.svelte +++ b/packages/client/src/components/app/blocks/CardsBlock.svelte @@ -30,7 +30,7 @@ export let cardButtonOnClick export let linkColumn export let noRowsMessage - export let repeat + export let autoRefresh const { fetchDatasourceSchema } = getContext("sdk") @@ -172,7 +172,7 @@ sortOrder, paginate, limit, - repeat, + autoRefresh, }} order={1} > diff --git a/packages/client/src/components/app/blocks/ChartBlock.svelte b/packages/client/src/components/app/blocks/ChartBlock.svelte index 416c843e98..2767c44b8e 100644 --- a/packages/client/src/components/app/blocks/ChartBlock.svelte +++ b/packages/client/src/components/app/blocks/ChartBlock.svelte @@ -8,7 +8,7 @@ export let sortColumn export let sortOrder export let limit - export let repeat + export let autoRefresh // Block export let chartTitle @@ -66,7 +66,7 @@ sortColumn, sortOrder, limit, - repeat, + autoRefresh, }} > {#if dataProviderId && chartType} diff --git a/packages/client/src/components/app/blocks/RepeaterBlock.svelte b/packages/client/src/components/app/blocks/RepeaterBlock.svelte index ffd34596ed..d0bc04e2fd 100644 --- a/packages/client/src/components/app/blocks/RepeaterBlock.svelte +++ b/packages/client/src/components/app/blocks/RepeaterBlock.svelte @@ -16,7 +16,7 @@ export let hAlign export let vAlign export let gap - export let repeat + export let autoRefresh const component = getContext("component") @@ -35,7 +35,7 @@ sortOrder, limit, paginate, - repeat, + autoRefresh, }} > {#if $component.empty} diff --git a/packages/client/src/components/app/blocks/RowExplorer.svelte b/packages/client/src/components/app/blocks/RowExplorer.svelte index 72fdf810db..292f3c4a76 100644 --- a/packages/client/src/components/app/blocks/RowExplorer.svelte +++ b/packages/client/src/components/app/blocks/RowExplorer.svelte @@ -14,7 +14,7 @@ export let detailFields export let detailTitle export let noRowsMessage - export let repeat + export let autoRefresh const stateKey = generate() @@ -54,7 +54,7 @@ noValue: false, }, ], - repeat, + autoRefresh, }} styles={{ custom: ` diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 2a149c2013..6b1f34920a 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -32,7 +32,7 @@ export let sidePanelSaveLabel export let sidePanelDeleteLabel export let notificationOverride - export let repeat + export let autoRefresh const { fetchDatasourceSchema, API } = getContext("sdk") const component = getContext("component") @@ -231,7 +231,7 @@ sortOrder, paginate, limit: rowCount, - repeat, + autoRefresh, }} context="provider" order={1} From d056b51c726eb0909f092e811eb73c2f8ba2e584 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 4 Mar 2024 09:58:40 +0000 Subject: [PATCH 03/50] Lint --- packages/client/src/components/app/DataProvider.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index 8f3c31c130..dc0c40f55c 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -1,5 +1,5 @@ + +
+ + {title} + +
+ + diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte index c7f8094084..9ff2a764b7 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte @@ -183,6 +183,7 @@ props={{ // Generic settings placeholder: setting.placeholder || null, + license: setting.license, // Select settings options: setting.options || [], diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 4ccc1cbd8d..6f8e450d6e 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4614,6 +4614,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { From 4214b7e7f1a865454073f3cdb23875f630745671 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 4 Apr 2024 16:26:48 +0100 Subject: [PATCH 26/50] Paywall all auto-refresh settings --- packages/client/manifest.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 6f8e450d6e..a056f59cc7 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -5010,6 +5010,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { @@ -5506,6 +5507,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { @@ -5820,6 +5822,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { @@ -6025,6 +6028,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { @@ -6649,6 +6653,7 @@ "type": "select", "label": "Auto-refresh", "key": "autoRefresh", + "license": "premium", "placeholder": "Never", "options": [ { From f80a207d289220be4c48550331741201a32d6235 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 4 Apr 2024 17:39:35 +0100 Subject: [PATCH 27/50] Working towards running table.spec.ts against external datasources. --- .../server/src/api/routes/tests/table.spec.ts | 374 ++++++++---------- .../server/src/tests/utilities/api/table.ts | 26 ++ .../server/src/tests/utilities/structures.ts | 29 +- 3 files changed, 206 insertions(+), 223 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 1038808fe1..6e72236cbb 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -1,6 +1,7 @@ import { context, events } from "@budibase/backend-core" import { AutoFieldSubType, + Datasource, FieldSubtype, FieldType, INTERNAL_TABLE_SOURCE_ID, @@ -21,23 +22,35 @@ import * as uuid from "uuid" import tk from "timekeeper" import { generator, mocks } from "@budibase/backend-core/tests" -import { TableToBuild } from "../../../tests/utilities/TestConfiguration" +import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" +import { tableForDatasource } from "../../../tests/utilities/structures" tk.freeze(mocks.date.MOCK_DATE) const { basicTable } = setup.structures const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ -describe("/tables", () => { - let request = setup.getRequest() +describe.each([ + ["internal", undefined], + [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], + // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], + // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], + // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], +])("/tables (%s)", (_, dsProvider) => { + let isInternal: boolean + let datasource: Datasource | undefined let config = setup.getConfig() - let appId: string afterAll(setup.afterAll) beforeAll(async () => { - const app = await config.init() - appId = app.appId + await config.init() + if (dsProvider) { + datasource = await config.api.datasource.create(await dsProvider) + isInternal = false + } else { + isInternal = true + } }) describe("create", () => { @@ -45,33 +58,15 @@ describe("/tables", () => { jest.clearAllMocks() }) - const createTable = (table?: Table) => { - if (!table) { - table = basicTable() - } - return request - .post(`/api/tables`) - .send(table) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - } - it("returns a success message when the table is successfully created", async () => { - const res = await createTable() - - expect((res as any).res.statusMessage).toEqual( - "Table TestTable saved successfully." - ) - expect(res.body.name).toEqual("TestTable") + const table = await config.api.table.save(basicTable(datasource)) + expect(table.name).toEqual("TestTable") expect(events.table.created).toHaveBeenCalledTimes(1) - expect(events.table.created).toHaveBeenCalledWith(res.body) + expect(events.table.created).toHaveBeenCalledWith(table) }) it("creates all the passed fields", async () => { - const tableData: TableToBuild = { - name: "TestTable", - type: "table", + const tableData = tableForDatasource(datasource, { schema: { autoId: { name: "id", @@ -92,8 +87,9 @@ describe("/tables", () => { tableId: "tableId", }, }, - } - const testTable = await config.createTable(tableData) + }) + + const testTable = await config.api.table.save(tableData) const expected: Table = { ...tableData, @@ -116,8 +112,6 @@ describe("/tables", () => { }, }, }, - sourceType: TableSourceType.INTERNAL, - sourceId: expect.any(String), _rev: expect.stringMatching(/^1-.+/), _id: expect.any(String), createdAt: mocks.date.MOCK_DATE.toISOString(), @@ -133,14 +127,14 @@ describe("/tables", () => { const table: SaveTableRequest = basicTable() table.rows = [{ name: "test-name", description: "test-desc" }] - const res = await createTable(table) + const res = await config.api.table.save(table) expect(events.table.created).toHaveBeenCalledTimes(1) - expect(events.table.created).toHaveBeenCalledWith(res.body) + expect(events.table.created).toHaveBeenCalledWith(res) expect(events.table.imported).toHaveBeenCalledTimes(1) - expect(events.table.imported).toHaveBeenCalledWith(res.body) + expect(events.table.imported).toHaveBeenCalledWith(res) expect(events.rows.imported).toHaveBeenCalledTimes(1) - expect(events.rows.imported).toHaveBeenCalledWith(res.body, 1) + expect(events.rows.imported).toHaveBeenCalledWith(res, 1) }) it("should apply authorization to endpoint", async () => { @@ -155,17 +149,24 @@ describe("/tables", () => { describe("update", () => { it("updates a table", async () => { - const testTable = await config.createTable() - - const res = await request - .post(`/api/tables`) - .send(testTable) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + const table = await config.api.table.save({ + name: "TestTable", + type: "table", + sourceId: INTERNAL_TABLE_SOURCE_ID, + sourceType: TableSourceType.INTERNAL, + schema: { + name: { + type: FieldType.STRING, + name: "name", + constraints: { + type: "string", + }, + }, + }, + }) expect(events.table.updated).toHaveBeenCalledTimes(1) - expect(events.table.updated).toHaveBeenCalledWith(res.body) + expect(events.table.updated).toHaveBeenCalledWith(table) }) it("updates all the row fields for a table when a schema key is renamed", async () => { @@ -179,111 +180,93 @@ describe("/tables", () => { filters: [], }) - const testRow = await request - .post(`/api/${testTable._id}/rows`) - .send({ - name: "test", - }) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + const testRow = await config.api.row.save(testTable._id!, { + name: "test", + }) - const updatedTable = await request - .post(`/api/tables`) - .send({ - _id: testTable._id, - _rev: testTable._rev, - name: "TestTable", - key: "name", - _rename: { - old: "name", - updated: "updatedName", - }, - schema: { - updatedName: { type: "string" }, - }, - }) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - expect((updatedTable as any).res.statusMessage).toEqual( - "Table TestTable saved successfully." - ) - expect(updatedTable.body.name).toEqual("TestTable") + const updatedTable = await config.api.table.save({ + _id: testTable._id, + _rev: testTable._rev, + type: "table", + sourceId: datasource ? datasource._id! : INTERNAL_TABLE_SOURCE_ID, + sourceType: isInternal + ? TableSourceType.INTERNAL + : TableSourceType.EXTERNAL, + name: "TestTable", + _rename: { + old: "name", + updated: "updatedName", + }, + schema: { + updatedName: { type: FieldType.STRING, name: "updatedName" }, + }, + }) - const res = await request - .get(`/api/${testTable._id}/rows/${testRow.body._id}`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + expect(updatedTable.name).toEqual("TestTable") - expect(res.body.updatedName).toEqual("test") - expect(res.body.name).toBeUndefined() + const res = await config.api.row.get(testTable._id!, testRow._id!) + expect(res.updatedName).toEqual("test") + expect(res.name).toBeUndefined() }) - it("updates only the passed fields", async () => { - const testTable = await config.createTable({ - name: "TestTable", - type: "table", - schema: { - autoId: { - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - autocolumn: true, - constraints: { - type: "number", - presence: false, + it.only("updates only the passed fields", async () => { + const table = await config.api.table.save( + tableForDatasource(datasource, { + name: "TestTable", + schema: { + autoId: { + name: "id", + type: FieldType.NUMBER, + subtype: AutoFieldSubType.AUTO_ID, + autocolumn: true, + constraints: { + type: "number", + presence: false, + }, }, }, - }, - views: { - view1: { - id: "viewId", - version: 2, - name: "table view", - tableId: "tableId", - }, - }, - }) - - const response = await request - .post(`/api/tables`) - .send({ - ...testTable, - name: "UpdatedName", }) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + ) - expect(response.body).toEqual({ - ...testTable, + const updatedTable = await config.api.table.save({ + ...table, name: "UpdatedName", - _rev: expect.stringMatching(/^2-.+/), }) - const persistedTable = await config.api.table.get(testTable._id!) - expect(persistedTable).toEqual({ - ...testTable, + let expected: Table = { + ...table, name: "UpdatedName", - _rev: expect.stringMatching(/^2-.+/), - }) + _id: expect.any(String), + } + if (isInternal) { + expected._rev = expect.stringMatching(/^2-.+/) + } + + expect(updatedTable).toEqual(expected) + + const persistedTable = await config.api.table.get(updatedTable._id!) + expected = { + ...table, + name: "UpdatedName", + _id: updatedTable._id, + } + if (datasource?.isSQL) { + expected.sql = true + } + if (isInternal) { + expected._rev = expect.stringMatching(/^2-.+/) + } + expect(persistedTable).toEqual(expected) }) describe("user table", () => { it("should add roleId and email field when adjusting user table schema", async () => { - const res = await request - .post(`/api/tables`) - .send({ - ...basicTable(), - _id: "ta_users", - }) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - expect(res.body.schema.email).toBeDefined() - expect(res.body.schema.roleId).toBeDefined() + const table = await config.api.table.save({ + ...basicTable(datasource), + _id: "ta_users", + }) + expect(table.schema.email).toBeDefined() + expect(table.schema.roleId).toBeDefined() }) }) @@ -295,12 +278,7 @@ describe("/tables", () => { ...basicTable(), } - const response = await request - .post(`/api/tables`) - .send(saveTableRequest) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + const response = await config.api.table.save(saveTableRequest) const expectedResponse = { ...saveTableRequest, @@ -311,15 +289,13 @@ describe("/tables", () => { views: {}, } delete expectedResponse._add - - expect(response.status).toBe(200) - expect(response.body).toEqual(expectedResponse) + expect(response).toEqual(expectedResponse) }) }) describe("import", () => { it("imports rows successfully", async () => { - const table = await config.createTable() + const table = await config.api.table.save(basicTable(datasource)) const importRequest = { schema: table.schema, rows: [{ name: "test-name", description: "test-desc" }], @@ -327,12 +303,7 @@ describe("/tables", () => { jest.clearAllMocks() - await request - .post(`/api/tables/${table._id}/import`) - .send(importRequest) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + await config.api.table.import(table._id!, importRequest) expect(events.table.created).not.toHaveBeenCalled() expect(events.rows.imported).toHaveBeenCalledTimes(1) @@ -346,22 +317,23 @@ describe("/tables", () => { }) it("should update Auto ID field after bulk import", async () => { - const table = await config.createTable({ - name: "TestTable", - type: "table", - schema: { - autoId: { - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - autocolumn: true, - constraints: { - type: "number", - presence: false, + const table = await config.api.table.save( + tableForDatasource(datasource, { + name: "TestTable", + schema: { + autoId: { + name: "id", + type: FieldType.NUMBER, + subtype: AutoFieldSubType.AUTO_ID, + autocolumn: true, + constraints: { + type: "number", + presence: false, + }, }, }, - }, - }) + }) + ) let row = await config.api.row.save(table._id!, {}) expect(row.autoId).toEqual(1) @@ -381,11 +353,7 @@ describe("/tables", () => { const enrichViewSchemasMock = jest.spyOn(sdk.tables, "enrichViewSchemas") beforeEach(async () => { - testTable = await config.createTable(testTable) - }) - - afterEach(() => { - delete testTable._rev + testTable = await config.api.table.save(basicTable(datasource)) }) afterAll(() => { @@ -393,17 +361,12 @@ describe("/tables", () => { }) it("returns all the tables for that instance in the response body", async () => { - const res = await request - .get(`/api/tables`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - - const table = res.body.find((t: Table) => t._id === testTable._id) + const res = await config.api.table.fetch() + const table = res.find(t => t._id === testTable._id) expect(table).toBeDefined() - expect(table.name).toEqual(testTable.name) - expect(table.type).toEqual("table") - expect(table.sourceType).toEqual("internal") + expect(table!.name).toEqual(testTable.name) + expect(table!.type).toEqual("table") + expect(table!.sourceType).toEqual("internal") }) it("should apply authorization to endpoint", async () => { @@ -421,13 +384,8 @@ describe("/tables", () => { await config.api.viewV2.create({ tableId, name: generator.guid() }), ] - const res = await request - .get(`/api/tables`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - - expect(res.body).toEqual( + const res = await config.api.table.fetch() + expect(res).toEqual( expect.arrayContaining([ expect.objectContaining({ _id: tableId, @@ -481,32 +439,22 @@ describe("/tables", () => { describe("indexing", () => { it("should be able to create a table with indexes", async () => { - await context.doInAppContext(appId, async () => { + await context.doInAppContext(config.getAppId(), async () => { const db = context.getAppDB() const indexCount = (await db.getIndexes()).total_rows const table = basicTable() table.indexes = ["name"] - const res = await request - .post(`/api/tables`) - .send(table) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - expect(res.body._id).toBeDefined() - expect(res.body._rev).toBeDefined() + const res = await config.api.table.save(table) + expect(res._id).toBeDefined() + expect(res._rev).toBeDefined() expect((await db.getIndexes()).total_rows).toEqual(indexCount + 1) // update index to see what happens table.indexes = ["name", "description"] - await request - .post(`/api/tables`) - .send({ - ...table, - _id: res.body._id, - _rev: res.body._rev, - }) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + await config.api.table.save({ + ...table, + _id: res._id, + _rev: res._rev, + }) // shouldn't have created a new index expect((await db.getIndexes()).total_rows).toEqual(indexCount + 1) }) @@ -521,12 +469,9 @@ describe("/tables", () => { }) it("returns a success response when a table is deleted.", async () => { - const res = await request - .delete(`/api/tables/${testTable._id}/${testTable._rev}`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`) + await config.api.table.destroy(testTable._id!, testTable._rev!, { + body: { message: `Table ${testTable._id} deleted.` }, + }) expect(events.table.deleted).toHaveBeenCalledTimes(1) expect(events.table.deleted).toHaveBeenCalledWith({ ...testTable, @@ -559,12 +504,9 @@ describe("/tables", () => { }, }) - const res = await request - .delete(`/api/tables/${testTable._id}/${testTable._rev}`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) - expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`) + await config.api.table.destroy(testTable._id!, testTable._rev!, { + body: { message: `Table ${testTable._id} deleted.` }, + }) const dependentTable = await config.api.table.get(linkedTable._id!) expect(dependentTable.schema.TestTable).not.toBeDefined() }) diff --git a/packages/server/src/tests/utilities/api/table.ts b/packages/server/src/tests/utilities/api/table.ts index 49105a3883..d918ba8b9a 100644 --- a/packages/server/src/tests/utilities/api/table.ts +++ b/packages/server/src/tests/utilities/api/table.ts @@ -1,4 +1,6 @@ import { + BulkImportRequest, + BulkImportResponse, MigrateRequest, MigrateResponse, SaveTableRequest, @@ -39,4 +41,28 @@ export class TableAPI extends TestAPI { expectations, }) } + + import = async ( + tableId: string, + data: BulkImportRequest, + expectations?: Expectations + ): Promise => { + return await this._post( + `/api/tables/${tableId}/import`, + { + body: data, + expectations, + } + ) + } + + destroy = async ( + tableId: string, + revId: string, + expectations?: Expectations + ): Promise => { + return await this._delete(`/api/tables/${tableId}/${revId}`, { + expectations, + }) + } } diff --git a/packages/server/src/tests/utilities/structures.ts b/packages/server/src/tests/utilities/structures.ts index 5b50bd1175..f4e59a3c78 100644 --- a/packages/server/src/tests/utilities/structures.ts +++ b/packages/server/src/tests/utilities/structures.ts @@ -26,15 +26,30 @@ import { WebhookActionType, } from "@budibase/types" import { LoopInput, LoopStepType } from "../../definitions/automations" +import { merge } from "lodash" const { BUILTIN_ROLE_IDS } = roles -export function basicTable(): Table { - return { - name: "TestTable", - type: "table", - sourceId: INTERNAL_TABLE_SOURCE_ID, - sourceType: TableSourceType.INTERNAL, +export function tableForDatasource( + datasource?: Datasource, + ...extra: Partial[] +): Table { + return merge( + { + name: "TestTable", + type: "table", + sourceType: datasource + ? TableSourceType.EXTERNAL + : TableSourceType.INTERNAL, + sourceId: datasource ? datasource._id! : INTERNAL_TABLE_SOURCE_ID, + schema: {}, + }, + ...extra + ) +} + +export function basicTable(datasource?: Datasource): Table { + return tableForDatasource(datasource, { schema: { name: { type: FieldType.STRING, @@ -51,7 +66,7 @@ export function basicTable(): Table { }, }, }, - } + }) } export function basicView(tableId: string) { From bc072e1424c2ab7f5d6ec5892daef6fa58ace928 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Apr 2024 11:50:27 +0100 Subject: [PATCH 28/50] More progress on fixing up table.spec.ts. --- .../server/src/api/routes/tests/table.spec.ts | 169 ++++++++++-------- .../server/src/tests/utilities/structures.ts | 41 +++-- 2 files changed, 121 insertions(+), 89 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 6e72236cbb..400ff858a7 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -17,7 +17,6 @@ import { } from "@budibase/types" import { checkBuilderEndpoint } from "./utilities/TestFunctions" import * as setup from "./utilities" -import sdk from "../../../sdk" import * as uuid from "uuid" import tk from "timekeeper" @@ -59,8 +58,11 @@ describe.each([ }) it("returns a success message when the table is successfully created", async () => { - const table = await config.api.table.save(basicTable(datasource)) - expect(table.name).toEqual("TestTable") + const name = generator.guid() + const table = await config.api.table.save( + tableForDatasource(datasource, { name }) + ) + expect(table.name).toEqual(name) expect(events.table.created).toHaveBeenCalledTimes(1) expect(events.table.created).toHaveBeenCalledWith(table) }) @@ -149,20 +151,23 @@ describe.each([ describe("update", () => { it("updates a table", async () => { - const table = await config.api.table.save({ - name: "TestTable", - type: "table", - sourceId: INTERNAL_TABLE_SOURCE_ID, - sourceType: TableSourceType.INTERNAL, - schema: { - name: { - type: FieldType.STRING, - name: "name", - constraints: { - type: "string", + const table = await config.api.table.save( + tableForDatasource(datasource, { + schema: { + name: { + type: FieldType.STRING, + name: "name", + constraints: { + type: "string", + }, }, }, - }, + }) + ) + + await config.api.table.save({ + ...table, + name: generator.guid(), }) expect(events.table.updated).toHaveBeenCalledTimes(1) @@ -209,7 +214,7 @@ describe.each([ expect(res.name).toBeUndefined() }) - it.only("updates only the passed fields", async () => { + it("updates only the passed fields", async () => { const table = await config.api.table.save( tableForDatasource(datasource, { name: "TestTable", @@ -350,23 +355,20 @@ describe.each([ describe("fetch", () => { let testTable: Table - const enrichViewSchemasMock = jest.spyOn(sdk.tables, "enrichViewSchemas") beforeEach(async () => { - testTable = await config.api.table.save(basicTable(datasource)) + testTable = await config.api.table.save( + basicTable(datasource, { name: generator.guid() }) + ) }) - afterAll(() => { - enrichViewSchemasMock.mockRestore() - }) - - it("returns all the tables for that instance in the response body", async () => { + it("returns all tables", async () => { const res = await config.api.table.fetch() const table = res.find(t => t._id === testTable._id) expect(table).toBeDefined() expect(table!.name).toEqual(testTable.name) expect(table!.type).toEqual("table") - expect(table!.sourceType).toEqual("internal") + expect(table!.sourceType).toEqual(testTable.sourceType) }) it("should apply authorization to endpoint", async () => { @@ -377,63 +379,84 @@ describe.each([ }) }) - it("should fetch views", async () => { - const tableId = config.table!._id! - const views = [ - await config.api.viewV2.create({ tableId, name: generator.guid() }), - await config.api.viewV2.create({ tableId, name: generator.guid() }), - ] + it("should enrich the view schemas", async () => { + const viewV2 = await config.api.viewV2.create({ + tableId: testTable._id!, + name: generator.guid(), + }) + const legacyView = await config.api.legacyView.save({ + tableId: testTable._id!, + name: generator.guid(), + filters: [], + schema: {}, + }) const res = await config.api.table.fetch() - expect(res).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - _id: tableId, - views: views.reduce((p, c) => { - p[c.name] = { ...c, schema: expect.anything() } - return p - }, {} as any), - }), - ]) - ) - }) - it("should enrich the view schemas for viewsV2", async () => { - const tableId = config.table!._id! - enrichViewSchemasMock.mockImplementation(t => ({ - ...t, - views: { - view1: { - version: 2, - name: "view1", - schema: {}, - id: "new_view_id", - tableId: t._id!, + const table = res.find(t => t._id === testTable._id) + expect(table).toBeDefined() + expect(table!.views![viewV2.name]).toBeDefined() + expect(table!.views![viewV2.name!]).toEqual({ + ...viewV2, + schema: { + description: { + constraints: { + type: "string", + }, + name: "description", + type: "string", + visible: false, + }, + name: { + constraints: { + type: "string", + }, + name: "name", + type: "string", + visible: false, }, }, - })) + }) - await config.api.viewV2.create({ tableId, name: generator.guid() }) - await config.createLegacyView() - - const res = await config.api.table.fetch() - - expect(res).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - _id: tableId, - views: { - view1: { - version: 2, - name: "view1", - schema: {}, - id: "new_view_id", - tableId, + if (isInternal) { + expect(table!.views![legacyView.name!]).toBeDefined() + expect(table!.views![legacyView.name!]).toEqual({ + ...legacyView, + schema: { + description: { + constraints: { + type: "string", }, + name: "description", + type: "string", }, - }), - ]) - ) + name: { + constraints: { + type: "string", + }, + name: "name", + type: "string", + }, + }, + }) + } + + // expect(res).toEqual( + // expect.arrayContaining([ + // expect.objectContaining({ + // _id: tableId, + // views: { + // view1: { + // version: 2, + // name: "view1", + // schema: {}, + // id: "new_view_id", + // tableId, + // }, + // }, + // }), + // ]) + // ) }) }) diff --git a/packages/server/src/tests/utilities/structures.ts b/packages/server/src/tests/utilities/structures.ts index f4e59a3c78..2a32489c30 100644 --- a/packages/server/src/tests/utilities/structures.ts +++ b/packages/server/src/tests/utilities/structures.ts @@ -27,6 +27,7 @@ import { } from "@budibase/types" import { LoopInput, LoopStepType } from "../../definitions/automations" import { merge } from "lodash" +import { generator } from "@budibase/backend-core/tests" const { BUILTIN_ROLE_IDS } = roles @@ -36,7 +37,7 @@ export function tableForDatasource( ): Table { return merge( { - name: "TestTable", + name: generator.guid(), type: "table", sourceType: datasource ? TableSourceType.EXTERNAL @@ -48,25 +49,33 @@ export function tableForDatasource( ) } -export function basicTable(datasource?: Datasource): Table { - return tableForDatasource(datasource, { - schema: { - name: { - type: FieldType.STRING, - name: "name", - constraints: { - type: "string", +export function basicTable( + datasource?: Datasource, + ...extra: Partial
[] +): Table { + return tableForDatasource( + datasource, + { + name: "TestTable", + schema: { + name: { + type: FieldType.STRING, + name: "name", + constraints: { + type: "string", + }, }, - }, - description: { - type: FieldType.STRING, - name: "description", - constraints: { - type: "string", + description: { + type: FieldType.STRING, + name: "description", + constraints: { + type: "string", + }, }, }, }, - }) + ...extra + ) } export function basicView(tableId: string) { From 86150c58ce9b53253f98a87be78d2d6b8c5dce96 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 Apr 2024 12:14:51 +0100 Subject: [PATCH 29/50] Fixing issue with BB_ADMIN environment variables for user creation introduced by user password becoming optional. Adding a test case as well to cover this to avoid it breaking in future. --- packages/backend-core/src/users/db.ts | 3 +- packages/server/src/app.ts | 2 +- .../src/{startup.ts => startup/index.ts} | 39 +++--- .../server/src/startup/tests/startup.spec.ts | 34 +++++ .../src/api/controllers/global/users.ts | 14 +- yarn.lock | 121 +----------------- 6 files changed, 69 insertions(+), 144 deletions(-) rename packages/server/src/{startup.ts => startup/index.ts} (80%) create mode 100644 packages/server/src/startup/tests/startup.spec.ts diff --git a/packages/backend-core/src/users/db.ts b/packages/backend-core/src/users/db.ts index 04d3264e6f..6165a68e57 100644 --- a/packages/backend-core/src/users/db.ts +++ b/packages/backend-core/src/users/db.ts @@ -45,6 +45,7 @@ type GroupFns = { getGroupBuilderAppIds: GroupBuildersFn } type CreateAdminUserOpts = { + password?: string ssoId?: string hashPassword?: boolean requirePassword?: boolean @@ -501,9 +502,9 @@ export class UserDB { static async createAdminUser( email: string, tenantId: string, - password?: string, opts?: CreateAdminUserOpts ) { + const password = opts?.password const user: User = { email: email, password, diff --git a/packages/server/src/app.ts b/packages/server/src/app.ts index aa96a30b00..75da54cbaf 100644 --- a/packages/server/src/app.ts +++ b/packages/server/src/app.ts @@ -21,7 +21,7 @@ async function start() { app = koa.app server = koa.server // startup includes automation runner - if enabled - await startup(app, server) + await startup({ app, server }) } start().catch(err => { diff --git a/packages/server/src/startup.ts b/packages/server/src/startup/index.ts similarity index 80% rename from packages/server/src/startup.ts rename to packages/server/src/startup/index.ts index 2cedda1099..48d500a0cf 100644 --- a/packages/server/src/startup.ts +++ b/packages/server/src/startup/index.ts @@ -1,6 +1,6 @@ -import env from "./environment" -import * as redis from "./utilities/redis" -import { generateApiKey, getChecklist } from "./utilities/workerRequests" +import env from "../environment" +import * as redis from "../utilities/redis" +import { generateApiKey, getChecklist } from "../utilities/workerRequests" import { events, installation, @@ -9,22 +9,22 @@ import { users, cache, } from "@budibase/backend-core" -import fs from "fs" -import { watch } from "./watch" -import * as automations from "./automations" -import * as fileSystem from "./utilities/fileSystem" -import { default as eventEmitter, init as eventInit } from "./events" -import * as migrations from "./migrations" -import * as bullboard from "./automations/bullboard" +import { watch } from "../watch" +import * as automations from "../automations" +import * as fileSystem from "../utilities/fileSystem" +import { default as eventEmitter, init as eventInit } from "../events" +import * as migrations from "../migrations" +import * as bullboard from "../automations/bullboard" import * as pro from "@budibase/pro" -import * as api from "./api" -import sdk from "./sdk" -import { initialise as initialiseWebsockets } from "./websockets" -import { automationsEnabled, printFeatures } from "./features" +import * as api from "../api" +import sdk from "../sdk" +import { initialise as initialiseWebsockets } from "../websockets" +import { automationsEnabled, printFeatures } from "../features" +import * as jsRunner from "../jsRunner" import Koa from "koa" import { Server } from "http" import { AddressInfo } from "net" -import * as jsRunner from "./jsRunner" +import fs from "fs" let STARTUP_RAN = false @@ -61,8 +61,11 @@ function shutdown(server?: Server) { } } -export async function startup(app?: Koa, server?: Server) { - if (STARTUP_RAN) { +export async function startup( + opts: { app?: Koa; server?: Server; rerun?: boolean } = {} +) { + const { app, server, rerun } = opts + if (STARTUP_RAN && !rerun) { return } printFeatures() @@ -139,9 +142,9 @@ export async function startup(app?: Koa, server?: Server) { try { const user = await users.UserDB.createAdminUser( bbAdminEmail, - bbAdminPassword, tenantId, { + password: bbAdminPassword, hashPassword: true, requirePassword: true, skipPasswordValidation: true, diff --git a/packages/server/src/startup/tests/startup.spec.ts b/packages/server/src/startup/tests/startup.spec.ts new file mode 100644 index 0000000000..ed31bc45b7 --- /dev/null +++ b/packages/server/src/startup/tests/startup.spec.ts @@ -0,0 +1,34 @@ +import TestConfiguration from "../../tests/utilities/TestConfiguration" +import { startup } from "../index" +import { users, utils, tenancy } from "@budibase/backend-core" + +describe("check BB_ADMIN environment variables", () => { + const config = new TestConfiguration() + beforeAll(async () => { + await config.init() + }) + + it("should be able to create a user with the BB_ADMIN environment variables", async () => { + const EMAIL = "budibase@budibase.com", + PASSWORD = "budibase" + await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => { + await config.withEnv( + { + BB_ADMIN_USER_EMAIL: EMAIL, + BB_ADMIN_USER_PASSWORD: PASSWORD, + MULTI_TENANCY: "0", + SELF_HOSTED: "1", + }, + async () => { + await startup({ rerun: true }) + const user = await users.getGlobalUserByEmail(EMAIL, { + cleanup: false, + }) + expect(user).toBeDefined() + expect(user?.password).toBeDefined() + expect(await utils.compare(PASSWORD, user?.password!)).toEqual(true) + } + ) + }) + }) +}) diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts index 0c1342fa08..4c1af90d38 100644 --- a/packages/worker/src/api/controllers/global/users.ts +++ b/packages/worker/src/api/controllers/global/users.ts @@ -146,16 +146,12 @@ export const adminUser = async ( } try { - const finalUser = await userSdk.db.createAdminUser( - email, - tenantId, + const finalUser = await userSdk.db.createAdminUser(email, tenantId, { password, - { - ssoId, - hashPassword, - requirePassword, - } - ) + ssoId, + hashPassword, + requirePassword, + }) // events let account: CloudAccount | undefined diff --git a/yarn.lock b/yarn.lock index 3497a55b0a..f4c0f56414 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5098,15 +5098,6 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@trendyol/jest-testcontainers@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@trendyol/jest-testcontainers/-/jest-testcontainers-2.1.1.tgz#dced95cf9c37b75efe0a65db9b75ae8912f2f14a" - integrity sha512-4iAc2pMsev4BTUzoA7jO1VvbTOU2N3juQUYa8TwiSPXPuQtxKwV9WB9ZEP+JQ+Pj15YqfGOXp5H0WNMPtapjiA== - dependencies: - cwd "^0.10.0" - node-duration "^1.0.4" - testcontainers "4.7.0" - "@trysound/sax@0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" @@ -5296,13 +5287,6 @@ "@types/node" "*" "@types/ssh2" "*" -"@types/dockerode@^2.5.34": - version "2.5.34" - resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-2.5.34.tgz#9adb884f7cc6c012a6eb4b2ad794cc5d01439959" - integrity sha512-LcbLGcvcBwBAvjH9UrUI+4qotY+A5WCer5r43DR5XHv2ZIEByNXFdPLo1XxR+v/BjkGjlggW8qUiXuVEhqfkpA== - dependencies: - "@types/node" "*" - "@types/dockerode@^3.3.24": version "3.3.24" resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-3.3.24.tgz#bea354a4fcd0824a80fd5ea5ede3e8cda71137a7" @@ -9152,14 +9136,6 @@ curlconverter@3.21.0: string.prototype.startswith "^1.0.0" yamljs "^0.3.0" -cwd@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/cwd/-/cwd-0.10.0.tgz#172400694057c22a13b0cf16162c7e4b7a7fe567" - integrity sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA== - dependencies: - find-pkg "^0.1.2" - fs-exists-sync "^0.1.0" - dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" @@ -9781,7 +9757,7 @@ docker-compose@0.24.0: dependencies: yaml "^1.10.2" -docker-compose@^0.23.5, docker-compose@^0.23.6: +docker-compose@^0.23.6: version "0.23.19" resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.19.tgz#9947726e2fe67bdfa9e8efe1ff15aa0de2e10eb8" integrity sha512-v5vNLIdUqwj4my80wxFDkNH+4S85zsRuH29SO7dCWVWPCMt/ohZBsGN6g6KXWifT0pzQ7uOxqEKCYCDPJ8Vz4g== @@ -9805,7 +9781,7 @@ docker-modem@^3.0.0: split-ca "^1.0.1" ssh2 "^1.11.0" -dockerode@^3.2.1, dockerode@^3.3.5: +dockerode@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.5.tgz#7ae3f40f2bec53ae5e9a741ce655fff459745629" integrity sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA== @@ -10830,13 +10806,6 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -expand-tilde@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" - integrity sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q== - dependencies: - os-homedir "^1.0.1" - expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -11175,26 +11144,11 @@ filter-obj@^1.1.0: resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== -find-file-up@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/find-file-up/-/find-file-up-0.1.3.tgz#cf68091bcf9f300a40da411b37da5cce5a2fbea0" - integrity sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A== - dependencies: - fs-exists-sync "^0.1.0" - resolve-dir "^0.1.0" - find-free-port@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/find-free-port/-/find-free-port-2.0.0.tgz#4b22e5f6579eb1a38c41ac6bcb3efed1b6da9b1b" integrity sha512-J1j8gfEVf5FN4PR5w5wrZZ7NYs2IvqsHcd03cAeQx3Ec/mo+lKceaVNhpsRKoZpZKbId88o8qh+dwUwzBV6WCg== -find-pkg@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/find-pkg/-/find-pkg-0.1.2.tgz#1bdc22c06e36365532e2a248046854b9788da557" - integrity sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw== - dependencies: - find-file-up "^0.1.2" - find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -11362,11 +11316,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - integrity sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg== - fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -11863,24 +11812,6 @@ global-dirs@^3.0.0: dependencies: ini "2.0.0" -global-modules@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" - integrity sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA== - dependencies: - global-prefix "^0.1.4" - is-windows "^0.2.0" - -global-prefix@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" - integrity sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw== - dependencies: - homedir-polyfill "^1.0.0" - ini "^1.3.4" - is-windows "^0.2.0" - which "^1.2.12" - global@~4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" @@ -12311,7 +12242,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: +homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== @@ -13285,11 +13216,6 @@ is-whitespace@^0.3.0: resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" integrity sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg== -is-windows@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" - integrity sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q== - is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -16116,7 +16042,7 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -nock@^13.5.4: +nock@13.5.4, nock@^13.5.4: version "13.5.4" resolved "https://registry.yarnpkg.com/nock/-/nock-13.5.4.tgz#8918f0addc70a63736170fef7106a9721e0dc479" integrity sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw== @@ -16152,11 +16078,6 @@ node-addon-api@^6.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== -node-duration@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/node-duration/-/node-duration-1.0.4.tgz#3e94ecc0e473691c89c4560074503362071cecac" - integrity sha512-eUXYNSY7DL53vqfTosggWkvyIW3bhAcqBDIlolgNYlZhianXTrCL50rlUJWD1eRqkIxMppXTfiFbp+9SjpPrgA== - node-fetch@2.6.0, node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -16903,11 +16824,6 @@ oracledb@5.3.0: resolved "https://registry.yarnpkg.com/oracledb/-/oracledb-5.3.0.tgz#a15e6cd16757d8711a2c006a28bd7ecd3b8466f7" integrity sha512-HMJzQ6lCf287ztvvehTEmjCWA21FQ3RMvM+mgoqd4i8pkREuqFWO+y3ovsGR9moJUg4T0xjcwS8rl4mggWPxmg== -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== - os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -19227,14 +19143,6 @@ resolve-dependency-path@^2.0.0: resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz#11700e340717b865d216c66cabeb4a2a3c696736" integrity sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w== -resolve-dir@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" - integrity sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA== - dependencies: - expand-tilde "^1.2.2" - global-modules "^0.2.3" - resolve-from@5.0.0, resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -20924,7 +20832,7 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar-fs@2.1.1, tar-fs@^2.0.0, tar-fs@^2.1.0: +tar-fs@2.1.1, tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -21102,23 +21010,6 @@ testcontainers@10.7.2, testcontainers@^10.7.2: tar-fs "^3.0.5" tmp "^0.2.1" -testcontainers@4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-4.7.0.tgz#5a9a864b1b0cc86984086dcc737c2f5e73490cf3" - integrity sha512-5SrG9RMfDRRZig34fDZeMcGD5i3lHCOJzn0kjouyK4TiEWjZB3h7kCk8524lwNRHROFE1j6DGjceonv/5hl5ag== - dependencies: - "@types/dockerode" "^2.5.34" - byline "^5.0.0" - debug "^4.1.1" - docker-compose "^0.23.5" - dockerode "^3.2.1" - get-port "^5.1.1" - glob "^7.1.6" - node-duration "^1.0.4" - slash "^3.0.0" - stream-to-array "^2.3.0" - tar-fs "^2.1.0" - text-extensions@^1.0.0: version "1.9.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" @@ -22357,7 +22248,7 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -which@^1.2.12, which@^1.2.9: +which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== From 0b36dc8567bf74d60c0a61cb6563b4866329444d Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Fri, 5 Apr 2024 15:32:36 +0000 Subject: [PATCH 30/50] Bump version to 2.22.17 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 7186c0ca17..94ca18985e 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.22.16", + "version": "2.22.17", "npmClient": "yarn", "packages": [ "packages/*", From bcc09bd86e6494b12eb79bef193a1022fb529e38 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Apr 2024 16:38:57 +0100 Subject: [PATCH 31/50] table.spec.ts passing for internal and postgres --- .../server/src/api/controllers/table/index.ts | 2 +- .../server/src/api/routes/tests/row.spec.ts | 33 ++ .../server/src/api/routes/tests/table.spec.ts | 305 +++++++----------- .../src/sdk/app/tables/external/index.ts | 16 + .../types/src/documents/app/table/schema.ts | 4 + 5 files changed, 166 insertions(+), 194 deletions(-) diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index 69305c461e..f799113333 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -84,8 +84,8 @@ export async function save(ctx: UserCtx) { } let savedTable = await api.save(ctx, renaming) if (!table._id) { - await events.table.created(savedTable) savedTable = sdk.tables.enrichViewSchemas(savedTable) + await events.table.created(savedTable) } else { await events.table.updated(savedTable) } diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index f9e05c5bd8..d9895466a5 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -722,6 +722,39 @@ describe.each([ }) }) + describe("bulkImport", () => { + isInternal && + it("should update Auto ID field after bulk import", async () => { + const table = await config.api.table.save( + saveTableRequest({ + primary: ["autoId"], + schema: { + autoId: { + name: "autoId", + type: FieldType.NUMBER, + subtype: AutoFieldSubType.AUTO_ID, + autocolumn: true, + constraints: { + type: "number", + presence: false, + }, + }, + }, + }) + ) + + let row = await config.api.row.save(table._id!, {}) + expect(row.autoId).toEqual(1) + + await config.api.row.bulkImport(table._id!, { + rows: [{ autoId: 2 }], + }) + + row = await config.api.row.save(table._id!, {}) + expect(row.autoId).toEqual(3) + }) + }) + describe("enrich", () => { beforeAll(async () => { table = await config.api.table.save(defaultTable()) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 400ff858a7..6d2dd791b1 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -6,7 +6,6 @@ import { FieldType, INTERNAL_TABLE_SOURCE_ID, InternalTable, - NumberFieldMetadata, RelationshipType, Row, SaveTableRequest, @@ -14,17 +13,16 @@ import { TableSourceType, User, ViewCalculation, + ViewV2, } from "@budibase/types" import { checkBuilderEndpoint } from "./utilities/TestFunctions" import * as setup from "./utilities" import * as uuid from "uuid" -import tk from "timekeeper" -import { generator, mocks } from "@budibase/backend-core/tests" +import { generator } from "@budibase/backend-core/tests" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import { tableForDatasource } from "../../../tests/utilities/structures" - -tk.freeze(mocks.date.MOCK_DATE) +import timekeeper from "timekeeper" const { basicTable } = setup.structures const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ @@ -57,7 +55,7 @@ describe.each([ jest.clearAllMocks() }) - it("returns a success message when the table is successfully created", async () => { + it("creates a table successfully", async () => { const name = generator.guid() const table = await config.api.table.save( tableForDatasource(datasource, { name }) @@ -67,64 +65,6 @@ describe.each([ expect(events.table.created).toHaveBeenCalledWith(table) }) - it("creates all the passed fields", async () => { - const tableData = tableForDatasource(datasource, { - schema: { - autoId: { - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - autocolumn: true, - constraints: { - type: "number", - presence: false, - }, - }, - }, - views: { - "table view": { - id: "viewId", - version: 2, - name: "table view", - tableId: "tableId", - }, - }, - }) - - const testTable = await config.api.table.save(tableData) - - const expected: Table = { - ...tableData, - type: "table", - views: { - "table view": { - ...tableData.views!["table view"], - schema: { - autoId: { - autocolumn: true, - constraints: { - presence: false, - type: "number", - }, - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - visible: false, - } as NumberFieldMetadata, - }, - }, - }, - _rev: expect.stringMatching(/^1-.+/), - _id: expect.any(String), - createdAt: mocks.date.MOCK_DATE.toISOString(), - updatedAt: mocks.date.MOCK_DATE.toISOString(), - } - expect(testTable).toEqual(expected) - - const persistedTable = await config.api.table.get(testTable._id!) - expect(persistedTable).toEqual(expected) - }) - it("creates a table via data import", async () => { const table: SaveTableRequest = basicTable() table.rows = [{ name: "test-name", description: "test-desc" }] @@ -165,17 +105,17 @@ describe.each([ }) ) - await config.api.table.save({ + const updatedTable = await config.api.table.save({ ...table, name: generator.guid(), }) expect(events.table.updated).toHaveBeenCalledTimes(1) - expect(events.table.updated).toHaveBeenCalledWith(table) + expect(events.table.updated).toHaveBeenCalledWith(updatedTable) }) it("updates all the row fields for a table when a schema key is renamed", async () => { - const testTable = await config.createTable() + const testTable = await config.api.table.save(basicTable(datasource)) await config.createLegacyView({ name: "TestView", field: "Price", @@ -215,64 +155,68 @@ describe.each([ }) it("updates only the passed fields", async () => { - const table = await config.api.table.save( - tableForDatasource(datasource, { - name: "TestTable", - schema: { - autoId: { - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - autocolumn: true, - constraints: { - type: "number", - presence: false, + await timekeeper.withFreeze(new Date(2021, 1, 1), async () => { + const table = await config.api.table.save( + tableForDatasource(datasource, { + schema: { + autoId: { + name: "id", + type: FieldType.NUMBER, + subtype: AutoFieldSubType.AUTO_ID, + autocolumn: true, + constraints: { + type: "number", + presence: false, + }, }, }, - }, + }) + ) + + const newName = generator.guid() + + const updatedTable = await config.api.table.save({ + ...table, + name: newName, }) - ) - const updatedTable = await config.api.table.save({ - ...table, - name: "UpdatedName", + let expected: Table = { + ...table, + name: newName, + _id: expect.any(String), + } + if (isInternal) { + expected._rev = expect.stringMatching(/^2-.+/) + } + + expect(updatedTable).toEqual(expected) + + const persistedTable = await config.api.table.get(updatedTable._id!) + expected = { + ...table, + name: newName, + _id: updatedTable._id, + } + if (datasource?.isSQL) { + expected.sql = true + } + if (isInternal) { + expected._rev = expect.stringMatching(/^2-.+/) + } + expect(persistedTable).toEqual(expected) }) - - let expected: Table = { - ...table, - name: "UpdatedName", - _id: expect.any(String), - } - if (isInternal) { - expected._rev = expect.stringMatching(/^2-.+/) - } - - expect(updatedTable).toEqual(expected) - - const persistedTable = await config.api.table.get(updatedTable._id!) - expected = { - ...table, - name: "UpdatedName", - _id: updatedTable._id, - } - if (datasource?.isSQL) { - expected.sql = true - } - if (isInternal) { - expected._rev = expect.stringMatching(/^2-.+/) - } - expect(persistedTable).toEqual(expected) }) describe("user table", () => { - it("should add roleId and email field when adjusting user table schema", async () => { - const table = await config.api.table.save({ - ...basicTable(datasource), - _id: "ta_users", + isInternal && + it("should add roleId and email field when adjusting user table schema", async () => { + const table = await config.api.table.save({ + ...basicTable(datasource), + _id: "ta_users", + }) + expect(table.schema.email).toBeDefined() + expect(table.schema.roleId).toBeDefined() }) - expect(table.schema.email).toBeDefined() - expect(table.schema.roleId).toBeDefined() - }) }) it("should add a new column for an internal DB table", async () => { @@ -300,7 +244,10 @@ describe.each([ describe("import", () => { it("imports rows successfully", async () => { - const table = await config.api.table.save(basicTable(datasource)) + const name = generator.guid() + const table = await config.api.table.save( + basicTable(datasource, { name }) + ) const importRequest = { schema: table.schema, rows: [{ name: "test-name", description: "test-desc" }], @@ -314,43 +261,12 @@ describe.each([ expect(events.rows.imported).toHaveBeenCalledTimes(1) expect(events.rows.imported).toHaveBeenCalledWith( expect.objectContaining({ - name: "TestTable", + name, _id: table._id, }), 1 ) }) - - it("should update Auto ID field after bulk import", async () => { - const table = await config.api.table.save( - tableForDatasource(datasource, { - name: "TestTable", - schema: { - autoId: { - name: "id", - type: FieldType.NUMBER, - subtype: AutoFieldSubType.AUTO_ID, - autocolumn: true, - constraints: { - type: "number", - presence: false, - }, - }, - }, - }) - ) - - let row = await config.api.row.save(table._id!, {}) - expect(row.autoId).toEqual(1) - - await config.api.row.bulkImport(table._id!, { - rows: [{ autoId: 2 }], - identifierFields: [], - }) - - row = await config.api.row.save(table._id!, {}) - expect(row.autoId).toEqual(3) - }) }) describe("fetch", () => { @@ -396,7 +312,8 @@ describe.each([ const table = res.find(t => t._id === testTable._id) expect(table).toBeDefined() expect(table!.views![viewV2.name]).toBeDefined() - expect(table!.views![viewV2.name!]).toEqual({ + + const expectedViewV2: ViewV2 = { ...viewV2, schema: { description: { @@ -404,7 +321,7 @@ describe.each([ type: "string", }, name: "description", - type: "string", + type: FieldType.STRING, visible: false, }, name: { @@ -412,11 +329,22 @@ describe.each([ type: "string", }, name: "name", - type: "string", + type: FieldType.STRING, visible: false, }, }, - }) + } + + if (!isInternal) { + expectedViewV2.schema!.id = { + name: "id", + type: FieldType.NUMBER, + visible: false, + autocolumn: true, + } + } + + expect(table!.views![viewV2.name!]).toEqual(expectedViewV2) if (isInternal) { expect(table!.views![legacyView.name!]).toBeDefined() @@ -440,23 +368,16 @@ describe.each([ }, }) } + }) + }) - // expect(res).toEqual( - // expect.arrayContaining([ - // expect.objectContaining({ - // _id: tableId, - // views: { - // view1: { - // version: 2, - // name: "view1", - // schema: {}, - // id: "new_view_id", - // tableId, - // }, - // }, - // }), - // ]) - // ) + describe("get", () => { + it("returns a table", async () => { + const table = await config.api.table.save( + basicTable(datasource, { name: generator.guid() }) + ) + const res = await config.api.table.get(table._id!) + expect(res).toEqual(table) }) }) @@ -781,33 +702,31 @@ describe.each([ describe("unhappy paths", () => { let table: Table beforeAll(async () => { - table = await config.api.table.save({ - name: "table", - type: "table", - sourceId: INTERNAL_TABLE_SOURCE_ID, - sourceType: TableSourceType.INTERNAL, - schema: { - "user relationship": { - type: FieldType.LINK, - fieldName: "test", - name: "user relationship", - constraints: { - type: "array", - presence: false, + table = await config.api.table.save( + tableForDatasource(datasource, { + schema: { + "user relationship": { + type: FieldType.LINK, + fieldName: "test", + name: "user relationship", + constraints: { + type: "array", + presence: false, + }, + relationshipType: RelationshipType.MANY_TO_ONE, + tableId: InternalTable.USER_METADATA, }, - relationshipType: RelationshipType.MANY_TO_ONE, - tableId: InternalTable.USER_METADATA, - }, - num: { - type: FieldType.NUMBER, - name: "num", - constraints: { - type: "number", - presence: false, + num: { + type: FieldType.NUMBER, + name: "num", + constraints: { + type: "number", + presence: false, + }, }, }, - }, - }) + }) + ) }) it("should fail if the new column name is blank", async () => { diff --git a/packages/server/src/sdk/app/tables/external/index.ts b/packages/server/src/sdk/app/tables/external/index.ts index 0ace19d00e..65cd4a07c1 100644 --- a/packages/server/src/sdk/app/tables/external/index.ts +++ b/packages/server/src/sdk/app/tables/external/index.ts @@ -48,6 +48,18 @@ export async function save( oldTable = await getTable(tableId) } + if ( + !oldTable && + (tableToSave.primary == null || tableToSave.primary.length === 0) + ) { + tableToSave.primary = ["id"] + tableToSave.schema.id = { + type: FieldType.NUMBER, + autocolumn: true, + name: "id", + } + } + if (hasTypeChanged(tableToSave, oldTable)) { throw new Error("A column type has changed.") } @@ -183,6 +195,10 @@ export async function save( // that the datasource definition changed const updatedDatasource = await datasourceSdk.get(datasource._id!) + if (updatedDatasource.isSQL) { + tableToSave.sql = true + } + return { datasource: updatedDatasource, table: tableToSave } } diff --git a/packages/types/src/documents/app/table/schema.ts b/packages/types/src/documents/app/table/schema.ts index 45e39268ac..42bac7d673 100644 --- a/packages/types/src/documents/app/table/schema.ts +++ b/packages/types/src/documents/app/table/schema.ts @@ -10,10 +10,14 @@ import { } from "./constants" export interface UIFieldMetadata { + constraints?: FieldConstraints + name?: string + type?: FieldType order?: number width?: number visible?: boolean icon?: string + autocolumn?: boolean } interface BaseRelationshipFieldMetadata From de2afa01b98044338fc0239cc04c8bf1717e2772 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Apr 2024 16:54:29 +0100 Subject: [PATCH 32/50] table.spec.ts passing with MySQL --- packages/server/src/api/routes/tests/table.spec.ts | 2 +- packages/server/src/integrations/base/sqlTable.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 6d2dd791b1..360c76d593 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -30,7 +30,7 @@ const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ describe.each([ ["internal", undefined], [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], - // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], + [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/tables (%s)", (_, dsProvider) => { diff --git a/packages/server/src/integrations/base/sqlTable.ts b/packages/server/src/integrations/base/sqlTable.ts index 0feecefb89..9718da0ad2 100644 --- a/packages/server/src/integrations/base/sqlTable.ts +++ b/packages/server/src/integrations/base/sqlTable.ts @@ -224,9 +224,8 @@ class SqlTableQueryBuilder { const tableName = schemaName ? `\`${schemaName}\`.\`${json.table.name}\`` : `\`${json.table.name}\`` - const externalType = json.table.schema[updatedColumn].externalType! return { - sql: `alter table ${tableName} change column \`${json.meta.renamed.old}\` \`${updatedColumn}\` ${externalType};`, + sql: `alter table ${tableName} rename column \`${json.meta.renamed.old}\` to \`${updatedColumn}\``, bindings: [], } } From 7d8cadb47f9c5f40e53724e0ff48eeebb87d07d7 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Apr 2024 16:55:00 +0100 Subject: [PATCH 33/50] table.spec.ts passing with MariaDB --- packages/server/src/api/routes/tests/table.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 360c76d593..b8528487ec 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -32,7 +32,7 @@ describe.each([ [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], - // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], + [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/tables (%s)", (_, dsProvider) => { let isInternal: boolean let datasource: Datasource | undefined From 9da10c790e827cb6b8976ad6cc8d3f3f08c2b513 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 5 Apr 2024 17:47:55 +0100 Subject: [PATCH 34/50] One failure left for MSSQL --- .../src/api/controllers/table/external.ts | 1 + .../server/src/api/routes/tests/table.spec.ts | 26 ++++++------------- .../server/src/integrations/base/sqlTable.ts | 22 ++++++++++++++++ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/packages/server/src/api/controllers/table/external.ts b/packages/server/src/api/controllers/table/external.ts index 7c036bec9d..0a6cf58bce 100644 --- a/packages/server/src/api/controllers/table/external.ts +++ b/packages/server/src/api/controllers/table/external.ts @@ -49,6 +49,7 @@ export async function save( builderSocket?.emitDatasourceUpdate(ctx, datasource) return table } catch (err: any) { + throw err if (err instanceof Error) { ctx.throw(400, err.message) } else { diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index b8528487ec..8162e08eb6 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -28,11 +28,11 @@ const { basicTable } = setup.structures const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ describe.each([ - ["internal", undefined], - [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], - [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], - // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], - [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], + // ["internal", undefined], + // [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], + // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], + [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], + // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/tables (%s)", (_, dsProvider) => { let isInternal: boolean let datasource: Datasource | undefined @@ -114,7 +114,7 @@ describe.each([ expect(events.table.updated).toHaveBeenCalledWith(updatedTable) }) - it("updates all the row fields for a table when a schema key is renamed", async () => { + it.only("updates all the row fields for a table when a schema key is renamed", async () => { const testTable = await config.api.table.save(basicTable(datasource)) await config.createLegacyView({ name: "TestView", @@ -130,24 +130,14 @@ describe.each([ }) const updatedTable = await config.api.table.save({ - _id: testTable._id, - _rev: testTable._rev, - type: "table", - sourceId: datasource ? datasource._id! : INTERNAL_TABLE_SOURCE_ID, - sourceType: isInternal - ? TableSourceType.INTERNAL - : TableSourceType.EXTERNAL, - name: "TestTable", + ...testTable, _rename: { old: "name", updated: "updatedName", }, - schema: { - updatedName: { type: FieldType.STRING, name: "updatedName" }, - }, }) - expect(updatedTable.name).toEqual("TestTable") + expect(updatedTable.name).toEqual(testTable.name) const res = await config.api.row.get(testTable._id!, testRow._id!) expect(res.updatedName).toEqual("test") diff --git a/packages/server/src/integrations/base/sqlTable.ts b/packages/server/src/integrations/base/sqlTable.ts index 9718da0ad2..32d0c38599 100644 --- a/packages/server/src/integrations/base/sqlTable.ts +++ b/packages/server/src/integrations/base/sqlTable.ts @@ -229,6 +229,7 @@ class SqlTableQueryBuilder { bindings: [], } } + query = buildUpdateTable( client, json.table, @@ -236,6 +237,27 @@ class SqlTableQueryBuilder { json.meta.table, json.meta.renamed! ) + + // renameColumn for SQL Server returns a parameterised `sp_rename` query, + // which is not supported by SQL Server and gives a syntax error. + if (this.sqlClient === SqlClient.MS_SQL && json.meta.renamed) { + const oldColumn = json.meta.renamed.old + const updatedColumn = json.meta.renamed.updated + const tableName = schemaName + ? `${schemaName}.${json.table.name}` + : `${json.table.name}` + const sql = query.toSQL() + if (Array.isArray(sql)) { + for (const query of sql) { + if (query.sql.startsWith("exec sp_rename")) { + query.sql = `exec sp_rename '${tableName}.${oldColumn}', '${updatedColumn}', 'COLUMN'` + query.bindings = [] + } + } + } + + return sql + } break case Operation.DELETE_TABLE: query = buildDeleteTable(client, json.table) From 2876085b61c3bcc1c34fcff9d7931fc10704f3bc Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 5 Apr 2024 18:35:56 +0100 Subject: [PATCH 35/50] Fixing test case to update schema when updating column name. --- packages/server/src/api/routes/tests/table.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 8162e08eb6..2f8f83896b 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -129,12 +129,20 @@ describe.each([ name: "test", }) + const { name, ...otherColumns } = testTable.schema const updatedTable = await config.api.table.save({ ...testTable, _rename: { old: "name", updated: "updatedName", }, + schema: { + ...otherColumns, + updatedName: { + ...name, + name: "updatedName", + }, + }, }) expect(updatedTable.name).toEqual(testTable.name) From fe2c6d5ec1701cb039c3bd94364d569968ebb5cd Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:58:59 +0100 Subject: [PATCH 36/50] get process env in JS file (#13414) --- packages/builder/package.json | 2 +- packages/builder/src/analytics/index.js | 4 ++++ packages/builder/src/components/deploy/AppActions.svelte | 5 +---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/builder/package.json b/packages/builder/package.json index 253f5a0c14..f29ae3f7f2 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -72,7 +72,7 @@ "fast-json-patch": "^3.1.1", "json-format-highlight": "^1.0.4", "lodash": "4.17.21", - "posthog-js": "^1.116.6", + "posthog-js": "^1.118.0", "remixicon": "2.5.0", "sanitize-html": "^2.7.0", "shortid": "2.2.15", diff --git a/packages/builder/src/analytics/index.js b/packages/builder/src/analytics/index.js index 3a80a05d7f..a0ddfe1d42 100644 --- a/packages/builder/src/analytics/index.js +++ b/packages/builder/src/analytics/index.js @@ -38,6 +38,10 @@ class AnalyticsHub { intercom.show(user) } + initPosthog() { + posthog.init() + } + async logout() { posthog.logout() intercom.logout() diff --git a/packages/builder/src/components/deploy/AppActions.svelte b/packages/builder/src/components/deploy/AppActions.svelte index 1d7bb4f65e..30b95d639e 100644 --- a/packages/builder/src/components/deploy/AppActions.svelte +++ b/packages/builder/src/components/deploy/AppActions.svelte @@ -33,13 +33,10 @@ import { TOUR_STEP_KEYS } from "components/portal/onboarding/tours.js" import { goto } from "@roxi/routify" import { onMount } from "svelte" - import PosthogClient from "../../analytics/PosthogClient" export let application export let loaded - const posthog = new PosthogClient(process.env.POSTHOG_TOKEN) - let unpublishModal let updateAppModal let revertModal @@ -156,7 +153,7 @@ } onMount(() => { - posthog.init() + analytics.initPosthog() }) From 90e73a77dcfcec3070560451b011bca0dca1d877 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 8 Apr 2024 09:00:03 +0000 Subject: [PATCH 37/50] Bump version to 2.22.18 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 94ca18985e..74b10c07ea 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.22.17", + "version": "2.22.18", "npmClient": "yarn", "packages": [ "packages/*", From 4347667cb31a568598583e8fe299a8bbd5902272 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 10:44:08 +0100 Subject: [PATCH 38/50] Remove .only --- packages/server/src/api/routes/tests/table.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 2f8f83896b..d96e76874f 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -114,7 +114,7 @@ describe.each([ expect(events.table.updated).toHaveBeenCalledWith(updatedTable) }) - it.only("updates all the row fields for a table when a schema key is renamed", async () => { + it("updates all the row fields for a table when a schema key is renamed", async () => { const testTable = await config.api.table.save(basicTable(datasource)) await config.createLegacyView({ name: "TestView", From 5caca2b401f076ecfe40e714717f39a3afecc37d Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 8 Apr 2024 10:52:33 +0100 Subject: [PATCH 39/50] updating acct-portal reference --- packages/account-portal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-portal b/packages/account-portal index 532c4db35c..a0ee9cad8c 160000 --- a/packages/account-portal +++ b/packages/account-portal @@ -1 +1 @@ -Subproject commit 532c4db35cecd346b5c24f0b89ab7b397a122a36 +Subproject commit a0ee9cad8cefb8f9f40228705711be174f018fa9 From c30cc06d47dcc5b9e11676662f6d506f936384dc Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 11:06:43 +0100 Subject: [PATCH 40/50] Fix lint. --- packages/server/src/api/controllers/table/external.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/server/src/api/controllers/table/external.ts b/packages/server/src/api/controllers/table/external.ts index 0a6cf58bce..7c036bec9d 100644 --- a/packages/server/src/api/controllers/table/external.ts +++ b/packages/server/src/api/controllers/table/external.ts @@ -49,7 +49,6 @@ export async function save( builderSocket?.emitDatasourceUpdate(ctx, datasource) return table } catch (err: any) { - throw err if (err instanceof Error) { ctx.throw(400, err.message) } else { From 83c7f08c5a56c81da75e5a2ede5f92443e1bb49d Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 11:11:06 +0100 Subject: [PATCH 41/50] Fix sql.spec.ts --- packages/server/src/integrations/base/sqlTable.ts | 2 +- packages/server/src/integrations/tests/sql.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/integrations/base/sqlTable.ts b/packages/server/src/integrations/base/sqlTable.ts index 32d0c38599..80f3864438 100644 --- a/packages/server/src/integrations/base/sqlTable.ts +++ b/packages/server/src/integrations/base/sqlTable.ts @@ -225,7 +225,7 @@ class SqlTableQueryBuilder { ? `\`${schemaName}\`.\`${json.table.name}\`` : `\`${json.table.name}\`` return { - sql: `alter table ${tableName} rename column \`${json.meta.renamed.old}\` to \`${updatedColumn}\``, + sql: `alter table ${tableName} rename column \`${json.meta.renamed.old}\` to \`${updatedColumn}\`;`, bindings: [], } } diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index c0b92b3849..dc2a06446b 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -722,7 +722,7 @@ describe("SQL query builder", () => { }) expect(query).toEqual({ bindings: [], - sql: `alter table \`${TABLE_NAME}\` change column \`name\` \`first_name\` varchar(45);`, + sql: `alter table \`${TABLE_NAME}\` rename column \`name\` to \`first_name\`;`, }) }) From 249e9e59f5f1e1e598dbee4c659688a1bd02b087 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 12:09:14 +0100 Subject: [PATCH 42/50] Remove extra fields from UIFieldMetadata. --- packages/types/src/documents/app/table/schema.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/types/src/documents/app/table/schema.ts b/packages/types/src/documents/app/table/schema.ts index 42bac7d673..45e39268ac 100644 --- a/packages/types/src/documents/app/table/schema.ts +++ b/packages/types/src/documents/app/table/schema.ts @@ -10,14 +10,10 @@ import { } from "./constants" export interface UIFieldMetadata { - constraints?: FieldConstraints - name?: string - type?: FieldType order?: number width?: number visible?: boolean icon?: string - autocolumn?: boolean } interface BaseRelationshipFieldMetadata From 81cd2a155967b322fa9689a86f93132cdbea090e Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 14:58:48 +0100 Subject: [PATCH 43/50] Attempt to fix View / ViewV2 types. --- .../src/api/controllers/view/viewsV2.ts | 2 +- packages/server/src/sdk/app/tables/getters.ts | 4 ++- packages/server/src/sdk/app/views/external.ts | 30 ++++++++++++------- packages/server/src/sdk/app/views/index.ts | 25 +++++++++++----- packages/server/src/sdk/app/views/internal.ts | 26 +++++++++------- .../server/src/tests/utilities/api/viewV2.ts | 10 +++---- packages/types/src/api/web/app/table.ts | 9 ++---- packages/types/src/api/web/app/view.ts | 13 ++++---- packages/types/src/documents/app/view.ts | 6 +++- 9 files changed, 74 insertions(+), 51 deletions(-) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index a386ac303f..00009ea17e 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -41,7 +41,7 @@ async function parseSchema(view: CreateViewRequest) { export async function get(ctx: Ctx) { ctx.body = { - data: await sdk.views.get(ctx.params.viewId, { enriched: true }), + data: await sdk.views.get(ctx.params.viewId), } } diff --git a/packages/server/src/sdk/app/tables/getters.ts b/packages/server/src/sdk/app/tables/getters.ts index 72a6ab61f1..414af2c837 100644 --- a/packages/server/src/sdk/app/tables/getters.ts +++ b/packages/server/src/sdk/app/tables/getters.ts @@ -142,7 +142,9 @@ export function enrichViewSchemas(table: Table): TableResponse { return { ...table, views: Object.values(table.views ?? []) - .map(v => sdk.views.enrichSchema(v, table.schema)) + .map(v => + sdk.views.isV2(v) ? sdk.views.enrichSchema(v, table.schema) : v + ) .reduce((p, v) => { p[v.name!] = v return p diff --git a/packages/server/src/sdk/app/views/external.ts b/packages/server/src/sdk/app/views/external.ts index 47301873f5..0f96bcc061 100644 --- a/packages/server/src/sdk/app/views/external.ts +++ b/packages/server/src/sdk/app/views/external.ts @@ -1,4 +1,4 @@ -import { ViewV2 } from "@budibase/types" +import { ViewV2, ViewV2Enriched } from "@budibase/types" import { context, HTTPError } from "@budibase/backend-core" import sdk from "../../../sdk" @@ -6,26 +6,34 @@ import * as utils from "../../../db/utils" import { enrichSchema, isV2 } from "." import { breakExternalTableId } from "../../../integrations/utils" -export async function get( - viewId: string, - opts?: { enriched: boolean } -): Promise { +export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) const { datasourceId, tableName } = breakExternalTableId(tableId) const ds = await sdk.datasources.get(datasourceId!) const table = ds.entities![tableName!] - const views = Object.values(table.views!) - const found = views.find(v => isV2(v) && v.id === viewId) + const views = Object.values(table.views!).filter(isV2) + const found = views.find(v => v.id === viewId) if (!found) { throw new Error("No view found") } - if (opts?.enriched) { - return enrichSchema(found, table.schema) as ViewV2 - } else { - return found as ViewV2 + return found +} + +export async function getEnriched(viewId: string): Promise { + const { tableId } = utils.extractViewInfoFromID(viewId) + + const { datasourceId, tableName } = breakExternalTableId(tableId) + const ds = await sdk.datasources.get(datasourceId!) + + const table = ds.entities![tableName!] + const views = Object.values(table.views!).filter(isV2) + const found = views.find(v => v.id === viewId) + if (!found) { + throw new Error("No view found") } + return enrichSchema(found, table.schema) } export async function create( diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 67e7158f21..9cfd2697f7 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -1,4 +1,10 @@ -import { RenameColumn, TableSchema, View, ViewV2 } from "@budibase/types" +import { + RenameColumn, + TableSchema, + View, + ViewV2, + ViewV2Enriched, +} from "@budibase/types" import { db as dbCore } from "@budibase/backend-core" import { cloneDeep } from "lodash" @@ -16,12 +22,14 @@ function pickApi(tableId: any) { return internal } -export async function get( - viewId: string, - opts?: { enriched: boolean } -): Promise { +export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) - return pickApi(tableId).get(viewId, opts) + return pickApi(tableId).get(viewId) +} + +export async function getEnriched(viewId: string): Promise { + const { tableId } = utils.extractViewInfoFromID(viewId) + return pickApi(tableId).getEnriched(viewId) } export async function create( @@ -52,7 +60,10 @@ export function allowedFields(view: View | ViewV2) { ] } -export function enrichSchema(view: View | ViewV2, tableSchema: TableSchema) { +export function enrichSchema( + view: ViewV2, + tableSchema: TableSchema +): ViewV2Enriched { if (!sdk.views.isV2(view)) { return view } diff --git a/packages/server/src/sdk/app/views/internal.ts b/packages/server/src/sdk/app/views/internal.ts index d1dedd8566..7b2f9f6c80 100644 --- a/packages/server/src/sdk/app/views/internal.ts +++ b/packages/server/src/sdk/app/views/internal.ts @@ -1,26 +1,30 @@ -import { ViewV2 } from "@budibase/types" +import { ViewV2, ViewV2Enriched } from "@budibase/types" import { context, HTTPError } from "@budibase/backend-core" import sdk from "../../../sdk" import * as utils from "../../../db/utils" import { enrichSchema, isV2 } from "." -export async function get( - viewId: string, - opts?: { enriched: boolean } -): Promise { +export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) const table = await sdk.tables.getTable(tableId) - const views = Object.values(table.views!) - const found = views.find(v => isV2(v) && v.id === viewId) + const views = Object.values(table.views!).filter(isV2) + const found = views.find(v => v.id === viewId) if (!found) { throw new Error("No view found") } - if (opts?.enriched) { - return enrichSchema(found, table.schema) as ViewV2 - } else { - return found as ViewV2 + return found +} + +export async function getEnriched(viewId: string): Promise { + const { tableId } = utils.extractViewInfoFromID(viewId) + const table = await sdk.tables.getTable(tableId) + const views = Object.values(table.views!).filter(isV2) + const found = views.find(v => v.id === viewId) + if (!found) { + throw new Error("No view found") } + return enrichSchema(found, table.schema) } export async function create( diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 2bc2357551..36aa935696 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -4,9 +4,9 @@ import { ViewV2, SearchViewRowRequest, PaginatedSearchRowResponse, + ViewV2Enriched, } from "@budibase/types" import { Expectations, TestAPI } from "./base" -import sdk from "../../../sdk" export class ViewV2API extends TestAPI { create = async ( @@ -44,10 +44,10 @@ export class ViewV2API extends TestAPI { return await this._delete(`/api/v2/views/${viewId}`, { expectations: exp }) } - get = async (viewId: string) => { - return await this.config.doInContext(this.config.appId, () => - sdk.views.get(viewId) - ) + get = async (viewId: string, expectations?: Expectations) => { + return await this._get(`/api/v2/views/${viewId}`, { + expectations, + }) } search = async ( diff --git a/packages/types/src/api/web/app/table.ts b/packages/types/src/api/web/app/table.ts index f4d6720516..ffe59ae395 100644 --- a/packages/types/src/api/web/app/table.ts +++ b/packages/types/src/api/web/app/table.ts @@ -3,16 +3,11 @@ import { Row, Table, TableRequest, - TableSchema, View, - ViewV2, + ViewV2Enriched, } from "../../../documents" -interface ViewV2Response extends ViewV2 { - schema: TableSchema -} - -export type TableViewsResponse = { [key: string]: View | ViewV2Response } +export type TableViewsResponse = { [key: string]: View | ViewV2Enriched } export interface TableResponse extends Table { views?: TableViewsResponse diff --git a/packages/types/src/api/web/app/view.ts b/packages/types/src/api/web/app/view.ts index 30e7bf77d7..c00bc0e468 100644 --- a/packages/types/src/api/web/app/view.ts +++ b/packages/types/src/api/web/app/view.ts @@ -1,14 +1,13 @@ -import { ViewV2, UIFieldMetadata } from "../../../documents" +import { ViewV2, ViewV2Enriched } from "../../../documents" export interface ViewResponse { data: ViewV2 } -export interface CreateViewRequest - extends Omit { - schema?: Record +export interface ViewResponseEnriched { + data: ViewV2Enriched } -export interface UpdateViewRequest extends Omit { - schema?: Record -} +export interface CreateViewRequest extends Omit {} + +export interface UpdateViewRequest extends ViewV2 {} diff --git a/packages/types/src/documents/app/view.ts b/packages/types/src/documents/app/view.ts index 7b93d24f3d..8a36b96b4e 100644 --- a/packages/types/src/documents/app/view.ts +++ b/packages/types/src/documents/app/view.ts @@ -1,5 +1,5 @@ import { SearchFilter, SortOrder, SortType } from "../../api" -import { UIFieldMetadata } from "./table" +import { TableSchema, UIFieldMetadata } from "./table" import { Document } from "../document" import { DBView } from "../../sdk" @@ -48,6 +48,10 @@ export interface ViewV2 { schema?: Record } +export interface ViewV2Enriched extends ViewV2 { + schema?: TableSchema +} + export type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema export interface ViewCountOrSumSchema { From d2c0842c4535008f4938ed972587ccc835466bcd Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 15:17:24 +0100 Subject: [PATCH 44/50] Fix viewV2 tests (for now) --- packages/server/src/api/controllers/view/viewsV2.ts | 5 +++-- packages/server/src/sdk/app/views/index.ts | 5 ----- packages/server/src/tests/utilities/api/viewV2.ts | 10 +++++----- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 00009ea17e..eb28883e15 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -6,6 +6,7 @@ import { UIFieldMetadata, UpdateViewRequest, ViewResponse, + ViewResponseEnriched, ViewV2, } from "@budibase/types" import { builderSocket, gridSocket } from "../../../websockets" @@ -39,9 +40,9 @@ async function parseSchema(view: CreateViewRequest) { return finalViewSchema } -export async function get(ctx: Ctx) { +export async function get(ctx: Ctx) { ctx.body = { - data: await sdk.views.get(ctx.params.viewId), + data: await sdk.views.getEnriched(ctx.params.viewId), } } diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 9cfd2697f7..2edfd900c4 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -8,7 +8,6 @@ import { import { db as dbCore } from "@budibase/backend-core" import { cloneDeep } from "lodash" -import sdk from "../../../sdk" import * as utils from "../../../db/utils" import { isExternalTableID } from "../../../integrations/utils" @@ -64,10 +63,6 @@ export function enrichSchema( view: ViewV2, tableSchema: TableSchema ): ViewV2Enriched { - if (!sdk.views.isV2(view)) { - return view - } - let schema = cloneDeep(tableSchema) const anyViewOrder = Object.values(view.schema || {}).some( ui => ui.order != null diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 36aa935696..53b67a23f8 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -4,9 +4,9 @@ import { ViewV2, SearchViewRowRequest, PaginatedSearchRowResponse, - ViewV2Enriched, } from "@budibase/types" import { Expectations, TestAPI } from "./base" +import sdk from "../../../sdk" export class ViewV2API extends TestAPI { create = async ( @@ -44,10 +44,10 @@ export class ViewV2API extends TestAPI { return await this._delete(`/api/v2/views/${viewId}`, { expectations: exp }) } - get = async (viewId: string, expectations?: Expectations) => { - return await this._get(`/api/v2/views/${viewId}`, { - expectations, - }) + get = async (viewId: string) => { + return await this.config.doInContext(this.config.getAppId(), () => + sdk.views.get(viewId) + ) } search = async ( From 8ad0729317b96222b341560066d7d985b57ee720 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 15:48:27 +0100 Subject: [PATCH 45/50] Fix ViewV2API.get to hit the API instead of using the sdk. --- .../server/src/api/routes/tests/viewV2.spec.ts | 14 +++++++------- packages/server/src/tests/utilities/api/viewV2.ts | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 1ed6b45a08..a4ecd7c818 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -181,7 +181,7 @@ describe.each([ const createdView = await config.api.viewV2.create(newView) - expect(await config.api.viewV2.get(createdView.id)).toEqual({ + expect(createdView).toEqual({ ...newView, schema: { Price: { @@ -398,7 +398,7 @@ describe.each([ }) it("updates only UI schema overrides", async () => { - await config.api.viewV2.update({ + const updatedView = await config.api.viewV2.update({ ...view, schema: { Price: { @@ -417,7 +417,7 @@ describe.each([ } as Record, }) - expect(await config.api.viewV2.get(view.id)).toEqual({ + expect(updatedView).toEqual({ ...view, schema: { Price: { @@ -479,17 +479,17 @@ describe.each([ describe("fetch view (through table)", () => { it("should be able to fetch a view V2", async () => { - const newView: CreateViewRequest = { + const res = await config.api.viewV2.create({ name: generator.name(), tableId: table._id!, schema: { Price: { visible: false }, Category: { visible: true }, }, - } - const res = await config.api.viewV2.create(newView) + }) + expect(res.schema?.Price).toBeUndefined() + const view = await config.api.viewV2.get(res.id) - expect(view!.schema?.Price).toBeUndefined() const updatedTable = await config.api.table.get(table._id!) const viewSchema = updatedTable.views![view!.name!].schema as Record< string, diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 53b67a23f8..653294188d 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -4,6 +4,7 @@ import { ViewV2, SearchViewRowRequest, PaginatedSearchRowResponse, + ViewResponseEnriched, } from "@budibase/types" import { Expectations, TestAPI } from "./base" import sdk from "../../../sdk" @@ -45,9 +46,8 @@ export class ViewV2API extends TestAPI { } get = async (viewId: string) => { - return await this.config.doInContext(this.config.getAppId(), () => - sdk.views.get(viewId) - ) + return (await this._get(`/api/v2/views/${viewId}`)) + .data } search = async ( From ee45efd6585fac8f058a0cba80e699dfef407e01 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 15:48:59 +0100 Subject: [PATCH 46/50] Remove unused import. --- packages/server/src/tests/utilities/api/viewV2.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 653294188d..9741240f27 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -7,7 +7,6 @@ import { ViewResponseEnriched, } from "@budibase/types" import { Expectations, TestAPI } from "./base" -import sdk from "../../../sdk" export class ViewV2API extends TestAPI { create = async ( From e1da9cbfa447df5641d197fa1177f8ce81d7bdd7 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 16:11:05 +0100 Subject: [PATCH 47/50] Fix types. --- packages/server/src/api/routes/tests/table.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index d96e76874f..71ff673881 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -13,7 +13,7 @@ import { TableSourceType, User, ViewCalculation, - ViewV2, + ViewV2Enriched, } from "@budibase/types" import { checkBuilderEndpoint } from "./utilities/TestFunctions" import * as setup from "./utilities" @@ -311,7 +311,7 @@ describe.each([ expect(table).toBeDefined() expect(table!.views![viewV2.name]).toBeDefined() - const expectedViewV2: ViewV2 = { + const expectedViewV2: ViewV2Enriched = { ...viewV2, schema: { description: { From 6a657625ae364a273d4b4c44c8b288c89edaf2af Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 8 Apr 2024 16:46:27 +0100 Subject: [PATCH 48/50] =?UTF-8?q?Uncomment=20tests=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/server/src/api/routes/tests/table.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 71ff673881..7639b840dc 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -28,11 +28,11 @@ const { basicTable } = setup.structures const ISO_REGEX_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/ describe.each([ - // ["internal", undefined], - // [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], - // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], + ["internal", undefined], + [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], + [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], - // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], + [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], ])("/tables (%s)", (_, dsProvider) => { let isInternal: boolean let datasource: Datasource | undefined From dde52c6f93ec5ac559307ba11fa6c70bdda92588 Mon Sep 17 00:00:00 2001 From: Christos Alexiou Date: Mon, 8 Apr 2024 19:08:04 +0300 Subject: [PATCH 49/50] Remove condition for looking up existing secret --- charts/budibase/templates/secrets.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/budibase/templates/secrets.yaml b/charts/budibase/templates/secrets.yaml index 263934187e..73ce25dc84 100644 --- a/charts/budibase/templates/secrets.yaml +++ b/charts/budibase/templates/secrets.yaml @@ -1,4 +1,3 @@ -{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "budibase.fullname" .) }} {{- if .Values.globals.createSecrets }} apiVersion: v1 kind: Secret @@ -21,5 +20,4 @@ data: jwtSecret: {{ template "budibase.defaultsecret" .Values.globals.jwtSecret }} objectStoreAccess: {{ template "budibase.defaultsecret" .Values.services.objectStore.accessKey }} objectStoreSecret: {{ template "budibase.defaultsecret" .Values.services.objectStore.secretKey }} - {{- end }} {{- end }} From 799d60beed38703ff851bb10114ff1c8f12a4e1d Mon Sep 17 00:00:00 2001 From: Christos Alexiou Date: Mon, 8 Apr 2024 19:17:55 +0300 Subject: [PATCH 50/50] Revert "Remove condition for looking up existing secret" This reverts commit dde52c6f93ec5ac559307ba11fa6c70bdda92588. --- charts/budibase/templates/secrets.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/budibase/templates/secrets.yaml b/charts/budibase/templates/secrets.yaml index 73ce25dc84..263934187e 100644 --- a/charts/budibase/templates/secrets.yaml +++ b/charts/budibase/templates/secrets.yaml @@ -1,3 +1,4 @@ +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "budibase.fullname" .) }} {{- if .Values.globals.createSecrets }} apiVersion: v1 kind: Secret @@ -20,4 +21,5 @@ data: jwtSecret: {{ template "budibase.defaultsecret" .Values.globals.jwtSecret }} objectStoreAccess: {{ template "budibase.defaultsecret" .Values.services.objectStore.accessKey }} objectStoreSecret: {{ template "budibase.defaultsecret" .Values.services.objectStore.secretKey }} + {{- end }} {{- end }}