@budibase/server 1.0.49 → 1.0.50-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/arangojs.ts +1 -1
- package/__mocks__/aws-sdk.ts +4 -4
- package/__mocks__/mongodb.ts +4 -5
- package/__mocks__/mssql.ts +3 -3
- package/__mocks__/node-fetch.ts +2 -1
- package/__mocks__/pg.ts +3 -5
- package/builder/assets/index.c0cc369d.css +6 -0
- package/builder/assets/{index.2c37968e.js → index.ff2bad21.js} +252 -249
- package/builder/assets/{vendor.f9faf6ab.js → vendor.5ad9695a.js} +202 -106
- package/builder/index.html +3 -3
- package/coverage/clover.xml +3105 -2814
- package/coverage/coverage-final.json +106 -101
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +257 -152
- package/coverage/lcov-report/api/controllers/auth.js.html +22 -13
- package/coverage/lcov-report/api/controllers/automation.js.html +39 -69
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +8 -11
- package/coverage/lcov-report/api/controllers/component.js.html +13 -16
- package/coverage/lcov-report/api/controllers/datasource.js.html +81 -51
- package/coverage/lcov-report/api/controllers/dev.js.html +6 -6
- package/coverage/lcov-report/api/controllers/index.html +78 -78
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
- package/coverage/lcov-report/api/controllers/metadata.js.html +6 -21
- package/coverage/lcov-report/api/controllers/migrations.js.html +119 -0
- package/coverage/lcov-report/api/controllers/permission.js.html +19 -19
- package/coverage/lcov-report/api/controllers/query/index.html +10 -10
- package/coverage/lcov-report/api/controllers/query/index.js.html +38 -35
- package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
- package/coverage/lcov-report/api/controllers/role.js.html +16 -16
- package/coverage/lcov-report/api/controllers/routing.js.html +7 -10
- package/coverage/lcov-report/api/controllers/row/external.js.html +48 -141
- package/coverage/lcov-report/api/controllers/row/index.html +55 -40
- package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
- package/coverage/lcov-report/api/controllers/row/internal.js.html +118 -226
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +52 -34
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +548 -0
- package/coverage/lcov-report/api/controllers/row/utils.js.html +47 -62
- package/coverage/lcov-report/api/controllers/screen.js.html +15 -21
- package/coverage/lcov-report/api/controllers/script.js.html +4 -4
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +599 -0
- package/coverage/lcov-report/api/controllers/table/external.js.html +25 -34
- package/coverage/lcov-report/api/controllers/table/index.html +58 -43
- package/coverage/lcov-report/api/controllers/table/index.js.html +58 -82
- package/coverage/lcov-report/api/controllers/table/internal.js.html +81 -66
- package/coverage/lcov-report/api/controllers/table/utils.js.html +218 -110
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +79 -76
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
- package/coverage/lcov-report/api/controllers/view/index.html +16 -16
- package/coverage/lcov-report/api/controllers/view/index.js.html +27 -33
- package/coverage/lcov-report/api/controllers/view/utils.js.html +35 -20
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
- package/coverage/lcov-report/api/controllers/webhook.js.html +34 -28
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +8 -8
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +18 -18
- package/coverage/lcov-report/api/routes/index.js.html +3 -3
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/{hosting.js.html → migrations.js.html} +17 -14
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +1 -1
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +17 -2
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +1 -1
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +24 -24
- package/coverage/lcov-report/automations/automationUtils.js.html +7 -10
- package/coverage/lcov-report/automations/bullboard.js.html +16 -16
- package/coverage/lcov-report/automations/index.html +18 -18
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
- package/coverage/lcov-report/automations/steps/createRow.js.html +13 -22
- package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +11 -20
- package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
- package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
- package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
- package/coverage/lcov-report/automations/steps/index.html +13 -13
- package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
- package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
- package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
- package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
- package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
- package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +61 -55
- package/coverage/lcov-report/automations/utils.js.html +54 -42
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +53 -26
- package/coverage/lcov-report/constants/layouts.js.html +5 -5
- package/coverage/lcov-report/constants/screens.js.html +4 -4
- package/coverage/lcov-report/db/client.js.html +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +25 -37
- package/coverage/lcov-report/db/linkedRows/index.html +27 -27
- package/coverage/lcov-report/db/linkedRows/index.js.html +51 -96
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +42 -42
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +87 -87
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +5 -5
- package/coverage/lcov-report/events/utils.js.html +3 -3
- package/coverage/lcov-report/index.html +135 -120
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +173 -65
- package/coverage/lcov-report/middleware/builder.js.html +10 -10
- package/coverage/lcov-report/middleware/currentapp.js.html +95 -83
- package/coverage/lcov-report/middleware/index.html +38 -38
- package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +281 -53
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +30 -24
- package/coverage/lcov-report/threads/index.html +26 -26
- package/coverage/lcov-report/threads/index.js.html +10 -10
- package/coverage/lcov-report/threads/query.js.html +39 -24
- package/coverage/lcov-report/threads/utils.js.html +14 -14
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
- package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
- package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
- package/coverage/lcov-report/utilities/global.js.html +58 -49
- package/coverage/lcov-report/utilities/index.html +37 -37
- package/coverage/lcov-report/utilities/index.js.html +43 -73
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +7 -7
- package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +97 -103
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +75 -27
- package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
- package/coverage/lcov-report/utilities/security.js.html +8 -8
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +141 -0
- package/coverage/lcov-report/utilities/usageQuota/index.js.html +359 -0
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +305 -0
- package/coverage/lcov-report/{api/controllers/hosting.js.html → utilities/usageQuota/usageQuoteReset.js.html} +36 -48
- package/coverage/lcov-report/utilities/users.js.html +9 -9
- package/coverage/lcov-report/utilities/workerRequests.js.html +43 -112
- package/coverage/lcov.info +5010 -4425
- package/dist/api/controllers/application.js +90 -60
- package/dist/api/controllers/auth.js +8 -5
- package/dist/api/controllers/automation.js +14 -19
- package/dist/api/controllers/cloud.js +2 -3
- package/dist/api/controllers/component.js +3 -4
- package/dist/api/controllers/datasource.js +20 -10
- package/dist/api/controllers/deploy/Deployment.js +3 -6
- package/dist/api/controllers/deploy/index.js +12 -13
- package/dist/api/controllers/dev.js +5 -5
- package/dist/api/controllers/layout.js +3 -3
- package/dist/api/controllers/metadata.js +4 -4
- package/dist/api/controllers/migrations.js +21 -0
- package/dist/api/controllers/permission.js +4 -4
- package/dist/api/controllers/query/import/index.js +4 -6
- package/dist/api/controllers/query/index.js +11 -10
- package/dist/api/controllers/role.js +5 -5
- package/dist/api/controllers/routing.js +5 -6
- package/dist/api/controllers/row/ExternalRequest.js +90 -67
- package/dist/api/controllers/row/external.js +14 -22
- package/dist/api/controllers/row/internal.js +55 -93
- package/dist/api/controllers/row/internalSearch.js +23 -17
- package/dist/api/controllers/row/staticFormula.js +147 -0
- package/dist/api/controllers/row/utils.js +13 -14
- package/dist/api/controllers/screen.js +5 -7
- package/dist/api/controllers/static/index.js +62 -16
- package/dist/api/controllers/table/bulkFormula.js +159 -0
- package/dist/api/controllers/table/external.js +7 -10
- package/dist/api/controllers/table/index.js +16 -13
- package/dist/api/controllers/table/internal.js +22 -16
- package/dist/api/controllers/table/utils.js +62 -35
- package/dist/api/controllers/user.js +43 -43
- package/dist/api/controllers/view/index.js +8 -10
- package/dist/api/controllers/view/utils.js +9 -4
- package/dist/api/controllers/webhook.js +10 -8
- package/dist/api/routes/index.js +2 -2
- package/dist/api/routes/migrations.js +9 -0
- package/dist/api/routes/static.js +2 -1
- package/dist/api/routes/tests/utilities/TestFunctions.js +37 -17
- package/dist/app.js +35 -5
- package/dist/automations/automationUtils.js +2 -3
- package/dist/automations/steps/createRow.js +3 -5
- package/dist/automations/steps/deleteRow.js +1 -4
- package/dist/automations/steps/updateRow.js +1 -1
- package/dist/automations/triggers.js +27 -25
- package/dist/automations/utils.js +10 -5
- package/dist/constants/index.js +7 -0
- package/dist/db/linkedRows/LinkController.js +3 -7
- package/dist/db/linkedRows/index.js +16 -27
- package/dist/db/linkedRows/linkUtils.js +6 -6
- package/dist/db/views/staticViews.js +9 -10
- package/dist/definitions/datasource.js +1 -0
- package/dist/environment.js +4 -1
- package/dist/integrations/base/sql.js +62 -21
- package/dist/integrations/googlesheets.js +340 -0
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/utils.js +60 -9
- package/dist/middleware/authorized.js +57 -30
- package/dist/middleware/builder.js +2 -2
- package/dist/middleware/currentapp.js +41 -37
- package/dist/middleware/usageQuota.js +82 -15
- package/dist/migrations/functions/appUrls.js +46 -0
- package/dist/migrations/functions/quotas1.js +50 -0
- package/dist/migrations/functions/usageQuotas/index.js +20 -0
- package/dist/migrations/functions/usageQuotas/syncApps.js +29 -0
- package/dist/migrations/functions/usageQuotas/syncRows.js +33 -0
- package/dist/migrations/functions/userEmailViewCasing.js +24 -0
- package/dist/migrations/index.js +62 -0
- package/dist/package.json +8 -5
- package/dist/tests/utilities/TestConfiguration.js +80 -50
- package/dist/threads/automation.js +13 -11
- package/dist/threads/query.js +15 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +4 -3
- package/dist/utilities/global.js +15 -12
- package/dist/utilities/index.js +7 -17
- package/dist/utilities/routing/index.js +5 -5
- package/dist/utilities/rowProcessor/index.js +23 -17
- package/dist/utilities/rowProcessor/utils.js +14 -4
- package/dist/utilities/{usageQuota.js → usageQuota/index.js} +45 -31
- package/dist/utilities/usageQuota/rows.js +78 -0
- package/dist/utilities/usageQuota/usageQuoteReset.js +16 -0
- package/dist/utilities/users.js +3 -3
- package/dist/utilities/workerRequests.js +4 -24
- package/nodemon.json +1 -1
- package/package.json +9 -6
- package/scripts/integrations/mssql/data/Dockerfile +1 -1
- package/scripts/integrations/mssql/data/setup.sql +17 -4
- package/scripts/integrations/postgres/init.sql +11 -6
- package/scripts/likeCypress.ts +1 -1
- package/src/api/controllers/application.js +85 -50
- package/src/api/controllers/auth.js +8 -5
- package/src/api/controllers/automation.js +13 -23
- package/src/api/controllers/cloud.js +2 -3
- package/src/api/controllers/component.js +3 -4
- package/src/api/controllers/datasource.js +21 -11
- package/src/api/controllers/deploy/Deployment.js +3 -7
- package/src/api/controllers/deploy/index.js +20 -13
- package/src/api/controllers/dev.js +5 -5
- package/src/api/controllers/layout.js +3 -3
- package/src/api/controllers/metadata.js +4 -9
- package/src/api/controllers/migrations.js +13 -0
- package/src/api/controllers/permission.js +4 -4
- package/src/api/controllers/query/import/index.ts +4 -6
- package/src/api/controllers/query/import/tests/index.spec.js +2 -1
- package/src/api/controllers/query/index.js +11 -10
- package/src/api/controllers/role.js +5 -5
- package/src/api/controllers/routing.js +5 -6
- package/src/api/controllers/row/ExternalRequest.ts +67 -43
- package/src/api/controllers/row/external.js +27 -58
- package/src/api/controllers/row/internal.js +54 -90
- package/src/api/controllers/row/internalSearch.js +23 -17
- package/src/api/controllers/row/staticFormula.js +156 -0
- package/src/api/controllers/row/utils.js +13 -18
- package/src/api/controllers/screen.js +5 -7
- package/src/api/controllers/static/index.js +66 -15
- package/src/api/controllers/table/bulkFormula.js +173 -0
- package/src/api/controllers/table/external.js +7 -10
- package/src/api/controllers/table/index.js +20 -28
- package/src/api/controllers/table/internal.js +24 -19
- package/src/api/controllers/table/utils.js +78 -42
- package/src/api/controllers/user.js +46 -45
- package/src/api/controllers/view/index.js +8 -10
- package/src/api/controllers/view/utils.js +9 -4
- package/src/api/controllers/webhook.js +10 -8
- package/src/api/routes/index.js +2 -2
- package/src/api/routes/migrations.js +14 -0
- package/src/api/routes/static.js +5 -0
- package/src/api/routes/tests/application.spec.js +2 -2
- package/src/api/routes/tests/auth.spec.js +1 -2
- package/src/api/routes/tests/automation.spec.js +1 -0
- package/src/api/routes/tests/misc.spec.js +0 -1
- package/src/api/routes/tests/routing.spec.js +21 -12
- package/src/api/routes/tests/row.spec.js +7 -4
- package/src/api/routes/tests/static.spec.js +98 -0
- package/src/api/routes/tests/utilities/TestFunctions.js +39 -17
- package/src/app.ts +18 -5
- package/src/automations/automationUtils.js +2 -3
- package/src/automations/steps/createRow.js +2 -5
- package/src/automations/steps/deleteRow.js +1 -4
- package/src/automations/steps/updateRow.js +1 -1
- package/src/automations/triggers.js +33 -31
- package/src/automations/utils.js +9 -5
- package/src/constants/index.js +9 -0
- package/src/db/linkedRows/LinkController.js +3 -7
- package/src/db/linkedRows/index.js +16 -31
- package/src/db/linkedRows/linkUtils.js +6 -6
- package/src/db/tests/linkController.spec.js +0 -1
- package/src/db/tests/linkTests.spec.js +5 -6
- package/src/db/views/staticViews.js +8 -10
- package/src/definitions/common.ts +3 -0
- package/src/definitions/datasource.ts +3 -0
- package/src/environment.js +4 -1
- package/src/integrations/base/sql.ts +75 -29
- package/src/integrations/googlesheets.ts +353 -0
- package/src/integrations/index.ts +3 -0
- package/src/integrations/tests/sql.spec.js +16 -0
- package/src/integrations/utils.ts +75 -12
- package/src/middleware/authorized.js +66 -30
- package/src/middleware/builder.js +2 -2
- package/src/middleware/currentapp.js +50 -46
- package/src/middleware/tests/authorized.spec.js +13 -6
- package/src/middleware/tests/currentapp.spec.js +6 -0
- package/src/middleware/tests/usageQuota.spec.js +18 -24
- package/src/middleware/usageQuota.js +93 -17
- package/src/migrations/functions/appUrls.ts +34 -0
- package/src/migrations/functions/quotas1.ts +20 -0
- package/src/migrations/functions/tests/appUrls.spec.js +29 -0
- package/src/migrations/functions/tests/quotas1.spec.js +27 -0
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +25 -0
- package/src/migrations/functions/usageQuotas/index.ts +8 -0
- package/src/migrations/functions/usageQuotas/syncApps.ts +18 -0
- package/src/migrations/functions/usageQuotas/syncRows.ts +22 -0
- package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +37 -0
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +43 -0
- package/src/migrations/functions/userEmailViewCasing.ts +13 -0
- package/src/migrations/index.ts +56 -0
- package/src/module.d.ts +3 -0
- package/src/tests/utilities/TestConfiguration.js +82 -55
- package/src/threads/automation.js +17 -15
- package/src/threads/query.js +17 -12
- package/src/utilities/fileSystem/index.js +4 -3
- package/src/utilities/global.js +15 -12
- package/src/utilities/index.js +7 -17
- package/src/utilities/routing/index.js +5 -5
- package/src/utilities/rowProcessor/index.js +25 -27
- package/src/utilities/rowProcessor/utils.js +23 -7
- package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
- package/src/utilities/usageQuota/index.js +93 -0
- package/src/utilities/usageQuota/rows.js +75 -0
- package/src/utilities/usageQuota/usageQuoteReset.js +18 -0
- package/src/utilities/users.js +3 -3
- package/src/utilities/workerRequests.js +4 -27
- package/tsconfig.json +2 -1
- package/builder/assets/index.39e01193.css +0 -1
- package/dist/api/controllers/hosting.js +0 -30
- package/dist/api/routes/hosting.js +0 -11
- package/src/api/controllers/hosting.js +0 -22
- package/src/api/routes/hosting.js +0 -13
- package/src/api/routes/tests/hosting.spec.js +0 -36
- package/src/utilities/usageQuota.js +0 -73
|
@@ -69,10 +69,16 @@ class InternalBuilder {
|
|
|
69
69
|
this.client = client;
|
|
70
70
|
}
|
|
71
71
|
// right now we only do filters on the specific table being queried
|
|
72
|
-
addFilters(
|
|
72
|
+
addFilters(query, filters, opts) {
|
|
73
73
|
function iterate(structure, fn) {
|
|
74
74
|
for (let [key, value] of Object.entries(structure)) {
|
|
75
|
-
|
|
75
|
+
const isRelationshipField = key.includes(".");
|
|
76
|
+
if (!opts.relationship && !isRelationshipField) {
|
|
77
|
+
fn(`${opts.tableName}.${key}`, value);
|
|
78
|
+
}
|
|
79
|
+
if (opts.relationship && isRelationshipField) {
|
|
80
|
+
fn(key, value);
|
|
81
|
+
}
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
if (!filters) {
|
|
@@ -153,15 +159,14 @@ class InternalBuilder {
|
|
|
153
159
|
addSorting(query, json) {
|
|
154
160
|
var _a;
|
|
155
161
|
let { sort, paginate } = json;
|
|
156
|
-
if (!sort) {
|
|
157
|
-
return query;
|
|
158
|
-
}
|
|
159
162
|
const table = (_a = json.meta) === null || _a === void 0 ? void 0 : _a.table;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
if (sort) {
|
|
164
|
+
for (let [key, value] of Object.entries(sort)) {
|
|
165
|
+
const direction = value === datasource_1.SortDirection.ASCENDING ? "asc" : "desc";
|
|
166
|
+
query = query.orderBy(`${table === null || table === void 0 ? void 0 : table.name}.${key}`, direction);
|
|
167
|
+
}
|
|
163
168
|
}
|
|
164
|
-
if (this.client === utils_1.SqlClients.MS_SQL &&
|
|
169
|
+
else if (this.client === utils_1.SqlClients.MS_SQL && (paginate === null || paginate === void 0 ? void 0 : paginate.limit)) {
|
|
165
170
|
// @ts-ignore
|
|
166
171
|
query = query.orderBy(`${table === null || table === void 0 ? void 0 : table.name}.${table === null || table === void 0 ? void 0 : table.primary[0]}`);
|
|
167
172
|
}
|
|
@@ -171,20 +176,55 @@ class InternalBuilder {
|
|
|
171
176
|
if (!relationships) {
|
|
172
177
|
return query;
|
|
173
178
|
}
|
|
179
|
+
const tableSets = {};
|
|
180
|
+
// aggregate into table sets (all the same to tables)
|
|
174
181
|
for (let relationship of relationships) {
|
|
175
|
-
const
|
|
176
|
-
|
|
182
|
+
const keyObj = {
|
|
183
|
+
toTable: relationship.tableName,
|
|
184
|
+
throughTable: undefined,
|
|
185
|
+
};
|
|
186
|
+
if (relationship.through) {
|
|
187
|
+
keyObj.throughTable = relationship.through;
|
|
188
|
+
}
|
|
189
|
+
const key = JSON.stringify(keyObj);
|
|
190
|
+
if (tableSets[key]) {
|
|
191
|
+
tableSets[key].push(relationship);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
tableSets[key] = [relationship];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (let [key, relationships] of Object.entries(tableSets)) {
|
|
198
|
+
const { toTable, throughTable } = JSON.parse(key);
|
|
199
|
+
if (!throughTable) {
|
|
177
200
|
// @ts-ignore
|
|
178
|
-
query = query.
|
|
201
|
+
query = query.join(toTable, function () {
|
|
202
|
+
for (let relationship of relationships) {
|
|
203
|
+
const from = relationship.from, to = relationship.to;
|
|
204
|
+
// @ts-ignore
|
|
205
|
+
this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`);
|
|
206
|
+
}
|
|
207
|
+
}, "left");
|
|
179
208
|
}
|
|
180
209
|
else {
|
|
181
|
-
const throughTable = relationship.through;
|
|
182
|
-
const fromPrimary = relationship.fromPrimary;
|
|
183
|
-
const toPrimary = relationship.toPrimary;
|
|
184
210
|
query = query
|
|
185
211
|
// @ts-ignore
|
|
186
|
-
.
|
|
187
|
-
|
|
212
|
+
.join(throughTable, function () {
|
|
213
|
+
for (let relationship of relationships) {
|
|
214
|
+
const fromPrimary = relationship.fromPrimary;
|
|
215
|
+
const from = relationship.from;
|
|
216
|
+
// @ts-ignore
|
|
217
|
+
this.orOn(`${fromTable}.${fromPrimary}`, "=", `${throughTable}.${from}`);
|
|
218
|
+
}
|
|
219
|
+
}, "left")
|
|
220
|
+
.join(toTable, function () {
|
|
221
|
+
for (let relationship of relationships) {
|
|
222
|
+
const toPrimary = relationship.toPrimary;
|
|
223
|
+
const to = relationship.to;
|
|
224
|
+
// @ts-ignore
|
|
225
|
+
this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`);
|
|
226
|
+
}
|
|
227
|
+
}, "left");
|
|
188
228
|
}
|
|
189
229
|
}
|
|
190
230
|
return query.limit(BASE_LIMIT);
|
|
@@ -248,7 +288,7 @@ class InternalBuilder {
|
|
|
248
288
|
if (foundOffset) {
|
|
249
289
|
query = query.offset(foundOffset);
|
|
250
290
|
}
|
|
251
|
-
query = this.addFilters(
|
|
291
|
+
query = this.addFilters(query, filters, { tableName });
|
|
252
292
|
// add sorting to pre-query
|
|
253
293
|
query = this.addSorting(query, json);
|
|
254
294
|
// @ts-ignore
|
|
@@ -261,13 +301,14 @@ class InternalBuilder {
|
|
|
261
301
|
preQuery = this.addSorting(preQuery, json);
|
|
262
302
|
}
|
|
263
303
|
// handle joins
|
|
264
|
-
|
|
304
|
+
query = this.addRelationships(knex, preQuery, selectStatement, tableName, relationships);
|
|
305
|
+
return this.addFilters(query, filters, { relationship: true });
|
|
265
306
|
}
|
|
266
307
|
update(knex, json, opts) {
|
|
267
308
|
const { endpoint, body, filters } = json;
|
|
268
309
|
let query = knex(endpoint.entityId);
|
|
269
310
|
const parsedBody = parseBody(body);
|
|
270
|
-
query = this.addFilters(endpoint.entityId
|
|
311
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId });
|
|
271
312
|
// mysql can't use returning
|
|
272
313
|
if (opts.disableReturning) {
|
|
273
314
|
return query.update(parsedBody);
|
|
@@ -279,7 +320,7 @@ class InternalBuilder {
|
|
|
279
320
|
delete(knex, json, opts) {
|
|
280
321
|
const { endpoint, filters } = json;
|
|
281
322
|
let query = knex(endpoint.entityId);
|
|
282
|
-
query = this.addFilters(endpoint.entityId
|
|
323
|
+
query = this.addFilters(query, filters, { tableName: endpoint.entityId });
|
|
283
324
|
// mysql can't use returning
|
|
284
325
|
if (opts.disableReturning) {
|
|
285
326
|
return query.delete();
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const datasource_1 = require("../definitions/datasource");
|
|
13
|
+
const google_auth_library_1 = require("google-auth-library");
|
|
14
|
+
const utils_1 = require("./utils");
|
|
15
|
+
const constants_1 = require("../constants");
|
|
16
|
+
const google_spreadsheet_1 = require("google-spreadsheet");
|
|
17
|
+
var GoogleSheetsModule;
|
|
18
|
+
(function (GoogleSheetsModule) {
|
|
19
|
+
const { getGlobalDB } = require("@budibase/backend-core/tenancy");
|
|
20
|
+
const { getScopedConfig } = require("@budibase/backend-core/db");
|
|
21
|
+
const { Configs } = require("@budibase/backend-core/constants");
|
|
22
|
+
const SCHEMA = {
|
|
23
|
+
plus: true,
|
|
24
|
+
auth: {
|
|
25
|
+
type: "google",
|
|
26
|
+
},
|
|
27
|
+
relationships: false,
|
|
28
|
+
docs: "https://developers.google.com/sheets/api/quickstart/nodejs",
|
|
29
|
+
description: "Create and collaborate on online spreadsheets in real-time and from any device. ",
|
|
30
|
+
friendlyName: "Google Sheets",
|
|
31
|
+
datasource: {
|
|
32
|
+
spreadsheetId: {
|
|
33
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
34
|
+
required: true,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
query: {
|
|
38
|
+
create: {
|
|
39
|
+
type: datasource_1.QueryTypes.FIELDS,
|
|
40
|
+
fields: {
|
|
41
|
+
sheet: {
|
|
42
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
row: {
|
|
46
|
+
type: datasource_1.QueryTypes.JSON,
|
|
47
|
+
required: true,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
read: {
|
|
52
|
+
type: datasource_1.QueryTypes.FIELDS,
|
|
53
|
+
fields: {
|
|
54
|
+
sheet: {
|
|
55
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
56
|
+
required: true,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
update: {
|
|
61
|
+
type: datasource_1.QueryTypes.FIELDS,
|
|
62
|
+
fields: {
|
|
63
|
+
sheet: {
|
|
64
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
65
|
+
required: true,
|
|
66
|
+
},
|
|
67
|
+
rowIndex: {
|
|
68
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
69
|
+
required: true,
|
|
70
|
+
},
|
|
71
|
+
row: {
|
|
72
|
+
type: datasource_1.QueryTypes.JSON,
|
|
73
|
+
required: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
delete: {
|
|
78
|
+
type: datasource_1.QueryTypes.FIELDS,
|
|
79
|
+
fields: {
|
|
80
|
+
sheet: {
|
|
81
|
+
type: datasource_1.DatasourceFieldTypes.STRING,
|
|
82
|
+
required: true,
|
|
83
|
+
},
|
|
84
|
+
rowIndex: {
|
|
85
|
+
type: datasource_1.DatasourceFieldTypes.NUMBER,
|
|
86
|
+
required: true,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
class GoogleSheetsIntegration {
|
|
93
|
+
constructor(config) {
|
|
94
|
+
this.tables = {};
|
|
95
|
+
this.schemaErrors = {};
|
|
96
|
+
this.config = config;
|
|
97
|
+
const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId);
|
|
98
|
+
this.client = new google_spreadsheet_1.GoogleSpreadsheet(spreadsheetId);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Pull the spreadsheet ID out from a valid google sheets URL
|
|
102
|
+
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
|
|
103
|
+
* @returns spreadsheet Id of the google sheet
|
|
104
|
+
*/
|
|
105
|
+
cleanSpreadsheetUrl(spreadsheetId) {
|
|
106
|
+
if (!spreadsheetId) {
|
|
107
|
+
throw new Error("You must set a spreadsheet ID in your configuration to fetch tables.");
|
|
108
|
+
}
|
|
109
|
+
const parts = spreadsheetId.split("/");
|
|
110
|
+
return parts.length > 5 ? parts[5] : spreadsheetId;
|
|
111
|
+
}
|
|
112
|
+
connect() {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
try {
|
|
115
|
+
// Initialise oAuth client
|
|
116
|
+
const db = getGlobalDB();
|
|
117
|
+
const googleConfig = yield getScopedConfig(db, {
|
|
118
|
+
type: Configs.GOOGLE,
|
|
119
|
+
});
|
|
120
|
+
const oauthClient = new google_auth_library_1.OAuth2Client({
|
|
121
|
+
clientId: googleConfig.clientID,
|
|
122
|
+
clientSecret: googleConfig.clientSecret,
|
|
123
|
+
});
|
|
124
|
+
oauthClient.credentials.access_token = this.config.auth.accessToken;
|
|
125
|
+
oauthClient.credentials.refresh_token = this.config.auth.refreshToken;
|
|
126
|
+
this.client.useOAuth2Client(oauthClient);
|
|
127
|
+
yield this.client.loadInfo();
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
console.error("Error connecting to google sheets", err);
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
buildSchema(datasourceId) {
|
|
136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
yield this.connect();
|
|
138
|
+
const sheets = yield this.client.sheetsByIndex;
|
|
139
|
+
const tables = {};
|
|
140
|
+
for (let sheet of sheets) {
|
|
141
|
+
// must fetch rows to determine schema
|
|
142
|
+
yield sheet.getRows();
|
|
143
|
+
// build schema
|
|
144
|
+
const schema = {};
|
|
145
|
+
// build schema from headers
|
|
146
|
+
for (let header of sheet.headerValues) {
|
|
147
|
+
schema[header] = {
|
|
148
|
+
name: header,
|
|
149
|
+
type: constants_1.FieldTypes.STRING,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// create tables
|
|
153
|
+
tables[sheet.title] = {
|
|
154
|
+
_id: utils_1.buildExternalTableId(datasourceId, sheet.title),
|
|
155
|
+
name: sheet.title,
|
|
156
|
+
primary: ["rowNumber"],
|
|
157
|
+
schema,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
this.tables = tables;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
query(json) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
const sheet = json.endpoint.entityId;
|
|
166
|
+
const handlers = {
|
|
167
|
+
[constants_1.DataSourceOperation.CREATE]: () => this.create({ sheet, row: json.body }),
|
|
168
|
+
[constants_1.DataSourceOperation.READ]: () => this.read({ sheet }),
|
|
169
|
+
[constants_1.DataSourceOperation.UPDATE]: () => {
|
|
170
|
+
var _a, _b, _c;
|
|
171
|
+
return this.update({
|
|
172
|
+
// exclude the header row and zero index
|
|
173
|
+
rowIndex: ((_c = (_b = (_a = json.extra) === null || _a === void 0 ? void 0 : _a.idFilter) === null || _b === void 0 ? void 0 : _b.equal) === null || _c === void 0 ? void 0 : _c.rowNumber) - 2,
|
|
174
|
+
sheet,
|
|
175
|
+
row: json.body,
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
[constants_1.DataSourceOperation.DELETE]: () => {
|
|
179
|
+
var _a, _b, _c;
|
|
180
|
+
return this.delete({
|
|
181
|
+
// exclude the header row and zero index
|
|
182
|
+
rowIndex: ((_c = (_b = (_a = json.extra) === null || _a === void 0 ? void 0 : _a.idFilter) === null || _b === void 0 ? void 0 : _b.equal) === null || _c === void 0 ? void 0 : _c.rowNumber) - 2,
|
|
183
|
+
sheet,
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
[constants_1.DataSourceOperation.CREATE_TABLE]: () => { var _a; return this.createTable((_a = json === null || json === void 0 ? void 0 : json.table) === null || _a === void 0 ? void 0 : _a.name); },
|
|
187
|
+
[constants_1.DataSourceOperation.UPDATE_TABLE]: () => this.updateTable(json.table),
|
|
188
|
+
[constants_1.DataSourceOperation.DELETE_TABLE]: () => { var _a; return this.deleteTable((_a = json === null || json === void 0 ? void 0 : json.table) === null || _a === void 0 ? void 0 : _a.name); },
|
|
189
|
+
};
|
|
190
|
+
const internalQueryMethod = handlers[json.endpoint.operation];
|
|
191
|
+
return yield internalQueryMethod();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
buildRowObject(headers, values, rowNumber) {
|
|
195
|
+
const rowObject = { rowNumber };
|
|
196
|
+
for (let i = 0; i < headers.length; i++) {
|
|
197
|
+
rowObject._id = rowNumber;
|
|
198
|
+
rowObject[headers[i]] = values[i];
|
|
199
|
+
}
|
|
200
|
+
return rowObject;
|
|
201
|
+
}
|
|
202
|
+
createTable(name) {
|
|
203
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
try {
|
|
205
|
+
yield this.connect();
|
|
206
|
+
const sheet = yield this.client.addSheet({ title: name });
|
|
207
|
+
return sheet;
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
console.error("Error creating new table in google sheets", err);
|
|
211
|
+
throw err;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
updateTable(table) {
|
|
216
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
217
|
+
try {
|
|
218
|
+
yield this.connect();
|
|
219
|
+
const sheet = yield this.client.sheetsByTitle[table.name];
|
|
220
|
+
yield sheet.loadHeaderRow();
|
|
221
|
+
if (table._rename) {
|
|
222
|
+
const headers = [];
|
|
223
|
+
for (let header of sheet.headerValues) {
|
|
224
|
+
if (header === table._rename.old) {
|
|
225
|
+
headers.push(table._rename.updated);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
headers.push(header);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
yield sheet.setHeaderRow(headers);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
let newField = Object.keys(table.schema).find(key => !sheet.headerValues.includes(key));
|
|
235
|
+
yield sheet.setHeaderRow([...sheet.headerValues, newField]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
console.error("Error updating table in google sheets", err);
|
|
240
|
+
throw err;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
deleteTable(sheet) {
|
|
245
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
246
|
+
try {
|
|
247
|
+
yield this.connect();
|
|
248
|
+
const sheetToDelete = yield this.client.sheetsByTitle[sheet];
|
|
249
|
+
return yield sheetToDelete.delete();
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
console.error("Error deleting table in google sheets", err);
|
|
253
|
+
throw err;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
create(query) {
|
|
258
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
try {
|
|
260
|
+
yield this.connect();
|
|
261
|
+
const sheet = yield this.client.sheetsByTitle[query.sheet];
|
|
262
|
+
const rowToInsert = typeof query.row === "string" ? JSON.parse(query.row) : query.row;
|
|
263
|
+
const row = yield sheet.addRow(rowToInsert);
|
|
264
|
+
return [
|
|
265
|
+
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),
|
|
266
|
+
];
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
console.error("Error writing to google sheets", err);
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
read(query) {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
try {
|
|
277
|
+
yield this.connect();
|
|
278
|
+
const sheet = yield this.client.sheetsByTitle[query.sheet];
|
|
279
|
+
const rows = yield sheet.getRows();
|
|
280
|
+
const headerValues = sheet.headerValues;
|
|
281
|
+
const response = [];
|
|
282
|
+
for (let row of rows) {
|
|
283
|
+
response.push(this.buildRowObject(headerValues, row._rawData, row._rowNumber));
|
|
284
|
+
}
|
|
285
|
+
return response;
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
console.error("Error reading from google sheets", err);
|
|
289
|
+
throw err;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
update(query) {
|
|
294
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
295
|
+
try {
|
|
296
|
+
yield this.connect();
|
|
297
|
+
const sheet = yield this.client.sheetsByTitle[query.sheet];
|
|
298
|
+
const rows = yield sheet.getRows();
|
|
299
|
+
const row = rows[query.rowIndex];
|
|
300
|
+
if (row) {
|
|
301
|
+
const updateValues = query.row;
|
|
302
|
+
for (let key in updateValues) {
|
|
303
|
+
row[key] = updateValues[key];
|
|
304
|
+
}
|
|
305
|
+
yield row.save();
|
|
306
|
+
return [
|
|
307
|
+
this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),
|
|
308
|
+
];
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
throw new Error("Row does not exist.");
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch (err) {
|
|
315
|
+
console.error("Error reading from google sheets", err);
|
|
316
|
+
throw err;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
delete(query) {
|
|
321
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
322
|
+
yield this.connect();
|
|
323
|
+
const sheet = yield this.client.sheetsByTitle[query.sheet];
|
|
324
|
+
const rows = yield sheet.getRows();
|
|
325
|
+
const row = rows[query.rowIndex];
|
|
326
|
+
if (row) {
|
|
327
|
+
yield row.delete();
|
|
328
|
+
return [{ deleted: query.rowIndex }];
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
throw new Error("Row does not exist.");
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
module.exports = {
|
|
337
|
+
schema: SCHEMA,
|
|
338
|
+
integration: GoogleSheetsIntegration,
|
|
339
|
+
};
|
|
340
|
+
})(GoogleSheetsModule || (GoogleSheetsModule = {}));
|
|
@@ -10,6 +10,7 @@ const airtable = require("./airtable");
|
|
|
10
10
|
const mysql = require("./mysql");
|
|
11
11
|
const arangodb = require("./arangodb");
|
|
12
12
|
const rest = require("./rest");
|
|
13
|
+
const googlesheets = require("./googlesheets");
|
|
13
14
|
const { SourceNames } = require("../definitions/datasource");
|
|
14
15
|
const DEFINITIONS = {
|
|
15
16
|
[SourceNames.POSTGRES]: postgres.schema,
|
|
@@ -23,6 +24,7 @@ const DEFINITIONS = {
|
|
|
23
24
|
[SourceNames.MYSQL]: mysql.schema,
|
|
24
25
|
[SourceNames.ARANGODB]: arangodb.schema,
|
|
25
26
|
[SourceNames.REST]: rest.schema,
|
|
27
|
+
[SourceNames.GOOGLE_SHEETS]: googlesheets.schema,
|
|
26
28
|
};
|
|
27
29
|
const INTEGRATIONS = {
|
|
28
30
|
[SourceNames.POSTGRES]: postgres.integration,
|
|
@@ -36,6 +38,7 @@ const INTEGRATIONS = {
|
|
|
36
38
|
[SourceNames.MYSQL]: mysql.integration,
|
|
37
39
|
[SourceNames.ARANGODB]: arangodb.integration,
|
|
38
40
|
[SourceNames.REST]: rest.integration,
|
|
41
|
+
[SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
|
|
39
42
|
};
|
|
40
43
|
// optionally add oracle integration if the oracle binary can be installed
|
|
41
44
|
if (!(process.arch === "arm64" && process.platform === "darwin")) {
|
|
@@ -52,6 +52,9 @@ function buildExternalTableId(datasourceId, tableName) {
|
|
|
52
52
|
}
|
|
53
53
|
exports.buildExternalTableId = buildExternalTableId;
|
|
54
54
|
function breakExternalTableId(tableId) {
|
|
55
|
+
if (!tableId) {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
55
58
|
const parts = tableId.split(DOUBLE_SEPARATOR);
|
|
56
59
|
let tableName = parts.pop();
|
|
57
60
|
// if they need joined
|
|
@@ -125,7 +128,12 @@ function isSQL(datasource) {
|
|
|
125
128
|
if (!datasource || !datasource.source) {
|
|
126
129
|
return false;
|
|
127
130
|
}
|
|
128
|
-
const SQL = [
|
|
131
|
+
const SQL = [
|
|
132
|
+
datasource_1.SourceNames.POSTGRES,
|
|
133
|
+
datasource_1.SourceNames.SQL_SERVER,
|
|
134
|
+
datasource_1.SourceNames.MYSQL,
|
|
135
|
+
datasource_1.SourceNames.ORACLE,
|
|
136
|
+
];
|
|
129
137
|
return SQL.indexOf(datasource.source) !== -1;
|
|
130
138
|
}
|
|
131
139
|
exports.isSQL = isSQL;
|
|
@@ -137,8 +145,44 @@ function isIsoDateString(str) {
|
|
|
137
145
|
return d.toISOString() === str;
|
|
138
146
|
}
|
|
139
147
|
exports.isIsoDateString = isIsoDateString;
|
|
140
|
-
|
|
141
|
-
function
|
|
148
|
+
/**
|
|
149
|
+
* This function will determine whether a column is a relationship and whether it
|
|
150
|
+
* is currently valid. The reason for the validity check is that tables can be deleted
|
|
151
|
+
* outside of Budibase control and if this is the case it will break Budibase relationships.
|
|
152
|
+
* The tableIds is a list passed down from the main finalise tables function, which is
|
|
153
|
+
* based on the tables that have just been fetched. This will only really be used on subsequent
|
|
154
|
+
* fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.
|
|
155
|
+
* @param column The column to check, to see if it is a valid relationship.
|
|
156
|
+
* @param tableIds The IDs of the tables which currently exist.
|
|
157
|
+
*/
|
|
158
|
+
function shouldCopyRelationship(column, tableIds) {
|
|
159
|
+
return (column.type === constants_1.FieldTypes.LINK &&
|
|
160
|
+
column.tableId &&
|
|
161
|
+
tableIds.includes(column.tableId));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean
|
|
165
|
+
* types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make
|
|
166
|
+
* sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a
|
|
167
|
+
* column has changed type in the external database then copying it over may not be possible.
|
|
168
|
+
* @param column The column to check for options or boolean type.
|
|
169
|
+
* @param fetchedColumn The fetched column to check for the type in the external database.
|
|
170
|
+
*/
|
|
171
|
+
function shouldCopySpecialColumn(column, fetchedColumn) {
|
|
172
|
+
return (column.type === constants_1.FieldTypes.OPTIONS ||
|
|
173
|
+
column.type === constants_1.FieldTypes.ARRAY ||
|
|
174
|
+
((!fetchedColumn || fetchedColumn.type === constants_1.FieldTypes.NUMBER) &&
|
|
175
|
+
column.type === constants_1.FieldTypes.BOOLEAN));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Looks for columns which need to be copied over into the new table definitions, like relationships
|
|
179
|
+
* and options types.
|
|
180
|
+
* @param tableName The name of the table which is being checked.
|
|
181
|
+
* @param table The specific table which is being checked.
|
|
182
|
+
* @param entities All the tables that existed before - the old table definitions.
|
|
183
|
+
* @param tableIds The IDs of the tables which exist now, to check if anything has been removed.
|
|
184
|
+
*/
|
|
185
|
+
function copyExistingPropsOver(tableName, table, entities, tableIds) {
|
|
142
186
|
if (entities && entities[tableName]) {
|
|
143
187
|
if (entities[tableName].primaryDisplay) {
|
|
144
188
|
table.primaryDisplay = entities[tableName].primaryDisplay;
|
|
@@ -148,21 +192,28 @@ function copyExistingPropsOver(tableName, table, entities) {
|
|
|
148
192
|
if (!existingTableSchema.hasOwnProperty(key)) {
|
|
149
193
|
continue;
|
|
150
194
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
((!table.schema[key] || table.schema[key].type === constants_1.FieldTypes.NUMBER) &&
|
|
155
|
-
existingTableSchema[key].type === constants_1.FieldTypes.BOOLEAN)) {
|
|
195
|
+
const column = existingTableSchema[key];
|
|
196
|
+
if (shouldCopyRelationship(column, tableIds) ||
|
|
197
|
+
shouldCopySpecialColumn(column, table.schema[key])) {
|
|
156
198
|
table.schema[key] = existingTableSchema[key];
|
|
157
199
|
}
|
|
158
200
|
}
|
|
159
201
|
}
|
|
160
202
|
return table;
|
|
161
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Look through the final table definitions to see if anything needs to be
|
|
206
|
+
* copied over from the old and if any errors have occurred mark them so
|
|
207
|
+
* that the user can be made aware.
|
|
208
|
+
* @param tables The list of tables that have been retrieved from the external database.
|
|
209
|
+
* @param entities The old list of tables, if there was any to look for definitions in.
|
|
210
|
+
*/
|
|
162
211
|
function finaliseExternalTables(tables, entities) {
|
|
163
212
|
const invalidColumns = Object.values(constants_1.InvalidColumns);
|
|
164
213
|
let finalTables = {};
|
|
165
214
|
const errors = {};
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
const tableIds = Object.values(tables).map(table => table._id);
|
|
166
217
|
for (let [name, table] of Object.entries(tables)) {
|
|
167
218
|
const schemaFields = Object.keys(table.schema);
|
|
168
219
|
// make sure every table has a key
|
|
@@ -175,7 +226,7 @@ function finaliseExternalTables(tables, entities) {
|
|
|
175
226
|
continue;
|
|
176
227
|
}
|
|
177
228
|
// make sure all previous props have been added back
|
|
178
|
-
finalTables[name] = copyExistingPropsOver(name, table, entities);
|
|
229
|
+
finalTables[name] = copyExistingPropsOver(name, table, entities, tableIds);
|
|
179
230
|
}
|
|
180
231
|
// sort the tables by name
|
|
181
232
|
finalTables = Object.entries(finalTables)
|