@budibase/server 2.1.43-alpha.2 → 2.1.43
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__/aws-sdk.ts +0 -14
- package/__mocks__/node-fetch.ts +1 -5
- package/builder/assets/index.534f6c29.css +6 -0
- package/builder/assets/index.fb99ddaf.js +1021 -0
- package/builder/index.html +2 -2
- package/coverage/clover.xml +3875 -10924
- package/coverage/coverage-final.json +118 -267
- package/coverage/lcov-report/{src/api/controllers/apikeys.ts.html → api/controllers/apikeys.js.html} +30 -30
- package/coverage/lcov-report/{src/api/controllers/automation.ts.html → api/controllers/automation.js.html} +99 -99
- package/coverage/lcov-report/{src/api/controllers/cloud.ts.html → api/controllers/cloud.js.html} +58 -58
- package/coverage/lcov-report/{src/api/controllers/datasource.ts.html → api/controllers/datasource.js.html} +107 -287
- package/coverage/lcov-report/{src/api/controllers/dev.ts.html → api/controllers/dev.js.html} +87 -69
- package/coverage/lcov-report/api/controllers/index.html +326 -0
- package/coverage/lcov-report/{src/middleware/selfhost.ts.html → api/controllers/integration.js.html} +28 -22
- package/coverage/lcov-report/{src/api/controllers/layout.ts.html → api/controllers/layout.js.html} +31 -31
- package/coverage/lcov-report/{src/api/controllers/metadata.ts.html → api/controllers/metadata.js.html} +30 -33
- package/coverage/lcov-report/{src/api/controllers/migrations.ts.html → api/controllers/migrations.js.html} +17 -20
- package/coverage/lcov-report/{src/api/controllers/permission.ts.html → api/controllers/permission.js.html} +79 -88
- package/coverage/lcov-report/{src/utilities/routing → api/controllers/query}/index.html +8 -8
- package/coverage/lcov-report/{src/api/controllers/query/validation.ts.html → api/controllers/query/validation.js.html} +25 -25
- package/coverage/lcov-report/{src/api/controllers/role.ts.html → api/controllers/role.js.html} +60 -48
- package/coverage/lcov-report/{src/api/controllers/routing.ts.html → api/controllers/routing.js.html} +58 -67
- package/coverage/lcov-report/{src/api/controllers/row/external.ts.html → api/controllers/row/external.js.html} +111 -162
- package/coverage/lcov-report/{src/api → api}/controllers/row/index.html +52 -82
- package/coverage/lcov-report/{src/api/controllers/row/internal.ts.html → api/controllers/row/internal.js.html} +121 -163
- package/coverage/lcov-report/{src/api/controllers/row/internalSearch.ts.html → api/controllers/row/internalSearch.js.html} +117 -189
- package/coverage/lcov-report/{src/api/controllers/row/staticFormula.ts.html → api/controllers/row/staticFormula.js.html} +58 -73
- package/coverage/lcov-report/{src/api/controllers/row/utils.ts.html → api/controllers/row/utils.js.html} +58 -88
- package/coverage/lcov-report/{src/api/controllers/script.ts.html → api/controllers/script.js.html} +16 -19
- package/coverage/lcov-report/{src/api/controllers/table/bulkFormula.ts.html → api/controllers/table/bulkFormula.js.html} +62 -104
- package/coverage/lcov-report/{src/api/controllers/table/external.ts.html → api/controllers/table/external.js.html} +111 -204
- package/coverage/lcov-report/{src/utilities/fileSystem → api/controllers/table}/index.html +44 -44
- package/coverage/lcov-report/{src/api/controllers/table/index.ts.html → api/controllers/table/index.js.html} +49 -58
- package/coverage/lcov-report/{src/api/controllers/templates.ts.html → api/controllers/templates.js.html} +29 -38
- package/coverage/lcov-report/{src/api/controllers/user.ts.html → api/controllers/user.js.html} +99 -93
- package/coverage/lcov-report/{src/api/controllers/view/exporters.ts.html → api/controllers/view/exporters.js.html} +16 -22
- package/coverage/lcov-report/{src/api → api}/controllers/view/index.html +36 -36
- package/coverage/lcov-report/{src/api/controllers/view/index.ts.html → api/controllers/view/index.js.html} +64 -91
- package/coverage/lcov-report/{src/api/controllers/view/utils.ts.html → api/controllers/view/utils.js.html} +54 -72
- package/coverage/lcov-report/{src/api/controllers/view/viewBuilder.ts.html → api/controllers/view/viewBuilder.js.html} +36 -78
- package/coverage/lcov-report/{src/api → api}/index.html +23 -23
- package/coverage/lcov-report/{src/api/index.ts.html → api/index.js.html} +76 -55
- package/coverage/lcov-report/{src/middleware/utils.ts.html → api/routes/analytics.js.html} +19 -19
- package/coverage/lcov-report/api/routes/apikeys.js.html +121 -0
- package/coverage/lcov-report/{src/api/routes/automation.ts.html → api/routes/automation.js.html} +47 -53
- package/coverage/lcov-report/{src/api/routes/backup.ts.html → api/routes/cloud.js.html} +28 -28
- package/coverage/lcov-report/{src/api/routes/component.ts.html → api/routes/component.js.html} +24 -24
- package/coverage/lcov-report/{src/definitions/datasource.ts.html → api/routes/datasource.js.html} +64 -61
- package/coverage/lcov-report/{src/api/routes/cloud.ts.html → api/routes/deploy.js.html} +28 -31
- package/coverage/lcov-report/{src/automations/index.ts.html → api/routes/dev.js.html} +46 -46
- package/coverage/lcov-report/{src/api → api}/routes/index.html +47 -167
- package/coverage/lcov-report/api/routes/integration.js.html +121 -0
- package/coverage/lcov-report/{src/db/index.ts.html → api/routes/layout.js.html} +28 -28
- package/coverage/lcov-report/{src/api/routes/metadata.ts.html → api/routes/metadata.js.html} +31 -31
- package/coverage/lcov-report/{src/sdk/index.ts.html → api/routes/migrations.js.html} +21 -24
- package/coverage/lcov-report/{src/api/routes/permission.ts.html → api/routes/permission.js.html} +31 -55
- package/coverage/lcov-report/{src/api/routes/query.ts.html → api/routes/query.js.html} +50 -41
- package/coverage/lcov-report/api/routes/role.js.html +130 -0
- package/coverage/lcov-report/{src/api/routes/routing.ts.html → api/routes/routing.js.html} +24 -24
- package/coverage/lcov-report/api/routes/screen.js.html +139 -0
- package/coverage/lcov-report/{src/api/routes/script.ts.html → api/routes/script.js.html} +17 -17
- package/coverage/lcov-report/{src/api/routes/table.ts.html → api/routes/table.js.html} +41 -32
- package/coverage/lcov-report/{src/api/routes/templates.ts.html → api/routes/templates.js.html} +25 -25
- package/coverage/lcov-report/{src/api/routes/user.ts.html → api/routes/user.js.html} +41 -35
- package/coverage/lcov-report/{src/api → api}/routes/utils/index.html +15 -15
- package/coverage/lcov-report/{src/api/routes/utils/validators.ts.html → api/routes/utils/validators.js.html} +98 -86
- package/coverage/lcov-report/{src/api/routes/view.ts.html → api/routes/view.js.html} +36 -45
- package/coverage/lcov-report/{src/automations/actions.ts.html → automations/actions.js.html} +60 -69
- package/coverage/lcov-report/{src/automations/automationUtils.ts.html → automations/automationUtils.js.html} +33 -36
- package/coverage/lcov-report/{src/automations/bullboard.ts.html → automations/bullboard.js.html} +42 -39
- package/coverage/lcov-report/{src/automations → automations}/index.html +48 -63
- package/coverage/lcov-report/{src/websocket.ts.html → automations/index.js.html} +50 -41
- package/coverage/lcov-report/{src/automations/steps/bash.ts.html → automations/steps/bash.js.html} +30 -45
- package/coverage/lcov-report/{src/automations/steps/delay.ts.html → automations/steps/delay.js.html} +19 -34
- package/coverage/lcov-report/{src/automations/steps/discord.ts.html → automations/steps/discord.js.html} +28 -43
- package/coverage/lcov-report/{src/automations/steps/executeQuery.ts.html → automations/steps/executeQuery.js.html} +30 -45
- package/coverage/lcov-report/{src/automations/steps/executeScript.ts.html → automations/steps/executeScript.js.html} +28 -58
- package/coverage/lcov-report/{src/automations/steps/filter.ts.html → automations/steps/filter.js.html} +30 -39
- package/coverage/lcov-report/automations/steps/index.html +341 -0
- package/coverage/lcov-report/{src/automations/steps/integromat.ts.html → automations/steps/integromat.js.html} +23 -38
- package/coverage/lcov-report/{src/automations/steps/loop.ts.html → automations/steps/loop.js.html} +15 -21
- package/coverage/lcov-report/{src/automations/steps/outgoingWebhook.ts.html → automations/steps/outgoingWebhook.js.html} +39 -54
- package/coverage/lcov-report/{src/automations/steps/queryRows.ts.html → automations/steps/queryRows.js.html} +66 -102
- package/coverage/lcov-report/{src/automations/steps/sendSmtpEmail.ts.html → automations/steps/sendSmtpEmail.js.html} +25 -40
- package/coverage/lcov-report/{src/automations/steps/serverLog.ts.html → automations/steps/serverLog.js.html} +22 -40
- package/coverage/lcov-report/{src/automations/steps/slack.ts.html → automations/steps/slack.js.html} +23 -38
- package/coverage/lcov-report/{src/automations/steps/updateRow.ts.html → automations/steps/updateRow.js.html} +25 -40
- package/coverage/lcov-report/{src/automations/steps/utils.ts.html → automations/steps/utils.js.html} +27 -45
- package/coverage/lcov-report/{src/automations/steps/zapier.ts.html → automations/steps/zapier.js.html} +23 -41
- package/coverage/lcov-report/{src/definitions/automations.ts.html → automations/triggerInfo/app.js.html} +42 -42
- package/coverage/lcov-report/{src/automations/triggerInfo/cron.ts.html → automations/triggerInfo/cron.js.html} +15 -30
- package/coverage/lcov-report/{src/automations → automations}/triggerInfo/index.html +31 -31
- package/coverage/lcov-report/{src/api/routes/layout.ts.html → automations/triggerInfo/index.js.html} +26 -29
- package/coverage/lcov-report/{src/automations/triggerInfo/rowDeleted.ts.html → automations/triggerInfo/rowDeleted.js.html} +15 -30
- package/coverage/lcov-report/{src/automations/triggerInfo/rowSaved.ts.html → automations/triggerInfo/rowSaved.js.html} +15 -30
- package/coverage/lcov-report/{src/automations/triggerInfo/rowUpdated.ts.html → automations/triggerInfo/rowUpdated.js.html} +15 -30
- package/coverage/lcov-report/{src/automations/triggerInfo/webhook.ts.html → automations/triggerInfo/webhook.js.html} +15 -30
- package/coverage/lcov-report/{src/automations/triggers.ts.html → automations/triggers.js.html} +66 -78
- package/coverage/lcov-report/{src/constants → constants}/index.html +26 -26
- package/coverage/lcov-report/{src/integrations/dynamodb.ts.html → constants/index.js.html} +227 -263
- package/coverage/lcov-report/{src/constants/layouts.ts.html → constants/layouts.js.html} +36 -18
- package/coverage/lcov-report/{src/constants/screens.ts.html → constants/screens.js.html} +58 -64
- package/coverage/lcov-report/{src/db/inMemoryView.ts.html → db/inMemoryView.js.html} +29 -47
- package/coverage/lcov-report/{src/db → db}/index.html +33 -48
- package/coverage/lcov-report/{src/api/routes/integration.ts.html → db/index.js.html} +33 -33
- package/coverage/lcov-report/{src/db/linkedRows/LinkController.ts.html → db/linkedRows/LinkController.js.html} +160 -97
- package/coverage/lcov-report/db/linkedRows/index.html +146 -0
- package/coverage/lcov-report/{src/db/linkedRows/index.ts.html → db/linkedRows/index.js.html} +78 -93
- package/coverage/lcov-report/{src/db/linkedRows/linkUtils.ts.html → db/linkedRows/linkUtils.js.html} +56 -83
- package/coverage/lcov-report/{src/db/newid.ts.html → db/newid.js.html} +14 -14
- package/coverage/lcov-report/{src/db/utils.ts.html → db/utils.js.html} +211 -163
- package/coverage/lcov-report/{src/events/AutomationEmitter.ts.html → events/AutomationEmitter.js.html} +25 -40
- package/coverage/lcov-report/{src/events → events}/index.html +33 -48
- package/coverage/lcov-report/{src/events/BudibaseEmitter.ts.html → events/index.js.html} +29 -26
- package/coverage/lcov-report/{src/api/routes/dev.ts.html → events/utils.js.html} +69 -69
- package/coverage/lcov-report/index.html +184 -679
- package/coverage/lcov-report/{src/integrations → integrations}/tests/TestConfiguration.js.html +10 -10
- package/coverage/lcov-report/{src/integrations → integrations}/tests/index.html +10 -10
- package/coverage/lcov-report/{src/middleware/appInfo.ts.html → middleware/appInfo.js.html} +30 -33
- package/coverage/lcov-report/{src/middleware/builder.ts.html → middleware/builder.js.html} +40 -46
- package/coverage/lcov-report/{src/middleware/currentapp.ts.html → middleware/currentapp.js.html} +72 -81
- package/coverage/lcov-report/{src/middleware → middleware}/index.html +63 -78
- package/coverage/lcov-report/{src/middleware/joi-validator.ts.html → middleware/joi-validator.js.html} +22 -25
- package/coverage/lcov-report/{src/middleware/publicApi.ts.html → middleware/publicApi.js.html} +27 -27
- package/coverage/lcov-report/{src/middleware/resourceId.ts.html → middleware/resourceId.js.html} +45 -60
- package/coverage/lcov-report/{src/tests/utilities/index.ts.html → middleware/selfhost.js.html} +30 -33
- package/coverage/lcov-report/{src/events/index.ts.html → middleware/utils.js.html} +24 -18
- package/coverage/lcov-report/{src/utilities/budibaseDir.ts.html → utilities/budibaseDir.js.html} +14 -14
- package/coverage/lcov-report/{src/utilities/centralPath.ts.html → utilities/centralPath.js.html} +16 -16
- package/coverage/lcov-report/{src/utilities/csvParser.ts.html → utilities/csvParser.js.html} +59 -107
- package/coverage/lcov-report/{src/utilities/global.ts.html → utilities/global.js.html} +82 -115
- package/coverage/lcov-report/{src/utilities → utilities}/index.html +77 -92
- package/coverage/lcov-report/{src/utilities/index.ts.html → utilities/index.js.html} +74 -98
- package/coverage/lcov-report/{src/utilities/plugins.ts.html → utilities/plugins.js.html} +22 -25
- package/coverage/lcov-report/{src/integrations/airtable.ts.html → utilities/queue/inMemoryQueue.js.html} +135 -213
- package/coverage/lcov-report/{src/migrations → utilities/queue}/index.html +23 -23
- package/coverage/lcov-report/{src/sdk → utilities/routing}/index.html +10 -10
- package/coverage/lcov-report/{src/api/controllers/public/mapping/tables.ts.html → utilities/routing/index.js.html} +43 -46
- package/coverage/lcov-report/{src/definitions → utilities/rowProcessor}/index.html +34 -34
- package/coverage/lcov-report/{src/utilities/rowProcessor/index.ts.html → utilities/rowProcessor/index.js.html} +359 -128
- package/coverage/lcov-report/{src/utilities/rowProcessor/utils.ts.html → utilities/rowProcessor/utils.js.html} +42 -54
- package/coverage/lcov-report/{src/utilities/scriptRunner.ts.html → utilities/scriptRunner.js.html} +19 -31
- package/coverage/lcov-report/{src/utilities/security.ts.html → utilities/security.js.html} +78 -60
- package/coverage/lcov-report/{src/utilities/statusCodes.ts.html → utilities/statusCodes.js.html} +11 -11
- package/coverage/lcov-report/{src/utilities → utilities}/usageQuota/index.html +28 -28
- package/coverage/lcov-report/{src/utilities/usageQuota/rows.ts.html → utilities/usageQuota/rows.js.html} +48 -36
- package/coverage/lcov-report/{src/utilities/usageQuota/usageQuoteReset.ts.html → utilities/usageQuota/usageQuoteReset.js.html} +13 -13
- package/coverage/lcov-report/{src/utilities/users.ts.html → utilities/users.js.html} +40 -34
- package/coverage/lcov-report/{src/utilities/workerRequests.ts.html → utilities/workerRequests.js.html} +112 -127
- package/coverage/lcov.info +7069 -19741
- package/dist/api/controllers/apikeys.js +9 -12
- package/dist/api/controllers/application.js +45 -48
- package/dist/api/controllers/automation.js +82 -122
- package/dist/api/controllers/cloud.js +71 -84
- package/dist/api/controllers/component.js +2 -4
- package/dist/api/controllers/datasource.js +94 -151
- package/dist/api/controllers/deploy/Deployment.js +6 -10
- package/dist/api/controllers/deploy/index.js +16 -13
- package/dist/api/controllers/dev.js +81 -96
- package/dist/api/controllers/integration.js +8 -11
- package/dist/api/controllers/layout.js +15 -18
- package/dist/api/controllers/metadata.js +37 -51
- package/dist/api/controllers/migrations.js +11 -19
- package/dist/api/controllers/permission.js +43 -52
- package/dist/api/controllers/plugin/index.js +7 -6
- package/dist/api/controllers/plugin/utils.js +1 -2
- package/dist/api/controllers/public/applications.js +9 -17
- package/dist/api/controllers/public/tables.js +9 -29
- package/dist/api/controllers/public/utils.js +2 -2
- package/dist/api/controllers/query/import/index.js +2 -1
- package/dist/api/controllers/query/index.js +13 -10
- package/dist/api/controllers/query/validation.js +33 -41
- package/dist/api/controllers/role.js +27 -29
- package/dist/api/controllers/routing.js +58 -71
- package/dist/api/controllers/row/ExternalRequest.js +542 -538
- package/dist/api/controllers/row/external.js +190 -258
- package/dist/api/controllers/row/index.js +14 -43
- package/dist/api/controllers/row/internal.js +295 -354
- package/dist/api/controllers/row/internalSearch.js +80 -95
- package/dist/api/controllers/row/staticFormula.js +112 -125
- package/dist/api/controllers/row/utils.js +84 -122
- package/dist/api/controllers/screen.js +66 -81
- package/dist/api/controllers/script.js +6 -13
- package/dist/api/controllers/static/index.js +14 -11
- package/dist/api/controllers/table/bulkFormula.js +35 -47
- package/dist/api/controllers/table/external.js +53 -89
- package/dist/api/controllers/table/index.js +31 -64
- package/dist/api/controllers/table/internal.js +6 -5
- package/dist/api/controllers/table/utils.js +35 -39
- package/dist/api/controllers/templates.js +10 -17
- package/dist/api/controllers/user.js +70 -82
- package/dist/api/controllers/view/exporters.js +4 -8
- package/dist/api/controllers/view/index.js +153 -201
- package/dist/api/controllers/view/utils.js +121 -151
- package/dist/api/controllers/view/viewBuilder.js +16 -4
- package/dist/api/controllers/webhook.js +2 -25
- package/dist/api/index.js +34 -38
- package/dist/api/routes/analytics.js +3 -29
- package/dist/api/routes/apikeys.js +7 -33
- package/dist/api/routes/application.js +9 -8
- package/dist/api/routes/auth.js +2 -1
- package/dist/api/routes/automation.js +20 -46
- package/dist/api/routes/backup.js +4 -3
- package/dist/api/routes/cloud.js +6 -32
- package/dist/api/routes/component.js +6 -32
- package/dist/api/routes/datasource.js +13 -39
- package/dist/api/routes/deploy.js +8 -34
- package/dist/api/routes/dev.js +10 -36
- package/dist/api/routes/integration.js +7 -33
- package/dist/api/routes/layout.js +7 -33
- package/dist/api/routes/metadata.js +10 -36
- package/dist/api/routes/migrations.js +6 -32
- package/dist/api/routes/permission.js +12 -38
- package/dist/api/routes/plugin.js +5 -5
- package/dist/api/routes/public/index.js +11 -11
- package/dist/api/routes/query.js +15 -42
- package/dist/api/routes/role.js +10 -36
- package/dist/api/routes/routing.js +6 -32
- package/dist/api/routes/row.js +11 -12
- package/dist/api/routes/screen.js +9 -35
- package/dist/api/routes/script.js +6 -32
- package/dist/api/routes/static.js +9 -9
- package/dist/api/routes/table.js +13 -40
- package/dist/api/routes/templates.js +7 -33
- package/dist/api/routes/tests/utilities/TestFunctions.js +8 -6
- package/dist/api/routes/tests/utilities/index.js +32 -69
- package/dist/api/routes/user.js +13 -40
- package/dist/api/routes/utils/validators.js +126 -142
- package/dist/api/routes/view.js +12 -38
- package/dist/api/routes/webhook.js +2 -1
- package/dist/app.js +22 -22
- package/dist/automations/actions.js +24 -53
- package/dist/automations/automationUtils.js +19 -31
- package/dist/automations/bullboard.js +29 -59
- package/dist/automations/index.js +18 -23
- package/dist/automations/steps/bash.js +10 -40
- package/dist/automations/steps/createRow.js +1 -2
- package/dist/automations/steps/delay.js +5 -9
- package/dist/automations/steps/deleteRow.js +1 -2
- package/dist/automations/steps/discord.js +7 -14
- package/dist/automations/steps/executeQuery.js +7 -34
- package/dist/automations/steps/executeScript.js +7 -34
- package/dist/automations/steps/filter.js +18 -20
- package/dist/automations/steps/integromat.js +7 -14
- package/dist/automations/steps/loop.js +1 -4
- package/dist/automations/steps/outgoingWebhook.js +14 -45
- package/dist/automations/steps/queryRows.js +38 -71
- package/dist/automations/steps/sendSmtpEmail.js +6 -33
- package/dist/automations/steps/serverLog.js +8 -12
- package/dist/automations/steps/slack.js +7 -14
- package/dist/automations/steps/updateRow.js +7 -34
- package/dist/automations/steps/utils.js +16 -22
- package/dist/automations/steps/zapier.js +7 -15
- package/dist/automations/tests/utilities/index.js +38 -62
- package/dist/automations/triggerInfo/app.js +1 -4
- package/dist/automations/triggerInfo/cron.js +1 -4
- package/dist/automations/triggerInfo/index.js +6 -31
- package/dist/automations/triggerInfo/rowDeleted.js +1 -4
- package/dist/automations/triggerInfo/rowSaved.js +1 -4
- package/dist/automations/triggerInfo/rowUpdated.js +1 -4
- package/dist/automations/triggerInfo/webhook.js +1 -4
- package/dist/automations/triggers.js +57 -90
- package/dist/automations/utils.js +8 -9
- package/dist/constants/index.js +104 -118
- package/dist/constants/layouts.js +10 -7
- package/dist/constants/screens.js +44 -49
- package/dist/db/dynamoClient.js +20 -20
- package/dist/db/inMemoryView.js +38 -47
- package/dist/db/index.js +4 -7
- package/dist/db/linkedRows/LinkController.js +70 -51
- package/dist/db/linkedRows/index.js +81 -93
- package/dist/db/linkedRows/linkUtils.js +32 -42
- package/dist/db/utils.js +119 -146
- package/dist/db/views/staticViews.js +74 -91
- package/dist/environment.js +6 -9
- package/dist/events/AutomationEmitter.js +10 -13
- package/dist/events/index.js +23 -5
- package/dist/events/utils.js +10 -18
- package/dist/integrations/elasticsearch.js +2 -26
- package/dist/integrations/googlesheets.js +6 -5
- package/dist/integrations/index.js +6 -15
- package/dist/integrations/s3.js +1 -157
- package/dist/integrations/tests/TestConfiguration.js +1 -0
- package/dist/middleware/appInfo.js +9 -14
- package/dist/middleware/authorized.js +21 -22
- package/dist/middleware/builder.js +40 -41
- package/dist/middleware/currentapp.js +37 -39
- package/dist/middleware/joi-validator.js +10 -17
- package/dist/middleware/publicApi.js +6 -5
- package/dist/middleware/resourceId.js +9 -16
- package/dist/middleware/selfhost.js +4 -5
- package/dist/middleware/utils.js +2 -5
- package/dist/migrations/functions/appUrls.js +2 -2
- package/dist/migrations/functions/backfill/global.js +1 -1
- package/dist/migrations/functions/usageQuotas/syncApps.js +4 -3
- package/dist/migrations/functions/usageQuotas/syncRows.js +4 -3
- package/dist/migrations/functions/userEmailViewCasing.js +3 -3
- package/dist/migrations/index.js +0 -5
- package/dist/package.json +45 -11
- package/dist/sdk/app/backups/exports.js +2 -1
- package/dist/sdk/app/backups/imports.js +3 -2
- package/dist/sdk/app/tables/index.js +5 -5
- package/dist/startup.js +10 -10
- package/dist/tests/utilities/TestConfiguration.js +87 -111
- package/dist/tests/utilities/controllers.js +15 -38
- package/dist/tests/utilities/structures.js +53 -72
- package/dist/threads/automation.js +27 -49
- package/dist/threads/query.js +19 -17
- package/dist/threads/utils.js +8 -33
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/budibaseDir.js +2 -4
- package/dist/utilities/centralPath.js +7 -14
- package/dist/utilities/csvParser.js +21 -27
- package/dist/utilities/fileSystem/clientLibrary.js +73 -87
- package/dist/utilities/fileSystem/index.js +175 -203
- package/dist/utilities/fileSystem/processor.js +3 -8
- package/dist/utilities/fileSystem/utilities.js +22 -0
- package/dist/utilities/global.js +66 -87
- package/dist/utilities/index.js +75 -102
- package/dist/utilities/plugins.js +9 -15
- package/dist/utilities/queue/inMemoryQueue.js +126 -0
- package/dist/utilities/redis.js +65 -100
- package/dist/utilities/routing/index.js +23 -27
- package/dist/utilities/rowProcessor/index.js +191 -133
- package/dist/utilities/rowProcessor/utils.js +26 -35
- package/dist/utilities/scriptRunner.js +5 -8
- package/dist/utilities/security.js +35 -39
- package/dist/utilities/usageQuota/rows.js +49 -56
- package/dist/utilities/users.js +28 -31
- package/dist/utilities/workerRequests.js +82 -115
- package/dist/watch.js +2 -1
- package/package.json +46 -12
- package/scripts/exportAppTemplate.js +2 -2
- package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +2 -11
- package/scripts/localdomain.js +6 -34
- package/src/api/controllers/{apikeys.ts → apikeys.js} +10 -10
- package/src/api/controllers/application.ts +42 -56
- package/src/api/controllers/auth.ts +3 -4
- package/src/api/controllers/{automation.ts → automation.js} +48 -48
- package/src/api/controllers/{cloud.ts → cloud.js} +24 -24
- package/src/api/controllers/component.ts +1 -2
- package/src/api/controllers/{datasource.ts → datasource.js} +49 -109
- package/src/api/controllers/deploy/{Deployment.ts → Deployment.js} +10 -13
- package/src/api/controllers/deploy/index.ts +25 -13
- package/src/api/controllers/{dev.ts → dev.js} +37 -31
- package/src/api/controllers/integration.js +14 -0
- package/src/api/controllers/{layout.ts → layout.js} +8 -8
- package/src/api/controllers/{metadata.ts → metadata.js} +10 -11
- package/src/api/controllers/migrations.js +13 -0
- package/src/api/controllers/{permission.ts → permission.js} +46 -49
- package/src/api/controllers/plugin/index.ts +5 -4
- package/src/api/controllers/plugin/utils.ts +5 -3
- package/src/api/controllers/public/applications.ts +9 -15
- package/src/api/controllers/public/rows.ts +1 -1
- package/src/api/controllers/public/tables.ts +2 -2
- package/src/api/controllers/public/utils.ts +2 -2
- package/src/api/controllers/query/import/index.ts +3 -2
- package/src/api/controllers/query/index.ts +14 -11
- package/src/api/controllers/query/{validation.ts → validation.js} +7 -7
- package/src/api/controllers/{role.ts → role.js} +25 -21
- package/src/api/controllers/{routing.ts → routing.js} +34 -37
- package/src/api/controllers/row/ExternalRequest.ts +624 -602
- package/src/api/controllers/row/{external.ts → external.js} +62 -79
- package/src/api/controllers/row/index.ts +11 -19
- package/src/api/controllers/row/{internal.ts → internal.js} +73 -87
- package/src/api/controllers/row/{internalSearch.ts → internalSearch.js} +68 -92
- package/src/api/controllers/row/{staticFormula.ts → staticFormula.js} +25 -30
- package/src/api/controllers/row/{utils.ts → utils.js} +22 -32
- package/src/api/controllers/screen.ts +6 -10
- package/src/api/controllers/script.js +11 -0
- package/src/api/controllers/static/index.ts +16 -14
- package/src/api/controllers/table/{bulkFormula.ts → bulkFormula.js} +25 -39
- package/src/api/controllers/table/{external.ts → external.js} +55 -86
- package/src/api/controllers/table/{index.ts → index.js} +18 -21
- package/src/api/controllers/table/internal.ts +6 -5
- package/src/api/controllers/table/utils.ts +21 -26
- package/src/api/controllers/{templates.ts → templates.js} +7 -10
- package/src/api/controllers/{user.ts → user.js} +49 -47
- package/src/api/controllers/view/{exporters.ts → exporters.js} +3 -5
- package/src/api/controllers/view/{index.ts → index.js} +27 -36
- package/src/api/controllers/view/{utils.ts → utils.js} +20 -26
- package/src/api/controllers/view/{viewBuilder.ts → viewBuilder.js} +11 -25
- package/src/api/controllers/webhook.ts +1 -1
- package/src/api/{index.ts → index.js} +22 -15
- package/src/api/routes/analytics.js +9 -0
- package/src/api/routes/apikeys.js +12 -0
- package/src/api/routes/application.ts +9 -17
- package/src/api/routes/auth.ts +2 -2
- package/src/api/routes/automation.js +85 -0
- package/src/api/routes/backup.ts +4 -8
- package/src/api/routes/cloud.js +14 -0
- package/src/api/routes/component.js +14 -0
- package/src/api/routes/datasource.js +51 -0
- package/src/api/routes/deploy.js +17 -0
- package/src/api/routes/dev.js +26 -0
- package/src/api/routes/integration.js +12 -0
- package/src/api/routes/layout.js +16 -0
- package/src/api/routes/{metadata.ts → metadata.js} +13 -13
- package/src/api/routes/migrations.js +14 -0
- package/src/api/routes/permission.js +33 -0
- package/src/api/routes/plugin.ts +6 -14
- package/src/api/routes/public/index.ts +14 -11
- package/src/api/routes/public/tests/compare.spec.js +1 -1
- package/src/api/routes/{query.ts → query.js} +22 -19
- package/src/api/routes/role.js +15 -0
- package/src/api/routes/routing.js +14 -0
- package/src/api/routes/row.ts +15 -13
- package/src/api/routes/screen.js +18 -0
- package/src/api/routes/script.js +10 -0
- package/src/api/routes/static.ts +10 -7
- package/src/api/routes/{table.ts → table.js} +13 -10
- package/src/api/routes/templates.js +16 -0
- package/src/api/routes/tests/analytics.spec.js +1 -1
- package/src/api/routes/tests/backup.spec.js +1 -9
- package/src/api/routes/tests/deployment.spec.ts +1 -1
- package/src/api/routes/tests/permissions.spec.js +1 -2
- package/src/api/routes/tests/query.spec.js +10 -15
- package/src/api/routes/tests/role.spec.js +9 -7
- package/src/api/routes/tests/routing.spec.js +1 -2
- package/src/api/routes/tests/row.spec.js +4 -3
- package/src/api/routes/tests/static.spec.js +2 -2
- package/src/api/routes/tests/table.spec.js +36 -40
- package/src/api/routes/tests/user.spec.js +1 -2
- package/src/api/routes/tests/utilities/TestFunctions.ts +8 -6
- package/src/api/routes/tests/utilities/{index.ts → index.js} +12 -12
- package/src/api/routes/tests/view.spec.js +3 -3
- package/src/api/routes/user.js +53 -0
- package/src/api/routes/utils/{validators.ts → validators.js} +37 -33
- package/src/api/routes/view.js +31 -0
- package/src/api/routes/webhook.ts +2 -2
- package/src/app.ts +14 -15
- package/src/automations/{actions.ts → actions.js} +23 -26
- package/src/automations/{automationUtils.ts → automationUtils.js} +12 -13
- package/src/automations/bullboard.js +39 -0
- package/src/automations/index.js +29 -0
- package/src/automations/steps/{bash.ts → bash.js} +8 -13
- package/src/automations/steps/createRow.ts +3 -8
- package/src/automations/steps/{delay.ts → delay.js} +4 -9
- package/src/automations/steps/deleteRow.ts +3 -8
- package/src/automations/steps/{discord.ts → discord.js} +5 -10
- package/src/automations/steps/{executeQuery.ts → executeQuery.js} +7 -12
- package/src/automations/steps/{executeScript.ts → executeScript.js} +7 -17
- package/src/automations/steps/{filter.ts → filter.js} +9 -12
- package/src/automations/steps/{integromat.ts → integromat.js} +5 -10
- package/src/automations/steps/{loop.ts → loop.js} +2 -4
- package/src/automations/steps/{outgoingWebhook.ts → outgoingWebhook.js} +13 -18
- package/src/automations/steps/{queryRows.ts → queryRows.js} +36 -48
- package/src/automations/steps/{sendSmtpEmail.ts → sendSmtpEmail.js} +5 -10
- package/src/automations/steps/{serverLog.ts → serverLog.js} +3 -9
- package/src/automations/steps/{slack.ts → slack.js} +5 -10
- package/src/automations/steps/{updateRow.ts → updateRow.js} +7 -12
- package/src/automations/steps/{utils.ts → utils.js} +4 -10
- package/src/automations/steps/{zapier.ts → zapier.js} +5 -11
- package/src/automations/tests/updateRow.spec.js +1 -0
- package/src/automations/tests/utilities/index.js +51 -0
- package/src/automations/triggerInfo/{app.ts → app.js} +2 -7
- package/src/automations/triggerInfo/{cron.ts → cron.js} +2 -7
- package/src/automations/triggerInfo/index.js +15 -0
- package/src/automations/triggerInfo/{rowDeleted.ts → rowDeleted.js} +2 -7
- package/src/automations/triggerInfo/{rowSaved.ts → rowSaved.js} +2 -7
- package/src/automations/triggerInfo/{rowUpdated.ts → rowUpdated.js} +2 -7
- package/src/automations/triggerInfo/{webhook.ts → webhook.js} +2 -7
- package/src/automations/{triggers.ts → triggers.js} +26 -30
- package/src/automations/utils.ts +12 -9
- package/src/constants/index.js +208 -0
- package/src/constants/{layouts.ts → layouts.js} +9 -3
- package/src/constants/screens.js +46 -0
- package/src/db/{dynamoClient.ts → dynamoClient.js} +19 -39
- package/src/db/{inMemoryView.ts → inMemoryView.js} +9 -15
- package/src/db/index.js +16 -0
- package/src/db/linkedRows/{LinkController.ts → LinkController.js} +85 -64
- package/src/db/linkedRows/{index.ts → index.js} +38 -43
- package/src/db/linkedRows/{linkUtils.ts → linkUtils.js} +24 -33
- package/src/db/{newid.ts → newid.js} +1 -1
- package/src/db/tests/linkController.spec.js +57 -73
- package/src/db/tests/linkTests.spec.js +14 -17
- package/src/db/{utils.ts → utils.js} +93 -77
- package/src/db/views/{staticViews.ts → staticViews.js} +13 -20
- package/src/{environment.ts → environment.js} +7 -11
- package/src/events/{AutomationEmitter.ts → AutomationEmitter.js} +7 -12
- package/src/events/{BudibaseEmitter.ts → index.js} +8 -7
- package/src/events/utils.js +38 -0
- package/src/integrations/base/sql.ts +1 -1
- package/src/integrations/base/sqlTable.ts +1 -1
- package/src/integrations/elasticsearch.ts +2 -32
- package/src/integrations/googlesheets.ts +7 -5
- package/src/integrations/index.ts +41 -45
- package/src/integrations/s3.ts +3 -179
- package/src/integrations/tests/s3.spec.ts +1 -85
- package/src/integrations/utils.ts +2 -6
- package/src/middleware/appInfo.js +19 -0
- package/src/middleware/authorized.ts +28 -21
- package/src/middleware/{builder.ts → builder.js} +15 -17
- package/src/middleware/{currentapp.ts → currentapp.js} +39 -42
- package/src/middleware/{joi-validator.ts → joi-validator.js} +8 -9
- package/src/middleware/publicApi.js +21 -0
- package/src/middleware/{resourceId.ts → resourceId.js} +11 -16
- package/src/middleware/{selfhost.ts → selfhost.js} +2 -4
- package/src/middleware/tests/authorized.spec.js +6 -5
- package/src/middleware/tests/currentapp.spec.js +63 -118
- package/src/middleware/{utils.ts → utils.js} +1 -3
- package/src/migrations/functions/appUrls.ts +2 -2
- package/src/migrations/functions/backfill/app/tables.ts +5 -2
- package/src/migrations/functions/backfill/global.ts +1 -1
- package/src/migrations/functions/tests/appUrls.spec.js +4 -4
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +9 -14
- package/src/migrations/functions/usageQuotas/syncApps.ts +4 -3
- package/src/migrations/functions/usageQuotas/syncRows.ts +5 -4
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +7 -7
- package/src/migrations/functions/userEmailViewCasing.ts +3 -3
- package/src/migrations/index.ts +0 -9
- package/src/migrations/tests/index.spec.ts +1 -1
- package/src/module.d.ts +14 -0
- package/src/sdk/app/backups/exports.ts +3 -5
- package/src/sdk/app/backups/imports.ts +14 -7
- package/src/sdk/app/backups/statistics.ts +18 -9
- package/src/sdk/app/tables/index.ts +8 -7
- package/src/startup.ts +5 -5
- package/src/tests/utilities/{TestConfiguration.ts → TestConfiguration.js} +78 -111
- package/src/tests/utilities/controllers.js +16 -0
- package/src/tests/utilities/{index.ts → index.js} +2 -2
- package/src/tests/utilities/{structures.ts → structures.js} +36 -41
- package/src/threads/automation.ts +19 -18
- package/src/threads/query.ts +16 -11
- package/src/threads/utils.ts +5 -4
- package/src/utilities/budibaseDir.js +3 -0
- package/src/utilities/{centralPath.ts → centralPath.js} +3 -3
- package/src/utilities/{csvParser.ts → csvParser.js} +26 -42
- package/src/utilities/fileSystem/{clientLibrary.ts → clientLibrary.js} +20 -20
- package/src/utilities/fileSystem/{index.ts → index.js} +65 -61
- package/src/utilities/fileSystem/{processor.ts → processor.js} +5 -3
- package/src/utilities/fileSystem/utilities.js +36 -0
- package/src/utilities/global.js +127 -0
- package/src/utilities/{index.ts → index.js} +32 -40
- package/src/utilities/{plugins.ts → plugins.js} +4 -5
- package/src/utilities/queue/inMemoryQueue.js +122 -0
- package/src/utilities/{redis.ts → redis.js} +20 -21
- package/src/utilities/routing/index.js +25 -0
- package/src/utilities/rowProcessor/{index.ts → index.js} +144 -67
- package/src/utilities/rowProcessor/{utils.ts → utils.js} +15 -19
- package/src/utilities/{scriptRunner.ts → scriptRunner.js} +4 -8
- package/src/utilities/security.js +71 -0
- package/src/utilities/{statusCodes.ts → statusCodes.js} +1 -1
- package/src/utilities/usageQuota/{rows.ts → rows.js} +18 -14
- package/src/utilities/usageQuota/{usageQuoteReset.ts → usageQuoteReset.js} +1 -1
- package/src/utilities/{users.ts → users.js} +13 -11
- package/src/utilities/{workerRequests.ts → workerRequests.js} +38 -43
- package/src/watch.ts +3 -2
- package/tsconfig.build.json +2 -1
- package/tsconfig.json +1 -3
- package/builder/assets/index.0c44dac3.css +0 -6
- package/builder/assets/index.cdf540dc.js +0 -1021
- package/coverage/lcov-report/src/api/controllers/analytics.ts.html +0 -190
- package/coverage/lcov-report/src/api/controllers/application.ts.html +0 -2038
- package/coverage/lcov-report/src/api/controllers/auth.ts.html +0 -301
- package/coverage/lcov-report/src/api/controllers/backup.ts.html +0 -148
- package/coverage/lcov-report/src/api/controllers/component.ts.html +0 -259
- package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +0 -259
- package/coverage/lcov-report/src/api/controllers/deploy/index.html +0 -131
- package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +0 -730
- package/coverage/lcov-report/src/api/controllers/index.html +0 -431
- package/coverage/lcov-report/src/api/controllers/integration.ts.html +0 -124
- package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +0 -130
- package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +0 -310
- package/coverage/lcov-report/src/api/controllers/plugin/index.html +0 -206
- package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +0 -484
- package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +0 -253
- package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +0 -97
- package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +0 -121
- package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +0 -136
- package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +0 -334
- package/coverage/lcov-report/src/api/controllers/public/index.html +0 -191
- package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +0 -181
- package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +0 -191
- package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +0 -124
- package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +0 -202
- package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +0 -178
- package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +0 -181
- package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +0 -145
- package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +0 -328
- package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +0 -253
- package/coverage/lcov-report/src/api/controllers/public/users.ts.html +0 -268
- package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +0 -220
- package/coverage/lcov-report/src/api/controllers/query/import/index.html +0 -116
- package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +0 -373
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +0 -131
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +0 -379
- package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +0 -157
- package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +0 -403
- package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +0 -146
- package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +0 -586
- package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +0 -712
- package/coverage/lcov-report/src/api/controllers/query/index.html +0 -131
- package/coverage/lcov-report/src/api/controllers/query/index.ts.html +0 -976
- package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +0 -2260
- package/coverage/lcov-report/src/api/controllers/row/index.ts.html +0 -541
- package/coverage/lcov-report/src/api/controllers/screen.ts.html +0 -463
- package/coverage/lcov-report/src/api/controllers/static/index.html +0 -116
- package/coverage/lcov-report/src/api/controllers/static/index.ts.html +0 -694
- package/coverage/lcov-report/src/api/controllers/table/index.html +0 -176
- package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +0 -661
- package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +0 -1255
- package/coverage/lcov-report/src/api/controllers/webhook.ts.html +0 -379
- package/coverage/lcov-report/src/api/routes/analytics.ts.html +0 -112
- package/coverage/lcov-report/src/api/routes/apikeys.ts.html +0 -121
- package/coverage/lcov-report/src/api/routes/application.ts.html +0 -223
- package/coverage/lcov-report/src/api/routes/auth.ts.html +0 -109
- package/coverage/lcov-report/src/api/routes/datasource.ts.html +0 -265
- package/coverage/lcov-report/src/api/routes/deploy.ts.html +0 -148
- package/coverage/lcov-report/src/api/routes/index.ts.html +0 -289
- package/coverage/lcov-report/src/api/routes/migrations.ts.html +0 -127
- package/coverage/lcov-report/src/api/routes/plugin.ts.html +0 -151
- package/coverage/lcov-report/src/api/routes/public/applications.ts.html +0 -541
- package/coverage/lcov-report/src/api/routes/public/index.html +0 -191
- package/coverage/lcov-report/src/api/routes/public/index.ts.html +0 -493
- package/coverage/lcov-report/src/api/routes/public/middleware/index.html +0 -116
- package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +0 -328
- package/coverage/lcov-report/src/api/routes/public/queries.ts.html +0 -313
- package/coverage/lcov-report/src/api/routes/public/rows.ts.html +0 -598
- package/coverage/lcov-report/src/api/routes/public/tables.ts.html +0 -586
- package/coverage/lcov-report/src/api/routes/public/users.ts.html +0 -511
- package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +0 -238
- package/coverage/lcov-report/src/api/routes/public/utils/index.html +0 -116
- package/coverage/lcov-report/src/api/routes/role.ts.html +0 -157
- package/coverage/lcov-report/src/api/routes/row.ts.html +0 -883
- package/coverage/lcov-report/src/api/routes/screen.ts.html +0 -154
- package/coverage/lcov-report/src/api/routes/static.ts.html +0 -280
- package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +0 -550
- package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +0 -131
- package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +0 -367
- package/coverage/lcov-report/src/api/routes/webhook.ts.html +0 -166
- package/coverage/lcov-report/src/app.ts.html +0 -406
- package/coverage/lcov-report/src/automations/logging/index.html +0 -116
- package/coverage/lcov-report/src/automations/logging/index.ts.html +0 -199
- package/coverage/lcov-report/src/automations/steps/createRow.ts.html +0 -382
- package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +0 -349
- package/coverage/lcov-report/src/automations/steps/index.html +0 -371
- package/coverage/lcov-report/src/automations/tests/utilities/index.html +0 -116
- package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +0 -265
- package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +0 -196
- package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +0 -130
- package/coverage/lcov-report/src/automations/utils.ts.html +0 -886
- package/coverage/lcov-report/src/constants/index.ts.html +0 -697
- package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +0 -2059
- package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +0 -541
- package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +0 -427
- package/coverage/lcov-report/src/db/defaultData/index.html +0 -176
- package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +0 -403
- package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +0 -559
- package/coverage/lcov-report/src/db/dynamoClient.ts.html +0 -526
- package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +0 -265
- package/coverage/lcov-report/src/db/linkedRows/index.html +0 -161
- package/coverage/lcov-report/src/environment.ts.html +0 -457
- package/coverage/lcov-report/src/events/utils.ts.html +0 -319
- package/coverage/lcov-report/src/index.html +0 -191
- package/coverage/lcov-report/src/index.ts.html +0 -133
- package/coverage/lcov-report/src/integrations/arangodb.ts.html +0 -415
- package/coverage/lcov-report/src/integrations/base/index.html +0 -161
- package/coverage/lcov-report/src/integrations/base/query.ts.html +0 -133
- package/coverage/lcov-report/src/integrations/base/sql.ts.html +0 -1951
- package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +0 -691
- package/coverage/lcov-report/src/integrations/base/utils.ts.html +0 -121
- package/coverage/lcov-report/src/integrations/couchdb.ts.html +0 -406
- package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +0 -634
- package/coverage/lcov-report/src/integrations/firebase.ts.html +0 -646
- package/coverage/lcov-report/src/integrations/googlesheets.ts.html +0 -1315
- package/coverage/lcov-report/src/integrations/index.html +0 -371
- package/coverage/lcov-report/src/integrations/index.ts.html +0 -445
- package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +0 -1006
- package/coverage/lcov-report/src/integrations/mongodb.ts.html +0 -1867
- package/coverage/lcov-report/src/integrations/mysql.ts.html +0 -964
- package/coverage/lcov-report/src/integrations/oracle.ts.html +0 -1474
- package/coverage/lcov-report/src/integrations/postgres.ts.html +0 -1069
- package/coverage/lcov-report/src/integrations/queries/index.html +0 -116
- package/coverage/lcov-report/src/integrations/queries/sql.ts.html +0 -463
- package/coverage/lcov-report/src/integrations/redis.ts.html +0 -550
- package/coverage/lcov-report/src/integrations/rest.ts.html +0 -1381
- package/coverage/lcov-report/src/integrations/s3.ts.html +0 -862
- package/coverage/lcov-report/src/integrations/snowflake.ts.html +0 -376
- package/coverage/lcov-report/src/integrations/utils.ts.html +0 -1018
- package/coverage/lcov-report/src/middleware/authorized.ts.html +0 -460
- package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +0 -187
- package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +0 -163
- package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +0 -151
- package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +0 -206
- package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +0 -172
- package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +0 -226
- package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +0 -151
- package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +0 -151
- package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +0 -166
- package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +0 -532
- package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +0 -283
- package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +0 -146
- package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +0 -265
- package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +0 -232
- package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +0 -724
- package/coverage/lcov-report/src/migrations/functions/backfill/index.html +0 -161
- package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +0 -106
- package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +0 -235
- package/coverage/lcov-report/src/migrations/functions/index.html +0 -161
- package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +0 -130
- package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +0 -520
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +0 -161
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +0 -94
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +0 -127
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +0 -115
- package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +0 -169
- package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +0 -124
- package/coverage/lcov-report/src/migrations/index.ts.html +0 -430
- package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +0 -205
- package/coverage/lcov-report/src/migrations/tests/index.html +0 -131
- package/coverage/lcov-report/src/migrations/tests/structures.ts.html +0 -283
- package/coverage/lcov-report/src/sdk/app/automations/index.html +0 -131
- package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +0 -100
- package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +0 -214
- package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +0 -91
- package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +0 -604
- package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +0 -682
- package/coverage/lcov-report/src/sdk/app/backups/index.html +0 -176
- package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +0 -112
- package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +0 -292
- package/coverage/lcov-report/src/sdk/app/tables/index.html +0 -116
- package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +0 -265
- package/coverage/lcov-report/src/startup.ts.html +0 -499
- package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +0 -1966
- package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +0 -127
- package/coverage/lcov-report/src/tests/utilities/index.html +0 -161
- package/coverage/lcov-report/src/tests/utilities/structures.ts.html +0 -667
- package/coverage/lcov-report/src/threads/automation.ts.html +0 -1594
- package/coverage/lcov-report/src/threads/index.html +0 -161
- package/coverage/lcov-report/src/threads/index.ts.html +0 -418
- package/coverage/lcov-report/src/threads/query.ts.html +0 -961
- package/coverage/lcov-report/src/threads/utils.ts.html +0 -373
- package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +0 -547
- package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +0 -1129
- package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +0 -142
- package/coverage/lcov-report/src/utilities/redis.ts.html +0 -343
- package/coverage/lcov-report/src/utilities/routing/index.ts.html +0 -181
- package/coverage/lcov-report/src/utilities/rowProcessor/index.html +0 -146
- package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +0 -373
- package/coverage/lcov-report/src/watch.ts.html +0 -196
- package/dist/db/defaultData/datasource_bb_default.js +0 -573
- package/dist/db/defaultData/employeeImport.js +0 -155
- package/dist/db/defaultData/expensesImport.js +0 -117
- package/dist/db/defaultData/inventoryImport.js +0 -109
- package/dist/db/defaultData/jobsImport.js +0 -152
- package/dist/db/linkedRows/LinkDocument.js +0 -32
- package/dist/events/BudibaseEmitter.js +0 -24
- package/dist/migrations/functions/tableSettings.js +0 -130
- package/dist/utilities/rowProcessor/map.js +0 -99
- package/jest.config.ts +0 -33
- package/src/api/controllers/integration.ts +0 -13
- package/src/api/controllers/migrations.ts +0 -14
- package/src/api/controllers/script.ts +0 -12
- package/src/api/routes/analytics.ts +0 -9
- package/src/api/routes/apikeys.ts +0 -12
- package/src/api/routes/automation.ts +0 -87
- package/src/api/routes/cloud.ts +0 -18
- package/src/api/routes/component.ts +0 -14
- package/src/api/routes/datasource.ts +0 -60
- package/src/api/routes/deploy.ts +0 -21
- package/src/api/routes/dev.ts +0 -38
- package/src/api/routes/integration.ts +0 -16
- package/src/api/routes/layout.ts +0 -16
- package/src/api/routes/migrations.ts +0 -14
- package/src/api/routes/permission.ts +0 -41
- package/src/api/routes/role.ts +0 -24
- package/src/api/routes/routing.ts +0 -14
- package/src/api/routes/screen.ts +0 -23
- package/src/api/routes/script.ts +0 -10
- package/src/api/routes/templates.ts +0 -16
- package/src/api/routes/user.ts +0 -51
- package/src/api/routes/view.ts +0 -34
- package/src/automations/bullboard.ts +0 -38
- package/src/automations/index.ts +0 -26
- package/src/automations/tests/utilities/index.ts +0 -60
- package/src/automations/triggerInfo/index.ts +0 -15
- package/src/constants/index.ts +0 -204
- package/src/constants/screens.ts +0 -48
- package/src/db/defaultData/datasource_bb_default.ts +0 -658
- package/src/db/defaultData/employeeImport.ts +0 -152
- package/src/db/defaultData/expensesImport.ts +0 -114
- package/src/db/defaultData/inventoryImport.ts +0 -106
- package/src/db/defaultData/jobsImport.ts +0 -158
- package/src/db/index.ts +0 -16
- package/src/db/linkedRows/LinkDocument.ts +0 -60
- package/src/events/index.ts +0 -5
- package/src/events/utils.ts +0 -78
- package/src/middleware/appInfo.ts +0 -20
- package/src/middleware/publicApi.ts +0 -21
- package/src/migrations/functions/tableSettings.ts +0 -145
- package/src/migrations/functions/tests/tableSettings.spec.ts +0 -144
- package/src/tests/utilities/controllers.ts +0 -14
- package/src/utilities/budibaseDir.ts +0 -3
- package/src/utilities/global.ts +0 -138
- package/src/utilities/routing/index.ts +0 -32
- package/src/utilities/rowProcessor/map.ts +0 -96
- package/src/utilities/security.ts +0 -65
|
@@ -18,15 +18,23 @@ import {
|
|
|
18
18
|
convertRowId,
|
|
19
19
|
} from "../../../integrations/utils"
|
|
20
20
|
import { getDatasourceAndQuery } from "./utils"
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
DataSourceOperation,
|
|
23
|
+
FieldTypes,
|
|
24
|
+
RelationshipTypes,
|
|
25
|
+
} from "../../../constants"
|
|
22
26
|
import { breakExternalTableId, isSQL } from "../../../integrations/utils"
|
|
23
27
|
import { processObjectSync } from "@budibase/string-templates"
|
|
24
28
|
// @ts-ignore
|
|
25
29
|
import { cloneDeep } from "lodash/fp"
|
|
26
|
-
import {
|
|
27
|
-
|
|
30
|
+
import {
|
|
31
|
+
processFormulas,
|
|
32
|
+
processDates,
|
|
33
|
+
} from "../../../utilities/rowProcessor/utils"
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
import { getAppDB } from "@budibase/backend-core/context"
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
interface ManyRelationship {
|
|
30
38
|
tableId?: string
|
|
31
39
|
id?: string
|
|
32
40
|
isUpdate?: boolean
|
|
@@ -34,692 +42,706 @@ export interface ManyRelationship {
|
|
|
34
42
|
[key: string]: any
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
id?:
|
|
45
|
+
interface RunConfig {
|
|
46
|
+
id?: string
|
|
39
47
|
filters?: SearchFilters
|
|
40
48
|
sort?: SortJson
|
|
41
49
|
paginate?: PaginationJson
|
|
42
|
-
datasource?: Datasource
|
|
43
50
|
row?: Row
|
|
44
51
|
rows?: Row[]
|
|
45
|
-
tables?: Record<string, Table>
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
module External {
|
|
55
|
+
function buildFilters(
|
|
56
|
+
id: string | undefined | string[],
|
|
57
|
+
filters: SearchFilters,
|
|
58
|
+
table: Table
|
|
59
|
+
) {
|
|
60
|
+
const primary = table.primary
|
|
61
|
+
// if passed in array need to copy for shifting etc
|
|
62
|
+
let idCopy: undefined | string | any[] = cloneDeep(id)
|
|
63
|
+
if (filters) {
|
|
64
|
+
// need to map over the filters and make sure the _id field isn't present
|
|
65
|
+
for (let filter of Object.values(filters)) {
|
|
66
|
+
if (filter._id && primary) {
|
|
67
|
+
const parts = breakRowIdField(filter._id)
|
|
68
|
+
for (let field of primary) {
|
|
69
|
+
filter[field] = parts.shift()
|
|
70
|
+
}
|
|
63
71
|
}
|
|
72
|
+
// make sure this field doesn't exist on any filter
|
|
73
|
+
delete filter._id
|
|
64
74
|
}
|
|
65
|
-
// make sure this field doesn't exist on any filter
|
|
66
|
-
delete filter._id
|
|
67
75
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
// there is no id, just use the user provided filters
|
|
77
|
+
if (!idCopy || !table) {
|
|
78
|
+
return filters
|
|
79
|
+
}
|
|
80
|
+
// if used as URL parameter it will have been joined
|
|
81
|
+
if (!Array.isArray(idCopy)) {
|
|
82
|
+
idCopy = breakRowIdField(idCopy)
|
|
83
|
+
}
|
|
84
|
+
const equal: any = {}
|
|
85
|
+
if (primary && idCopy) {
|
|
86
|
+
for (let field of primary) {
|
|
87
|
+
// work through the ID and get the parts
|
|
88
|
+
equal[field] = idCopy.shift()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
equal,
|
|
82
93
|
}
|
|
83
94
|
}
|
|
84
|
-
return {
|
|
85
|
-
equal,
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
95
|
|
|
89
|
-
/**
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
function cleanupConfig(config: RunConfig, table: Table): RunConfig {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
96
|
+
/**
|
|
97
|
+
* This function checks the incoming parameters to make sure all the inputs are
|
|
98
|
+
* valid based on on the table schema. The main thing this is looking for is when a
|
|
99
|
+
* user has made use of the _id field of a row for a foreign key or a search parameter.
|
|
100
|
+
* In these cases the key will be sent up as [1], rather than 1. In these cases we will
|
|
101
|
+
* simplify it down to the requirements. This function is quite complex as we try to be
|
|
102
|
+
* relatively restrictive over what types of columns we will perform this action for.
|
|
103
|
+
*/
|
|
104
|
+
function cleanupConfig(config: RunConfig, table: Table): RunConfig {
|
|
105
|
+
const primaryOptions = [
|
|
106
|
+
FieldTypes.STRING,
|
|
107
|
+
FieldTypes.LONGFORM,
|
|
108
|
+
FieldTypes.OPTIONS,
|
|
109
|
+
FieldTypes.NUMBER,
|
|
110
|
+
]
|
|
111
|
+
// filter out fields which cannot be keys
|
|
112
|
+
const fieldNames = Object.entries(table.schema)
|
|
113
|
+
.filter(schema => primaryOptions.find(val => val === schema[1].type))
|
|
114
|
+
.map(([fieldName]) => fieldName)
|
|
115
|
+
const iterateObject = (obj: { [key: string]: any }) => {
|
|
116
|
+
for (let [field, value] of Object.entries(obj)) {
|
|
117
|
+
if (fieldNames.find(name => name === field) && isRowId(value)) {
|
|
118
|
+
obj[field] = convertRowId(value)
|
|
119
|
+
}
|
|
112
120
|
}
|
|
113
121
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
// check the row and filters to make sure they aren't a key of some sort
|
|
123
|
+
if (config.filters) {
|
|
124
|
+
for (let [key, filter] of Object.entries(config.filters)) {
|
|
125
|
+
// oneOf is an array, don't iterate it
|
|
126
|
+
if (
|
|
127
|
+
typeof filter !== "object" ||
|
|
128
|
+
Object.keys(filter).length === 0 ||
|
|
129
|
+
key === FilterType.ONE_OF
|
|
130
|
+
) {
|
|
131
|
+
continue
|
|
132
|
+
}
|
|
133
|
+
iterateObject(filter)
|
|
125
134
|
}
|
|
126
|
-
iterateObject(filter)
|
|
127
135
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
iterateObject(config.row)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return config
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function generateIdForRow(row: Row | undefined, table: Table): string {
|
|
137
|
-
const primary = table.primary
|
|
138
|
-
if (!row || !primary) {
|
|
139
|
-
return ""
|
|
140
|
-
}
|
|
141
|
-
// build id array
|
|
142
|
-
let idParts = []
|
|
143
|
-
for (let field of primary) {
|
|
144
|
-
// need to handle table name + field or just field, depending on if relationships used
|
|
145
|
-
const fieldValue = row[`${table.name}.${field}`] || row[field]
|
|
146
|
-
if (fieldValue) {
|
|
147
|
-
idParts.push(fieldValue)
|
|
136
|
+
if (config.row) {
|
|
137
|
+
iterateObject(config.row)
|
|
148
138
|
}
|
|
149
|
-
}
|
|
150
|
-
if (idParts.length === 0) {
|
|
151
|
-
return ""
|
|
152
|
-
}
|
|
153
|
-
return generateRowIdField(idParts)
|
|
154
|
-
}
|
|
155
139
|
|
|
156
|
-
|
|
157
|
-
if (!tableId) {
|
|
158
|
-
return {}
|
|
159
|
-
}
|
|
160
|
-
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
161
|
-
return {
|
|
162
|
-
datasourceId,
|
|
163
|
-
entityId: tableName,
|
|
164
|
-
operation,
|
|
140
|
+
return config
|
|
165
141
|
}
|
|
166
|
-
}
|
|
167
142
|
|
|
168
|
-
function
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const pathValue = row[`${table.name}.${fieldName}`]
|
|
173
|
-
const value = pathValue != null ? pathValue : row[fieldName]
|
|
174
|
-
// all responses include "select col as table.col" so that overlaps are handled
|
|
175
|
-
if (value != null) {
|
|
176
|
-
thisRow[fieldName] = value
|
|
143
|
+
function generateIdForRow(row: Row | undefined, table: Table): string {
|
|
144
|
+
const primary = table.primary
|
|
145
|
+
if (!row || !primary) {
|
|
146
|
+
return ""
|
|
177
147
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
function fixArrayTypes(row: Row, table: Table) {
|
|
186
|
-
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
|
187
|
-
if (
|
|
188
|
-
schema.type === FieldTypes.ARRAY &&
|
|
189
|
-
typeof row[fieldName] === "string"
|
|
190
|
-
) {
|
|
191
|
-
try {
|
|
192
|
-
row[fieldName] = JSON.parse(row[fieldName])
|
|
193
|
-
} catch (err) {
|
|
194
|
-
// couldn't convert back to array, ignore
|
|
195
|
-
delete row[fieldName]
|
|
148
|
+
// build id array
|
|
149
|
+
let idParts = []
|
|
150
|
+
for (let field of primary) {
|
|
151
|
+
// need to handle table name + field or just field, depending on if relationships used
|
|
152
|
+
const fieldValue = row[`${table.name}.${field}`] || row[field]
|
|
153
|
+
if (fieldValue) {
|
|
154
|
+
idParts.push(fieldValue)
|
|
196
155
|
}
|
|
197
156
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function isOneSide(field: FieldSchema) {
|
|
203
|
-
return (
|
|
204
|
-
field.relationshipType && field.relationshipType.split("-")[0] === "one"
|
|
205
|
-
)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export class ExternalRequest {
|
|
209
|
-
private operation: Operation
|
|
210
|
-
private tableId: string
|
|
211
|
-
private datasource?: Datasource
|
|
212
|
-
private tables: { [key: string]: Table } = {}
|
|
213
|
-
|
|
214
|
-
constructor(operation: Operation, tableId: string, datasource?: Datasource) {
|
|
215
|
-
this.operation = operation
|
|
216
|
-
this.tableId = tableId
|
|
217
|
-
this.datasource = datasource
|
|
218
|
-
if (datasource && datasource.entities) {
|
|
219
|
-
this.tables = datasource.entities
|
|
157
|
+
if (idParts.length === 0) {
|
|
158
|
+
return ""
|
|
220
159
|
}
|
|
160
|
+
return generateRowIdField(idParts)
|
|
221
161
|
}
|
|
222
162
|
|
|
223
|
-
|
|
163
|
+
function getEndpoint(tableId: string | undefined, operation: string) {
|
|
224
164
|
if (!tableId) {
|
|
225
|
-
|
|
165
|
+
return {}
|
|
226
166
|
}
|
|
227
|
-
const { tableName } = breakExternalTableId(tableId)
|
|
228
|
-
|
|
229
|
-
|
|
167
|
+
const { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
168
|
+
return {
|
|
169
|
+
datasourceId,
|
|
170
|
+
entityId: tableName,
|
|
171
|
+
operation,
|
|
230
172
|
}
|
|
231
173
|
}
|
|
232
174
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
175
|
+
function basicProcessing(row: Row, table: Table): Row {
|
|
176
|
+
const thisRow: Row = {}
|
|
177
|
+
// filter the row down to what is actually the row (not joined)
|
|
178
|
+
for (let fieldName of Object.keys(table.schema)) {
|
|
179
|
+
const pathValue = row[`${table.name}.${fieldName}`]
|
|
180
|
+
const value = pathValue != null ? pathValue : row[fieldName]
|
|
181
|
+
// all responses include "select col as table.col" so that overlaps are handled
|
|
182
|
+
if (value != null) {
|
|
183
|
+
thisRow[fieldName] = value
|
|
184
|
+
}
|
|
236
185
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
186
|
+
thisRow._id = generateIdForRow(row, table)
|
|
187
|
+
thisRow.tableId = table._id
|
|
188
|
+
thisRow._rev = "rev"
|
|
189
|
+
return processFormulas(table, thisRow)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function fixArrayTypes(row: Row, table: Table) {
|
|
193
|
+
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
|
244
194
|
if (
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
field.autocolumn ||
|
|
248
|
-
field.type === FieldTypes.FORMULA
|
|
195
|
+
schema.type === FieldTypes.ARRAY &&
|
|
196
|
+
typeof row[fieldName] === "string"
|
|
249
197
|
) {
|
|
250
|
-
|
|
198
|
+
try {
|
|
199
|
+
row[fieldName] = JSON.parse(row[fieldName])
|
|
200
|
+
} catch (err) {
|
|
201
|
+
// couldn't convert back to array, ignore
|
|
202
|
+
delete row[fieldName]
|
|
203
|
+
}
|
|
251
204
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
205
|
+
}
|
|
206
|
+
return row
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function isOneSide(field: FieldSchema) {
|
|
210
|
+
return (
|
|
211
|
+
field.relationshipType && field.relationshipType.split("-")[0] === "one"
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
class ExternalRequest {
|
|
216
|
+
private operation: Operation
|
|
217
|
+
private tableId: string
|
|
218
|
+
private datasource: Datasource
|
|
219
|
+
private tables: { [key: string]: Table } = {}
|
|
220
|
+
|
|
221
|
+
constructor(operation: Operation, tableId: string, datasource: Datasource) {
|
|
222
|
+
this.operation = operation
|
|
223
|
+
this.tableId = tableId
|
|
224
|
+
this.datasource = datasource
|
|
225
|
+
if (datasource && datasource.entities) {
|
|
226
|
+
this.tables = datasource.entities
|
|
256
227
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
getTable(tableId: string | undefined): Table | undefined {
|
|
231
|
+
if (!tableId) {
|
|
232
|
+
throw "Table ID is unknown, cannot find table"
|
|
260
233
|
}
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
|
|
264
|
-
continue
|
|
234
|
+
const { tableName } = breakExternalTableId(tableId)
|
|
235
|
+
if (tableName) {
|
|
236
|
+
return this.tables[tableName]
|
|
265
237
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
inputProcessing(row: Row | undefined, table: Table) {
|
|
241
|
+
if (!row) {
|
|
242
|
+
return { row, manyRelationships: [] }
|
|
270
243
|
}
|
|
271
|
-
|
|
244
|
+
// we don't really support composite keys for relationships, this is why [0] is used
|
|
272
245
|
// @ts-ignore
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
row[key]
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const
|
|
246
|
+
const tablePrimary: string = table.primary[0]
|
|
247
|
+
let newRow: Row = {},
|
|
248
|
+
manyRelationships: ManyRelationship[] = []
|
|
249
|
+
for (let [key, field] of Object.entries(table.schema)) {
|
|
250
|
+
// if set already, or not set just skip it
|
|
251
|
+
if (
|
|
252
|
+
row[key] == null ||
|
|
253
|
+
newRow[key] ||
|
|
254
|
+
field.autocolumn ||
|
|
255
|
+
field.type === FieldTypes.FORMULA
|
|
256
|
+
) {
|
|
257
|
+
continue
|
|
258
|
+
}
|
|
259
|
+
// if its an empty string then it means return the column to null (if possible)
|
|
260
|
+
if (row[key] === "") {
|
|
261
|
+
newRow[key] = null
|
|
262
|
+
continue
|
|
263
|
+
}
|
|
264
|
+
// parse floats/numbers
|
|
265
|
+
if (field.type === FieldTypes.NUMBER && !isNaN(parseFloat(row[key]))) {
|
|
266
|
+
newRow[key] = parseFloat(row[key])
|
|
267
|
+
}
|
|
268
|
+
// if its not a link then just copy it over
|
|
269
|
+
if (field.type !== FieldTypes.LINK) {
|
|
270
|
+
newRow[key] = row[key]
|
|
271
|
+
continue
|
|
272
|
+
}
|
|
273
|
+
const { tableName: linkTableName } = breakExternalTableId(
|
|
274
|
+
field?.tableId
|
|
275
|
+
)
|
|
276
|
+
// table has to exist for many to many
|
|
277
|
+
if (!linkTableName || !this.tables[linkTableName]) {
|
|
278
|
+
continue
|
|
279
|
+
}
|
|
280
|
+
const linkTable = this.tables[linkTableName]
|
|
301
281
|
// @ts-ignore
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
282
|
+
const linkTablePrimary = linkTable.primary[0]
|
|
283
|
+
// one to many
|
|
284
|
+
if (isOneSide(field)) {
|
|
285
|
+
newRow[field.foreignKey || linkTablePrimary] = breakRowIdField(
|
|
286
|
+
row[key][0]
|
|
287
|
+
)[0]
|
|
288
|
+
}
|
|
289
|
+
// many to many
|
|
290
|
+
else if (field.through) {
|
|
291
|
+
// we're not inserting a doc, will be a bunch of update calls
|
|
292
|
+
const otherKey: string = field.throughFrom || linkTablePrimary
|
|
293
|
+
const thisKey: string = field.throughTo || tablePrimary
|
|
294
|
+
row[key].map((relationship: any) => {
|
|
295
|
+
manyRelationships.push({
|
|
296
|
+
tableId: field.through || field.tableId,
|
|
297
|
+
isUpdate: false,
|
|
298
|
+
key: otherKey,
|
|
299
|
+
[otherKey]: breakRowIdField(relationship)[0],
|
|
300
|
+
// leave the ID for enrichment later
|
|
301
|
+
[thisKey]: `{{ literal ${tablePrimary} }}`,
|
|
302
|
+
})
|
|
311
303
|
})
|
|
312
|
-
}
|
|
304
|
+
}
|
|
305
|
+
// many to one
|
|
306
|
+
else {
|
|
307
|
+
const thisKey: string = "id"
|
|
308
|
+
// @ts-ignore
|
|
309
|
+
const otherKey: string = field.fieldName
|
|
310
|
+
row[key].map((relationship: any) => {
|
|
311
|
+
manyRelationships.push({
|
|
312
|
+
tableId: field.tableId,
|
|
313
|
+
isUpdate: true,
|
|
314
|
+
key: otherKey,
|
|
315
|
+
[thisKey]: breakRowIdField(relationship)[0],
|
|
316
|
+
// leave the ID for enrichment later
|
|
317
|
+
[otherKey]: `{{ literal ${tablePrimary} }}`,
|
|
318
|
+
})
|
|
319
|
+
})
|
|
320
|
+
}
|
|
313
321
|
}
|
|
322
|
+
// we return the relationships that may need to be created in the through table
|
|
323
|
+
// we do this so that if the ID is generated by the DB it can be inserted
|
|
324
|
+
// after the fact
|
|
325
|
+
return { row: newRow, manyRelationships }
|
|
314
326
|
}
|
|
315
|
-
// we return the relationships that may need to be created in the through table
|
|
316
|
-
// we do this so that if the ID is generated by the DB it can be inserted
|
|
317
|
-
// after the fact
|
|
318
|
-
return { row: newRow, manyRelationships }
|
|
319
|
-
}
|
|
320
327
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
328
|
+
squashRelationshipColumns(
|
|
329
|
+
table: Table,
|
|
330
|
+
row: Row,
|
|
331
|
+
relationships: RelationshipsJson[]
|
|
332
|
+
): Row {
|
|
333
|
+
for (let relationship of relationships) {
|
|
334
|
+
const linkedTable = this.tables[relationship.tableName]
|
|
335
|
+
if (!linkedTable || !row[relationship.column]) {
|
|
336
|
+
continue
|
|
337
|
+
}
|
|
338
|
+
const display = linkedTable.primaryDisplay
|
|
339
|
+
for (let key of Object.keys(row[relationship.column])) {
|
|
340
|
+
const related: Row = row[relationship.column][key]
|
|
341
|
+
row[relationship.column][key] = {
|
|
342
|
+
primaryDisplay: display ? related[display] : undefined,
|
|
343
|
+
_id: related._id,
|
|
344
|
+
}
|
|
337
345
|
}
|
|
338
346
|
}
|
|
347
|
+
return row
|
|
339
348
|
}
|
|
340
|
-
return row
|
|
341
|
-
}
|
|
342
349
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
for (let [column, related] of Object.entries(columns)) {
|
|
380
|
-
if (!row._id) {
|
|
381
|
-
continue
|
|
382
|
-
}
|
|
383
|
-
const rowId: string = row._id
|
|
384
|
-
if (!Array.isArray(rows[rowId][column])) {
|
|
385
|
-
rows[rowId][column] = []
|
|
350
|
+
/**
|
|
351
|
+
* This iterates through the returned rows and works out what elements of the rows
|
|
352
|
+
* actually match up to another row (based on primary keys) - this is pretty specific
|
|
353
|
+
* to SQL and the way that SQL relationships are returned based on joins.
|
|
354
|
+
* This is complicated, but the idea is that when a SQL query returns all the relations
|
|
355
|
+
* will be separate rows, with all of the data in each row. We have to decipher what comes
|
|
356
|
+
* from where (which tables) and how to convert that into budibase columns.
|
|
357
|
+
*/
|
|
358
|
+
updateRelationshipColumns(
|
|
359
|
+
table: Table,
|
|
360
|
+
row: Row,
|
|
361
|
+
rows: { [key: string]: Row },
|
|
362
|
+
relationships: RelationshipsJson[]
|
|
363
|
+
) {
|
|
364
|
+
const columns: { [key: string]: any } = {}
|
|
365
|
+
for (let relationship of relationships) {
|
|
366
|
+
const linkedTable = this.tables[relationship.tableName]
|
|
367
|
+
if (!linkedTable) {
|
|
368
|
+
continue
|
|
369
|
+
}
|
|
370
|
+
const fromColumn = `${table.name}.${relationship.from}`
|
|
371
|
+
const toColumn = `${linkedTable.name}.${relationship.to}`
|
|
372
|
+
// this is important when working with multiple relationships
|
|
373
|
+
// between the same tables, don't want to overlap/multiply the relations
|
|
374
|
+
if (
|
|
375
|
+
!relationship.through &&
|
|
376
|
+
row[fromColumn]?.toString() !== row[toColumn]?.toString()
|
|
377
|
+
) {
|
|
378
|
+
continue
|
|
379
|
+
}
|
|
380
|
+
let linked = basicProcessing(row, linkedTable)
|
|
381
|
+
if (!linked._id) {
|
|
382
|
+
continue
|
|
383
|
+
}
|
|
384
|
+
columns[relationship.column] = linked
|
|
386
385
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
386
|
+
for (let [column, related] of Object.entries(columns)) {
|
|
387
|
+
if (!row._id) {
|
|
388
|
+
continue
|
|
389
|
+
}
|
|
390
|
+
const rowId: string = row._id
|
|
391
|
+
if (!Array.isArray(rows[rowId][column])) {
|
|
392
|
+
rows[rowId][column] = []
|
|
393
|
+
}
|
|
394
|
+
// make sure relationship hasn't been found already
|
|
395
|
+
if (
|
|
396
|
+
!rows[rowId][column].find(
|
|
397
|
+
(relation: Row) => relation._id === related._id
|
|
398
|
+
)
|
|
399
|
+
) {
|
|
400
|
+
rows[rowId][column].push(related)
|
|
401
|
+
}
|
|
394
402
|
}
|
|
403
|
+
return rows
|
|
395
404
|
}
|
|
396
|
-
return rows
|
|
397
|
-
}
|
|
398
405
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
406
|
+
outputProcessing(
|
|
407
|
+
rows: Row[] = [],
|
|
408
|
+
table: Table,
|
|
409
|
+
relationships: RelationshipsJson[]
|
|
410
|
+
) {
|
|
411
|
+
if (!rows || rows.length === 0 || rows[0].read === true) {
|
|
412
|
+
return []
|
|
413
|
+
}
|
|
414
|
+
let finalRows: { [key: string]: Row } = {}
|
|
415
|
+
for (let row of rows) {
|
|
416
|
+
const rowId = generateIdForRow(row, table)
|
|
417
|
+
row._id = rowId
|
|
418
|
+
// this is a relationship of some sort
|
|
419
|
+
if (finalRows[rowId]) {
|
|
420
|
+
finalRows = this.updateRelationshipColumns(
|
|
421
|
+
table,
|
|
422
|
+
row,
|
|
423
|
+
finalRows,
|
|
424
|
+
relationships
|
|
425
|
+
)
|
|
426
|
+
continue
|
|
427
|
+
}
|
|
428
|
+
const thisRow = fixArrayTypes(basicProcessing(row, table), table)
|
|
429
|
+
if (thisRow._id == null) {
|
|
430
|
+
throw "Unable to generate row ID for SQL rows"
|
|
431
|
+
}
|
|
432
|
+
finalRows[thisRow._id] = thisRow
|
|
433
|
+
// do this at end once its been added to the final rows
|
|
413
434
|
finalRows = this.updateRelationshipColumns(
|
|
414
435
|
table,
|
|
415
436
|
row,
|
|
416
437
|
finalRows,
|
|
417
438
|
relationships
|
|
418
439
|
)
|
|
419
|
-
continue
|
|
420
|
-
}
|
|
421
|
-
const thisRow = fixArrayTypes(basicProcessing(row, table), table)
|
|
422
|
-
if (thisRow._id == null) {
|
|
423
|
-
throw "Unable to generate row ID for SQL rows"
|
|
424
440
|
}
|
|
425
|
-
finalRows[thisRow._id] = thisRow
|
|
426
|
-
// do this at end once its been added to the final rows
|
|
427
|
-
finalRows = this.updateRelationshipColumns(
|
|
428
|
-
table,
|
|
429
|
-
row,
|
|
430
|
-
finalRows,
|
|
431
|
-
relationships
|
|
432
|
-
)
|
|
433
|
-
}
|
|
434
441
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
442
|
+
// Process some additional data types
|
|
443
|
+
let finalRowArray = Object.values(finalRows)
|
|
444
|
+
finalRowArray = processDates(table, finalRowArray)
|
|
445
|
+
finalRowArray = processFormulas(table, finalRowArray)
|
|
439
446
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
447
|
+
return finalRowArray.map((row: Row) =>
|
|
448
|
+
this.squashRelationshipColumns(table, row, relationships)
|
|
449
|
+
)
|
|
450
|
+
}
|
|
444
451
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
452
|
+
/**
|
|
453
|
+
* Gets the list of relationship JSON structures based on the columns in the table,
|
|
454
|
+
* this will be used by the underlying library to build whatever relationship mechanism
|
|
455
|
+
* it has (e.g. SQL joins).
|
|
456
|
+
*/
|
|
457
|
+
buildRelationships(table: Table): RelationshipsJson[] {
|
|
458
|
+
const relationships = []
|
|
459
|
+
for (let [fieldName, field] of Object.entries(table.schema)) {
|
|
460
|
+
if (field.type !== FieldTypes.LINK) {
|
|
461
|
+
continue
|
|
462
|
+
}
|
|
463
|
+
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
|
464
|
+
// no table to link to, this is not a valid relationships
|
|
465
|
+
if (!linkTableName || !this.tables[linkTableName]) {
|
|
466
|
+
continue
|
|
467
|
+
}
|
|
468
|
+
const linkTable = this.tables[linkTableName]
|
|
469
|
+
if (!table.primary || !linkTable.primary) {
|
|
470
|
+
continue
|
|
471
|
+
}
|
|
472
|
+
const definition: any = {
|
|
473
|
+
// if no foreign key specified then use the name of the field in other table
|
|
474
|
+
from: field.foreignKey || table.primary[0],
|
|
475
|
+
to: field.fieldName,
|
|
476
|
+
tableName: linkTableName,
|
|
477
|
+
// need to specify where to put this back into
|
|
478
|
+
column: fieldName,
|
|
479
|
+
}
|
|
480
|
+
if (field.through) {
|
|
481
|
+
const { tableName: throughTableName } = breakExternalTableId(
|
|
482
|
+
field.through
|
|
483
|
+
)
|
|
484
|
+
definition.through = throughTableName
|
|
485
|
+
// don't support composite keys for relationships
|
|
486
|
+
definition.from = field.throughTo || table.primary[0]
|
|
487
|
+
definition.to = field.throughFrom || linkTable.primary[0]
|
|
488
|
+
definition.fromPrimary = table.primary[0]
|
|
489
|
+
definition.toPrimary = linkTable.primary[0]
|
|
490
|
+
}
|
|
491
|
+
relationships.push(definition)
|
|
483
492
|
}
|
|
484
|
-
relationships
|
|
493
|
+
return relationships
|
|
485
494
|
}
|
|
486
|
-
return relationships
|
|
487
|
-
}
|
|
488
495
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
// @ts-ignore
|
|
501
|
-
const primaryKey = table.primary[0]
|
|
502
|
-
// make a new request to get the row with all its relationships
|
|
503
|
-
// we need this to work out if any relationships need removed
|
|
504
|
-
for (let field of Object.values(table.schema)) {
|
|
505
|
-
if (
|
|
506
|
-
field.type !== FieldTypes.LINK ||
|
|
507
|
-
!field.fieldName ||
|
|
508
|
-
isOneSide(field)
|
|
509
|
-
) {
|
|
510
|
-
continue
|
|
511
|
-
}
|
|
512
|
-
const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY
|
|
513
|
-
const tableId = isMany ? field.through : field.tableId
|
|
514
|
-
const { tableName: relatedTableName } = breakExternalTableId(tableId)
|
|
496
|
+
/**
|
|
497
|
+
* This is a cached lookup, of relationship records, this is mainly for creating/deleting junction
|
|
498
|
+
* information.
|
|
499
|
+
*/
|
|
500
|
+
async lookupRelations(tableId: string, row: Row) {
|
|
501
|
+
const related: { [key: string]: any } = {}
|
|
502
|
+
const { tableName } = breakExternalTableId(tableId)
|
|
503
|
+
if (!tableName) {
|
|
504
|
+
return related
|
|
505
|
+
}
|
|
506
|
+
const table = this.tables[tableName]
|
|
515
507
|
// @ts-ignore
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
508
|
+
const primaryKey = table.primary[0]
|
|
509
|
+
// make a new request to get the row with all its relationships
|
|
510
|
+
// we need this to work out if any relationships need removed
|
|
511
|
+
for (let field of Object.values(table.schema)) {
|
|
512
|
+
if (
|
|
513
|
+
field.type !== FieldTypes.LINK ||
|
|
514
|
+
!field.fieldName ||
|
|
515
|
+
isOneSide(field)
|
|
516
|
+
) {
|
|
517
|
+
continue
|
|
518
|
+
}
|
|
519
|
+
const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY
|
|
520
|
+
const tableId = isMany ? field.through : field.tableId
|
|
521
|
+
const { tableName: relatedTableName } = breakExternalTableId(tableId)
|
|
522
|
+
// @ts-ignore
|
|
523
|
+
const linkPrimaryKey = this.tables[relatedTableName].primary[0]
|
|
524
|
+
const manyKey = field.throughTo || primaryKey
|
|
525
|
+
const lookupField = isMany ? primaryKey : field.foreignKey
|
|
526
|
+
const fieldName = isMany ? manyKey : field.fieldName
|
|
527
|
+
if (!lookupField || !row[lookupField]) {
|
|
528
|
+
continue
|
|
529
|
+
}
|
|
530
|
+
const response = await getDatasourceAndQuery({
|
|
531
|
+
endpoint: getEndpoint(tableId, DataSourceOperation.READ),
|
|
532
|
+
filters: {
|
|
533
|
+
equal: {
|
|
534
|
+
[fieldName]: row[lookupField],
|
|
535
|
+
},
|
|
528
536
|
},
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
537
|
+
})
|
|
538
|
+
// this is the response from knex if no rows found
|
|
539
|
+
const rows = !response[0].read ? response : []
|
|
540
|
+
const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName
|
|
541
|
+
related[storeTo] = { rows, isMany, tableId }
|
|
542
|
+
}
|
|
543
|
+
return related
|
|
535
544
|
}
|
|
536
|
-
return related
|
|
537
|
-
}
|
|
538
545
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
)
|
|
572
|
-
const operation = isUpdate ? Operation.UPDATE : Operation.CREATE
|
|
573
|
-
if (!found) {
|
|
574
|
-
promises.push(
|
|
575
|
-
getDatasourceAndQuery({
|
|
576
|
-
endpoint: getEndpoint(tableId, operation),
|
|
577
|
-
// if we're doing many relationships then we're writing, only one response
|
|
578
|
-
body,
|
|
579
|
-
filters: buildFilters(id, {}, linkTable),
|
|
580
|
-
})
|
|
546
|
+
/**
|
|
547
|
+
* Once a row has been written we may need to update a many field, e.g. updating foreign keys
|
|
548
|
+
* in a bunch of rows in another table, or inserting/deleting rows from a junction table (many to many).
|
|
549
|
+
* This is quite a complex process and is handled by this function, there are a few things going on here:
|
|
550
|
+
* 1. If updating foreign keys its relatively simple, just create a filter for the row that needs updated
|
|
551
|
+
* and write the various components.
|
|
552
|
+
* 2. If junction table, then we lookup what exists already, write what doesn't exist, work out what
|
|
553
|
+
* isn't supposed to exist anymore and delete those. This is better than the usual method of delete them
|
|
554
|
+
* all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail).
|
|
555
|
+
*/
|
|
556
|
+
async handleManyRelationships(
|
|
557
|
+
mainTableId: string,
|
|
558
|
+
row: Row,
|
|
559
|
+
relationships: ManyRelationship[]
|
|
560
|
+
) {
|
|
561
|
+
// if we're creating (in a through table) need to wipe the existing ones first
|
|
562
|
+
const promises = []
|
|
563
|
+
const related = await this.lookupRelations(mainTableId, row)
|
|
564
|
+
for (let relationship of relationships) {
|
|
565
|
+
const { key, tableId, isUpdate, id, ...rest } = relationship
|
|
566
|
+
const body: { [key: string]: any } = processObjectSync(rest, row, {})
|
|
567
|
+
const linkTable = this.getTable(tableId)
|
|
568
|
+
// @ts-ignore
|
|
569
|
+
const linkPrimary = linkTable?.primary[0]
|
|
570
|
+
if (!linkTable || !linkPrimary) {
|
|
571
|
+
return
|
|
572
|
+
}
|
|
573
|
+
const rows = related[key]?.rows || []
|
|
574
|
+
const found = rows.find(
|
|
575
|
+
(row: { [key: string]: any }) =>
|
|
576
|
+
row[linkPrimary] === relationship.id ||
|
|
577
|
+
row[linkPrimary] === body?.[linkPrimary]
|
|
581
578
|
)
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
// finally cleanup anything that needs to be removed
|
|
588
|
-
for (let [colName, { isMany, rows, tableId }] of Object.entries(related)) {
|
|
589
|
-
const table: Table | undefined = this.getTable(tableId)
|
|
590
|
-
// if its not the foreign key skip it, nothing to do
|
|
591
|
-
if (!table || (table.primary && table.primary.indexOf(colName) !== -1)) {
|
|
592
|
-
continue
|
|
593
|
-
}
|
|
594
|
-
for (let row of rows) {
|
|
595
|
-
const filters = buildFilters(generateIdForRow(row, table), {}, table)
|
|
596
|
-
// safety check, if there are no filters on deletion bad things happen
|
|
597
|
-
if (Object.keys(filters).length !== 0) {
|
|
598
|
-
const op = isMany ? Operation.DELETE : Operation.UPDATE
|
|
599
|
-
const body = isMany ? null : { [colName]: null }
|
|
579
|
+
const operation = isUpdate
|
|
580
|
+
? DataSourceOperation.UPDATE
|
|
581
|
+
: DataSourceOperation.CREATE
|
|
582
|
+
if (!found) {
|
|
600
583
|
promises.push(
|
|
601
584
|
getDatasourceAndQuery({
|
|
602
|
-
endpoint: getEndpoint(tableId,
|
|
585
|
+
endpoint: getEndpoint(tableId, operation),
|
|
586
|
+
// if we're doing many relationships then we're writing, only one response
|
|
603
587
|
body,
|
|
604
|
-
filters,
|
|
588
|
+
filters: buildFilters(id, {}, linkTable),
|
|
605
589
|
})
|
|
606
590
|
)
|
|
591
|
+
} else {
|
|
592
|
+
// remove the relationship from cache so it isn't adjusted again
|
|
593
|
+
rows.splice(rows.indexOf(found), 1)
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
// finally cleanup anything that needs to be removed
|
|
597
|
+
for (let [colName, { isMany, rows, tableId }] of Object.entries(
|
|
598
|
+
related
|
|
599
|
+
)) {
|
|
600
|
+
const table: Table | undefined = this.getTable(tableId)
|
|
601
|
+
// if its not the foreign key skip it, nothing to do
|
|
602
|
+
if (
|
|
603
|
+
!table ||
|
|
604
|
+
(table.primary && table.primary.indexOf(colName) !== -1)
|
|
605
|
+
) {
|
|
606
|
+
continue
|
|
607
|
+
}
|
|
608
|
+
for (let row of rows) {
|
|
609
|
+
const filters = buildFilters(generateIdForRow(row, table), {}, table)
|
|
610
|
+
// safety check, if there are no filters on deletion bad things happen
|
|
611
|
+
if (Object.keys(filters).length !== 0) {
|
|
612
|
+
const op = isMany
|
|
613
|
+
? DataSourceOperation.DELETE
|
|
614
|
+
: DataSourceOperation.UPDATE
|
|
615
|
+
const body = isMany ? null : { [colName]: null }
|
|
616
|
+
promises.push(
|
|
617
|
+
getDatasourceAndQuery({
|
|
618
|
+
endpoint: getEndpoint(tableId, op),
|
|
619
|
+
body,
|
|
620
|
+
filters,
|
|
621
|
+
})
|
|
622
|
+
)
|
|
623
|
+
}
|
|
607
624
|
}
|
|
608
625
|
}
|
|
626
|
+
await Promise.all(promises)
|
|
609
627
|
}
|
|
610
|
-
await Promise.all(promises)
|
|
611
|
-
}
|
|
612
628
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
}
|
|
634
|
-
let fields = extractRealFields(table)
|
|
635
|
-
for (let field of Object.values(table.schema)) {
|
|
636
|
-
if (field.type !== FieldTypes.LINK || !includeRelations) {
|
|
637
|
-
continue
|
|
629
|
+
/**
|
|
630
|
+
* This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which
|
|
631
|
+
* you have column overlap in relationships, e.g. we join a few different tables and they all have the
|
|
632
|
+
* concept of an ID, but for some of them it will be null (if they say don't have a relationship).
|
|
633
|
+
* Creating the specific list of fields that we desire, and excluding the ones that are no use to us
|
|
634
|
+
* is more performant and has the added benefit of protecting against this scenario.
|
|
635
|
+
*/
|
|
636
|
+
buildFields(
|
|
637
|
+
table: Table,
|
|
638
|
+
includeRelations: IncludeRelationship = IncludeRelationship.INCLUDE
|
|
639
|
+
) {
|
|
640
|
+
function extractRealFields(table: Table, existing: string[] = []) {
|
|
641
|
+
return Object.entries(table.schema)
|
|
642
|
+
.filter(
|
|
643
|
+
column =>
|
|
644
|
+
column[1].type !== FieldTypes.LINK &&
|
|
645
|
+
column[1].type !== FieldTypes.FORMULA &&
|
|
646
|
+
!existing.find((field: string) => field === column[0])
|
|
647
|
+
)
|
|
648
|
+
.map(column => `${table.name}.${column[0]}`)
|
|
638
649
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
650
|
+
let fields = extractRealFields(table)
|
|
651
|
+
for (let field of Object.values(table.schema)) {
|
|
652
|
+
if (field.type !== FieldTypes.LINK || !includeRelations) {
|
|
653
|
+
continue
|
|
654
|
+
}
|
|
655
|
+
const { tableName: linkTableName } = breakExternalTableId(field.tableId)
|
|
656
|
+
if (linkTableName) {
|
|
657
|
+
const linkTable = this.tables[linkTableName]
|
|
658
|
+
if (linkTable) {
|
|
659
|
+
const linkedFields = extractRealFields(linkTable, fields)
|
|
660
|
+
fields = fields.concat(linkedFields)
|
|
661
|
+
}
|
|
645
662
|
}
|
|
646
663
|
}
|
|
664
|
+
return fields
|
|
647
665
|
}
|
|
648
|
-
return fields
|
|
649
|
-
}
|
|
650
666
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
667
|
+
async run(config: RunConfig) {
|
|
668
|
+
const { operation, tableId } = this
|
|
669
|
+
let { datasourceId, tableName } = breakExternalTableId(tableId)
|
|
670
|
+
if (!tableName) {
|
|
671
|
+
throw "Unable to run without a table name"
|
|
672
|
+
}
|
|
673
|
+
if (!this.datasource) {
|
|
674
|
+
const db = getAppDB()
|
|
675
|
+
this.datasource = await db.get(datasourceId)
|
|
676
|
+
if (!this.datasource || !this.datasource.entities) {
|
|
677
|
+
throw "No tables found, fetch tables before query."
|
|
678
|
+
}
|
|
679
|
+
this.tables = this.datasource.entities
|
|
662
680
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
config,
|
|
673
|
-
table
|
|
674
|
-
)
|
|
675
|
-
filters = buildFilters(id, filters || {}, table)
|
|
676
|
-
const relationships = this.buildRelationships(table)
|
|
677
|
-
// clean up row on ingress using schema
|
|
678
|
-
const processed = this.inputProcessing(row, table)
|
|
679
|
-
row = processed.row
|
|
680
|
-
if (
|
|
681
|
-
operation === Operation.DELETE &&
|
|
682
|
-
(filters == null || Object.keys(filters).length === 0)
|
|
683
|
-
) {
|
|
684
|
-
throw "Deletion must be filtered"
|
|
685
|
-
}
|
|
686
|
-
let json = {
|
|
687
|
-
endpoint: {
|
|
688
|
-
datasourceId,
|
|
689
|
-
entityId: tableName,
|
|
690
|
-
operation,
|
|
691
|
-
},
|
|
692
|
-
resource: {
|
|
693
|
-
// have to specify the fields to avoid column overlap (for SQL)
|
|
694
|
-
fields: isSql ? this.buildFields(table) : [],
|
|
695
|
-
},
|
|
696
|
-
filters,
|
|
697
|
-
sort,
|
|
698
|
-
paginate,
|
|
699
|
-
relationships,
|
|
700
|
-
body: row || rows,
|
|
701
|
-
// pass an id filter into extra, purely for mysql/returning
|
|
702
|
-
extra: {
|
|
703
|
-
idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
|
|
704
|
-
},
|
|
705
|
-
meta: {
|
|
706
|
-
table,
|
|
707
|
-
},
|
|
708
|
-
}
|
|
709
|
-
// can't really use response right now
|
|
710
|
-
const response = await getDatasourceAndQuery(json)
|
|
711
|
-
// handle many to many relationships now if we know the ID (could be auto increment)
|
|
712
|
-
if (operation !== Operation.READ && processed.manyRelationships) {
|
|
713
|
-
await this.handleManyRelationships(
|
|
714
|
-
table._id || "",
|
|
715
|
-
response[0],
|
|
716
|
-
processed.manyRelationships
|
|
681
|
+
const table = this.tables[tableName]
|
|
682
|
+
let isSql = isSQL(this.datasource)
|
|
683
|
+
if (!table) {
|
|
684
|
+
throw `Unable to process query, table "${tableName}" not defined.`
|
|
685
|
+
}
|
|
686
|
+
// look for specific components of config which may not be considered acceptable
|
|
687
|
+
let { id, row, filters, sort, paginate, rows } = cleanupConfig(
|
|
688
|
+
config,
|
|
689
|
+
table
|
|
717
690
|
)
|
|
691
|
+
filters = buildFilters(id, filters || {}, table)
|
|
692
|
+
const relationships = this.buildRelationships(table)
|
|
693
|
+
// clean up row on ingress using schema
|
|
694
|
+
const processed = this.inputProcessing(row, table)
|
|
695
|
+
row = processed.row
|
|
696
|
+
if (
|
|
697
|
+
operation === DataSourceOperation.DELETE &&
|
|
698
|
+
(filters == null || Object.keys(filters).length === 0)
|
|
699
|
+
) {
|
|
700
|
+
throw "Deletion must be filtered"
|
|
701
|
+
}
|
|
702
|
+
let json = {
|
|
703
|
+
endpoint: {
|
|
704
|
+
datasourceId,
|
|
705
|
+
entityId: tableName,
|
|
706
|
+
operation,
|
|
707
|
+
},
|
|
708
|
+
resource: {
|
|
709
|
+
// have to specify the fields to avoid column overlap (for SQL)
|
|
710
|
+
fields: isSql ? this.buildFields(table) : [],
|
|
711
|
+
},
|
|
712
|
+
filters,
|
|
713
|
+
sort,
|
|
714
|
+
paginate,
|
|
715
|
+
relationships,
|
|
716
|
+
body: row || rows,
|
|
717
|
+
// pass an id filter into extra, purely for mysql/returning
|
|
718
|
+
extra: {
|
|
719
|
+
idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
|
|
720
|
+
},
|
|
721
|
+
meta: {
|
|
722
|
+
table,
|
|
723
|
+
},
|
|
724
|
+
}
|
|
725
|
+
// can't really use response right now
|
|
726
|
+
const response = await getDatasourceAndQuery(json)
|
|
727
|
+
// handle many to many relationships now if we know the ID (could be auto increment)
|
|
728
|
+
if (
|
|
729
|
+
operation !== DataSourceOperation.READ &&
|
|
730
|
+
processed.manyRelationships
|
|
731
|
+
) {
|
|
732
|
+
await this.handleManyRelationships(
|
|
733
|
+
table._id || "",
|
|
734
|
+
response[0],
|
|
735
|
+
processed.manyRelationships
|
|
736
|
+
)
|
|
737
|
+
}
|
|
738
|
+
const output = this.outputProcessing(response, table, relationships)
|
|
739
|
+
// if reading it'll just be an array of rows, return whole thing
|
|
740
|
+
return operation === DataSourceOperation.READ && Array.isArray(response)
|
|
741
|
+
? output
|
|
742
|
+
: { row: output[0], table }
|
|
718
743
|
}
|
|
719
|
-
const output = this.outputProcessing(response, table, relationships)
|
|
720
|
-
// if reading it'll just be an array of rows, return whole thing
|
|
721
|
-
return operation === Operation.READ && Array.isArray(response)
|
|
722
|
-
? output
|
|
723
|
-
: { row: output[0], table }
|
|
724
744
|
}
|
|
745
|
+
|
|
746
|
+
module.exports = ExternalRequest
|
|
725
747
|
}
|