@budibase/server 2.6.19-alpha.2 → 2.6.19-alpha.20
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/.dockerignore +7 -6
- package/Dockerfile +16 -8
- package/builder/assets/{index.07382a47.css → index.46d94ca7.css} +2 -2
- package/builder/assets/{index.6c1171e2.js → index.9a9bace2.js} +346 -338
- package/builder/index.html +2 -2
- package/client/manifest.json +5229 -0
- package/dist/automation.js +32208 -0
- package/dist/automation.js.map +7 -0
- package/dist/index.js +44381 -13
- package/dist/index.js.map +7 -0
- package/dist/query.js +24327 -0
- package/dist/query.js.map +7 -0
- package/jest.config.ts +3 -0
- package/nodemon.json +1 -1
- package/package.json +30 -13
- package/pm2.config.js +1 -1
- package/scripts/build.js +48 -0
- package/src/api/controllers/datasource.ts +16 -0
- package/src/api/controllers/row/internal.ts +1 -1
- package/src/api/controllers/static/index.ts +3 -3
- package/src/api/controllers/table/internal.ts +2 -6
- package/src/api/controllers/table/utils.ts +32 -1
- package/src/api/routes/datasource.ts +5 -0
- package/src/api/routes/static.ts +3 -1
- package/src/api/routes/tests/datasource.spec.ts +1 -1
- package/src/automations/actions.ts +5 -0
- package/src/automations/steps/openai.ts +105 -0
- package/src/automations/tests/openai.spec.ts +86 -0
- package/src/constants/index.ts +17 -16
- package/src/db/inMemoryView.ts +1 -0
- package/src/environment.ts +2 -0
- package/src/integration-test/postgres.spec.ts +47 -4
- package/src/integrations/airtable.ts +3 -1
- package/src/integrations/arangodb.ts +3 -1
- package/src/integrations/base/sqlTable.ts +0 -1
- package/src/integrations/couchdb.ts +3 -1
- package/src/integrations/dynamodb.ts +3 -1
- package/src/integrations/elasticsearch.ts +3 -1
- package/src/integrations/firebase.ts +3 -1
- package/src/integrations/googlesheets.ts +11 -3
- package/src/integrations/microsoftSqlServer.ts +18 -2
- package/src/integrations/mongodb.ts +3 -1
- package/src/integrations/mysql.ts +27 -11
- package/src/integrations/oracle.ts +11 -1
- package/src/integrations/postgres.ts +27 -10
- package/src/integrations/redis.ts +3 -1
- package/src/integrations/s3.ts +3 -1
- package/src/integrations/snowflake.ts +3 -1
- package/src/integrations/tests/googlesheets.spec.ts +41 -9
- package/src/utilities/fileSystem/app.ts +1 -1
- package/src/utilities/fileSystem/clientLibrary.ts +8 -3
- package/src/utilities/fileSystem/filesystem.ts +3 -1
- package/tsconfig.build.json +9 -1
- package/tsconfig.json +1 -14
- package/dist/api/controllers/analytics.js +0 -46
- package/dist/api/controllers/apikeys.js +0 -72
- package/dist/api/controllers/application.js +0 -574
- package/dist/api/controllers/auth.js +0 -80
- package/dist/api/controllers/automation.js +0 -303
- package/dist/api/controllers/backup.js +0 -37
- package/dist/api/controllers/component.js +0 -59
- package/dist/api/controllers/datasource.js +0 -337
- package/dist/api/controllers/deploy/Deployment.js +0 -53
- package/dist/api/controllers/deploy/index.js +0 -198
- package/dist/api/controllers/dev.js +0 -146
- package/dist/api/controllers/integration.js +0 -28
- package/dist/api/controllers/layout.js +0 -49
- package/dist/api/controllers/metadata.js +0 -63
- package/dist/api/controllers/migrations.js +0 -29
- package/dist/api/controllers/ops.js +0 -40
- package/dist/api/controllers/permission.js +0 -162
- package/dist/api/controllers/plugin/file.js +0 -24
- package/dist/api/controllers/plugin/github.js +0 -69
- package/dist/api/controllers/plugin/index.js +0 -112
- package/dist/api/controllers/plugin/npm.js +0 -58
- package/dist/api/controllers/plugin/uploaders.js +0 -11
- package/dist/api/controllers/plugin/url.js +0 -24
- package/dist/api/controllers/plugin/utils.js +0 -27
- package/dist/api/controllers/public/applications.js +0 -146
- package/dist/api/controllers/public/mapping/applications.js +0 -29
- package/dist/api/controllers/public/mapping/index.js +0 -11
- package/dist/api/controllers/public/mapping/queries.js +0 -36
- package/dist/api/controllers/public/mapping/rows.js +0 -24
- package/dist/api/controllers/public/mapping/tables.js +0 -23
- package/dist/api/controllers/public/mapping/types.js +0 -2
- package/dist/api/controllers/public/mapping/users.js +0 -29
- package/dist/api/controllers/public/metrics.js +0 -113
- package/dist/api/controllers/public/queries.js +0 -58
- package/dist/api/controllers/public/rows.js +0 -120
- package/dist/api/controllers/public/tables.js +0 -95
- package/dist/api/controllers/public/users.js +0 -93
- package/dist/api/controllers/public/utils.js +0 -56
- package/dist/api/controllers/query/import/index.js +0 -87
- package/dist/api/controllers/query/import/sources/base/index.js +0 -75
- package/dist/api/controllers/query/import/sources/base/openapi.js +0 -42
- package/dist/api/controllers/query/import/sources/curl.js +0 -99
- package/dist/api/controllers/query/import/sources/openapi2.js +0 -145
- package/dist/api/controllers/query/import/sources/openapi3.js +0 -177
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +0 -253
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +0 -1054
- package/dist/api/controllers/query/import/sources/tests/openapi3/data/crud/crud.json +0 -253
- package/dist/api/controllers/query/import/sources/tests/openapi3/data/petstore/petstore.json +0 -1225
- package/dist/api/controllers/query/index.js +0 -299
- package/dist/api/controllers/query/validation.js +0 -53
- package/dist/api/controllers/role.js +0 -109
- package/dist/api/controllers/routing.js +0 -105
- package/dist/api/controllers/row/ExternalRequest.js +0 -683
- package/dist/api/controllers/row/external.js +0 -339
- package/dist/api/controllers/row/index.js +0 -203
- package/dist/api/controllers/row/internal.js +0 -509
- package/dist/api/controllers/row/internalSearch.js +0 -28
- package/dist/api/controllers/row/staticFormula.js +0 -165
- package/dist/api/controllers/row/utils.js +0 -183
- package/dist/api/controllers/screen.js +0 -110
- package/dist/api/controllers/script.js +0 -30
- package/dist/api/controllers/static/index.js +0 -268
- package/dist/api/controllers/table/bulkFormula.js +0 -173
- package/dist/api/controllers/table/external.js +0 -279
- package/dist/api/controllers/table/index.js +0 -179
- package/dist/api/controllers/table/internal.js +0 -197
- package/dist/api/controllers/table/utils.js +0 -379
- package/dist/api/controllers/templates.js +0 -56
- package/dist/api/controllers/user.js +0 -124
- package/dist/api/controllers/view/exporters.js +0 -46
- package/dist/api/controllers/view/index.js +0 -193
- package/dist/api/controllers/view/utils.js +0 -177
- package/dist/api/controllers/view/viewBuilder.js +0 -158
- package/dist/api/controllers/webhook.js +0 -134
- package/dist/api/index.js +0 -55
- package/dist/api/routes/analytics.js +0 -34
- package/dist/api/routes/apikeys.js +0 -37
- package/dist/api/routes/application.js +0 -48
- package/dist/api/routes/auth.js +0 -33
- package/dist/api/routes/automation.js +0 -50
- package/dist/api/routes/backup.js +0 -35
- package/dist/api/routes/component.js +0 -35
- package/dist/api/routes/datasource.js +0 -44
- package/dist/api/routes/deploy.js +0 -37
- package/dist/api/routes/dev.js +0 -49
- package/dist/api/routes/index.js +0 -75
- package/dist/api/routes/integration.js +0 -37
- package/dist/api/routes/layout.js +0 -37
- package/dist/api/routes/metadata.js +0 -40
- package/dist/api/routes/migrations.js +0 -36
- package/dist/api/routes/ops.js +0 -52
- package/dist/api/routes/permission.js +0 -44
- package/dist/api/routes/plugin.js +0 -39
- package/dist/api/routes/public/applications.js +0 -174
- package/dist/api/routes/public/index.js +0 -140
- package/dist/api/routes/public/metrics.js +0 -30
- package/dist/api/routes/public/middleware/mapper.js +0 -97
- package/dist/api/routes/public/queries.js +0 -72
- package/dist/api/routes/public/rows.js +0 -158
- package/dist/api/routes/public/tables.js +0 -152
- package/dist/api/routes/public/users.js +0 -135
- package/dist/api/routes/public/utils/Endpoint.js +0 -36
- package/dist/api/routes/query.js +0 -47
- package/dist/api/routes/role.js +0 -40
- package/dist/api/routes/routing.js +0 -39
- package/dist/api/routes/row.js +0 -239
- package/dist/api/routes/screen.js +0 -39
- package/dist/api/routes/script.js +0 -35
- package/dist/api/routes/static.js +0 -80
- package/dist/api/routes/table.js +0 -163
- package/dist/api/routes/templates.js +0 -37
- package/dist/api/routes/user.js +0 -43
- package/dist/api/routes/utils/validators.js +0 -238
- package/dist/api/routes/view.js +0 -42
- package/dist/api/routes/webhook.js +0 -43
- package/dist/app.js +0 -132
- package/dist/automations/actions.js +0 -137
- package/dist/automations/automationUtils.js +0 -173
- package/dist/automations/bullboard.js +0 -71
- package/dist/automations/index.js +0 -43
- package/dist/automations/logging/index.js +0 -53
- package/dist/automations/steps/bash.js +0 -111
- package/dist/automations/steps/createRow.js +0 -108
- package/dist/automations/steps/delay.js +0 -53
- package/dist/automations/steps/deleteRow.js +0 -96
- package/dist/automations/steps/discord.js +0 -116
- package/dist/automations/steps/executeQuery.js +0 -134
- package/dist/automations/steps/executeScript.js +0 -106
- package/dist/automations/steps/filter.js +0 -112
- package/dist/automations/steps/loop.js +0 -54
- package/dist/automations/steps/make.js +0 -134
- package/dist/automations/steps/outgoingWebhook.js +0 -166
- package/dist/automations/steps/queryRows.js +0 -216
- package/dist/automations/steps/sendSmtpEmail.js +0 -115
- package/dist/automations/steps/serverLog.js +0 -65
- package/dist/automations/steps/slack.js +0 -98
- package/dist/automations/steps/updateRow.js +0 -144
- package/dist/automations/steps/utils.js +0 -56
- package/dist/automations/steps/zapier.js +0 -130
- package/dist/automations/triggerInfo/app.js +0 -36
- package/dist/automations/triggerInfo/cron.js +0 -35
- package/dist/automations/triggerInfo/index.js +0 -40
- package/dist/automations/triggerInfo/rowDeleted.js +0 -36
- package/dist/automations/triggerInfo/rowSaved.js +0 -44
- package/dist/automations/triggerInfo/rowUpdated.js +0 -44
- package/dist/automations/triggerInfo/webhook.js +0 -40
- package/dist/automations/triggers.js +0 -181
- package/dist/automations/utils.js +0 -275
- package/dist/constants/definitions.js +0 -2
- package/dist/constants/index.js +0 -181
- package/dist/constants/layouts.js +0 -148
- package/dist/constants/screens.js +0 -51
- package/dist/db/defaultData/datasource_bb_default.js +0 -574
- 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/dynamoClient.js +0 -124
- package/dist/db/inMemoryView.js +0 -62
- package/dist/db/index.js +0 -43
- package/dist/db/linkedRows/LinkController.js +0 -392
- package/dist/db/linkedRows/LinkDocument.js +0 -33
- package/dist/db/linkedRows/index.js +0 -206
- package/dist/db/linkedRows/linkUtils.js +0 -131
- package/dist/db/newid.js +0 -7
- package/dist/db/utils.js +0 -248
- package/dist/db/views/staticViews.js +0 -144
- package/dist/ddApm.js +0 -11
- package/dist/definitions/automations.js +0 -8
- package/dist/definitions/common.js +0 -2
- package/dist/definitions/datasource.js +0 -7
- package/dist/definitions/openapi.js +0 -6
- package/dist/environment.js +0 -109
- package/dist/events/AutomationEmitter.js +0 -53
- package/dist/events/BudibaseEmitter.js +0 -25
- package/dist/events/docUpdates/index.js +0 -17
- package/dist/events/docUpdates/processors.js +0 -18
- package/dist/events/docUpdates/syncUsers.js +0 -49
- package/dist/events/index.js +0 -11
- package/dist/events/utils.js +0 -43
- package/dist/integrations/airtable.js +0 -173
- package/dist/integrations/arangodb.js +0 -119
- package/dist/integrations/base/query.js +0 -32
- package/dist/integrations/base/sql.js +0 -600
- package/dist/integrations/base/sqlTable.js +0 -167
- package/dist/integrations/base/types.js +0 -2
- package/dist/integrations/couchdb.js +0 -140
- package/dist/integrations/dynamodb.js +0 -210
- package/dist/integrations/elasticsearch.js +0 -201
- package/dist/integrations/firebase.js +0 -189
- package/dist/integrations/googlesheets.js +0 -484
- package/dist/integrations/index.js +0 -138
- package/dist/integrations/microsoftSqlServer.js +0 -289
- package/dist/integrations/mongodb.js +0 -630
- package/dist/integrations/mysql.js +0 -272
- package/dist/integrations/oracle.js +0 -404
- package/dist/integrations/postgres.js +0 -319
- package/dist/integrations/queries/sql.js +0 -84
- package/dist/integrations/redis.js +0 -187
- package/dist/integrations/rest.js +0 -400
- package/dist/integrations/s3.js +0 -256
- package/dist/integrations/snowflake.js +0 -114
- package/dist/integrations/utils.js +0 -295
- package/dist/middleware/appInfo.js +0 -22
- package/dist/middleware/authorized.js +0 -112
- package/dist/middleware/builder.js +0 -93
- package/dist/middleware/currentapp.js +0 -103
- package/dist/middleware/joi-validator.js +0 -43
- package/dist/middleware/publicApi.js +0 -25
- package/dist/middleware/resourceId.js +0 -59
- package/dist/middleware/selfhost.js +0 -24
- package/dist/middleware/utils.js +0 -8
- package/dist/migrations/functions/appUrls.js +0 -42
- package/dist/migrations/functions/backfill/app/automations.js +0 -31
- package/dist/migrations/functions/backfill/app/datasources.js +0 -28
- package/dist/migrations/functions/backfill/app/layouts.js +0 -33
- package/dist/migrations/functions/backfill/app/queries.js +0 -49
- package/dist/migrations/functions/backfill/app/roles.js +0 -28
- package/dist/migrations/functions/backfill/app/screens.js +0 -28
- package/dist/migrations/functions/backfill/app/tables.js +0 -37
- package/dist/migrations/functions/backfill/app.js +0 -176
- package/dist/migrations/functions/backfill/global/configs.js +0 -67
- package/dist/migrations/functions/backfill/global/quotas.js +0 -60
- package/dist/migrations/functions/backfill/global/users.js +0 -50
- package/dist/migrations/functions/backfill/global.js +0 -205
- package/dist/migrations/functions/backfill/index.js +0 -32
- package/dist/migrations/functions/backfill/installation.js +0 -80
- package/dist/migrations/functions/syncQuotas.js +0 -52
- package/dist/migrations/functions/tableSettings.js +0 -130
- package/dist/migrations/functions/usageQuotas/index.js +0 -16
- package/dist/migrations/functions/usageQuotas/syncApps.js +0 -24
- package/dist/migrations/functions/usageQuotas/syncPlugins.js +0 -23
- package/dist/migrations/functions/usageQuotas/syncRows.js +0 -33
- package/dist/migrations/functions/usageQuotas/syncUsers.js +0 -21
- package/dist/migrations/functions/userEmailViewCasing.js +0 -24
- package/dist/migrations/index.js +0 -111
- package/dist/migrations/tests/helpers.js +0 -72
- package/dist/migrations/tests/structures.js +0 -37
- package/dist/sdk/app/applications/index.js +0 -28
- package/dist/sdk/app/applications/sync.js +0 -164
- package/dist/sdk/app/applications/utils.js +0 -21
- package/dist/sdk/app/automations/index.js +0 -29
- package/dist/sdk/app/automations/webhook.js +0 -54
- package/dist/sdk/app/backups/constants.js +0 -6
- package/dist/sdk/app/backups/exports.js +0 -160
- package/dist/sdk/app/backups/imports.js +0 -170
- package/dist/sdk/app/backups/index.js +0 -29
- package/dist/sdk/app/backups/statistics.js +0 -73
- package/dist/sdk/app/datasources/datasources.js +0 -173
- package/dist/sdk/app/datasources/index.js +0 -27
- package/dist/sdk/app/queries/index.js +0 -27
- package/dist/sdk/app/queries/queries.js +0 -60
- package/dist/sdk/app/rows/attachments.js +0 -61
- package/dist/sdk/app/rows/index.js +0 -28
- package/dist/sdk/app/rows/rows.js +0 -30
- package/dist/sdk/app/tables/index.js +0 -65
- package/dist/sdk/index.js +0 -27
- package/dist/sdk/plugins/index.js +0 -27
- package/dist/sdk/plugins/plugins.js +0 -53
- package/dist/sdk/users/index.js +0 -27
- package/dist/sdk/users/utils.js +0 -87
- package/dist/sdk/utils/index.js +0 -29
- package/dist/startup.js +0 -158
- package/dist/threads/automation.js +0 -450
- package/dist/threads/definitions.js +0 -2
- package/dist/threads/index.js +0 -140
- package/dist/threads/query.js +0 -265
- package/dist/threads/utils.js +0 -120
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/utilities/appDirectoryTemplate/package.json +0 -10
- package/dist/utilities/budibaseDir.js +0 -5
- package/dist/utilities/centralPath.js +0 -27
- package/dist/utilities/csv.js +0 -33
- package/dist/utilities/fileSystem/app.js +0 -88
- package/dist/utilities/fileSystem/clientLibrary.js +0 -138
- package/dist/utilities/fileSystem/filesystem.js +0 -180
- package/dist/utilities/fileSystem/index.js +0 -21
- package/dist/utilities/fileSystem/plugin.js +0 -76
- package/dist/utilities/fileSystem/processor.js +0 -34
- package/dist/utilities/fileSystem/template.js +0 -47
- package/dist/utilities/global.js +0 -149
- package/dist/utilities/index.js +0 -143
- package/dist/utilities/redis.js +0 -117
- package/dist/utilities/retry.js +0 -30
- package/dist/utilities/routing/index.js +0 -39
- package/dist/utilities/rowProcessor/index.js +0 -282
- package/dist/utilities/rowProcessor/map.js +0 -116
- package/dist/utilities/rowProcessor/utils.js +0 -87
- package/dist/utilities/schema.js +0 -112
- package/dist/utilities/scriptRunner.js +0 -26
- package/dist/utilities/security.js +0 -57
- package/dist/utilities/statusCodes.js +0 -9
- package/dist/utilities/usageQuota/rows.js +0 -88
- package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
- package/dist/utilities/users.js +0 -57
- package/dist/utilities/workerRequests.js +0 -171
- package/dist/watch.js +0 -53
- package/dist/websockets/client.js +0 -14
- package/dist/websockets/grid.js +0 -60
- package/dist/websockets/index.js +0 -17
- package/dist/websockets/websocket.js +0 -78
- /package/dist/{api/controllers/static/templates/BudibaseApp.svelte → BudibaseApp-Y5NZEDTC.svelte} +0 -0
- /package/dist/{api/controllers/static/templates/app.hbs → app.hbs} +0 -0
- /package/dist/{api/controllers/static/templates/preview.hbs → preview.hbs} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/environment.ts", "../../types/src/sdk/automations/index.ts", "../../types/src/sdk/hosting.ts", "../../types/src/sdk/context.ts", "../../types/src/sdk/events/app.ts", "../../types/src/sdk/events/auth.ts", "../../types/src/sdk/events/automation.ts", "../../types/src/sdk/events/email.ts", "../../types/src/sdk/events/datasource.ts", "../../types/src/sdk/events/event.ts", "../../types/src/sdk/events/layout.ts", "../../types/src/sdk/events/license.ts", "../../types/src/sdk/events/version.ts", "../../types/src/sdk/events/query.ts", "../../types/src/sdk/events/role.ts", "../../types/src/sdk/events/rows.ts", "../../types/src/sdk/events/screen.ts", "../../types/src/sdk/events/serve.ts", "../../types/src/sdk/events/table.ts", "../../types/src/sdk/events/user.ts", "../../types/src/sdk/events/view.ts", "../../types/src/sdk/events/account.ts", "../../types/src/sdk/events/backfill.ts", "../../types/src/sdk/events/identification.ts", "../../types/src/sdk/events/userGroup.ts", "../../types/src/sdk/events/plugin.ts", "../../types/src/sdk/events/backup.ts", "../../types/src/sdk/events/environmentVariable.ts", "../../types/src/sdk/events/auditLog.ts", "../../types/src/sdk/events/index.ts", "../../types/src/sdk/licensing/license.ts", "../../types/src/sdk/licensing/plan.ts", "../../types/src/sdk/licensing/quota.ts", "../../types/src/sdk/licensing/feature.ts", "../../types/src/sdk/licensing/billing.ts", "../../types/src/sdk/licensing/index.ts", "../../types/src/sdk/migrations.ts", "../../types/src/sdk/datasources.ts", "../../types/src/sdk/search.ts", "../../types/src/sdk/koa.ts", "../../types/src/sdk/auth.ts", "../../types/src/sdk/locks.ts", "../../types/src/sdk/db.ts", "../../types/src/sdk/middleware/matchers.ts", "../../types/src/sdk/middleware/tenancy.ts", "../../types/src/sdk/middleware/index.ts", "../../types/src/sdk/featureFlag.ts", "../../types/src/sdk/environmentVariables.ts", "../../types/src/sdk/auditLogs.ts", "../../types/src/sdk/sso.ts", "../../types/src/sdk/user.ts", "../../types/src/sdk/cli/constants.ts", "../../types/src/sdk/cli/index.ts", "../../types/src/sdk/index.ts", "../../types/src/documents/account/account.ts", "../../types/src/documents/account/user.ts", "../../types/src/documents/account/index.ts", "../../types/src/documents/app/app.ts", "../../types/src/documents/app/automation.ts", "../../types/src/documents/app/datasource.ts", "../../types/src/documents/app/layout.ts", "../../types/src/documents/app/query.ts", "../../types/src/documents/app/role.ts", "../../types/src/documents/app/table.ts", "../../types/src/documents/app/screen.ts", "../../types/src/documents/app/view.ts", "../../types/src/documents/document.ts", "../../types/src/documents/app/row.ts", "../../types/src/documents/app/user.ts", "../../types/src/documents/app/backup.ts", "../../types/src/documents/app/webhook.ts", "../../types/src/documents/app/links.ts", "../../types/src/documents/app/component.ts", "../../types/src/documents/app/index.ts", "../../types/src/documents/global/config.ts", "../../types/src/documents/global/user.ts", "../../types/src/documents/global/userGroup.ts", "../../types/src/documents/global/plugin.ts", "../../types/src/documents/global/quotas.ts", "../../types/src/documents/global/schedule.ts", "../../types/src/documents/global/templates.ts", "../../types/src/documents/global/environmentVariables.ts", "../../types/src/documents/global/auditLogs.ts", "../../types/src/documents/global/index.ts", "../../types/src/documents/platform/info.ts", "../../types/src/documents/platform/users.ts", "../../types/src/documents/platform/accounts.ts", "../../types/src/documents/platform/tenants.ts", "../../types/src/documents/platform/index.ts", "../../types/src/documents/pouch.ts", "../../types/src/documents/index.ts", "../../types/src/api/account/accounts.ts", "../../types/src/api/account/user.ts", "../../types/src/api/account/license.ts", "../../types/src/api/account/status.ts", "../../types/src/api/account/index.ts", "../../types/src/api/web/analytics.ts", "../../types/src/api/web/auth.ts", "../../types/src/api/web/user.ts", "../../types/src/api/web/errors.ts", "../../types/src/api/web/schedule.ts", "../../types/src/api/web/system/environment.ts", "../../types/src/api/web/system/index.ts", "../../types/src/api/web/app/backup.ts", "../../types/src/api/web/app/datasource.ts", "../../types/src/api/web/app/index.ts", "../../types/src/api/web/global/environmentVariables.ts", "../../types/src/api/web/global/auditLogs.ts", "../../types/src/api/web/global/events.ts", "../../types/src/api/web/global/configs.ts", "../../types/src/api/web/global/scim/users.ts", "../../types/src/api/web/global/scim/groups.ts", "../../types/src/api/web/global/scim/shared.ts", "../../types/src/api/web/global/scim/index.ts", "../../types/src/api/web/global/index.ts", "../../types/src/api/web/pagination.ts", "../../types/src/api/web/index.ts", "../../types/src/api/index.ts", "../../types/src/index.ts", "../../backend-core/src/constants/db.ts", "../../backend-core/src/constants/misc.ts", "../../backend-core/src/constants/index.ts", "../../backend-core/src/context/identity.ts", "../../backend-core/src/environment.ts", "../../backend-core/src/context/Context.ts", "../../backend-core/src/docIds/conversions.ts", "../../backend-core/src/db/couch/connections.ts", "../../backend-core/src/helpers.ts", "../../backend-core/src/db/couch/utils.ts", "../../backend-core/src/db/couch/pouchDB.ts", "../../backend-core/src/docIds/newid.ts", "../../backend-core/src/db/couch/DatabaseImpl.ts", "../../backend-core/src/db/couch/index.ts", "../../backend-core/src/db/db.ts", "../../backend-core/src/context/mainContext.ts", "../../backend-core/src/context/index.ts", "../../backend-core/src/redis/utils.ts", "../../backend-core/src/timers/timers.ts", "../../backend-core/src/timers/index.ts", "../../backend-core/src/redis/redis.ts", "../../backend-core/src/redis/init.ts", "../../backend-core/src/cache/base/index.ts", "../../backend-core/src/cache/generic.ts", "../../backend-core/src/tenancy/db.ts", "../../backend-core/src/tenancy/tenancy.ts", "../../backend-core/src/tenancy/index.ts", "../../backend-core/src/platform/platformDb.ts", "../../backend-core/src/platform/users.ts", "../../backend-core/src/redis/redlockImpl.ts", "../../backend-core/src/platform/tenants.ts", "../../backend-core/src/platform/index.ts", "../../backend-core/src/logging/correlation/correlation.ts", "../../backend-core/src/logging/correlation/index.ts", "../../backend-core/src/logging/pino/logger.ts", "../../backend-core/src/logging/alerts.ts", "../../backend-core/src/logging/index.ts", "../../backend-core/src/accounts/api.ts", "../../backend-core/src/accounts/accounts.ts", "../../backend-core/src/accounts/index.ts", "../../backend-core/src/cache/user.ts", "../../backend-core/src/docIds/ids.ts", "../../backend-core/src/docIds/params.ts", "../../backend-core/src/docIds/index.ts", "../../backend-core/src/db/utils.ts", "../../backend-core/src/db/views.ts", "../../backend-core/src/db/Replication.ts", "../../backend-core/src/db/lucene.ts", "../../backend-core/src/db/searchIndexes/searchIndexes.ts", "../../backend-core/src/db/searchIndexes/index.ts", "../../backend-core/src/db/index.ts", "../../backend-core/src/cache/appMetadata.ts", "../../backend-core/src/cache/writethrough.ts", "../../backend-core/src/cache/index.ts", "../../backend-core/src/configs/configs.ts", "../../backend-core/src/configs/index.ts", "../../backend-core/src/events/analytics.ts", "../../backend-core/src/events/processors/posthog/rateLimiting.ts", "../../backend-core/src/events/processors/posthog/PosthogProcessor.ts", "../../backend-core/src/events/processors/posthog/index.ts", "../../backend-core/src/events/processors/AnalyticsProcessor.ts", "../../backend-core/src/events/processors/LoggingProcessor.ts", "../../backend-core/src/utils/hashing.ts", "../../backend-core/src/utils/utils.ts", "../../backend-core/src/utils/stringUtils.ts", "../../backend-core/src/utils/index.ts", "../../backend-core/src/queue/inMemoryQueue.ts", "../../backend-core/src/queue/constants.ts", "../../backend-core/src/queue/listeners.ts", "../../backend-core/src/queue/queue.ts", "../../backend-core/src/queue/index.ts", "../../backend-core/src/events/processors/AuditLogsProcessor.ts", "../../backend-core/src/events/processors/Processors.ts", "../../backend-core/src/events/processors/index.ts", "../../backend-core/src/installation.ts", "../../backend-core/src/events/identification.ts", "../../backend-core/src/events/backfill.ts", "../../backend-core/src/events/asyncEvents/queue.ts", "../../backend-core/src/events/asyncEvents/publisher.ts", "../../backend-core/src/events/asyncEvents/index.ts", "../../backend-core/src/events/events.ts", "../../backend-core/src/events/publishers/account.ts", "../../backend-core/src/events/publishers/app.ts", "../../backend-core/src/events/publishers/auth.ts", "../../backend-core/src/events/publishers/automation.ts", "../../backend-core/src/events/publishers/datasource.ts", "../../backend-core/src/events/publishers/email.ts", "../../backend-core/src/events/publishers/license.ts", "../../backend-core/src/events/publishers/layout.ts", "../../backend-core/src/events/publishers/org.ts", "../../backend-core/src/events/publishers/query.ts", "../../backend-core/src/events/publishers/role.ts", "../../backend-core/src/events/publishers/screen.ts", "../../backend-core/src/events/publishers/rows.ts", "../../backend-core/src/events/publishers/table.ts", "../../backend-core/src/events/publishers/serve.ts", "../../backend-core/src/events/publishers/user.ts", "../../backend-core/src/events/publishers/view.ts", "../../backend-core/src/events/publishers/installation.ts", "../../backend-core/src/events/publishers/backfill.ts", "../../backend-core/src/events/publishers/group.ts", "../../backend-core/src/events/publishers/plugin.ts", "../../backend-core/src/events/publishers/backup.ts", "../../backend-core/src/events/publishers/environmentVariable.ts", "../../backend-core/src/events/publishers/auditLog.ts", "../../backend-core/src/events/publishers/index.ts", "../../backend-core/src/events/index.ts", "../../backend-core/src/migrations/migrations.ts", "../../backend-core/src/migrations/definitions.ts", "../../backend-core/src/migrations/index.ts", "../../backend-core/src/users.ts", "../../backend-core/src/security/permissions.ts", "../../backend-core/src/security/roles.ts", "../../backend-core/src/featureFlags/index.ts", "../../backend-core/src/security/sessions.ts", "../../backend-core/src/middleware/passport/utils.ts", "../../backend-core/src/middleware/passport/local.ts", "../../backend-core/src/middleware/passport/sso/sso.ts", "../../backend-core/src/middleware/passport/sso/google.ts", "../../backend-core/src/middleware/passport/sso/oidc.ts", "../../backend-core/src/middleware/passport/datasource/google.ts", "../../backend-core/src/middleware/matchers.ts", "../../backend-core/src/security/encryption.ts", "../../backend-core/src/errors/errors.ts", "../../backend-core/src/errors/index.ts", "../../backend-core/src/middleware/authenticated.ts", "../../backend-core/src/middleware/auditLog.ts", "../../backend-core/src/middleware/tenancy.ts", "../../backend-core/src/middleware/internalApi.ts", "../../backend-core/src/middleware/csrf.ts", "../../backend-core/src/middleware/adminOnly.ts", "../../backend-core/src/middleware/builderOrAdmin.ts", "../../backend-core/src/middleware/builderOnly.ts", "../../backend-core/src/logging/pino/middleware.ts", "../../backend-core/src/logging/correlation/middleware.ts", "../../backend-core/src/middleware/errorHandling.ts", "../../backend-core/src/middleware/querystringToBody.ts", "../../backend-core/src/middleware/joi-validator.ts", "../../backend-core/src/middleware/index.ts", "../../backend-core/src/auth/auth.ts", "../../backend-core/src/auth/index.ts", "../../backend-core/src/plugin/utils.ts", "../../backend-core/src/plugin/index.ts", "../../backend-core/src/objectStore/utils.ts", "../../backend-core/src/objectStore/objectStore.ts", "../../backend-core/src/objectStore/cloudfront.ts", "../../backend-core/src/objectStore/buckets/app.ts", "../../backend-core/src/objectStore/buckets/global.ts", "../../backend-core/src/objectStore/buckets/plugins.ts", "../../backend-core/src/objectStore/buckets/index.ts", "../../backend-core/src/objectStore/index.ts", "../../backend-core/src/redis/index.ts", "../../backend-core/src/blacklist/blacklist.ts", "../../backend-core/src/blacklist/index.ts", "../../backend-core/src/events/documentId.ts", "../../backend-core/src/events/processors/async/DocumentUpdateProcessor.ts", "../../backend-core/src/docUpdates/index.ts", "../../backend-core/src/index.ts", "../../pro/packages/pro/src/types/api.ts", "../../pro/packages/pro/src/types/license.ts", "../../pro/packages/pro/src/types/documents/license.ts", "../../pro/packages/pro/src/types/documents/index.ts", "../../pro/packages/pro/src/types/init.ts", "../../pro/packages/pro/src/types/index.ts", "../../pro/packages/pro/src/sdk/licensing/cache/redis.ts", "../../pro/packages/pro/src/utilities/api.ts", "../../pro/packages/pro/src/utilities/index.ts", "../../pro/packages/pro/src/db/quotas/utils.ts", "../../pro/packages/pro/src/db/quotas/quotas.ts", "../../pro/packages/pro/src/db/quotas/index.ts", "../../pro/packages/pro/src/db/licenseInfo.ts", "../../pro/packages/pro/src/db/views/staticViews.ts", "../../pro/packages/pro/src/db/views/groups.ts", "../../pro/packages/pro/src/db/views/index.ts", "../../pro/packages/pro/src/db/groups.ts", "../../pro/packages/pro/src/db/utils/pagination.ts", "../../pro/packages/pro/src/db/utils/views.ts", "../../pro/packages/pro/src/constants/quotas.ts", "../../pro/packages/pro/src/constants/licenses.ts", "../../pro/packages/pro/src/constants/version.ts", "../../pro/packages/pro/src/constants/misc.ts", "../../pro/packages/pro/src/constants/index.ts", "../../pro/packages/pro/src/db/utils/retention.ts", "../../pro/packages/pro/src/db/backups.ts", "../../pro/packages/pro/src/db/environmentVariables.ts", "../../pro/packages/pro/src/db/index.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/client.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/offline.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/licenses.ts", "../../pro/packages/pro/src/sdk/licensing/licenses/index.ts", "../../pro/packages/pro/src/sdk/licensing/cache/cache.ts", "../../pro/packages/pro/src/sdk/licensing/cache/index.ts", "../../pro/packages/pro/src/sdk/licensing/index.ts", "../../pro/packages/pro/src/sdk/features/features.ts", "../../pro/packages/pro/src/sdk/features/index.ts", "../../pro/packages/pro/src/sdk/branding/branding.ts", "../../pro/packages/pro/src/sdk/branding/index.ts", "../../pro/packages/pro/src/sdk/quotas/quotas.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/apps.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/queries.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/rows.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/automations.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/dayPasses.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/groups.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/plugins.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/users.ts", "../../pro/packages/pro/src/sdk/quotas/helpers/index.ts", "../../pro/packages/pro/src/sdk/quotas/index.ts", "../../pro/packages/pro/src/sdk/api/api.ts", "../../pro/packages/pro/src/sdk/api/index.ts", "../../pro/packages/pro/src/sdk/users/users.ts", "../../pro/packages/pro/src/sdk/users/index.ts", "../../pro/packages/pro/src/utilities/delay.ts", "../../pro/packages/pro/src/db/automations.ts", "../../pro/packages/pro/src/sdk/automations/logging/index.ts", "../../pro/packages/pro/src/sdk/automations/index.ts", "../../pro/packages/pro/src/api/errors.ts", "../../pro/packages/pro/src/sdk/groups/groups.ts", "../../pro/packages/pro/src/sdk/groups/index.ts", "../../pro/packages/pro/src/utilities/fileSystem.ts", "../../pro/packages/pro/src/sdk/plugins/index.ts", "../../pro/packages/pro/src/sdk/environmentVariables/environmentVariables.ts", "../../pro/packages/pro/src/sdk/environmentVariables/index.ts", "../../pro/packages/pro/src/db/auditLogs.ts", "../../string-templates/src/helpers/Helper.js", "../../string-templates/src/helpers/date.js", "../../string-templates/src/helpers/constants.js", "../../string-templates/src/helpers/external.js", "../../string-templates/src/utilities.js", "../../string-templates/src/helpers/list.js", "../../string-templates/src/helpers/javascript.js", "../../string-templates/src/helpers/index.js", "../../string-templates/src/processors/preprocessor.js", "../../string-templates/src/processors/postprocessor.js", "../../string-templates/src/processors/index.js", "../../string-templates/manifest.json", "../../string-templates/src/conversion/index.js", "../../string-templates/src/index.js", "../../string-templates/src/index.cjs", "../../pro/packages/pro/src/sdk/auditLogs/utils.ts", "../../pro/packages/pro/src/sdk/auditLogs/auditLogs.ts", "../../pro/packages/pro/src/sdk/auditLogs/index.ts", "../../pro/packages/pro/src/sdk/backups/queue.ts", "../../pro/packages/pro/src/sdk/backups/backup.ts", "../../pro/packages/pro/src/sdk/backups/processing.ts", "../../pro/packages/pro/src/sdk/backups/index.ts", "../../pro/packages/pro/src/sdk/utils/apps.ts", "../../pro/packages/pro/src/sdk/utils/index.ts", "../../pro/packages/pro/src/sdk/scim/users.ts", "../../pro/packages/pro/src/sdk/init.ts", "../../pro/packages/pro/src/sdk/scim/index.ts", "../../pro/packages/pro/src/sdk/index.ts", "../../pro/packages/pro/src/middleware/licensing.ts", "../../pro/packages/pro/src/middleware/feature.ts", "../../pro/packages/pro/src/middleware/doInScimContext.ts", "../../pro/packages/pro/src/middleware/requireSCIM.ts", "../../pro/packages/pro/src/middleware/index.ts", "../../pro/packages/pro/src/api/controllers/global/groups.ts", "../../pro/packages/pro/src/api/controllers/global/environmentVariables.ts", "../../pro/packages/pro/src/api/controllers/global/index.ts", "../../pro/packages/pro/src/api/routes/global/groups.ts", "../../pro/packages/pro/src/api/routes/global/environmentVariables.ts", "../../pro/packages/pro/src/api/controllers/global/auditLogs.ts", "../../pro/packages/pro/src/api/routes/global/auditLogs.ts", "../../pro/packages/pro/src/api/controllers/apps/backups.ts", "../../pro/packages/pro/src/api/routes/apps/backups.ts", "../../pro/packages/pro/src/api/controllers/schedules/index.ts", "../../pro/packages/pro/src/api/routes/schedules/index.ts", "../../pro/packages/pro/src/api/controllers/global/scim/users.ts", "../../shared-core/src/constants.ts", "../../shared-core/src/helpers/helpers.ts", "../../shared-core/src/helpers/integrations.ts", "../../shared-core/src/helpers/index.ts", "../../shared-core/src/filters.ts", "../../shared-core/src/utils.ts", "../../shared-core/src/index.ts", "../../pro/packages/pro/src/api/controllers/global/scim/groups.ts", "../../pro/packages/pro/src/api/routes/global/scim.ts", "../../pro/packages/pro/src/api/index.ts", "../../pro/packages/pro/src/mappers/users.ts", "../../pro/packages/pro/src/mappers/groups.ts", "../../pro/packages/pro/src/mappers/index.ts", "../../pro/packages/pro/src/index.ts", "../src/db/newid.ts", "../src/db/utils.ts", "../src/utilities/index.ts", "../src/constants/index.ts", "../src/utilities/budibaseDir.ts", "../src/utilities/centralPath.ts", "../src/utilities/fileSystem/filesystem.ts", "../src/utilities/fileSystem/clientLibrary.ts", "../src/utilities/fileSystem/app.ts", "../src/utilities/fileSystem/plugin.ts", "../src/utilities/fileSystem/template.ts", "../src/utilities/fileSystem/index.ts", "../src/sdk/app/backups/constants.ts", "../src/sdk/app/backups/exports.ts", "../src/sdk/app/backups/imports.ts", "../src/sdk/app/backups/statistics.ts", "../src/sdk/app/backups/index.ts", "../src/integrations/utils.ts", "../src/sdk/utils/index.ts", "../src/integrations/base/sqlTable.ts", "../src/integrations/base/sql.ts", "../src/integrations/postgres.ts", "../src/db/dynamoClient.ts", "../src/integrations/dynamodb.ts", "../src/integrations/mongodb.ts", "../src/integrations/elasticsearch.ts", "../src/integrations/couchdb.ts", "../src/integrations/microsoftSqlServer.ts", "../src/integrations/s3.ts", "../src/integrations/airtable.ts", "../src/integrations/mysql.ts", "../src/integrations/arangodb.ts", "../src/integrations/rest.ts", "../src/integrations/googlesheets.ts", "../src/integrations/firebase.ts", "../src/integrations/redis.ts", "../src/integrations/snowflake.ts", "../src/integrations/oracle.ts", "../src/integrations/index.ts", "../src/sdk/app/datasources/datasources.ts", "../src/sdk/app/datasources/index.ts", "../src/sdk/app/tables/index.ts", "../src/sdk/app/automations/webhook.ts", "../src/sdk/app/automations/index.ts", "../src/utilities/global.ts", "../src/sdk/app/applications/sync.ts", "../src/sdk/app/applications/utils.ts", "../src/sdk/app/applications/index.ts", "../src/sdk/app/queries/queries.ts", "../src/sdk/app/queries/index.ts", "../src/sdk/app/rows/attachments.ts", "../src/sdk/app/rows/rows.ts", "../src/sdk/app/rows/index.ts", "../src/sdk/users/utils.ts", "../src/sdk/users/index.ts", "../src/api/controllers/plugin/file.ts", "../src/utilities/redis.ts", "../src/middleware/builder.ts", "../src/middleware/utils.ts", "../src/middleware/authorized.ts", "../src/middleware/currentapp.ts", "../src/websockets/websocket.ts", "../src/websockets/grid.ts", "../src/websockets/client.ts", "../src/websockets/index.ts", "../src/sdk/plugins/plugins.ts", "../src/sdk/plugins/index.ts", "../src/sdk/index.ts", "../src/definitions/automations.ts", "../src/automations/automationUtils.ts", "../src/utilities/users.ts", "../src/api/controllers/user.ts", "../src/integrations/base/query.ts", "../src/api/controllers/view/exporters.ts", "../src/api/controllers/row/utils.ts", "../src/automations/steps/bash.ts", "../src/automations/steps/openai.ts", "../src/threads/automation.ts", "../src/threads/utils.ts", "../src/db/index.ts", "../src/threads/index.ts", "../src/automations/triggerInfo/app.ts", "../src/automations/triggerInfo/cron.ts", "../src/automations/triggerInfo/rowDeleted.ts", "../src/automations/triggerInfo/rowSaved.ts", "../src/automations/triggerInfo/rowUpdated.ts", "../src/automations/triggerInfo/webhook.ts", "../src/automations/triggerInfo/index.ts", "../src/automations/bullboard.ts", "../src/automations/utils.ts", "../src/utilities/workerRequests.ts", "../src/automations/steps/sendSmtpEmail.ts", "../src/api/controllers/row/index.ts", "../src/api/controllers/row/internal.ts", "../src/db/linkedRows/linkUtils.ts", "../src/db/views/staticViews.ts", "../src/db/linkedRows/LinkController.ts", "../src/db/linkedRows/LinkDocument.ts", "../src/db/linkedRows/index.ts", "../src/utilities/rowProcessor/index.ts", "../src/utilities/rowProcessor/utils.ts", "../src/utilities/rowProcessor/map.ts", "../src/api/controllers/row/internalSearch.ts", "../src/db/inMemoryView.ts", "../src/api/controllers/view/utils.ts", "../src/api/controllers/view/viewBuilder.ts", "../src/api/controllers/row/staticFormula.ts", "../src/api/controllers/row/external.ts", "../src/api/controllers/row/ExternalRequest.ts", "../src/automations/steps/createRow.ts", "../src/automations/steps/utils.ts", "../src/automations/steps/updateRow.ts", "../src/automations/steps/deleteRow.ts", "../src/utilities/scriptRunner.ts", "../src/api/controllers/script.ts", "../src/automations/steps/executeScript.ts", "../src/api/controllers/query/index.ts", "../src/api/controllers/datasource.ts", "../src/api/controllers/table/internal.ts", "../src/utilities/schema.ts", "../src/api/controllers/table/utils.ts", "../src/api/controllers/table/bulkFormula.ts", "../src/api/controllers/query/validation.ts", "../src/api/controllers/query/import/index.ts", "../src/api/controllers/query/import/sources/openapi2.ts", "../src/api/controllers/query/import/sources/base/openapi.ts", "../src/api/controllers/query/import/sources/openapi3.ts", "../src/api/controllers/query/import/sources/curl.ts", "../src/automations/steps/executeQuery.ts", "../src/automations/steps/outgoingWebhook.ts", "../src/automations/steps/serverLog.ts", "../src/automations/steps/discord.ts", "../src/automations/steps/slack.ts", "../src/automations/steps/zapier.ts", "../src/automations/steps/make.ts", "../src/automations/steps/filter.ts", "../src/automations/steps/delay.ts", "../src/api/controllers/table/external.ts", "../src/api/controllers/table/index.ts", "../src/utilities/csv.ts", "../src/automations/steps/queryRows.ts", "../src/automations/steps/loop.ts", "../src/automations/actions.ts", "../src/events/utils.ts", "../src/events/BudibaseEmitter.ts", "../src/events/docUpdates/syncUsers.ts", "../src/events/docUpdates/processors.ts", "../src/events/index.ts", "../src/events/AutomationEmitter.ts", "../src/automations/logging/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { join } from \"path\"\n\nfunction isTest() {\n return isCypress() || isJest()\n}\n\nfunction isJest() {\n return (\n process.env.NODE_ENV === \"jest\" ||\n (process.env.JEST_WORKER_ID != null &&\n process.env.JEST_WORKER_ID !== \"null\")\n )\n}\n\nfunction isDev() {\n return process.env.NODE_ENV !== \"production\"\n}\n\nfunction isCypress() {\n return process.env.NODE_ENV === \"cypress\"\n}\n\nlet LOADED = false\nif (!LOADED && isDev() && !isTest()) {\n require(\"dotenv\").config({\n path: join(__dirname, \"..\", \".env\"),\n })\n LOADED = true\n}\n\nfunction parseIntSafe(number?: string) {\n if (number) {\n return parseInt(number)\n }\n}\n\nconst environment = {\n // important - prefer app port to generic port\n PORT: process.env.APP_PORT || process.env.PORT,\n COUCH_DB_URL: process.env.COUCH_DB_URL,\n MINIO_URL: process.env.MINIO_URL,\n WORKER_URL: process.env.WORKER_URL,\n AWS_REGION: process.env.AWS_REGION,\n MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,\n MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,\n REDIS_URL: process.env.REDIS_URL,\n REDIS_PASSWORD: process.env.REDIS_PASSWORD,\n REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,\n HTTP_MIGRATIONS: process.env.HTTP_MIGRATIONS,\n API_REQ_LIMIT_PER_SEC: process.env.API_REQ_LIMIT_PER_SEC,\n GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,\n GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,\n // environment\n NODE_ENV: process.env.NODE_ENV,\n JEST_WORKER_ID: process.env.JEST_WORKER_ID,\n BUDIBASE_ENVIRONMENT: process.env.BUDIBASE_ENVIRONMENT,\n DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,\n TEMPLATE_REPOSITORY: process.env.TEMPLATE_REPOSITORY || \"app\",\n DISABLE_AUTO_PROD_APP_SYNC: process.env.DISABLE_AUTO_PROD_APP_SYNC,\n SESSION_UPDATE_PERIOD: process.env.SESSION_UPDATE_PERIOD,\n // minor\n SALT_ROUNDS: process.env.SALT_ROUNDS,\n LOGGER: process.env.LOGGER,\n ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,\n AUTOMATION_MAX_ITERATIONS:\n parseIntSafe(process.env.AUTOMATION_MAX_ITERATIONS) || 200,\n SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,\n DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,\n QUERY_THREAD_TIMEOUT: parseIntSafe(process.env.QUERY_THREAD_TIMEOUT),\n SQL_MAX_ROWS: process.env.SQL_MAX_ROWS,\n BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,\n BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,\n PLUGINS_DIR: process.env.PLUGINS_DIR || \"/plugins\",\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n // flags\n ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS,\n DISABLE_THREADING: process.env.DISABLE_THREADING,\n DISABLE_AUTOMATION_LOGS: process.env.DISABLE_AUTOMATION_LOGS,\n MULTI_TENANCY: process.env.MULTI_TENANCY,\n ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,\n SELF_HOSTED: process.env.SELF_HOSTED,\n HTTP_MB_LIMIT: process.env.HTTP_MB_LIMIT,\n // old\n CLIENT_ID: process.env.CLIENT_ID,\n _set(key: string, value: any) {\n process.env[key] = value\n // @ts-ignore\n environment[key] = value\n },\n isTest,\n isJest,\n isCypress,\n isDev,\n isProd: () => {\n return !isDev()\n },\n isInThread: () => {\n return process.env.FORKED_PROCESS\n },\n TOP_LEVEL_PATH: process.env.TOP_LEVEL_PATH,\n}\n\n// threading can cause memory issues with node-ts in development\nif (isDev() && environment.DISABLE_THREADING == null) {\n environment._set(\"DISABLE_THREADING\", \"1\")\n}\n\n// clean up any environment variable edge cases\nfor (let [key, value] of Object.entries(environment)) {\n // handle the edge case of \"0\" to disable an environment variable\n if (value === \"0\") {\n // @ts-ignore\n environment[key] = 0\n }\n // handle the edge case of \"false\" to disable an environment variable\n if (value === \"false\") {\n // @ts-ignore\n environment[key] = 0\n }\n}\n\nexport default environment\n", "import { Automation, AutomationMetadata } from \"../../documents\"\nimport { Job } from \"bull\"\n\nexport interface AutomationDataEvent {\n appId?: string\n metadata?: AutomationMetadata\n automation?: Automation\n}\n\nexport interface AutomationData {\n event: AutomationDataEvent\n automation: Automation\n}\n\nexport type AutomationJob = Job<AutomationData>\n", "export enum Hosting {\n CLOUD = \"cloud\",\n SELF = \"self\",\n}\n", "import { User, Account } from \"../documents\"\nimport { IdentityType, HostInfo } from \"./events\"\n\nexport interface BaseContext {\n _id: string\n type: IdentityType\n tenantId?: string\n}\n\nexport interface AccountUserContext extends BaseContext {\n tenantId: string\n account: Account\n}\n\nexport interface UserContext extends BaseContext, User {\n _id: string\n tenantId: string\n account?: Account\n hostInfo: HostInfo\n}\n\nexport type IdentityContext = BaseContext | AccountUserContext | UserContext\n", "import { BaseEvent } from \"./event\"\n\nexport interface AppCreatedEvent extends BaseEvent {\n appId: string\n version: string\n audited: {\n name: string\n }\n}\n\nexport interface AppUpdatedEvent extends BaseEvent {\n appId: string\n version: string\n audited: {\n name: string\n }\n}\n\nexport interface AppDeletedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppPublishedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppUnpublishedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppFileImportedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppTemplateImportedEvent extends BaseEvent {\n appId: string\n templateKey: string\n audited: {\n name: string\n }\n}\n\nexport interface AppVersionUpdatedEvent extends BaseEvent {\n appId: string\n currentVersion: string\n updatedToVersion: string\n audited: {\n name: string\n }\n}\n\nexport interface AppVersionRevertedEvent extends BaseEvent {\n appId: string\n currentVersion: string\n revertedToVersion: string\n audited: {\n name: string\n }\n}\n\nexport interface AppRevertedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n\nexport interface AppExportedEvent extends BaseEvent {\n appId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\nimport { ConfigType } from \"../../documents\"\n\nexport type LoginSource = \"local\" | \"google\" | \"oidc\" | \"google-internal\"\nexport type SSOType = ConfigType.OIDC | ConfigType.GOOGLE\n\nexport interface LoginEvent extends BaseEvent {\n userId: string\n source: LoginSource\n audited: {\n email: string\n }\n}\n\nexport interface LogoutEvent extends BaseEvent {\n userId: string\n audited: {\n email?: string\n }\n}\n\nexport interface SSOCreatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSOUpdatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSOActivatedEvent extends BaseEvent {\n type: SSOType\n}\n\nexport interface SSODeactivatedEvent extends BaseEvent {\n type: SSOType\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface AutomationCreatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationTriggerUpdatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n}\n\nexport interface AutomationDeletedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationTestedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n}\n\nexport interface AutomationStepCreatedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n stepId: string\n stepType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationStepDeletedEvent extends BaseEvent {\n appId: string\n automationId: string\n triggerId: string\n triggerType: string\n stepId: string\n stepType: string\n audited: {\n name: string\n }\n}\n\nexport interface AutomationsRunEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface SMTPCreatedEvent extends BaseEvent {}\n\nexport interface SMTPUpdatedEvent extends BaseEvent {}\n", "import { BaseEvent } from \"./event\"\n\nexport interface DatasourceCreatedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n\nexport interface DatasourceUpdatedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n\nexport interface DatasourceDeletedEvent extends BaseEvent {\n datasourceId: string\n source: string\n custom: boolean\n}\n", "import { Hosting } from \"../hosting\"\nimport { Group, Identity } from \"./identification\"\n\nexport enum Event {\n // USER\n USER_CREATED = \"user:created\",\n USER_UPDATED = \"user:updated\",\n USER_DELETED = \"user:deleted\",\n\n // USER / ONBOARDING\n USER_ONBOARDING_COMPLETE = \"user:onboarding:complete\",\n\n // USER / PERMISSIONS\n USER_PERMISSION_ADMIN_ASSIGNED = \"user:admin:assigned\",\n USER_PERMISSION_ADMIN_REMOVED = \"user:admin:removed\",\n USER_PERMISSION_BUILDER_ASSIGNED = \"user:builder:assigned\",\n USER_PERMISSION_BUILDER_REMOVED = \"user:builder:removed\",\n\n // USER / INVITE\n USER_INVITED = \"user:invited\",\n USER_INVITED_ACCEPTED = \"user:invite:accepted\",\n\n // USER / PASSWORD\n USER_PASSWORD_FORCE_RESET = \"user:password:force:reset\",\n USER_PASSWORD_UPDATED = \"user:password:updated\",\n USER_PASSWORD_RESET_REQUESTED = \"user:password:reset:requested\",\n USER_PASSWORD_RESET = \"user:password:reset\",\n\n // EMAIL\n EMAIL_SMTP_CREATED = \"email:smtp:created\",\n EMAIL_SMTP_UPDATED = \"email:smtp:updated\",\n\n // AUTH\n AUTH_SSO_CREATED = \"auth:sso:created\",\n AUTH_SSO_UPDATED = \"auth:sso:updated\",\n AUTH_SSO_ACTIVATED = \"auth:sso:activated\",\n AUTH_SSO_DEACTIVATED = \"auth:sso:deactivated\",\n AUTH_LOGIN = \"auth:login\",\n AUTH_LOGOUT = \"auth:logout\",\n\n // ORG\n ORG_NAME_UPDATED = \"org:info:name:updated\",\n ORG_LOGO_UPDATED = \"org:info:logo:updated\",\n ORG_PLATFORM_URL_UPDATED = \"org:platformurl:updated\",\n\n // INSTALLATION\n INSTALLATION_VERSION_CHECKED = \"installation:version:checked\",\n INSTALLATION_VERSION_UPGRADED = \"installation:version:upgraded\",\n INSTALLATION_VERSION_DOWNGRADED = \"installation:version:downgraded\",\n INSTALLATION_FIRST_STARTUP = \"installation:firstStartup\",\n\n // ORG / ANALYTICS\n ANALYTICS_OPT_OUT = \"analytics:opt:out\",\n ANALYTICS_OPT_IN = \"analytics:opt:in\",\n\n // APP\n APP_CREATED = \"app:created\",\n APP_UPDATED = \"app:updated\",\n APP_DELETED = \"app:deleted\",\n APP_PUBLISHED = \"app:published\",\n APP_UNPUBLISHED = \"app:unpublished\",\n APP_TEMPLATE_IMPORTED = \"app:template:imported\",\n APP_FILE_IMPORTED = \"app:file:imported\",\n APP_VERSION_UPDATED = \"app:version:updated\",\n APP_VERSION_REVERTED = \"app:version:reverted\",\n APP_REVERTED = \"app:reverted\",\n APP_EXPORTED = \"app:exported\",\n\n // ROLE\n ROLE_CREATED = \"role:created\",\n ROLE_UPDATED = \"role:updated\",\n ROLE_DELETED = \"role:deleted\",\n ROLE_ASSIGNED = \"role:assigned\",\n ROLE_UNASSIGNED = \"role:unassigned\",\n\n // SERVE\n SERVED_BUILDER = \"served:builder\",\n SERVED_APP = \"served:app\",\n SERVED_APP_PREVIEW = \"served:app:preview\",\n\n // DATASOURCE\n DATASOURCE_CREATED = \"datasource:created\",\n DATASOURCE_UPDATED = \"datasource:updated\",\n DATASOURCE_DELETED = \"datasource:deleted\",\n\n // QUERY\n QUERY_CREATED = \"query:created\",\n QUERY_UPDATED = \"query:updated\",\n QUERY_DELETED = \"query:deleted\",\n QUERY_IMPORT = \"query:import\",\n QUERIES_RUN = \"queries:run\",\n QUERY_PREVIEWED = \"query:previewed\",\n\n // TABLE\n TABLE_CREATED = \"table:created\",\n TABLE_UPDATED = \"table:updated\",\n TABLE_DELETED = \"table:deleted\",\n TABLE_EXPORTED = \"table:exported\",\n TABLE_IMPORTED = \"table:imported\",\n TABLE_DATA_IMPORTED = \"table:data:imported\",\n\n // VIEW\n VIEW_CREATED = \"view:created\",\n VIEW_UPDATED = \"view:updated\",\n VIEW_DELETED = \"view:deleted\",\n VIEW_EXPORTED = \"view:exported\",\n VIEW_FILTER_CREATED = \"view:filter:created\",\n VIEW_FILTER_UPDATED = \"view:filter:updated\",\n VIEW_FILTER_DELETED = \"view:filter:deleted\",\n VIEW_CALCULATION_CREATED = \"view:calculation:created\",\n VIEW_CALCULATION_UPDATED = \"view:calculation:updated\",\n VIEW_CALCULATION_DELETED = \"view:calculation:deleted\",\n\n // ROWS\n ROWS_CREATED = \"rows:created\",\n ROWS_IMPORTED = \"rows:imported\",\n\n // COMPONENT\n COMPONENT_CREATED = \"component:created\",\n COMPONENT_DELETED = \"component:deleted\",\n\n // SCREEN\n SCREEN_CREATED = \"screen:created\",\n SCREEN_DELETED = \"screen:deleted\",\n\n // LAYOUT\n LAYOUT_CREATED = \"layout:created\",\n LAYOUT_DELETED = \"layout:deleted\",\n\n // AUTOMATION\n AUTOMATION_CREATED = \"automation:created\",\n AUTOMATION_DELETED = \"automation:deleted\",\n AUTOMATION_TESTED = \"automation:tested\",\n AUTOMATIONS_RUN = \"automations:run\",\n AUTOMATION_STEP_CREATED = \"automation:step:created\",\n AUTOMATION_STEP_DELETED = \"automation:step:deleted\",\n AUTOMATION_TRIGGER_UPDATED = \"automation:trigger:updated\",\n\n // LICENSE\n LICENSE_PLAN_CHANGED = \"license:plan:changed\",\n LICENSE_ACTIVATED = \"license:activated\",\n LICENSE_PAYMENT_FAILED = \"license:payment:failed\",\n LICENSE_PAYMENT_RECOVERED = \"license:payment:recovered\",\n LICENSE_CHECKOUT_OPENED = \"license:checkout:opened\",\n LICENSE_CHECKOUT_SUCCESS = \"license:checkout:success\",\n LICENSE_PORTAL_OPENED = \"license:portal:opened\",\n\n // ACCOUNT\n ACCOUNT_CREATED = \"account:created\",\n ACCOUNT_DELETED = \"account:deleted\",\n ACCOUNT_VERIFIED = \"account:verified\",\n\n // BACKFILL\n APP_BACKFILL_SUCCEEDED = \"app:backfill:succeeded\",\n APP_BACKFILL_FAILED = \"app:backfill:failed\",\n TENANT_BACKFILL_SUCCEEDED = \"tenant:backfill:succeeded\",\n TENANT_BACKFILL_FAILED = \"tenant:backfill:failed\",\n INSTALLATION_BACKFILL_SUCCEEDED = \"installation:backfill:succeeded\",\n INSTALLATION_BACKFILL_FAILED = \"installation:backfill:failed\",\n\n // USER\n USER_GROUP_CREATED = \"user_group:created\",\n USER_GROUP_UPDATED = \"user_group:updated\",\n USER_GROUP_DELETED = \"user_group:deleted\",\n USER_GROUP_USERS_ADDED = \"user_group:user_added\",\n USER_GROUP_USERS_REMOVED = \"user_group:users_deleted\",\n USER_GROUP_PERMISSIONS_EDITED = \"user_group:permissions_edited\",\n USER_GROUP_ONBOARDING = \"user_group:onboarding_added\",\n\n // PLUGIN\n PLUGIN_INIT = \"plugin:init\",\n PLUGIN_IMPORTED = \"plugin:imported\",\n PLUGIN_DELETED = \"plugin:deleted\",\n\n // BACKUP\n APP_BACKUP_RESTORED = \"app:backup:restored\",\n APP_BACKUP_TRIGGERED = \"app:backup:triggered\",\n\n // ENVIRONMENT VARIABLE\n ENVIRONMENT_VARIABLE_CREATED = \"environment_variable:created\",\n ENVIRONMENT_VARIABLE_DELETED = \"environment_variable:deleted\",\n ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED = \"environment_variable:upgrade_panel_opened\",\n\n // AUDIT LOG\n AUDIT_LOGS_FILTERED = \"audit_log:filtered\",\n AUDIT_LOGS_DOWNLOADED = \"audit_log:downloaded\",\n}\n\nexport const UserGroupSyncEvents: Event[] = [\n Event.USER_CREATED,\n Event.USER_UPDATED,\n Event.USER_DELETED,\n Event.USER_PERMISSION_ADMIN_ASSIGNED,\n Event.USER_PERMISSION_ADMIN_REMOVED,\n Event.USER_PERMISSION_BUILDER_ASSIGNED,\n Event.USER_PERMISSION_BUILDER_REMOVED,\n Event.USER_GROUP_CREATED,\n Event.USER_GROUP_UPDATED,\n Event.USER_GROUP_DELETED,\n Event.USER_GROUP_USERS_ADDED,\n Event.USER_GROUP_USERS_REMOVED,\n Event.USER_GROUP_PERMISSIONS_EDITED,\n]\n\nexport const AsyncEvents: Event[] = [...UserGroupSyncEvents]\n\n// all events that are not audited have been added to this record as undefined, this means\n// that Typescript can protect us against new events being added and auditing of those\n// events not being considered. This might be a little ugly, but provides a level of\n// Typescript build protection for the audit log feature, any new event also needs to be\n// added to this map, during which the developer will need to consider if it should be\n// a user facing event or not.\nexport const AuditedEventFriendlyName: Record<Event, string | undefined> = {\n // USER\n [Event.USER_CREATED]: `User \"{{ email }}\" created{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_UPDATED]: `User \"{{ email }}\" updated{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_DELETED]: `User \"{{ email }}\" deleted{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: `User \"{{ email }}\" admin role assigned`,\n [Event.USER_PERMISSION_ADMIN_REMOVED]: `User \"{{ email }}\" admin role removed`,\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: `User \"{{ email }}\" builder role assigned`,\n [Event.USER_PERMISSION_BUILDER_REMOVED]: `User \"{{ email }}\" builder role removed`,\n [Event.USER_INVITED]: `User \"{{ email }}\" invited`,\n [Event.USER_INVITED_ACCEPTED]: `User \"{{ email }}\" accepted invite`,\n [Event.USER_PASSWORD_UPDATED]: `User \"{{ email }}\" password updated`,\n [Event.USER_PASSWORD_RESET_REQUESTED]: `User \"{{ email }}\" password reset requested`,\n [Event.USER_PASSWORD_RESET]: `User \"{{ email }}\" password reset`,\n [Event.USER_GROUP_CREATED]: `User group \"{{ name }}\" created{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_UPDATED]: `User group \"{{ name }}\" updated{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_DELETED]: `User group \"{{ name }}\" deleted{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_USERS_ADDED]: `User group \"{{ name }}\" {{ count }} users added{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_USERS_REMOVED]: `User group \"{{ name }}\" {{ count }} users removed{{#if viaScim}} via SCIM{{/if}}`,\n [Event.USER_GROUP_PERMISSIONS_EDITED]: `User group \"{{ name }}\" permissions edited`,\n [Event.USER_PASSWORD_FORCE_RESET]: undefined,\n [Event.USER_GROUP_ONBOARDING]: undefined,\n [Event.USER_ONBOARDING_COMPLETE]: undefined,\n\n // EMAIL\n [Event.EMAIL_SMTP_CREATED]: `Email configuration created`,\n [Event.EMAIL_SMTP_UPDATED]: `Email configuration updated`,\n\n // AUTH\n [Event.AUTH_SSO_CREATED]: `SSO configuration created`,\n [Event.AUTH_SSO_UPDATED]: `SSO configuration updated`,\n [Event.AUTH_SSO_ACTIVATED]: `SSO configuration activated`,\n [Event.AUTH_SSO_DEACTIVATED]: `SSO configuration deactivated`,\n [Event.AUTH_LOGIN]: `User \"{{ email }}\" logged in`,\n [Event.AUTH_LOGOUT]: `User \"{{ email }}\" logged out`,\n\n // ORG\n [Event.ORG_NAME_UPDATED]: `Organisation name updated`,\n [Event.ORG_LOGO_UPDATED]: `Organisation logo updated`,\n [Event.ORG_PLATFORM_URL_UPDATED]: `Organisation platform URL updated`,\n\n // APP\n [Event.APP_CREATED]: `App \"{{ name }}\" created`,\n [Event.APP_UPDATED]: `App \"{{ name }}\" updated`,\n [Event.APP_DELETED]: `App \"{{ name }}\" deleted`,\n [Event.APP_PUBLISHED]: `App \"{{ name }}\" published`,\n [Event.APP_UNPUBLISHED]: `App \"{{ name }}\" unpublished`,\n [Event.APP_TEMPLATE_IMPORTED]: `App \"{{ name }}\" template imported`,\n [Event.APP_FILE_IMPORTED]: `App \"{{ name }}\" file imported`,\n [Event.APP_VERSION_UPDATED]: `App \"{{ name }}\" version updated`,\n [Event.APP_VERSION_REVERTED]: `App \"{{ name }}\" version reverted`,\n [Event.APP_REVERTED]: `App \"{{ name }}\" reverted`,\n [Event.APP_EXPORTED]: `App \"{{ name }}\" exported`,\n [Event.APP_BACKUP_RESTORED]: `App backup \"{{ name }}\" restored`,\n [Event.APP_BACKUP_TRIGGERED]: `App backup \"{{ name }}\" triggered`,\n\n // DATASOURCE\n [Event.DATASOURCE_CREATED]: `Datasource created`,\n [Event.DATASOURCE_UPDATED]: `Datasource updated`,\n [Event.DATASOURCE_DELETED]: `Datasource deleted`,\n\n // QUERY\n [Event.QUERY_CREATED]: `Query created`,\n [Event.QUERY_UPDATED]: `Query updated`,\n [Event.QUERY_DELETED]: `Query deleted`,\n [Event.QUERY_IMPORT]: `Query import`,\n [Event.QUERIES_RUN]: undefined,\n [Event.QUERY_PREVIEWED]: undefined,\n\n // TABLE\n [Event.TABLE_CREATED]: `Table \"{{ name }}\" created`,\n [Event.TABLE_UPDATED]: `Table \"{{ name }}\" updated`,\n [Event.TABLE_DELETED]: `Table \"{{ name }}\" deleted`,\n [Event.TABLE_EXPORTED]: `Table \"{{ name }}\" exported`,\n [Event.TABLE_IMPORTED]: `Table \"{{ name }}\" imported`,\n [Event.TABLE_DATA_IMPORTED]: `Data imported to table`,\n\n // ROWS\n [Event.ROWS_CREATED]: `Rows created`,\n [Event.ROWS_IMPORTED]: `Rows imported`,\n\n // AUTOMATION\n [Event.AUTOMATION_CREATED]: `Automation \"{{ name }}\" created`,\n [Event.AUTOMATION_DELETED]: `Automation \"{{ name }}\" deleted`,\n [Event.AUTOMATION_STEP_CREATED]: `Automation \"{{ name }}\" step added`,\n [Event.AUTOMATION_STEP_DELETED]: `Automation \"{{ name }}\" step removed`,\n [Event.AUTOMATION_TESTED]: undefined,\n [Event.AUTOMATIONS_RUN]: undefined,\n [Event.AUTOMATION_TRIGGER_UPDATED]: undefined,\n\n // SCREEN\n [Event.SCREEN_CREATED]: `Screen \"{{ name }}\" created`,\n [Event.SCREEN_DELETED]: `Screen \"{{ name }}\" deleted`,\n\n // COMPONENT\n [Event.COMPONENT_CREATED]: `Component created`,\n [Event.COMPONENT_DELETED]: `Component deleted`,\n\n // ENVIRONMENT VARIABLE\n [Event.ENVIRONMENT_VARIABLE_CREATED]: `Environment variable created`,\n [Event.ENVIRONMENT_VARIABLE_DELETED]: `Environment variable deleted`,\n [Event.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED]: undefined,\n\n // PLUGIN\n [Event.PLUGIN_IMPORTED]: `Plugin imported`,\n [Event.PLUGIN_DELETED]: `Plugin deleted`,\n [Event.PLUGIN_INIT]: undefined,\n\n // ROLE - NOT AUDITED\n [Event.ROLE_CREATED]: undefined,\n [Event.ROLE_UPDATED]: undefined,\n [Event.ROLE_DELETED]: undefined,\n [Event.ROLE_ASSIGNED]: undefined,\n [Event.ROLE_UNASSIGNED]: undefined,\n\n // LICENSE - NOT AUDITED\n [Event.LICENSE_PLAN_CHANGED]: undefined,\n [Event.LICENSE_ACTIVATED]: undefined,\n [Event.LICENSE_PAYMENT_FAILED]: undefined,\n [Event.LICENSE_PAYMENT_RECOVERED]: undefined,\n [Event.LICENSE_CHECKOUT_OPENED]: undefined,\n [Event.LICENSE_CHECKOUT_SUCCESS]: undefined,\n [Event.LICENSE_PORTAL_OPENED]: undefined,\n\n // ACCOUNT - NOT AUDITED\n [Event.ACCOUNT_CREATED]: undefined,\n [Event.ACCOUNT_DELETED]: undefined,\n [Event.ACCOUNT_VERIFIED]: undefined,\n\n // BACKFILL - NOT AUDITED\n [Event.APP_BACKFILL_SUCCEEDED]: undefined,\n [Event.APP_BACKFILL_FAILED]: undefined,\n [Event.TENANT_BACKFILL_SUCCEEDED]: undefined,\n [Event.TENANT_BACKFILL_FAILED]: undefined,\n [Event.INSTALLATION_BACKFILL_SUCCEEDED]: undefined,\n [Event.INSTALLATION_BACKFILL_FAILED]: undefined,\n\n // LAYOUT - NOT AUDITED\n [Event.LAYOUT_CREATED]: undefined,\n [Event.LAYOUT_DELETED]: undefined,\n\n // VIEW - NOT AUDITED\n [Event.VIEW_CREATED]: undefined,\n [Event.VIEW_UPDATED]: undefined,\n [Event.VIEW_DELETED]: undefined,\n [Event.VIEW_EXPORTED]: undefined,\n [Event.VIEW_FILTER_CREATED]: undefined,\n [Event.VIEW_FILTER_UPDATED]: undefined,\n [Event.VIEW_FILTER_DELETED]: undefined,\n [Event.VIEW_CALCULATION_CREATED]: undefined,\n [Event.VIEW_CALCULATION_UPDATED]: undefined,\n [Event.VIEW_CALCULATION_DELETED]: undefined,\n\n // SERVED - NOT AUDITED\n [Event.SERVED_BUILDER]: undefined,\n [Event.SERVED_APP]: undefined,\n [Event.SERVED_APP_PREVIEW]: undefined,\n\n // ANALYTICS - NOT AUDITED\n [Event.ANALYTICS_OPT_OUT]: undefined,\n [Event.ANALYTICS_OPT_IN]: undefined,\n\n // INSTALLATION - NOT AUDITED\n [Event.INSTALLATION_VERSION_CHECKED]: undefined,\n [Event.INSTALLATION_VERSION_UPGRADED]: undefined,\n [Event.INSTALLATION_VERSION_DOWNGRADED]: undefined,\n [Event.INSTALLATION_FIRST_STARTUP]: undefined,\n\n // AUDIT LOG - NOT AUDITED\n [Event.AUDIT_LOGS_FILTERED]: undefined,\n [Event.AUDIT_LOGS_DOWNLOADED]: undefined,\n}\n\n// properties added at the final stage of the event pipeline\nexport interface BaseEvent {\n version?: string\n service?: string\n environment?: string\n appId?: string\n installationId?: string\n tenantId?: string\n hosting?: Hosting\n // any props in the audited section will be removed before passing events\n // up out of system (purely for use with auditing)\n audited?: {\n [key: string]: any\n }\n}\n\nexport type TableExportFormat = \"json\" | \"csv\"\n\nexport type DocUpdateEvent = {\n id: string\n tenantId: string\n appId?: string\n}\n\nexport interface EventProcessor {\n processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void>\n identify?(identity: Identity, timestamp?: string | number): Promise<void>\n identifyGroup?(group: Group, timestamp?: string | number): Promise<void>\n shutdown?(): void\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface LayoutCreatedEvent extends BaseEvent {\n layoutId: string\n}\n\nexport interface LayoutDeletedEvent extends BaseEvent {\n layoutId: string\n}\n", "import { PlanType, PriceDuration } from \"../licensing\"\n\nexport interface LicensePlanChangedEvent {\n accountId: string\n from: PlanType\n to: PlanType\n // may not be on historical events\n fromDuration: PriceDuration | undefined\n toDuration: PriceDuration | undefined\n fromQuantity: number | undefined\n toQuantity: number | undefined\n}\n\nexport interface LicenseActivatedEvent {\n accountId: string\n}\n\nexport interface LicenseCheckoutOpenedEvent {\n accountId: string\n}\n\nexport interface LicenseCheckoutSuccessEvent {\n accountId: string\n}\n\nexport interface LicensePortalOpenedEvent {\n accountId: string\n}\n\nexport interface LicensePaymentFailedEvent {\n accountId: string\n}\n\nexport interface LicensePaymentRecoveredEvent {\n accountId: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface VersionCheckedEvent extends BaseEvent {\n currentVersion: string\n}\n\nexport interface VersionChangeEvent extends BaseEvent {\n from: string\n to: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface QueryCreatedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryUpdatedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryDeletedEvent extends BaseEvent {\n queryId: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueryImportedEvent extends BaseEvent {\n datasourceId: string\n source: string\n count: number\n importSource: string\n}\n\nexport interface QueryPreviewedEvent extends BaseEvent {\n queryId?: string\n datasourceId: string\n source: string\n queryVerb: string\n}\n\nexport interface QueriesRunEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface RoleCreatedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleUpdatedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleDeletedEvent extends BaseEvent {\n roleId: string\n permissionId: string\n inherits?: string\n}\n\nexport interface RoleAssignedEvent extends BaseEvent {\n userId: string\n roleId: string\n}\n\nexport interface RoleUnassignedEvent extends BaseEvent {\n userId: string\n roleId: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface RowsImportedEvent extends BaseEvent {\n tableId: string\n count: number\n}\n\nexport interface RowsCreatedEvent extends BaseEvent {\n count: number\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface ScreenCreatedEvent extends BaseEvent {\n screenId: string\n layoutId?: string\n roleId: string\n audited: {\n name: string\n }\n}\n\nexport interface ScreenDeletedEvent extends BaseEvent {\n screenId: string\n layoutId?: string\n roleId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface BuilderServedEvent extends BaseEvent {\n timezone: string\n}\n\nexport interface AppServedEvent extends BaseEvent {\n appVersion: string\n timezone: string\n}\n\nexport interface AppPreviewServedEvent extends BaseEvent {\n appVersion: string\n timezone: string\n}\n", "import { BaseEvent, TableExportFormat } from \"./event\"\n\nexport interface TableCreatedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableUpdatedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableDeletedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n\nexport interface TableExportedEvent extends BaseEvent {\n tableId: string\n format: TableExportFormat\n audited: {\n name: string\n }\n}\n\nexport interface TableImportedEvent extends BaseEvent {\n tableId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface UserCreatedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserUpdatedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserDeletedEvent extends BaseEvent {\n userId: string\n viaScim?: boolean\n audited: {\n email: string\n }\n}\n\nexport interface UserOnboardingEvent extends BaseEvent {\n userId: string\n step?: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPermissionAssignedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPermissionRemovedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserInvitedEvent extends BaseEvent {\n audited: {\n email: string\n }\n}\n\nexport interface UserInviteAcceptedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordForceResetEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordUpdatedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordResetRequestedEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n\nexport interface UserPasswordResetEvent extends BaseEvent {\n userId: string\n audited: {\n email: string\n }\n}\n", "import { ViewCalculation } from \"../../documents\"\nimport { BaseEvent, TableExportFormat } from \"./event\"\n\nexport interface ViewCreatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewUpdatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewDeletedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewExportedEvent extends BaseEvent {\n tableId: string\n format: TableExportFormat\n}\n\nexport interface ViewFilterCreatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewFilterUpdatedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewFilterDeletedEvent extends BaseEvent {\n tableId: string\n}\n\nexport interface ViewCalculationCreatedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n\nexport interface ViewCalculationUpdatedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n\nexport interface ViewCalculationDeletedEvent extends BaseEvent {\n tableId: string\n calculation: ViewCalculation\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface AccountCreatedEvent extends BaseEvent {\n tenantId: string\n registrationStep?: string\n}\n\nexport interface AccountDeletedEvent extends BaseEvent {\n tenantId: string\n registrationStep?: string\n}\n\nexport interface AccountVerifiedEvent extends BaseEvent {\n tenantId: string\n}\n", "import { BaseEvent, Event } from \"./event\"\n\nexport interface AppBackfillSucceededEvent extends BaseEvent {\n appId: string\n automations: number\n datasources: number\n layouts: number\n queries: number\n roles: number\n tables: number\n screens: number\n errors?: string[]\n errorCount?: number\n}\n\nexport interface AppBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface TenantBackfillSucceededEvent extends BaseEvent {\n apps: number\n users: number\n\n usage: any\n errors?: [string]\n errorCount?: number\n}\n\nexport interface TenantBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface InstallationBackfillSucceededEvent extends BaseEvent {}\n\nexport interface InstallationBackfillFailedEvent extends BaseEvent {\n error: string\n}\n\nexport interface BackfillMetadata extends BaseEvent {\n eventWhitelist: Event[]\n}\n\nexport interface CachedEvent extends BaseEvent {\n event: Event\n properties: any\n}\n", "import { Hosting } from \"..\"\n\n// GROUPS\n\nexport enum GroupType {\n TENANT = \"tenant\",\n INSTALLATION = \"installation\",\n}\n\nexport interface Group {\n id: string\n type: IdentityType\n environment: string\n hosting: Hosting\n}\n\nexport interface TenantGroup extends Group {\n // account level information is associated with the tenant group\n // as we don't have this at the user level\n profession?: string // only available in cloud\n companySize?: string // only available in cloud\n installationId: string\n}\n\nexport interface InstallationGroup extends Group {\n version: string\n}\n\n// IDENTITIES\n\nexport enum IdentityType {\n USER = \"user\",\n TENANT = \"tenant\",\n INSTALLATION = \"installation\",\n}\n\nexport interface HostInfo {\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Identity {\n id: string\n type: IdentityType\n hosting: Hosting\n environment: string\n installationId?: string\n tenantId?: string\n // usable - no unique format\n realTenantId?: string\n hostInfo?: HostInfo\n}\n\nexport interface UserIdentity extends Identity {\n verified: boolean\n accountHolder: boolean\n providerType?: string\n builder?: boolean\n admin?: boolean\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface GroupCreatedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUpdatedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupDeletedEvent extends BaseEvent {\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUsersAddedEvent extends BaseEvent {\n count: number\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupUsersDeletedEvent extends BaseEvent {\n count: number\n groupId: string\n viaScim?: boolean\n audited: {\n name: string\n }\n}\n\nexport interface GroupAddedOnboardingEvent extends BaseEvent {\n groupId: string\n onboarding: boolean\n}\n\nexport interface GroupPermissionsEditedEvent extends BaseEvent {\n permissions: Record<string, string>\n groupId: string\n audited: {\n name: string\n }\n}\n", "import { BaseEvent } from \"./event\"\nimport { PluginSource, PluginType } from \"../../\"\n\nexport interface PluginInitEvent extends BaseEvent {\n type: PluginType\n name: string\n version: string\n description: string\n}\n\nexport interface PluginImportedEvent extends BaseEvent {\n pluginId: string\n type: PluginType\n source: PluginSource\n name: string\n version: string\n description: string\n}\n\nexport interface PluginDeletedEvent extends BaseEvent {\n pluginId: string\n type: PluginType\n name: string\n version: string\n description: string\n}\n", "import { BaseEvent } from \"./event\"\nimport { AppBackupTrigger, AppBackupType } from \"../../documents\"\n\nexport interface AppBackupRestoreEvent extends BaseEvent {\n appId: string\n restoreId: string\n backupCreatedAt: string\n name: string\n}\n\nexport interface AppBackupTriggeredEvent extends BaseEvent {\n backupId: string\n appId: string\n trigger: AppBackupTrigger\n type: AppBackupType\n name: string\n}\n", "import { BaseEvent } from \"./event\"\n\nexport interface EnvironmentVariableCreatedEvent extends BaseEvent {\n name: string\n environments: string[]\n}\n\nexport interface EnvironmentVariableDeletedEvent extends BaseEvent {\n name: string\n}\n\nexport interface EnvironmentVariableUpgradePanelOpenedEvent extends BaseEvent {\n userId: string\n}\n", "import { BaseEvent } from \"./event\"\nimport { AuditLogSearchParams } from \"../../api\"\n\nexport interface AuditLogFilteredEvent extends BaseEvent {\n filters: AuditLogSearchParams\n}\n\nexport interface AuditLogDownloadedEvent extends BaseEvent {\n filters: AuditLogSearchParams\n}\n", "export * from \"./app\"\nexport * from \"./auth\"\nexport * from \"./automation\"\nexport * from \"./email\"\nexport * from \"./datasource\"\nexport * from \"./event\"\nexport * from \"./layout\"\nexport * from \"./license\"\nexport * from \"./version\"\nexport * from \"./query\"\nexport * from \"./role\"\nexport * from \"./rows\"\nexport * from \"./screen\"\nexport * from \"./serve\"\nexport * from \"./table\"\nexport * from \"./user\"\nexport * from \"./view\"\nexport * from \"./account\"\nexport * from \"./backfill\"\nexport * from \"./identification\"\nexport * from \"./userGroup\"\nexport * from \"./plugin\"\nexport * from \"./backup\"\nexport * from \"./environmentVariable\"\nexport * from \"./auditLog\"\n", "import { PurchasedPlan, Quotas, Feature, Billing } from \".\"\n\nexport interface License {\n features: Feature[]\n quotas: Quotas\n plan: PurchasedPlan\n billing?: Billing\n testClockId?: string\n}\n", "export enum PlanType {\n FREE = \"free\",\n /** @deprecated */\n PRO = \"pro\",\n /** @deprecated */\n TEAM = \"team\",\n PREMIUM = \"premium\",\n BUSINESS = \"business\",\n ENTERPRISE = \"enterprise\",\n}\n\nexport enum PriceDuration {\n MONTHLY = \"monthly\",\n YEARLY = \"yearly\",\n}\n\nexport interface AvailablePlan {\n type: PlanType\n maxUsers: number\n prices: AvailablePrice[]\n}\n\nexport interface AvailablePrice {\n amount: number\n amountMonthly: number\n currency: string\n duration: PriceDuration\n priceId: string\n}\n\nexport enum PlanModel {\n PER_USER = \"perUser\",\n DAY_PASS = \"dayPass\",\n}\n\nexport interface PurchasedPlan {\n type: PlanType\n model: PlanModel\n usesInvoicing: boolean\n price?: PurchasedPrice\n}\n\nexport interface PurchasedPrice extends AvailablePrice {\n dayPasses: number | undefined\n /** @deprecated - now at the plan level via model */\n isPerUser: boolean\n}\n", "import { PlanType } from \".\"\n\nexport enum QuotaUsageType {\n STATIC = \"static\",\n MONTHLY = \"monthly\",\n}\n\nexport enum QuotaType {\n USAGE = \"usage\",\n CONSTANT = \"constant\",\n}\n\nexport enum StaticQuotaName {\n ROWS = \"rows\",\n APPS = \"apps\",\n USERS = \"users\",\n USER_GROUPS = \"userGroups\",\n PLUGINS = \"plugins\",\n}\n\nexport enum MonthlyQuotaName {\n QUERIES = \"queries\",\n AUTOMATIONS = \"automations\",\n DAY_PASSES = \"dayPasses\",\n}\n\nexport enum ConstantQuotaName {\n AUTOMATION_LOG_RETENTION_DAYS = \"automationLogRetentionDays\",\n APP_BACKUPS_RETENTION_DAYS = \"appBackupRetentionDays\",\n}\n\nexport type MeteredQuotaName = StaticQuotaName | MonthlyQuotaName\nexport type QuotaName = StaticQuotaName | MonthlyQuotaName | ConstantQuotaName\n\nexport const isStaticQuota = (\n quotaType: QuotaType,\n usageType: QuotaUsageType,\n name: QuotaName\n): name is StaticQuotaName => {\n return quotaType === QuotaType.USAGE && usageType === QuotaUsageType.STATIC\n}\n\nexport const isMonthlyQuota = (\n quotaType: QuotaType,\n usageType: QuotaUsageType,\n name: QuotaName\n): name is MonthlyQuotaName => {\n return quotaType === QuotaType.USAGE && usageType === QuotaUsageType.MONTHLY\n}\n\nexport const isConstantQuota = (\n quotaType: QuotaType,\n name: QuotaName\n): name is ConstantQuotaName => {\n return quotaType === QuotaType.CONSTANT\n}\n\nexport type PlanQuotas = { [key in PlanType]: Quotas | undefined }\n\nexport type MonthlyQuotas = {\n [MonthlyQuotaName.QUERIES]: Quota\n [MonthlyQuotaName.AUTOMATIONS]: Quota\n [MonthlyQuotaName.DAY_PASSES]: Quota\n}\n\nexport type StaticQuotas = {\n [StaticQuotaName.ROWS]: Quota\n [StaticQuotaName.APPS]: Quota\n [StaticQuotaName.USERS]: Quota\n [StaticQuotaName.USER_GROUPS]: Quota\n [StaticQuotaName.PLUGINS]: Quota\n}\n\nexport type ConstantQuotas = {\n [ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: Quota\n [ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS]: Quota\n}\n\nexport type Quotas = {\n [QuotaType.USAGE]: {\n [QuotaUsageType.MONTHLY]: MonthlyQuotas\n [QuotaUsageType.STATIC]: StaticQuotas\n }\n [QuotaType.CONSTANT]: ConstantQuotas\n}\n\nexport interface Quota {\n name: string\n value: number\n /**\n * Array of whole numbers (1-100) that dictate the percentage that this quota should trigger\n * at in relation to the corresponding usage inside budibase.\n *\n * Triggering results in a budibase installation sending a request to account-portal,\n * which can have subsequent effects such as sending emails to users.\n */\n triggers: number[]\n startDate?: number\n}\n", "import { PlanType } from \"./plan\"\n\nexport enum Feature {\n USER_GROUPS = \"userGroups\",\n APP_BACKUPS = \"appBackups\",\n ENVIRONMENT_VARIABLES = \"environmentVariables\",\n AUDIT_LOGS = \"auditLogs\",\n ENFORCEABLE_SSO = \"enforceableSSO\",\n BRANDING = \"branding\",\n SCIM = \"scim\",\n}\n\nexport type PlanFeatures = { [key in PlanType]: Feature[] | undefined }\n", "import { PriceDuration } from \"./plan\"\n\nexport interface Customer {\n balance: number | null | undefined\n currency: string | null | undefined\n}\n\nexport interface Subscription {\n amount: number\n currency: string\n quantity: number\n duration: PriceDuration\n cancelAt: number | null | undefined\n currentPeriodStart: number\n currentPeriodEnd: number\n status: string\n pastDueAt?: number | null\n downgradeAt?: number\n}\n\nexport interface Billing {\n customer: Customer\n subscription?: Subscription\n}\n", "export * from \"./license\"\nexport * from \"./plan\"\nexport * from \"./quota\"\nexport * from \"./feature\"\nexport * from \"./billing\"\n", "export interface Migration extends MigrationDefinition {\n appOpts?: object\n fn: Function\n silent?: boolean\n preventRetry?: boolean\n}\n\nexport enum MigrationType {\n // run once per tenant, recorded in global db, global db is provided as an argument\n GLOBAL = \"global\",\n // run per app, recorded in each app db, app db is provided as an argument\n APP = \"app\",\n // run once, recorded in global info db, global info db is provided as an argument\n INSTALLATION = \"installation\",\n}\n\nexport interface MigrationNoOpOptions {\n type: MigrationType\n tenantId: string\n appId?: string\n}\n\n/**\n * e.g.\n * {\n * tenantIds: ['bb'],\n * force: {\n * global: ['quota_1']\n * }\n * }\n */\nexport interface MigrationOptions {\n tenantIds?: string[]\n force?: {\n [type: string]: string[]\n }\n noOp?: MigrationNoOpOptions\n}\n\nexport enum MigrationName {\n USER_EMAIL_VIEW_CASING = \"user_email_view_casing\",\n APP_URLS = \"app_urls\",\n EVENT_APP_BACKFILL = \"event_app_backfill\",\n EVENT_GLOBAL_BACKFILL = \"event_global_backfill\",\n EVENT_INSTALLATION_BACKFILL = \"event_installation_backfill\",\n GLOBAL_INFO_SYNC_USERS = \"global_info_sync_users\",\n TABLE_SETTINGS_LINKS_TO_ACTIONS = \"table_settings_links_to_actions\",\n // increment this number to re-activate this migration\n SYNC_QUOTAS = \"sync_quotas_1\",\n}\n\nexport interface MigrationDefinition {\n type: MigrationType\n name: MigrationName\n}\n", "import { Table } from \"../documents\"\n\nexport const PASSWORD_REPLACEMENT = \"--secret-value--\"\n\nexport enum Operation {\n CREATE = \"CREATE\",\n READ = \"READ\",\n UPDATE = \"UPDATE\",\n DELETE = \"DELETE\",\n BULK_CREATE = \"BULK_CREATE\",\n CREATE_TABLE = \"CREATE_TABLE\",\n UPDATE_TABLE = \"UPDATE_TABLE\",\n DELETE_TABLE = \"DELETE_TABLE\",\n}\n\nexport enum SortDirection {\n ASCENDING = \"ASCENDING\",\n DESCENDING = \"DESCENDING\",\n}\n\nexport enum QueryType {\n SQL = \"sql\",\n JSON = \"json\",\n FIELDS = \"fields\",\n}\n\nexport enum DatasourceFieldType {\n STRING = \"string\",\n CODE = \"code\",\n LONGFORM = \"longForm\",\n BOOLEAN = \"boolean\",\n NUMBER = \"number\",\n PASSWORD = \"password\",\n LIST = \"list\",\n OBJECT = \"object\",\n JSON = \"json\",\n FILE = \"file\",\n FIELD_GROUP = \"fieldGroup\",\n}\n\nexport enum SourceName {\n POSTGRES = \"POSTGRES\",\n DYNAMODB = \"DYNAMODB\",\n MONGODB = \"MONGODB\",\n ELASTICSEARCH = \"ELASTICSEARCH\",\n COUCHDB = \"COUCHDB\",\n SQL_SERVER = \"SQL_SERVER\",\n S3 = \"S3\",\n AIRTABLE = \"AIRTABLE\",\n MYSQL = \"MYSQL\",\n ARANGODB = \"ARANGODB\",\n REST = \"REST\",\n ORACLE = \"ORACLE\",\n GOOGLE_SHEETS = \"GOOGLE_SHEETS\",\n FIRESTORE = \"FIRESTORE\",\n REDIS = \"REDIS\",\n SNOWFLAKE = \"SNOWFLAKE\",\n}\n\nexport enum IncludeRelationship {\n INCLUDE = 1,\n EXCLUDE = 0,\n}\n\nexport enum FilterType {\n STRING = \"string\",\n FUZZY = \"fuzzy\",\n RANGE = \"range\",\n EQUAL = \"equal\",\n NOT_EQUAL = \"notEqual\",\n EMPTY = \"empty\",\n NOT_EMPTY = \"notEmpty\",\n ONE_OF = \"oneOf\",\n}\n\nexport enum DatasourceFeature {\n CONNECTION_CHECKING = \"connection\",\n FETCH_TABLE_NAMES = \"fetch_table_names\",\n}\n\nexport interface StepDefinition {\n key: string\n template: string\n}\n\nexport interface QueryDefinition {\n type: QueryType\n displayName?: string\n readable?: boolean\n customisable?: boolean\n fields?: object\n urlDisplay?: boolean\n steps?: Array<StepDefinition>\n}\n\nexport interface ExtraQueryConfig {\n [key: string]: {\n displayName: string\n type: string\n required: boolean\n data?: object\n }\n}\n\nexport interface DatasourceConfig {\n [key: string]: {\n type: string\n display?: string\n required?: boolean\n default?: any\n deprecated?: boolean\n }\n}\n\nexport interface Integration {\n docs: string\n plus?: boolean\n auth?: { type: string }\n features?: Partial<Record<DatasourceFeature, boolean>>\n relationships?: boolean\n description: string\n friendlyName: string\n type?: string\n iconUrl?: string\n datasource: DatasourceConfig\n query: {\n [key: string]: QueryDefinition\n }\n extra?: ExtraQueryConfig\n}\n\nexport type ConnectionInfo = {\n connected: boolean\n error?: string\n}\n\nexport interface IntegrationBase {\n create?(query: any): Promise<any[] | any>\n read?(query: any): Promise<any[] | any>\n update?(query: any): Promise<any[] | any>\n delete?(query: any): Promise<any[] | any>\n testConnection?(): Promise<ConnectionInfo>\n}\n\nexport interface DatasourcePlus extends IntegrationBase {\n tables: Record<string, Table>\n schemaErrors: Record<string, string>\n\n // if the datasource supports the use of bindings directly (to protect against SQL injection)\n // this returns the format of the identifier\n getBindingIdentifier(): string\n getStringConcat(parts: string[]): string\n buildSchema(datasourceId: string, entities: Record<string, Table>): any\n getTableNames(): Promise<string[]>\n}\n", "import { Operation, SortDirection } from \"./datasources\"\nimport { Row, Table } from \"../documents\"\nimport { SortType } from \"../api\"\n\nexport interface SearchFilters {\n allOr?: boolean\n string?: {\n [key: string]: string\n }\n fuzzy?: {\n [key: string]: string\n }\n range?: {\n [key: string]: {\n high: number | string\n low: number | string\n }\n }\n equal?: {\n [key: string]: any\n }\n notEqual?: {\n [key: string]: any\n }\n empty?: {\n [key: string]: any\n }\n notEmpty?: {\n [key: string]: any\n }\n oneOf?: {\n [key: string]: any[]\n }\n contains?: {\n [key: string]: any[]\n }\n notContains?: {\n [key: string]: any[]\n }\n containsAny?: {\n [key: string]: any[]\n }\n}\n\nexport interface SortJson {\n [key: string]: {\n direction: SortDirection\n type?: SortType\n }\n}\n\nexport interface PaginationJson {\n limit: number\n page?: string | number\n}\n\nexport interface RenameColumn {\n old: string\n updated: string\n}\n\nexport interface RelationshipsJson {\n through?: string\n from?: string\n to?: string\n fromPrimary?: string\n toPrimary?: string\n tableName: string\n column: string\n}\n\nexport interface QueryJson {\n endpoint: {\n datasourceId: string\n entityId: string\n operation: Operation\n schema?: string\n }\n resource?: {\n fields: string[]\n }\n filters?: SearchFilters\n sort?: SortJson\n paginate?: PaginationJson\n body?: Row | Row[]\n table?: Table\n meta?: {\n table?: Table\n tables?: Record<string, Table>\n renamed?: RenameColumn\n }\n extra?: {\n idFilter?: SearchFilters\n }\n relationships?: RelationshipsJson[]\n}\n\nexport interface SqlQuery {\n sql: string\n bindings?: string[]\n}\n", "import { Context, Request } from \"koa\"\nimport { User, Role, UserRoles, Account } from \"../documents\"\nimport { FeatureFlag, License } from \"../sdk\"\nimport { Files } from \"formidable\"\n\nexport interface ContextUser extends Omit<User, \"roles\"> {\n globalId?: string\n license?: License\n userId?: string\n roleId?: string | null\n role?: Role\n roles?: UserRoles\n csrfToken?: string\n featureFlags?: FeatureFlag[]\n accountPortalAccess?: boolean\n account?: Account\n}\n\n/**\n * Add support for koa-body in context.\n */\nexport interface BBRequest<RequestBody> extends Request {\n body: RequestBody\n files?: Files\n}\n\n/**\n * Basic context with no user.\n */\nexport interface Ctx<RequestBody = any, ResponseBody = any> extends Context {\n request: BBRequest<RequestBody>\n body: ResponseBody\n}\n\n/**\n * Authenticated context.\n */\nexport interface UserCtx<RequestBody = any, ResponseBody = any>\n extends Ctx<RequestBody, ResponseBody> {\n user: ContextUser\n}\n\n/**\n * @deprecated: Use UserCtx / Ctx appropriately\n * Authenticated context.\n */\nexport interface BBContext extends Ctx {\n user?: ContextUser\n}\n", "import { BBContext } from \"./koa\"\nimport { Hosting } from \"./hosting\"\n\nexport interface AuthToken {\n userId: string\n tenantId: string\n sessionId: string\n}\n\nexport interface CreateSession {\n sessionId: string\n tenantId: string\n csrfToken?: string\n hosting?: Hosting\n}\n\nexport interface Session extends CreateSession {\n userId: string\n lastAccessedAt: string\n createdAt: string\n // make optional attributes required\n csrfToken: string\n}\n\nexport interface SessionKey {\n key: string\n}\n\nexport interface ScannedSession {\n value: Session\n}\n\nexport interface PlatformLogoutOpts {\n ctx: BBContext\n userId: string\n keepActiveSession?: boolean\n}\n", "import Redlock from \"redlock\"\n\nexport enum LockType {\n /**\n * If this lock is already held the attempted operation will not be performed.\n * No retries will take place and no error will be thrown.\n */\n TRY_ONCE = \"try_once\",\n DEFAULT = \"default\",\n DELAY_500 = \"delay_500\",\n CUSTOM = \"custom\",\n}\n\nexport enum LockName {\n MIGRATIONS = \"migrations\",\n TRIGGER_QUOTA = \"trigger_quota\",\n SYNC_ACCOUNT_LICENSE = \"sync_account_license\",\n UPDATE_TENANTS_DOC = \"update_tenants_doc\",\n PERSIST_WRITETHROUGH = \"persist_writethrough\",\n QUOTA_USAGE_EVENT = \"quota_usage_event\",\n}\n\nexport interface LockOptions {\n /**\n * The lock type determines which client to use\n */\n type: LockType\n /**\n * The custom options to use when creating the redlock instance\n * type must be set to custom for the options to be applied\n */\n customOptions?: Redlock.Options\n /**\n * The name for the lock\n */\n name: LockName\n /**\n * The ttl to auto-expire the lock if not unlocked manually\n */\n ttl: number\n /**\n * The individual resource to lock. This is useful for locking around very specific identifiers, e.g. a document that is prone to conflicts\n */\n resource?: string\n /**\n * This is a system-wide lock - don't use tenancy in lock key\n */\n systemLock?: boolean\n}\n", "import Nano from \"@budibase/nano\"\nimport { AllDocsResponse, AnyDocument, Document } from \"../\"\nimport { Writable } from \"stream\"\nimport PouchDB from \"pouchdb\"\n\nexport enum SearchIndex {\n ROWS = \"rows\",\n AUDIT = \"audit\",\n USER = \"user\",\n}\n\nexport type PouchOptions = {\n inMemory?: boolean\n replication?: boolean\n onDisk?: boolean\n find?: boolean\n}\n\nexport enum SortOption {\n ASCENDING = \"asc\",\n DESCENDING = \"desc\",\n}\n\nexport type CouchFindOptions = {\n selector: PouchDB.Find.Selector\n fields?: string[]\n sort?: {\n [key: string]: SortOption\n }[]\n limit?: number\n skip?: number\n bookmark?: string\n}\n\nexport type DatabaseOpts = {\n skip_setup?: boolean\n}\n\nexport type DatabasePutOpts = {\n force?: boolean\n}\n\nexport type DatabaseCreateIndexOpts = {\n index: {\n fields: string[]\n name?: string | undefined\n ddoc?: string | undefined\n type?: string | undefined\n }\n}\n\nexport type DatabaseDeleteIndexOpts = {\n name: string\n ddoc: string\n type?: string | undefined\n}\n\nexport type DatabaseQueryOpts = {\n include_docs?: boolean\n startkey?: string\n endkey?: string\n limit?: number\n skip?: number\n descending?: boolean\n key?: string\n keys?: string[]\n group?: boolean\n startkey_docid?: string\n}\n\nexport const isDocument = (doc: any): doc is Document => {\n return typeof doc === \"object\" && doc._id && doc._rev\n}\n\nexport interface DatabaseDumpOpts {\n filter?: (doc: AnyDocument) => boolean\n batch_size?: number\n batch_limit?: number\n style?: \"main_only\" | \"all_docs\"\n timeout?: number\n doc_ids?: string[]\n query_params?: any\n view?: string\n selector?: any\n}\n\nexport interface Database {\n name: string\n\n exists(): Promise<boolean>\n checkSetup(): Promise<Nano.DocumentScope<any>>\n get<T>(id?: string): Promise<T | any>\n remove(\n id: string | Document,\n rev?: string\n ): Promise<Nano.DocumentDestroyResponse>\n put(\n document: AnyDocument,\n opts?: DatabasePutOpts\n ): Promise<Nano.DocumentInsertResponse>\n bulkDocs(documents: AnyDocument[]): Promise<Nano.DocumentBulkResponse[]>\n allDocs<T>(params: DatabaseQueryOpts): Promise<AllDocsResponse<T>>\n query<T>(\n viewName: string,\n params: DatabaseQueryOpts\n ): Promise<AllDocsResponse<T>>\n destroy(): Promise<Nano.OkResponse | void>\n compact(): Promise<Nano.OkResponse | void>\n // these are all PouchDB related functions that are rarely used - in future\n // should be replaced by better typed/non-pouch implemented methods\n dump(stream: Writable, opts?: DatabaseDumpOpts): Promise<any>\n load(...args: any[]): Promise<any>\n createIndex(...args: any[]): Promise<any>\n deleteIndex(...args: any[]): Promise<any>\n getIndexes(...args: any[]): Promise<any>\n}\n", "export interface EndpointMatcher {\n /**\n * The HTTP Path. e.g. /api/things/:thingId\n */\n route: string\n /**\n * The HTTP Verb. e.g. GET, POST, etc.\n * ALL is also accepted to cover all verbs.\n */\n method: string\n /**\n * The route must match exactly - not just begins with\n */\n strict?: boolean\n}\n\nexport interface RegexMatcher {\n regex: RegExp\n method: string\n strict: boolean\n route: string\n}\n", "export interface GetTenantIdOptions {\n allowNoTenant?: boolean\n excludeStrategies?: TenantResolutionStrategy[]\n includeStrategies?: TenantResolutionStrategy[]\n}\n\nexport enum TenantResolutionStrategy {\n USER = \"user\",\n HEADER = \"header\",\n QUERY = \"query\",\n SUBDOMAIN = \"subdomain\",\n PATH = \"path\",\n}\n", "export * from \"./matchers\"\nexport * from \"./tenancy\"\n", "export enum FeatureFlag {\n LICENSING = \"LICENSING\",\n}\n\nexport interface TenantFeatureFlags {\n [key: string]: FeatureFlag[]\n}\n", "export enum AppEnvironment {\n PRODUCTION = \"production\",\n DEVELOPMENT = \"development\",\n}\n", "import { Event, HostInfo } from \"./events\"\nimport { AuditLogDoc } from \"../documents\"\n\nexport type AuditWriteOpts = {\n appId?: string\n timestamp?: string | number\n userId?: string\n hostInfo?: HostInfo\n}\n\nexport type AuditLogFn = (\n event: Event,\n metadata: any,\n opts: AuditWriteOpts\n) => Promise<AuditLogDoc | undefined>\n\nexport type AuditLogQueueEvent = {\n event: Event\n properties: any\n opts: AuditWriteOpts\n tenantId: string\n}\n", "import {\n OAuth2,\n SSOProfileJson,\n SSOProviderType,\n SSOUser,\n User,\n} from \"../documents\"\nimport { SaveUserOpts } from \"./user\"\n\nexport interface JwtClaims {\n preferred_username?: string\n email?: string\n}\n\nexport interface SSOAuthDetails {\n oauth2: OAuth2\n provider: string\n providerType: SSOProviderType\n userId: string\n email?: string\n profile?: SSOProfile\n}\n\nexport interface SSOProfile {\n id: string\n name?: {\n givenName?: string\n familyName?: string\n }\n _json: SSOProfileJson\n provider?: string\n}\n\nexport type SaveSSOUserFunction = (\n user: SSOUser,\n opts: SaveUserOpts\n) => Promise<User>\n", "export interface SaveUserOpts {\n hashPassword?: boolean\n requirePassword?: boolean\n currentUserId?: string\n}\n", "import { Event } from \"../events\"\n\nexport enum CommandWord {\n BACKUPS = \"backups\",\n HOSTING = \"hosting\",\n ANALYTICS = \"analytics\",\n HELP = \"help\",\n PLUGIN = \"plugins\",\n}\n\nexport enum InitType {\n QUICK = \"quick\",\n DIGITAL_OCEAN = \"do\",\n}\n\nexport const AnalyticsEvent = {\n OptOut: \"analytics:opt:out\",\n OptIn: \"analytics:opt:in\",\n SelfHostInit: \"hosting:init\",\n PluginInit: Event.PLUGIN_INIT,\n}\n", "export * from \"./constants\"\n", "export * from \"./automations\"\nexport * from \"./hosting\"\nexport * from \"./context\"\nexport * from \"./events\"\nexport * from \"./licensing\"\nexport * from \"./migrations\"\nexport * from \"./datasources\"\nexport * from \"./search\"\nexport * from \"./koa\"\nexport * from \"./auth\"\nexport * from \"./locks\"\nexport * from \"./db\"\nexport * from \"./middleware\"\nexport * from \"./featureFlag\"\nexport * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\nexport * from \"./sso\"\nexport * from \"./user\"\nexport * from \"./cli\"\n", "import { Feature, Hosting, License, PlanType, Quotas } from \"../../sdk\"\nimport { DeepPartial } from \"../../shared\"\nimport { QuotaUsage } from \"../global\"\n\nexport interface CreateAccount {\n email: string\n tenantId: string\n hosting: Hosting\n authType: AuthType\n // optional fields - for sso based sign ups\n registrationStep?: string\n // profile\n tenantName?: string\n name?: string\n size?: string\n profession?: string\n}\n\nexport interface CreatePassswordAccount extends CreateAccount {\n password: string\n}\n\nexport const isCreatePasswordAccount = (\n account: CreateAccount\n): account is CreatePassswordAccount => account.authType === AuthType.PASSWORD\n\nexport interface LicenseOverrides {\n features?: Feature[]\n quotas?: DeepPartial<Quotas>\n}\n\nexport interface Account extends CreateAccount {\n // generated\n accountId: string\n createdAt: number\n // registration\n verified: boolean\n verificationSent: boolean\n // licensing\n tier: string // deprecated\n planType?: PlanType\n /** @deprecated */\n planTier?: number\n license?: License\n installId?: string\n installTenantId?: string\n installVersion?: string\n stripeCustomerId?: string\n licenseKey?: string\n licenseKeyActivatedAt?: number\n licenseRequestedAt?: number\n licenseOverrides?: LicenseOverrides\n quotaUsage?: QuotaUsage\n}\n\nexport interface PasswordAccount extends Account {\n password: string\n}\n\nexport const isPasswordAccount = (\n account: Account\n): account is PasswordAccount =>\n account.authType === AuthType.PASSWORD && account.hosting === Hosting.SELF\n\nexport interface CloudAccount extends Account {\n password?: string\n budibaseUserId: string\n}\n\nexport const isCloudAccount = (account: Account): account is CloudAccount =>\n account.hosting === Hosting.CLOUD\n\nexport const isSelfHostAccount = (account: Account) =>\n account.hosting === Hosting.SELF\n\nexport const isSSOAccount = (account: Account): account is SSOAccount =>\n account.authType === AuthType.SSO\n\nexport enum AccountSSOProviderType {\n GOOGLE = \"google\",\n MICROSOFT = \"microsoft\",\n}\n\nexport enum AccountSSOProvider {\n GOOGLE = \"google\",\n MICROSOFT = \"microsoft\",\n}\n\nexport interface AccountSSO {\n provider: AccountSSOProvider\n providerType: AccountSSOProviderType\n oauth2?: OAuthTokens\n pictureUrl?: string\n thirdPartyProfile: any // TODO: define what the google profile looks like\n}\n\nexport type SSOAccount = (Account | CloudAccount) & AccountSSO\n\nexport enum AuthType {\n SSO = \"sso\",\n PASSWORD = \"password\",\n}\n\nexport interface OAuthTokens {\n accessToken: string\n refreshToken: string\n}\n", "export interface CreateAccountUserActivity {\n accountId: string\n userId: string\n timestamp: number\n}\n\nexport interface AccountUserActivity extends CreateAccountUserActivity {\n PK: string\n SK: string\n}\n", "export * from \"./account\"\nexport * from \"./user\"\n", "import { User, Document } from \"../\"\n\nexport type AppMetadataErrors = { [key: string]: string[] }\n\nexport interface App extends Document {\n appId: string\n type: string\n version: string\n componentLibraries: string[]\n name: string\n url: string | undefined\n template: string | undefined\n instance: AppInstance\n tenantId: string\n status: string\n theme?: string\n customTheme?: AppCustomTheme\n revertableVersion?: string\n lockedBy?: User\n navigation?: AppNavigation\n automationErrors?: AppMetadataErrors\n icon?: AppIcon\n}\n\nexport interface AppInstance {\n _id: string\n}\n\nexport interface AppNavigation {\n navigation: string\n title: string\n navWidth: string\n sticky?: boolean\n hideLogo?: boolean\n logoUrl?: string\n hideTitle?: boolean\n navBackground?: string\n navTextColor?: string\n links?: AppNavigationLink[]\n}\n\nexport interface AppNavigationLink {\n text: string\n url: string\n id?: string\n roleId?: string\n}\n\nexport interface AppCustomTheme {\n buttonBorderRadius?: string\n primaryColor?: string\n primaryColorHover?: string\n\n // Used to exist before new design UI\n navTextColor?: string\n navBackground?: string\n}\n\nexport interface AppIcon {\n name: string\n color: string\n}\n", "import { Document } from \"../document\"\nimport { EventEmitter } from \"events\"\n\nexport enum AutomationIOType {\n OBJECT = \"object\",\n STRING = \"string\",\n BOOLEAN = \"boolean\",\n NUMBER = \"number\",\n ARRAY = \"array\",\n JSON = \"json\",\n}\n\nexport enum AutomationCustomIOType {\n TABLE = \"table\",\n ROW = \"row\",\n ROWS = \"rows\",\n WIDE = \"wide\",\n QUERY = \"query\",\n QUERY_PARAMS = \"queryParams\",\n QUERY_LIMIT = \"queryLimit\",\n LOOP_OPTION = \"loopOption\",\n ITEM = \"item\",\n CODE = \"code\",\n FILTERS = \"filters\",\n COLUMN = \"column\",\n TRIGGER_SCHEMA = \"triggerSchema\",\n CRON = \"cron\",\n WEBHOOK_URL = \"webhookUrl\",\n}\n\nexport enum AutomationTriggerStepId {\n ROW_SAVED = \"ROW_SAVED\",\n ROW_UPDATED = \"ROW_UPDATED\",\n ROW_DELETED = \"ROW_DELETED\",\n WEBHOOK = \"WEBHOOK\",\n APP = \"APP\",\n CRON = \"CRON\",\n}\n\nexport enum AutomationStepType {\n LOGIC = \"LOGIC\",\n ACTION = \"ACTION\",\n TRIGGER = \"TRIGGER\",\n}\n\nexport enum AutomationActionStepId {\n SEND_EMAIL_SMTP = \"SEND_EMAIL_SMTP\",\n CREATE_ROW = \"CREATE_ROW\",\n UPDATE_ROW = \"UPDATE_ROW\",\n DELETE_ROW = \"DELETE_ROW\",\n EXECUTE_BASH = \"EXECUTE_BASH\",\n OUTGOING_WEBHOOK = \"OUTGOING_WEBHOOK\",\n EXECUTE_SCRIPT = \"EXECUTE_SCRIPT\",\n EXECUTE_QUERY = \"EXECUTE_QUERY\",\n SERVER_LOG = \"SERVER_LOG\",\n DELAY = \"DELAY\",\n FILTER = \"FILTER\",\n QUERY_ROWS = \"QUERY_ROWS\",\n LOOP = \"LOOP\",\n OPENAI = \"OPENAI\",\n // these used to be lowercase step IDs, maintain for backwards compat\n discord = \"discord\",\n slack = \"slack\",\n zapier = \"zapier\",\n integromat = \"integromat\",\n}\n\nexport const AutomationStepIdArray = [\n ...Object.values(AutomationActionStepId),\n ...Object.values(AutomationTriggerStepId),\n]\n\nexport interface Automation extends Document {\n definition: {\n steps: AutomationStep[]\n trigger: AutomationTrigger\n }\n screenId?: string\n uiTree?: any\n appId: string\n live?: boolean\n name: string\n internal?: boolean\n type?: string\n}\n\ninterface BaseIOStructure {\n type?: AutomationIOType\n customType?: AutomationCustomIOType\n title?: string\n description?: string\n enum?: string[]\n pretty?: string[]\n properties?: {\n [key: string]: BaseIOStructure\n }\n required?: string[]\n}\n\ninterface InputOutputBlock {\n properties: {\n [key: string]: BaseIOStructure\n }\n required?: string[]\n}\n\nexport interface AutomationStepSchema {\n name: string\n stepTitle?: string\n tagline: string\n icon: string\n description: string\n type: AutomationStepType\n internal?: boolean\n deprecated?: boolean\n stepId: AutomationTriggerStepId | AutomationActionStepId\n blockToLoop?: string\n inputs: {\n [key: string]: any\n }\n schema: {\n inputs: InputOutputBlock\n outputs: InputOutputBlock\n }\n custom?: boolean\n}\n\nexport interface AutomationStep extends AutomationStepSchema {\n id: string\n}\n\nexport interface AutomationTriggerSchema extends AutomationStepSchema {\n event?: string\n cronJobId?: string\n}\n\nexport interface AutomationTrigger extends AutomationTriggerSchema {\n id: string\n}\n\nexport enum AutomationStatus {\n SUCCESS = \"success\",\n ERROR = \"error\",\n STOPPED = \"stopped\",\n STOPPED_ERROR = \"stopped_error\",\n NO_ITERATIONS = \"no_iterations\",\n}\n\nexport interface AutomationResults {\n automationId?: string\n status?: AutomationStatus\n trigger?: any\n steps: {\n stepId: AutomationTriggerStepId | AutomationActionStepId\n inputs: {\n [key: string]: any\n }\n outputs: {\n [key: string]: any\n }\n }[]\n}\n\nexport interface AutomationLog extends AutomationResults, Document {\n automationName: string\n _rev?: string\n}\n\nexport interface AutomationLogPage {\n data: AutomationLog[]\n hasNextPage: boolean\n nextPage?: string\n}\n\nexport type AutomationStepInput = {\n inputs: Record<string, any>\n context: Record<string, any>\n emitter: EventEmitter\n appId: string\n apiKey?: string\n}\n\nexport interface AutomationMetadata extends Document {\n errorCount?: number\n automationChainCount?: number\n}\n", "import { Document } from \"../document\"\nimport { SourceName } from \"../../sdk\"\nimport { Table } from \"./table\"\n\nexport interface Datasource extends Document {\n type: string\n name?: string\n source: SourceName\n // the config is defined by the schema\n config?: {\n [key: string]: string | number | boolean | any[]\n }\n plus?: boolean\n entities?: {\n [key: string]: Table\n }\n}\n\nexport enum RestAuthType {\n BASIC = \"basic\",\n BEARER = \"bearer\",\n}\n\nexport interface RestBasicAuthConfig {\n username: string\n password: string\n}\n\nexport interface RestBearerAuthConfig {\n token: string\n}\n\nexport interface RestAuthConfig {\n _id: string\n name: string\n type: RestAuthType\n config: RestBasicAuthConfig | RestBearerAuthConfig\n}\n\nexport interface RestConfig {\n url: string\n rejectUnauthorized: boolean\n defaultHeaders: {\n [key: string]: any\n }\n legacyHttpParser: boolean\n authConfigs: RestAuthConfig[]\n staticVariables: {\n [key: string]: string\n }\n dynamicVariables: [\n {\n name: string\n queryId: string\n value: string\n }\n ]\n}\n", "import { Document } from \"../document\"\n\nexport interface Layout extends Document {\n props: any\n}\n", "import { Document } from \"../document\"\n\nexport interface Query extends Document {\n datasourceId: string\n name: string\n parameters: QueryParameter[]\n fields: RestQueryFields | any\n transformer: string | null\n schema: any\n readable: boolean\n queryVerb: string\n}\n\nexport interface QueryParameter {\n name: string\n default: string\n}\n\nexport interface RestQueryFields {\n path: string\n queryString?: string\n headers: { [key: string]: any }\n disabledHeaders: { [key: string]: any }\n requestBody: any\n bodyType: string\n json: object\n method: string\n authConfigId: string\n pagination: PaginationConfig | null\n paginationValues: PaginationValues | null\n}\n\nexport interface PaginationConfig {\n type: string\n location: string\n pageParam: string\n sizeParam: string | null\n responseParam: string | null\n}\n\nexport interface PaginationValues {\n page: string | number | null\n limit: number | null\n}\n\nexport interface PreviewQueryRequest extends Omit<Query, \"parameters\"> {\n parameters: {}\n flags?: {\n urlName?: boolean\n }\n}\n", "import { Document } from \"../document\"\n\nexport interface Role extends Document {\n permissionId: string\n inherits?: string\n permissions: { [key: string]: string[] }\n}\n", "import { Document } from \"../document\"\nimport { View } from \"./view\"\nimport { RenameColumn } from \"../../sdk\"\nimport { FieldType } from \"./row\"\n\nexport enum RelationshipTypes {\n ONE_TO_MANY = \"one-to-many\",\n MANY_TO_ONE = \"many-to-one\",\n MANY_TO_MANY = \"many-to-many\",\n}\n\nexport interface FieldSchema {\n type: FieldType\n externalType?: string\n fieldName?: string\n name: string\n sortable?: boolean\n tableId?: string\n relationshipType?: RelationshipTypes\n through?: string\n foreignKey?: string\n icon?: string\n autocolumn?: boolean\n subtype?: string\n throughFrom?: string\n throughTo?: string\n formula?: string\n formulaType?: string\n main?: boolean\n ignoreTimezones?: boolean\n timeOnly?: boolean\n lastID?: number\n useRichText?: boolean | null\n order?: number\n width?: number\n meta?: {\n toTable: string\n toKey: string\n }\n constraints?: {\n type?: string\n email?: boolean\n inclusion?: string[]\n length?: {\n minimum?: string | number | null\n maximum?: string | number | null\n }\n numericality?: {\n greaterThanOrEqualTo: string | null\n lessThanOrEqualTo: string | null\n }\n presence?:\n | boolean\n | {\n allowEmpty?: boolean\n }\n datetime?: {\n latest: string\n earliest: string\n }\n }\n}\n\nexport interface TableSchema {\n [key: string]: FieldSchema\n}\n\nexport interface Table extends Document {\n type?: string\n views?: { [key: string]: View }\n name: string\n primary?: string[]\n schema: TableSchema\n primaryDisplay?: string\n sourceId?: string\n relatedFormula?: string[]\n constrained?: string[]\n sql?: boolean\n indexes?: { [key: string]: any }\n rows?: { [key: string]: any }\n created?: boolean\n rowHeight?: number\n}\n\nexport interface TableRequest extends Table {\n _rename?: RenameColumn\n created?: boolean\n}\n", "import { Document } from \"../document\"\nimport { Component } from \"./component\"\n\nexport interface ScreenProps extends Component {\n size?: string\n gap?: string\n direction?: string\n vAlign?: string\n hAlign?: string\n}\n\nexport interface ScreenRouting {\n route: string\n roleId: string\n homeScreen?: boolean\n}\n\nexport interface Screen extends Document {\n layoutId?: string\n showNavigation?: boolean\n width?: string\n routing: ScreenRouting\n props: ScreenProps\n name?: string\n}\n", "export interface View {\n name: string\n tableId: string\n field?: string\n filters: ViewFilter[]\n schema: ViewSchema\n calculation?: ViewCalculation\n map?: string\n reduce?: any\n meta?: Record<string, any>\n}\n\nexport type ViewSchema = ViewCountOrSumSchema | ViewStatisticsSchema\n\nexport interface ViewCountOrSumSchema {\n field: string\n value: string\n}\n\n/**\n e.g:\n \"min\": {\n \"type\": \"number\"\n },\n \"max\": {\n \"type\": \"number\"\n }\n */\nexport interface ViewStatisticsSchema {\n [key: string]: {\n type: string\n }\n}\n\nexport interface ViewFilter {\n value?: any\n condition: string\n key: string\n conjunction?: string\n}\n\nexport enum ViewCalculation {\n SUM = \"sum\",\n COUNT = \"count\",\n STATISTICS = \"stats\",\n}\n", "export interface Document {\n _id?: string\n _rev?: string\n createdAt?: string | number\n updatedAt?: string\n}\n\nexport interface AnyDocument extends Document {\n [key: string]: any\n}\n", "import { Document } from \"../document\"\n\nexport enum FieldType {\n STRING = \"string\",\n LONGFORM = \"longform\",\n OPTIONS = \"options\",\n NUMBER = \"number\",\n BOOLEAN = \"boolean\",\n ARRAY = \"array\",\n DATETIME = \"datetime\",\n ATTACHMENT = \"attachment\",\n LINK = \"link\",\n FORMULA = \"formula\",\n AUTO = \"auto\",\n JSON = \"json\",\n INTERNAL = \"internal\",\n BARCODEQR = \"barcodeqr\",\n}\n\nexport interface RowAttachment {\n size: number\n name: string\n extension: string\n key: string\n // Populated on read\n url?: string\n}\n\nexport interface Row extends Document {\n type?: string\n tableId?: string\n [key: string]: any\n}\n", "import { Document } from \"../document\"\n\nexport interface UserMetadata extends Document {\n roleId: string\n email?: string\n}\n", "import { Document } from \"../document\"\nimport { User } from \"../../\"\n\nexport enum AppBackupType {\n BACKUP = \"backup\",\n RESTORE = \"restore\",\n}\n\nexport enum AppBackupStatus {\n STARTED = \"started\",\n PENDING = \"pending\",\n COMPLETE = \"complete\",\n FAILED = \"failed\",\n}\n\nexport enum AppBackupTrigger {\n PUBLISH = \"publish\",\n MANUAL = \"manual\",\n SCHEDULED = \"scheduled\",\n RESTORING = \"restoring\",\n}\n\nexport interface AppBackupContents {\n datasources: string[]\n screens: string[]\n automations: string[]\n}\n\nexport interface AppBackupMetadata {\n appId: string\n trigger?: AppBackupTrigger\n type: AppBackupType\n status: AppBackupStatus\n name?: string\n createdBy?: string | User\n timestamp: string\n finishedAt?: string\n startedAt?: string\n contents?: AppBackupContents\n}\n\nexport interface AppBackup extends Document, AppBackupMetadata {\n _id: string\n filename?: string\n}\n\nexport type AppBackupFetchOpts = {\n trigger?: AppBackupTrigger\n type?: AppBackupType\n limit?: number\n page?: string\n paginate?: boolean\n startDate?: string\n endDate?: string\n}\n\nexport interface AppBackupQueueData {\n appId: string\n docId: string\n docRev: string\n export?: {\n trigger: AppBackupTrigger\n name?: string\n createdBy?: string\n }\n import?: {\n backupId: string\n nameForBackup: string\n createdBy?: string\n }\n}\n", "import { Document } from \"../document\"\n\nexport enum WebhookActionType {\n AUTOMATION = \"automation\",\n}\n\nexport interface Webhook extends Document {\n live: boolean\n name: string\n action: {\n type: WebhookActionType\n target: string\n }\n bodySchema?: any\n}\n", "import { Document } from \"../document\"\n\nexport interface LinkDocument extends Document {\n type: string\n doc1: {\n rowId: string\n fieldName: string\n tableId: string\n }\n doc2: {\n rowId: string\n fieldName: string\n tableId: string\n }\n}\n\nexport interface LinkDocumentValue {\n id: string\n thisId: string\n fieldName: string\n}\n", "import { Document } from \"../document\"\n\nexport interface Component extends Document {\n _instanceName: string\n _styles: { [key: string]: any }\n _component: string\n _children?: Component[]\n [key: string]: any\n}\n", "export * from \"./app\"\nexport * from \"./automation\"\nexport * from \"./datasource\"\nexport * from \"./layout\"\nexport * from \"./query\"\nexport * from \"./role\"\nexport * from \"./table\"\nexport * from \"./screen\"\nexport * from \"./view\"\nexport * from \"../document\"\nexport * from \"./row\"\nexport * from \"./user\"\nexport * from \"./backup\"\nexport * from \"./webhook\"\nexport * from \"./links\"\nexport * from \"./component\"\n", "import { Document } from \"../document\"\n\nexport interface Config<T = any> extends Document {\n type: ConfigType\n config: T\n}\n\nexport interface SMTPInnerConfig {\n port: number\n host: string\n from: string\n subject?: string\n secure: boolean\n auth?: {\n user: string\n pass: string\n }\n connectionTimeout?: any\n}\n\nexport interface SMTPConfig extends Config<SMTPInnerConfig> {}\n\n/**\n * Accessible only via pro.\n */\nexport interface SettingsBrandingConfig {\n faviconUrl?: string\n faviconUrlEtag?: string\n\n emailBrandingEnabled?: boolean\n testimonialsEnabled?: boolean\n platformTitle?: string\n loginHeading?: string\n loginButton?: string\n\n metaDescription?: string\n metaImageUrl?: string\n metaTitle?: string\n}\n\nexport interface SettingsInnerConfig {\n platformUrl?: string\n company?: string\n logoUrl?: string // Populated on read\n logoUrlEtag?: string\n uniqueTenantId?: string\n analyticsEnabled?: boolean\n isSSOEnforced?: boolean\n}\n\nexport interface SettingsConfig extends Config<SettingsInnerConfig> {}\n\nexport type SSOConfigType = ConfigType.GOOGLE | ConfigType.OIDC\nexport type SSOConfig = GoogleInnerConfig | OIDCInnerConfig\n\nexport interface GoogleInnerConfig {\n clientID: string\n clientSecret: string\n activated: boolean\n /**\n * @deprecated read only\n */\n callbackURL?: string\n}\n\nexport interface GoogleConfig extends Config<GoogleInnerConfig> {}\n\nexport interface OIDCStrategyConfiguration {\n issuer: string\n authorizationURL: string\n tokenURL: string\n userInfoURL: string\n clientID: string\n clientSecret: string\n callbackURL: string\n}\n\nexport interface OIDCConfigs {\n configs: OIDCInnerConfig[]\n}\n\nexport interface OIDCInnerConfig {\n configUrl: string\n clientID: string\n clientSecret: string\n logo: string\n name: string\n uuid: string\n activated: boolean\n scopes: string[]\n}\n\nexport interface OIDCConfig extends Config<OIDCConfigs> {}\n\nexport interface OIDCWellKnownConfig {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint: string\n}\n\nexport interface SCIMInnerConfig {\n enabled: boolean\n}\n\nexport interface SCIMConfig extends Config<SCIMInnerConfig> {}\n\nexport const isSettingsConfig = (config: Config): config is SettingsConfig =>\n config.type === ConfigType.SETTINGS\n\nexport const isSMTPConfig = (config: Config): config is SMTPConfig =>\n config.type === ConfigType.SMTP\n\nexport const isGoogleConfig = (config: Config): config is GoogleConfig =>\n config.type === ConfigType.GOOGLE\n\nexport const isOIDCConfig = (config: Config): config is OIDCConfig =>\n config.type === ConfigType.OIDC\n\nexport const isSCIMConfig = (config: Config): config is SCIMConfig =>\n config.type === ConfigType.SCIM\n\nexport enum ConfigType {\n SETTINGS = \"settings\",\n ACCOUNT = \"account\",\n SMTP = \"smtp\",\n GOOGLE = \"google\",\n OIDC = \"oidc\",\n OIDC_LOGOS = \"logos_oidc\",\n SCIM = \"scim\",\n}\n", "import { Document } from \"../document\"\n\n// SSO\n\nexport interface SSOProfileJson {\n email?: string\n picture?: string\n}\n\nexport interface OAuth2 {\n accessToken: string\n refreshToken?: string\n}\n\nexport enum SSOProviderType {\n OIDC = \"oidc\",\n GOOGLE = \"google\",\n}\n\nexport interface UserSSO {\n provider: string // the individual provider e.g. Okta, Auth0, Google\n providerType: SSOProviderType\n oauth2?: OAuth2\n thirdPartyProfile?: SSOProfileJson\n}\n\nexport type SSOUser = User & UserSSO\n\nexport function isSSOUser(user: User): user is SSOUser {\n return !!(user as SSOUser).providerType\n}\n\n// USER\n\nexport interface User extends Document {\n tenantId: string\n email: string\n userId?: string\n firstName?: string\n lastName?: string\n pictureUrl?: string\n forceResetPassword?: boolean\n roles: UserRoles\n builder?: {\n global: boolean\n }\n admin?: {\n global: boolean\n }\n password?: string\n status?: UserStatus\n createdAt?: number // override the default createdAt behaviour - users sdk historically set this to Date.now()\n dayPassRecordedAt?: string\n userGroups?: string[]\n onboardedAt?: string\n scimInfo?: { isSync: true } & Record<string, any>\n}\n\nexport enum UserStatus {\n ACTIVE = \"active\",\n INACTIVE = \"inactive\",\n}\n\nexport interface UserRoles {\n [key: string]: string\n}\n\n// UTILITY TYPES\n\nexport interface BuilderUser extends User {\n builder: {\n global: boolean\n }\n}\n\nexport interface AdminUser extends User {\n admin: {\n global: boolean\n }\n builder: {\n global: boolean\n }\n}\n\nexport function isUser(user: object): user is User {\n return !!(user as User).roles\n}\n", "import { PaginationResponse } from \"../../api\"\nimport { Document } from \"../document\"\n\nexport interface UserGroup extends Document {\n name: string\n icon: string\n color: string\n users?: GroupUser[]\n roles?: UserGroupRoles\n createdAt?: number\n scimInfo?: {\n externalId: string\n isSync: boolean\n }\n}\n\nexport interface GroupUser {\n _id: string\n email: string\n}\n\nexport interface UserGroupRoles {\n [key: string]: string\n}\n\nexport interface SearchGroupRequest {}\nexport interface SearchGroupResponse {\n data: UserGroup[]\n}\n\nexport interface SearchUserGroupResponse extends PaginationResponse {\n users: {\n _id: any\n email: any\n }[]\n}\n", "import { Document } from \"../document\"\n\nexport enum PluginType {\n DATASOURCE = \"datasource\",\n COMPONENT = \"component\",\n AUTOMATION = \"automation\",\n}\n\nexport enum PluginSource {\n NPM = \"NPM\",\n GITHUB = \"Github\",\n URL = \"URL\",\n FILE = \"File Upload\",\n}\nexport interface FileType {\n path: string\n name: string\n}\n\nexport interface Plugin extends Document {\n description: string\n name: string\n version: string\n source: PluginSource\n package: { [key: string]: any }\n hash: string\n schema: {\n type: PluginType\n [key: string]: any\n }\n iconFileName?: string\n // Populated on read\n jsUrl?: string\n // Populated on read\n iconUrl?: string\n}\n\nexport const PLUGIN_TYPE_ARR = Object.values(PluginType)\n", "import { MonthlyQuotaName, StaticQuotaName } from \"../../sdk\"\n\nexport enum BreakdownQuotaName {\n ROW_QUERIES = \"rowQueries\",\n DATASOURCE_QUERIES = \"datasourceQueries\",\n AUTOMATIONS = \"automations\",\n}\n\nexport const APP_QUOTA_NAMES = [\n StaticQuotaName.ROWS,\n MonthlyQuotaName.QUERIES,\n MonthlyQuotaName.AUTOMATIONS,\n]\n\nexport const BREAKDOWN_QUOTA_NAMES = [\n MonthlyQuotaName.QUERIES,\n MonthlyQuotaName.AUTOMATIONS,\n]\n\nexport interface UsageBreakdown {\n parent: MonthlyQuotaName\n values: {\n [key: string]: number\n }\n}\n\nexport type QuotaTriggers = {\n [key: string]: string | undefined\n}\n\nexport interface StaticUsage {\n [StaticQuotaName.APPS]: number\n [StaticQuotaName.PLUGINS]: number\n [StaticQuotaName.USERS]: number\n [StaticQuotaName.USER_GROUPS]: number\n [StaticQuotaName.ROWS]: number\n triggers: {\n [key in StaticQuotaName]?: QuotaTriggers\n }\n}\n\nexport interface MonthlyUsage {\n [MonthlyQuotaName.QUERIES]: number\n [MonthlyQuotaName.AUTOMATIONS]: number\n [MonthlyQuotaName.DAY_PASSES]: number\n triggers: {\n [key in MonthlyQuotaName]?: QuotaTriggers\n }\n breakdown?: {\n [key in BreakdownQuotaName]?: UsageBreakdown\n }\n}\n\nexport interface BaseQuotaUsage {\n usageQuota: StaticUsage\n monthly: {\n [key: string]: MonthlyUsage\n }\n}\n\nexport interface QuotaUsage extends BaseQuotaUsage {\n _id: string\n _rev?: string\n quotaReset: string\n apps?: {\n [key: string]: BaseQuotaUsage\n }\n}\n\nexport type SetUsageValues = {\n total: number\n app?: number\n breakdown?: number\n triggers?: QuotaTriggers\n}\n\nexport type UsageValues = {\n total: number\n app?: number\n breakdown?: number\n}\n", "import { Document } from \"../document\"\n\nexport enum ScheduleType {\n APP_BACKUP = \"app_backup\",\n}\n\nexport enum ScheduleRepeatPeriod {\n DAILY = \"daily\",\n WEEKLY = \"weekly\",\n MONTHLY = \"monthly\",\n}\n\nexport interface Schedule extends Document {\n type: ScheduleType\n name: string\n startDate: string\n repeat: ScheduleRepeatPeriod\n metadata: ScheduleMetadata\n}\n\nexport type ScheduleMetadata = AppBackupScheduleMetadata\n\nexport const isAppBackupMetadata = (\n type: ScheduleType,\n metadata: ScheduleMetadata\n): metadata is AppBackupScheduleMetadata => {\n return type === ScheduleType.APP_BACKUP\n}\n\nexport interface AppBackupScheduleMetadata {\n apps: string[]\n}\n", "import { Document } from \"../document\"\n\nexport interface Template extends Document {\n ownerId?: string\n name?: string\n contents: string\n purpose: string\n type?: string\n}\n", "import { Document } from \"../document\"\n\nexport interface EnvironmentVariablesDoc extends Document {\n variables: string\n}\n\nexport type EnvironmentVariableValue = {\n production: string\n development: string\n}\n\n// what comes out of the \"variables\" when it is decrypted\nexport type EnvironmentVariablesDecrypted = Record<\n string,\n EnvironmentVariableValue\n>\n\nexport interface EnvironmentVariablesDocDecrypted extends Document {\n variables: EnvironmentVariablesDecrypted\n}\n", "import { Document } from \"../document\"\nimport { Event } from \"../../sdk\"\n\nexport const AuditLogSystemUser = \"SYSTEM\"\n\nexport type FallbackInfo = {\n appName?: string\n email?: string\n}\n\nexport interface AuditLogDoc extends Document {\n appId?: string\n event: Event\n userId: string\n timestamp: string\n metadata: any\n name: string\n fallback?: FallbackInfo\n}\n", "export * from \"./config\"\nexport * from \"./user\"\nexport * from \"./userGroup\"\nexport * from \"./plugin\"\nexport * from \"./quotas\"\nexport * from \"./schedule\"\nexport * from \"./templates\"\nexport * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\n", "import { Document } from \"../document\"\n\nexport interface GlobalInfo {}\n\nexport interface Installation extends Document {\n _id: string\n installId: string\n version: string\n}\n", "import { Document } from \"../document\"\n\n/**\n * doc id is user email\n */\nexport interface PlatformUserByEmail extends Document {\n tenantId: string\n userId: string\n}\n\n/**\n * doc id is userId\n */\nexport interface PlatformUserById extends Document {\n tenantId: string\n}\n\nexport type PlatformUser = PlatformUserByEmail | PlatformUserById\n", "import { Document } from \"../document\"\n\nexport interface AccountMetadata extends Document {\n email: string\n}\n", "import { Document } from \"../document\"\n\nexport interface Tenants extends Document {\n tenantIds: string[]\n}\n", "export * from \"./info\"\nexport * from \"./users\"\nexport * from \"./accounts\"\nexport * from \"./tenants\"\n", "export interface RowValue {\n rev: string\n deleted: boolean\n}\n\nexport interface RowResponse<T> {\n id: string\n key: string\n error: string\n value: T | RowValue\n doc?: T | any\n}\n\nexport interface AllDocsResponse<T> {\n offset: number\n total_rows: number\n rows: RowResponse<T>[]\n}\n\nexport type BulkDocsResponse = BulkDocResponse[]\n\ninterface BulkDocResponse {\n ok: boolean\n id: string\n rev: string\n}\n\nexport interface PutResponse {\n ok: boolean\n id: string\n rev: string\n}\n", "export * from \"./account\"\nexport * from \"./app\"\nexport * from \"./global\"\nexport * from \"./platform\"\nexport * from \"./document\"\nexport * from \"./pouch\"\n", "import { Hosting } from \"../../sdk\"\n\nexport interface CreateAccountRequest {\n email: string\n tenantId: string\n hosting: Hosting\n size: string\n profession: string\n // optional fields\n tenantName?: string\n name?: string\n password: string\n}\n", "export interface PostAccountUserActivity {\n timestamp: number\n}\n\nexport interface PostAccountUserActivityResponse {\n userId: string\n timestamp: number\n}\n", "import { LicenseOverrides, QuotaUsage } from \"../../documents\"\nimport { PlanType } from \"../../sdk\"\n\nexport interface GetLicenseRequest {\n // All fields should be optional to cater for\n // historical versions of budibase\n quotaUsage?: QuotaUsage\n install: {\n id: string\n tenantId: string\n version: string\n }\n}\n\nexport interface QuotaTriggeredRequest {\n percentage: number\n name: string\n resetDate?: string\n}\n\nexport interface LicenseActivateRequest {\n installVersion?: string\n}\n\nexport interface UpdateLicenseRequest {\n planType?: PlanType\n overrides?: LicenseOverrides\n}\n", "export interface HealthStatusResponse {\n passing: boolean\n checks: {\n login: boolean\n search: boolean\n }\n}\n", "export * from \"./accounts\"\nexport * from \"./user\"\nexport * from \"./license\"\nexport * from \"./status\"\n", "export enum PingSource {\n BUILDER = \"builder\",\n APP = \"app\",\n}\n\nexport interface AnalyticsPingRequest {\n source: PingSource\n timezone: string\n}\n", "export interface LoginRequest {\n username: string\n password: string\n}\n\nexport interface PasswordResetRequest {\n email: string\n}\n\nexport interface PasswordResetUpdateRequest {\n resetCode: string\n password: string\n}\n\nexport interface UpdateSelfRequest {\n firstName?: string\n lastName?: string\n password?: string\n forceResetPassword?: boolean\n onboardedAt?: string\n}\n\nexport interface UpdateSelfResponse {\n _id: string\n _rev: string\n}\n", "import { User } from \"../../documents\"\n\nexport interface SaveUserResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface UserDetails {\n _id: string\n email: string\n}\n\nexport interface BulkUserRequest {\n delete?: {\n userIds: string[]\n }\n create?: {\n roles?: any[]\n users: User[]\n groups: any[]\n }\n}\n\nexport interface BulkUserCreated {\n successful: UserDetails[]\n unsuccessful: { email: string; reason: string }[]\n}\n\nexport interface BulkUserDeleted {\n successful: UserDetails[]\n unsuccessful: { _id: string; email: string; reason: string }[]\n}\n\nexport interface BulkUserResponse {\n created?: BulkUserCreated\n deleted?: BulkUserDeleted\n message?: string\n}\n\nexport interface InviteUserRequest {\n email: string\n userInfo: any\n}\n\nexport type InviteUsersRequest = InviteUserRequest[]\n\nexport interface InviteUsersResponse {\n successful: { email: string }[]\n unsuccessful: { email: string; reason: string }[]\n}\n\nexport interface SearchUsersRequest {\n page?: string\n email?: string\n appId?: string\n paginated?: boolean\n}\n\nexport interface CreateAdminUserRequest {\n email: string\n password: string\n tenantId: string\n}\n\nexport interface CreateAdminUserResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface AcceptUserInviteRequest {\n inviteCode: string\n password: string\n firstName: string\n lastName: string\n}\n\nexport interface AcceptUserInviteResponse {\n _id: string\n _rev: string\n email: string\n}\n\nexport interface SyncUserRequest {\n previousUser?: User\n}\n", "export interface APIError {\n message: string\n status: number\n error?: any\n validationErrors?: any\n}\n", "import {\n ScheduleMetadata,\n ScheduleRepeatPeriod,\n ScheduleType,\n} from \"../../documents\"\n\nexport interface CreateScheduleRequest {\n type: ScheduleType\n name: string\n startDate: string\n repeat: ScheduleRepeatPeriod\n metadata: ScheduleMetadata\n}\n\nexport interface UpdateScheduleRequest extends CreateScheduleRequest {}\n", "export interface GetEnvironmentResponse {\n multiTenancy: boolean\n cloud: boolean\n accountPortalUrl: string\n baseUrl: string\n disableAccountPortal: boolean\n isDev: boolean\n}\n", "export * from \"./environment\"\n", "import { AppBackupTrigger, AppBackupType } from \"../../../documents\"\n\nexport interface SearchAppBackupsRequest {\n trigger: AppBackupTrigger\n type: AppBackupType\n startDate: string\n endDate: string\n page?: string\n}\n\nexport interface CreateAppBackupRequest {\n name: string\n}\n\nexport interface CreateAppBackupResponse {\n backupId: string\n message: string\n}\n\nexport interface UpdateAppBackupRequest {\n name: string\n}\n", "import { Datasource } from \"../../../documents\"\n\nexport interface CreateDatasourceResponse {\n datasource: Datasource\n error?: any\n}\n\nexport interface UpdateDatasourceResponse {\n datasource: Datasource\n}\n\nexport interface CreateDatasourceRequest {\n datasource: Datasource\n fetchSchema?: boolean\n}\n\nexport interface VerifyDatasourceRequest {\n datasource: Datasource\n}\n\nexport interface VerifyDatasourceResponse {\n connected: boolean\n error?: string\n}\n\nexport interface FetchDatasourceInfoResponse {\n tableNames: string[]\n}\n\nexport interface UpdateDatasourceRequest extends Datasource {\n datasource: Datasource\n}\n", "export * from \"./backup\"\nexport * from \"./datasource\"\n", "export interface StatusEnvironmentVariableResponse {\n encryptionKeyAvailable: boolean\n}\n\nexport interface CreateEnvironmentVariableRequest {\n name: string\n production: string\n development: string\n}\n\nexport interface UpdateEnvironmentVariableRequest {\n production: string\n development: string\n}\n\nexport interface GetEnvironmentVariablesResponse {\n variables: string[]\n}\n", "import { Event, AuditedEventFriendlyName } from \"../../../sdk\"\nimport {\n PaginationResponse,\n PaginationRequest,\n BasicPaginationRequest,\n} from \"../\"\nimport { User, App } from \"../../../\"\n\nexport interface AuditLogSearchParams {\n userIds?: string[]\n appIds?: string[]\n events?: Event[]\n startDate?: string\n endDate?: string\n fullSearch?: string\n bookmark?: string\n}\n\nexport interface DownloadAuditLogsRequest extends AuditLogSearchParams {}\n\nexport interface SearchAuditLogsRequest\n extends BasicPaginationRequest,\n AuditLogSearchParams {}\n\nexport enum AuditLogResourceStatus {\n DELETED = \"deleted\",\n}\n\nexport type DeletedResourceInfo = {\n _id: string\n status: AuditLogResourceStatus\n email?: string\n name?: string\n}\n\nexport interface AuditLogEnriched {\n app?: App | DeletedResourceInfo\n user: User | DeletedResourceInfo\n event: Event\n timestamp: string\n name: string\n metadata: any\n}\n\nexport interface SearchAuditLogsResponse extends PaginationResponse {\n data: AuditLogEnriched[]\n}\n\nexport interface DefinitionsAuditLogsResponse {\n events: Record<string, string>\n}\n", "export enum EventPublishType {\n ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED = \"environment_variable_upgrade_panel_opened\",\n}\n\nexport interface PostEventPublishRequest {\n type: EventPublishType\n}\n", "import { SettingsConfig, SettingsInnerConfig } from \"../../../documents\"\n\n/**\n * Settings that aren't stored in the database - enriched at runtime.\n */\nexport interface PublicSettingsInnerConfig extends SettingsInnerConfig {\n google: boolean\n googleDatasourceConfigured: boolean\n oidc: boolean\n oidcCallbackUrl: string\n googleCallbackUrl: string\n}\n\nexport interface GetPublicSettingsResponse extends SettingsConfig {\n config: PublicSettingsInnerConfig\n}\n\nexport interface PublicOIDCConfig {\n logo?: string\n name?: string\n uuid?: string\n}\n\nexport type GetPublicOIDCConfigResponse = PublicOIDCConfig[]\n", "import { ScimResource, ScimMeta } from \"scim-patch\"\nimport { ScimListResponse } from \"./shared\"\n\ntype BooleanString = boolean | \"True\" | \"true\" | \"False\" | \"false\"\n\ntype Emails =\n | {\n value: string\n type: \"work\"\n primary: boolean\n }[]\n\nexport interface ScimUserResponse extends ScimResource {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:User\"]\n id: string\n externalId: string\n meta: ScimMeta & {\n resourceType: \"User\"\n }\n userName: string\n displayName?: string\n name?: {\n formatted?: string\n familyName?: string\n givenName?: string\n }\n active: BooleanString\n emails?: Emails\n}\n\nexport interface ScimCreateUserRequest {\n schemas: [\n \"urn:ietf:params:scim:schemas:core:2.0:User\",\n \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\"\n ]\n externalId: string\n userName: string\n active: BooleanString\n emails?: Emails\n meta: {\n resourceType: \"User\"\n }\n displayName?: string\n name?: {\n formatted: string\n familyName: string\n givenName: string\n }\n roles: []\n}\n\nexport interface ScimUserListResponse\n extends ScimListResponse<ScimUserResponse> {}\n", "import { ScimResource, ScimMeta } from \"scim-patch\"\nimport { ScimListResponse } from \"./shared\"\n\nexport interface ScimGroupResponse extends ScimResource {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:Group\"]\n id: string\n externalId: string\n displayName: string\n meta: ScimMeta & {\n resourceType: \"Group\"\n }\n members?: {\n value: string\n }[]\n}\n\nexport interface ScimCreateGroupRequest {\n schemas: [\n \"urn:ietf:params:scim:schemas:core:2.0:Group\",\n \"http://schemas.microsoft.com/2006/11/ResourceManagement/ADSCIM/2.0/Group\"\n ]\n externalId: string\n displayName: string\n meta: ScimMeta & {\n resourceType: \"Group\"\n }\n}\n\nexport interface ScimGroupListResponse\n extends ScimListResponse<ScimGroupResponse> {}\n", "import { ScimPatchOperation } from \"scim-patch\"\n\nexport interface ScimListResponse<T> {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"]\n totalResults: number\n Resources: T[]\n startIndex: number\n itemsPerPage: number\n}\n\nexport interface ScimUpdateRequest {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:PatchOp\"]\n Operations: ScimPatchOperation[]\n}\n", "export * from \"./users\"\nexport * from \"./groups\"\nexport * from \"./shared\"\n", "export * from \"./environmentVariables\"\nexport * from \"./auditLogs\"\nexport * from \"./events\"\nexport * from \"./configs\"\nexport * from \"./scim\"\n", "export enum SortOrder {\n ASCENDING = \"ascending\",\n DESCENDING = \"descending\",\n}\n\nexport enum SortType {\n STRING = \"string\",\n number = \"number\",\n}\n\nexport interface BasicPaginationRequest {\n bookmark?: string\n}\n\nexport interface PaginationRequest extends BasicPaginationRequest {\n limit?: number\n sort?: {\n order: SortOrder\n column: string\n type: SortType\n }\n}\n\nexport interface PaginationResponse {\n bookmark: string | undefined\n hasNextPage: boolean\n}\n", "export * from \"./analytics\"\nexport * from \"./auth\"\nexport * from \"./user\"\nexport * from \"./errors\"\nexport * from \"./schedule\"\nexport * from \"./system\"\nexport * from \"./app\"\nexport * from \"./global\"\nexport * from \"./pagination\"\n", "export * from \"./account\"\nexport * from \"./web\"\n", "export * from \"./documents\"\nexport * from \"./sdk\"\nexport * from \"./api\"\n", "export const SEPARATOR = \"_\"\nexport const UNICODE_MAX = \"\\ufff0\"\n\n/**\n * Can be used to create a few different forms of querying a view.\n */\nexport enum AutomationViewMode {\n ALL = \"all\",\n AUTOMATION = \"automation\",\n STATUS = \"status\",\n}\n\nexport enum ViewName {\n USER_BY_APP = \"by_app\",\n USER_BY_EMAIL = \"by_email2\",\n BY_API_KEY = \"by_api_key\",\n /** @deprecated - could be deleted */\n USER_BY_BUILDERS = \"by_builders\",\n LINK = \"by_link\",\n ROUTING = \"screen_routes\",\n AUTOMATION_LOGS = \"automation_logs\",\n ACCOUNT_BY_EMAIL = \"account_by_email\",\n PLATFORM_USERS_LOWERCASE = \"platform_users_lowercase\",\n USER_BY_GROUP = \"user_by_group\",\n APP_BACKUP_BY_TRIGGER = \"by_trigger\",\n}\n\nexport const DeprecatedViews = {\n [ViewName.USER_BY_EMAIL]: [\n // removed due to inaccuracy in view doc filter logic\n \"by_email\",\n ],\n}\n\nexport enum InternalTable {\n USER_METADATA = \"ta_users\",\n}\n\nexport enum DocumentType {\n USER = \"us\",\n GROUP = \"gr\",\n WORKSPACE = \"workspace\",\n CONFIG = \"config\",\n TEMPLATE = \"template\",\n APP = \"app\",\n DEV = \"dev\",\n APP_DEV = \"app_dev\",\n APP_METADATA = \"app_metadata\",\n ROLE = \"role\",\n MIGRATIONS = \"migrations\",\n DEV_INFO = \"devinfo\",\n AUTOMATION_LOG = \"log_au\",\n ACCOUNT_METADATA = \"acc_metadata\",\n PLUGIN = \"plg\",\n DATASOURCE = \"datasource\",\n DATASOURCE_PLUS = \"datasource_plus\",\n APP_BACKUP = \"backup\",\n TABLE = \"ta\",\n ROW = \"ro\",\n AUTOMATION = \"au\",\n LINK = \"li\",\n WEBHOOK = \"wh\",\n INSTANCE = \"inst\",\n LAYOUT = \"layout\",\n SCREEN = \"screen\",\n QUERY = \"query\",\n DEPLOYMENTS = \"deployments\",\n METADATA = \"metadata\",\n MEM_VIEW = \"view\",\n USER_FLAG = \"flag\",\n AUTOMATION_METADATA = \"meta_au\",\n AUDIT_LOG = \"al\",\n}\n\nexport const StaticDatabases = {\n GLOBAL: {\n name: \"global-db\",\n docs: {\n apiKeys: \"apikeys\",\n usageQuota: \"usage_quota\",\n licenseInfo: \"license_info\",\n environmentVariables: \"environmentvariables\",\n },\n },\n // contains information about tenancy and so on\n PLATFORM_INFO: {\n name: \"global-info\",\n docs: {\n tenants: \"tenants\",\n install: \"install\",\n },\n },\n AUDIT_LOGS: {\n name: \"audit-logs\",\n },\n}\n\nexport const APP_PREFIX = DocumentType.APP + SEPARATOR\nexport const APP_DEV = DocumentType.APP_DEV + SEPARATOR\nexport const APP_DEV_PREFIX = APP_DEV\nexport const BUDIBASE_DATASOURCE_TYPE = \"budibase\"\n", "export enum UserStatus {\n ACTIVE = \"active\",\n INACTIVE = \"inactive\",\n}\n\nexport enum Cookie {\n Auth = \"budibase:auth\",\n Init = \"budibase:init\",\n ACCOUNT_RETURN_URL = \"budibase:account:returnurl\",\n DatasourceAuth = \"budibase:datasourceauth\",\n OIDC_CONFIG = \"budibase:oidc:config\",\n}\n\nexport enum Header {\n API_KEY = \"x-budibase-api-key\",\n LICENSE_KEY = \"x-budibase-license-key\",\n API_VER = \"x-budibase-api-version\",\n APP_ID = \"x-budibase-app-id\",\n TYPE = \"x-budibase-type\",\n PREVIEW_ROLE = \"x-budibase-role\",\n TENANT_ID = \"x-budibase-tenant-id\",\n TOKEN = \"x-budibase-token\",\n CSRF_TOKEN = \"x-csrf-token\",\n CORRELATION_ID = \"x-budibase-correlation-id\",\n AUTHORIZATION = \"authorization\",\n}\n\nexport enum GlobalRole {\n OWNER = \"owner\",\n ADMIN = \"admin\",\n BUILDER = \"builder\",\n WORKSPACE_MANAGER = \"workspace_manager\",\n}\n\nexport enum Config {\n SETTINGS = \"settings\",\n ACCOUNT = \"account\",\n SMTP = \"smtp\",\n GOOGLE = \"google\",\n OIDC = \"oidc\",\n OIDC_LOGOS = \"logos_oidc\",\n SCIM = \"scim\",\n}\n\nexport const MIN_VALID_DATE = new Date(-2147483647000)\nexport const MAX_VALID_DATE = new Date(2147483647000)\nexport const DEFAULT_TENANT_ID = \"default\"\n", "export * from \"./db\"\nexport * from \"./misc\"\n", "import {\n IdentityContext,\n IdentityType,\n User,\n isCloudAccount,\n Account,\n AccountUserContext,\n UserContext,\n Ctx,\n} from \"@budibase/types\"\nimport * as context from \".\"\n\nexport function getIdentity(): IdentityContext | undefined {\n return context.getIdentity()\n}\n\nexport function doInIdentityContext(identity: IdentityContext, task: any) {\n return context.doInIdentityContext(identity, task)\n}\n\n// used in server/worker\nexport function doInUserContext(user: User, ctx: Ctx, task: any) {\n const userContext: UserContext = {\n ...user,\n _id: user._id as string,\n type: IdentityType.USER,\n hostInfo: {\n ipAddress: ctx.request.ip,\n // filled in by koa-useragent package\n userAgent: ctx.userAgent._agent.source,\n },\n }\n return doInIdentityContext(userContext, task)\n}\n\n// used in account portal\nexport function doInAccountContext(account: Account, task: any) {\n const _id = getAccountUserId(account)\n const tenantId = account.tenantId\n const accountContext: AccountUserContext = {\n _id,\n type: IdentityType.USER,\n tenantId,\n account,\n }\n return doInIdentityContext(accountContext, task)\n}\n\nexport function getAccountUserId(account: Account) {\n let userId: string\n if (isCloudAccount(account)) {\n userId = account.budibaseUserId\n } else {\n // use account id as user id for self-hosting\n userId = account.accountId\n }\n return userId\n}\n", "import { existsSync, readFileSync } from \"fs\"\n\nfunction isTest() {\n return isCypress() || isJest()\n}\n\nfunction isJest() {\n return !!(process.env.NODE_ENV === \"jest\" || process.env.JEST_WORKER_ID)\n}\n\nfunction isCypress() {\n return process.env.NODE_ENV === \"cypress\"\n}\n\nfunction isDev() {\n return process.env.NODE_ENV !== \"production\"\n}\n\nlet LOADED = false\nif (!LOADED && isDev() && !isTest()) {\n require(\"dotenv\").config()\n LOADED = true\n}\n\nconst DefaultBucketName = {\n BACKUPS: \"backups\",\n APPS: \"prod-budi-app-assets\",\n TEMPLATES: \"templates\",\n GLOBAL: \"global\",\n PLUGINS: \"plugins\",\n}\n\nconst selfHosted = !!parseInt(process.env.SELF_HOSTED || \"\")\n\nfunction getAPIEncryptionKey() {\n return process.env.API_ENCRYPTION_KEY\n ? process.env.API_ENCRYPTION_KEY\n : process.env.JWT_SECRET // fallback to the JWT_SECRET used historically\n}\n\nfunction httpLogging() {\n if (process.env.HTTP_LOGGING === undefined) {\n // on by default unless otherwise specified\n return true\n }\n\n return process.env.HTTP_LOGGING\n}\n\nfunction findVersion() {\n function findFileInAncestors(\n fileName: string,\n currentDir: string\n ): string | null {\n const filePath = `${currentDir}/${fileName}`\n if (existsSync(filePath)) {\n return filePath\n }\n\n const parentDir = `${currentDir}/..`\n if (parentDir === currentDir) {\n // reached root directory\n return null\n }\n\n return findFileInAncestors(fileName, parentDir)\n }\n\n try {\n const packageJsonFile = findFileInAncestors(\"package.json\", process.cwd())\n const content = readFileSync(packageJsonFile!, \"utf-8\")\n return JSON.parse(content).version\n } catch {\n // throwing an error here is confusing/causes backend-core to be hard to import\n return undefined\n }\n}\n\nconst environment = {\n isTest,\n isJest,\n isDev,\n isProd: () => {\n return !isDev()\n },\n JS_BCRYPT: process.env.JS_BCRYPT,\n JWT_SECRET: process.env.JWT_SECRET,\n JWT_SECRET_FALLBACK: process.env.JWT_SECRET_FALLBACK,\n ENCRYPTION_KEY: process.env.ENCRYPTION_KEY,\n API_ENCRYPTION_KEY: getAPIEncryptionKey(),\n COUCH_DB_URL: process.env.COUCH_DB_URL || \"http://localhost:4005\",\n COUCH_DB_USERNAME: process.env.COUCH_DB_USER,\n COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,\n GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,\n GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,\n SALT_ROUNDS: process.env.SALT_ROUNDS,\n REDIS_URL: process.env.REDIS_URL || \"localhost:6379\",\n REDIS_PASSWORD: process.env.REDIS_PASSWORD,\n REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,\n MOCK_REDIS: process.env.MOCK_REDIS,\n MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,\n MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,\n AWS_REGION: process.env.AWS_REGION,\n MINIO_URL: process.env.MINIO_URL,\n MINIO_ENABLED: process.env.MINIO_ENABLED || 1,\n INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,\n INTERNAL_API_KEY_FALLBACK: process.env.INTERNAL_API_KEY_FALLBACK,\n MULTI_TENANCY: process.env.MULTI_TENANCY,\n ACCOUNT_PORTAL_URL:\n process.env.ACCOUNT_PORTAL_URL || \"https://account.budibase.app\",\n ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY || \"\",\n DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,\n SELF_HOSTED: selfHosted,\n COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,\n PLATFORM_URL: process.env.PLATFORM_URL || \"\",\n POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,\n ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,\n TENANT_FEATURE_FLAGS: process.env.TENANT_FEATURE_FLAGS,\n CLOUDFRONT_CDN: process.env.CLOUDFRONT_CDN,\n CLOUDFRONT_PRIVATE_KEY_64: process.env.CLOUDFRONT_PRIVATE_KEY_64,\n CLOUDFRONT_PUBLIC_KEY_ID: process.env.CLOUDFRONT_PUBLIC_KEY_ID,\n BACKUPS_BUCKET_NAME:\n process.env.BACKUPS_BUCKET_NAME || DefaultBucketName.BACKUPS,\n APPS_BUCKET_NAME: process.env.APPS_BUCKET_NAME || DefaultBucketName.APPS,\n TEMPLATES_BUCKET_NAME:\n process.env.TEMPLATES_BUCKET_NAME || DefaultBucketName.TEMPLATES,\n GLOBAL_BUCKET_NAME:\n process.env.GLOBAL_BUCKET_NAME || DefaultBucketName.GLOBAL,\n PLUGIN_BUCKET_NAME:\n process.env.PLUGIN_BUCKET_NAME || DefaultBucketName.PLUGINS,\n USE_COUCH: process.env.USE_COUCH || true,\n DEFAULT_LICENSE: process.env.DEFAULT_LICENSE,\n SERVICE: process.env.SERVICE || \"budibase\",\n LOG_LEVEL: process.env.LOG_LEVEL || \"info\",\n SESSION_UPDATE_PERIOD: process.env.SESSION_UPDATE_PERIOD,\n DEPLOYMENT_ENVIRONMENT:\n process.env.DEPLOYMENT_ENVIRONMENT || \"docker-compose\",\n HTTP_LOGGING: httpLogging(),\n ENABLE_AUDIT_LOG_IP_ADDR: process.env.ENABLE_AUDIT_LOG_IP_ADDR,\n // smtp\n SMTP_FALLBACK_ENABLED: process.env.SMTP_FALLBACK_ENABLED,\n SMTP_USER: process.env.SMTP_USER,\n SMTP_PASSWORD: process.env.SMTP_PASSWORD,\n SMTP_HOST: process.env.SMTP_HOST,\n SMTP_PORT: parseInt(process.env.SMTP_PORT || \"\"),\n SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS,\n DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING,\n BLACKLIST_IPS: process.env.BLACKLIST_IPS,\n /**\n * Enable to allow an admin user to login using a password.\n * This can be useful to prevent lockout when configuring SSO.\n * However, this should be turned OFF by default for security purposes.\n */\n ENABLE_SSO_MAINTENANCE_MODE: selfHosted\n ? process.env.ENABLE_SSO_MAINTENANCE_MODE\n : false,\n VERSION: findVersion(),\n DISABLE_PINO_LOGGER: process.env.DISABLE_PINO_LOGGER,\n _set(key: any, value: any) {\n process.env[key] = value\n // @ts-ignore\n environment[key] = value\n },\n}\n\n// clean up any environment variable edge cases\nfor (let [key, value] of Object.entries(environment)) {\n // handle the edge case of \"0\" to disable an environment variable\n if (value === \"0\") {\n // @ts-ignore\n environment[key] = 0\n }\n // handle the edge case of \"false\" to disable an environment variable\n if (value === \"false\") {\n // @ts-ignore\n environment[key] = 0\n }\n}\n\nexport default environment\n", "import { AsyncLocalStorage } from \"async_hooks\"\nimport { ContextMap } from \"./types\"\n\nexport default class Context {\n static storage = new AsyncLocalStorage<ContextMap>()\n\n static run(context: ContextMap, func: any) {\n return Context.storage.run(context, () => func())\n }\n\n static get(): ContextMap {\n return Context.storage.getStore() as ContextMap\n }\n}\n", "import { APP_DEV_PREFIX, APP_PREFIX } from \"../constants\"\nimport { App } from \"@budibase/types\"\nconst NO_APP_ERROR = \"No app provided\"\n\nexport function isDevAppID(appId?: string) {\n if (!appId) {\n throw NO_APP_ERROR\n }\n return appId.startsWith(APP_DEV_PREFIX)\n}\n\nexport function isProdAppID(appId?: string) {\n if (!appId) {\n throw NO_APP_ERROR\n }\n return appId.startsWith(APP_PREFIX) && !isDevAppID(appId)\n}\n\nexport function isDevApp(app: App) {\n if (!app) {\n throw NO_APP_ERROR\n }\n return isDevAppID(app.appId)\n}\n\n/**\n * Generates a development app ID from a real app ID.\n * @returns {string} the dev app ID which can be used for dev database.\n */\nexport function getDevelopmentAppID(appId: string) {\n if (!appId || appId.startsWith(APP_DEV_PREFIX)) {\n return appId\n }\n // split to take off the app_ element, then join it together incase any other app_ exist\n const split = appId.split(APP_PREFIX)\n split.shift()\n const rest = split.join(APP_PREFIX)\n return `${APP_DEV_PREFIX}${rest}`\n}\nexport const getDevAppID = getDevelopmentAppID\n\n/**\n * Convert a development app ID to a deployed app ID.\n */\nexport function getProdAppID(appId: string) {\n if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {\n return appId\n }\n // split to take off the app_dev element, then join it together incase any other app_ exist\n const split = appId.split(APP_DEV_PREFIX)\n split.shift()\n const rest = split.join(APP_DEV_PREFIX)\n return `${APP_PREFIX}${rest}`\n}\n\nexport function extractAppUUID(id: string) {\n const split = id?.split(\"_\") || []\n return split.length ? split[split.length - 1] : null\n}\n", "import env from \"../../environment\"\n\nexport const getCouchInfo = (connection?: string) => {\n const urlInfo = getUrlInfo(connection)\n let username\n let password\n if (urlInfo.auth?.username) {\n // set from url\n username = urlInfo.auth.username\n } else if (env.COUCH_DB_USERNAME) {\n // set from env\n username = env.COUCH_DB_USERNAME\n } else if (!env.isTest()) {\n throw new Error(\"CouchDB username not set\")\n }\n if (urlInfo.auth?.password) {\n // set from url\n password = urlInfo.auth.password\n } else if (env.COUCH_DB_PASSWORD) {\n // set from env\n password = env.COUCH_DB_PASSWORD\n } else if (!env.isTest()) {\n throw new Error(\"CouchDB password not set\")\n }\n const authCookie = Buffer.from(`${username}:${password}`).toString(\"base64\")\n return {\n url: urlInfo.url!,\n auth: {\n username: username,\n password: password,\n },\n cookie: `Basic ${authCookie}`,\n }\n}\n\nexport const getUrlInfo = (url = env.COUCH_DB_URL) => {\n let cleanUrl, username, password, host\n if (url) {\n // Ensure the URL starts with a protocol\n const protoRegex = /^https?:\\/\\//i\n if (!protoRegex.test(url)) {\n url = `http://${url}`\n }\n\n // Split into protocol and remainder\n const split = url.split(\"://\")\n const protocol = split[0]\n const rest = split.slice(1).join(\"://\")\n\n // Extract auth if specified\n if (url.includes(\"@\")) {\n // Split into host and remainder\n let parts = rest.split(\"@\")\n host = parts[parts.length - 1]\n let auth = parts.slice(0, -1).join(\"@\")\n\n // Split auth into username and password\n if (auth.includes(\":\")) {\n const authParts = auth.split(\":\")\n username = authParts[0]\n password = authParts.slice(1).join(\":\")\n } else {\n username = auth\n }\n } else {\n host = rest\n }\n cleanUrl = `${protocol}://${host}`\n }\n return {\n url: cleanUrl,\n auth: {\n username,\n password,\n },\n }\n}\n", "/**\n * Makes sure that a URL has the correct number of slashes, while maintaining the\n * http(s):// double slashes.\n * @param {string} url The URL to test and remove any extra double slashes.\n * @return {string} The updated url.\n */\nexport function checkSlashesInUrl(url: string) {\n return url.replace(/(https?:\\/\\/)|(\\/)+/g, \"$1$2\")\n}\n", "import { getCouchInfo } from \"./connections\"\nimport fetch from \"node-fetch\"\nimport { checkSlashesInUrl } from \"../../helpers\"\n\nexport async function directCouchCall(\n path: string,\n method: string = \"GET\",\n body?: any\n) {\n let { url, cookie } = getCouchInfo()\n const couchUrl = `${url}/${path}`\n return await directCouchUrlCall({ url: couchUrl, cookie, method, body })\n}\n\nexport async function directCouchUrlCall({\n url,\n cookie,\n method,\n body,\n}: {\n url: string\n cookie: string\n method: string\n body?: any\n}) {\n const params: any = {\n method: method,\n headers: {\n Authorization: cookie,\n },\n }\n if (body && method !== \"GET\") {\n params.body = JSON.stringify(body)\n params.headers[\"Content-Type\"] = \"application/json\"\n }\n return await fetch(checkSlashesInUrl(encodeURI(url)), params)\n}\n\nexport async function directCouchQuery(\n path: string,\n method: string = \"GET\",\n body?: any\n) {\n const response = await directCouchCall(path, method, body)\n if (response.status < 300) {\n return await response.json()\n } else {\n throw \"Cannot connect to CouchDB instance\"\n }\n}\n", "import PouchDB from \"pouchdb\"\nimport env from \"../../environment\"\nimport { PouchOptions } from \"@budibase/types\"\nimport { getCouchInfo } from \"./connections\"\n\nlet Pouch: any\nlet initialised = false\n\n/**\n * Return a constructor for PouchDB.\n * This should be rarely used outside of the main application config.\n * Exposed for exceptional cases such as in-memory views.\n */\nexport const getPouch = (opts: PouchOptions = {}) => {\n let { url, cookie } = getCouchInfo()\n let POUCH_DB_DEFAULTS = {\n prefix: url,\n fetch: (url: string, opts: any) => {\n // use a specific authorization cookie - be very explicit about how we authenticate\n opts.headers.set(\"Authorization\", cookie)\n return PouchDB.fetch(url, opts)\n },\n }\n\n if (opts.inMemory) {\n const inMemory = require(\"pouchdb-adapter-memory\")\n PouchDB.plugin(inMemory)\n POUCH_DB_DEFAULTS = {\n // @ts-ignore\n adapter: \"memory\",\n }\n }\n\n if (opts.onDisk) {\n POUCH_DB_DEFAULTS = {\n // @ts-ignore\n adapter: \"leveldb\",\n }\n }\n\n if (opts.replication) {\n const replicationStream = require(\"@budibase/pouchdb-replication-stream\")\n PouchDB.plugin(replicationStream.plugin)\n // @ts-ignore\n PouchDB.adapter(\"writableStream\", replicationStream.adapters.writableStream)\n }\n\n if (opts.find) {\n const find = require(\"pouchdb-find\")\n PouchDB.plugin(find)\n }\n\n return PouchDB.defaults(POUCH_DB_DEFAULTS)\n}\n\nexport function init(opts?: PouchOptions) {\n Pouch = getPouch(opts)\n initialised = true\n}\n\nconst checkInitialised = () => {\n if (!initialised) {\n throw new Error(\"init has not been called\")\n }\n}\n\nexport function getPouchDB(dbName: string, opts?: any): PouchDB.Database {\n checkInitialised()\n const db = new Pouch(dbName, opts)\n const dbPut = db.put\n db.put = async (doc: any, options = {}) => {\n if (!doc.createdAt) {\n doc.createdAt = new Date().toISOString()\n }\n doc.updatedAt = new Date().toISOString()\n return dbPut(doc, options)\n }\n db.exists = async () => {\n const info = await db.info()\n return !info.error\n }\n return db\n}\n\n// use this function if you have called getPouchDB - close\n// the databases you've opened once finished\nexport async function closePouchDB(db: PouchDB.Database) {\n if (!db || env.isTest()) {\n return\n }\n try {\n // specifically await so that if there is an error, it can be ignored\n return await db.close()\n } catch (err) {\n // ignore error, already closed\n }\n}\n", "import { v4 } from \"uuid\"\n\nexport function newid() {\n return v4().replace(/-/g, \"\")\n}\n", "import Nano from \"@budibase/nano\"\nimport {\n AllDocsResponse,\n AnyDocument,\n Database,\n DatabaseOpts,\n DatabaseQueryOpts,\n DatabasePutOpts,\n DatabaseCreateIndexOpts,\n DatabaseDeleteIndexOpts,\n Document,\n isDocument,\n} from \"@budibase/types\"\nimport { getCouchInfo } from \"./connections\"\nimport { directCouchUrlCall } from \"./utils\"\nimport { getPouchDB } from \"./pouchDB\"\nimport { WriteStream, ReadStream } from \"fs\"\nimport { newid } from \"../../docIds/newid\"\n\nfunction buildNano(couchInfo: { url: string; cookie: string }) {\n return Nano({\n url: couchInfo.url,\n requestDefaults: {\n headers: {\n Authorization: couchInfo.cookie,\n },\n },\n parseUrl: false,\n })\n}\n\nexport function DatabaseWithConnection(\n dbName: string,\n connection: string,\n opts?: DatabaseOpts\n) {\n if (!connection) {\n throw new Error(\"Must provide connection details\")\n }\n return new DatabaseImpl(dbName, opts, connection)\n}\n\nexport class DatabaseImpl implements Database {\n public readonly name: string\n private static nano: Nano.ServerScope\n private readonly instanceNano?: Nano.ServerScope\n private readonly pouchOpts: DatabaseOpts\n\n private readonly couchInfo = getCouchInfo()\n\n constructor(dbName?: string, opts?: DatabaseOpts, connection?: string) {\n if (dbName == null) {\n throw new Error(\"Database name cannot be undefined.\")\n }\n this.name = dbName\n this.pouchOpts = opts || {}\n if (connection) {\n this.couchInfo = getCouchInfo(connection)\n this.instanceNano = buildNano(this.couchInfo)\n }\n if (!DatabaseImpl.nano) {\n DatabaseImpl.init()\n }\n }\n\n static init() {\n const couchInfo = getCouchInfo()\n DatabaseImpl.nano = buildNano(couchInfo)\n }\n\n async exists() {\n const response = await directCouchUrlCall({\n url: `${this.couchInfo.url}/${this.name}`,\n method: \"HEAD\",\n cookie: this.couchInfo.cookie,\n })\n return response.status === 200\n }\n\n private nano() {\n return this.instanceNano || DatabaseImpl.nano\n }\n\n async checkSetup() {\n let shouldCreate = !this.pouchOpts?.skip_setup\n // check exists in a lightweight fashion\n let exists = await this.exists()\n if (!shouldCreate && !exists) {\n throw new Error(\"DB does not exist\")\n }\n if (!exists) {\n try {\n await this.nano().db.create(this.name)\n } catch (err: any) {\n // Handling race conditions\n if (err.statusCode !== 412) {\n throw err\n }\n }\n }\n return this.nano().db.use(this.name)\n }\n\n private async updateOutput(fnc: any) {\n try {\n return await fnc()\n } catch (err: any) {\n if (err.statusCode) {\n err.status = err.statusCode\n }\n throw err\n }\n }\n\n async get<T>(id?: string): Promise<T | any> {\n const db = await this.checkSetup()\n if (!id) {\n throw new Error(\"Unable to get doc without a valid _id.\")\n }\n return this.updateOutput(() => db.get(id))\n }\n\n async remove(idOrDoc: string | Document, rev?: string) {\n const db = await this.checkSetup()\n let _id: string\n let _rev: string\n\n if (isDocument(idOrDoc)) {\n _id = idOrDoc._id!\n _rev = idOrDoc._rev!\n } else {\n _id = idOrDoc\n _rev = rev!\n }\n\n if (!_id || !_rev) {\n throw new Error(\"Unable to remove doc without a valid _id and _rev.\")\n }\n return this.updateOutput(() => db.destroy(_id, _rev))\n }\n\n async post(document: AnyDocument, opts?: DatabasePutOpts) {\n if (!document._id) {\n document._id = newid()\n }\n return this.put(document, opts)\n }\n\n async put(document: AnyDocument, opts?: DatabasePutOpts) {\n if (!document._id) {\n throw new Error(\"Cannot store document without _id field.\")\n }\n const db = await this.checkSetup()\n if (!document.createdAt) {\n document.createdAt = new Date().toISOString()\n }\n document.updatedAt = new Date().toISOString()\n if (opts?.force && document._id) {\n try {\n const existing = await this.get(document._id)\n if (existing) {\n document._rev = existing._rev\n }\n } catch (err: any) {\n if (err.status !== 404) {\n throw err\n }\n }\n }\n return this.updateOutput(() => db.insert(document))\n }\n\n async bulkDocs(documents: AnyDocument[]) {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.bulk({ docs: documents }))\n }\n\n async allDocs<T>(params: DatabaseQueryOpts): Promise<AllDocsResponse<T>> {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.list(params))\n }\n\n async query<T>(\n viewName: string,\n params: DatabaseQueryOpts\n ): Promise<AllDocsResponse<T>> {\n const db = await this.checkSetup()\n const [database, view] = viewName.split(\"/\")\n return this.updateOutput(() => db.view(database, view, params))\n }\n\n async destroy() {\n try {\n return await this.nano().db.destroy(this.name)\n } catch (err: any) {\n // didn't exist, don't worry\n if (err.statusCode === 404) {\n return\n } else {\n throw { ...err, status: err.statusCode }\n }\n }\n }\n\n async compact() {\n const db = await this.checkSetup()\n return this.updateOutput(() => db.compact())\n }\n\n // All below functions are in-frequently called, just utilise PouchDB\n // for them as it implements them better than we can\n async dump(stream: WriteStream, opts?: { filter?: any }) {\n const pouch = getPouchDB(this.name)\n // @ts-ignore\n return pouch.dump(stream, opts)\n }\n\n async load(stream: ReadStream) {\n const pouch = getPouchDB(this.name)\n // @ts-ignore\n return pouch.load(stream)\n }\n\n async createIndex(opts: DatabaseCreateIndexOpts) {\n const pouch = getPouchDB(this.name)\n return pouch.createIndex(opts)\n }\n\n async deleteIndex(opts: DatabaseDeleteIndexOpts) {\n const pouch = getPouchDB(this.name)\n return pouch.deleteIndex(opts)\n }\n\n async getIndexes() {\n const pouch = getPouchDB(this.name)\n return pouch.getIndexes()\n }\n}\n", "export * from \"./connections\"\nexport * from \"./DatabaseImpl\"\nexport * from \"./utils\"\nexport { init, getPouch, getPouchDB, closePouchDB } from \"./pouchDB\"\n", "import env from \"../environment\"\nimport { directCouchQuery, DatabaseImpl } from \"./couch\"\nimport { CouchFindOptions, Database } from \"@budibase/types\"\n\nconst dbList = new Set()\n\nexport function getDB(dbName?: string, opts?: any): Database {\n return new DatabaseImpl(dbName, opts)\n}\n\n// we have to use a callback for this so that we can close\n// the DB when we're done, without this manual requests would\n// need to close the database when done with it to avoid memory leaks\nexport async function doWithDB(dbName: string, cb: any, opts = {}) {\n const db = getDB(dbName, opts)\n // need this to be async so that we can correctly close DB after all\n // async operations have been completed\n return await cb(db)\n}\n\nexport function allDbs() {\n if (!env.isTest()) {\n throw new Error(\"Cannot be used outside test environment.\")\n }\n return [...dbList]\n}\n\nexport async function directCouchAllDbs(queryString?: string) {\n let couchPath = \"/_all_dbs\"\n if (queryString) {\n couchPath += `?${queryString}`\n }\n return await directCouchQuery(couchPath)\n}\n\nexport async function directCouchFind(dbName: string, opts: CouchFindOptions) {\n const json = await directCouchQuery(`${dbName}/_find`, \"POST\", opts)\n return { rows: json.docs, bookmark: json.bookmark }\n}\n", "// some test cases call functions directly, need to\n// store an app ID to pretend there is a context\nimport env from \"../environment\"\nimport Context from \"./Context\"\nimport * as conversions from \"../docIds/conversions\"\nimport { getDB } from \"../db/db\"\nimport {\n DocumentType,\n SEPARATOR,\n StaticDatabases,\n DEFAULT_TENANT_ID,\n} from \"../constants\"\nimport { Database, IdentityContext } from \"@budibase/types\"\nimport { ContextMap } from \"./types\"\n\nlet TEST_APP_ID: string | null = null\n\nexport function getGlobalDBName(tenantId?: string) {\n // tenant ID can be set externally, for example user API where\n // new tenants are being created, this may be the case\n if (!tenantId) {\n tenantId = getTenantId()\n }\n return baseGlobalDBName(tenantId)\n}\n\nexport function getAuditLogDBName(tenantId?: string) {\n if (!tenantId) {\n tenantId = getTenantId()\n }\n if (tenantId === DEFAULT_TENANT_ID) {\n return StaticDatabases.AUDIT_LOGS.name\n } else {\n return `${tenantId}${SEPARATOR}${StaticDatabases.AUDIT_LOGS.name}`\n }\n}\n\nexport function baseGlobalDBName(tenantId: string | undefined | null) {\n if (!tenantId || tenantId === DEFAULT_TENANT_ID) {\n return StaticDatabases.GLOBAL.name\n } else {\n return `${tenantId}${SEPARATOR}${StaticDatabases.GLOBAL.name}`\n }\n}\n\nexport function getPlatformURL() {\n return env.PLATFORM_URL\n}\n\nexport function isMultiTenant() {\n return !!env.MULTI_TENANCY\n}\n\nexport function isTenantIdSet() {\n const context = Context.get()\n return !!context?.tenantId\n}\n\nexport function isTenancyEnabled() {\n return env.MULTI_TENANCY\n}\n\n/**\n * Given an app ID this will attempt to retrieve the tenant ID from it.\n * @return {null|string} The tenant ID found within the app ID.\n */\nexport function getTenantIDFromAppID(appId: string) {\n if (!appId) {\n return undefined\n }\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n const split = appId.split(SEPARATOR)\n const hasDev = split[1] === DocumentType.DEV\n if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) {\n return undefined\n }\n if (hasDev) {\n return split[2]\n } else {\n return split[1]\n }\n}\n\nfunction updateContext(updates: ContextMap): ContextMap {\n let context: ContextMap\n try {\n context = Context.get()\n } catch (err) {\n // no context, start empty\n context = {}\n }\n context = {\n ...context,\n ...updates,\n }\n return context\n}\n\nasync function newContext(updates: ContextMap, task: any) {\n // see if there already is a context setup\n let context: ContextMap = updateContext(updates)\n return Context.run(context, task)\n}\n\nexport async function doInAutomationContext(params: {\n appId: string\n automationId: string\n task: any\n}): Promise<any> {\n const tenantId = getTenantIDFromAppID(params.appId)\n return newContext(\n {\n tenantId,\n appId: params.appId,\n automationId: params.automationId,\n },\n params.task\n )\n}\n\nexport async function doInContext(appId: string, task: any): Promise<any> {\n const tenantId = getTenantIDFromAppID(appId)\n return newContext(\n {\n tenantId,\n appId,\n },\n task\n )\n}\n\nexport async function doInTenant<T>(\n tenantId: string | null,\n task: () => T\n): Promise<T> {\n // make sure default always selected in single tenancy\n if (!env.MULTI_TENANCY) {\n tenantId = tenantId || DEFAULT_TENANT_ID\n }\n\n const updates = tenantId ? { tenantId } : {}\n return newContext(updates, task)\n}\n\nexport async function doInAppContext(\n appId: string | null,\n task: any\n): Promise<any> {\n if (!appId && !env.isTest()) {\n throw new Error(\"appId is required\")\n }\n\n let updates: ContextMap\n if (!appId) {\n updates = { appId: \"\" }\n } else {\n const tenantId = getTenantIDFromAppID(appId)\n updates = { appId }\n if (tenantId) {\n updates.tenantId = tenantId\n }\n }\n return newContext(updates, task)\n}\n\nexport async function doInIdentityContext(\n identity: IdentityContext,\n task: any\n): Promise<any> {\n if (!identity) {\n throw new Error(\"identity is required\")\n }\n\n const context: ContextMap = {\n identity,\n }\n if (identity.tenantId) {\n context.tenantId = identity.tenantId\n }\n return newContext(context, task)\n}\n\nexport function getIdentity(): IdentityContext | undefined {\n try {\n const context = Context.get()\n return context?.identity\n } catch (e) {\n // do nothing - identity is not in context\n }\n}\n\nexport function getTenantId(): string {\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n const context = Context.get()\n const tenantId = context?.tenantId\n if (!tenantId) {\n throw new Error(\"Tenant id not found\")\n }\n return tenantId\n}\n\nexport function getAutomationId(): string | undefined {\n const context = Context.get()\n return context?.automationId\n}\n\nexport function getAppId(): string | undefined {\n const context = Context.get()\n const foundId = context?.appId\n if (!foundId && env.isTest() && TEST_APP_ID) {\n return TEST_APP_ID\n } else {\n return foundId\n }\n}\n\nexport const getProdAppId = () => {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Could not get appId\")\n }\n return conversions.getProdAppID(appId)\n}\n\nexport function doInEnvironmentContext(\n values: Record<string, string>,\n task: any\n) {\n if (!values) {\n throw new Error(\"Must supply environment variables.\")\n }\n const updates = {\n environmentVariables: values,\n }\n return newContext(updates, task)\n}\n\nexport function doInScimContext(task: any) {\n const updates: ContextMap = {\n isScim: true,\n }\n return newContext(updates, task)\n}\n\nexport function getEnvironmentVariables() {\n const context = Context.get()\n if (!context.environmentVariables) {\n return null\n } else {\n return context.environmentVariables\n }\n}\n\nexport function getGlobalDB(): Database {\n const context = Context.get()\n if (!context || (env.MULTI_TENANCY && !context.tenantId)) {\n throw new Error(\"Global DB not found\")\n }\n return getDB(baseGlobalDBName(context?.tenantId))\n}\n\nexport function getAuditLogsDB(): Database {\n if (!getTenantId()) {\n throw new Error(\"No tenant ID found - cannot open audit log DB\")\n }\n return getDB(getAuditLogDBName())\n}\n\n/**\n * Gets the app database based on whatever the request\n * contained, dev or prod.\n */\nexport function getAppDB(opts?: any): Database {\n const appId = getAppId()\n return getDB(appId, opts)\n}\n\n/**\n * This specifically gets the prod app ID, if the request\n * contained a development app ID, this will get the prod one.\n */\nexport function getProdAppDB(opts?: any): Database {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Unable to retrieve prod DB - no app ID.\")\n }\n return getDB(conversions.getProdAppID(appId), opts)\n}\n\n/**\n * This specifically gets the dev app ID, if the request\n * contained a prod app ID, this will get the dev one.\n */\nexport function getDevAppDB(opts?: any): Database {\n const appId = getAppId()\n if (!appId) {\n throw new Error(\"Unable to retrieve dev DB - no app ID.\")\n }\n return getDB(conversions.getDevelopmentAppID(appId), opts)\n}\n\nexport function isScim(): boolean {\n const context = Context.get()\n const scimCall = context?.isScim\n return !!scimCall\n}\n", "export { DEFAULT_TENANT_ID } from \"../constants\"\nexport * as identity from \"./identity\"\nexport * from \"./mainContext\"\n", "import env from \"../environment\"\n\nconst SLOT_REFRESH_MS = 2000\nconst CONNECT_TIMEOUT_MS = 10000\nexport const SEPARATOR = \"-\"\n\n/**\n * These Redis databases help us to segment up a Redis keyspace by prepending the\n * specified database name onto the cache key. This means that a single real Redis database\n * can be split up a bit; allowing us to use scans on small databases to find some particular\n * keys within.\n * If writing a very large volume of keys is expected (say 10K+) then it is better to keep these out\n * of the default keyspace and use a separate one - the SelectableDatabase can be used for this.\n */\nexport enum Databases {\n PW_RESETS = \"pwReset\",\n VERIFICATIONS = \"verification\",\n INVITATIONS = \"invitation\",\n DEV_LOCKS = \"devLocks\",\n DEBOUNCE = \"debounce\",\n SESSIONS = \"session\",\n USER_CACHE = \"users\",\n FLAGS = \"flags\",\n APP_METADATA = \"appMetadata\",\n QUERY_VARS = \"queryVars\",\n LICENSES = \"license\",\n GENERIC_CACHE = \"data_cache\",\n WRITE_THROUGH = \"writeThrough\",\n LOCKS = \"locks\",\n}\n\n/**\n * These define the numeric Redis databases that can be access with the SELECT command -\n * (https://redis.io/commands/select/). By default a Redis server/cluster will have 16 selectable\n * databases, increasing this count increases the amount of CPU/memory required to run the server.\n * Ideally new Redis keyspaces should be used sparingly, only when absolutely necessary for performance\n * to be maintained. Generally a keyspace can grow to be very large is scans are not needed or desired,\n * but if you need to walk through all values in a database periodically then a separate selectable\n * keyspace should be used.\n */\nexport enum SelectableDatabase {\n DEFAULT = 0,\n WRITE_THROUGH = 1,\n UNUSED_1 = 2,\n UNUSED_2 = 3,\n UNUSED_3 = 4,\n UNUSED_4 = 5,\n UNUSED_5 = 6,\n UNUSED_6 = 7,\n UNUSED_7 = 8,\n UNUSED_8 = 9,\n UNUSED_9 = 10,\n UNUSED_10 = 11,\n UNUSED_11 = 12,\n UNUSED_12 = 13,\n UNUSED_13 = 14,\n UNUSED_14 = 15,\n}\n\nexport function getRedisOptions() {\n let password = env.REDIS_PASSWORD\n let url: string[] | string = env.REDIS_URL.split(\"//\")\n // get rid of the protocol\n url = url.length > 1 ? url[1] : url[0]\n // check for a password etc\n url = url.split(\"@\")\n if (url.length > 1) {\n // get the password\n password = url[0].split(\":\")[1]\n url = url[1]\n } else {\n url = url[0]\n }\n const [host, port] = url.split(\":\")\n\n let redisProtocolUrl\n\n // fully qualified redis URL\n if (/rediss?:\\/\\//.test(env.REDIS_URL)) {\n redisProtocolUrl = env.REDIS_URL\n }\n\n const opts: any = {\n connectTimeout: CONNECT_TIMEOUT_MS,\n }\n if (env.REDIS_CLUSTERED) {\n opts.redisOptions = {}\n opts.redisOptions.tls = {}\n opts.redisOptions.password = password\n opts.slotsRefreshTimeout = SLOT_REFRESH_MS\n opts.dnsLookup = (address: string, callback: any) => callback(null, address)\n } else {\n opts.host = host\n opts.port = port\n opts.password = password\n }\n return { opts, host, port, redisProtocolUrl }\n}\n\nexport function addDbPrefix(db: string, key: string) {\n if (key.includes(db)) {\n return key\n }\n return `${db}${SEPARATOR}${key}`\n}\n\nexport function removeDbPrefix(key: string) {\n let parts = key.split(SEPARATOR)\n if (parts.length >= 2) {\n parts.shift()\n return parts.join(SEPARATOR)\n } else {\n // return the only part\n return parts[0]\n }\n}\n", "let intervals: NodeJS.Timeout[] = []\n\nexport function set(callback: () => any, period: number) {\n const interval = setInterval(callback, period)\n intervals.push(interval)\n return interval\n}\n\nexport function clear(interval: NodeJS.Timeout) {\n const idx = intervals.indexOf(interval)\n if (idx !== -1) {\n intervals.splice(idx, 1)\n }\n clearInterval(interval)\n}\n\nexport function cleanup() {\n for (let interval of intervals) {\n clearInterval(interval)\n }\n intervals = []\n}\n", "export * from \"./timers\"\n", "import env from \"../environment\"\n// ioredis mock is all in memory\nconst Redis = env.MOCK_REDIS ? require(\"ioredis-mock\") : require(\"ioredis\")\nimport {\n addDbPrefix,\n removeDbPrefix,\n getRedisOptions,\n SEPARATOR,\n SelectableDatabase,\n} from \"./utils\"\nimport * as timers from \"../timers\"\n\nconst RETRY_PERIOD_MS = 2000\nconst STARTUP_TIMEOUT_MS = 5000\nconst CLUSTERED = env.REDIS_CLUSTERED\nconst DEFAULT_SELECT_DB = SelectableDatabase.DEFAULT\n\n// for testing just generate the client once\nlet CLOSED = false\nlet CLIENTS: { [key: number]: any } = {}\n\nlet CONNECTED = false\n\n// mock redis always connected\nif (env.MOCK_REDIS) {\n CONNECTED = true\n}\n\nfunction pickClient(selectDb: number): any {\n return CLIENTS[selectDb]\n}\n\nfunction connectionError(\n selectDb: number,\n timeout: NodeJS.Timeout,\n err: Error | string\n) {\n // manually shut down, ignore errors\n if (CLOSED) {\n return\n }\n pickClient(selectDb).disconnect()\n CLOSED = true\n // always clear this on error\n clearTimeout(timeout)\n CONNECTED = false\n console.error(\"Redis connection failed - \" + err)\n setTimeout(() => {\n init()\n }, RETRY_PERIOD_MS)\n}\n\n/**\n * Inits the system, will error if unable to connect to redis cluster (may take up to 10 seconds) otherwise\n * will return the ioredis client which will be ready to use.\n */\nfunction init(selectDb = DEFAULT_SELECT_DB) {\n let timeout: NodeJS.Timeout\n CLOSED = false\n let client = pickClient(selectDb)\n // already connected, ignore\n if (client && CONNECTED) {\n return\n }\n // testing uses a single in memory client\n if (env.MOCK_REDIS) {\n CLIENTS[selectDb] = new Redis(getRedisOptions())\n }\n // start the timer - only allowed 5 seconds to connect\n timeout = setTimeout(() => {\n if (!CONNECTED) {\n connectionError(\n selectDb,\n timeout,\n \"Did not successfully connect in timeout\"\n )\n }\n }, STARTUP_TIMEOUT_MS)\n\n // disconnect any lingering client\n if (client) {\n client.disconnect()\n }\n const { redisProtocolUrl, opts, host, port } = getRedisOptions()\n\n if (CLUSTERED) {\n client = new Redis.Cluster([{ host, port }], opts)\n } else if (redisProtocolUrl) {\n client = new Redis(redisProtocolUrl)\n } else {\n client = new Redis(opts)\n }\n // attach handlers\n client.on(\"end\", (err: Error) => {\n if (env.isTest()) {\n // don't try to re-connect in test env\n // allow the process to exit\n return\n }\n connectionError(selectDb, timeout, err)\n })\n client.on(\"error\", (err: Error) => {\n connectionError(selectDb, timeout, err)\n })\n client.on(\"connect\", () => {\n clearTimeout(timeout)\n CONNECTED = true\n })\n CLIENTS[selectDb] = client\n}\n\nfunction waitForConnection(selectDb: number = DEFAULT_SELECT_DB) {\n return new Promise(resolve => {\n if (pickClient(selectDb) == null) {\n init()\n } else if (CONNECTED) {\n resolve(\"\")\n return\n }\n // check if the connection is ready\n const interval = timers.set(() => {\n if (CONNECTED) {\n timers.clear(interval)\n resolve(\"\")\n }\n }, 500)\n })\n}\n\n/**\n * Utility function, takes a redis stream and converts it to a promisified response -\n * this can only be done with redis streams because they will have an end.\n * @param stream A redis stream, specifically as this type of stream will have an end.\n * @param client The client to use for further lookups.\n * @return {Promise<object>} The final output of the stream\n */\nfunction promisifyStream(stream: any, client: RedisWrapper) {\n return new Promise((resolve, reject) => {\n const outputKeys = new Set()\n stream.on(\"data\", (keys: string[]) => {\n keys.forEach(key => {\n outputKeys.add(key)\n })\n })\n stream.on(\"error\", (err: Error) => {\n reject(err)\n })\n stream.on(\"end\", async () => {\n const keysArray: string[] = Array.from(outputKeys) as string[]\n try {\n let getPromises = []\n for (let key of keysArray) {\n getPromises.push(client.get(key))\n }\n const jsonArray = await Promise.all(getPromises)\n resolve(\n keysArray.map(key => ({\n key: removeDbPrefix(key),\n value: JSON.parse(jsonArray.shift()),\n }))\n )\n } catch (err) {\n reject(err)\n }\n })\n })\n}\n\nclass RedisWrapper {\n _db: string\n _select: number\n\n constructor(db: string, selectDb: number | null = null) {\n this._db = db\n this._select = selectDb || DEFAULT_SELECT_DB\n }\n\n getClient() {\n return pickClient(this._select)\n }\n\n async init() {\n CLOSED = false\n init(this._select)\n await waitForConnection(this._select)\n return this\n }\n\n async finish() {\n CLOSED = true\n this.getClient().disconnect()\n }\n\n async scan(key = \"\"): Promise<any> {\n const db = this._db\n key = `${db}${SEPARATOR}${key}`\n let stream\n if (CLUSTERED) {\n let node = this.getClient().nodes(\"master\")\n stream = node[0].scanStream({ match: key + \"*\", count: 100 })\n } else {\n stream = this.getClient().scanStream({ match: key + \"*\", count: 100 })\n }\n return promisifyStream(stream, this.getClient())\n }\n\n async keys(pattern: string) {\n const db = this._db\n return this.getClient().keys(addDbPrefix(db, pattern))\n }\n\n async get(key: string) {\n const db = this._db\n let response = await this.getClient().get(addDbPrefix(db, key))\n // overwrite the prefixed key\n if (response != null && response.key) {\n response.key = key\n }\n // if its not an object just return the response\n try {\n return JSON.parse(response)\n } catch (err) {\n return response\n }\n }\n\n async bulkGet(keys: string[]) {\n const db = this._db\n if (keys.length === 0) {\n return {}\n }\n const prefixedKeys = keys.map(key => addDbPrefix(db, key))\n let response = await this.getClient().mget(prefixedKeys)\n if (Array.isArray(response)) {\n let final: any = {}\n let count = 0\n for (let result of response) {\n if (result) {\n let parsed\n try {\n parsed = JSON.parse(result)\n } catch (err) {\n parsed = result\n }\n final[keys[count]] = parsed\n }\n count++\n }\n return final\n } else {\n throw new Error(`Invalid response: ${response}`)\n }\n }\n\n async store(key: string, value: any, expirySeconds: number | null = null) {\n const db = this._db\n if (typeof value === \"object\") {\n value = JSON.stringify(value)\n }\n const prefixedKey = addDbPrefix(db, key)\n await this.getClient().set(prefixedKey, value)\n if (expirySeconds) {\n await this.getClient().expire(prefixedKey, expirySeconds)\n }\n }\n\n async getTTL(key: string) {\n const db = this._db\n const prefixedKey = addDbPrefix(db, key)\n return this.getClient().ttl(prefixedKey)\n }\n\n async setExpiry(key: string, expirySeconds: number | null) {\n const db = this._db\n const prefixedKey = addDbPrefix(db, key)\n await this.getClient().expire(prefixedKey, expirySeconds)\n }\n\n async delete(key: string) {\n const db = this._db\n await this.getClient().del(addDbPrefix(db, key))\n }\n\n async clear() {\n let items = await this.scan()\n await Promise.all(items.map((obj: any) => this.delete(obj.key)))\n }\n}\n\nexport default RedisWrapper\n", "import Client from \"./redis\"\nimport * as utils from \"./utils\"\n\nlet userClient: Client,\n sessionClient: Client,\n appClient: Client,\n cacheClient: Client,\n writethroughClient: Client,\n lockClient: Client\n\nasync function init() {\n userClient = await new Client(utils.Databases.USER_CACHE).init()\n sessionClient = await new Client(utils.Databases.SESSIONS).init()\n appClient = await new Client(utils.Databases.APP_METADATA).init()\n cacheClient = await new Client(utils.Databases.GENERIC_CACHE).init()\n lockClient = await new Client(utils.Databases.LOCKS).init()\n writethroughClient = await new Client(\n utils.Databases.WRITE_THROUGH,\n utils.SelectableDatabase.WRITE_THROUGH\n ).init()\n}\n\nexport async function shutdown() {\n if (userClient) await userClient.finish()\n if (sessionClient) await sessionClient.finish()\n if (appClient) await appClient.finish()\n if (cacheClient) await cacheClient.finish()\n if (writethroughClient) await writethroughClient.finish()\n if (lockClient) await lockClient.finish()\n}\n\nprocess.on(\"exit\", async () => {\n await shutdown()\n})\n\nexport async function getUserClient() {\n if (!userClient) {\n await init()\n }\n return userClient\n}\n\nexport async function getSessionClient() {\n if (!sessionClient) {\n await init()\n }\n return sessionClient\n}\n\nexport async function getAppClient() {\n if (!appClient) {\n await init()\n }\n return appClient\n}\n\nexport async function getCacheClient() {\n if (!cacheClient) {\n await init()\n }\n return cacheClient\n}\n\nexport async function getWritethroughClient() {\n if (!writethroughClient) {\n await init()\n }\n return writethroughClient\n}\n\nexport async function getLockClient() {\n if (!lockClient) {\n await init()\n }\n return lockClient\n}\n", "import { getTenantId } from \"../../context\"\nimport * as redis from \"../../redis/init\"\nimport { Client } from \"../../redis\"\n\nfunction generateTenantKey(key: string) {\n const tenantId = getTenantId()\n return `${key}:${tenantId}`\n}\n\nexport default class BaseCache {\n client: Client | undefined\n\n constructor(client: Client | undefined = undefined) {\n this.client = client\n }\n\n async getClient() {\n return !this.client ? await redis.getCacheClient() : this.client\n }\n\n async keys(pattern: string) {\n const client = await this.getClient()\n return client.keys(pattern)\n }\n\n /**\n * Read only from the cache.\n */\n async get(key: string, opts = { useTenancy: true }) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n return client.get(key)\n }\n\n /**\n * Write to the cache.\n */\n async store(\n key: string,\n value: any,\n ttl: number | null = null,\n opts = { useTenancy: true }\n ) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n await client.store(key, value, ttl)\n }\n\n /**\n * Remove from cache.\n */\n async delete(key: string, opts = { useTenancy: true }) {\n key = opts.useTenancy ? generateTenantKey(key) : key\n const client = await this.getClient()\n return client.delete(key)\n }\n\n /**\n * Read from the cache. Write to the cache if not exists.\n */\n async withCache(\n key: string,\n ttl: number,\n fetchFn: any,\n opts = { useTenancy: true }\n ) {\n const cachedValue = await this.get(key, opts)\n if (cachedValue) {\n return cachedValue\n }\n\n try {\n const fetchedValue = await fetchFn()\n\n await this.store(key, fetchedValue, ttl, opts)\n return fetchedValue\n } catch (err) {\n console.error(\"Error fetching before cache - \", err)\n throw err\n }\n }\n\n async bustCache(key: string, opts = { client: null }) {\n const client = await this.getClient()\n try {\n await client.delete(generateTenantKey(key))\n } catch (err) {\n console.error(\"Error busting cache - \", err)\n throw err\n }\n }\n}\n", "const BaseCache = require(\"./base\")\n\nconst GENERIC = new BaseCache.default()\n\nexport enum CacheKey {\n CHECKLIST = \"checklist\",\n INSTALLATION = \"installation\",\n ANALYTICS_ENABLED = \"analyticsEnabled\",\n UNIQUE_TENANT_ID = \"uniqueTenantId\",\n EVENTS = \"events\",\n BACKFILL_METADATA = \"backfillMetadata\",\n EVENTS_RATE_LIMIT = \"eventsRateLimit\",\n}\n\nexport enum TTL {\n ONE_MINUTE = 600,\n ONE_HOUR = 3600,\n ONE_DAY = 86400,\n}\n\nfunction performExport(funcName: string) {\n return (...args: any) => GENERIC[funcName](...args)\n}\n\nexport const keys = performExport(\"keys\")\nexport const get = performExport(\"get\")\nexport const store = performExport(\"store\")\nexport const destroy = performExport(\"delete\")\nexport const withCache = performExport(\"withCache\")\nexport const bustCache = performExport(\"bustCache\")\n", "import { getDB } from \"../db/db\"\nimport { getGlobalDBName } from \"../context\"\n\nexport function getTenantDB(tenantId: string) {\n return getDB(getGlobalDBName(tenantId))\n}\n", "import {\n DEFAULT_TENANT_ID,\n getTenantId,\n getTenantIDFromAppID,\n isMultiTenant,\n getPlatformURL,\n} from \"../context\"\nimport {\n BBContext,\n TenantResolutionStrategy,\n GetTenantIdOptions,\n} from \"@budibase/types\"\nimport { Header } from \"../constants\"\n\nexport function addTenantToUrl(url: string) {\n const tenantId = getTenantId()\n\n if (isMultiTenant()) {\n const char = url.indexOf(\"?\") === -1 ? \"?\" : \"&\"\n url += `${char}tenantId=${tenantId}`\n }\n\n return url\n}\n\nexport const isUserInAppTenant = (appId: string, user?: any) => {\n let userTenantId\n if (user) {\n userTenantId = user.tenantId || DEFAULT_TENANT_ID\n } else {\n userTenantId = getTenantId()\n }\n const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID\n return tenantId === userTenantId\n}\n\nconst ALL_STRATEGIES = Object.values(TenantResolutionStrategy)\n\nexport const getTenantIDFromCtx = (\n ctx: BBContext,\n opts: GetTenantIdOptions\n): string | null => {\n // exit early if not multi-tenant\n if (!isMultiTenant()) {\n return DEFAULT_TENANT_ID\n }\n\n // opt defaults\n if (opts.allowNoTenant === undefined) {\n opts.allowNoTenant = false\n }\n if (!opts.includeStrategies) {\n opts.includeStrategies = ALL_STRATEGIES\n }\n if (!opts.excludeStrategies) {\n opts.excludeStrategies = []\n }\n\n const isAllowed = (strategy: TenantResolutionStrategy) => {\n // excluded takes precedence\n if (opts.excludeStrategies?.includes(strategy)) {\n return false\n }\n if (opts.includeStrategies?.includes(strategy)) {\n return true\n }\n }\n\n // always use user first\n if (isAllowed(TenantResolutionStrategy.USER)) {\n const userTenantId = ctx.user?.tenantId\n if (userTenantId) {\n return userTenantId\n }\n }\n\n // header\n if (isAllowed(TenantResolutionStrategy.HEADER)) {\n const headerTenantId = ctx.request.headers[Header.TENANT_ID]\n if (headerTenantId) {\n return headerTenantId as string\n }\n }\n\n // query param\n if (isAllowed(TenantResolutionStrategy.QUERY)) {\n const queryTenantId = ctx.request.query.tenantId\n if (queryTenantId) {\n return queryTenantId as string\n }\n }\n\n // subdomain\n if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) {\n // e.g. budibase.app or local.com:10000\n const platformHost = new URL(getPlatformURL()).host.split(\":\")[0]\n // e.g. tenant.budibase.app or tenant.local.com\n const requestHost = ctx.host\n // parse the tenant id from the difference\n if (requestHost.includes(platformHost)) {\n const tenantId = requestHost.substring(\n 0,\n requestHost.indexOf(`.${platformHost}`)\n )\n if (tenantId) {\n return tenantId\n }\n }\n }\n\n // path\n if (isAllowed(TenantResolutionStrategy.PATH)) {\n // params - have to parse manually due to koa-router not run yet\n const match = ctx.matched.find(\n (m: any) => !!m.paramNames.find((p: any) => p.name === \"tenantId\")\n )\n\n // get the raw path url - without any query params\n const ctxUrl = ctx.originalUrl\n let url\n if (ctxUrl.includes(\"?\")) {\n url = ctxUrl.split(\"?\")[0]\n } else {\n url = ctxUrl\n }\n\n if (match) {\n const params = match.params(url, match.captures(url), {})\n if (params.tenantId) {\n return params.tenantId\n }\n }\n }\n\n if (!opts.allowNoTenant) {\n ctx.throw(403, \"Tenant id not set\")\n }\n\n return null\n}\n", "export * from \"./db\"\nexport * from \"./tenancy\"\n", "import { StaticDatabases } from \"../constants\"\nimport { getDB } from \"../db/db\"\n\nexport function getPlatformDB() {\n return getDB(StaticDatabases.PLATFORM_INFO.name)\n}\n", "import { getPlatformDB } from \"./platformDb\"\nimport { DEFAULT_TENANT_ID } from \"../constants\"\nimport env from \"../environment\"\nimport {\n PlatformUser,\n PlatformUserByEmail,\n PlatformUserById,\n User,\n} from \"@budibase/types\"\n\n// READ\n\nexport async function lookupTenantId(userId: string) {\n if (!env.MULTI_TENANCY) {\n return DEFAULT_TENANT_ID\n }\n\n const user = await getUserDoc(userId)\n return user.tenantId\n}\n\nasync function getUserDoc(emailOrId: string): Promise<PlatformUser> {\n const db = getPlatformDB()\n return db.get(emailOrId)\n}\n\n// CREATE\n\nfunction newUserIdDoc(id: string, tenantId: string): PlatformUserById {\n return {\n _id: id,\n tenantId,\n }\n}\n\nfunction newUserEmailDoc(\n userId: string,\n email: string,\n tenantId: string\n): PlatformUserByEmail {\n return {\n _id: email,\n userId,\n tenantId,\n }\n}\n\n/**\n * Add a new user id or email doc if it doesn't exist.\n */\nasync function addUserDoc(emailOrId: string, newDocFn: () => PlatformUser) {\n const db = getPlatformDB()\n let user: PlatformUser\n\n try {\n await db.get(emailOrId)\n } catch (e: any) {\n if (e.status === 404) {\n user = newDocFn()\n await db.put(user)\n } else {\n throw e\n }\n }\n}\n\nexport async function addUser(tenantId: string, userId: string, email: string) {\n await Promise.all([\n addUserDoc(userId, () => newUserIdDoc(userId, tenantId)),\n addUserDoc(email, () => newUserEmailDoc(userId, email, tenantId)),\n ])\n}\n\n// DELETE\n\nexport async function removeUser(user: User) {\n const db = getPlatformDB()\n const keys = [user._id!, user.email]\n const userDocs = await db.allDocs({\n keys,\n include_docs: true,\n })\n const toDelete = userDocs.rows.map((row: any) => {\n return {\n ...row.doc,\n _deleted: true,\n }\n })\n await db.bulkDocs(toDelete)\n}\n", "import Redlock from \"redlock\"\nimport { getLockClient } from \"./init\"\nimport { LockOptions, LockType } from \"@budibase/types\"\nimport * as context from \"../context\"\nimport env from \"../environment\"\n\nconst getClient = async (\n type: LockType,\n opts?: Redlock.Options\n): Promise<Redlock> => {\n if (type === LockType.CUSTOM) {\n return newRedlock(opts)\n }\n if (env.isTest() && type !== LockType.TRY_ONCE) {\n return newRedlock(OPTIONS.TEST)\n }\n switch (type) {\n case LockType.TRY_ONCE: {\n return newRedlock(OPTIONS.TRY_ONCE)\n }\n case LockType.DEFAULT: {\n return newRedlock(OPTIONS.DEFAULT)\n }\n case LockType.DELAY_500: {\n return newRedlock(OPTIONS.DELAY_500)\n }\n default: {\n throw new Error(`Could not get redlock client: ${type}`)\n }\n }\n}\n\nconst OPTIONS = {\n TRY_ONCE: {\n // immediately throws an error if the lock is already held\n retryCount: 0,\n },\n TEST: {\n // higher retry count in unit tests\n // due to high contention.\n retryCount: 100,\n },\n DEFAULT: {\n // the expected clock drift; for more details\n // see http://redis.io/topics/distlock\n driftFactor: 0.01, // multiplied by lock ttl to determine drift time\n\n // the max number of times Redlock will attempt\n // to lock a resource before erroring\n retryCount: 10,\n\n // the time in ms between attempts\n retryDelay: 200, // time in ms\n\n // the max time in ms randomly added to retries\n // to improve performance under high contention\n // see https://www.awsarchitectureblog.com/2015/03/backoff.html\n retryJitter: 100, // time in ms\n },\n DELAY_500: {\n retryDelay: 500,\n },\n}\n\nconst newRedlock = async (opts: Redlock.Options = {}) => {\n let options = { ...OPTIONS.DEFAULT, ...opts }\n const redisWrapper = await getLockClient()\n const client = redisWrapper.getClient()\n return new Redlock([client], options)\n}\n\ntype SuccessfulRedlockExecution<T> = {\n executed: true\n result: T\n}\ntype UnsuccessfulRedlockExecution = {\n executed: false\n}\n\ntype RedlockExecution<T> =\n | SuccessfulRedlockExecution<T>\n | UnsuccessfulRedlockExecution\n\nexport const doWithLock = async <T>(\n opts: LockOptions,\n task: () => Promise<T>\n): Promise<RedlockExecution<T>> => {\n const redlock = await getClient(opts.type, opts.customOptions)\n let lock\n try {\n // determine lock name\n // by default use the tenantId for uniqueness, unless using a system lock\n const prefix = opts.systemLock ? \"system\" : context.getTenantId()\n let name: string = `lock:${prefix}_${opts.name}`\n\n // add additional unique name if required\n if (opts.resource) {\n name = name + `_${opts.resource}`\n }\n\n // create the lock\n lock = await redlock.lock(name, opts.ttl)\n\n // perform locked task\n // need to await to ensure completion before unlocking\n const result = await task()\n return { executed: true, result }\n } catch (e: any) {\n console.warn(\"lock error\")\n // lock limit exceeded\n if (e.name === \"LockError\") {\n if (opts.type === LockType.TRY_ONCE) {\n // don't throw for try-once locks, they will always error\n // due to retry count (0) exceeded\n console.warn(e)\n return { executed: false }\n } else {\n console.error(e)\n throw e\n }\n } else {\n console.error(e)\n throw e\n }\n } finally {\n if (lock) {\n await lock.unlock()\n }\n }\n}\n", "import { StaticDatabases } from \"../constants\"\nimport { getPlatformDB } from \"./platformDb\"\nimport { LockName, LockOptions, LockType, Tenants } from \"@budibase/types\"\nimport * as locks from \"../redis/redlockImpl\"\n\nconst TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants\n\nexport const tenacyLockOptions: LockOptions = {\n type: LockType.DEFAULT,\n name: LockName.UPDATE_TENANTS_DOC,\n ttl: 10 * 1000, // auto expire after 10 seconds\n systemLock: true,\n}\n\n// READ\n\nexport async function getTenantIds(): Promise<string[]> {\n const tenants = await getTenants()\n return tenants.tenantIds\n}\n\nasync function getTenants(): Promise<Tenants> {\n const db = getPlatformDB()\n let tenants: Tenants\n\n try {\n tenants = await db.get(TENANT_DOC)\n } catch (e: any) {\n // doesn't exist yet - create\n if (e.status === 404) {\n tenants = await createTenantsDoc()\n } else {\n throw e\n }\n }\n\n return tenants\n}\n\nexport async function exists(tenantId: string) {\n const tenants = await getTenants()\n return tenants.tenantIds.indexOf(tenantId) !== -1\n}\n\n// CREATE / UPDATE\n\nfunction newTenantsDoc(): Tenants {\n return {\n _id: TENANT_DOC,\n tenantIds: [],\n }\n}\n\nasync function createTenantsDoc(): Promise<Tenants> {\n const db = getPlatformDB()\n let tenants = newTenantsDoc()\n\n try {\n const response = await db.put(tenants)\n tenants._rev = response.rev\n } catch (e: any) {\n // don't throw 409 is doc has already been created\n if (e.status === 409) {\n return db.get(TENANT_DOC)\n }\n throw e\n }\n\n return tenants\n}\n\nexport async function addTenant(tenantId: string) {\n const db = getPlatformDB()\n\n // use a lock as tenant creation is conflict prone\n await locks.doWithLock(tenacyLockOptions, async () => {\n const tenants = await getTenants()\n\n // write the new tenant if it doesn't already exist\n if (tenants.tenantIds.indexOf(tenantId) === -1) {\n tenants.tenantIds.push(tenantId)\n await db.put(tenants)\n }\n })\n}\n\n// DELETE\n\nexport async function removeTenant(tenantId: string) {\n try {\n await locks.doWithLock(tenacyLockOptions, async () => {\n const db = getPlatformDB()\n const tenants = await getTenants()\n tenants.tenantIds = tenants.tenantIds.filter(id => id !== tenantId)\n await db.put(tenants)\n })\n } catch (err) {\n console.error(`Error removing tenant ${tenantId} from info db`, err)\n throw err\n }\n}\n", "export * as users from \"./users\"\nexport * as tenants from \"./tenants\"\nexport * from \"./platformDb\"\n", "import { Header } from \"../../constants\"\nconst correlator = require(\"correlation-id\")\n\nexport const setHeader = (headers: any) => {\n const correlationId = correlator.getId()\n if (correlationId) {\n headers[Header.CORRELATION_ID] = correlationId\n }\n}\n\nexport function getId() {\n return correlator.getId()\n}\n", "export * from \"./correlation\"\n", "import env from \"../../environment\"\nimport pino, { LoggerOptions } from \"pino\"\nimport * as context from \"../../context\"\nimport * as correlation from \"../correlation\"\nimport { IdentityType } from \"@budibase/types\"\nimport { LOG_CONTEXT } from \"../index\"\n\n// LOGGER\n\nlet pinoInstance: pino.Logger | undefined\nif (!env.DISABLE_PINO_LOGGER) {\n const pinoOptions: LoggerOptions = {\n level: env.LOG_LEVEL,\n formatters: {\n level: label => {\n return { level: label.toUpperCase() }\n },\n bindings: () => {\n return {}\n },\n },\n timestamp: () => `,\"timestamp\":\"${new Date(Date.now()).toISOString()}\"`,\n }\n\n if (env.isDev()) {\n pinoOptions.transport = {\n target: \"pino-pretty\",\n options: {\n singleLine: true,\n },\n }\n }\n\n pinoInstance = pino(pinoOptions)\n\n // CONSOLE OVERRIDES\n\n interface MergingObject {\n objects?: any[]\n tenantId?: string\n appId?: string\n automationId?: string\n identityId?: string\n identityType?: IdentityType\n correlationId?: string\n err?: Error\n }\n\n function isPlainObject(obj: any) {\n return typeof obj === \"object\" && obj !== null && !(obj instanceof Error)\n }\n\n function isError(obj: any) {\n return obj instanceof Error\n }\n\n function isMessage(obj: any) {\n return typeof obj === \"string\"\n }\n\n /**\n * Backwards compatibility between console logging statements\n * and pino logging requirements.\n */\n function getLogParams(args: any[]): [MergingObject, string] {\n let error = undefined\n let objects: any[] = []\n let message = \"\"\n\n args.forEach(arg => {\n if (isMessage(arg)) {\n message = `${message} ${arg}`.trimStart()\n }\n if (isPlainObject(arg)) {\n objects.push(arg)\n }\n if (isError(arg)) {\n error = arg\n }\n })\n\n const identity = getIdentity()\n\n let contextObject = {}\n\n if (LOG_CONTEXT) {\n contextObject = {\n tenantId: getTenantId(),\n appId: getAppId(),\n automationId: getAutomationId(),\n identityId: identity?._id,\n identityType: identity?.type,\n correlationId: correlation.getId(),\n }\n }\n\n const mergingObject: any = {\n err: error,\n ...contextObject,\n }\n\n if (objects.length) {\n // init generic data object for params supplied that don't have a\n // '_logKey' field. This prints an object using argument index as the key\n // e.g. { 0: {}, 1: {} }\n const data: any = {}\n let dataIndex = 0\n\n for (let i = 0; i < objects.length; i++) {\n const object = objects[i]\n // the object has specified a log key\n // use this instead of generic key\n const logKey = object._logKey\n if (logKey) {\n delete object._logKey\n mergingObject[logKey] = object\n } else {\n data[dataIndex] = object\n dataIndex++\n }\n }\n\n if (Object.keys(data).length) {\n mergingObject.data = data\n }\n }\n\n return [mergingObject, message]\n }\n\n console.log = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.info(obj, msg)\n }\n console.info = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.info(obj, msg)\n }\n console.warn = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.warn(obj, msg)\n }\n console.error = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.error(obj, msg)\n }\n\n /**\n * custom trace impl - this resembles the node trace behaviour rather\n * than traditional trace logging\n * @param arg\n */\n console.trace = (...arg: any[]) => {\n const [obj, msg] = getLogParams(arg)\n if (!obj.err) {\n // to get stack trace\n obj.err = new Error()\n }\n pinoInstance?.trace(obj, msg)\n }\n\n console.debug = (...arg: any) => {\n const [obj, msg] = getLogParams(arg)\n pinoInstance?.debug(obj, msg)\n }\n\n // CONTEXT\n\n const getTenantId = () => {\n let tenantId\n try {\n tenantId = context.getTenantId()\n } catch (e: any) {\n // do nothing\n }\n return tenantId\n }\n\n const getAppId = () => {\n let appId\n try {\n appId = context.getAppId()\n } catch (e) {\n // do nothing\n }\n return appId\n }\n\n const getAutomationId = () => {\n let appId\n try {\n appId = context.getAutomationId()\n } catch (e) {\n // do nothing\n }\n return appId\n }\n\n const getIdentity = () => {\n let identity\n try {\n identity = context.getIdentity()\n } catch (e) {\n // do nothing\n }\n return identity\n }\n}\n\nexport const logger = pinoInstance\n", "const NonErrors = [\"AccountError\"]\n\nfunction isSuppressed(e?: any) {\n return e && e[\"suppressAlert\"]\n}\n\nexport function logAlert(message: string, e?: any) {\n if (e && NonErrors.includes(e.name) && isSuppressed(e)) {\n return\n }\n console.error(`bb-alert: ${message}`, e)\n}\n\nexport function logAlertWithInfo(\n message: string,\n db: string,\n id: string,\n error: any\n) {\n message = `${message} - db: ${db} - doc: ${id} - error: `\n logAlert(message, error)\n}\n\nexport function logWarn(message: string) {\n console.warn(`bb-warn: ${message}`)\n}\n", "export * as correlation from \"./correlation/correlation\"\nexport { logger } from \"./pino/logger\"\nexport * from \"./alerts\"\n\n// turn off or on context logging i.e. tenantId, appId etc\nexport let LOG_CONTEXT = true\n", "import fetch from \"node-fetch\"\nimport * as logging from \"../logging\"\n\nexport default class API {\n host: string\n\n constructor(host: string) {\n this.host = host\n }\n\n async apiCall(method: string, url: string, options?: any) {\n if (!options.headers) {\n options.headers = {}\n }\n\n if (!options.headers[\"Content-Type\"]) {\n options.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n }\n }\n\n let json = options.headers[\"Content-Type\"] === \"application/json\"\n\n // add x-budibase-correlation-id header\n logging.correlation.setHeader(options.headers)\n\n const requestOptions = {\n method: method,\n body: json ? JSON.stringify(options.body) : options.body,\n headers: options.headers,\n // TODO: See if this is necessary\n credentials: \"include\",\n }\n\n return await fetch(`${this.host}${url}`, requestOptions)\n }\n\n async post(url: string, options?: any) {\n return this.apiCall(\"POST\", url, options)\n }\n\n async get(url: string, options?: any) {\n return this.apiCall(\"GET\", url, options)\n }\n\n async patch(url: string, options?: any) {\n return this.apiCall(\"PATCH\", url, options)\n }\n\n async del(url: string, options?: any) {\n return this.apiCall(\"DELETE\", url, options)\n }\n\n async put(url: string, options?: any) {\n return this.apiCall(\"PUT\", url, options)\n }\n}\n", "import API from \"./api\"\nimport env from \"../environment\"\nimport { Header } from \"../constants\"\nimport { CloudAccount, HealthStatusResponse } from \"@budibase/types\"\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\n/**\n * This client is intended to be used in a cloud hosted deploy only.\n * Rather than relying on each consumer to perform the necessary environmental checks\n * we use the following check to exit early with a undefined response which should be\n * handled by the caller.\n */\nconst EXIT_EARLY = env.SELF_HOSTED || env.DISABLE_ACCOUNT_PORTAL\n\nexport const getAccount = async (\n email: string\n): Promise<CloudAccount | undefined> => {\n if (EXIT_EARLY) {\n return\n }\n const payload = {\n email,\n }\n const response = await api.post(`/api/accounts/search`, {\n body: payload,\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n\n if (response.status !== 200) {\n throw new Error(`Error getting account by email ${email}`)\n }\n\n const json: CloudAccount[] = await response.json()\n return json[0]\n}\n\nexport const getAccountByTenantId = async (\n tenantId: string\n): Promise<CloudAccount | undefined> => {\n if (EXIT_EARLY) {\n return\n }\n const payload = {\n tenantId,\n }\n const response = await api.post(`/api/accounts/search`, {\n body: payload,\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n\n if (response.status !== 200) {\n throw new Error(`Error getting account by tenantId ${tenantId}`)\n }\n\n const json: CloudAccount[] = await response.json()\n return json[0]\n}\n\nexport const getStatus = async (): Promise<\n HealthStatusResponse | undefined\n> => {\n if (EXIT_EARLY) {\n return\n }\n const response = await api.get(`/api/status`, {\n headers: {\n [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n },\n })\n const json = await response.json()\n\n if (response.status !== 200) {\n throw new Error(`Error getting status`)\n }\n\n return json\n}\n", "export * from \"./accounts\"\n", "import * as redis from \"../redis/init\"\nimport * as tenancy from \"../tenancy\"\nimport * as context from \"../context\"\nimport * as platform from \"../platform\"\nimport env from \"../environment\"\nimport * as accounts from \"../accounts\"\n\nconst EXPIRY_SECONDS = 3600\n\n/**\n * The default populate user function\n */\nasync function populateFromDB(userId: string, tenantId: string) {\n const db = tenancy.getTenantDB(tenantId)\n const user = await db.get(userId)\n user.budibaseAccess = true\n if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {\n const account = await accounts.getAccount(user.email)\n if (account) {\n user.account = account\n user.accountPortalAccess = true\n }\n }\n\n return user\n}\n\n/**\n * Get the requested user by id.\n * Use redis cache to first read the user.\n * If not present fallback to loading the user directly and re-caching.\n * @param {*} userId the id of the user to get\n * @param {*} tenantId the tenant of the user to get\n * @param {*} populateUser function to provide the user for re-caching. default to couch db\n * @returns\n */\nexport async function getUser(\n userId: string,\n tenantId?: string,\n populateUser?: any\n) {\n if (!populateUser) {\n populateUser = populateFromDB\n }\n if (!tenantId) {\n try {\n tenantId = context.getTenantId()\n } catch (err) {\n tenantId = await platform.users.lookupTenantId(userId)\n }\n }\n const client = await redis.getUserClient()\n // try cache\n let user = await client.get(userId)\n if (!user) {\n user = await populateUser(userId, tenantId)\n await client.store(userId, user, EXPIRY_SECONDS)\n }\n if (user && !user.tenantId && tenantId) {\n // make sure the tenant ID is always correct/set\n user.tenantId = tenantId\n }\n return user\n}\n\nexport async function invalidateUser(userId: string) {\n const client = await redis.getUserClient()\n await client.delete(userId)\n}\n", "import {\n APP_PREFIX,\n DocumentType,\n InternalTable,\n SEPARATOR,\n} from \"../constants\"\nimport { newid } from \"./newid\"\n\n/**\n * Generates a new app ID.\n * @returns {string} The new app ID which the app doc can be stored under.\n */\nexport const generateAppID = (tenantId?: string | null) => {\n let id = APP_PREFIX\n if (tenantId) {\n id += `${tenantId}${SEPARATOR}`\n }\n return `${id}${newid()}`\n}\n\n/**\n * Gets a new row ID for the specified table.\n * @param {string} tableId The table which the row is being created for.\n * @param {string|null} id If an ID is to be used then the UUID can be substituted for this.\n * @returns {string} The new ID which a row doc can be stored under.\n */\nexport function generateRowID(tableId: string, id?: string) {\n id = id || newid()\n return `${DocumentType.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}`\n}\n\n/**\n * Generates a new workspace ID.\n * @returns {string} The new workspace ID which the workspace doc can be stored under.\n */\nexport function generateWorkspaceID() {\n return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a new global user ID.\n * @returns {string} The new user ID which the user doc can be stored under.\n */\nexport function generateGlobalUserID(id?: any) {\n return `${DocumentType.USER}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Generates a new user ID based on the passed in global ID.\n * @param {string} globalId The ID of the global user.\n * @returns {string} The new user ID which the user doc can be stored under.\n */\nexport function generateUserMetadataID(globalId: string) {\n return generateRowID(InternalTable.USER_METADATA, globalId)\n}\n\n/**\n * Breaks up the ID to get the global ID.\n */\nexport function getGlobalIDFromUserMetadataID(id: string) {\n const prefix = `${DocumentType.ROW}${SEPARATOR}${InternalTable.USER_METADATA}${SEPARATOR}`\n if (!id || !id.includes(prefix)) {\n return id\n }\n return id.split(prefix)[1]\n}\n\n/**\n * Generates a template ID.\n * @param ownerId The owner/user of the template, this could be global or a workspace level.\n */\nexport function generateTemplateID(ownerId: any) {\n return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}`\n}\n\nexport function generateAppUserID(prodAppId: string, userId: string) {\n return `${prodAppId}${SEPARATOR}${userId}`\n}\n\n/**\n * Generates a new role ID.\n * @returns {string} The new role ID which the role doc can be stored under.\n */\nexport function generateRoleID(id?: any) {\n return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Generates a new dev info document ID - this is scoped to a user.\n * @returns {string} The new dev info ID which info for dev (like api key) can be stored under.\n */\nexport const generateDevInfoID = (userId: any) => {\n return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}`\n}\n\n/**\n * Generates a new plugin ID - to be used in the global DB.\n * @returns {string} The new plugin ID which a plugin metadata document can be stored under.\n */\nexport const generatePluginID = (name: string) => {\n return `${DocumentType.PLUGIN}${SEPARATOR}${name}`\n}\n", "import {\n DocumentType,\n InternalTable,\n SEPARATOR,\n UNICODE_MAX,\n ViewName,\n} from \"../constants\"\nimport { getProdAppID } from \"./conversions\"\n\n/**\n * If creating DB allDocs/query params with only a single top level ID this can be used, this\n * is usually the case as most of our docs are top level e.g. tables, automations, users and so on.\n * More complex cases such as link docs and rows which have multiple levels of IDs that their\n * ID consists of need their own functions to build the allDocs parameters.\n * @param {string} docType The type of document which input params are being built for, e.g. user,\n * link, app, table and so on.\n * @param {string|null} docId The ID of the document minus its type - this is only needed if looking\n * for a singular document.\n * @param {object} otherProps Add any other properties onto the request, e.g. include_docs.\n * @returns {object} Parameters which can then be used with an allDocs request.\n */\nexport function getDocParams(\n docType: string,\n docId?: string | null,\n otherProps: any = {}\n) {\n if (docId == null) {\n docId = \"\"\n }\n return {\n ...otherProps,\n startkey: `${docType}${SEPARATOR}${docId}`,\n endkey: `${docType}${SEPARATOR}${docId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets the DB allDocs/query params for retrieving a row.\n * @param {string|null} tableId The table in which the rows have been stored.\n * @param {string|null} rowId The ID of the row which is being specifically queried for. This can be\n * left null to get all the rows in the table.\n * @param {object} otherProps Any other properties to add to the request.\n * @returns {object} Parameters which can then be used with an allDocs request.\n */\nexport function getRowParams(\n tableId?: string | null,\n rowId?: string | null,\n otherProps = {}\n) {\n if (tableId == null) {\n return getDocParams(DocumentType.ROW, null, otherProps)\n }\n\n const endOfKey = rowId == null ? `${tableId}${SEPARATOR}` : rowId\n\n return getDocParams(DocumentType.ROW, endOfKey, otherProps)\n}\n\n/**\n * Retrieve the correct index for a view based on default design DB.\n */\nexport function getQueryIndex(viewName: ViewName) {\n return `database/${viewName}`\n}\n\n/**\n * Check if a given ID is that of a table.\n * @returns {boolean}\n */\nexport const isTableId = (id: string) => {\n // this includes datasource plus tables\n return (\n id &&\n (id.startsWith(`${DocumentType.TABLE}${SEPARATOR}`) ||\n id.startsWith(`${DocumentType.DATASOURCE_PLUS}${SEPARATOR}`))\n )\n}\n\n/**\n * Check if a given ID is that of a datasource or datasource plus.\n * @returns {boolean}\n */\nexport const isDatasourceId = (id: string) => {\n // this covers both datasources and datasource plus\n return id && id.startsWith(`${DocumentType.DATASOURCE}${SEPARATOR}`)\n}\n\n/**\n * Gets parameters for retrieving workspaces.\n */\nexport function getWorkspaceParams(id = \"\", otherProps = {}) {\n return {\n ...otherProps,\n startkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}`,\n endkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving users.\n */\nexport function getGlobalUserParams(globalId: any, otherProps: any = {}) {\n if (!globalId) {\n globalId = \"\"\n }\n const startkey = otherProps?.startkey\n return {\n ...otherProps,\n // need to include this incase pagination\n startkey: startkey\n ? startkey\n : `${DocumentType.USER}${SEPARATOR}${globalId}`,\n endkey: `${DocumentType.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving users, this is a utility function for the getDocParams function.\n */\nexport function getUserMetadataParams(userId?: string | null, otherProps = {}) {\n return getRowParams(InternalTable.USER_METADATA, userId, otherProps)\n}\n\nexport function getUsersByAppParams(appId: any, otherProps: any = {}) {\n const prodAppId = getProdAppID(appId)\n return {\n ...otherProps,\n startkey: prodAppId,\n endkey: `${prodAppId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving templates. Owner ID must be specified, either global or a workspace level.\n */\nexport function getTemplateParams(\n ownerId: any,\n templateId: any,\n otherProps = {}\n) {\n if (!templateId) {\n templateId = \"\"\n }\n let final\n if (templateId) {\n final = templateId\n } else {\n final = `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}`\n }\n return {\n ...otherProps,\n startkey: final,\n endkey: `${final}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving a role, this is a utility function for the getDocParams function.\n */\nexport function getRoleParams(roleId?: string | null, otherProps = {}) {\n return getDocParams(DocumentType.ROLE, roleId, otherProps)\n}\n\nexport function getStartEndKeyURL(baseKey: any, tenantId?: string) {\n const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : \"\"\n return `startkey=\"${baseKey}${tenancy}\"&endkey=\"${baseKey}${tenancy}${UNICODE_MAX}\"`\n}\n\n/**\n * Gets parameters for retrieving automations, this is a utility function for the getDocParams function.\n */\nexport const getPluginParams = (pluginId?: string | null, otherProps = {}) => {\n return getDocParams(DocumentType.PLUGIN, pluginId, otherProps)\n}\n", "export * from \"./ids\"\nexport * from \"./params\"\n", "import env from \"../environment\"\nimport { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from \"../constants\"\nimport { getTenantId, getGlobalDBName } from \"../context\"\nimport { doWithDB, directCouchAllDbs } from \"./db\"\nimport { getAppMetadata } from \"../cache/appMetadata\"\nimport { isDevApp, isDevAppID, getProdAppID } from \"../docIds/conversions\"\nimport { App, Database } from \"@budibase/types\"\nimport { getStartEndKeyURL } from \"../docIds\"\nexport * from \"../docIds\"\n\n/**\n * if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing\n * when using Pouch it will use the pouchdb-all-dbs package.\n * opts.efficient can be provided to make sure this call is always quick in a multi-tenant environment,\n * but it may not be 100% accurate in full efficiency mode (some tenantless apps may be missed).\n */\nexport async function getAllDbs(opts = { efficient: false }) {\n const efficient = opts && opts.efficient\n\n let dbs: any[] = []\n async function addDbs(queryString?: string) {\n const json = await directCouchAllDbs(queryString)\n dbs = dbs.concat(json)\n }\n let tenantId = getTenantId()\n if (!env.MULTI_TENANCY || (!efficient && tenantId === DEFAULT_TENANT_ID)) {\n // just get all DBs when:\n // - single tenancy\n // - default tenant\n // - apps dbs don't contain tenant id\n // - non-default tenant dbs are filtered out application side in getAllApps\n await addDbs()\n } else {\n // get prod apps\n await addDbs(getStartEndKeyURL(DocumentType.APP, tenantId))\n // get dev apps\n await addDbs(getStartEndKeyURL(DocumentType.APP_DEV, tenantId))\n // add global db name\n dbs.push(getGlobalDBName(tenantId))\n }\n return dbs\n}\n\n/**\n * Lots of different points in the system need to find the full list of apps, this will\n * enumerate the entire CouchDB cluster and get the list of databases (every app).\n *\n * @return {Promise<object[]>} returns the app information document stored in each app database.\n */\nexport async function getAllApps({\n dev,\n all,\n idsOnly,\n efficient,\n}: any = {}): Promise<App[] | string[]> {\n let tenantId = getTenantId()\n if (!env.MULTI_TENANCY && !tenantId) {\n tenantId = DEFAULT_TENANT_ID\n }\n let dbs = await getAllDbs({ efficient })\n const appDbNames = dbs.filter((dbName: any) => {\n if (env.isTest() && !dbName) {\n return false\n }\n\n const split = dbName.split(SEPARATOR)\n // it is an app, check the tenantId\n if (split[0] === DocumentType.APP) {\n // tenantId is always right before the UUID\n const possibleTenantId = split[split.length - 2]\n\n const noTenantId =\n split.length === 2 || possibleTenantId === DocumentType.DEV\n\n return (\n (tenantId === DEFAULT_TENANT_ID && noTenantId) ||\n possibleTenantId === tenantId\n )\n }\n return false\n })\n if (idsOnly) {\n const devAppIds = appDbNames.filter(appId => isDevAppID(appId))\n const prodAppIds = appDbNames.filter(appId => !isDevAppID(appId))\n switch (dev) {\n case true:\n return devAppIds\n case false:\n return prodAppIds\n default:\n return appDbNames\n }\n }\n const appPromises = appDbNames.map((app: any) =>\n // skip setup otherwise databases could be re-created\n getAppMetadata(app)\n )\n if (appPromises.length === 0) {\n return []\n } else {\n const response = await Promise.allSettled(appPromises)\n const apps = response\n .filter(\n (result: any) => result.status === \"fulfilled\" && result.value != null\n )\n .map(({ value }: any) => value)\n if (!all) {\n return apps.filter((app: any) => {\n if (dev) {\n return isDevApp(app)\n }\n return !isDevApp(app)\n })\n } else {\n return apps.map((app: any) => ({\n ...app,\n status: isDevApp(app) ? \"development\" : \"published\",\n }))\n }\n }\n}\n\nexport async function getAppsByIDs(appIds: string[]) {\n const settled = await Promise.allSettled(\n appIds.map(appId => getAppMetadata(appId))\n )\n // have to list the apps which exist, some may have been deleted\n return settled\n .filter(promise => promise.status === \"fulfilled\")\n .map(promise => (promise as PromiseFulfilledResult<App>).value)\n}\n\n/**\n * Utility function for getAllApps but filters to production apps only.\n */\nexport async function getProdAppIDs() {\n const apps = (await getAllApps({ idsOnly: true })) as string[]\n return apps.filter((id: any) => !isDevAppID(id))\n}\n\n/**\n * Utility function for the inverse of above.\n */\nexport async function getDevAppIDs() {\n const apps = (await getAllApps({ idsOnly: true })) as string[]\n return apps.filter((id: any) => isDevAppID(id))\n}\n\nexport function isSameAppID(\n appId1: string | undefined,\n appId2: string | undefined\n) {\n if (appId1 == undefined || appId2 == undefined) {\n return false\n }\n return getProdAppID(appId1) === getProdAppID(appId2)\n}\n\nexport async function dbExists(dbName: any) {\n return doWithDB(\n dbName,\n async (db: Database) => {\n return await db.exists()\n },\n { skip_setup: true }\n )\n}\n\nexport function pagination<T>(\n data: T[],\n pageSize: number,\n {\n paginate,\n property,\n getKey,\n }: {\n paginate: boolean\n property: string\n getKey?: (doc: T) => string | undefined\n } = {\n paginate: true,\n property: \"_id\",\n }\n) {\n if (!paginate) {\n return { data, hasNextPage: false }\n }\n const hasNextPage = data.length > pageSize\n let nextPage = undefined\n if (!getKey) {\n getKey = (doc: any) => (property ? doc?.[property] : doc?._id)\n }\n if (hasNextPage) {\n nextPage = getKey(data[pageSize])\n }\n return {\n data: data.slice(0, pageSize),\n hasNextPage,\n nextPage,\n }\n}\n", "import {\n DeprecatedViews,\n DocumentType,\n SEPARATOR,\n StaticDatabases,\n ViewName,\n} from \"../constants\"\nimport { getGlobalDB } from \"../context\"\nimport { doWithDB } from \"./\"\nimport { AllDocsResponse, Database, DatabaseQueryOpts } from \"@budibase/types\"\nimport env from \"../environment\"\n\nconst DESIGN_DB = \"_design/database\"\n\nfunction DesignDoc() {\n return {\n _id: DESIGN_DB,\n // view collation information, read before writing any complex views:\n // https://docs.couchdb.org/en/master/ddocs/views/collation.html#collation-specification\n views: {},\n }\n}\n\ninterface DesignDocument {\n views: any\n}\n\nasync function removeDeprecated(db: Database, viewName: ViewName) {\n // @ts-ignore\n if (!DeprecatedViews[viewName]) {\n return\n }\n try {\n const designDoc = await db.get<DesignDocument>(DESIGN_DB)\n // @ts-ignore\n for (let deprecatedNames of DeprecatedViews[viewName]) {\n delete designDoc.views[deprecatedNames]\n }\n await db.put(designDoc)\n } catch (err) {\n // doesn't exist, ignore\n }\n}\n\nexport async function createView(\n db: any,\n viewJs: string,\n viewName: string\n): Promise<void> {\n let designDoc\n try {\n designDoc = (await db.get(DESIGN_DB)) as DesignDocument\n } catch (err) {\n // no design doc, make one\n designDoc = DesignDoc()\n }\n const view = {\n map: viewJs,\n }\n designDoc.views = {\n ...designDoc.views,\n [viewName]: view,\n }\n try {\n await db.put(designDoc)\n } catch (err: any) {\n if (err.status === 409) {\n return await createView(db, viewJs, viewName)\n } else {\n throw err\n }\n }\n}\n\nexport const createNewUserEmailView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.USER}${SEPARATOR}\")) {\n emit(doc.email.toLowerCase(), doc._id)\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_EMAIL)\n}\n\nexport const createUserAppView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.USER}${SEPARATOR}\") && doc.roles) {\n for (let prodAppId of Object.keys(doc.roles)) {\n let emitted = prodAppId + \"${SEPARATOR}\" + doc._id\n emit(emitted, null)\n }\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_APP)\n}\n\nexport const createApiKeyView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.DEV_INFO}\") && doc.apiKey) {\n emit(doc.apiKey, doc.userId)\n }\n }`\n await createView(db, viewJs, ViewName.BY_API_KEY)\n}\n\nexport const createUserBuildersView = async () => {\n const db = getGlobalDB()\n const viewJs = `function(doc) {\n if (doc.builder && doc.builder.global === true) {\n emit(doc._id, doc._id)\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_BUILDERS)\n}\n\nexport interface QueryViewOptions {\n arrayResponse?: boolean\n}\n\nexport async function queryViewRaw<T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db: Database,\n createFunc: any,\n opts?: QueryViewOptions\n): Promise<AllDocsResponse<T>> {\n try {\n const response = await db.query<T>(`database/${viewName}`, params)\n // await to catch error\n return response\n } catch (err: any) {\n const pouchNotFound = err && err.name === \"not_found\"\n const couchNotFound = err && err.status === 404\n if (pouchNotFound || couchNotFound) {\n await removeDeprecated(db, viewName)\n await createFunc()\n return queryViewRaw(viewName, params, db, createFunc, opts)\n } else if (err.status === 409) {\n // can happen when multiple queries occur at once, view couldn't be created\n // other design docs being updated, re-run\n return queryViewRaw(viewName, params, db, createFunc, opts)\n } else {\n throw err\n }\n }\n}\n\nexport const queryView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db: Database,\n createFunc: any,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n const response = await queryViewRaw<T>(viewName, params, db, createFunc, opts)\n const rows = response.rows\n const docs = rows.map((row: any) =>\n params.include_docs ? row.doc : row.value\n )\n\n // if arrayResponse has been requested, always return array regardless of length\n if (opts?.arrayResponse) {\n return docs as T[]\n } else {\n // return the single document if there is only one\n return docs.length <= 1 ? (docs[0] as T) : (docs as T[])\n }\n}\n\n// PLATFORM\n\nasync function createPlatformView(viewJs: string, viewName: ViewName) {\n try {\n await doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {\n await createView(db, viewJs, viewName)\n })\n } catch (e: any) {\n if (e.status === 409 && env.isTest()) {\n // multiple tests can try to initialise platforms views\n // at once - safe to exit on conflict\n return\n }\n throw e\n }\n}\n\nexport const createPlatformAccountEmailView = async () => {\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${DocumentType.ACCOUNT_METADATA}${SEPARATOR}\")) {\n emit(doc.email.toLowerCase(), doc._id)\n }\n }`\n await createPlatformView(viewJs, ViewName.ACCOUNT_BY_EMAIL)\n}\n\nexport const createPlatformUserView = async () => {\n const viewJs = `function(doc) {\n if (doc.tenantId) {\n emit(doc._id.toLowerCase(), doc._id)\n }\n }`\n await createPlatformView(viewJs, ViewName.PLATFORM_USERS_LOWERCASE)\n}\n\nexport const queryPlatformView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n const CreateFuncByName: any = {\n [ViewName.ACCOUNT_BY_EMAIL]: createPlatformAccountEmailView,\n [ViewName.PLATFORM_USERS_LOWERCASE]: createPlatformUserView,\n }\n\n return doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {\n const createFn = CreateFuncByName[viewName]\n return queryView(viewName, params, db, createFn, opts)\n })\n}\n\nconst CreateFuncByName: any = {\n [ViewName.USER_BY_EMAIL]: createNewUserEmailView,\n [ViewName.BY_API_KEY]: createApiKeyView,\n [ViewName.USER_BY_BUILDERS]: createUserBuildersView,\n [ViewName.USER_BY_APP]: createUserAppView,\n}\n\nexport const queryGlobalView = async <T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n db?: Database,\n opts?: QueryViewOptions\n): Promise<T[] | T | undefined> => {\n // can pass DB in if working with something specific\n if (!db) {\n db = getGlobalDB()\n }\n const createFn = CreateFuncByName[viewName]\n return queryView(viewName, params, db!, createFn, opts)\n}\n\nexport async function queryGlobalViewRaw<T>(\n viewName: ViewName,\n params: DatabaseQueryOpts,\n opts?: QueryViewOptions\n) {\n const db = getGlobalDB()\n const createFn = CreateFuncByName[viewName]\n return queryViewRaw<T>(viewName, params, db, createFn, opts)\n}\n", "import { getPouchDB, closePouchDB } from \"./couch\"\nimport { DocumentType } from \"../constants\"\n\nclass Replication {\n source: any\n target: any\n replication: any\n\n /**\n *\n * @param {String} source - the DB you want to replicate or rollback to\n * @param {String} target - the DB you want to replicate to, or rollback from\n */\n constructor({ source, target }: any) {\n this.source = getPouchDB(source)\n this.target = getPouchDB(target)\n }\n\n close() {\n return Promise.all([closePouchDB(this.source), closePouchDB(this.target)])\n }\n\n promisify(operation: any, opts = {}) {\n return new Promise(resolve => {\n operation(this.target, opts)\n .on(\"denied\", function (err: any) {\n // a document failed to replicate (e.g. due to permissions)\n throw new Error(`Denied: Document failed to replicate ${err}`)\n })\n .on(\"complete\", function (info: any) {\n return resolve(info)\n })\n .on(\"error\", function (err: any) {\n throw new Error(`Replication Error: ${err}`)\n })\n })\n }\n\n /**\n * Two way replication operation, intended to be promise based.\n * @param {Object} opts - PouchDB replication options\n */\n sync(opts = {}) {\n this.replication = this.promisify(this.source.sync, opts)\n return this.replication\n }\n\n /**\n * One way replication operation, intended to be promise based.\n * @param {Object} opts - PouchDB replication options\n */\n replicate(opts = {}) {\n this.replication = this.promisify(this.source.replicate.to, opts)\n return this.replication\n }\n\n appReplicateOpts() {\n return {\n filter: (doc: any) => {\n return doc._id !== DocumentType.APP_METADATA\n },\n }\n }\n\n /**\n * Rollback the target DB back to the state of the source DB\n */\n async rollback() {\n await this.target.destroy()\n // Recreate the DB again\n this.target = getPouchDB(this.target.name)\n // take the opportunity to remove deleted tombstones\n await this.replicate()\n }\n\n cancel() {\n this.replication.cancel()\n }\n}\n\nexport default Replication\n", "import fetch from \"node-fetch\"\nimport { getCouchInfo } from \"./couch\"\nimport { SearchFilters, Row } from \"@budibase/types\"\nimport { createUserIndex } from \"./searchIndexes/searchIndexes\"\n\nconst QUERY_START_REGEX = /\\d[0-9]*:/g\n\ninterface SearchResponse<T> {\n rows: T[] | any[]\n bookmark?: string\n totalRows: number\n}\n\ninterface PaginatedSearchResponse<T> extends SearchResponse<T> {\n hasNextPage: boolean\n}\n\nexport type SearchParams<T> = {\n tableId?: string\n sort?: string\n sortOrder?: string\n sortType?: string\n limit?: number\n bookmark?: string\n version?: string\n indexer?: () => Promise<any>\n disableEscaping?: boolean\n rows?: T | Row[]\n}\n\nexport function removeKeyNumbering(key: any): string {\n if (typeof key === \"string\" && key.match(QUERY_START_REGEX) != null) {\n const parts = key.split(\":\")\n // remove the number\n parts.shift()\n return parts.join(\":\")\n } else {\n return key\n }\n}\n\n/**\n * Class to build lucene query URLs.\n * Optionally takes a base lucene query object.\n */\nexport class QueryBuilder<T> {\n #dbName: string\n #index: string\n #query: SearchFilters\n #limit: number\n #sort?: string\n #bookmark?: string\n #sortOrder: string\n #sortType: string\n #includeDocs: boolean\n #version?: string\n #indexBuilder?: () => Promise<any>\n #noEscaping = false\n #skip?: number\n\n static readonly maxLimit = 200\n\n constructor(dbName: string, index: string, base?: SearchFilters) {\n this.#dbName = dbName\n this.#index = index\n this.#query = {\n allOr: false,\n string: {},\n fuzzy: {},\n range: {},\n equal: {},\n notEqual: {},\n empty: {},\n notEmpty: {},\n oneOf: {},\n contains: {},\n notContains: {},\n containsAny: {},\n ...base,\n }\n this.#limit = 50\n this.#sortOrder = \"ascending\"\n this.#sortType = \"string\"\n this.#includeDocs = true\n }\n\n disableEscaping() {\n this.#noEscaping = true\n return this\n }\n\n setIndexBuilder(builderFn: () => Promise<any>) {\n this.#indexBuilder = builderFn\n return this\n }\n\n setVersion(version?: string) {\n if (version != null) {\n this.#version = version\n }\n return this\n }\n\n setTable(tableId: string) {\n this.#query.equal!.tableId = tableId\n return this\n }\n\n setLimit(limit?: number) {\n if (limit != null) {\n this.#limit = limit\n }\n return this\n }\n\n setSort(sort?: string) {\n if (sort != null) {\n this.#sort = sort\n }\n return this\n }\n\n setSortOrder(sortOrder?: string) {\n if (sortOrder != null) {\n this.#sortOrder = sortOrder\n }\n return this\n }\n\n setSortType(sortType?: string) {\n if (sortType != null) {\n this.#sortType = sortType\n }\n return this\n }\n\n setBookmark(bookmark?: string) {\n if (bookmark != null) {\n this.#bookmark = bookmark\n }\n return this\n }\n\n setSkip(skip: number | undefined) {\n this.#skip = skip\n return this\n }\n\n excludeDocs() {\n this.#includeDocs = false\n return this\n }\n\n includeDocs() {\n this.#includeDocs = true\n return this\n }\n\n addString(key: string, partial: string) {\n this.#query.string![key] = partial\n return this\n }\n\n addFuzzy(key: string, fuzzy: string) {\n this.#query.fuzzy![key] = fuzzy\n return this\n }\n\n addRange(key: string, low: string | number, high: string | number) {\n this.#query.range![key] = {\n low,\n high,\n }\n return this\n }\n\n addEqual(key: string, value: any) {\n this.#query.equal![key] = value\n return this\n }\n\n addNotEqual(key: string, value: any) {\n this.#query.notEqual![key] = value\n return this\n }\n\n addEmpty(key: string, value: any) {\n this.#query.empty![key] = value\n return this\n }\n\n addNotEmpty(key: string, value: any) {\n this.#query.notEmpty![key] = value\n return this\n }\n\n addOneOf(key: string, value: any) {\n this.#query.oneOf![key] = value\n return this\n }\n\n addContains(key: string, value: any) {\n this.#query.contains![key] = value\n return this\n }\n\n addNotContains(key: string, value: any) {\n this.#query.notContains![key] = value\n return this\n }\n\n addContainsAny(key: string, value: any) {\n this.#query.containsAny![key] = value\n return this\n }\n\n setAllOr() {\n this.#query.allOr = true\n }\n\n handleSpaces(input: string) {\n if (this.#noEscaping) {\n return input\n } else {\n return input.replace(/ /g, \"_\")\n }\n }\n\n /**\n * Preprocesses a value before going into a lucene search.\n * Transforms strings to lowercase and wraps strings and bools in quotes.\n * @param value The value to process\n * @param options The preprocess options\n * @returns {string|*}\n */\n preprocess(value: any, { escape, lowercase, wrap, type }: any = {}) {\n const hasVersion = !!this.#version\n // Determine if type needs wrapped\n const originalType = typeof value\n // Convert to lowercase\n if (value && lowercase) {\n value = value.toLowerCase ? value.toLowerCase() : value\n }\n // Escape characters\n if (!this.#noEscaping && escape && originalType === \"string\") {\n value = `${value}`.replace(/[ \\/#+\\-&|!(){}\\]^\"~*?:\\\\]/g, \"\\\\$&\")\n }\n\n // Wrap in quotes\n if (originalType === \"string\" && !isNaN(value) && !type) {\n value = `\"${value}\"`\n } else if (hasVersion && wrap) {\n value = originalType === \"number\" ? value : `\"${value}\"`\n }\n return value\n }\n\n isMultiCondition() {\n let count = 0\n for (let filters of Object.values(this.#query)) {\n // not contains is one massive filter in allOr mode\n if (typeof filters === \"object\") {\n count += Object.keys(filters).length\n }\n }\n return count > 1\n }\n\n compressFilters(filters: Record<string, string[]>) {\n const compressed: typeof filters = {}\n for (let key of Object.keys(filters)) {\n const finalKey = removeKeyNumbering(key)\n if (compressed[finalKey]) {\n compressed[finalKey] = compressed[finalKey].concat(filters[key])\n } else {\n compressed[finalKey] = filters[key]\n }\n }\n // add prefixes back\n const final: typeof filters = {}\n let count = 1\n for (let [key, value] of Object.entries(compressed)) {\n final[`${count++}:${key}`] = value\n }\n return final\n }\n\n buildSearchQuery() {\n const builder = this\n let allOr = this.#query && this.#query.allOr\n let query = allOr ? \"\" : \"*:*\"\n const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true }\n let tableId\n if (this.#query.equal!.tableId) {\n tableId = this.#query.equal!.tableId\n delete this.#query.equal!.tableId\n }\n\n const equal = (key: string, value: any) => {\n // 0 evaluates to false, which means we would return all rows if we don't check it\n if (!value && value !== 0) {\n return null\n }\n return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`\n }\n\n const contains = (key: string, value: any, mode = \"AND\") => {\n if (Array.isArray(value) && value.length === 0) {\n return null\n }\n if (!Array.isArray(value)) {\n return `${key}:${value}`\n }\n let statement = `${builder.preprocess(value[0], { escape: true })}`\n for (let i = 1; i < value.length; i++) {\n statement += ` ${mode} ${builder.preprocess(value[i], {\n escape: true,\n })}`\n }\n return `${key}:(${statement})`\n }\n\n const fuzzy = (key: string, value: any) => {\n if (!value) {\n return null\n }\n value = builder.preprocess(value, {\n escape: true,\n lowercase: true,\n type: \"fuzzy\",\n })\n return `${key}:/.*${value}.*/`\n }\n\n const notContains = (key: string, value: any) => {\n const allPrefix = allOr ? \"*:* AND \" : \"\"\n const mode = allOr ? \"AND\" : undefined\n return allPrefix + \"NOT \" + contains(key, value, mode)\n }\n\n const containsAny = (key: string, value: any) => {\n return contains(key, value, \"OR\")\n }\n\n const oneOf = (key: string, value: any) => {\n if (!Array.isArray(value)) {\n if (typeof value === \"string\") {\n value = value.split(\",\")\n } else {\n return \"\"\n }\n }\n let orStatement = `${builder.preprocess(value[0], allPreProcessingOpts)}`\n for (let i = 1; i < value.length; i++) {\n orStatement += ` OR ${builder.preprocess(\n value[i],\n allPreProcessingOpts\n )}`\n }\n return `${key}:(${orStatement})`\n }\n\n function build(\n structure: any,\n queryFn: (key: string, value: any) => string | null,\n opts?: { returnBuilt?: boolean; mode?: string }\n ) {\n let built = \"\"\n for (let [key, value] of Object.entries(structure)) {\n // check for new format - remove numbering if needed\n key = removeKeyNumbering(key)\n key = builder.preprocess(builder.handleSpaces(key), {\n escape: true,\n })\n let expression = queryFn(key, value)\n if (expression == null) {\n continue\n }\n if (built.length > 0 || query.length > 0) {\n const mode = opts?.mode ? opts.mode : allOr ? \"OR\" : \"AND\"\n built += ` ${mode} `\n }\n built += expression\n }\n if (opts?.returnBuilt) {\n return built\n } else {\n query += built\n }\n }\n\n // Construct the actual lucene search query string from JSON structure\n if (this.#query.string) {\n build(this.#query.string, (key: string, value: any) => {\n if (!value) {\n return null\n }\n value = builder.preprocess(value, {\n escape: true,\n lowercase: true,\n type: \"string\",\n })\n return `${key}:${value}*`\n })\n }\n if (this.#query.range) {\n build(this.#query.range, (key: string, value: any) => {\n if (!value) {\n return null\n }\n if (value.low == null || value.low === \"\") {\n return null\n }\n if (value.high == null || value.high === \"\") {\n return null\n }\n const low = builder.preprocess(value.low, allPreProcessingOpts)\n const high = builder.preprocess(value.high, allPreProcessingOpts)\n return `${key}:[${low} TO ${high}]`\n })\n }\n if (this.#query.fuzzy) {\n build(this.#query.fuzzy, fuzzy)\n }\n if (this.#query.equal) {\n build(this.#query.equal, equal)\n }\n if (this.#query.notEqual) {\n build(this.#query.notEqual, (key: string, value: any) => {\n if (!value) {\n return null\n }\n return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}`\n })\n }\n if (this.#query.empty) {\n build(this.#query.empty, (key: string) => `(*:* -${key}:[\"\" TO *])`)\n }\n if (this.#query.notEmpty) {\n build(this.#query.notEmpty, (key: string) => `${key}:[\"\" TO *]`)\n }\n if (this.#query.oneOf) {\n build(this.#query.oneOf, oneOf)\n }\n if (this.#query.contains) {\n build(this.#query.contains, contains)\n }\n if (this.#query.notContains) {\n build(this.compressFilters(this.#query.notContains), notContains)\n }\n if (this.#query.containsAny) {\n build(this.#query.containsAny, containsAny)\n }\n // make sure table ID is always added as an AND\n if (tableId) {\n query = this.isMultiCondition() ? `(${query})` : query\n allOr = false\n build({ tableId }, equal)\n }\n return query\n }\n\n buildSearchBody() {\n let body: any = {\n q: this.buildSearchQuery(),\n limit: Math.min(this.#limit, QueryBuilder.maxLimit),\n include_docs: this.#includeDocs,\n }\n if (this.#bookmark) {\n body.bookmark = this.#bookmark\n }\n if (this.#sort) {\n const order = this.#sortOrder === \"descending\" ? \"-\" : \"\"\n const type = `<${this.#sortType}>`\n body.sort = `${order}${this.handleSpaces(this.#sort)}${type}`\n }\n return body\n }\n\n async run() {\n if (this.#skip) {\n await this.#skipItems(this.#skip)\n }\n return await this.#execute()\n }\n\n /**\n * Lucene queries do not support pagination and use bookmarks instead.\n * For the given builder, walk through pages using bookmarks until the desired\n * page has been met.\n */\n async #skipItems(skip: number) {\n // Lucene does not support pagination.\n // Handle pagination by finding the right bookmark\n const prevIncludeDocs = this.#includeDocs\n const prevLimit = this.#limit\n\n this.excludeDocs()\n let skipRemaining = skip\n let iterationFetched = 0\n do {\n const toSkip = Math.min(QueryBuilder.maxLimit, skipRemaining)\n this.setLimit(toSkip)\n const { bookmark, rows } = await this.#execute()\n this.setBookmark(bookmark)\n iterationFetched = rows.length\n skipRemaining -= rows.length\n } while (skipRemaining > 0 && iterationFetched > 0)\n\n this.#includeDocs = prevIncludeDocs\n this.#limit = prevLimit\n }\n\n async #execute() {\n const { url, cookie } = getCouchInfo()\n const fullPath = `${url}/${this.#dbName}/_design/database/_search/${\n this.#index\n }`\n const body = this.buildSearchBody()\n try {\n return await runQuery<T>(fullPath, body, cookie)\n } catch (err: any) {\n if (err.status === 404 && this.#indexBuilder) {\n await this.#indexBuilder()\n return await runQuery<T>(fullPath, body, cookie)\n } else {\n throw err\n }\n }\n }\n}\n\n/**\n * Executes a lucene search query.\n * @param url The query URL\n * @param body The request body defining search criteria\n * @param cookie The auth cookie for CouchDB\n * @returns {Promise<{rows: []}>}\n */\nasync function runQuery<T>(\n url: string,\n body: any,\n cookie: string\n): Promise<SearchResponse<T>> {\n const response = await fetch(url, {\n body: JSON.stringify(body),\n method: \"POST\",\n headers: {\n Authorization: cookie,\n },\n })\n\n if (response.status === 404) {\n throw response\n }\n const json = await response.json()\n\n let output: SearchResponse<T> = {\n rows: [],\n totalRows: 0,\n }\n if (json.rows != null && json.rows.length > 0) {\n output.rows = json.rows.map((row: any) => row.doc)\n }\n if (json.bookmark) {\n output.bookmark = json.bookmark\n }\n if (json.total_rows) {\n output.totalRows = json.total_rows\n }\n return output\n}\n\n/**\n * Gets round the fixed limit of 200 results from a query by fetching as many\n * pages as required and concatenating the results. This recursively operates\n * until enough results have been found.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The number of results to fetch\n * bookmark {string|null} Current bookmark in the recursive search\n * rows {array|null} Current results in the recursive search\n * @returns {Promise<*[]|*>}\n */\nasync function recursiveSearch<T>(\n dbName: string,\n index: string,\n query: any,\n params: any\n): Promise<any> {\n const bookmark = params.bookmark\n const rows = params.rows || []\n if (rows.length >= params.limit) {\n return rows\n }\n let pageSize = QueryBuilder.maxLimit\n if (rows.length > params.limit - QueryBuilder.maxLimit) {\n pageSize = params.limit - rows.length\n }\n const page = await new QueryBuilder<T>(dbName, index, query)\n .setVersion(params.version)\n .setTable(params.tableId)\n .setBookmark(bookmark)\n .setLimit(pageSize)\n .setSort(params.sort)\n .setSortOrder(params.sortOrder)\n .setSortType(params.sortType)\n .run()\n if (!page.rows.length) {\n return rows\n }\n if (page.rows.length < QueryBuilder.maxLimit) {\n return [...rows, ...page.rows]\n }\n const newParams = {\n ...params,\n bookmark: page.bookmark,\n rows: [...rows, ...page.rows],\n }\n return await recursiveSearch(dbName, index, query, newParams)\n}\n\n/**\n * Performs a paginated search. A bookmark will be returned to allow the next\n * page to be fetched. There is a max limit off 200 results per page in a\n * paginated search.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The desired page size\n * bookmark {string} The bookmark to resume from\n * @returns {Promise<{hasNextPage: boolean, rows: *[]}>}\n */\nexport async function paginatedSearch<T>(\n dbName: string,\n index: string,\n query: SearchFilters,\n params: SearchParams<T>\n) {\n let limit = params.limit\n if (limit == null || isNaN(limit) || limit < 0) {\n limit = 50\n }\n limit = Math.min(limit, QueryBuilder.maxLimit)\n const search = new QueryBuilder<T>(dbName, index, query)\n if (params.version) {\n search.setVersion(params.version)\n }\n if (params.tableId) {\n search.setTable(params.tableId)\n }\n if (params.sort) {\n search\n .setSort(params.sort)\n .setSortOrder(params.sortOrder)\n .setSortType(params.sortType)\n }\n if (params.indexer) {\n search.setIndexBuilder(params.indexer)\n }\n if (params.disableEscaping) {\n search.disableEscaping()\n }\n const searchResults = await search\n .setBookmark(params.bookmark)\n .setLimit(limit)\n .run()\n\n // Try fetching 1 row in the next page to see if another page of results\n // exists or not\n search.setBookmark(searchResults.bookmark).setLimit(1)\n if (params.tableId) {\n search.setTable(params.tableId)\n }\n const nextResults = await search.run()\n\n return {\n ...searchResults,\n hasNextPage: nextResults.rows && nextResults.rows.length > 0,\n }\n}\n\n/**\n * Performs a full search, fetching multiple pages if required to return the\n * desired amount of results. There is a limit of 1000 results to avoid\n * heavy performance hits, and to avoid client components breaking from\n * handling too much data.\n * @param dbName {string} Which database to run a lucene query on\n * @param index {string} Which search index to utilise\n * @param query {object} The JSON query structure\n * @param params {object} The search params including:\n * tableId {string} The table ID to search\n * sort {string} The sort column\n * sortOrder {string} The sort order (\"ascending\" or \"descending\")\n * sortType {string} Whether to treat sortable values as strings or\n * numbers. (\"string\" or \"number\")\n * limit {number} The desired number of results\n * @returns {Promise<{rows: *}>}\n */\nexport async function fullSearch<T>(\n dbName: string,\n index: string,\n query: SearchFilters,\n params: SearchParams<T>\n) {\n let limit = params.limit\n if (limit == null || isNaN(limit) || limit < 0) {\n limit = 1000\n }\n params.limit = Math.min(limit, 1000)\n const rows = await recursiveSearch<T>(dbName, index, query, params)\n return { rows }\n}\n", "import { User, SearchIndex } from \"@budibase/types\"\nimport { getGlobalDB } from \"../../context\"\n\nexport async function createUserIndex() {\n const db = getGlobalDB()\n let designDoc\n try {\n designDoc = await db.get(\"_design/database\")\n } catch (err: any) {\n if (err.status === 404) {\n designDoc = { _id: \"_design/database\" }\n }\n }\n\n const fn = function (user: User) {\n if (user._id && !user._id.startsWith(\"us_\")) {\n return\n }\n const ignoredFields = [\n \"_id\",\n \"_rev\",\n \"password\",\n \"account\",\n \"license\",\n \"budibaseAccess\",\n \"accountPortalAccess\",\n \"csrfToken\",\n ]\n\n function idx(input: Record<string, any>, prev?: string) {\n for (let key of Object.keys(input)) {\n if (ignoredFields.includes(key)) {\n continue\n }\n let idxKey = prev != null ? `${prev}.${key}` : key\n if (typeof input[key] === \"string\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key].toLowerCase(), { facet: true })\n } else if (typeof input[key] !== \"object\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key], { facet: true })\n } else {\n idx(input[key], idxKey)\n }\n }\n }\n idx(user)\n }\n\n designDoc.indexes = {\n [SearchIndex.USER]: {\n index: fn.toString(),\n analyzer: {\n default: \"keyword\",\n name: \"perfield\",\n },\n },\n }\n await db.put(designDoc)\n}\n", "export * from \"./searchIndexes\"\n", "export * from \"./couch\"\nexport * from \"./db\"\nexport * from \"./utils\"\nexport * from \"./views\"\nexport * from \"../docIds/conversions\"\nexport { default as Replication } from \"./Replication\"\n// exports to support old export structure\nexport * from \"../constants/db\"\nexport { getGlobalDBName, baseGlobalDBName } from \"../context\"\nexport * from \"./lucene\"\nexport * as searchIndexes from \"./searchIndexes\"\n", "import { getAppClient } from \"../redis/init\"\nimport { doWithDB, DocumentType } from \"../db\"\nimport { Database, App } from \"@budibase/types\"\n\nconst AppState = {\n INVALID: \"invalid\",\n}\nconst EXPIRY_SECONDS = 3600\n\n/**\n * The default populate app metadata function\n */\nasync function populateFromDB(appId: string) {\n return doWithDB(\n appId,\n (db: Database) => {\n return db.get(DocumentType.APP_METADATA)\n },\n { skip_setup: true }\n )\n}\n\nfunction isInvalid(metadata?: { state: string }) {\n return !metadata || metadata.state === AppState.INVALID\n}\n\n/**\n * Get the requested app metadata by id.\n * Use redis cache to first read the app metadata.\n * If not present fallback to loading the app metadata directly and re-caching.\n * @param {string} appId the id of the app to get metadata from.\n * @returns {object} the app metadata.\n */\nexport async function getAppMetadata(appId: string) {\n const client = await getAppClient()\n // try cache\n let metadata = await client.get(appId)\n if (!metadata) {\n let expiry: number | undefined = EXPIRY_SECONDS\n try {\n metadata = await populateFromDB(appId)\n } catch (err: any) {\n // app DB left around, but no metadata, it is invalid\n if (err && err.status === 404) {\n metadata = { state: AppState.INVALID }\n // don't expire the reference to an invalid app, it'll only be\n // updated if a metadata doc actually gets stored (app is remade/reverted)\n expiry = undefined\n } else {\n throw err\n }\n }\n // needed for cypress/some scenarios where the caching happens\n // so quickly the requests can get slightly out of sync\n // might store its invalid just before it stores its valid\n if (isInvalid(metadata)) {\n const temp = await client.get(appId)\n if (temp) {\n metadata = temp\n }\n }\n await client.store(appId, metadata, expiry)\n }\n // we've stored in the cache an object to tell us that it is currently invalid\n if (isInvalid(metadata)) {\n throw { status: 404, message: \"No app metadata found\" }\n }\n return metadata as App\n}\n\n/**\n * Invalidate/reset the cached metadata when a change occurs in the db.\n * @param appId {string} the cache key to bust/update.\n * @param newMetadata {object|undefined} optional - can simply provide the new metadata to update with.\n * @return {Promise<void>} will respond with success when cache is updated.\n */\nexport async function invalidateAppMetadata(appId: string, newMetadata?: any) {\n if (!appId) {\n throw \"Cannot invalidate if no app ID provided.\"\n }\n const client = await getAppClient()\n await client.delete(appId)\n if (newMetadata) {\n await client.store(appId, newMetadata, EXPIRY_SECONDS)\n }\n}\n", "import BaseCache from \"./base\"\nimport { getWritethroughClient } from \"../redis/init\"\nimport { logWarn } from \"../logging\"\nimport { Database, Document, LockName, LockType } from \"@budibase/types\"\nimport * as locks from \"../redis/redlockImpl\"\n\nconst DEFAULT_WRITE_RATE_MS = 10000\nlet CACHE: BaseCache | null = null\n\ninterface CacheItem {\n doc: any\n lastWrite: number\n}\n\nasync function getCache() {\n if (!CACHE) {\n const client = await getWritethroughClient()\n CACHE = new BaseCache(client)\n }\n return CACHE\n}\n\nfunction makeCacheKey(db: Database, key: string) {\n return db.name + key\n}\n\nfunction makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {\n return { doc, lastWrite: lastWrite || Date.now() }\n}\n\nasync function put(\n db: Database,\n doc: Document,\n writeRateMs: number = DEFAULT_WRITE_RATE_MS\n) {\n const cache = await getCache()\n const key = doc._id\n let cacheItem: CacheItem | undefined\n if (key) {\n cacheItem = await cache.get(makeCacheKey(db, key))\n }\n const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs\n let output = doc\n if (updateDb) {\n const lockResponse = await locks.doWithLock(\n {\n type: LockType.TRY_ONCE,\n name: LockName.PERSIST_WRITETHROUGH,\n resource: key,\n ttl: 15000,\n },\n async () => {\n const writeDb = async (toWrite: any) => {\n // doc should contain the _id and _rev\n const response = await db.put(toWrite, { force: true })\n output = {\n ...doc,\n _id: response.id,\n _rev: response.rev,\n }\n }\n try {\n await writeDb(doc)\n } catch (err: any) {\n if (err.status !== 409) {\n throw err\n } else {\n // Swallow 409s but log them\n logWarn(`Ignoring conflict in write-through cache`)\n }\n }\n }\n )\n\n if (!lockResponse.executed) {\n logWarn(`Ignoring redlock conflict in write-through cache`)\n }\n }\n // if we are updating the DB then need to set the lastWrite to now\n cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)\n if (output._id) {\n await cache.store(makeCacheKey(db, output._id), cacheItem)\n }\n return { ok: true, id: output._id, rev: output._rev }\n}\n\nasync function get(db: Database, id: string): Promise<any> {\n const cache = await getCache()\n const cacheKey = makeCacheKey(db, id)\n let cacheItem: CacheItem = await cache.get(cacheKey)\n if (!cacheItem) {\n const doc = await db.get(id)\n cacheItem = makeCacheItem(doc)\n await cache.store(cacheKey, cacheItem)\n }\n return cacheItem.doc\n}\n\nasync function remove(db: Database, docOrId: any, rev?: any): Promise<void> {\n const cache = await getCache()\n if (!docOrId) {\n throw new Error(\"No ID/Rev provided.\")\n }\n const id = typeof docOrId === \"string\" ? docOrId : docOrId._id\n rev = typeof docOrId === \"string\" ? rev : docOrId._rev\n try {\n await cache.delete(makeCacheKey(db, id))\n } finally {\n await db.remove(id, rev)\n }\n}\n\nexport class Writethrough {\n db: Database\n writeRateMs: number\n\n constructor(db: Database, writeRateMs: number = DEFAULT_WRITE_RATE_MS) {\n this.db = db\n this.writeRateMs = writeRateMs\n }\n\n async put(doc: any) {\n return put(this.db, doc, this.writeRateMs)\n }\n\n async get(id: string) {\n return get(this.db, id)\n }\n\n async remove(docOrId: any, rev?: any) {\n return remove(this.db, docOrId, rev)\n }\n}\n", "export * as generic from \"./generic\"\nexport * as user from \"./user\"\nexport * as app from \"./appMetadata\"\nexport * as writethrough from \"./writethrough\"\nexport * from \"./generic\"\n", "import {\n Config,\n ConfigType,\n GoogleConfig,\n GoogleInnerConfig,\n OIDCConfig,\n OIDCInnerConfig,\n SCIMConfig,\n SCIMInnerConfig,\n SettingsConfig,\n SettingsInnerConfig,\n SMTPConfig,\n SMTPInnerConfig,\n} from \"@budibase/types\"\nimport { DocumentType, SEPARATOR } from \"../constants\"\nimport { CacheKey, TTL, withCache } from \"../cache\"\nimport * as context from \"../context\"\nimport env from \"../environment\"\nimport environment from \"../environment\"\n\n// UTILS\n\n/**\n * Generates a new configuration ID.\n * @returns {string} The new configuration ID which the config doc can be stored under.\n */\nexport function generateConfigID(type: ConfigType) {\n return `${DocumentType.CONFIG}${SEPARATOR}${type}`\n}\n\nexport async function getConfig<T extends Config>(\n type: ConfigType\n): Promise<T | undefined> {\n const db = context.getGlobalDB()\n try {\n // await to catch error\n return (await db.get(generateConfigID(type))) as T\n } catch (e: any) {\n if (e.status === 404) {\n return\n }\n throw e\n }\n}\n\nexport async function save(\n config: Config\n): Promise<{ id: string; rev: string }> {\n const db = context.getGlobalDB()\n return db.put(config)\n}\n\n// SETTINGS\n\nexport async function getSettingsConfigDoc(): Promise<SettingsConfig> {\n let config = await getConfig<SettingsConfig>(ConfigType.SETTINGS)\n\n if (!config) {\n config = {\n _id: generateConfigID(ConfigType.SETTINGS),\n type: ConfigType.SETTINGS,\n config: {},\n }\n }\n\n // overridden fields\n config.config.platformUrl = await getPlatformUrl({\n tenantAware: true,\n config: config.config,\n })\n config.config.analyticsEnabled = await analyticsEnabled({\n config: config.config,\n })\n\n return config\n}\n\nexport async function getSettingsConfig(): Promise<SettingsInnerConfig> {\n return (await getSettingsConfigDoc()).config\n}\n\nexport async function getPlatformUrl(\n opts: { tenantAware: boolean; config?: SettingsInnerConfig } = {\n tenantAware: true,\n }\n) {\n let platformUrl = env.PLATFORM_URL || \"http://localhost:10000\"\n\n if (!env.SELF_HOSTED && env.MULTI_TENANCY && opts.tenantAware) {\n // cloud and multi tenant - add the tenant to the default platform url\n const tenantId = context.getTenantId()\n if (!platformUrl.includes(\"localhost:\")) {\n platformUrl = platformUrl.replace(\"://\", `://${tenantId}.`)\n }\n } else if (env.SELF_HOSTED) {\n const config = opts?.config\n ? opts.config\n : // direct to db to prevent infinite loop\n (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config\n if (config?.platformUrl) {\n platformUrl = config.platformUrl\n }\n }\n\n return platformUrl\n}\n\nexport const analyticsEnabled = async (opts?: {\n config?: SettingsInnerConfig\n}) => {\n // cloud - always use the environment variable\n if (!env.SELF_HOSTED) {\n return !!env.ENABLE_ANALYTICS\n }\n\n // self host - prefer the settings doc\n // use cache as events have high throughput\n const enabledInDB = await withCache(\n CacheKey.ANALYTICS_ENABLED,\n TTL.ONE_DAY,\n async () => {\n const config = opts?.config\n ? opts.config\n : // direct to db to prevent infinite loop\n (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config\n\n // need to do explicit checks in case the field is not set\n if (config?.analyticsEnabled === false) {\n return false\n } else if (config?.analyticsEnabled === true) {\n return true\n }\n }\n )\n\n if (enabledInDB !== undefined) {\n return enabledInDB\n }\n\n // fallback to the environment variable\n // explicitly check for 0 or false here, undefined or otherwise is treated as true\n const envEnabled: any = env.ENABLE_ANALYTICS\n if (envEnabled === 0 || envEnabled === false) {\n return false\n } else {\n return true\n }\n}\n\n// GOOGLE\n\nasync function getGoogleConfigDoc(): Promise<GoogleConfig | undefined> {\n return await getConfig<GoogleConfig>(ConfigType.GOOGLE)\n}\n\nexport async function getGoogleConfig(): Promise<\n GoogleInnerConfig | undefined\n> {\n const config = await getGoogleConfigDoc()\n return config?.config\n}\n\nexport async function getGoogleDatasourceConfig(): Promise<\n GoogleInnerConfig | undefined\n> {\n if (!env.SELF_HOSTED) {\n // always use the env vars in cloud\n return getDefaultGoogleConfig()\n }\n\n // prefer the config in self-host\n let config = await getGoogleConfig()\n\n // fallback to env vars\n if (!config || !config.activated) {\n config = getDefaultGoogleConfig()\n }\n\n return config\n}\n\nexport function getDefaultGoogleConfig(): GoogleInnerConfig | undefined {\n if (environment.GOOGLE_CLIENT_ID && environment.GOOGLE_CLIENT_SECRET) {\n return {\n clientID: environment.GOOGLE_CLIENT_ID!,\n clientSecret: environment.GOOGLE_CLIENT_SECRET!,\n activated: true,\n }\n }\n}\n\n// OIDC\n\nasync function getOIDCConfigDoc(): Promise<OIDCConfig | undefined> {\n return getConfig<OIDCConfig>(ConfigType.OIDC)\n}\n\nexport async function getOIDCConfig(): Promise<OIDCInnerConfig | undefined> {\n const config = (await getOIDCConfigDoc())?.config\n // default to the 0th config\n return config?.configs && config.configs[0]\n}\n\n/**\n * @param configId The config id of the inner config to retrieve\n */\nexport async function getOIDCConfigById(\n configId: string\n): Promise<OIDCInnerConfig | undefined> {\n const config = (await getConfig<OIDCConfig>(ConfigType.OIDC))?.config\n return config && config.configs.filter((c: any) => c.uuid === configId)[0]\n}\n\n// SMTP\n\nexport async function getSMTPConfigDoc(): Promise<SMTPConfig | undefined> {\n return getConfig<SMTPConfig>(ConfigType.SMTP)\n}\n\nexport async function getSMTPConfig(\n isAutomation?: boolean\n): Promise<SMTPInnerConfig | undefined> {\n const config = await getSMTPConfigDoc()\n if (config) {\n return config.config\n }\n\n // always allow fallback in self host\n // in cloud don't allow for automations\n const allowFallback = env.SELF_HOSTED || !isAutomation\n\n // Use an SMTP fallback configuration from env variables\n if (env.SMTP_FALLBACK_ENABLED && allowFallback) {\n return {\n port: env.SMTP_PORT,\n host: env.SMTP_HOST!,\n secure: false,\n from: env.SMTP_FROM_ADDRESS!,\n auth: {\n user: env.SMTP_USER!,\n pass: env.SMTP_PASSWORD!,\n },\n }\n }\n}\n\n// SCIM\n\nexport async function getSCIMConfig(): Promise<SCIMInnerConfig | undefined> {\n const config = await getConfig<SCIMConfig>(ConfigType.SCIM)\n return config?.config\n}\n", "export * from \"./configs\"\n", "import * as configs from \"../configs\"\n\n// wrapper utility function\nexport const enabled = async () => {\n return configs.analyticsEnabled()\n}\n", "import { Event } from \"@budibase/types\"\nimport { CacheKey, TTL } from \"../../../cache/generic\"\nimport * as cache from \"../../../cache/generic\"\nimport * as context from \"../../../context\"\n\ntype RateLimitedEvent =\n | Event.SERVED_BUILDER\n | Event.SERVED_APP_PREVIEW\n | Event.SERVED_APP\n\nconst isRateLimited = (event: Event): event is RateLimitedEvent => {\n return (\n event === Event.SERVED_BUILDER ||\n event === Event.SERVED_APP_PREVIEW ||\n event === Event.SERVED_APP\n )\n}\n\nconst isPerApp = (event: RateLimitedEvent) => {\n return event === Event.SERVED_APP_PREVIEW || event === Event.SERVED_APP\n}\n\ninterface EventProperties {\n timestamp: number\n}\n\nenum RateLimit {\n CALENDAR_DAY = \"calendarDay\",\n}\n\nconst RATE_LIMITS = {\n [Event.SERVED_APP]: RateLimit.CALENDAR_DAY,\n [Event.SERVED_APP_PREVIEW]: RateLimit.CALENDAR_DAY,\n [Event.SERVED_BUILDER]: RateLimit.CALENDAR_DAY,\n}\n\n/**\n * Check if this event should be sent right now\n * Return false to signal the event SHOULD be sent\n * Return true to signal the event should NOT be sent\n */\nexport const limited = async (event: Event): Promise<boolean> => {\n // not a rate limited event -- send\n if (!isRateLimited(event)) {\n return false\n }\n\n const cachedEvent = await readEvent(event)\n if (cachedEvent) {\n const timestamp = new Date(cachedEvent.timestamp)\n const limit = RATE_LIMITS[event]\n switch (limit) {\n case RateLimit.CALENDAR_DAY: {\n // get midnight at the start of the next day for the timestamp\n timestamp.setDate(timestamp.getDate() + 1)\n timestamp.setHours(0, 0, 0, 0)\n\n // if we have passed the threshold into the next day\n if (Date.now() > timestamp.getTime()) {\n // update the timestamp in the event -- send\n await recordEvent(event, { timestamp: Date.now() })\n return false\n } else {\n // still within the limited period -- don't send\n return true\n }\n }\n }\n } else {\n // no event present i.e. expired -- send\n await recordEvent(event, { timestamp: Date.now() })\n return false\n }\n}\n\nconst eventKey = (event: RateLimitedEvent) => {\n let key = `${CacheKey.EVENTS_RATE_LIMIT}:${event}`\n if (isPerApp(event)) {\n key = key + \":\" + context.getAppId()\n }\n return key\n}\n\nconst readEvent = async (\n event: RateLimitedEvent\n): Promise<EventProperties | undefined> => {\n const key = eventKey(event)\n const result = await cache.get(key)\n return result as EventProperties\n}\n\nconst recordEvent = async (\n event: RateLimitedEvent,\n properties: EventProperties\n) => {\n const key = eventKey(event)\n const limit = RATE_LIMITS[event]\n let ttl\n switch (limit) {\n case RateLimit.CALENDAR_DAY: {\n ttl = TTL.ONE_DAY\n }\n }\n\n await cache.store(key, properties, ttl)\n}\n", "import PostHog from \"posthog-node\"\nimport { Event, Identity, Group, BaseEvent } from \"@budibase/types\"\nimport { EventProcessor } from \"../types\"\nimport env from \"../../../environment\"\nimport * as context from \"../../../context\"\nimport * as rateLimiting from \"./rateLimiting\"\n\nconst EXCLUDED_EVENTS: Event[] = [\n Event.USER_UPDATED,\n Event.EMAIL_SMTP_UPDATED,\n Event.AUTH_SSO_UPDATED,\n Event.APP_UPDATED,\n Event.ROLE_UPDATED,\n Event.DATASOURCE_UPDATED,\n Event.QUERY_UPDATED,\n Event.TABLE_UPDATED,\n Event.VIEW_UPDATED,\n Event.VIEW_FILTER_UPDATED,\n Event.VIEW_CALCULATION_UPDATED,\n Event.AUTOMATION_TRIGGER_UPDATED,\n Event.USER_GROUP_UPDATED,\n]\n\nexport default class PosthogProcessor implements EventProcessor {\n posthog: PostHog\n\n constructor(token: string | undefined) {\n if (!token) {\n throw new Error(\"Posthog token is not defined\")\n }\n this.posthog = new PostHog(token)\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: BaseEvent,\n timestamp?: string | number\n ): Promise<void> {\n // don't send excluded events\n if (EXCLUDED_EVENTS.includes(event)) {\n return\n }\n\n if (await rateLimiting.limited(event)) {\n return\n }\n\n properties = this.clearPIIProperties(properties)\n\n properties.version = env.VERSION\n properties.service = env.SERVICE\n properties.environment = identity.environment\n properties.hosting = identity.hosting\n\n const appId = context.getAppId()\n if (appId) {\n properties.appId = appId\n }\n\n const payload: any = { distinctId: identity.id, event, properties }\n\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n\n // add groups to the event\n if (identity.installationId || identity.tenantId) {\n payload.groups = {}\n if (identity.installationId) {\n payload.groups.installation = identity.installationId\n payload.properties.installationId = identity.installationId\n }\n if (identity.tenantId) {\n payload.groups.tenant = identity.tenantId\n payload.properties.tenantId = identity.tenantId\n }\n }\n\n this.posthog.capture(payload)\n }\n\n clearPIIProperties(properties: any) {\n if (properties.email) {\n delete properties.email\n }\n if (properties.audited) {\n delete properties.audited\n }\n return properties\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n const payload: any = { distinctId: identity.id, properties: identity }\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n this.posthog.identify(payload)\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n const payload: any = {\n distinctId: group.id,\n groupType: group.type,\n groupKey: group.id,\n properties: group,\n }\n\n if (timestamp) {\n payload.timestamp = new Date(timestamp)\n }\n this.posthog.groupIdentify(payload)\n }\n\n shutdown() {\n this.posthog.shutdown()\n }\n}\n", "import PosthogProcessor from \"./PosthogProcessor\"\nexport default PosthogProcessor\n", "import { Event, Identity, Group, IdentityType } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport env from \"../../environment\"\nimport * as analytics from \"../analytics\"\nimport PosthogProcessor from \"./posthog\"\n\n/**\n * Events that are always captured.\n */\nconst EVENT_WHITELIST = [\n Event.INSTALLATION_VERSION_UPGRADED,\n Event.INSTALLATION_VERSION_DOWNGRADED,\n]\nconst IDENTITY_WHITELIST = [IdentityType.INSTALLATION, IdentityType.TENANT]\n\nexport default class AnalyticsProcessor implements EventProcessor {\n posthog: PosthogProcessor | undefined\n\n constructor() {\n if (env.POSTHOG_TOKEN && !env.isTest()) {\n this.posthog = new PosthogProcessor(env.POSTHOG_TOKEN)\n }\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void> {\n if (!EVENT_WHITELIST.includes(event) && !(await analytics.enabled())) {\n return\n }\n if (this.posthog) {\n await this.posthog.processEvent(event, identity, properties, timestamp)\n }\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n // Group indentifications (tenant and installation) always on\n if (\n !IDENTITY_WHITELIST.includes(identity.type) &&\n !(await analytics.enabled())\n ) {\n return\n }\n if (this.posthog) {\n await this.posthog.identify(identity, timestamp)\n }\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n // Group indentifications (tenant and installation) always on\n if (this.posthog) {\n await this.posthog.identifyGroup(group, timestamp)\n }\n }\n\n shutdown() {\n if (this.posthog) {\n this.posthog.shutdown()\n }\n }\n}\n", "import { Event, Identity, Group } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport env from \"../../environment\"\n\nconst skipLogging = env.SELF_HOSTED && !env.isDev()\n\nexport default class LoggingProcessor implements EventProcessor {\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string\n ): Promise<void> {\n if (skipLogging) {\n return\n }\n console.log(`[audit] [identityType=${identity.type}] ${event}`, properties)\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n if (skipLogging) {\n return\n }\n console.log(`[audit] identified`, identity)\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n if (skipLogging) {\n return\n }\n console.log(`[audit] group identified`, group)\n }\n\n shutdown(): void {\n // no-op\n }\n}\n", "import env from \"../environment\"\nexport * from \"../docIds/newid\"\nconst bcrypt = env.JS_BCRYPT ? require(\"bcryptjs\") : require(\"bcrypt\")\n\nconst SALT_ROUNDS = env.SALT_ROUNDS || 10\n\nexport async function hash(data: string) {\n const salt = await bcrypt.genSalt(SALT_ROUNDS)\n return bcrypt.hash(data, salt)\n}\n\nexport async function compare(data: string, encrypted: string) {\n return bcrypt.compare(data, encrypted)\n}\n", "import { getAllApps } from \"../db\"\nimport { Header, MAX_VALID_DATE, DocumentType, SEPARATOR } from \"../constants\"\nimport env from \"../environment\"\nimport * as tenancy from \"../tenancy\"\nimport * as context from \"../context\"\nimport {\n App,\n AuditedEventFriendlyName,\n Ctx,\n Event,\n TenantResolutionStrategy,\n} from \"@budibase/types\"\nimport { SetOption } from \"cookies\"\nconst jwt = require(\"jsonwebtoken\")\n\nconst APP_PREFIX = DocumentType.APP + SEPARATOR\nconst PROD_APP_PREFIX = \"/app/\"\n\nconst BUILDER_PREVIEW_PATH = \"/app/preview\"\nconst BUILDER_PREFIX = \"/builder\"\nconst BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`\nconst PUBLIC_API_PREFIX = \"/api/public/v\"\n\nfunction confirmAppId(possibleAppId: string | undefined) {\n return possibleAppId && possibleAppId.startsWith(APP_PREFIX)\n ? possibleAppId\n : undefined\n}\n\nexport async function resolveAppUrl(ctx: Ctx) {\n const appUrl = ctx.path.split(\"/\")[2]\n let possibleAppUrl = `/${appUrl.toLowerCase()}`\n\n let tenantId: string | null = context.getTenantId()\n if (env.MULTI_TENANCY) {\n // always use the tenant id from the subdomain in multi tenancy\n // this ensures the logged-in user tenant id doesn't overwrite\n // e.g. in the case of viewing a public app while already logged-in to another tenant\n tenantId = tenancy.getTenantIDFromCtx(ctx, {\n includeStrategies: [TenantResolutionStrategy.SUBDOMAIN],\n })\n }\n\n // search prod apps for a url that matches\n const apps: App[] = await context.doInTenant(\n tenantId,\n () => getAllApps({ dev: false }) as Promise<App[]>\n )\n const app = apps.filter(\n a => a.url && a.url.toLowerCase() === possibleAppUrl\n )[0]\n\n return app && app.appId ? app.appId : undefined\n}\n\nexport function isServingApp(ctx: Ctx) {\n // dev app\n if (ctx.path.startsWith(`/${APP_PREFIX}`)) {\n return true\n }\n // prod app\n if (ctx.path.startsWith(PROD_APP_PREFIX)) {\n return true\n }\n return false\n}\n\nexport function isServingBuilder(ctx: Ctx): boolean {\n return ctx.path.startsWith(BUILDER_APP_PREFIX)\n}\n\nexport function isServingBuilderPreview(ctx: Ctx): boolean {\n return ctx.path.startsWith(BUILDER_PREVIEW_PATH)\n}\n\nexport function isPublicApiRequest(ctx: Ctx): boolean {\n return ctx.path.startsWith(PUBLIC_API_PREFIX)\n}\n\n/**\n * Given a request tries to find the appId, which can be located in various places\n * @param {object} ctx The main request body to look through.\n * @returns {string|undefined} If an appId was found it will be returned.\n */\nexport async function getAppIdFromCtx(ctx: Ctx) {\n // look in headers\n const options = [ctx.request.headers[Header.APP_ID]]\n let appId\n for (let option of options) {\n appId = confirmAppId(option as string)\n if (appId) {\n break\n }\n }\n\n // look in body\n if (!appId && ctx.request.body && ctx.request.body.appId) {\n appId = confirmAppId(ctx.request.body.appId)\n }\n\n // look in the path\n const pathId = parseAppIdFromUrl(ctx.path)\n if (!appId && pathId) {\n appId = confirmAppId(pathId)\n }\n\n // lookup using custom url - prod apps only\n // filter out the builder preview path which collides with the prod app path\n // to ensure we don't load all apps excessively\n const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH)\n const isViewingProdApp =\n ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview\n if (!appId && isViewingProdApp) {\n appId = confirmAppId(await resolveAppUrl(ctx))\n }\n\n // look in the referer - builder only\n // make sure this is performed after prod app url resolution, in case the\n // referer header is present from a builder redirect\n const referer = ctx.request.headers.referer\n if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {\n const refererId = parseAppIdFromUrl(ctx.request.headers.referer)\n appId = confirmAppId(refererId)\n }\n\n return appId\n}\n\nfunction parseAppIdFromUrl(url?: string) {\n if (!url) {\n return\n }\n return url.split(\"/\").find(subPath => subPath.startsWith(APP_PREFIX))\n}\n\n/**\n * opens the contents of the specified encrypted JWT.\n * @return {object} the contents of the token.\n */\nexport function openJwt(token: string) {\n if (!token) {\n return token\n }\n try {\n return jwt.verify(token, env.JWT_SECRET)\n } catch (e) {\n if (env.JWT_SECRET_FALLBACK) {\n // fallback to enable rotation\n return jwt.verify(token, env.JWT_SECRET_FALLBACK)\n } else {\n throw e\n }\n }\n}\n\nexport function isValidInternalAPIKey(apiKey: string) {\n if (env.INTERNAL_API_KEY && env.INTERNAL_API_KEY === apiKey) {\n return true\n }\n // fallback to enable rotation\n if (\n env.INTERNAL_API_KEY_FALLBACK &&\n env.INTERNAL_API_KEY_FALLBACK === apiKey\n ) {\n return true\n }\n return false\n}\n\n/**\n * Get a cookie from context, and decrypt if necessary.\n * @param {object} ctx The request which is to be manipulated.\n * @param {string} name The name of the cookie to get.\n */\nexport function getCookie(ctx: Ctx, name: string) {\n const cookie = ctx.cookies.get(name)\n\n if (!cookie) {\n return cookie\n }\n\n return openJwt(cookie)\n}\n\n/**\n * Store a cookie for the request - it will not expire.\n * @param {object} ctx The request which is to be manipulated.\n * @param {string} name The name of the cookie to set.\n * @param {string|object} value The value of cookie which will be set.\n * @param {object} opts options like whether to sign.\n */\nexport function setCookie(\n ctx: Ctx,\n value: any,\n name = \"builder\",\n opts = { sign: true }\n) {\n if (value && opts && opts.sign) {\n value = jwt.sign(value, env.JWT_SECRET)\n }\n\n const config: SetOption = {\n expires: MAX_VALID_DATE,\n path: \"/\",\n httpOnly: false,\n overwrite: true,\n }\n\n if (env.COOKIE_DOMAIN) {\n config.domain = env.COOKIE_DOMAIN\n }\n\n ctx.cookies.set(name, value, config)\n}\n\n/**\n * Utility function, simply calls setCookie with an empty string for value\n */\nexport function clearCookie(ctx: Ctx, name: string) {\n setCookie(ctx, null, name)\n}\n\n/**\n * Checks if the API call being made (based on the provided ctx object) is from the client. If\n * the call is not from a client app then it is from the builder.\n * @param {object} ctx The koa context object to be tested.\n * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder).\n */\nexport function isClient(ctx: Ctx) {\n return ctx.headers[Header.TYPE] === \"client\"\n}\n\nexport function timeout(timeMs: number) {\n return new Promise(resolve => setTimeout(resolve, timeMs))\n}\n\nexport function isAudited(event: Event) {\n return !!AuditedEventFriendlyName[event]\n}\n", "export function validEmail(value: string) {\n return (\n value &&\n !!value.match(\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n )\n )\n}\n", "export * from \"./hashing\"\nexport * from \"./utils\"\nexport * from \"./stringUtils\"\n", "import events from \"events\"\nimport { timeout } from \"../utils\"\n\n/**\n * Bull works with a Job wrapper around all messages that contains a lot more information about\n * the state of the message, this object constructor implements the same schema of Bull jobs\n * for the sake of maintaining API consistency.\n * @param {string} queue The name of the queue which the message will be carried on.\n * @param {object} message The JSON message which will be passed back to the consumer.\n * @returns {Object} A new job which can now be put onto the queue, this is mostly an\n * internal structure so that an in memory queue can be easily swapped for a Bull queue.\n */\nfunction newJob(queue: string, message: any) {\n return {\n timestamp: Date.now(),\n queue: queue,\n data: message,\n }\n}\n\n/**\n * This is designed to replicate Bull (https://github.com/OptimalBits/bull) in memory as a sort of mock.\n * It is relatively simple, using an event emitter internally to register when messages are available\n * to the consumers - in can support many inputs and many consumers.\n */\nclass InMemoryQueue {\n _name: string\n _opts?: any\n _messages: any[]\n _emitter: EventEmitter\n _runCount: number\n _addCount: number\n /**\n * The constructor the queue, exactly the same as that of Bulls.\n * @param {string} name The name of the queue which is being configured.\n * @param {object|null} opts This is not used by the in memory queue as there is no real use\n * case when in memory, but is the same API as Bull\n */\n constructor(name: string, opts = null) {\n this._name = name\n this._opts = opts\n this._messages = []\n this._emitter = new events.EventEmitter()\n this._runCount = 0\n this._addCount = 0\n }\n\n /**\n * Same callback API as Bull, each callback passed to this will consume messages as they are\n * available. Please note this is a queue service, not a notification service, so each\n * consumer will receive different messages.\n * @param {function<object>} func The callback function which will return a \"Job\", the same\n * as the Bull API, within this job the property \"data\" contains the JSON message. Please\n * note this is incredibly limited compared to Bull as in reality the Job would contain\n * a lot more information about the queue and current status of Bull cluster.\n */\n process(func: any) {\n this._emitter.on(\"message\", async () => {\n if (this._messages.length <= 0) {\n return\n }\n let msg = this._messages.shift()\n let resp = func(msg)\n if (resp.then != null) {\n await resp\n }\n this._runCount++\n })\n }\n\n // simply puts a message to the queue and emits to the queue for processing\n /**\n * Simple function to replicate the add message functionality of Bull, putting\n * a new message on the queue. This then emits an event which will be used to\n * return the message to a consumer (if one is attached).\n * @param {object} msg A message to be transported over the queue, this should be\n * a JSON message as this is required by Bull.\n * @param {boolean} repeat serves no purpose for the import queue.\n */\n // eslint-disable-next-line no-unused-vars\n add(msg: any, repeat: boolean) {\n if (typeof msg !== \"object\") {\n throw \"Queue only supports carrying JSON.\"\n }\n this._messages.push(newJob(this._name, msg))\n this._addCount++\n this._emitter.emit(\"message\")\n }\n\n /**\n * replicating the close function from bull, which waits for jobs to finish.\n */\n async close() {\n return []\n }\n\n /**\n * This removes a cron which has been implemented, this is part of Bull API.\n * @param {string} cronJobId The cron which is to be removed.\n */\n removeRepeatableByKey(cronJobId: string) {\n // TODO: implement for testing\n console.log(cronJobId)\n }\n\n /**\n * Implemented for tests\n */\n getRepeatableJobs() {\n return []\n }\n\n // eslint-disable-next-line no-unused-vars\n removeJobs(pattern: string) {\n // no-op\n }\n\n /**\n * Implemented for tests\n */\n async clean() {\n return []\n }\n\n async getJob() {\n return {}\n }\n\n on() {\n // do nothing\n return this\n }\n\n async waitForCompletion() {\n do {\n await timeout(50)\n } while (this._addCount < this._runCount)\n }\n}\n\nexport default InMemoryQueue\n", "export enum JobQueue {\n AUTOMATION = \"automationQueue\",\n APP_BACKUP = \"appBackupQueue\",\n AUDIT_LOG = \"auditLogQueue\",\n SYSTEM_EVENT_QUEUE = \"systemEventQueue\",\n}\n", "import { Job, JobId, Queue } from \"bull\"\nimport { JobQueue } from \"./constants\"\nimport * as context from \"../context\"\n\nexport type StalledFn = (job: Job) => Promise<void>\n\nexport function addListeners(\n queue: Queue,\n jobQueue: JobQueue,\n removeStalledCb?: StalledFn\n) {\n logging(queue, jobQueue)\n if (removeStalledCb) {\n handleStalled(queue, removeStalledCb)\n }\n}\n\nfunction handleStalled(queue: Queue, removeStalledCb?: StalledFn) {\n queue.on(\"stalled\", async (job: Job) => {\n if (removeStalledCb) {\n await removeStalledCb(job)\n } else if (job.opts.repeat) {\n const jobId = job.id\n const repeatJobs = await queue.getRepeatableJobs()\n for (let repeatJob of repeatJobs) {\n if (repeatJob.id === jobId) {\n await queue.removeRepeatableByKey(repeatJob.key)\n }\n }\n console.log(`jobId=${jobId} disabled`)\n }\n })\n}\n\nfunction getLogParams(\n eventType: QueueEventType,\n event: BullEvent,\n opts: {\n job?: Job\n jobId?: JobId\n error?: Error\n } = {},\n extra: any = {}\n) {\n const message = `[BULL] ${eventType}=${event}`\n const err = opts.error\n\n const bullLog = {\n _logKey: \"bull\",\n eventType,\n event,\n job: opts.job,\n jobId: opts.jobId || opts.job?.id,\n ...extra,\n }\n\n let automationLog\n if (opts.job?.data?.automation) {\n automationLog = {\n _logKey: \"automation\",\n trigger: opts.job\n ? opts.job.data.automation.definition.trigger.event\n : undefined,\n }\n }\n\n return [message, err, bullLog, automationLog]\n}\n\nenum BullEvent {\n ERROR = \"error\",\n WAITING = \"waiting\",\n ACTIVE = \"active\",\n STALLED = \"stalled\",\n PROGRESS = \"progress\",\n COMPLETED = \"completed\",\n FAILED = \"failed\",\n PAUSED = \"paused\",\n RESUMED = \"resumed\",\n CLEANED = \"cleaned\",\n DRAINED = \"drained\",\n REMOVED = \"removed\",\n}\n\nenum QueueEventType {\n AUTOMATION_EVENT = \"automation-event\",\n APP_BACKUP_EVENT = \"app-backup-event\",\n AUDIT_LOG_EVENT = \"audit-log-event\",\n SYSTEM_EVENT = \"system-event\",\n}\n\nconst EventTypeMap: { [key in JobQueue]: QueueEventType } = {\n [JobQueue.AUTOMATION]: QueueEventType.AUTOMATION_EVENT,\n [JobQueue.APP_BACKUP]: QueueEventType.APP_BACKUP_EVENT,\n [JobQueue.AUDIT_LOG]: QueueEventType.AUDIT_LOG_EVENT,\n [JobQueue.SYSTEM_EVENT_QUEUE]: QueueEventType.SYSTEM_EVENT,\n}\n\nfunction logging(queue: Queue, jobQueue: JobQueue) {\n const eventType = EventTypeMap[jobQueue]\n\n function doInJobContext(job: Job, task: any) {\n // if this is an automation job try to get the app id\n const appId = job.data.event?.appId\n if (appId) {\n return context.doInContext(appId, task)\n } else {\n task()\n }\n }\n\n queue\n .on(BullEvent.STALLED, async (job: Job) => {\n // A job has been marked as stalled. This is useful for debugging job\n // workers that crash or pause the event loop.\n await doInJobContext(job, () => {\n console.error(...getLogParams(eventType, BullEvent.STALLED, { job }))\n })\n })\n .on(BullEvent.ERROR, (error: any) => {\n // An error occurred.\n console.error(...getLogParams(eventType, BullEvent.ERROR, { error }))\n })\n\n if (process.env.NODE_DEBUG?.includes(\"bull\")) {\n queue\n .on(BullEvent.WAITING, (jobId: JobId) => {\n // A Job is waiting to be processed as soon as a worker is idling.\n console.info(...getLogParams(eventType, BullEvent.WAITING, { jobId }))\n })\n .on(BullEvent.ACTIVE, async (job: Job, jobPromise: any) => {\n // A job has started. You can use `jobPromise.cancel()`` to abort it.\n await doInJobContext(job, () => {\n console.info(...getLogParams(eventType, BullEvent.ACTIVE, { job }))\n })\n })\n .on(BullEvent.PROGRESS, async (job: Job, progress: any) => {\n // A job's progress was updated\n await doInJobContext(job, () => {\n console.info(\n ...getLogParams(\n eventType,\n BullEvent.PROGRESS,\n { job },\n { progress }\n )\n )\n })\n })\n .on(BullEvent.COMPLETED, async (job: Job, result) => {\n // A job successfully completed with a `result`.\n await doInJobContext(job, () => {\n console.info(\n ...getLogParams(eventType, BullEvent.COMPLETED, { job }, { result })\n )\n })\n })\n .on(BullEvent.FAILED, async (job: Job, error: any) => {\n // A job failed with reason `err`!\n await doInJobContext(job, () => {\n console.error(\n ...getLogParams(eventType, BullEvent.FAILED, { job, error })\n )\n })\n })\n .on(BullEvent.PAUSED, () => {\n // The queue has been paused.\n console.info(...getLogParams(eventType, BullEvent.PAUSED))\n })\n .on(BullEvent.RESUMED, () => {\n // The queue has been resumed.\n console.info(...getLogParams(eventType, BullEvent.RESUMED))\n })\n .on(BullEvent.CLEANED, (jobs: Job[], type: string) => {\n // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned\n // jobs, and `type` is the type of jobs cleaned.\n console.info(\n ...getLogParams(\n eventType,\n BullEvent.CLEANED,\n {},\n { length: jobs.length, type }\n )\n )\n })\n .on(BullEvent.DRAINED, () => {\n // Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed)\n console.info(...getLogParams(eventType, BullEvent.DRAINED))\n })\n .on(BullEvent.REMOVED, (job: Job) => {\n // A job successfully removed.\n console.info(...getLogParams(eventType, BullEvent.REMOVED, { job }))\n })\n }\n}\n", "import env from \"../environment\"\nimport { getRedisOptions } from \"../redis/utils\"\nimport { JobQueue } from \"./constants\"\nimport InMemoryQueue from \"./inMemoryQueue\"\nimport BullQueue from \"bull\"\nimport { addListeners, StalledFn } from \"./listeners\"\nimport * as timers from \"../timers\"\n\nconst CLEANUP_PERIOD_MS = 60 * 1000\nlet QUEUES: BullQueue.Queue[] | InMemoryQueue[] = []\nlet cleanupInterval: NodeJS.Timeout\n\nasync function cleanup() {\n for (let queue of QUEUES) {\n await queue.clean(CLEANUP_PERIOD_MS, \"completed\")\n }\n}\n\nexport function createQueue<T>(\n jobQueue: JobQueue,\n opts: { removeStalledCb?: StalledFn } = {}\n): BullQueue.Queue<T> {\n const { opts: redisOpts, redisProtocolUrl } = getRedisOptions()\n const queueConfig: any = redisProtocolUrl || { redis: redisOpts }\n let queue: any\n if (!env.isTest()) {\n queue = new BullQueue(jobQueue, queueConfig)\n } else {\n queue = new InMemoryQueue(jobQueue, queueConfig)\n }\n addListeners(queue, jobQueue, opts?.removeStalledCb)\n QUEUES.push(queue)\n if (!cleanupInterval && !env.isTest()) {\n cleanupInterval = timers.set(cleanup, CLEANUP_PERIOD_MS)\n // fire off an initial cleanup\n cleanup().catch(err => {\n console.error(`Unable to cleanup automation queue initially - ${err}`)\n })\n }\n return queue\n}\n\nexport async function shutdown() {\n if (cleanupInterval) {\n timers.clear(cleanupInterval)\n }\n if (QUEUES.length) {\n for (let queue of QUEUES) {\n await queue.close()\n }\n QUEUES = []\n }\n console.log(\"Queues shutdown\")\n}\n", "export * from \"./queue\"\nexport * from \"./constants\"\n", "import {\n Event,\n Identity,\n Group,\n IdentityType,\n AuditLogQueueEvent,\n AuditLogFn,\n HostInfo,\n} from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\nimport { getAppId, doInTenant, getTenantId } from \"../../context\"\nimport BullQueue from \"bull\"\nimport { createQueue, JobQueue } from \"../../queue\"\nimport { isAudited } from \"../../utils\"\nimport env from \"../../environment\"\n\nexport default class AuditLogsProcessor implements EventProcessor {\n static auditLogsEnabled = false\n static auditLogQueue: BullQueue.Queue<AuditLogQueueEvent>\n\n // can't use constructor as need to return promise\n static init(fn: AuditLogFn) {\n AuditLogsProcessor.auditLogsEnabled = true\n const writeAuditLogs = fn\n AuditLogsProcessor.auditLogQueue = createQueue<AuditLogQueueEvent>(\n JobQueue.AUDIT_LOG\n )\n return AuditLogsProcessor.auditLogQueue.process(async job => {\n return doInTenant(job.data.tenantId, async () => {\n let properties = job.data.properties\n if (properties.audited) {\n properties = {\n ...properties,\n ...properties.audited,\n }\n delete properties.audited\n }\n\n // this feature is disabled by default due to privacy requirements\n // in some countries - available as env var in-case it is desired\n // in self host deployments\n let hostInfo: HostInfo | undefined = {}\n if (env.ENABLE_AUDIT_LOG_IP_ADDR) {\n hostInfo = job.data.opts.hostInfo\n }\n\n await writeAuditLogs(job.data.event, properties, {\n userId: job.data.opts.userId,\n timestamp: job.data.opts.timestamp,\n appId: job.data.opts.appId,\n hostInfo,\n })\n })\n })\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string\n ): Promise<void> {\n if (AuditLogsProcessor.auditLogsEnabled && isAudited(event)) {\n // only audit log actual events, don't include backfills\n const userId =\n identity.type === IdentityType.USER ? identity.id : undefined\n // add to the event queue, rather than just writing immediately\n await AuditLogsProcessor.auditLogQueue.add({\n event,\n properties,\n opts: {\n userId,\n timestamp,\n appId: getAppId(),\n hostInfo: identity.hostInfo,\n },\n tenantId: getTenantId(),\n })\n }\n }\n\n async identify(identity: Identity, timestamp?: string | number) {\n // no-op\n }\n\n async identifyGroup(group: Group, timestamp?: string | number) {\n // no-op\n }\n\n shutdown(): void {\n AuditLogsProcessor.auditLogQueue?.close()\n }\n}\n", "import { Event, Identity, Group } from \"@budibase/types\"\nimport { EventProcessor } from \"./types\"\n\nexport default class Processor implements EventProcessor {\n initialised: boolean = false\n processors: EventProcessor[] = []\n\n constructor(processors: EventProcessor[]) {\n this.processors = processors\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n await eventProcessor.processEvent(event, identity, properties, timestamp)\n }\n }\n\n async identify(\n identity: Identity,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.identify) {\n await eventProcessor.identify(identity, timestamp)\n }\n }\n }\n\n async identifyGroup(\n identity: Group,\n timestamp?: string | number\n ): Promise<void> {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.identifyGroup) {\n await eventProcessor.identifyGroup(identity, timestamp)\n }\n }\n }\n\n shutdown() {\n for (const eventProcessor of this.processors) {\n if (eventProcessor.shutdown) {\n eventProcessor.shutdown()\n }\n }\n }\n}\n", "import AnalyticsProcessor from \"./AnalyticsProcessor\"\nimport LoggingProcessor from \"./LoggingProcessor\"\nimport AuditLogsProcessor from \"./AuditLogsProcessor\"\nimport Processors from \"./Processors\"\nimport { AuditLogFn } from \"@budibase/types\"\n\nexport const analyticsProcessor = new AnalyticsProcessor()\nconst loggingProcessor = new LoggingProcessor()\nconst auditLogsProcessor = new AuditLogsProcessor()\n\nexport function init(auditingFn: AuditLogFn) {\n return AuditLogsProcessor.init(auditingFn)\n}\n\nexport const processors = new Processors([\n analyticsProcessor,\n loggingProcessor,\n auditLogsProcessor,\n])\n", "import { newid } from \"./utils\"\nimport * as events from \"./events\"\nimport { StaticDatabases } from \"./db\"\nimport { doWithDB } from \"./db\"\nimport { Installation, IdentityType, Database } from \"@budibase/types\"\nimport * as context from \"./context\"\nimport semver from \"semver\"\nimport { bustCache, withCache, TTL, CacheKey } from \"./cache/generic\"\nimport environment from \"./environment\"\n\nexport const getInstall = async (): Promise<Installation> => {\n return withCache(CacheKey.INSTALLATION, TTL.ONE_DAY, getInstallFromDB, {\n useTenancy: false,\n })\n}\nasync function createInstallDoc(platformDb: Database) {\n const install: Installation = {\n _id: StaticDatabases.PLATFORM_INFO.docs.install,\n installId: newid(),\n version: environment.VERSION,\n }\n try {\n const resp = await platformDb.put(install)\n install._rev = resp.rev\n return install\n } catch (err: any) {\n if (err.status === 409) {\n return getInstallFromDB()\n } else {\n throw err\n }\n }\n}\n\nexport const getInstallFromDB = async (): Promise<Installation> => {\n return doWithDB(\n StaticDatabases.PLATFORM_INFO.name,\n async (platformDb: any) => {\n let install: Installation\n try {\n install = await platformDb.get(\n StaticDatabases.PLATFORM_INFO.docs.install\n )\n } catch (e: any) {\n if (e.status === 404) {\n install = await createInstallDoc(platformDb)\n } else {\n throw e\n }\n }\n return install\n }\n )\n}\n\nconst updateVersion = async (version: string): Promise<boolean> => {\n try {\n await doWithDB(\n StaticDatabases.PLATFORM_INFO.name,\n async (platformDb: any) => {\n const install = await getInstall()\n install.version = version\n await platformDb.put(install)\n await bustCache(CacheKey.INSTALLATION)\n }\n )\n } catch (e: any) {\n if (e.status === 409) {\n // do nothing - version has already been updated\n // likely in clustered environment\n return false\n }\n throw e\n }\n return true\n}\n\nexport const checkInstallVersion = async (): Promise<void> => {\n const install = await getInstall()\n\n const currentVersion = install.version\n const newVersion = environment.VERSION\n\n if (currentVersion !== newVersion) {\n const isUpgrade = semver.gt(newVersion, currentVersion)\n const isDowngrade = semver.lt(newVersion, currentVersion)\n\n const success = await updateVersion(newVersion)\n\n if (success) {\n await context.doInIdentityContext(\n {\n _id: install.installId,\n type: IdentityType.INSTALLATION,\n },\n async () => {\n if (isUpgrade) {\n await events.installation.upgraded(currentVersion, newVersion)\n } else if (isDowngrade) {\n await events.installation.downgraded(currentVersion, newVersion)\n }\n }\n )\n await events.identification.identifyInstallationGroup(install.installId)\n }\n }\n}\n", "import * as context from \"../context\"\nimport * as identityCtx from \"../context/identity\"\nimport env from \"../environment\"\nimport {\n Hosting,\n User,\n Identity,\n IdentityType,\n Account,\n isCloudAccount,\n isSSOAccount,\n TenantGroup,\n CloudAccount,\n UserIdentity,\n InstallationGroup,\n UserContext,\n Group,\n isSSOUser,\n} from \"@budibase/types\"\nimport { processors } from \"./processors\"\nimport { newid } from \"../utils\"\nimport * as installation from \"../installation\"\nimport * as configs from \"../configs\"\nimport { withCache, TTL, CacheKey } from \"../cache/generic\"\n\n/**\n * An identity can be:\n * - account user (Self host)\n * - budibase user\n * - tenant\n * - installation\n */\nconst getCurrentIdentity = async (): Promise<Identity> => {\n let identityContext = identityCtx.getIdentity()\n const environment = getDeploymentEnvironment()\n\n let identityType\n\n if (!identityContext) {\n identityType = IdentityType.TENANT\n } else {\n identityType = identityContext.type\n }\n\n if (identityType === IdentityType.INSTALLATION) {\n const installationId = await getInstallationId()\n const hosting = getHostingFromEnv()\n return {\n id: formatDistinctId(installationId, identityType),\n hosting,\n type: identityType,\n installationId,\n environment,\n }\n } else if (identityType === IdentityType.TENANT) {\n const installationId = await getInstallationId()\n const tenantId = await getEventTenantId(context.getTenantId())\n const hosting = getHostingFromEnv()\n\n return {\n id: formatDistinctId(tenantId, identityType),\n type: identityType,\n hosting,\n installationId,\n tenantId,\n realTenantId: context.getTenantId(),\n environment,\n }\n } else if (identityType === IdentityType.USER) {\n const userContext = identityContext as UserContext\n const tenantId = await getEventTenantId(context.getTenantId())\n const installationId = await getInstallationId()\n\n const account = userContext.account\n let hosting\n if (account) {\n hosting = account.hosting\n } else {\n hosting = getHostingFromEnv()\n }\n\n return {\n id: userContext._id,\n type: identityType,\n hosting,\n installationId,\n tenantId,\n environment,\n hostInfo: userContext.hostInfo,\n }\n } else {\n throw new Error(\"Unknown identity type\")\n }\n}\n\nconst identifyInstallationGroup = async (\n installId: string,\n timestamp?: string | number\n): Promise<void> => {\n const id = installId\n const type = IdentityType.INSTALLATION\n const hosting = getHostingFromEnv()\n const version = env.VERSION\n const environment = getDeploymentEnvironment()\n\n const group: InstallationGroup = {\n id,\n type,\n hosting,\n version,\n environment,\n }\n\n await identifyGroup(group, timestamp)\n // need to create a normal identity for the group to be able to query it globally\n // match the posthog syntax to link this identity to the empty auto generated one\n await identify({ ...group, id: `$${type}_${id}` }, timestamp)\n}\n\nconst identifyTenantGroup = async (\n tenantId: string,\n account: Account | undefined,\n timestamp?: string | number\n): Promise<void> => {\n const id = await getEventTenantId(tenantId)\n const type = IdentityType.TENANT\n const installationId = await getInstallationId()\n const environment = getDeploymentEnvironment()\n\n let hosting: Hosting\n let profession: string | undefined\n let companySize: string | undefined\n\n if (account) {\n profession = account.profession\n companySize = account.size\n hosting = account.hosting\n } else {\n hosting = getHostingFromEnv()\n }\n\n const group: TenantGroup = {\n id,\n type,\n hosting,\n environment,\n installationId,\n profession,\n companySize,\n }\n\n await identifyGroup(group, timestamp)\n // need to create a normal identity for the group to be able to query it globally\n // match the posthog syntax to link this identity to the auto generated one\n await identify({ ...group, id: `$${type}_${id}` }, timestamp)\n}\n\nconst identifyUser = async (\n user: User,\n account: CloudAccount | undefined,\n timestamp?: string | number\n) => {\n const id = user._id as string\n const tenantId = await getEventTenantId(user.tenantId)\n const type = IdentityType.USER\n let builder = user.builder?.global || false\n let admin = user.admin?.global || false\n let providerType\n if (isSSOUser(user)) {\n providerType = user.providerType\n }\n const accountHolder = account?.budibaseUserId === user._id || false\n const verified =\n account && account?.budibaseUserId === user._id ? account.verified : false\n const installationId = await getInstallationId()\n const hosting = account ? account.hosting : getHostingFromEnv()\n const environment = getDeploymentEnvironment()\n\n const identity: UserIdentity = {\n id,\n type,\n hosting,\n installationId,\n tenantId,\n verified,\n accountHolder,\n providerType,\n builder,\n admin,\n environment,\n }\n\n await identify(identity, timestamp)\n}\n\nconst identifyAccount = async (account: Account) => {\n let id = account.accountId\n const tenantId = account.tenantId\n let type = IdentityType.USER\n let providerType = isSSOAccount(account) ? account.providerType : undefined\n const verified = account.verified\n const accountHolder = true\n const hosting = account.hosting\n const installationId = await getInstallationId()\n const environment = getDeploymentEnvironment()\n\n if (isCloudAccount(account)) {\n if (account.budibaseUserId) {\n // use the budibase user as the id if set\n id = account.budibaseUserId\n }\n }\n\n const identity: UserIdentity = {\n id,\n type,\n hosting,\n installationId,\n tenantId,\n providerType,\n verified,\n accountHolder,\n environment,\n }\n\n await identify(identity)\n}\n\nconst identify = async (identity: Identity, timestamp?: string | number) => {\n await processors.identify(identity, timestamp)\n}\n\nconst identifyGroup = async (group: Group, timestamp?: string | number) => {\n await processors.identifyGroup(group, timestamp)\n}\n\nconst getDeploymentEnvironment = () => {\n if (env.isDev()) {\n return \"development\"\n } else {\n return env.DEPLOYMENT_ENVIRONMENT\n }\n}\n\nconst getHostingFromEnv = () => {\n return env.SELF_HOSTED ? Hosting.SELF : Hosting.CLOUD\n}\n\nconst getInstallationId = async () => {\n if (isAccountPortal()) {\n return \"account-portal\"\n }\n const install = await installation.getInstall()\n return install.installId\n}\n\nconst getEventTenantId = async (tenantId: string): Promise<string> => {\n if (env.SELF_HOSTED) {\n return getUniqueTenantId(tenantId)\n } else {\n // tenant id's in the cloud are already unique\n return tenantId\n }\n}\n\nconst getUniqueTenantId = async (tenantId: string): Promise<string> => {\n // make sure this tenantId always matches the tenantId in context\n return context.doInTenant(tenantId, () => {\n return withCache(CacheKey.UNIQUE_TENANT_ID, TTL.ONE_DAY, async () => {\n const db = context.getGlobalDB()\n const config = await configs.getSettingsConfigDoc()\n\n let uniqueTenantId: string\n if (config.config.uniqueTenantId) {\n return config.config.uniqueTenantId\n } else {\n uniqueTenantId = `${newid()}_${tenantId}`\n config.config.uniqueTenantId = uniqueTenantId\n await db.put(config)\n return uniqueTenantId\n }\n })\n })\n}\n\nconst isAccountPortal = () => {\n return env.SERVICE === \"account-portal\"\n}\n\nconst formatDistinctId = (id: string, type: IdentityType) => {\n if (type === IdentityType.INSTALLATION || type === IdentityType.TENANT) {\n return `$${type}_${id}`\n } else {\n return id\n }\n}\n\nexport default {\n getCurrentIdentity,\n identifyInstallationGroup,\n identifyTenantGroup,\n identifyUser,\n identifyAccount,\n identify,\n identifyGroup,\n getInstallationId,\n getUniqueTenantId,\n}\n", "import {\n Event,\n BackfillMetadata,\n CachedEvent,\n SSOCreatedEvent,\n AutomationCreatedEvent,\n AutomationStepCreatedEvent,\n DatasourceCreatedEvent,\n LayoutCreatedEvent,\n QueryCreatedEvent,\n RoleCreatedEvent,\n ScreenCreatedEvent,\n TableCreatedEvent,\n ViewCreatedEvent,\n ViewCalculationCreatedEvent,\n ViewFilterCreatedEvent,\n AppPublishedEvent,\n UserCreatedEvent,\n RoleAssignedEvent,\n UserPermissionAssignedEvent,\n AppCreatedEvent,\n} from \"@budibase/types\"\nimport * as context from \"../context\"\nimport { CacheKey } from \"../cache/generic\"\nimport * as cache from \"../cache/generic\"\n\n// LIFECYCLE\n\nexport const start = async (events: Event[]) => {\n const metadata: BackfillMetadata = {\n eventWhitelist: events,\n }\n return saveBackfillMetadata(metadata)\n}\n\nexport const recordEvent = async (event: Event, properties: any) => {\n const eventKey = getEventKey(event, properties)\n // don't use a ttl - cleaned up by migration\n // don't use tenancy - already in the key\n await cache.store(eventKey, properties, undefined, { useTenancy: false })\n}\n\nexport const end = async () => {\n await deleteBackfillMetadata()\n await clearEvents()\n}\n\n// CRUD\n\nconst getBackfillMetadata = async (): Promise<BackfillMetadata | null> => {\n return cache.get(CacheKey.BACKFILL_METADATA)\n}\n\nconst saveBackfillMetadata = async (\n backfill: BackfillMetadata\n): Promise<void> => {\n // no TTL - deleted by backfill\n return cache.store(CacheKey.BACKFILL_METADATA, backfill)\n}\n\nconst deleteBackfillMetadata = async (): Promise<void> => {\n await cache.destroy(CacheKey.BACKFILL_METADATA)\n}\n\nconst clearEvents = async () => {\n // wildcard\n const pattern = getEventKey()\n const keys = await cache.keys(pattern)\n\n for (const key of keys) {\n // delete each key\n // don't use tenancy, already in the key\n await cache.destroy(key, { useTenancy: false })\n }\n}\n\n// HELPERS\n\nexport const isBackfillingEvent = async (event: Event) => {\n const backfill = await getBackfillMetadata()\n const events = backfill?.eventWhitelist\n if (events && events.includes(event)) {\n return true\n } else {\n return false\n }\n}\n\nexport const isAlreadySent = async (event: Event, properties: any) => {\n const eventKey = getEventKey(event, properties)\n const cachedEvent: CachedEvent = await cache.get(eventKey, {\n useTenancy: false,\n })\n return !!cachedEvent\n}\n\nconst CUSTOM_PROPERTY_SUFFIX: any = {\n // APP EVENTS\n [Event.AUTOMATION_CREATED]: (properties: AutomationCreatedEvent) => {\n return properties.automationId\n },\n [Event.AUTOMATION_STEP_CREATED]: (properties: AutomationStepCreatedEvent) => {\n return properties.stepId\n },\n [Event.DATASOURCE_CREATED]: (properties: DatasourceCreatedEvent) => {\n return properties.datasourceId\n },\n [Event.LAYOUT_CREATED]: (properties: LayoutCreatedEvent) => {\n return properties.layoutId\n },\n [Event.QUERY_CREATED]: (properties: QueryCreatedEvent) => {\n return properties.queryId\n },\n [Event.ROLE_CREATED]: (properties: RoleCreatedEvent) => {\n return properties.roleId\n },\n [Event.SCREEN_CREATED]: (properties: ScreenCreatedEvent) => {\n return properties.screenId\n },\n [Event.TABLE_CREATED]: (properties: TableCreatedEvent) => {\n return properties.tableId\n },\n [Event.VIEW_CREATED]: (properties: ViewCreatedEvent) => {\n return properties.tableId // best uniqueness\n },\n [Event.VIEW_CALCULATION_CREATED]: (\n properties: ViewCalculationCreatedEvent\n ) => {\n return properties.tableId // best uniqueness\n },\n [Event.VIEW_FILTER_CREATED]: (properties: ViewFilterCreatedEvent) => {\n return properties.tableId // best uniqueness\n },\n [Event.APP_CREATED]: (properties: AppCreatedEvent) => {\n return properties.appId // best uniqueness\n },\n [Event.APP_PUBLISHED]: (properties: AppPublishedEvent) => {\n return properties.appId // best uniqueness\n },\n // GLOBAL EVENTS\n [Event.AUTH_SSO_CREATED]: (properties: SSOCreatedEvent) => {\n return properties.type\n },\n [Event.AUTH_SSO_ACTIVATED]: (properties: SSOCreatedEvent) => {\n return properties.type\n },\n [Event.USER_CREATED]: (properties: UserCreatedEvent) => {\n return properties.userId\n },\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => {\n return properties.userId\n },\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => {\n return properties.userId\n },\n [Event.ROLE_ASSIGNED]: (properties: RoleAssignedEvent) => {\n return `${properties.roleId}-${properties.userId}`\n },\n}\n\nconst getEventKey = (event?: Event, properties?: any) => {\n let eventKey: string\n\n const tenantId = context.getTenantId()\n if (event) {\n eventKey = `${CacheKey.EVENTS}:${tenantId}:${event}`\n\n // use some properties to make the key more unique\n const custom = CUSTOM_PROPERTY_SUFFIX[event]\n const suffix = custom ? custom(properties) : undefined\n if (suffix) {\n eventKey = `${eventKey}:${suffix}`\n }\n } else {\n eventKey = `${CacheKey.EVENTS}:${tenantId}:*`\n }\n\n return eventKey\n}\n", "import BullQueue from \"bull\"\nimport { createQueue, JobQueue } from \"../../queue\"\nimport { Event, Identity } from \"@budibase/types\"\n\nexport interface EventPayload {\n event: Event\n identity: Identity\n properties: any\n timestamp?: string | number\n}\n\nexport let asyncEventQueue: BullQueue.Queue\n\nexport function init() {\n asyncEventQueue = createQueue<EventPayload>(JobQueue.SYSTEM_EVENT_QUEUE)\n}\n\nexport async function shutdown() {\n if (asyncEventQueue) {\n await asyncEventQueue.close()\n }\n}\n", "import { AsyncEvents } from \"@budibase/types\"\nimport { EventPayload, asyncEventQueue, init } from \"./queue\"\n\nexport async function publishAsyncEvent(payload: EventPayload) {\n if (!asyncEventQueue) {\n init()\n }\n const { event, identity } = payload\n if (AsyncEvents.indexOf(event) !== -1 && identity.tenantId) {\n await asyncEventQueue.add(payload)\n }\n}\n", "export * from \"./queue\"\nexport * from \"./publisher\"\n", "import { Event } from \"@budibase/types\"\nimport { processors } from \"./processors\"\nimport identification from \"./identification\"\nimport * as backfill from \"./backfill\"\nimport { publishAsyncEvent } from \"./asyncEvents\"\n\nexport const publishEvent = async (\n event: Event,\n properties: any,\n timestamp?: string | number\n) => {\n // in future this should use async events via a distributed queue.\n const identity = await identification.getCurrentIdentity()\n\n const backfilling = await backfill.isBackfillingEvent(event)\n // no backfill - send the event and exit\n if (!backfilling) {\n // send off async events if required\n await publishAsyncEvent({\n event,\n identity,\n properties,\n timestamp,\n })\n // now handle the main sync event processing pipeline\n await processors.processEvent(event, identity, properties, timestamp)\n return\n }\n\n // backfill active - check if the event has been sent already\n const alreadySent = await backfill.isAlreadySent(event, properties)\n if (alreadySent) {\n // do nothing\n return\n } else {\n // send and record the event\n await processors.processEvent(event, identity, properties, timestamp)\n await backfill.recordEvent(event, properties)\n }\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Account,\n AccountCreatedEvent,\n AccountDeletedEvent,\n AccountVerifiedEvent,\n} from \"@budibase/types\"\n\nasync function created(account: Account) {\n const properties: AccountCreatedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_CREATED, properties)\n}\n\nasync function deleted(account: Account) {\n const properties: AccountDeletedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_DELETED, properties)\n}\n\nasync function verified(account: Account) {\n const properties: AccountVerifiedEvent = {\n tenantId: account.tenantId,\n }\n await publishEvent(Event.ACCOUNT_VERIFIED, properties)\n}\n\nexport default {\n created,\n deleted,\n verified,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n App,\n AppCreatedEvent,\n AppUpdatedEvent,\n AppDeletedEvent,\n AppPublishedEvent,\n AppUnpublishedEvent,\n AppFileImportedEvent,\n AppTemplateImportedEvent,\n AppVersionUpdatedEvent,\n AppVersionRevertedEvent,\n AppRevertedEvent,\n AppExportedEvent,\n} from \"@budibase/types\"\n\nconst created = async (app: App, timestamp?: string | number) => {\n const properties: AppCreatedEvent = {\n appId: app.appId,\n version: app.version,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_CREATED, properties, timestamp)\n}\n\nasync function updated(app: App) {\n const properties: AppUpdatedEvent = {\n appId: app.appId,\n version: app.version,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_UPDATED, properties)\n}\n\nasync function deleted(app: App) {\n const properties: AppDeletedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_DELETED, properties)\n}\n\nasync function published(app: App, timestamp?: string | number) {\n const properties: AppPublishedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_PUBLISHED, properties, timestamp)\n}\n\nasync function unpublished(app: App) {\n const properties: AppUnpublishedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_UNPUBLISHED, properties)\n}\n\nasync function fileImported(app: App) {\n const properties: AppFileImportedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_FILE_IMPORTED, properties)\n}\n\nasync function templateImported(app: App, templateKey: string) {\n const properties: AppTemplateImportedEvent = {\n appId: app.appId,\n templateKey,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_TEMPLATE_IMPORTED, properties)\n}\n\nasync function versionUpdated(\n app: App,\n currentVersion: string,\n updatedToVersion: string\n) {\n const properties: AppVersionUpdatedEvent = {\n appId: app.appId,\n currentVersion,\n updatedToVersion,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_VERSION_UPDATED, properties)\n}\n\nasync function versionReverted(\n app: App,\n currentVersion: string,\n revertedToVersion: string\n) {\n const properties: AppVersionRevertedEvent = {\n appId: app.appId,\n currentVersion,\n revertedToVersion,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_VERSION_REVERTED, properties)\n}\n\nasync function reverted(app: App) {\n const properties: AppRevertedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_REVERTED, properties)\n}\n\nasync function exported(app: App) {\n const properties: AppExportedEvent = {\n appId: app.appId,\n audited: {\n name: app.name,\n },\n }\n await publishEvent(Event.APP_EXPORTED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n published,\n unpublished,\n fileImported,\n templateImported,\n versionUpdated,\n versionReverted,\n reverted,\n exported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n LoginEvent,\n LoginSource,\n LogoutEvent,\n SSOActivatedEvent,\n SSOCreatedEvent,\n SSODeactivatedEvent,\n SSOType,\n SSOUpdatedEvent,\n} from \"@budibase/types\"\nimport { identification } from \"..\"\n\nasync function login(source: LoginSource, email: string) {\n const identity = await identification.getCurrentIdentity()\n const properties: LoginEvent = {\n userId: identity.id,\n source,\n audited: {\n email,\n },\n }\n await publishEvent(Event.AUTH_LOGIN, properties)\n}\n\nasync function logout(email?: string) {\n const identity = await identification.getCurrentIdentity()\n const properties: LogoutEvent = {\n userId: identity.id,\n audited: {\n email,\n },\n }\n await publishEvent(Event.AUTH_LOGOUT, properties)\n}\n\nasync function SSOCreated(type: SSOType, timestamp?: string | number) {\n const properties: SSOCreatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_CREATED, properties, timestamp)\n}\n\nasync function SSOUpdated(type: SSOType) {\n const properties: SSOUpdatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_UPDATED, properties)\n}\n\nasync function SSOActivated(type: SSOType, timestamp?: string | number) {\n const properties: SSOActivatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_ACTIVATED, properties, timestamp)\n}\n\nasync function SSODeactivated(type: SSOType) {\n const properties: SSODeactivatedEvent = {\n type,\n }\n await publishEvent(Event.AUTH_SSO_DEACTIVATED, properties)\n}\n\nexport default {\n login,\n logout,\n SSOCreated,\n SSOUpdated,\n SSOActivated,\n SSODeactivated,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Automation,\n Event,\n AutomationStep,\n AutomationCreatedEvent,\n AutomationDeletedEvent,\n AutomationTestedEvent,\n AutomationStepCreatedEvent,\n AutomationStepDeletedEvent,\n AutomationTriggerUpdatedEvent,\n AutomationsRunEvent,\n} from \"@budibase/types\"\n\nasync function created(automation: Automation, timestamp?: string | number) {\n const properties: AutomationCreatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_CREATED, properties, timestamp)\n}\n\nasync function triggerUpdated(automation: Automation) {\n const properties: AutomationTriggerUpdatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n }\n await publishEvent(Event.AUTOMATION_TRIGGER_UPDATED, properties)\n}\n\nasync function deleted(automation: Automation) {\n const properties: AutomationDeletedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_DELETED, properties)\n}\n\nasync function tested(automation: Automation) {\n const properties: AutomationTestedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n }\n await publishEvent(Event.AUTOMATION_TESTED, properties)\n}\n\nconst run = async (count: number, timestamp?: string | number) => {\n const properties: AutomationsRunEvent = {\n count,\n }\n await publishEvent(Event.AUTOMATIONS_RUN, properties, timestamp)\n}\n\nasync function stepCreated(\n automation: Automation,\n step: AutomationStep,\n timestamp?: string | number\n) {\n const properties: AutomationStepCreatedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n stepId: step.id!,\n stepType: step.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_STEP_CREATED, properties, timestamp)\n}\n\nasync function stepDeleted(automation: Automation, step: AutomationStep) {\n const properties: AutomationStepDeletedEvent = {\n appId: automation.appId,\n automationId: automation._id as string,\n triggerId: automation.definition?.trigger?.id,\n triggerType: automation.definition?.trigger?.stepId,\n stepId: step.id!,\n stepType: step.stepId,\n audited: {\n name: automation.name,\n },\n }\n await publishEvent(Event.AUTOMATION_STEP_DELETED, properties)\n}\n\nexport default {\n created,\n triggerUpdated,\n deleted,\n tested,\n run,\n stepCreated,\n stepDeleted,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Datasource,\n DatasourceCreatedEvent,\n DatasourceUpdatedEvent,\n DatasourceDeletedEvent,\n SourceName,\n} from \"@budibase/types\"\n\nfunction isCustom(datasource: Datasource) {\n const sources = Object.values(SourceName)\n // if not in the base source list, then it must be custom\n return !sources.includes(datasource.source)\n}\n\nasync function created(datasource: Datasource, timestamp?: string | number) {\n const properties: DatasourceCreatedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)\n}\n\nasync function updated(datasource: Datasource) {\n const properties: DatasourceUpdatedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_UPDATED, properties)\n}\n\nasync function deleted(datasource: Datasource) {\n const properties: DatasourceDeletedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n custom: isCustom(datasource),\n }\n await publishEvent(Event.DATASOURCE_DELETED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event, SMTPCreatedEvent, SMTPUpdatedEvent } from \"@budibase/types\"\n\nasync function SMTPCreated(timestamp?: string | number) {\n const properties: SMTPCreatedEvent = {}\n await publishEvent(Event.EMAIL_SMTP_CREATED, properties, timestamp)\n}\n\nasync function SMTPUpdated() {\n const properties: SMTPUpdatedEvent = {}\n await publishEvent(Event.EMAIL_SMTP_UPDATED, properties)\n}\n\nexport default {\n SMTPCreated,\n SMTPUpdated,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n LicenseActivatedEvent,\n LicensePlanChangedEvent,\n PlanType,\n Account,\n LicensePortalOpenedEvent,\n LicenseCheckoutSuccessEvent,\n LicenseCheckoutOpenedEvent,\n LicensePaymentFailedEvent,\n LicensePaymentRecoveredEvent,\n PriceDuration,\n} from \"@budibase/types\"\n\nasync function planChanged(\n account: Account,\n opts: {\n from: PlanType\n to: PlanType\n fromQuantity: number | undefined\n toQuantity: number | undefined\n fromDuration: PriceDuration | undefined\n toDuration: PriceDuration | undefined\n }\n) {\n const properties: LicensePlanChangedEvent = {\n accountId: account.accountId,\n ...opts,\n }\n await publishEvent(Event.LICENSE_PLAN_CHANGED, properties)\n}\n\nasync function activated(account: Account) {\n const properties: LicenseActivatedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_ACTIVATED, properties)\n}\n\nasync function checkoutOpened(account: Account) {\n const properties: LicenseCheckoutOpenedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties)\n}\n\nasync function checkoutSuccess(account: Account) {\n const properties: LicenseCheckoutSuccessEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties)\n}\n\nasync function portalOpened(account: Account) {\n const properties: LicensePortalOpenedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PORTAL_OPENED, properties)\n}\n\nasync function paymentFailed(account: Account) {\n const properties: LicensePaymentFailedEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties)\n}\n\nasync function paymentRecovered(account: Account) {\n const properties: LicensePaymentRecoveredEvent = {\n accountId: account.accountId,\n }\n await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties)\n}\n\nexport default {\n planChanged,\n activated,\n checkoutOpened,\n checkoutSuccess,\n portalOpened,\n paymentFailed,\n paymentRecovered,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Layout,\n LayoutCreatedEvent,\n LayoutDeletedEvent,\n} from \"@budibase/types\"\n\nasync function created(layout: Layout, timestamp?: string | number) {\n const properties: LayoutCreatedEvent = {\n layoutId: layout._id as string,\n }\n await publishEvent(Event.LAYOUT_CREATED, properties, timestamp)\n}\n\nasync function deleted(layoutId: string) {\n const properties: LayoutDeletedEvent = {\n layoutId,\n }\n await publishEvent(Event.LAYOUT_DELETED, properties)\n}\n\nexport default {\n created,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event } from \"@budibase/types\"\n\nasync function nameUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_NAME_UPDATED, properties, timestamp)\n}\n\nasync function logoUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_LOGO_UPDATED, properties, timestamp)\n}\n\nasync function platformURLUpdated(timestamp?: string | number) {\n const properties = {}\n await publishEvent(Event.ORG_PLATFORM_URL_UPDATED, properties, timestamp)\n}\n\n// TODO\n\nasync function analyticsOptOut() {\n const properties = {}\n await publishEvent(Event.ANALYTICS_OPT_OUT, properties)\n}\n\nasync function analyticsOptIn() {\n const properties = {}\n await publishEvent(Event.ANALYTICS_OPT_OUT, properties)\n}\n\nexport default {\n nameUpdated,\n logoUpdated,\n platformURLUpdated,\n analyticsOptOut,\n analyticsOptIn,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Datasource,\n Query,\n QueryCreatedEvent,\n QueryUpdatedEvent,\n QueryDeletedEvent,\n QueryImportedEvent,\n QueryPreviewedEvent,\n QueriesRunEvent,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nconst created = async (\n datasource: Datasource,\n query: Query,\n timestamp?: string | number\n) => {\n const properties: QueryCreatedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_CREATED, properties, timestamp)\n}\n\nconst updated = async (datasource: Datasource, query: Query) => {\n const properties: QueryUpdatedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_UPDATED, properties)\n}\n\nconst deleted = async (datasource: Datasource, query: Query) => {\n const properties: QueryDeletedEvent = {\n queryId: query._id as string,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_DELETED, properties)\n}\n\nconst imported = async (\n datasource: Datasource,\n importSource: any,\n count: any\n) => {\n const properties: QueryImportedEvent = {\n datasourceId: datasource._id as string,\n source: datasource.source,\n count,\n importSource,\n }\n await publishEvent(Event.QUERY_IMPORT, properties)\n}\n\nconst run = async (count: number, timestamp?: string | number) => {\n const properties: QueriesRunEvent = {\n count,\n }\n await publishEvent(Event.QUERIES_RUN, properties, timestamp)\n}\n\nconst previewed = async (datasource: Datasource, query: Query) => {\n const properties: QueryPreviewedEvent = {\n queryId: query._id,\n datasourceId: datasource._id as string,\n source: datasource.source,\n queryVerb: query.queryVerb,\n }\n await publishEvent(Event.QUERY_PREVIEWED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n imported,\n run,\n previewed,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Role,\n RoleAssignedEvent,\n RoleCreatedEvent,\n RoleDeletedEvent,\n RoleUnassignedEvent,\n RoleUpdatedEvent,\n User,\n} from \"@budibase/types\"\n\nasync function created(role: Role, timestamp?: string | number) {\n const properties: RoleCreatedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_CREATED, properties, timestamp)\n}\n\nasync function updated(role: Role) {\n const properties: RoleUpdatedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_UPDATED, properties)\n}\n\nasync function deleted(role: Role) {\n const properties: RoleDeletedEvent = {\n roleId: role._id as string,\n permissionId: role.permissionId,\n inherits: role.inherits,\n }\n await publishEvent(Event.ROLE_DELETED, properties)\n}\n\nasync function assigned(user: User, roleId: string, timestamp?: number) {\n const properties: RoleAssignedEvent = {\n userId: user._id as string,\n roleId,\n }\n await publishEvent(Event.ROLE_ASSIGNED, properties, timestamp)\n}\n\nasync function unassigned(user: User, roleId: string) {\n const properties: RoleUnassignedEvent = {\n userId: user._id as string,\n roleId,\n }\n await publishEvent(Event.ROLE_UNASSIGNED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n assigned,\n unassigned,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Screen,\n ScreenCreatedEvent,\n ScreenDeletedEvent,\n} from \"@budibase/types\"\n\nasync function created(screen: Screen, timestamp?: string | number) {\n const properties: ScreenCreatedEvent = {\n layoutId: screen.layoutId,\n screenId: screen._id as string,\n roleId: screen.routing.roleId,\n audited: {\n name: screen.routing?.route,\n },\n }\n await publishEvent(Event.SCREEN_CREATED, properties, timestamp)\n}\n\nasync function deleted(screen: Screen) {\n const properties: ScreenDeletedEvent = {\n layoutId: screen.layoutId,\n screenId: screen._id as string,\n roleId: screen.routing.roleId,\n audited: {\n name: screen.routing?.route,\n },\n }\n await publishEvent(Event.SCREEN_DELETED, properties)\n}\n\nexport default {\n created,\n deleted,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n RowsImportedEvent,\n RowsCreatedEvent,\n Table,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nconst created = async (count: number, timestamp?: string | number) => {\n const properties: RowsCreatedEvent = {\n count,\n }\n await publishEvent(Event.ROWS_CREATED, properties, timestamp)\n}\n\nconst imported = async (table: Table, count: number) => {\n const properties: RowsImportedEvent = {\n tableId: table._id as string,\n count,\n }\n await publishEvent(Event.ROWS_IMPORTED, properties)\n}\n\nexport default {\n created,\n imported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n TableExportFormat,\n Table,\n TableCreatedEvent,\n TableUpdatedEvent,\n TableDeletedEvent,\n TableExportedEvent,\n TableImportedEvent,\n} from \"@budibase/types\"\n\nasync function created(table: Table, timestamp?: string | number) {\n const properties: TableCreatedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_CREATED, properties, timestamp)\n}\n\nasync function updated(table: Table) {\n const properties: TableUpdatedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_UPDATED, properties)\n}\n\nasync function deleted(table: Table) {\n const properties: TableDeletedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_DELETED, properties)\n}\n\nasync function exported(table: Table, format: TableExportFormat) {\n const properties: TableExportedEvent = {\n tableId: table._id as string,\n format,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_EXPORTED, properties)\n}\n\nasync function imported(table: Table) {\n const properties: TableImportedEvent = {\n tableId: table._id as string,\n audited: {\n name: table.name,\n },\n }\n await publishEvent(Event.TABLE_IMPORTED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n exported,\n imported,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n App,\n BuilderServedEvent,\n Event,\n AppPreviewServedEvent,\n AppServedEvent,\n} from \"@budibase/types\"\n\nasync function servedBuilder(timezone: string) {\n const properties: BuilderServedEvent = {\n timezone,\n }\n await publishEvent(Event.SERVED_BUILDER, properties)\n}\n\nasync function servedApp(app: App, timezone: string) {\n const properties: AppServedEvent = {\n appVersion: app.version,\n timezone,\n }\n await publishEvent(Event.SERVED_APP, properties)\n}\n\nasync function servedAppPreview(app: App, timezone: string) {\n const properties: AppPreviewServedEvent = {\n appId: app.appId,\n appVersion: app.version,\n timezone,\n }\n await publishEvent(Event.SERVED_APP_PREVIEW, properties)\n}\n\nexport default {\n servedBuilder,\n servedApp,\n servedAppPreview,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n User,\n UserCreatedEvent,\n UserDeletedEvent,\n UserInviteAcceptedEvent,\n UserInvitedEvent,\n UserPasswordForceResetEvent,\n UserPasswordResetEvent,\n UserPasswordResetRequestedEvent,\n UserPasswordUpdatedEvent,\n UserPermissionAssignedEvent,\n UserPermissionRemovedEvent,\n UserUpdatedEvent,\n UserOnboardingEvent,\n} from \"@budibase/types\"\nimport { isScim } from \"../../context\"\n\nasync function created(user: User, timestamp?: number) {\n const properties: UserCreatedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_CREATED, properties, timestamp)\n}\n\nasync function updated(user: User) {\n const properties: UserUpdatedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_UPDATED, properties)\n}\n\nasync function deleted(user: User) {\n const properties: UserDeletedEvent = {\n userId: user._id as string,\n viaScim: isScim(),\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_DELETED, properties)\n}\n\nexport async function onboardingComplete(user: User) {\n const properties: UserOnboardingEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_ONBOARDING_COMPLETE, properties)\n}\n\n// PERMISSIONS\n\nasync function permissionAdminAssigned(user: User, timestamp?: number) {\n const properties: UserPermissionAssignedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(\n Event.USER_PERMISSION_ADMIN_ASSIGNED,\n properties,\n timestamp\n )\n}\n\nasync function permissionAdminRemoved(user: User) {\n const properties: UserPermissionRemovedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PERMISSION_ADMIN_REMOVED, properties)\n}\n\nasync function permissionBuilderAssigned(user: User, timestamp?: number) {\n const properties: UserPermissionAssignedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(\n Event.USER_PERMISSION_BUILDER_ASSIGNED,\n properties,\n timestamp\n )\n}\n\nasync function permissionBuilderRemoved(user: User) {\n const properties: UserPermissionRemovedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PERMISSION_BUILDER_REMOVED, properties)\n}\n\n// INVITE\n\nasync function invited(email: string) {\n const properties: UserInvitedEvent = {\n audited: {\n email,\n },\n }\n await publishEvent(Event.USER_INVITED, properties)\n}\n\nasync function inviteAccepted(user: User) {\n const properties: UserInviteAcceptedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_INVITED_ACCEPTED, properties)\n}\n\n// PASSWORD\n\nasync function passwordForceReset(user: User) {\n const properties: UserPasswordForceResetEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_FORCE_RESET, properties)\n}\n\nasync function passwordUpdated(user: User) {\n const properties: UserPasswordUpdatedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_UPDATED, properties)\n}\n\nasync function passwordResetRequested(user: User) {\n const properties: UserPasswordResetRequestedEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_RESET_REQUESTED, properties)\n}\n\nasync function passwordReset(user: User) {\n const properties: UserPasswordResetEvent = {\n userId: user._id as string,\n audited: {\n email: user.email,\n },\n }\n await publishEvent(Event.USER_PASSWORD_RESET, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n permissionAdminAssigned,\n permissionAdminRemoved,\n permissionBuilderAssigned,\n permissionBuilderRemoved,\n onboardingComplete,\n invited,\n inviteAccepted,\n passwordForceReset,\n passwordUpdated,\n passwordResetRequested,\n passwordReset,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n ViewCalculationCreatedEvent,\n ViewCalculationDeletedEvent,\n ViewCalculationUpdatedEvent,\n ViewCreatedEvent,\n ViewDeletedEvent,\n ViewExportedEvent,\n ViewFilterCreatedEvent,\n ViewFilterDeletedEvent,\n ViewFilterUpdatedEvent,\n ViewUpdatedEvent,\n View,\n ViewCalculation,\n Table,\n TableExportFormat,\n} from \"@budibase/types\"\n\n/* eslint-disable */\n\nasync function created(view: View, timestamp?: string | number) {\n const properties: ViewCreatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_CREATED, properties, timestamp)\n}\n\nasync function updated(view: View) {\n const properties: ViewUpdatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_UPDATED, properties)\n}\n\nasync function deleted(view: View) {\n const properties: ViewDeletedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_DELETED, properties)\n}\n\nasync function exported(table: Table, format: TableExportFormat) {\n const properties: ViewExportedEvent = {\n tableId: table._id as string,\n format,\n }\n await publishEvent(Event.VIEW_EXPORTED, properties)\n}\n\nasync function filterCreated(view: View, timestamp?: string | number) {\n const properties: ViewFilterCreatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp)\n}\n\nasync function filterUpdated(view: View) {\n const properties: ViewFilterUpdatedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_UPDATED, properties)\n}\n\nasync function filterDeleted(view: View) {\n const properties: ViewFilterDeletedEvent = {\n tableId: view.tableId,\n }\n await publishEvent(Event.VIEW_FILTER_DELETED, properties)\n}\n\nasync function calculationCreated(view: View, timestamp?: string | number) {\n const properties: ViewCalculationCreatedEvent = {\n tableId: view.tableId,\n calculation: view.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp)\n}\n\nasync function calculationUpdated(view: View) {\n const properties: ViewCalculationUpdatedEvent = {\n tableId: view.tableId,\n calculation: view.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_UPDATED, properties)\n}\n\nasync function calculationDeleted(existingView: View) {\n const properties: ViewCalculationDeletedEvent = {\n tableId: existingView.tableId,\n calculation: existingView.calculation as ViewCalculation,\n }\n await publishEvent(Event.VIEW_CALCULATION_DELETED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n exported,\n filterCreated,\n filterUpdated,\n filterDeleted,\n calculationCreated,\n calculationUpdated,\n calculationDeleted,\n}\n", "import { publishEvent } from \"../events\"\nimport { Event, VersionCheckedEvent, VersionChangeEvent } from \"@budibase/types\"\n\nasync function versionChecked(version: string) {\n const properties: VersionCheckedEvent = {\n currentVersion: version,\n }\n await publishEvent(Event.INSTALLATION_VERSION_CHECKED, properties)\n}\n\nasync function upgraded(from: string, to: string) {\n const properties: VersionChangeEvent = {\n from,\n to,\n }\n\n await publishEvent(Event.INSTALLATION_VERSION_UPGRADED, properties)\n}\n\nasync function downgraded(from: string, to: string) {\n const properties: VersionChangeEvent = {\n from,\n to,\n }\n await publishEvent(Event.INSTALLATION_VERSION_DOWNGRADED, properties)\n}\n\nasync function firstStartup() {\n const properties = {}\n await publishEvent(Event.INSTALLATION_FIRST_STARTUP, properties)\n}\n\nexport default {\n versionChecked,\n upgraded,\n downgraded,\n firstStartup,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n AppBackfillSucceededEvent,\n AppBackfillFailedEvent,\n TenantBackfillSucceededEvent,\n TenantBackfillFailedEvent,\n InstallationBackfillSucceededEvent,\n InstallationBackfillFailedEvent,\n} from \"@budibase/types\"\nimport env from \"../../environment\"\n\nconst shouldSkip = !env.SELF_HOSTED && !env.isDev()\n\nasync function appSucceeded(properties: AppBackfillSucceededEvent) {\n if (shouldSkip) {\n return\n }\n await publishEvent(Event.APP_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function appFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: AppBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.APP_BACKFILL_FAILED, properties)\n}\n\nasync function tenantSucceeded(properties: TenantBackfillSucceededEvent) {\n if (shouldSkip) {\n return\n }\n await publishEvent(Event.TENANT_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function tenantFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: TenantBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.TENANT_BACKFILL_FAILED, properties)\n}\n\nasync function installationSucceeded() {\n if (shouldSkip) {\n return\n }\n const properties: InstallationBackfillSucceededEvent = {}\n await publishEvent(Event.INSTALLATION_BACKFILL_SUCCEEDED, properties)\n}\n\nasync function installationFailed(error: any) {\n if (shouldSkip) {\n return\n }\n const properties: InstallationBackfillFailedEvent = {\n error: JSON.stringify(error, Object.getOwnPropertyNames(error)),\n }\n await publishEvent(Event.INSTALLATION_BACKFILL_FAILED, properties)\n}\n\nexport default {\n appSucceeded,\n appFailed,\n tenantSucceeded,\n tenantFailed,\n installationSucceeded,\n installationFailed,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n UserGroup,\n GroupCreatedEvent,\n GroupDeletedEvent,\n GroupUpdatedEvent,\n GroupUsersAddedEvent,\n GroupUsersDeletedEvent,\n GroupAddedOnboardingEvent,\n GroupPermissionsEditedEvent,\n} from \"@budibase/types\"\nimport { isScim } from \"../../context\"\n\nasync function created(group: UserGroup, timestamp?: number) {\n const properties: GroupCreatedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_CREATED, properties, timestamp)\n}\n\nasync function updated(group: UserGroup) {\n const properties: GroupUpdatedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_UPDATED, properties)\n}\n\nasync function deleted(group: UserGroup) {\n const properties: GroupDeletedEvent = {\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_DELETED, properties)\n}\n\nasync function usersAdded(count: number, group: UserGroup) {\n const properties: GroupUsersAddedEvent = {\n count,\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_USERS_ADDED, properties)\n}\n\nasync function usersDeleted(count: number, group: UserGroup) {\n const properties: GroupUsersDeletedEvent = {\n count,\n groupId: group._id as string,\n viaScim: isScim(),\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties)\n}\n\nasync function createdOnboarding(groupId: string) {\n const properties: GroupAddedOnboardingEvent = {\n groupId: groupId,\n onboarding: true,\n }\n await publishEvent(Event.USER_GROUP_ONBOARDING, properties)\n}\n\nasync function permissionsEdited(group: UserGroup) {\n const properties: GroupPermissionsEditedEvent = {\n permissions: group.roles!,\n groupId: group._id as string,\n audited: {\n name: group.name,\n },\n }\n await publishEvent(Event.USER_GROUP_PERMISSIONS_EDITED, properties)\n}\n\nexport default {\n created,\n updated,\n deleted,\n usersAdded,\n usersDeleted,\n createdOnboarding,\n permissionsEdited,\n}\n", "import { publishEvent } from \"../events\"\nimport {\n Event,\n Plugin,\n PluginDeletedEvent,\n PluginImportedEvent,\n PluginInitEvent,\n} from \"@budibase/types\"\n\nasync function init(plugin: Plugin) {\n const properties: PluginInitEvent = {\n type: plugin.schema.type,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_INIT, properties)\n}\n\nasync function imported(plugin: Plugin) {\n const properties: PluginImportedEvent = {\n pluginId: plugin._id as string,\n type: plugin.schema.type,\n source: plugin.source,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_IMPORTED, properties)\n}\n\nasync function deleted(plugin: Plugin) {\n const properties: PluginDeletedEvent = {\n pluginId: plugin._id as string,\n type: plugin.schema.type,\n name: plugin.name,\n description: plugin.description,\n version: plugin.version,\n }\n await publishEvent(Event.PLUGIN_DELETED, properties)\n}\n\nexport default {\n init,\n imported,\n deleted,\n}\n", "import {\n AppBackup,\n AppBackupRestoreEvent,\n AppBackupTriggeredEvent,\n AppBackupTrigger,\n AppBackupType,\n Event,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function appBackupRestored(backup: AppBackup) {\n const properties: AppBackupRestoreEvent = {\n appId: backup.appId,\n restoreId: backup._id!,\n backupCreatedAt: backup.timestamp,\n name: backup.name as string,\n }\n\n await publishEvent(Event.APP_BACKUP_RESTORED, properties)\n}\n\nasync function appBackupTriggered(\n appId: string,\n backupId: string,\n type: AppBackupType,\n trigger: AppBackupTrigger,\n name: string\n) {\n const properties: AppBackupTriggeredEvent = {\n appId: appId,\n backupId,\n type,\n trigger,\n name,\n }\n await publishEvent(Event.APP_BACKUP_TRIGGERED, properties)\n}\n\nexport default {\n appBackupRestored,\n appBackupTriggered,\n}\n", "import {\n Event,\n EnvironmentVariableCreatedEvent,\n EnvironmentVariableDeletedEvent,\n EnvironmentVariableUpgradePanelOpenedEvent,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function created(name: string, environments: string[]) {\n const properties: EnvironmentVariableCreatedEvent = {\n name,\n environments,\n }\n await publishEvent(Event.ENVIRONMENT_VARIABLE_CREATED, properties)\n}\n\nasync function deleted(name: string) {\n const properties: EnvironmentVariableDeletedEvent = {\n name,\n }\n await publishEvent(Event.ENVIRONMENT_VARIABLE_DELETED, properties)\n}\n\nasync function upgradePanelOpened(userId: string) {\n const properties: EnvironmentVariableUpgradePanelOpenedEvent = {\n userId,\n }\n await publishEvent(\n Event.ENVIRONMENT_VARIABLE_UPGRADE_PANEL_OPENED,\n properties\n )\n}\n\nexport default {\n created,\n deleted,\n upgradePanelOpened,\n}\n", "import {\n Event,\n AuditLogSearchParams,\n AuditLogFilteredEvent,\n AuditLogDownloadedEvent,\n} from \"@budibase/types\"\nimport { publishEvent } from \"../events\"\n\nasync function filtered(search: AuditLogSearchParams) {\n const properties: AuditLogFilteredEvent = {\n filters: search,\n }\n await publishEvent(Event.AUDIT_LOGS_FILTERED, properties)\n}\n\nasync function downloaded(search: AuditLogSearchParams) {\n const properties: AuditLogDownloadedEvent = {\n filters: search,\n }\n await publishEvent(Event.AUDIT_LOGS_DOWNLOADED, properties)\n}\n\nexport default {\n filtered,\n downloaded,\n}\n", "export { default as account } from \"./account\"\nexport { default as app } from \"./app\"\nexport { default as auth } from \"./auth\"\nexport { default as automation } from \"./automation\"\nexport { default as datasource } from \"./datasource\"\nexport { default as email } from \"./email\"\nexport { default as license } from \"./license\"\nexport { default as layout } from \"./layout\"\nexport { default as org } from \"./org\"\nexport { default as query } from \"./query\"\nexport { default as role } from \"./role\"\nexport { default as screen } from \"./screen\"\nexport { default as rows } from \"./rows\"\nexport { default as table } from \"./table\"\nexport { default as serve } from \"./serve\"\nexport { default as user } from \"./user\"\nexport { default as view } from \"./view\"\nexport { default as installation } from \"./installation\"\nexport { default as backfill } from \"./backfill\"\nexport { default as group } from \"./group\"\nexport { default as plugin } from \"./plugin\"\nexport { default as backup } from \"./backup\"\nexport { default as environmentVariable } from \"./environmentVariable\"\nexport { default as auditLog } from \"./auditLog\"\n", "export * from \"./publishers\"\nexport * as processors from \"./processors\"\nexport * as analytics from \"./analytics\"\nexport { default as identification } from \"./identification\"\nexport * as backfillCache from \"./backfill\"\n\nimport { processors } from \"./processors\"\n\nexport function initAsyncEvents() {}\n\nexport const shutdown = () => {\n processors.shutdown()\n console.log(\"Events shutdown\")\n}\n", "import { DEFAULT_TENANT_ID } from \"../constants\"\nimport {\n DocumentType,\n StaticDatabases,\n getAllApps,\n getGlobalDBName,\n getDB,\n} from \"../db\"\nimport environment from \"../environment\"\nimport * as platform from \"../platform\"\nimport * as context from \"../context\"\nimport { DEFINITIONS } from \".\"\nimport {\n Migration,\n MigrationOptions,\n MigrationType,\n MigrationNoOpOptions,\n App,\n} from \"@budibase/types\"\n\nexport const getMigrationsDoc = async (db: any) => {\n // get the migrations doc\n try {\n return await db.get(DocumentType.MIGRATIONS)\n } catch (err: any) {\n if (err.status && err.status === 404) {\n return { _id: DocumentType.MIGRATIONS }\n } else {\n console.error(err)\n throw err\n }\n }\n}\n\nexport const backPopulateMigrations = async (opts: MigrationNoOpOptions) => {\n // filter migrations to the type and populate a no-op migration\n const migrations: Migration[] = DEFINITIONS.filter(\n def => def.type === opts.type\n ).map(d => ({ ...d, fn: () => {} }))\n await runMigrations(migrations, { noOp: opts })\n}\n\nexport const runMigration = async (\n migration: Migration,\n options: MigrationOptions = {}\n) => {\n const migrationType = migration.type\n let tenantId: string | undefined\n if (migrationType !== MigrationType.INSTALLATION) {\n tenantId = context.getTenantId()\n }\n const migrationName = migration.name\n const silent = migration.silent\n\n const log = (message: string) => {\n if (!silent) {\n console.log(message)\n }\n }\n\n // get the db to store the migration in\n let dbNames: string[]\n if (migrationType === MigrationType.GLOBAL) {\n dbNames = [getGlobalDBName()]\n } else if (migrationType === MigrationType.APP) {\n if (options.noOp) {\n if (!options.noOp.appId) {\n throw new Error(\"appId is required for noOp app migration\")\n }\n dbNames = [options.noOp.appId]\n } else {\n const apps = (await getAllApps(migration.appOpts)) as App[]\n dbNames = apps.map(app => app.appId)\n }\n } else if (migrationType === MigrationType.INSTALLATION) {\n dbNames = [StaticDatabases.PLATFORM_INFO.name]\n } else {\n throw new Error(`Unrecognised migration type [${migrationType}]`)\n }\n\n const length = dbNames.length\n let count = 0\n\n // run the migration against each db\n for (const dbName of dbNames) {\n count++\n const lengthStatement = length > 1 ? `[${count}/${length}]` : \"\"\n\n const db = getDB(dbName)\n\n try {\n const doc = await getMigrationsDoc(db)\n\n // the migration has already been run\n if (doc[migrationName]) {\n // check for force\n if (\n options.force &&\n options.force[migrationType] &&\n options.force[migrationType].includes(migrationName)\n ) {\n log(`[Migration: ${migrationName}] [DB: ${dbName}] Forcing`)\n } else {\n // no force, exit\n return\n }\n }\n\n // check if the migration is not a no-op\n if (!options.noOp) {\n log(\n `[Migration: ${migrationName}] [DB: ${dbName}] Running ${lengthStatement}`\n )\n\n if (migration.preventRetry) {\n // eagerly set the completion date\n // so that we never run this migration twice even upon failure\n doc[migrationName] = Date.now()\n const response = await db.put(doc)\n doc._rev = response.rev\n }\n\n // run the migration\n if (migrationType === MigrationType.APP) {\n await context.doInAppContext(db.name, async () => {\n await migration.fn(db)\n })\n } else {\n await migration.fn(db)\n }\n\n log(`[Migration: ${migrationName}] [DB: ${dbName}] Complete`)\n }\n\n // mark as complete\n doc[migrationName] = Date.now()\n await db.put(doc)\n } catch (err) {\n console.error(\n `[Migration: ${migrationName}] [DB: ${dbName}] Error: `,\n err\n )\n throw err\n }\n }\n}\n\nexport const runMigrations = async (\n migrations: Migration[],\n options: MigrationOptions = {}\n) => {\n let tenantIds\n\n if (environment.MULTI_TENANCY) {\n if (options.noOp) {\n tenantIds = [options.noOp.tenantId]\n } else if (!options.tenantIds || !options.tenantIds.length) {\n // run for all tenants\n tenantIds = await platform.tenants.getTenantIds()\n } else {\n tenantIds = options.tenantIds\n }\n } else {\n // single tenancy\n tenantIds = [DEFAULT_TENANT_ID]\n }\n\n if (tenantIds.length > 1) {\n console.log(`Checking migrations for ${tenantIds.length} tenants`)\n } else {\n console.log(\"Checking migrations\")\n }\n\n let count = 0\n // for all tenants\n for (const tenantId of tenantIds) {\n count++\n if (tenantIds.length > 1) {\n console.log(`Progress [${count}/${tenantIds.length}]`)\n }\n // for all migrations\n for (const migration of migrations) {\n // run the migration\n await context.doInTenant(\n tenantId,\n async () => await runMigration(migration, options)\n )\n }\n }\n console.log(\"Migrations complete\")\n}\n", "import {\n MigrationType,\n MigrationName,\n MigrationDefinition,\n} from \"@budibase/types\"\n\nexport const DEFINITIONS: MigrationDefinition[] = [\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.USER_EMAIL_VIEW_CASING,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.SYNC_QUOTAS,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.APP_URLS,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.EVENT_APP_BACKFILL,\n },\n {\n type: MigrationType.APP,\n name: MigrationName.TABLE_SETTINGS_LINKS_TO_ACTIONS,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.EVENT_GLOBAL_BACKFILL,\n },\n {\n type: MigrationType.INSTALLATION,\n name: MigrationName.EVENT_INSTALLATION_BACKFILL,\n },\n {\n type: MigrationType.GLOBAL,\n name: MigrationName.GLOBAL_INFO_SYNC_USERS,\n },\n]\n", "export * from \"./migrations\"\nexport * from \"./definitions\"\n", "import {\n directCouchFind,\n DocumentType,\n generateAppUserID,\n getGlobalUserParams,\n getProdAppID,\n getUsersByAppParams,\n pagination,\n queryGlobalView,\n queryGlobalViewRaw,\n SEPARATOR,\n UNICODE_MAX,\n ViewName,\n} from \"./db\"\nimport { BulkDocsResponse, SearchUsersRequest, User } from \"@budibase/types\"\nimport { getGlobalDB } from \"./context\"\nimport * as context from \"./context\"\n\ntype GetOpts = { cleanup?: boolean }\n\nfunction removeUserPassword(users: User | User[]) {\n if (Array.isArray(users)) {\n return users.map(user => {\n if (user) {\n delete user.password\n return user\n }\n })\n } else if (users) {\n delete users.password\n return users\n }\n return users\n}\n\nexport const bulkGetGlobalUsersById = async (\n userIds: string[],\n opts?: GetOpts\n) => {\n const db = getGlobalDB()\n let users = (\n await db.allDocs({\n keys: userIds,\n include_docs: true,\n })\n ).rows.map(row => row.doc) as User[]\n if (opts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\nexport const getAllUserIds = async () => {\n const db = getGlobalDB()\n const startKey = `${DocumentType.USER}${SEPARATOR}`\n const response = await db.allDocs({\n startkey: startKey,\n endkey: `${startKey}${UNICODE_MAX}`,\n })\n return response.rows.map(row => row.id)\n}\n\nexport const bulkUpdateGlobalUsers = async (users: User[]) => {\n const db = getGlobalDB()\n return (await db.bulkDocs(users)) as BulkDocsResponse\n}\n\nexport async function getById(id: string, opts?: GetOpts): Promise<User> {\n const db = context.getGlobalDB()\n let user = await db.get(id)\n if (opts?.cleanup) {\n user = removeUserPassword(user)\n }\n return user\n}\n\n/**\n * Given an email address this will use a view to search through\n * all the users to find one with this email address.\n */\nexport const getGlobalUserByEmail = async (\n email: String,\n opts?: GetOpts\n): Promise<User | undefined> => {\n if (email == null) {\n throw \"Must supply an email address to view\"\n }\n\n const response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {\n key: email.toLowerCase(),\n include_docs: true,\n })\n\n if (Array.isArray(response)) {\n // shouldn't be able to happen, but need to handle just in case\n throw new Error(`Multiple users found with email address: ${email}`)\n }\n\n let user = response as User\n if (opts?.cleanup) {\n user = removeUserPassword(user) as User\n }\n\n return user\n}\n\nexport const searchGlobalUsersByApp = async (\n appId: any,\n opts: any,\n getOpts?: GetOpts\n) => {\n if (typeof appId !== \"string\") {\n throw new Error(\"Must provide a string based app ID\")\n }\n const params = getUsersByAppParams(appId, {\n include_docs: true,\n })\n params.startkey = opts && opts.startkey ? opts.startkey : params.startkey\n let response = await queryGlobalView(ViewName.USER_BY_APP, params)\n\n if (!response) {\n response = []\n }\n let users: User[] = Array.isArray(response) ? response : [response]\n if (getOpts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\n/*\n Return any user who potentially has access to the application\n Admins, developers and app users with the explicitly role.\n*/\nexport const searchGlobalUsersByAppAccess = async (appId: any, opts: any) => {\n const roleSelector = `roles.${appId}`\n\n let orQuery: any[] = [\n {\n \"builder.global\": true,\n },\n {\n \"admin.global\": true,\n },\n ]\n\n if (appId) {\n const roleCheck = {\n [roleSelector]: {\n $exists: true,\n },\n }\n orQuery.push(roleCheck)\n }\n\n let searchOptions = {\n selector: {\n $or: orQuery,\n _id: {\n $regex: \"^us_\",\n },\n },\n limit: opts?.limit || 50,\n }\n\n const resp = await directCouchFind(context.getGlobalDBName(), searchOptions)\n return resp?.rows\n}\n\nexport const getGlobalUserByAppPage = (appId: string, user: User) => {\n if (!user) {\n return\n }\n return generateAppUserID(getProdAppID(appId)!, user._id!)\n}\n\n/**\n * Performs a starts with search on the global email view.\n */\nexport const searchGlobalUsersByEmail = async (\n email: string,\n opts: any,\n getOpts?: GetOpts\n) => {\n if (typeof email !== \"string\") {\n throw new Error(\"Must provide a string to search by\")\n }\n const lcEmail = email.toLowerCase()\n // handle if passing up startkey for pagination\n const startkey = opts && opts.startkey ? opts.startkey : lcEmail\n let response = await queryGlobalView<User>(ViewName.USER_BY_EMAIL, {\n ...opts,\n startkey,\n endkey: `${lcEmail}${UNICODE_MAX}`,\n })\n if (!response) {\n response = []\n }\n let users: User[] = Array.isArray(response) ? response : [response]\n if (getOpts?.cleanup) {\n users = removeUserPassword(users) as User[]\n }\n return users\n}\n\nconst PAGE_LIMIT = 8\nexport const paginatedUsers = async ({\n page,\n email,\n appId,\n}: SearchUsersRequest = {}) => {\n const db = getGlobalDB()\n // get one extra document, to have the next page\n const opts: any = {\n include_docs: true,\n limit: PAGE_LIMIT + 1,\n }\n // add a startkey if the page was specified (anchor)\n if (page) {\n opts.startkey = page\n }\n // property specifies what to use for the page/anchor\n let userList: User[],\n property = \"_id\",\n getKey\n if (appId) {\n userList = await searchGlobalUsersByApp(appId, opts)\n getKey = (doc: any) => getGlobalUserByAppPage(appId, doc)\n } else if (email) {\n userList = await searchGlobalUsersByEmail(email, opts)\n property = \"email\"\n } else {\n // no search, query allDocs\n const response = await db.allDocs(getGlobalUserParams(null, opts))\n userList = response.rows.map((row: any) => row.doc)\n }\n return pagination(userList, PAGE_LIMIT, {\n paginate: true,\n property,\n getKey,\n })\n}\n\nexport async function getUserCount() {\n const response = await queryGlobalViewRaw(ViewName.USER_BY_EMAIL, {\n limit: 0, // to be as fast as possible - we just want the total rows count\n include_docs: false,\n })\n return response.total_rows\n}\n", "const { flatten } = require(\"lodash\")\nconst { cloneDeep } = require(\"lodash/fp\")\n\nexport type RoleHierarchy = {\n permissionId: string\n}[]\n\nexport enum PermissionLevel {\n READ = \"read\",\n WRITE = \"write\",\n EXECUTE = \"execute\",\n ADMIN = \"admin\",\n}\n\n// these are the global types, that govern the underlying default behaviour\nexport enum PermissionType {\n APP = \"app\",\n TABLE = \"table\",\n USER = \"user\",\n AUTOMATION = \"automation\",\n WEBHOOK = \"webhook\",\n BUILDER = \"builder\",\n VIEW = \"view\",\n QUERY = \"query\",\n}\n\nexport class Permission {\n type: PermissionType\n level: PermissionLevel\n\n constructor(type: PermissionType, level: PermissionLevel) {\n this.type = type\n this.level = level\n }\n}\n\nexport function levelToNumber(perm: PermissionLevel) {\n switch (perm) {\n // not everything has execute privileges\n case PermissionLevel.EXECUTE:\n return 0\n case PermissionLevel.READ:\n return 1\n case PermissionLevel.WRITE:\n return 2\n case PermissionLevel.ADMIN:\n return 3\n default:\n return -1\n }\n}\n\n/**\n * Given the specified permission level for the user return the levels they are allowed to carry out.\n * @param {string} userPermLevel The permission level of the user.\n * @return {string[]} All the permission levels this user is allowed to carry out.\n */\nexport function getAllowedLevels(userPermLevel: PermissionLevel): string[] {\n switch (userPermLevel) {\n case PermissionLevel.EXECUTE:\n return [PermissionLevel.EXECUTE]\n case PermissionLevel.READ:\n return [PermissionLevel.EXECUTE, PermissionLevel.READ]\n case PermissionLevel.WRITE:\n case PermissionLevel.ADMIN:\n return [\n PermissionLevel.EXECUTE,\n PermissionLevel.READ,\n PermissionLevel.WRITE,\n ]\n default:\n return []\n }\n}\n\nexport enum BuiltinPermissionID {\n PUBLIC = \"public\",\n READ_ONLY = \"read_only\",\n WRITE = \"write\",\n ADMIN = \"admin\",\n POWER = \"power\",\n}\n\nexport const BUILTIN_PERMISSIONS = {\n PUBLIC: {\n _id: BuiltinPermissionID.PUBLIC,\n name: \"Public\",\n permissions: [\n new Permission(PermissionType.WEBHOOK, PermissionLevel.EXECUTE),\n ],\n },\n READ_ONLY: {\n _id: BuiltinPermissionID.READ_ONLY,\n name: \"Read only\",\n permissions: [\n new Permission(PermissionType.QUERY, PermissionLevel.READ),\n new Permission(PermissionType.TABLE, PermissionLevel.READ),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n ],\n },\n WRITE: {\n _id: BuiltinPermissionID.WRITE,\n name: \"Read/Write\",\n permissions: [\n new Permission(PermissionType.QUERY, PermissionLevel.WRITE),\n new Permission(PermissionType.TABLE, PermissionLevel.WRITE),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),\n ],\n },\n POWER: {\n _id: BuiltinPermissionID.POWER,\n name: \"Power\",\n permissions: [\n new Permission(PermissionType.TABLE, PermissionLevel.WRITE),\n new Permission(PermissionType.USER, PermissionLevel.READ),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.EXECUTE),\n new Permission(PermissionType.VIEW, PermissionLevel.READ),\n new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),\n ],\n },\n ADMIN: {\n _id: BuiltinPermissionID.ADMIN,\n name: \"Admin\",\n permissions: [\n new Permission(PermissionType.TABLE, PermissionLevel.ADMIN),\n new Permission(PermissionType.USER, PermissionLevel.ADMIN),\n new Permission(PermissionType.AUTOMATION, PermissionLevel.ADMIN),\n new Permission(PermissionType.VIEW, PermissionLevel.ADMIN),\n new Permission(PermissionType.WEBHOOK, PermissionLevel.READ),\n new Permission(PermissionType.QUERY, PermissionLevel.ADMIN),\n ],\n },\n}\n\nexport function getBuiltinPermissions() {\n return cloneDeep(BUILTIN_PERMISSIONS)\n}\n\nexport function getBuiltinPermissionByID(id: string) {\n const perms = Object.values(BUILTIN_PERMISSIONS)\n return perms.find(perm => perm._id === id)\n}\n\nexport function doesHaveBasePermission(\n permType: PermissionType,\n permLevel: PermissionLevel,\n rolesHierarchy: RoleHierarchy\n) {\n const basePermissions = [\n ...new Set(rolesHierarchy.map(role => role.permissionId)),\n ]\n const builtins = Object.values(BUILTIN_PERMISSIONS)\n let permissions = flatten(\n builtins\n .filter(builtin => basePermissions.indexOf(builtin._id) !== -1)\n .map(builtin => builtin.permissions)\n )\n for (let permission of permissions) {\n if (\n permission.type === permType &&\n getAllowedLevels(permission.level).indexOf(permLevel) !== -1\n ) {\n return true\n }\n }\n return false\n}\n\nexport function isPermissionLevelHigherThanRead(level: PermissionLevel) {\n return levelToNumber(level) > 1\n}\n\n// utility as a lot of things need simply the builder permission\nexport const BUILDER = PermissionType.BUILDER\n", "import { BuiltinPermissionID, PermissionLevel } from \"./permissions\"\nimport { generateRoleID, getRoleParams, DocumentType, SEPARATOR } from \"../db\"\nimport { getAppDB } from \"../context\"\nimport { doWithDB } from \"../db\"\nimport { Screen, Role as RoleDoc } from \"@budibase/types\"\nconst { cloneDeep } = require(\"lodash/fp\")\n\nexport const BUILTIN_ROLE_IDS = {\n ADMIN: \"ADMIN\",\n POWER: \"POWER\",\n BASIC: \"BASIC\",\n PUBLIC: \"PUBLIC\",\n}\n\nconst BUILTIN_IDS = {\n ...BUILTIN_ROLE_IDS,\n BUILDER: \"BUILDER\",\n}\n\n// exclude internal roles like builder\nconst EXTERNAL_BUILTIN_ROLE_IDS = [\n BUILTIN_IDS.ADMIN,\n BUILTIN_IDS.POWER,\n BUILTIN_IDS.BASIC,\n BUILTIN_IDS.PUBLIC,\n]\n\nexport class Role implements RoleDoc {\n _id: string\n _rev?: string\n name: string\n permissionId: string\n inherits?: string\n permissions = {}\n\n constructor(id: string, name: string, permissionId: string) {\n this._id = id\n this.name = name\n this.permissionId = permissionId\n }\n\n addInheritance(inherits: string) {\n this.inherits = inherits\n return this\n }\n}\n\nconst BUILTIN_ROLES = {\n ADMIN: new Role(\n BUILTIN_IDS.ADMIN,\n \"Admin\",\n BuiltinPermissionID.ADMIN\n ).addInheritance(BUILTIN_IDS.POWER),\n POWER: new Role(\n BUILTIN_IDS.POWER,\n \"Power\",\n BuiltinPermissionID.POWER\n ).addInheritance(BUILTIN_IDS.BASIC),\n BASIC: new Role(\n BUILTIN_IDS.BASIC,\n \"Basic\",\n BuiltinPermissionID.WRITE\n ).addInheritance(BUILTIN_IDS.PUBLIC),\n PUBLIC: new Role(BUILTIN_IDS.PUBLIC, \"Public\", BuiltinPermissionID.PUBLIC),\n BUILDER: new Role(BUILTIN_IDS.BUILDER, \"Builder\", BuiltinPermissionID.ADMIN),\n}\n\nexport function getBuiltinRoles(): { [key: string]: RoleDoc } {\n return cloneDeep(BUILTIN_ROLES)\n}\n\nexport const BUILTIN_ROLE_ID_ARRAY = Object.values(BUILTIN_ROLES).map(\n role => role._id\n)\n\nexport const BUILTIN_ROLE_NAME_ARRAY = Object.values(BUILTIN_ROLES).map(\n role => role.name\n)\n\nexport function isBuiltin(role?: string) {\n return BUILTIN_ROLE_ID_ARRAY.some(builtin => role?.includes(builtin))\n}\n\n/**\n * Works through the inheritance ranks to see how far up the builtin stack this ID is.\n */\nexport function builtinRoleToNumber(id?: string) {\n if (!id) {\n return 0\n }\n const builtins = getBuiltinRoles()\n const MAX = Object.values(builtins).length + 1\n if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) {\n return MAX\n }\n let role = builtins[id],\n count = 0\n do {\n if (!role) {\n break\n }\n role = builtins[role.inherits!]\n count++\n } while (role !== null)\n return count\n}\n\n/**\n * Converts any role to a number, but has to be async to get the roles from db.\n */\nexport async function roleToNumber(id?: string) {\n if (isBuiltin(id)) {\n return builtinRoleToNumber(id)\n }\n const hierarchy = (await getUserRoleHierarchy(id)) as RoleDoc[]\n for (let role of hierarchy) {\n if (isBuiltin(role?.inherits)) {\n return builtinRoleToNumber(role.inherits) + 1\n }\n }\n return 0\n}\n\n/**\n * Returns whichever builtin roleID is lower.\n */\nexport function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {\n if (!roleId1) {\n return roleId2 as string\n }\n if (!roleId2) {\n return roleId1 as string\n }\n return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2)\n ? roleId2\n : roleId1\n}\n\n/**\n * Gets the role object, this is mainly useful for two purposes, to check if the level exists and\n * to check if the role inherits any others.\n * @param {string|null} roleId The level ID to lookup.\n * @returns {Promise<Role|object|null>} The role object, which may contain an \"inherits\" property.\n */\nexport async function getRole(roleId?: string): Promise<RoleDoc | undefined> {\n if (!roleId) {\n return undefined\n }\n let role: any = {}\n // built in roles mostly come from the in-code implementation,\n // but can be extended by a doc stored about them (e.g. permissions)\n if (isBuiltin(roleId)) {\n role = cloneDeep(\n Object.values(BUILTIN_ROLES).find(role => role._id === roleId)\n )\n }\n try {\n const db = getAppDB()\n const dbRole = await db.get(getDBRoleID(roleId))\n role = Object.assign(role, dbRole)\n // finalise the ID\n role._id = getExternalRoleID(role._id)\n } catch (err) {\n // only throw an error if there is no role at all\n if (Object.keys(role).length === 0) {\n throw err\n }\n }\n return role\n}\n\n/**\n * Simple function to get all the roles based on the top level user role ID.\n */\nasync function getAllUserRoles(userRoleId?: string): Promise<RoleDoc[]> {\n // admins have access to all roles\n if (userRoleId === BUILTIN_IDS.ADMIN) {\n return getAllRoles()\n }\n let currentRole = await getRole(userRoleId)\n let roles = currentRole ? [currentRole] : []\n let roleIds = [userRoleId]\n // get all the inherited roles\n while (\n currentRole &&\n currentRole.inherits &&\n roleIds.indexOf(currentRole.inherits) === -1\n ) {\n roleIds.push(currentRole.inherits)\n currentRole = await getRole(currentRole.inherits)\n if (currentRole) {\n roles.push(currentRole)\n }\n }\n return roles\n}\n\n/**\n * Returns an ordered array of the user's inherited role IDs, this can be used\n * to determine if a user can access something that requires a specific role.\n * @param {string} userRoleId The user's role ID, this can be found in their access token.\n * @param {object} opts Various options, such as whether to only retrieve the IDs (default true).\n * @returns {Promise<string[]|object[]>} returns an ordered array of the roles, with the first being their\n * highest level of access and the last being the lowest level.\n */\nexport async function getUserRoleHierarchy(\n userRoleId?: string,\n opts = { idOnly: true }\n) {\n // special case, if they don't have a role then they are a public user\n const roles = await getAllUserRoles(userRoleId)\n return opts.idOnly ? roles.map(role => role._id) : roles\n}\n\n// this function checks that the provided permissions are in an array format\n// some templates/older apps will use a simple string instead of array for roles\n// convert the string to an array using the theory that write is higher than read\nexport function checkForRoleResourceArray(\n rolePerms: { [key: string]: string[] },\n resourceId: string\n) {\n if (rolePerms && !Array.isArray(rolePerms[resourceId])) {\n const permLevel = rolePerms[resourceId] as any\n rolePerms[resourceId] = [permLevel]\n if (permLevel === PermissionLevel.WRITE) {\n rolePerms[resourceId].push(PermissionLevel.READ)\n }\n }\n return rolePerms\n}\n\n/**\n * Given an app ID this will retrieve all of the roles that are currently within that app.\n * @return {Promise<object[]>} An array of the role objects that were found.\n */\nexport async function getAllRoles(appId?: string) {\n if (appId) {\n return doWithDB(appId, internal)\n } else {\n let appDB\n try {\n appDB = getAppDB()\n } catch (error) {\n // We don't have any apps, so we'll just use the built-in roles\n }\n return internal(appDB)\n }\n async function internal(db: any) {\n let roles: RoleDoc[] = []\n if (db) {\n const body = await db.allDocs(\n getRoleParams(null, {\n include_docs: true,\n })\n )\n roles = body.rows.map((row: any) => row.doc)\n }\n const builtinRoles = getBuiltinRoles()\n\n // need to combine builtin with any DB record of them (for sake of permissions)\n for (let builtinRoleId of EXTERNAL_BUILTIN_ROLE_IDS) {\n const builtinRole = builtinRoles[builtinRoleId]\n const dbBuiltin = roles.filter(\n dbRole => getExternalRoleID(dbRole._id) === builtinRoleId\n )[0]\n if (dbBuiltin == null) {\n roles.push(builtinRole || builtinRoles.BASIC)\n } else {\n // remove role and all back after combining with the builtin\n roles = roles.filter(role => role._id !== dbBuiltin._id)\n dbBuiltin._id = getExternalRoleID(dbBuiltin._id)\n roles.push(Object.assign(builtinRole, dbBuiltin))\n }\n }\n // check permissions\n for (let role of roles) {\n if (!role.permissions) {\n continue\n }\n for (let resourceId of Object.keys(role.permissions)) {\n role.permissions = checkForRoleResourceArray(\n role.permissions,\n resourceId\n )\n }\n }\n return roles\n }\n}\n\n/**\n * This retrieves the required role for a resource\n * @param permLevel The level of request\n * @param resourceId The resource being requested\n * @param subResourceId The sub resource being requested\n * @return {Promise<{permissions}|Object>} returns the permissions required to access.\n */\nexport async function getRequiredResourceRole(\n permLevel: string,\n { resourceId, subResourceId }: { resourceId?: string; subResourceId?: string }\n) {\n const roles = await getAllRoles()\n let main = [],\n sub = []\n for (let role of roles) {\n // no permissions, ignore it\n if (!role.permissions) {\n continue\n }\n const mainRes = resourceId ? role.permissions[resourceId] : undefined\n const subRes = subResourceId ? role.permissions[subResourceId] : undefined\n if (mainRes && mainRes.indexOf(permLevel) !== -1) {\n main.push(role._id)\n } else if (subRes && subRes.indexOf(permLevel) !== -1) {\n sub.push(role._id)\n }\n }\n // for now just return the IDs\n return main.concat(sub)\n}\n\nexport class AccessController {\n userHierarchies: { [key: string]: string[] }\n constructor() {\n this.userHierarchies = {}\n }\n\n async hasAccess(tryingRoleId?: string, userRoleId?: string) {\n // special cases, the screen has no role, the roles are the same or the user\n // is currently in the builder\n if (\n tryingRoleId == null ||\n tryingRoleId === \"\" ||\n tryingRoleId === userRoleId ||\n tryingRoleId === BUILTIN_IDS.BUILDER ||\n userRoleId === BUILTIN_IDS.BUILDER\n ) {\n return true\n }\n let roleIds = userRoleId ? this.userHierarchies[userRoleId] : null\n if (!roleIds && userRoleId) {\n roleIds = (await getUserRoleHierarchy(userRoleId, {\n idOnly: true,\n })) as string[]\n this.userHierarchies[userRoleId] = roleIds\n }\n\n return roleIds?.indexOf(tryingRoleId) !== -1\n }\n\n async checkScreensAccess(screens: Screen[], userRoleId: string) {\n let accessibleScreens = []\n // don't want to handle this with Promise.all as this would mean all custom roles would be\n // retrieved at same time, it is likely a custom role will be re-used and therefore want\n // to work in sync for performance save\n for (let screen of screens) {\n const accessible = await this.checkScreenAccess(screen, userRoleId)\n if (accessible) {\n accessibleScreens.push(accessible)\n }\n }\n return accessibleScreens\n }\n\n async checkScreenAccess(screen: Screen, userRoleId: string) {\n const roleId = screen && screen.routing ? screen.routing.roleId : undefined\n if (await this.hasAccess(roleId, userRoleId)) {\n return screen\n }\n return null\n }\n}\n\n/**\n * Adds the \"role_\" for builtin role IDs which are to be written to the DB (for permissions).\n */\nexport function getDBRoleID(roleId?: string) {\n if (roleId?.startsWith(DocumentType.ROLE)) {\n return roleId\n }\n return generateRoleID(roleId)\n}\n\n/**\n * Remove the \"role_\" from builtin role IDs that have been written to the DB (for permissions).\n */\nexport function getExternalRoleID(roleId?: string) {\n // for built-in roles we want to remove the DB role ID element (role_)\n if (roleId?.startsWith(DocumentType.ROLE) && isBuiltin(roleId)) {\n return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1]\n }\n return roleId\n}\n", "import env from \"../environment\"\nimport * as context from \"../context\"\n\n/**\n * Read the TENANT_FEATURE_FLAGS env var and return an array of features flags for each tenant.\n * The env var is formatted as:\n * tenant1:feature1:feature2,tenant2:feature1\n */\nexport function buildFeatureFlags() {\n if (!env.TENANT_FEATURE_FLAGS) {\n return\n }\n\n const tenantFeatureFlags: Record<string, string[]> = {}\n\n env.TENANT_FEATURE_FLAGS.split(\",\").forEach(tenantToFeatures => {\n const [tenantId, ...features] = tenantToFeatures.split(\":\")\n\n features.forEach(feature => {\n if (!tenantFeatureFlags[tenantId]) {\n tenantFeatureFlags[tenantId] = []\n }\n tenantFeatureFlags[tenantId].push(feature)\n })\n })\n\n return tenantFeatureFlags\n}\n\nexport function isEnabled(featureFlag: string) {\n const tenantId = context.getTenantId()\n const flags = getTenantFeatureFlags(tenantId)\n return flags.includes(featureFlag)\n}\n\nexport function getTenantFeatureFlags(tenantId: string) {\n let flags: string[] = []\n const envFlags = buildFeatureFlags()\n if (envFlags) {\n const globalFlags = envFlags[\"*\"]\n const tenantFlags = envFlags[tenantId] || []\n\n // Explicitly exclude tenants from global features if required.\n // Prefix the tenant flag with '!'\n const tenantOverrides = tenantFlags.reduce(\n (acc: string[], flag: string) => {\n if (flag.startsWith(\"!\")) {\n let stripped = flag.substring(1)\n acc.push(stripped)\n }\n return acc\n },\n []\n )\n\n if (globalFlags) {\n flags.push(...globalFlags)\n }\n if (tenantFlags.length) {\n flags.push(...tenantFlags)\n }\n\n // Purge any tenant specific overrides\n flags = flags.filter(flag => {\n return tenantOverrides.indexOf(flag) == -1 && !flag.startsWith(\"!\")\n })\n }\n\n return flags\n}\n\nexport enum TenantFeatureFlag {\n LICENSING = \"LICENSING\",\n GOOGLE_SHEETS = \"GOOGLE_SHEETS\",\n USER_GROUPS = \"USER_GROUPS\",\n ONBOARDING_TOUR = \"ONBOARDING_TOUR\",\n}\n", "const redis = require(\"../redis/init\")\nconst { v4: uuidv4 } = require(\"uuid\")\nconst { logWarn } = require(\"../logging\")\nimport env from \"../environment\"\nimport {\n Session,\n ScannedSession,\n SessionKey,\n CreateSession,\n} from \"@budibase/types\"\n\n// a week in seconds\nconst EXPIRY_SECONDS = 86400 * 7\n\nfunction makeSessionID(userId: string, sessionId: string) {\n return `${userId}/${sessionId}`\n}\n\nexport async function getSessionsForUser(userId: string): Promise<Session[]> {\n if (!userId) {\n console.trace(\"Cannot get sessions for undefined userId\")\n return []\n }\n const client = await redis.getSessionClient()\n const sessions: ScannedSession[] = await client.scan(userId)\n return sessions.map(session => session.value)\n}\n\nexport async function invalidateSessions(\n userId: string,\n opts: { sessionIds?: string[]; reason?: string } = {}\n) {\n try {\n const reason = opts?.reason || \"unknown\"\n let sessionIds: string[] = opts.sessionIds || []\n let sessionKeys: SessionKey[]\n\n // If no sessionIds, get all the sessions for the user\n if (sessionIds.length === 0) {\n const sessions = await getSessionsForUser(userId)\n sessionKeys = sessions.map(session => ({\n key: makeSessionID(session.userId, session.sessionId),\n }))\n } else {\n // use the passed array of sessionIds\n sessionIds = Array.isArray(sessionIds) ? sessionIds : [sessionIds]\n sessionKeys = sessionIds.map(sessionId => ({\n key: makeSessionID(userId, sessionId),\n }))\n }\n\n if (sessionKeys && sessionKeys.length > 0) {\n const client = await redis.getSessionClient()\n const promises = []\n for (let sessionKey of sessionKeys) {\n promises.push(client.delete(sessionKey.key))\n }\n if (!env.isTest()) {\n logWarn(\n `Invalidating sessions for ${userId} (reason: ${reason}) - ${sessionKeys\n .map(sessionKey => sessionKey.key)\n .join(\", \")}`\n )\n }\n await Promise.all(promises)\n }\n } catch (err) {\n console.error(`Error invalidating sessions: ${err}`)\n }\n}\n\nexport async function createASession(\n userId: string,\n createSession: CreateSession\n) {\n // invalidate all other sessions\n await invalidateSessions(userId, { reason: \"creation\" })\n\n const client = await redis.getSessionClient()\n const sessionId = createSession.sessionId\n const csrfToken = createSession.csrfToken ? createSession.csrfToken : uuidv4()\n const key = makeSessionID(userId, sessionId)\n\n const session: Session = {\n ...createSession,\n csrfToken,\n createdAt: new Date().toISOString(),\n lastAccessedAt: new Date().toISOString(),\n userId,\n }\n await client.store(key, session, EXPIRY_SECONDS)\n return session\n}\n\nexport async function updateSessionTTL(session: Session) {\n const client = await redis.getSessionClient()\n const key = makeSessionID(session.userId, session.sessionId)\n session.lastAccessedAt = new Date().toISOString()\n await client.store(key, session, EXPIRY_SECONDS)\n}\n\nexport async function endSession(userId: string, sessionId: string) {\n const client = await redis.getSessionClient()\n await client.delete(makeSessionID(userId, sessionId))\n}\n\nexport async function getSession(\n userId: string,\n sessionId: string\n): Promise<Session> {\n if (!userId || !sessionId) {\n throw new Error(`Invalid session details - ${userId} - ${sessionId}`)\n }\n const client = await redis.getSessionClient()\n const session = await client.get(makeSessionID(userId, sessionId))\n if (!session) {\n throw new Error(`Session not found - ${userId} - ${sessionId}`)\n }\n return session\n}\n", "import { getTenantId, isMultiTenant } from \"../../context\"\nimport * as configs from \"../../configs\"\nimport { ConfigType, GoogleInnerConfig } from \"@budibase/types\"\n\n/**\n * Utility to handle authentication errors.\n *\n * @param {*} done The passport callback.\n * @param {*} message Message that will be returned in the response body\n * @param {*} err (Optional) error that will be logged\n */\n\nexport function authError(done: Function, message: string, err?: any) {\n return done(\n err,\n null, // never return a user\n { message: message }\n )\n}\n\nexport async function ssoCallbackUrl(\n type: ConfigType,\n config?: GoogleInnerConfig\n) {\n // incase there is a callback URL from before\n if (config && (config as GoogleInnerConfig).callbackURL) {\n return (config as GoogleInnerConfig).callbackURL as string\n }\n const settingsConfig = await configs.getSettingsConfig()\n\n let callbackUrl = `/api/global/auth`\n if (isMultiTenant()) {\n callbackUrl += `/${getTenantId()}`\n }\n callbackUrl += `/${type}/callback`\n\n return `${settingsConfig.platformUrl}${callbackUrl}`\n}\n", "import { UserStatus } from \"../../constants\"\nimport { compare } from \"../../utils\"\nimport * as users from \"../../users\"\nimport { authError } from \"./utils\"\nimport { BBContext } from \"@budibase/types\"\n\nconst INVALID_ERR = \"Invalid credentials\"\nconst EXPIRED = \"This account has expired. Please reset your password\"\n\nexport const options = {\n passReqToCallback: true,\n}\n\n/**\n * Passport Local Authentication Middleware.\n * @param {*} ctx the request structure\n * @param {*} email username to login with\n * @param {*} password plain text password to log in with\n * @param {*} done callback from passport to return user information and errors\n * @returns The authenticated user, or errors if they occur\n */\nexport async function authenticate(\n ctx: BBContext,\n email: string,\n password: string,\n done: Function\n) {\n if (!email) return authError(done, \"Email Required\")\n if (!password) return authError(done, \"Password Required\")\n\n const dbUser = await users.getGlobalUserByEmail(email)\n if (dbUser == null) {\n console.info(`user=${email} could not be found`)\n return authError(done, INVALID_ERR)\n }\n\n if (dbUser.status === UserStatus.INACTIVE) {\n console.info(`user=${email} is inactive`, dbUser)\n return authError(done, INVALID_ERR)\n }\n\n if (!dbUser.password) {\n console.info(`user=${email} has no password set`, dbUser)\n return authError(done, EXPIRED)\n }\n\n if (!(await compare(password, dbUser.password))) {\n return authError(done, INVALID_ERR)\n }\n\n // intentionally remove the users password in payload\n delete dbUser.password\n return done(null, dbUser)\n}\n", "import { generateGlobalUserID } from \"../../../db\"\nimport { authError } from \"../utils\"\nimport * as users from \"../../../users\"\nimport * as context from \"../../../context\"\nimport fetch from \"node-fetch\"\nimport {\n SaveSSOUserFunction,\n SaveUserOpts,\n SSOAuthDetails,\n SSOUser,\n User,\n} from \"@budibase/types\"\n\n// no-op function for user save\n// - this allows datasource auth and access token refresh to work correctly\n// - prefer no-op over an optional argument to ensure function is provided to login flows\nexport const ssoSaveUserNoOp: SaveSSOUserFunction = (\n user: SSOUser,\n opts: SaveUserOpts\n) => Promise.resolve(user)\n\n/**\n * Common authentication logic for third parties. e.g. OAuth, OIDC.\n */\nexport async function authenticate(\n details: SSOAuthDetails,\n requireLocalAccount: boolean = true,\n done: any,\n saveUserFn: SaveSSOUserFunction\n) {\n if (!saveUserFn) {\n throw new Error(\"Save user function must be provided\")\n }\n if (!details.userId) {\n return authError(done, \"sso user id required\")\n }\n if (!details.email) {\n return authError(done, \"sso user email required\")\n }\n\n // use the third party id\n const userId = generateGlobalUserID(details.userId)\n\n let dbUser: User | undefined\n\n // try to load by id\n try {\n dbUser = await users.getById(userId)\n } catch (err: any) {\n // abort when not 404 error\n if (!err.status || err.status !== 404) {\n return authError(\n done,\n \"Unexpected error when retrieving existing user\",\n err\n )\n }\n }\n\n // fallback to loading by email\n if (!dbUser) {\n dbUser = await users.getGlobalUserByEmail(details.email)\n }\n\n // exit early if there is still no user and auto creation is disabled\n if (!dbUser && requireLocalAccount) {\n return authError(\n done,\n \"Email does not yet exist. You must set up your local budibase account first.\"\n )\n }\n\n // first time creation\n if (!dbUser) {\n // setup a blank user using the third party id\n dbUser = {\n _id: userId,\n email: details.email,\n roles: {},\n tenantId: context.getTenantId(),\n }\n }\n\n let ssoUser = await syncUser(dbUser, details)\n // never prompt for password reset\n ssoUser.forceResetPassword = false\n\n try {\n // don't try to re-save any existing password\n delete ssoUser.password\n // create or sync the user\n ssoUser = (await saveUserFn(ssoUser, {\n hashPassword: false,\n requirePassword: false,\n })) as SSOUser\n } catch (err: any) {\n return authError(done, \"Error saving user\", err)\n }\n\n return done(null, ssoUser)\n}\n\nasync function getProfilePictureUrl(user: User, details: SSOAuthDetails) {\n const pictureUrl = details.profile?._json.picture\n if (pictureUrl) {\n const response = await fetch(pictureUrl)\n if (response.status === 200) {\n const type = response.headers.get(\"content-type\") as string\n if (type.startsWith(\"image/\")) {\n return pictureUrl\n }\n }\n }\n}\n\n/**\n * @returns a user that has been sync'd with third party information\n */\nasync function syncUser(user: User, details: SSOAuthDetails): Promise<SSOUser> {\n let firstName\n let lastName\n let pictureUrl\n let oauth2\n let thirdPartyProfile\n\n if (details.profile) {\n const profile = details.profile\n\n if (profile.name) {\n const name = profile.name\n // first name\n if (name.givenName) {\n firstName = name.givenName\n }\n // last name\n if (name.familyName) {\n lastName = name.familyName\n }\n }\n\n pictureUrl = await getProfilePictureUrl(user, details)\n\n thirdPartyProfile = {\n ...profile._json,\n }\n }\n\n // oauth tokens for future use\n if (details.oauth2) {\n oauth2 = {\n ...details.oauth2,\n }\n }\n\n return {\n ...user,\n provider: details.provider,\n providerType: details.providerType,\n firstName,\n lastName,\n thirdPartyProfile,\n pictureUrl,\n oauth2,\n }\n}\n", "import { ssoCallbackUrl } from \"../utils\"\nimport * as sso from \"./sso\"\nimport {\n ConfigType,\n SSOProfile,\n SSOAuthDetails,\n SSOProviderType,\n SaveSSOUserFunction,\n GoogleInnerConfig,\n} from \"@budibase/types\"\nconst GoogleStrategy = require(\"passport-google-oauth\").OAuth2Strategy\n\nexport function buildVerifyFn(saveUserFn: SaveSSOUserFunction) {\n return (\n accessToken: string,\n refreshToken: string,\n profile: SSOProfile,\n done: Function\n ) => {\n const details: SSOAuthDetails = {\n provider: \"google\",\n providerType: SSOProviderType.GOOGLE,\n userId: profile.id,\n profile: profile,\n email: profile._json.email,\n oauth2: {\n accessToken,\n refreshToken,\n },\n }\n\n return sso.authenticate(\n details,\n true, // require local accounts to exist\n done,\n saveUserFn\n )\n }\n}\n\n/**\n * Create an instance of the google passport strategy. This wrapper fetches the configuration\n * from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.\n * @returns Dynamically configured Passport Google Strategy\n */\nexport async function strategyFactory(\n config: GoogleInnerConfig,\n callbackUrl: string,\n saveUserFn: SaveSSOUserFunction\n) {\n try {\n const { clientID, clientSecret } = config\n\n if (!clientID || !clientSecret) {\n throw new Error(\n \"Configuration invalid. Must contain google clientID and clientSecret\"\n )\n }\n\n const verify = buildVerifyFn(saveUserFn)\n return new GoogleStrategy(\n {\n clientID: config.clientID,\n clientSecret: config.clientSecret,\n callbackURL: callbackUrl,\n },\n verify\n )\n } catch (err: any) {\n console.error(err)\n throw new Error(`Error constructing google authentication strategy: ${err}`)\n }\n}\n\nexport async function getCallbackUrl(config: GoogleInnerConfig) {\n return ssoCallbackUrl(ConfigType.GOOGLE, config)\n}\n", "import fetch from \"node-fetch\"\nimport * as sso from \"./sso\"\nimport { ssoCallbackUrl } from \"../utils\"\nimport { validEmail } from \"../../../utils\"\nimport {\n ConfigType,\n OIDCInnerConfig,\n SSOProfile,\n OIDCStrategyConfiguration,\n SSOAuthDetails,\n SSOProviderType,\n JwtClaims,\n SaveSSOUserFunction,\n} from \"@budibase/types\"\n\nconst OIDCStrategy = require(\"@techpass/passport-openidconnect\").Strategy\n\nexport function buildVerifyFn(saveUserFn: SaveSSOUserFunction) {\n /**\n * @param {*} issuer The identity provider base URL\n * @param {*} sub The user ID\n * @param {*} profile The user profile information. Created by passport from the /userinfo response\n * @param {*} jwtClaims The parsed id_token claims\n * @param {*} accessToken The access_token for contacting the identity provider - may or may not be a JWT\n * @param {*} refreshToken The refresh_token for obtaining a new access_token - usually not a JWT\n * @param {*} idToken The id_token - always a JWT\n * @param {*} params The response body from requesting an access_token\n * @param {*} done The passport callback: err, user, info\n */\n return async (\n issuer: string,\n sub: string,\n profile: SSOProfile,\n jwtClaims: JwtClaims,\n accessToken: string,\n refreshToken: string,\n idToken: string,\n params: any,\n done: Function\n ) => {\n const details: SSOAuthDetails = {\n // store the issuer info to enable sync in future\n provider: issuer,\n providerType: SSOProviderType.OIDC,\n userId: profile.id,\n profile: profile,\n email: getEmail(profile, jwtClaims),\n oauth2: {\n accessToken: accessToken,\n refreshToken: refreshToken,\n },\n }\n\n return sso.authenticate(\n details,\n false, // don't require local accounts to exist\n done,\n saveUserFn\n )\n }\n}\n\n/**\n * @param {*} profile The structured profile created by passport using the user info endpoint\n * @param {*} jwtClaims The claims returned in the id token\n */\nfunction getEmail(profile: SSOProfile, jwtClaims: JwtClaims) {\n // profile not guaranteed to contain email e.g. github connected azure ad account\n if (profile._json.email) {\n return profile._json.email\n }\n\n // fallback to id token email\n if (jwtClaims.email) {\n return jwtClaims.email\n }\n\n // fallback to id token preferred username\n const username = jwtClaims.preferred_username\n if (username && validEmail(username)) {\n return username\n }\n\n throw new Error(\n `Could not determine user email from profile ${JSON.stringify(\n profile\n )} and claims ${JSON.stringify(jwtClaims)}`\n )\n}\n\n/**\n * Create an instance of the oidc passport strategy. This wrapper fetches the configuration\n * from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.\n * @returns Dynamically configured Passport OIDC Strategy\n */\nexport async function strategyFactory(\n config: OIDCStrategyConfiguration,\n saveUserFn: SaveSSOUserFunction\n) {\n try {\n const verify = buildVerifyFn(saveUserFn)\n const strategy = new OIDCStrategy(config, verify)\n strategy.name = \"oidc\"\n return strategy\n } catch (err: any) {\n console.error(err)\n throw new Error(`Error constructing OIDC authentication strategy - ${err}`)\n }\n}\n\nexport async function fetchStrategyConfig(\n oidcConfig: OIDCInnerConfig,\n callbackUrl?: string\n): Promise<OIDCStrategyConfiguration> {\n try {\n const { clientID, clientSecret, configUrl } = oidcConfig\n\n if (!clientID || !clientSecret || !callbackUrl || !configUrl) {\n // check for remote config and all required elements\n throw new Error(\n \"Configuration invalid. Must contain clientID, clientSecret, callbackUrl and configUrl\"\n )\n }\n\n const response = await fetch(configUrl)\n\n if (!response.ok) {\n throw new Error(\n `Unexpected response when fetching openid-configuration: ${response.statusText}`\n )\n }\n\n const body = await response.json()\n\n return {\n issuer: body.issuer,\n authorizationURL: body.authorization_endpoint,\n tokenURL: body.token_endpoint,\n userInfoURL: body.userinfo_endpoint,\n clientID: clientID,\n clientSecret: clientSecret,\n callbackURL: callbackUrl,\n }\n } catch (err) {\n console.error(err)\n throw new Error(\n `Error constructing OIDC authentication configuration - ${err}`\n )\n }\n}\n\nexport async function getCallbackUrl() {\n return ssoCallbackUrl(ConfigType.OIDC)\n}\n", "import * as google from \"../sso/google\"\nimport { Cookie } from \"../../../constants\"\nimport { clearCookie, getCookie } from \"../../../utils\"\nimport { doWithDB } from \"../../../db\"\nimport * as configs from \"../../../configs\"\nimport { BBContext, Database, SSOProfile } from \"@budibase/types\"\nimport { ssoSaveUserNoOp } from \"../sso/sso\"\nconst GoogleStrategy = require(\"passport-google-oauth\").OAuth2Strategy\n\ntype Passport = {\n authenticate: any\n}\n\nasync function fetchGoogleCreds() {\n let config = await configs.getGoogleDatasourceConfig()\n\n if (!config) {\n throw new Error(\"No google configuration found\")\n }\n return config\n}\n\nexport async function preAuth(\n passport: Passport,\n ctx: BBContext,\n next: Function\n) {\n // get the relevant config\n const googleConfig = await fetchGoogleCreds()\n const platformUrl = await configs.getPlatformUrl({ tenantAware: false })\n\n let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`\n const strategy = await google.strategyFactory(\n googleConfig,\n callbackUrl,\n ssoSaveUserNoOp\n )\n\n if (!ctx.query.appId || !ctx.query.datasourceId) {\n ctx.throw(400, \"appId and datasourceId query params not present.\")\n }\n\n return passport.authenticate(strategy, {\n scope: [\"profile\", \"email\", \"https://www.googleapis.com/auth/spreadsheets\"],\n accessType: \"offline\",\n prompt: \"consent\",\n })(ctx, next)\n}\n\nexport async function postAuth(\n passport: Passport,\n ctx: BBContext,\n next: Function\n) {\n // get the relevant config\n const config = await fetchGoogleCreds()\n const platformUrl = await configs.getPlatformUrl({ tenantAware: false })\n\n let callbackUrl = `${platformUrl}/api/global/auth/datasource/google/callback`\n const authStateCookie = getCookie(ctx, Cookie.DatasourceAuth)\n\n return passport.authenticate(\n new GoogleStrategy(\n {\n clientID: config.clientID,\n clientSecret: config.clientSecret,\n callbackURL: callbackUrl,\n },\n (\n accessToken: string,\n refreshToken: string,\n profile: SSOProfile,\n done: Function\n ) => {\n clearCookie(ctx, Cookie.DatasourceAuth)\n done(null, { accessToken, refreshToken })\n }\n ),\n { successRedirect: \"/\", failureRedirect: \"/error\" },\n async (err: any, tokens: string[]) => {\n const baseUrl = `/builder/app/${authStateCookie.appId}/data`\n // update the DB for the datasource with all the user info\n await doWithDB(authStateCookie.appId, async (db: Database) => {\n let datasource\n try {\n datasource = await db.get(authStateCookie.datasourceId)\n } catch (err: any) {\n if (err.status === 404) {\n ctx.redirect(baseUrl)\n }\n }\n if (!datasource.config) {\n datasource.config = {}\n }\n datasource.config.auth = { type: \"google\", ...tokens }\n await db.put(datasource)\n ctx.redirect(`${baseUrl}/datasource/${authStateCookie.datasourceId}`)\n })\n }\n )(ctx, next)\n}\n", "import { BBContext, EndpointMatcher, RegexMatcher } from \"@budibase/types\"\n\nconst PARAM_REGEX = /\\/:(.*?)(\\/.*)?$/g\n\nexport const buildMatcherRegex = (\n patterns: EndpointMatcher[]\n): RegexMatcher[] => {\n if (!patterns) {\n return []\n }\n return patterns.map(pattern => {\n let route = pattern.route\n const method = pattern.method\n const strict = pattern.strict ? pattern.strict : false\n\n // if there is a param in the route\n // use a wildcard pattern\n const matches = route.match(PARAM_REGEX)\n if (matches) {\n for (let match of matches) {\n const suffix = match.endsWith(\"/\") ? \"/\" : \"\"\n const pattern = \"/.*\" + suffix\n route = route.replace(match, pattern)\n }\n }\n\n return { regex: new RegExp(route), method, strict, route }\n })\n}\n\nexport const matches = (ctx: BBContext, options: RegexMatcher[]) => {\n return options.find(({ regex, method, strict, route }) => {\n let urlMatch\n if (strict) {\n urlMatch = ctx.request.url === route\n } else {\n urlMatch = regex.test(ctx.request.url)\n }\n\n const methodMatch =\n method === \"ALL\"\n ? true\n : ctx.request.method.toLowerCase() === method.toLowerCase()\n\n return urlMatch && methodMatch\n })\n}\n", "import crypto from \"crypto\"\nimport env from \"../environment\"\n\nconst ALGO = \"aes-256-ctr\"\nconst SEPARATOR = \"-\"\nconst ITERATIONS = 10000\nconst RANDOM_BYTES = 16\nconst STRETCH_LENGTH = 32\n\nexport enum SecretOption {\n API = \"api\",\n ENCRYPTION = \"encryption\",\n}\n\nexport function getSecret(secretOption: SecretOption): string {\n let secret, secretName\n switch (secretOption) {\n case SecretOption.ENCRYPTION:\n secret = env.ENCRYPTION_KEY\n secretName = \"ENCRYPTION_KEY\"\n break\n case SecretOption.API:\n default:\n secret = env.API_ENCRYPTION_KEY\n secretName = \"API_ENCRYPTION_KEY\"\n break\n }\n if (!secret) {\n throw new Error(`Secret \"${secretName}\" has not been set in environment.`)\n }\n return secret\n}\n\nfunction stretchString(string: string, salt: Buffer) {\n return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, \"sha512\")\n}\n\nexport function encrypt(\n input: string,\n secretOption: SecretOption = SecretOption.API\n) {\n const salt = crypto.randomBytes(RANDOM_BYTES)\n const stretched = stretchString(getSecret(secretOption), salt)\n const cipher = crypto.createCipheriv(ALGO, stretched, salt)\n const base = cipher.update(input)\n const final = cipher.final()\n const encrypted = Buffer.concat([base, final]).toString(\"hex\")\n return `${salt.toString(\"hex\")}${SEPARATOR}${encrypted}`\n}\n\nexport function decrypt(\n input: string,\n secretOption: SecretOption = SecretOption.API\n) {\n const [salt, encrypted] = input.split(SEPARATOR)\n const saltBuffer = Buffer.from(salt, \"hex\")\n const stretched = stretchString(getSecret(secretOption), saltBuffer)\n const decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)\n const base = decipher.update(Buffer.from(encrypted, \"hex\"))\n const final = decipher.final()\n return Buffer.concat([base, final]).toString()\n}\n", "// BASE\n\nexport abstract class BudibaseError extends Error {\n code: string\n\n constructor(message: string, code: ErrorCode) {\n super(message)\n this.code = code\n }\n\n protected getPublicError?(): any\n}\n\n// ERROR HANDLING\n\nexport enum ErrorCode {\n USAGE_LIMIT_EXCEEDED = \"usage_limit_exceeded\",\n FEATURE_DISABLED = \"feature_disabled\",\n INVALID_API_KEY = \"invalid_api_key\",\n HTTP = \"http\",\n}\n\n/**\n * For the given error, build the public representation that is safe\n * to be exposed over an api.\n */\nexport const getPublicError = (err: any) => {\n let error\n if (err.code) {\n // add generic error information\n error = {\n code: err.code,\n }\n\n if (err.getPublicError) {\n error = {\n ...error,\n // get any additional context from this error\n ...err.getPublicError(),\n }\n }\n }\n\n return error\n}\n\n// HTTP\n\nexport class HTTPError extends BudibaseError {\n status: number\n\n constructor(message: string, httpStatus: number, code = ErrorCode.HTTP) {\n super(message, code)\n this.status = httpStatus\n }\n}\n\n// LICENSING\n\nexport class UsageLimitError extends HTTPError {\n limitName: string\n\n constructor(message: string, limitName: string) {\n super(message, 400, ErrorCode.USAGE_LIMIT_EXCEEDED)\n this.limitName = limitName\n }\n\n getPublicError() {\n return {\n limitName: this.limitName,\n }\n }\n}\n\nexport class FeatureDisabledError extends HTTPError {\n featureName: string\n\n constructor(message: string, featureName: string) {\n super(message, 400, ErrorCode.FEATURE_DISABLED)\n this.featureName = featureName\n }\n\n getPublicError() {\n return {\n featureName: this.featureName,\n }\n }\n}\n\n// AUTH\n\nexport class InvalidAPIKeyError extends BudibaseError {\n constructor() {\n super(\n \"Invalid API key - may need re-generated, or user doesn't exist\",\n ErrorCode.INVALID_API_KEY\n )\n }\n}\n\n// USERS\n\nexport class EmailUnavailableError extends Error {\n constructor(email: string) {\n super(`Email already in use: '${email}'`)\n }\n}\n", "export * from \"./errors\"\n", "import { Cookie, Header } from \"../constants\"\nimport {\n getCookie,\n clearCookie,\n openJwt,\n isValidInternalAPIKey,\n} from \"../utils\"\nimport { getUser } from \"../cache/user\"\nimport { getSession, updateSessionTTL } from \"../security/sessions\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { SEPARATOR, queryGlobalView, ViewName } from \"../db\"\nimport { getGlobalDB, doInTenant } from \"../context\"\nimport { decrypt } from \"../security/encryption\"\nimport * as identity from \"../context/identity\"\nimport env from \"../environment\"\nimport { Ctx, EndpointMatcher } from \"@budibase/types\"\nimport { InvalidAPIKeyError, ErrorCode } from \"../errors\"\n\nconst ONE_MINUTE = env.SESSION_UPDATE_PERIOD\n ? parseInt(env.SESSION_UPDATE_PERIOD)\n : 60 * 1000\n\ninterface FinaliseOpts {\n authenticated?: boolean\n internal?: boolean\n publicEndpoint?: boolean\n version?: string\n user?: any\n}\n\nfunction timeMinusOneMinute() {\n return new Date(Date.now() - ONE_MINUTE).toISOString()\n}\n\nfunction finalise(ctx: any, opts: FinaliseOpts = {}) {\n ctx.publicEndpoint = opts.publicEndpoint || false\n ctx.isAuthenticated = opts.authenticated || false\n ctx.user = opts.user\n ctx.internal = opts.internal || false\n ctx.version = opts.version\n}\n\nasync function checkApiKey(apiKey: string, populateUser?: Function) {\n // check both the primary and the fallback internal api keys\n // this allows for rotation\n if (isValidInternalAPIKey(apiKey)) {\n return { valid: true, user: undefined }\n }\n const decrypted = decrypt(apiKey)\n const tenantId = decrypted.split(SEPARATOR)[0]\n return doInTenant(tenantId, async () => {\n let userId\n try {\n const db = getGlobalDB()\n // api key is encrypted in the database\n userId = (await queryGlobalView(\n ViewName.BY_API_KEY,\n {\n key: apiKey,\n },\n db\n )) as string\n } catch (err) {\n userId = undefined\n }\n if (userId) {\n return {\n valid: true,\n user: await getUser(userId, tenantId, populateUser),\n }\n } else {\n throw new InvalidAPIKeyError()\n }\n })\n}\n\n/**\n * This middleware is tenancy aware, so that it does not depend on other middlewares being used.\n * The tenancy modules should not be used here and it should be assumed that the tenancy context\n * has not yet been populated.\n */\nexport default function (\n noAuthPatterns: EndpointMatcher[] = [],\n opts: { publicAllowed?: boolean; populateUser?: Function } = {\n publicAllowed: false,\n }\n) {\n const noAuthOptions = noAuthPatterns ? buildMatcherRegex(noAuthPatterns) : []\n return async (ctx: Ctx | any, next: any) => {\n let publicEndpoint = false\n const version = ctx.request.headers[Header.API_VER]\n // the path is not authenticated\n const found = matches(ctx, noAuthOptions)\n if (found) {\n publicEndpoint = true\n }\n try {\n // check the actual user is authenticated first, try header or cookie\n let headerToken = ctx.request.headers[Header.TOKEN]\n\n const authCookie = getCookie(ctx, Cookie.Auth) || openJwt(headerToken)\n let apiKey = ctx.request.headers[Header.API_KEY]\n\n if (!apiKey && ctx.request.headers[Header.AUTHORIZATION]) {\n apiKey = ctx.request.headers[Header.AUTHORIZATION].split(\" \")[1]\n }\n\n const tenantId = ctx.request.headers[Header.TENANT_ID]\n let authenticated = false,\n user = null,\n internal = false\n if (authCookie && !apiKey) {\n const sessionId = authCookie.sessionId\n const userId = authCookie.userId\n let session\n try {\n // getting session handles error checking (if session exists etc)\n session = await getSession(userId, sessionId)\n if (opts && opts.populateUser) {\n user = await getUser(\n userId,\n session.tenantId,\n opts.populateUser(ctx)\n )\n } else {\n user = await getUser(userId, session.tenantId)\n }\n user.csrfToken = session.csrfToken\n\n if (session?.lastAccessedAt < timeMinusOneMinute()) {\n // make sure we denote that the session is still in use\n await updateSessionTTL(session)\n }\n authenticated = true\n } catch (err: any) {\n authenticated = false\n console.error(`Auth Error: ${err.message}`)\n console.error(err)\n // remove the cookie as the user does not exist anymore\n clearCookie(ctx, Cookie.Auth)\n }\n }\n // this is an internal request, no user made it\n if (!authenticated && apiKey) {\n const populateUser = opts.populateUser ? opts.populateUser(ctx) : null\n const { valid, user: foundUser } = await checkApiKey(\n apiKey,\n populateUser\n )\n if (valid && foundUser) {\n authenticated = true\n user = foundUser\n } else if (valid) {\n authenticated = true\n internal = true\n }\n }\n if (!user && tenantId) {\n user = { tenantId }\n } else if (user) {\n delete user.password\n }\n // be explicit\n if (!authenticated) {\n authenticated = false\n }\n // isAuthenticated is a function, so use a variable to be able to check authed state\n finalise(ctx, { authenticated, user, internal, version, publicEndpoint })\n\n if (user && user.email) {\n return identity.doInUserContext(user, ctx, next)\n } else {\n return next()\n }\n } catch (err: any) {\n console.error(`Auth Error: ${err.message}`)\n console.error(err)\n // invalid token, clear the cookie\n if (err?.name === \"JsonWebTokenError\") {\n clearCookie(ctx, Cookie.Auth)\n } else if (err?.code === ErrorCode.INVALID_API_KEY) {\n ctx.throw(403, err.message)\n }\n // allow configuring for public access\n if ((opts && opts.publicAllowed) || publicEndpoint) {\n finalise(ctx, { authenticated: false, version, publicEndpoint })\n return next()\n } else {\n ctx.throw(err.status || 403, err)\n }\n }\n }\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext | any, next: any) => {\n // Placeholder for audit log middleware\n return next()\n}\n", "import { doInTenant } from \"../context\"\nimport { getTenantIDFromCtx } from \"../tenancy\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { Header } from \"../constants\"\nimport {\n BBContext,\n EndpointMatcher,\n GetTenantIdOptions,\n TenantResolutionStrategy,\n} from \"@budibase/types\"\n\nexport default function (\n allowQueryStringPatterns: EndpointMatcher[],\n noTenancyPatterns: EndpointMatcher[],\n opts: { noTenancyRequired?: boolean } = { noTenancyRequired: false }\n) {\n const allowQsOptions = buildMatcherRegex(allowQueryStringPatterns)\n const noTenancyOptions = buildMatcherRegex(noTenancyPatterns)\n\n return async function (ctx: BBContext | any, next: any) {\n const allowNoTenant =\n opts.noTenancyRequired || !!matches(ctx, noTenancyOptions)\n const tenantOpts: GetTenantIdOptions = {\n allowNoTenant,\n }\n\n const allowQs = !!matches(ctx, allowQsOptions)\n if (!allowQs) {\n tenantOpts.excludeStrategies = [TenantResolutionStrategy.QUERY]\n }\n\n const tenantId = getTenantIDFromCtx(ctx, tenantOpts)\n ctx.set(Header.TENANT_ID, tenantId as string)\n return doInTenant(tenantId, next)\n }\n}\n", "import { Header } from \"../constants\"\nimport { BBContext } from \"@budibase/types\"\nimport { isValidInternalAPIKey } from \"../utils\"\n\n/**\n * API Key only endpoint.\n */\nexport default async (ctx: BBContext, next: any) => {\n const apiKey = ctx.request.headers[Header.API_KEY]\n if (!apiKey) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n if (Array.isArray(apiKey)) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n if (!isValidInternalAPIKey(apiKey)) {\n ctx.throw(403, \"Unauthorized\")\n }\n\n return next()\n}\n", "import { Header } from \"../constants\"\nimport { buildMatcherRegex, matches } from \"./matchers\"\nimport { BBContext, EndpointMatcher } from \"@budibase/types\"\n\n/**\n * GET, HEAD and OPTIONS methods are considered safe operations\n *\n * POST, PUT, PATCH, and DELETE methods, being state changing verbs,\n * should have a CSRF token attached to the request\n */\nconst EXCLUDED_METHODS = [\"GET\", \"HEAD\", \"OPTIONS\"]\n\n/**\n * There are only three content type values that can be used in cross domain requests.\n * If any other value is used, e.g. application/json, the browser will first make a OPTIONS\n * request which will be protected by CORS.\n */\nconst INCLUDED_CONTENT_TYPES = [\n \"application/x-www-form-urlencoded\",\n \"multipart/form-data\",\n \"text/plain\",\n]\n\n/**\n * Validate the CSRF token generated aganst the user session.\n * Compare the token with the x-csrf-token header.\n *\n * If the token is not found within the request or the value provided\n * does not match the value within the user session, the request is rejected.\n *\n * CSRF protection provided using the 'Synchronizer Token Pattern'\n * https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern\n *\n */\nexport default function (\n opts: { noCsrfPatterns: EndpointMatcher[] } = { noCsrfPatterns: [] }\n) {\n const noCsrfOptions = buildMatcherRegex(opts.noCsrfPatterns)\n return async (ctx: BBContext | any, next: any) => {\n // don't apply for excluded paths\n const found = matches(ctx, noCsrfOptions)\n if (found) {\n return next()\n }\n\n // don't apply for the excluded http methods\n if (EXCLUDED_METHODS.indexOf(ctx.method) !== -1) {\n return next()\n }\n\n // don't apply when the content type isn't supported\n let contentType = ctx.get(\"content-type\")\n ? ctx.get(\"content-type\").toLowerCase()\n : \"\"\n if (\n !INCLUDED_CONTENT_TYPES.filter(type => contentType.includes(type)).length\n ) {\n return next()\n }\n\n // don't apply csrf when the internal api key has been used\n if (ctx.internal) {\n return next()\n }\n\n // apply csrf when there is a token in the session (new logins)\n // in future there should be a hard requirement that the token is present\n const userToken = ctx.user?.csrfToken\n if (!userToken) {\n return next()\n }\n\n // reject if no token in request or mismatch\n const requestToken = ctx.get(Header.CSRF_TOKEN)\n if (!requestToken || requestToken !== userToken) {\n ctx.throw(403, \"Invalid CSRF token\")\n }\n\n return next()\n }\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)\n ) {\n ctx.throw(403, \"Admin user only endpoint.\")\n }\n return next()\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.builder || !ctx.user.builder.global) &&\n (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)\n ) {\n ctx.throw(403, \"Builder user only endpoint.\")\n }\n return next()\n}\n", "import { BBContext } from \"@budibase/types\"\n\nexport default async (ctx: BBContext, next: any) => {\n if (\n !ctx.internal &&\n (!ctx.user || !ctx.user.builder || !ctx.user.builder.global)\n ) {\n ctx.throw(403, \"Builder user only endpoint.\")\n }\n return next()\n}\n", "import env from \"../../environment\"\nimport { logger } from \"./logger\"\nimport { IncomingMessage } from \"http\"\nconst pino = require(\"koa-pino-logger\")\nimport { Options } from \"pino-http\"\nimport { Ctx } from \"@budibase/types\"\nconst correlator = require(\"correlation-id\")\n\nexport function pinoSettings(): Options {\n return {\n logger,\n genReqId: correlator.getId,\n autoLogging: {\n ignore: (req: IncomingMessage) => !!req.url?.includes(\"/health\"),\n },\n serializers: {\n req: req => {\n return {\n method: req.method,\n url: req.url,\n correlationId: req.id,\n }\n },\n res: res => {\n return {\n status: res.statusCode,\n }\n },\n },\n }\n}\n\nfunction getMiddleware() {\n if (env.HTTP_LOGGING) {\n return pino(pinoSettings())\n } else {\n return (ctx: Ctx, next: any) => {\n return next()\n }\n }\n}\n\nconst pinoMiddleware = getMiddleware()\n\nexport default pinoMiddleware\n", "import { Header } from \"../../constants\"\nimport { v4 as uuid } from \"uuid\"\nconst correlator = require(\"correlation-id\")\n\nconst correlation = (ctx: any, next: any) => {\n // use the provided correlation id header if present\n let correlationId = ctx.headers[Header.CORRELATION_ID]\n if (!correlationId) {\n correlationId = uuid()\n }\n\n return correlator.withId(correlationId, () => {\n return next()\n })\n}\n\nexport default correlation\n", "import { APIError } from \"@budibase/types\"\nimport * as errors from \"../errors\"\n\nexport async function errorHandling(ctx: any, next: any) {\n try {\n await next()\n } catch (err: any) {\n const status = err.status || err.statusCode || 500\n ctx.status = status\n\n if (status >= 400 && status < 500) {\n console.warn(err)\n } else {\n console.error(err)\n }\n\n const error = errors.getPublicError(err)\n const body: APIError = {\n message: err.message,\n status: status,\n validationErrors: err.validation,\n error,\n }\n\n ctx.body = body\n }\n}\n\nexport default errorHandling\n", "import { Ctx } from \"@budibase/types\"\n\n/**\n * Expects a standard \"query\" query string property which is the JSON body\n * of the request, which has to be sent via query string due to the requirement\n * of making an endpoint a GET request e.g. downloading a file stream.\n */\nexport default function (ctx: Ctx, next: any) {\n const queryString = ctx.request.query?.query as string | undefined\n if (ctx.request.method.toLowerCase() !== \"get\") {\n ctx.throw(\n 500,\n \"Query to download middleware can only be used for get requests.\"\n )\n }\n if (!queryString) {\n return next()\n }\n const decoded = decodeURIComponent(queryString)\n let json\n try {\n json = JSON.parse(decoded)\n } catch (err) {\n return next()\n }\n ctx.request.body = json\n return next()\n}\n", "import Joi, { ObjectSchema } from \"joi\"\nimport { BBContext } from \"@budibase/types\"\n\nfunction validate(\n schema: Joi.ObjectSchema | Joi.ArraySchema,\n property: string\n) {\n // Return a Koa middleware function\n return (ctx: BBContext, next: any) => {\n if (!schema) {\n return next()\n }\n let params = null\n // @ts-ignore\n let reqProp = ctx.request?.[property]\n if (ctx[property] != null) {\n params = ctx[property]\n } else if (reqProp != null) {\n params = reqProp\n }\n\n // not all schemas have the append property e.g. array schemas\n if ((schema as Joi.ObjectSchema).append) {\n schema = (schema as Joi.ObjectSchema).append({\n createdAt: Joi.any().optional(),\n updatedAt: Joi.any().optional(),\n })\n }\n\n const { error } = schema.validate(params)\n if (error) {\n ctx.throw(400, `Invalid ${property} - ${error.message}`)\n return\n }\n return next()\n }\n}\n\nexport function body(schema: Joi.ObjectSchema | Joi.ArraySchema) {\n return validate(schema, \"body\")\n}\n\nexport function params(schema: Joi.ObjectSchema | Joi.ArraySchema) {\n return validate(schema, \"params\")\n}\n", "export * as local from \"./passport/local\"\nexport * as google from \"./passport/sso/google\"\nexport * as oidc from \"./passport/sso/oidc\"\nimport * as datasourceGoogle from \"./passport/datasource/google\"\nexport const datasource = {\n google: datasourceGoogle,\n}\nexport { authError, ssoCallbackUrl } from \"./passport/utils\"\nexport { default as authenticated } from \"./authenticated\"\nexport { default as auditLog } from \"./auditLog\"\nexport { default as tenancy } from \"./tenancy\"\nexport { default as internalApi } from \"./internalApi\"\nexport { default as csrf } from \"./csrf\"\nexport { default as adminOnly } from \"./adminOnly\"\nexport { default as builderOrAdmin } from \"./builderOrAdmin\"\nexport { default as builderOnly } from \"./builderOnly\"\nexport { default as pino } from \"../logging/pino/middleware\"\nexport { default as correlation } from \"../logging/correlation/middleware\"\nexport { default as errorHandling } from \"./errorHandling\"\nexport { default as querystringToBody } from \"./querystringToBody\"\nexport * as joiValidator from \"./joi-validator\"\n", "const _passport = require(\"koa-passport\")\nconst LocalStrategy = require(\"passport-local\").Strategy\nimport { getGlobalDB } from \"../context\"\nimport { Cookie } from \"../constants\"\nimport { getSessionsForUser, invalidateSessions } from \"../security/sessions\"\nimport {\n authenticated,\n csrf,\n google,\n local,\n oidc,\n tenancy,\n} from \"../middleware\"\nimport * as userCache from \"../cache/user\"\nimport { invalidateUser } from \"../cache/user\"\nimport {\n ConfigType,\n GoogleInnerConfig,\n OIDCInnerConfig,\n PlatformLogoutOpts,\n SSOProviderType,\n} from \"@budibase/types\"\nimport * as events from \"../events\"\nimport * as configs from \"../configs\"\nimport { clearCookie, getCookie } from \"../utils\"\nimport { ssoSaveUserNoOp } from \"../middleware/passport/sso/sso\"\n\nconst refresh = require(\"passport-oauth2-refresh\")\nexport {\n auditLog,\n authError,\n internalApi,\n ssoCallbackUrl,\n adminOnly,\n builderOnly,\n builderOrAdmin,\n joiValidator,\n google,\n oidc,\n} from \"../middleware\"\nexport const buildAuthMiddleware = authenticated\nexport const buildTenancyMiddleware = tenancy\nexport const buildCsrfMiddleware = csrf\nexport const passport = _passport\nexport const jwt = require(\"jsonwebtoken\")\n\n// Strategies\n_passport.use(new LocalStrategy(local.options, local.authenticate))\n\nasync function refreshOIDCAccessToken(\n chosenConfig: OIDCInnerConfig,\n refreshToken: string\n): Promise<RefreshResponse> {\n const callbackUrl = await oidc.getCallbackUrl()\n let enrichedConfig: any\n let strategy: any\n\n try {\n enrichedConfig = await oidc.fetchStrategyConfig(chosenConfig, callbackUrl)\n if (!enrichedConfig) {\n throw new Error(\"OIDC Config contents invalid\")\n }\n strategy = await oidc.strategyFactory(enrichedConfig, ssoSaveUserNoOp)\n } catch (err) {\n console.error(err)\n throw new Error(\"Could not refresh OAuth Token\")\n }\n\n refresh.use(strategy, {\n setRefreshOAuth2() {\n return strategy._getOAuth2Client(enrichedConfig)\n },\n })\n\n return new Promise(resolve => {\n refresh.requestNewAccessToken(\n ConfigType.OIDC,\n refreshToken,\n (err: any, accessToken: string, refreshToken: any, params: any) => {\n resolve({ err, accessToken, refreshToken, params })\n }\n )\n })\n}\n\nasync function refreshGoogleAccessToken(\n config: GoogleInnerConfig,\n refreshToken: any\n): Promise<RefreshResponse> {\n let callbackUrl = await google.getCallbackUrl(config)\n\n let strategy\n try {\n strategy = await google.strategyFactory(\n config,\n callbackUrl,\n ssoSaveUserNoOp\n )\n } catch (err: any) {\n console.error(err)\n throw new Error(\n `Error constructing OIDC refresh strategy: message=${err.message}`\n )\n }\n\n refresh.use(strategy)\n\n return new Promise(resolve => {\n refresh.requestNewAccessToken(\n ConfigType.GOOGLE,\n refreshToken,\n (err: any, accessToken: string, refreshToken: string, params: any) => {\n resolve({ err, accessToken, refreshToken, params })\n }\n )\n })\n}\n\ninterface RefreshResponse {\n err?: {\n data?: string\n }\n accessToken?: string\n refreshToken?: string\n params?: any\n}\n\nexport async function refreshOAuthToken(\n refreshToken: string,\n providerType: SSOProviderType,\n configId?: string\n): Promise<RefreshResponse> {\n switch (providerType) {\n case SSOProviderType.OIDC:\n if (!configId) {\n return { err: { data: \"OIDC config id not provided\" } }\n }\n const oidcConfig = await configs.getOIDCConfigById(configId)\n if (!oidcConfig) {\n return { err: { data: \"OIDC configuration not found\" } }\n }\n return refreshOIDCAccessToken(oidcConfig, refreshToken)\n case SSOProviderType.GOOGLE:\n let googleConfig = await configs.getGoogleConfig()\n if (!googleConfig) {\n return { err: { data: \"Google configuration not found\" } }\n }\n return refreshGoogleAccessToken(googleConfig, refreshToken)\n }\n}\n\n// TODO: Refactor to use user save function instead to prevent the need for\n// manually saving and invalidating on callback\nexport async function updateUserOAuth(userId: string, oAuthConfig: any) {\n const details = {\n accessToken: oAuthConfig.accessToken,\n refreshToken: oAuthConfig.refreshToken,\n }\n\n try {\n const db = getGlobalDB()\n const dbUser = await db.get(userId)\n\n //Do not overwrite the refresh token if a valid one is not provided.\n if (typeof details.refreshToken !== \"string\") {\n delete details.refreshToken\n }\n\n dbUser.oauth2 = {\n ...dbUser.oauth2,\n ...details,\n }\n\n await db.put(dbUser)\n\n await invalidateUser(userId)\n } catch (e) {\n console.error(\"Could not update OAuth details for current user\", e)\n }\n}\n\n/**\n * Logs a user out from budibase. Re-used across account portal and builder.\n */\nexport async function platformLogout(opts: PlatformLogoutOpts) {\n const ctx = opts.ctx\n const userId = opts.userId\n const keepActiveSession = opts.keepActiveSession\n\n if (!ctx) throw new Error(\"Koa context must be supplied to logout.\")\n\n const currentSession = getCookie(ctx, Cookie.Auth)\n let sessions = await getSessionsForUser(userId)\n\n if (keepActiveSession) {\n sessions = sessions.filter(\n session => session.sessionId !== currentSession.sessionId\n )\n } else {\n // clear cookies\n clearCookie(ctx, Cookie.Auth)\n }\n\n const sessionIds = sessions.map(({ sessionId }) => sessionId)\n await invalidateSessions(userId, { sessionIds, reason: \"logout\" })\n await events.auth.logout(ctx.user?.email)\n await userCache.invalidateUser(userId)\n}\n", "export * from \"./auth\"\n", "import {\n DatasourceFieldType,\n QueryType,\n PluginType,\n AutomationStepType,\n AutomationStepIdArray,\n AutomationIOType,\n AutomationCustomIOType,\n} from \"@budibase/types\"\nimport joi from \"joi\"\n\nconst DATASOURCE_TYPES = [\n \"Relational\",\n \"Non-relational\",\n \"Spreadsheet\",\n \"Object store\",\n \"Graph\",\n \"API\",\n]\n\nfunction runJoi(validator: joi.Schema, schema: any) {\n const { error } = validator.validate(schema)\n if (error) {\n throw error\n }\n}\n\nfunction validateComponent(schema: any) {\n const validator = joi.object({\n type: joi.string().allow(PluginType.COMPONENT).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi\n .object({\n name: joi.string().required(),\n settings: joi.array().items(joi.object().unknown(true)).required(),\n })\n .unknown(true),\n })\n runJoi(validator, schema)\n}\n\nfunction validateDatasource(schema: any) {\n const fieldValidator = joi.object({\n type: joi\n .string()\n .allow(...Object.values(DatasourceFieldType))\n .required(),\n required: joi.boolean().required(),\n default: joi.any(),\n display: joi.string(),\n })\n\n const queryValidator = joi\n .object({\n type: joi.string().allow(...Object.values(QueryType)),\n readable: joi.boolean(),\n fields: joi.object().pattern(joi.string(), fieldValidator),\n })\n .required()\n\n const validator = joi.object({\n type: joi.string().allow(PluginType.DATASOURCE).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi.object({\n docs: joi.string(),\n friendlyName: joi.string().required(),\n type: joi.string().allow(...DATASOURCE_TYPES),\n description: joi.string().required(),\n datasource: joi.object().pattern(joi.string(), fieldValidator).required(),\n query: joi\n .object()\n .pattern(joi.string(), queryValidator)\n .unknown(true)\n .required(),\n extra: joi.object().pattern(\n joi.string(),\n joi.object({\n type: joi.string().required(),\n displayName: joi.string().required(),\n required: joi.boolean(),\n data: joi.object(),\n })\n ),\n }),\n })\n runJoi(validator, schema)\n}\n\nfunction validateAutomation(schema: any) {\n const basePropsValidator = joi.object().pattern(joi.string(), {\n type: joi\n .string()\n .allow(...Object.values(AutomationIOType))\n .required(),\n customType: joi.string().allow(...Object.values(AutomationCustomIOType)),\n title: joi.string(),\n description: joi.string(),\n enum: joi.array().items(joi.string()),\n pretty: joi.array().items(joi.string()),\n })\n const stepSchemaValidator = joi\n .object({\n properties: basePropsValidator,\n required: joi.array().items(joi.string()),\n })\n .concat(basePropsValidator)\n .required()\n const validator = joi.object({\n type: joi.string().allow(PluginType.AUTOMATION).required(),\n metadata: joi.object().unknown(true).required(),\n hash: joi.string().optional(),\n version: joi.string().optional(),\n schema: joi.object({\n name: joi.string().required(),\n tagline: joi.string().required(),\n icon: joi.string().required(),\n description: joi.string().required(),\n type: joi\n .string()\n .allow(AutomationStepType.ACTION, AutomationStepType.LOGIC)\n .required(),\n stepId: joi\n .string()\n .disallow(...AutomationStepIdArray)\n .required(),\n inputs: joi.object().optional(),\n schema: joi\n .object({\n inputs: stepSchemaValidator,\n outputs: stepSchemaValidator,\n })\n .required(),\n }),\n })\n runJoi(validator, schema)\n}\n\nexport function validate(schema: any) {\n switch (schema?.type) {\n case PluginType.COMPONENT:\n validateComponent(schema)\n break\n case PluginType.DATASOURCE:\n validateDatasource(schema)\n break\n case PluginType.AUTOMATION:\n validateAutomation(schema)\n break\n default:\n throw new Error(`Unknown plugin type - check schema.json: ${schema.type}`)\n }\n}\n", "export * from \"./utils\"\n", "import { join } from \"path\"\nimport { tmpdir } from \"os\"\nimport fs from \"fs\"\nimport env from \"../environment\"\n\n/****************************************************\n * NOTE: When adding a new bucket - name *\n * sure that S3 usages (like budibase-infra) *\n * have been updated to have a unique bucket name. *\n ****************************************************/\n// can't be an enum - only numbers can be used for computed types\nexport const ObjectStoreBuckets = {\n BACKUPS: env.BACKUPS_BUCKET_NAME,\n APPS: env.APPS_BUCKET_NAME,\n TEMPLATES: env.TEMPLATES_BUCKET_NAME,\n GLOBAL: env.GLOBAL_BUCKET_NAME,\n PLUGINS: env.PLUGIN_BUCKET_NAME,\n}\n\nconst bbTmp = join(tmpdir(), \".budibase\")\nif (!fs.existsSync(bbTmp)) {\n fs.mkdirSync(bbTmp)\n}\n\nexport function budibaseTempDir() {\n return bbTmp\n}\n", "const sanitize = require(\"sanitize-s3-objectkey\")\nimport AWS from \"aws-sdk\"\nimport stream from \"stream\"\nimport fetch from \"node-fetch\"\nimport tar from \"tar-fs\"\nimport zlib from \"zlib\"\nimport { promisify } from \"util\"\nimport { join } from \"path\"\nimport fs from \"fs\"\nimport env from \"../environment\"\nimport { budibaseTempDir } from \"./utils\"\nimport { v4 } from \"uuid\"\nimport { APP_PREFIX, APP_DEV_PREFIX } from \"../db\"\n\nconst streamPipeline = promisify(stream.pipeline)\n// use this as a temporary store of buckets that are being created\nconst STATE = {\n bucketCreationPromises: {},\n}\n\ntype ListParams = {\n ContinuationToken?: string\n}\n\ntype UploadParams = {\n bucket: string\n filename: string\n path: string\n type?: string | null\n // can be undefined, we will remove it\n metadata?: {\n [key: string]: string | undefined\n }\n}\n\nconst CONTENT_TYPE_MAP: any = {\n txt: \"text/plain\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n json: \"application/json\",\n gz: \"application/gzip\",\n}\n\nconst STRING_CONTENT_TYPES = [\n CONTENT_TYPE_MAP.html,\n CONTENT_TYPE_MAP.css,\n CONTENT_TYPE_MAP.js,\n CONTENT_TYPE_MAP.json,\n]\n\n// does normal sanitization and then swaps dev apps to apps\nexport function sanitizeKey(input: string) {\n return sanitize(sanitizeBucket(input)).replace(/\\\\/g, \"/\")\n}\n\n// simply handles the dev app to app conversion\nexport function sanitizeBucket(input: string) {\n return input.replace(new RegExp(APP_DEV_PREFIX, \"g\"), APP_PREFIX)\n}\n\n/**\n * Gets a connection to the object store using the S3 SDK.\n * @param {string} bucket the name of the bucket which blobs will be uploaded/retrieved from.\n * @param {object} opts configuration for the object store.\n * @return {Object} an S3 object store object, check S3 Nodejs SDK for usage.\n * @constructor\n */\nexport const ObjectStore = (\n bucket: string,\n opts: { presigning: boolean } = { presigning: false }\n) => {\n const config: any = {\n s3ForcePathStyle: true,\n signatureVersion: \"v4\",\n apiVersion: \"2006-03-01\",\n accessKeyId: env.MINIO_ACCESS_KEY,\n secretAccessKey: env.MINIO_SECRET_KEY,\n region: env.AWS_REGION,\n }\n if (bucket) {\n config.params = {\n Bucket: sanitizeBucket(bucket),\n }\n }\n\n // custom S3 is in use i.e. minio\n if (env.MINIO_URL) {\n if (opts.presigning && env.MINIO_ENABLED) {\n // IMPORTANT: Signed urls will inspect the host header of the request.\n // Normally a signed url will need to be generated with a specified host in mind.\n // To support dynamic hosts, e.g. some unknown self-hosted installation url,\n // use a predefined host. The host 'minio-service' is also forwarded to minio requests via nginx\n config.endpoint = \"minio-service\"\n } else {\n config.endpoint = env.MINIO_URL\n }\n }\n\n return new AWS.S3(config)\n}\n\n/**\n * Given an object store and a bucket name this will make sure the bucket exists,\n * if it does not exist then it will create it.\n */\nexport const makeSureBucketExists = async (client: any, bucketName: string) => {\n bucketName = sanitizeBucket(bucketName)\n try {\n await client\n .headBucket({\n Bucket: bucketName,\n })\n .promise()\n } catch (err: any) {\n const promises: any = STATE.bucketCreationPromises\n const doesntExist = err.statusCode === 404,\n noAccess = err.statusCode === 403\n if (promises[bucketName]) {\n await promises[bucketName]\n } else if (doesntExist || noAccess) {\n if (doesntExist) {\n // bucket doesn't exist create it\n promises[bucketName] = client\n .createBucket({\n Bucket: bucketName,\n })\n .promise()\n await promises[bucketName]\n delete promises[bucketName]\n }\n } else {\n throw new Error(\"Unable to write to object store bucket.\")\n }\n }\n}\n\n/**\n * Uploads the contents of a file given the required parameters, useful when\n * temp files in use (for example file uploaded as an attachment).\n */\nexport const upload = async ({\n bucket: bucketName,\n filename,\n path,\n type,\n metadata,\n}: UploadParams) => {\n const extension = filename.split(\".\").pop()\n const fileBytes = fs.readFileSync(path)\n\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n\n let contentType = type\n if (!contentType) {\n contentType = extension\n ? CONTENT_TYPE_MAP[extension.toLowerCase()]\n : CONTENT_TYPE_MAP.txt\n }\n const config: any = {\n // windows file paths need to be converted to forward slashes for s3\n Key: sanitizeKey(filename),\n Body: fileBytes,\n ContentType: contentType,\n }\n if (metadata && typeof metadata === \"object\") {\n // remove any nullish keys from the metadata object, as these may be considered invalid\n for (let key of Object.keys(metadata)) {\n if (!metadata[key] || typeof metadata[key] !== \"string\") {\n delete metadata[key]\n }\n }\n config.Metadata = metadata\n }\n return objectStore.upload(config).promise()\n}\n\n/**\n * Similar to the upload function but can be used to send a file stream\n * through to the object store.\n */\nexport const streamUpload = async (\n bucketName: string,\n filename: string,\n stream: any,\n extra = {}\n) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n\n // Set content type for certain known extensions\n if (filename?.endsWith(\".js\")) {\n extra = {\n ...extra,\n ContentType: \"application/javascript\",\n }\n } else if (filename?.endsWith(\".svg\")) {\n extra = {\n ...extra,\n ContentType: \"image\",\n }\n }\n\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(filename),\n Body: stream,\n ...extra,\n }\n return objectStore.upload(params).promise()\n}\n\n/**\n * retrieves the contents of a file from the object store, if it is a known content type it\n * will be converted, otherwise it will be returned as a buffer stream.\n */\nexport const retrieve = async (bucketName: string, filepath: string) => {\n const objectStore = ObjectStore(bucketName)\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(filepath),\n }\n const response: any = await objectStore.getObject(params).promise()\n // currently these are all strings\n if (STRING_CONTENT_TYPES.includes(response.ContentType)) {\n return response.Body.toString(\"utf8\")\n } else {\n return response.Body\n }\n}\n\nexport const listAllObjects = async (bucketName: string, path: string) => {\n const objectStore = ObjectStore(bucketName)\n const list = (params: ListParams = {}) => {\n return objectStore\n .listObjectsV2({\n ...params,\n Bucket: sanitizeBucket(bucketName),\n Prefix: sanitizeKey(path),\n })\n .promise()\n }\n let isTruncated = false,\n token,\n objects: AWS.S3.Types.Object[] = []\n do {\n let params: ListParams = {}\n if (token) {\n params.ContinuationToken = token\n }\n const response = await list(params)\n if (response.Contents) {\n objects = objects.concat(response.Contents)\n }\n isTruncated = !!response.IsTruncated\n } while (isTruncated)\n return objects\n}\n\n/**\n * Generate a presigned url with a default TTL of 1 hour\n */\nexport const getPresignedUrl = (\n bucketName: string,\n key: string,\n durationSeconds: number = 3600\n) => {\n const objectStore = ObjectStore(bucketName, { presigning: true })\n const params = {\n Bucket: sanitizeBucket(bucketName),\n Key: sanitizeKey(key),\n Expires: durationSeconds,\n }\n const url = objectStore.getSignedUrl(\"getObject\", params)\n\n if (!env.MINIO_ENABLED) {\n // return the full URL to the client\n return url\n } else {\n // return the path only to the client\n // use the presigned url route to ensure the static\n // hostname will be used in the request\n const signedUrl = new URL(url)\n const path = signedUrl.pathname\n const query = signedUrl.search\n return `/files/signed${path}${query}`\n }\n}\n\n/**\n * Same as retrieval function but puts to a temporary file.\n */\nexport const retrieveToTmp = async (bucketName: string, filepath: string) => {\n bucketName = sanitizeBucket(bucketName)\n filepath = sanitizeKey(filepath)\n const data = await retrieve(bucketName, filepath)\n const outputPath = join(budibaseTempDir(), v4())\n fs.writeFileSync(outputPath, data)\n return outputPath\n}\n\nexport const retrieveDirectory = async (bucketName: string, path: string) => {\n let writePath = join(budibaseTempDir(), v4())\n fs.mkdirSync(writePath)\n const objects = await listAllObjects(bucketName, path)\n let fullObjects = await Promise.all(\n objects.map(obj => retrieve(bucketName, obj.Key!))\n )\n let count = 0\n for (let obj of objects) {\n const filename = obj.Key!\n const data = fullObjects[count++]\n const possiblePath = filename.split(\"/\")\n if (possiblePath.length > 1) {\n const dirs = possiblePath.slice(0, possiblePath.length - 1)\n fs.mkdirSync(join(writePath, ...dirs), { recursive: true })\n }\n fs.writeFileSync(join(writePath, ...possiblePath), data)\n }\n return writePath\n}\n\n/**\n * Delete a single file.\n */\nexport const deleteFile = async (bucketName: string, filepath: string) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n const params = {\n Bucket: bucketName,\n Key: sanitizeKey(filepath),\n }\n return objectStore.deleteObject(params).promise()\n}\n\nexport const deleteFiles = async (bucketName: string, filepaths: string[]) => {\n const objectStore = ObjectStore(bucketName)\n await makeSureBucketExists(objectStore, bucketName)\n const params = {\n Bucket: bucketName,\n Delete: {\n Objects: filepaths.map((path: any) => ({ Key: sanitizeKey(path) })),\n },\n }\n return objectStore.deleteObjects(params).promise()\n}\n\n/**\n * Delete a path, including everything within.\n */\nexport const deleteFolder = async (\n bucketName: string,\n folder: string\n): Promise<any> => {\n bucketName = sanitizeBucket(bucketName)\n folder = sanitizeKey(folder)\n const client = ObjectStore(bucketName)\n const listParams = {\n Bucket: bucketName,\n Prefix: folder,\n }\n\n const existingObjectsResponse = await client.listObjects(listParams).promise()\n if (existingObjectsResponse.Contents?.length === 0) {\n return\n }\n const deleteParams: any = {\n Bucket: bucketName,\n Delete: {\n Objects: [],\n },\n }\n\n existingObjectsResponse.Contents?.forEach((content: any) => {\n deleteParams.Delete.Objects.push({ Key: content.Key })\n })\n\n const deleteResponse = await client.deleteObjects(deleteParams).promise()\n // can only empty 1000 items at once\n if (deleteResponse.Deleted?.length === 1000) {\n return deleteFolder(bucketName, folder)\n }\n}\n\nexport const uploadDirectory = async (\n bucketName: string,\n localPath: string,\n bucketPath: string\n) => {\n bucketName = sanitizeBucket(bucketName)\n let uploads = []\n const files = fs.readdirSync(localPath, { withFileTypes: true })\n for (let file of files) {\n const path = sanitizeKey(join(bucketPath, file.name))\n const local = join(localPath, file.name)\n if (file.isDirectory()) {\n uploads.push(uploadDirectory(bucketName, local, path))\n } else {\n uploads.push(streamUpload(bucketName, path, fs.createReadStream(local)))\n }\n }\n await Promise.all(uploads)\n return files\n}\n\nexport const downloadTarballDirect = async (\n url: string,\n path: string,\n headers = {}\n) => {\n path = sanitizeKey(path)\n const response = await fetch(url, { headers })\n if (!response.ok) {\n throw new Error(`unexpected response ${response.statusText}`)\n }\n\n await streamPipeline(response.body, zlib.createUnzip(), tar.extract(path))\n}\n\nexport const downloadTarball = async (\n url: string,\n bucketName: string,\n path: string\n) => {\n bucketName = sanitizeBucket(bucketName)\n path = sanitizeKey(path)\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`unexpected response ${response.statusText}`)\n }\n\n const tmpPath = join(budibaseTempDir(), path)\n await streamPipeline(response.body, zlib.createUnzip(), tar.extract(tmpPath))\n if (!env.isTest() && env.SELF_HOSTED) {\n await uploadDirectory(bucketName, tmpPath, path)\n }\n // return the temporary path incase there is a use for it\n return tmpPath\n}\n", "import env from \"../environment\"\nconst cfsign = require(\"aws-cloudfront-sign\")\n\nlet PRIVATE_KEY: string | undefined\n\nfunction getPrivateKey() {\n if (!env.CLOUDFRONT_PRIVATE_KEY_64) {\n throw new Error(\"CLOUDFRONT_PRIVATE_KEY_64 is not set\")\n }\n\n if (PRIVATE_KEY) {\n return PRIVATE_KEY\n }\n\n PRIVATE_KEY = Buffer.from(env.CLOUDFRONT_PRIVATE_KEY_64, \"base64\").toString(\n \"utf-8\"\n )\n\n return PRIVATE_KEY\n}\n\nconst getCloudfrontSignParams = () => {\n return {\n keypairId: env.CLOUDFRONT_PUBLIC_KEY_ID,\n privateKeyString: getPrivateKey(),\n expireTime: new Date().getTime() + 1000 * 60 * 60, // 1 hour\n }\n}\n\nexport const getPresignedUrl = (s3Key: string) => {\n const url = getUrl(s3Key)\n return cfsign.getSignedUrl(url, getCloudfrontSignParams())\n}\n\nexport const getUrl = (s3Key: string) => {\n let prefix = \"/\"\n if (s3Key.startsWith(\"/\")) {\n prefix = \"\"\n }\n return `${env.CLOUDFRONT_CDN}${prefix}${s3Key}`\n}\n", "import env from \"../../environment\"\nimport * as objectStore from \"../objectStore\"\nimport * as cloudfront from \"../cloudfront\"\n\n/**\n * In production the client library is stored in the object store, however in development\n * we use the symlinked version produced by lerna, located in node modules. We link to this\n * via a specific endpoint (under /api/assets/client).\n * @param {string} appId In production we need the appId to look up the correct bucket, as the\n * version of the client lib may differ between apps.\n * @param {string} version The version to retrieve.\n * @return {string} The URL to be inserted into appPackage response or server rendered\n * app index file.\n */\nexport const clientLibraryUrl = (appId: string, version: string) => {\n if (env.isProd()) {\n let file = `${objectStore.sanitizeKey(appId)}/budibase-client.js`\n if (env.CLOUDFRONT_CDN) {\n // append app version to bust the cache\n if (version) {\n file += `?v=${version}`\n }\n // don't need to use presigned for client with cloudfront\n // file is public\n return cloudfront.getUrl(file)\n } else {\n return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, file)\n }\n } else {\n return `/api/assets/client`\n }\n}\n\nexport const getAppFileUrl = (s3Key: string) => {\n if (env.CLOUDFRONT_CDN) {\n return cloudfront.getPresignedUrl(s3Key)\n } else {\n return objectStore.getPresignedUrl(env.APPS_BUCKET_NAME, s3Key)\n }\n}\n", "import env from \"../../environment\"\nimport * as context from \"../../context\"\nimport * as objectStore from \"../objectStore\"\nimport * as cloudfront from \"../cloudfront\"\n\n// URLs\n\nexport const getGlobalFileUrl = (type: string, name: string, etag?: string) => {\n let file = getGlobalFileS3Key(type, name)\n if (env.CLOUDFRONT_CDN) {\n if (etag) {\n file = `${file}?etag=${etag}`\n }\n return cloudfront.getPresignedUrl(file)\n } else {\n return objectStore.getPresignedUrl(env.GLOBAL_BUCKET_NAME, file)\n }\n}\n\n// KEYS\n\nexport const getGlobalFileS3Key = (type: string, name: string) => {\n let file = `${type}/${name}`\n if (env.MULTI_TENANCY) {\n const tenantId = context.getTenantId()\n file = `${tenantId}/${file}`\n }\n return file\n}\n", "import env from \"../../environment\"\nimport * as objectStore from \"../objectStore\"\nimport * as context from \"../../context\"\nimport * as cloudfront from \"../cloudfront\"\nimport { Plugin } from \"@budibase/types\"\n\n// URLS\n\nexport const enrichPluginURLs = (plugins: Plugin[]) => {\n if (!plugins || !plugins.length) {\n return []\n }\n return plugins.map(plugin => {\n const jsUrl = getPluginJSUrl(plugin)\n const iconUrl = getPluginIconUrl(plugin)\n return { ...plugin, jsUrl, iconUrl }\n })\n}\n\nconst getPluginJSUrl = (plugin: Plugin) => {\n const s3Key = getPluginJSKey(plugin)\n return getPluginUrl(s3Key)\n}\n\nconst getPluginIconUrl = (plugin: Plugin): string | undefined => {\n const s3Key = getPluginIconKey(plugin)\n if (!s3Key) {\n return\n }\n return getPluginUrl(s3Key)\n}\n\nconst getPluginUrl = (s3Key: string) => {\n if (env.CLOUDFRONT_CDN) {\n return cloudfront.getPresignedUrl(s3Key)\n } else {\n return objectStore.getPresignedUrl(env.PLUGIN_BUCKET_NAME, s3Key)\n }\n}\n\n// S3 KEYS\n\nexport const getPluginJSKey = (plugin: Plugin) => {\n return getPluginS3Key(plugin, \"plugin.min.js\")\n}\n\nexport const getPluginIconKey = (plugin: Plugin) => {\n // stored iconUrl is deprecated - hardcode to icon.svg in this case\n const iconFileName = plugin.iconUrl ? \"icon.svg\" : plugin.iconFileName\n if (!iconFileName) {\n return\n }\n return getPluginS3Key(plugin, iconFileName)\n}\n\nconst getPluginS3Key = (plugin: Plugin, fileName: string) => {\n const s3Key = getPluginS3Dir(plugin.name)\n return `${s3Key}/${fileName}`\n}\n\nexport const getPluginS3Dir = (pluginName: string) => {\n let s3Key = `${pluginName}`\n if (env.MULTI_TENANCY) {\n const tenantId = context.getTenantId()\n s3Key = `${tenantId}/${s3Key}`\n }\n if (env.CLOUDFRONT_CDN) {\n s3Key = `plugins/${s3Key}`\n }\n return s3Key\n}\n", "export * from \"./app\"\nexport * from \"./global\"\nexport * from \"./plugins\"\n", "export * from \"./objectStore\"\nexport * from \"./utils\"\nexport * from \"./buckets\"\n", "// Mimic the outer package export for usage in index.ts\n// The outer exports can't be used as they now reference dist directly\nexport { default as Client } from \"./redis\"\nexport * as utils from \"./utils\"\nexport * as clients from \"./init\"\nexport * as locks from \"./redlockImpl\"\n", "import dns from \"dns\"\nimport net from \"net\"\nimport env from \"../environment\"\nimport { promisify } from \"util\"\n\nlet blackListArray: string[] | undefined\nconst performLookup = promisify(dns.lookup)\n\nasync function lookup(address: string): Promise<string[]> {\n if (!net.isIP(address)) {\n // need this for URL parsing simply\n if (!address.startsWith(\"http\")) {\n address = `https://${address}`\n }\n address = new URL(address).hostname\n }\n const addresses = await performLookup(address, {\n all: true,\n })\n return addresses.map(addr => addr.address)\n}\n\nexport async function refreshBlacklist() {\n const blacklist = env.BLACKLIST_IPS\n const list = blacklist?.split(\",\") || []\n let final: string[] = []\n for (let addr of list) {\n const trimmed = addr.trim()\n if (!net.isIP(trimmed)) {\n const addresses = await lookup(trimmed)\n final = final.concat(addresses)\n } else {\n final.push(trimmed)\n }\n }\n blackListArray = final\n}\n\nexport async function isBlacklisted(address: string): Promise<boolean> {\n if (!blackListArray) {\n await refreshBlacklist()\n }\n if (blackListArray?.length === 0) {\n return false\n }\n // no need for DNS\n let ips: string[]\n if (!net.isIP(address)) {\n ips = await lookup(address)\n } else {\n ips = [address]\n }\n return !!blackListArray?.find(addr => ips.includes(addr))\n}\n", "export * from \"./blacklist\"\n", "import {\n Event,\n UserCreatedEvent,\n UserUpdatedEvent,\n UserDeletedEvent,\n UserPermissionAssignedEvent,\n UserPermissionRemovedEvent,\n GroupCreatedEvent,\n GroupUpdatedEvent,\n GroupDeletedEvent,\n GroupUsersAddedEvent,\n GroupUsersDeletedEvent,\n GroupPermissionsEditedEvent,\n} from \"@budibase/types\"\n\nconst getEventProperties: Record<\n string,\n (properties: any) => string | undefined\n> = {\n [Event.USER_CREATED]: (properties: UserCreatedEvent) => properties.userId,\n [Event.USER_UPDATED]: (properties: UserUpdatedEvent) => properties.userId,\n [Event.USER_DELETED]: (properties: UserDeletedEvent) => properties.userId,\n [Event.USER_PERMISSION_ADMIN_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_ADMIN_REMOVED]: (\n properties: UserPermissionRemovedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_BUILDER_ASSIGNED]: (\n properties: UserPermissionAssignedEvent\n ) => properties.userId,\n [Event.USER_PERMISSION_BUILDER_REMOVED]: (\n properties: UserPermissionRemovedEvent\n ) => properties.userId,\n [Event.USER_GROUP_CREATED]: (properties: GroupCreatedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_UPDATED]: (properties: GroupUpdatedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_DELETED]: (properties: GroupDeletedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_USERS_ADDED]: (properties: GroupUsersAddedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_USERS_REMOVED]: (properties: GroupUsersDeletedEvent) =>\n properties.groupId,\n [Event.USER_GROUP_PERMISSIONS_EDITED]: (\n properties: GroupPermissionsEditedEvent\n ) => properties.groupId,\n}\n\nexport function getDocumentId(event: Event, properties: any) {\n const extractor = getEventProperties[event]\n if (!extractor) {\n throw new Error(\"Event does not have a method of document ID extraction\")\n }\n return extractor(properties)\n}\n", "import { EventProcessor } from \"../types\"\nimport { Event, Identity, DocUpdateEvent } from \"@budibase/types\"\nimport { doInTenant } from \"../../../context\"\nimport { getDocumentId } from \"../../documentId\"\nimport { shutdown } from \"../../asyncEvents\"\n\nexport type Processor = (update: DocUpdateEvent) => Promise<void>\nexport type ProcessorMap = { events: Event[]; processor: Processor }[]\n\nexport default class DocumentUpdateProcessor implements EventProcessor {\n processors: ProcessorMap = []\n\n constructor(processors: ProcessorMap) {\n this.processors = processors\n }\n\n async processEvent(\n event: Event,\n identity: Identity,\n properties: any,\n timestamp?: string | number\n ) {\n const tenantId = identity.realTenantId\n const docId = getDocumentId(event, properties)\n if (!tenantId || !docId) {\n return\n }\n for (let { events, processor } of this.processors) {\n if (events.includes(event)) {\n await doInTenant(tenantId, async () => {\n await processor({\n id: docId,\n tenantId,\n })\n })\n }\n }\n }\n\n shutdown() {\n return shutdown()\n }\n}\n", "import { asyncEventQueue, init as initQueue } from \"../events/asyncEvents\"\nimport {\n ProcessorMap,\n default as DocumentUpdateProcessor,\n} from \"../events/processors/async/DocumentUpdateProcessor\"\n\nlet processingPromise: Promise<void>\nlet documentProcessor: DocumentUpdateProcessor\n\nexport function init(processors: ProcessorMap) {\n if (!asyncEventQueue) {\n initQueue()\n }\n if (!documentProcessor) {\n documentProcessor = new DocumentUpdateProcessor(processors)\n }\n // if not processing in this instance, kick it off\n if (!processingPromise) {\n processingPromise = asyncEventQueue.process(async job => {\n const { event, identity, properties, timestamp } = job.data\n await documentProcessor.processEvent(\n event,\n identity,\n properties,\n timestamp\n )\n })\n }\n}\n", "export * as configs from \"./configs\"\nexport * as events from \"./events\"\nexport * as migrations from \"./migrations\"\nexport * as users from \"./users\"\nexport * as roles from \"./security/roles\"\nexport * as permissions from \"./security/permissions\"\nexport * as accounts from \"./accounts\"\nexport * as installation from \"./installation\"\nexport * as featureFlags from \"./featureFlags\"\nexport * as sessions from \"./security/sessions\"\nexport * as platform from \"./platform\"\nexport * as auth from \"./auth\"\nexport * as constants from \"./constants\"\nexport * as logging from \"./logging\"\nexport * as middleware from \"./middleware\"\nexport * as plugins from \"./plugin\"\nexport * as encryption from \"./security/encryption\"\nexport * as queue from \"./queue\"\nexport * as db from \"./db\"\nexport * as context from \"./context\"\nexport * as cache from \"./cache\"\nexport * as objectStore from \"./objectStore\"\nexport * as redis from \"./redis\"\nexport * as locks from \"./redis/redlockImpl\"\nexport * as utils from \"./utils\"\nexport * as errors from \"./errors\"\nexport * as timers from \"./timers\"\nexport { default as env } from \"./environment\"\nexport * as blacklist from \"./blacklist\"\nexport * as docUpdates from \"./docUpdates\"\nexport { SearchParams } from \"./db\"\n// Add context to tenancy for backwards compatibility\n// only do this for external usages to prevent internal\n// circular dependencies\nimport * as context from \"./context\"\nimport * as _tenancy from \"./tenancy\"\nexport const tenancy = {\n ..._tenancy,\n ...context,\n}\n\n// expose error classes directly\nexport * from \"./errors\"\n\n// expose constants directly\nexport * from \"./constants\"\n\n// expose package init function\nimport * as db from \"./db\"\nexport const init = (opts: any = {}) => {\n db.init(opts.db)\n}\n", "export interface Options {\n headers?: { [key: string]: string }\n body?: any\n}\n\nexport enum Method {\n POST = \"POST\",\n GET = \"GET\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n PUT = \"PUT\",\n}\n", "import { License } from \"@budibase/types\"\n\nexport interface CachedLicense extends License {\n refreshedAt?: string\n version?: string\n}\n\n// Middleware\n\nexport interface LicenseMiddlewareOptions {\n checkDayPasses: boolean\n checkUsersLimit: boolean\n refreshVersion: boolean\n licensingCheck?: (ctx: any) => boolean\n populateLicense?: (tenantId: string) => Promise<License | undefined>\n populateFreeLicense?: (ctx: any, tenantId: string) => License\n}\n\n// Cache\n\nexport interface GetCachedLicenseOptions {\n populateLicense?: (tenantId: string) => Promise<License | undefined>\n populateFreeLicense?: (ctx: any, tenantId: string) => License\n refreshVersion: boolean\n}\n", "export interface SelfHostLicenseInfo {\n _id?: string\n _rev?: string\n licenseKey: string\n}\n", "export * from \"./license\"\n", "import { AppBackupContents } from \"@budibase/types\"\nimport { ScimUserServiceConfig } from \"../sdk/scim/users\"\n\nexport interface InitOpts {\n backups?: BackupInitOpts\n scimUserServiceConfig?: ScimUserServiceConfig\n}\n\n// BACKUPS\n\nexport interface BackupInitOpts {\n processing: BackupProcessingOpts\n}\n\nexport interface ImportAppConfig {\n file: {\n type: string\n path: string\n }\n key: string\n}\n\ntype ExportAppFn = (devAppId: string, opts: { tar: boolean }) => Promise<string>\ntype ImportAppFn = (\n devAppId: string,\n db: any,\n config: ImportAppConfig\n) => Promise<string>\ntype StatsFn = (devAppId: string) => Promise<AppBackupContents>\n\nexport interface BackupProcessingOpts {\n exportAppFn: ExportAppFn\n importAppFn: ImportAppFn\n statsFn: StatsFn\n}\n", "export * from \"./api\"\nexport * from \"./license\"\nexport * from \"./documents\"\nexport * from \"./init\"\n", "import { redis } from \"@budibase/backend-core\"\n\nlet client: any\n\nconst init = async () => {\n client = await new redis.Client(redis.utils.Databases.LICENSES).init()\n}\n\nconst shutdown = async () => {\n if (client) {\n await client.finish()\n }\n}\n\nprocess.on(\"exit\", async () => {\n await shutdown()\n})\n\nexport const getClient = async () => {\n if (!client) {\n await init()\n }\n return client\n}\n", "import fetch from \"node-fetch\"\nimport { Method, Options } from \"../types\"\nimport { logging } from \"@budibase/backend-core\"\n\nclass API {\n host: string\n\n constructor(host: string) {\n this.host = host\n }\n\n apiCall =\n (method: Method) =>\n async (url = \"\", options: Options = {}) => {\n if (!options.headers) {\n options.headers = {}\n }\n\n if (!options.headers[\"Content-Type\"]) {\n options.headers = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...options.headers,\n }\n }\n\n const json = options.headers[\"Content-Type\"] === \"application/json\"\n\n // add x-budibase-correlation-id header\n logging.correlation.setHeader(options.headers)\n\n const requestOptions = {\n method: method,\n body: json ? JSON.stringify(options.body) : options.body,\n headers: options.headers,\n // TODO: See if this is necessary\n credentials: \"include\",\n }\n\n return fetch(`${this.host}${url}`, requestOptions)\n }\n\n post = this.apiCall(Method.POST)\n get = this.apiCall(Method.GET)\n patch = this.apiCall(Method.PATCH)\n del = this.apiCall(Method.DELETE)\n put = this.apiCall(Method.PUT)\n}\n\nexport default API\n", "export { default as API } from \"./api\"\n", "import {\n BreakdownQuotaName,\n MonthlyUsage,\n MonthlyQuotaName,\n QuotaUsage,\n StaticQuotaName,\n BaseQuotaUsage,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\nconst getNextQuotaReset = () => {\n const now = new Date()\n // first day of next month - always using the server time\n const nextMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1)\n return nextMonth.toISOString()\n}\n\nexport const setQuotaReset = (usage: QuotaUsage) => {\n usage.quotaReset = getNextQuotaReset()\n}\n\nexport const getCurrentMonthString = (): string => {\n const date = new Date()\n const month = date.getMonth() + 1 // month is 0-based\n const year = date.getFullYear()\n return `${month}-${year}`\n}\n\nexport const generateBaseQuotaUsage = (): BaseQuotaUsage => {\n return {\n usageQuota: {\n [StaticQuotaName.APPS]: 0,\n [StaticQuotaName.ROWS]: 0,\n [StaticQuotaName.PLUGINS]: 0,\n [StaticQuotaName.USERS]: 0,\n [StaticQuotaName.USER_GROUPS]: 0,\n triggers: {},\n },\n monthly: {\n [getCurrentMonthString()]: generateNewMonthlyQuotas(),\n },\n }\n}\n\nexport const generateNewQuotaUsage = (): QuotaUsage => {\n const usage = {\n _id: dbCore.StaticDatabases.GLOBAL.docs.usageQuota,\n quotaReset: getNextQuotaReset(),\n ...generateBaseQuotaUsage(),\n apps: {},\n }\n setCurrentMonth(usage)\n return usage\n}\n\nexport const generateNewMonthlyQuotas = (): MonthlyUsage => {\n return {\n [MonthlyQuotaName.QUERIES]: 0,\n [MonthlyQuotaName.AUTOMATIONS]: 0,\n [MonthlyQuotaName.DAY_PASSES]: 0,\n triggers: {},\n }\n}\n\nexport const setCurrentMonth = (usage: QuotaUsage) => {\n const currentMonth = getCurrentMonthString()\n\n // set the monthly field if it doesn't exist\n if (!usage.monthly) {\n usage.monthly = {}\n }\n\n // set the monthly > currentMonth field if it doesn't exist\n if (!usage.monthly[currentMonth]) {\n usage.monthly[currentMonth] = generateNewMonthlyQuotas()\n }\n\n // set the current field to the current month\n usage.monthly.current = usage.monthly[currentMonth]\n}\n\nexport const getBreakdownName = (\n name: MonthlyQuotaName,\n id?: string\n): BreakdownQuotaName | undefined => {\n if (!id || !name) {\n return\n }\n switch (name) {\n case MonthlyQuotaName.AUTOMATIONS:\n return BreakdownQuotaName.AUTOMATIONS\n case MonthlyQuotaName.QUERIES:\n return dbCore.isTableId(id)\n ? BreakdownQuotaName.ROW_QUERIES\n : dbCore.isDatasourceId(id)\n ? BreakdownQuotaName.DATASOURCE_QUERIES\n : undefined\n }\n}\n", "import {\n UsageBreakdown,\n MonthlyUsage,\n MonthlyQuotaName,\n BREAKDOWN_QUOTA_NAMES,\n APP_QUOTA_NAMES,\n MeteredQuotaName,\n QuotaUsage,\n QuotaUsageType,\n StaticQuotaName,\n UsageValues,\n SetUsageValues,\n QuotaTriggers,\n} from \"@budibase/types\"\nimport { tenancy, db as dbCore, context, cache } from \"@budibase/backend-core\"\nimport * as utils from \"./utils\"\nconst { Writethrough } = cache.writethrough\n\nconst getDB = () => {\n return new Writethrough(tenancy.getGlobalDB())\n}\n\nexport const bustCache = async () => {\n const db = getDB()\n try {\n const usage = await db.get(dbCore.StaticDatabases.GLOBAL.docs.usageQuota)\n if (usage?._rev) {\n await db.remove(\n dbCore.StaticDatabases.GLOBAL.docs.usageQuota,\n usage?._rev\n )\n }\n } catch (e: any) {\n if (e.status !== 404) {\n throw e\n }\n }\n}\n\nexport const getQuotaUsage = async (): Promise<QuotaUsage> => {\n const db = getDB()\n let usage\n try {\n usage = await db.get(dbCore.StaticDatabases.GLOBAL.docs.usageQuota)\n utils.setCurrentMonth(usage)\n utils.setQuotaReset(usage)\n } catch (err: any) {\n if (err.status === 404) {\n // doc doesn't exist. Create it\n usage = utils.generateNewQuotaUsage()\n const response = await db.put(usage)\n usage._rev = response.rev\n } else {\n throw err\n }\n }\n\n // deprecated\n delete usage.usageLimits\n // unused\n delete usage.usageQuota.automationRuns\n delete usage.usageQuota.emails\n delete usage.usageQuota.storage\n delete usage.usageQuota.views\n delete usage.usageQuota.publishedApps\n delete usage.usageQuota.developers\n\n return usage\n}\n\nexport const setUsage = async (\n value: number,\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n return setAllUsage(name, type, { total: value })\n}\n\nexport const setUsagePerApp = async (\n appValues: { [key: string]: number },\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n const db = getDB()\n let quotaUsage = await getQuotaUsage()\n const total = Object.values(appValues).reduce((sum, num) => sum + num, 0)\n for (let [appId, value] of Object.entries(appValues)) {\n quotaUsage = coreUsageUpdate(\n quotaUsage,\n name,\n type,\n {\n total,\n app: value,\n },\n {\n appId,\n }\n )\n }\n const response = await db.put(quotaUsage)\n quotaUsage._rev = response.rev\n return quotaUsage\n}\n\nconst setBreakdown = (\n monthUsage: MonthlyUsage,\n name: MonthlyQuotaName,\n id: string,\n values: UsageValues\n) => {\n const breakdownName = utils.getBreakdownName(name, id)\n if (!breakdownName || !values?.breakdown) {\n return monthUsage\n }\n if (!monthUsage.breakdown) {\n monthUsage.breakdown = {}\n }\n if (!monthUsage.breakdown[breakdownName]) {\n monthUsage.breakdown[breakdownName] = {\n parent: name,\n values: {},\n }\n }\n const breakdown = monthUsage.breakdown[breakdownName] as UsageBreakdown\n breakdown.values[id] = values.breakdown\n return monthUsage\n}\n\nexport const setAppUsageValue = (\n quotaUsage: QuotaUsage,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: { id?: string; appId?: string } = {},\n values: UsageValues\n) => {\n let appId\n try {\n appId = dbCore.getProdAppID((opts?.appId || context.getAppId())!)\n } catch (err) {\n // ignore error for now\n }\n if (!appId || !values.app || !APP_QUOTA_NAMES.includes(name)) {\n return quotaUsage\n }\n if (!quotaUsage.apps?.[appId]) {\n quotaUsage.apps = {\n ...quotaUsage.apps,\n [appId]: utils.generateBaseQuotaUsage(),\n }\n }\n const appUsage = quotaUsage.apps[appId]\n switch (type) {\n case QuotaUsageType.STATIC:\n appUsage.usageQuota[name as StaticQuotaName] = values.app\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName: MonthlyQuotaName = name as MonthlyQuotaName\n let monthUsage = appUsage.monthly[currentMonth]\n\n // init the new month if required\n if (!monthUsage) {\n appUsage.monthly[currentMonth] = utils.generateNewMonthlyQuotas()\n monthUsage = appUsage.monthly[currentMonth]\n }\n\n monthUsage[monthlyName] = values.app\n if (BREAKDOWN_QUOTA_NAMES.includes(monthlyName) && opts?.id) {\n monthUsage = setBreakdown(monthUsage, monthlyName, opts.id, values)\n }\n break\n }\n return quotaUsage\n}\n\nconst getAppUsageValue = (\n quotaUsage: QuotaUsage,\n type: QuotaUsageType,\n name: MeteredQuotaName,\n id?: string\n): { app?: number; breakdown?: number } => {\n if (!APP_QUOTA_NAMES.includes(name)) {\n return {}\n }\n let appId\n try {\n appId = dbCore.getProdAppID(context.getAppId()!)\n } catch (err) {\n // ignore error for now\n }\n if (!appId || !quotaUsage.apps || !quotaUsage.apps[appId]) {\n return { app: 0 }\n }\n const appUsage = quotaUsage.apps[appId]\n switch (type) {\n case QuotaUsageType.STATIC:\n if (appUsage.usageQuota?.[name as StaticQuotaName]) {\n return { app: appUsage.usageQuota[name as StaticQuotaName] }\n }\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName = name as MonthlyQuotaName\n if (!appUsage.monthly?.[currentMonth]?.[monthlyName]) {\n break\n }\n const month = appUsage.monthly[currentMonth]\n const app = month[monthlyName]\n let breakdown\n const breakdownName = utils.getBreakdownName(monthlyName, id)\n\n if (breakdownName && id && month.breakdown?.[breakdownName]) {\n breakdown = month.breakdown[breakdownName]?.values[id]\n }\n return { app, breakdown: breakdown || 0 }\n }\n return { app: 0 }\n}\n\nconst setStaticTriggers = (\n name: StaticQuotaName,\n quotaUsage: QuotaUsage,\n triggers?: QuotaTriggers\n) => {\n // init triggers if not exists\n if (!quotaUsage.usageQuota.triggers) {\n quotaUsage.usageQuota.triggers = {}\n }\n // set triggers if supplied\n if (triggers) {\n quotaUsage.usageQuota.triggers[name] = triggers\n }\n}\n\nconst setMonthlyTriggers = (\n name: MonthlyQuotaName,\n currentMonth: string,\n quotaUsage: QuotaUsage,\n triggers?: QuotaTriggers\n) => {\n // init triggers if not exists\n if (!quotaUsage.monthly[currentMonth].triggers) {\n quotaUsage.monthly[currentMonth].triggers = {}\n }\n // set triggers if supplied\n if (triggers) {\n quotaUsage.monthly[currentMonth].triggers[name] = triggers\n }\n}\n\nconst coreUsageUpdate = (\n quotaUsage: QuotaUsage,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n values: SetUsageValues,\n opts: { id?: string; appId?: string } = {}\n) => {\n if (type === QuotaUsageType.STATIC) {\n name = name as StaticQuotaName\n quotaUsage.usageQuota[name] = values.total\n setStaticTriggers(name, quotaUsage, values.triggers)\n } else if (type === QuotaUsageType.MONTHLY) {\n name = name as MonthlyQuotaName\n const currentMonth = utils.getCurrentMonthString()\n quotaUsage.monthly[currentMonth][name] = values.total\n setMonthlyTriggers(name, currentMonth, quotaUsage, values.triggers)\n } else {\n throw new Error(`Invalid usage type: ${type}`)\n }\n return setAppUsageValue(quotaUsage, name, type, opts, values)\n}\n\nexport const setAllUsage = async (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n values: SetUsageValues,\n opts: { id?: string; appId?: string } = {}\n) => {\n const db = getDB()\n let quotaUsage = await getQuotaUsage()\n quotaUsage = coreUsageUpdate(quotaUsage, name, type, values, opts)\n const response = await db.put(quotaUsage)\n quotaUsage._rev = response.rev\n return quotaUsage\n}\n\nexport const getCurrentUsageValues = async (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n id?: string\n): Promise<UsageValues> => {\n const quotaUsage = await getQuotaUsage()\n let total = 0,\n appValues: { app?: number; breakdown?: number } = {}\n switch (type) {\n case QuotaUsageType.STATIC:\n if (quotaUsage.usageQuota[name as StaticQuotaName]) {\n const staticName = name as StaticQuotaName\n total = quotaUsage.usageQuota[staticName]\n appValues = getAppUsageValue(quotaUsage, type, name, id)\n }\n break\n case QuotaUsageType.MONTHLY:\n const currentMonth = utils.getCurrentMonthString()\n const monthlyName = name as MonthlyQuotaName\n if (quotaUsage.monthly[currentMonth][monthlyName]) {\n total = quotaUsage.monthly[currentMonth][monthlyName]\n appValues = getAppUsageValue(quotaUsage, type, name, id)\n }\n break\n default:\n throw new Error(`Invalid usage type: ${type}`)\n }\n if (\n APP_QUOTA_NAMES.includes(name) &&\n !(appValues.app || appValues.breakdown)\n ) {\n appValues.app = appValues.app || 0\n appValues.breakdown = appValues.breakdown || 0\n }\n return { total, app: appValues.app, breakdown: appValues.breakdown }\n}\n", "export * from \"./quotas\"\nexport * as utils from \"./utils\"\n", "import { SelfHostLicenseInfo } from \"../types\"\nimport { tenancy, StaticDatabases } from \"@budibase/backend-core\"\n\nconst newLicenseInfo = (licenseKey: string): SelfHostLicenseInfo => {\n return {\n _id: StaticDatabases.GLOBAL.docs.licenseInfo,\n licenseKey: licenseKey,\n }\n}\n\nconst save = async (licenseInfo: SelfHostLicenseInfo) => {\n const db = tenancy.getGlobalDB()\n const response = await db.put(licenseInfo)\n licenseInfo._rev = response.rev\n return licenseInfo\n}\n\nexport const create = async (\n licenseKey: string\n): Promise<SelfHostLicenseInfo> => {\n const licenseInfo = newLicenseInfo(licenseKey)\n return save(licenseInfo)\n}\n\nexport const get = async (): Promise<SelfHostLicenseInfo | undefined> => {\n const db = tenancy.getGlobalDB()\n try {\n // await to catch error\n return await db.get(StaticDatabases.GLOBAL.docs.licenseInfo)\n } catch (err: any) {\n if (err.status === 404) {\n return undefined\n }\n throw err\n }\n}\n\nexport const destroy = async (): Promise<{\n id?: string\n rev?: string\n} | void> => {\n const info = await get()\n if (!info) {\n // nothing to destroy\n return\n }\n const db = tenancy.getGlobalDB()\n return db.remove(StaticDatabases.GLOBAL.docs.licenseInfo, info._rev)\n}\n", "import { AuditLogDoc, SearchIndex } from \"@budibase/types\"\nimport { context, db as dbCore } from \"@budibase/backend-core\"\n\nexport async function createAuditLogSearchIndex() {\n const db = context.getAuditLogsDB()\n let designDoc\n try {\n designDoc = await db.get(\"_design/database\")\n } catch (err: any) {\n if (err.status === 404) {\n designDoc = { _id: \"_design/database\" }\n }\n }\n // this is a very specific function given that it is only for audit logs\n const fn = function (auditLog: AuditLogDoc) {\n if (auditLog._id && !auditLog._id.startsWith(\"al_\")) {\n return\n }\n const ignoredFields = [\"_id\", \"_rev\", \"metadata\"]\n let wholeString = Object.values(auditLog.metadata).join(\" \")\n for (let key of Object.keys(auditLog)) {\n if (ignoredFields.includes(key)) {\n continue\n }\n const value = auditLog[key as keyof AuditLogDoc]\n if (typeof value === \"string\") {\n //@ts-ignore\n // eslint-disable-next-line no-undef\n index(key, value.toLowerCase(), { facet: true })\n wholeString += ` ${value}`\n }\n }\n if (auditLog.fallback) {\n for (let value of Object.values(auditLog.fallback)) {\n if (value && typeof value === \"string\") {\n wholeString += ` ${value}`\n }\n }\n }\n //@ts-ignore\n // eslint-disable-next-line no-undef\n index(\"all\", wholeString)\n }\n\n designDoc.indexes = {\n [SearchIndex.AUDIT]: {\n index: fn.toString(),\n analyzer: {\n default: \"whitespace\",\n fields: {\n all: \"standard\",\n },\n name: \"perfield\",\n },\n },\n }\n await db.put(designDoc)\n}\n", "import { tenancy, db as dbCore } from \"@budibase/backend-core\"\n\nconst { ViewName, SEPARATOR, DocumentType, createView } = dbCore\n\nconst USER_PREFIX = DocumentType.USER + SEPARATOR\n\nexport enum GroupViewMode {\n SEARCH_BY_ID = \"g_\",\n SEARCH_BY_EMAIL = \"e_\",\n}\n\nexport async function createGroupUserLookupView() {\n const db = tenancy.getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${USER_PREFIX}\") && Array.isArray(doc.userGroups)) {\n for (let groupId of doc.userGroups) {\n emit(\"${GroupViewMode.SEARCH_BY_ID}\" + groupId, { email: doc.email, userId: doc._id })\n emit(\"${GroupViewMode.SEARCH_BY_EMAIL}\" + groupId + doc.email, { email: doc.email, userId: doc._id })\n }\n }\n }`\n await createView(db, viewJs, ViewName.USER_BY_GROUP)\n}\n", "export * from \"./staticViews\"\nexport * from \"./groups\"\n", "import { DatabaseQueryOpts, UserGroup } from \"@budibase/types\"\nimport {\n db as dbCore,\n users as usersCore,\n tenancy,\n utils,\n SEPARATOR,\n UNICODE_MAX,\n DocumentType,\n} from \"@budibase/backend-core\"\nimport { GroupViewMode, createGroupUserLookupView } from \"./views\"\n\nconst GROUP_PREFIX = `${DocumentType.GROUP}${SEPARATOR}`\n\ntype UserGroupsViewParams = DatabaseQueryOpts & {\n emailSearch?: string\n bookmark?: string\n}\n/**\n * Gets parameters for retrieving groups.\n */\nexport function getUserGroupsParams(\n groupId: string | null | undefined,\n otherProps = {}\n) {\n if (!groupId) {\n groupId = \"\"\n }\n const start = groupId?.startsWith(DocumentType.GROUP) ? \"\" : GROUP_PREFIX\n return {\n ...otherProps,\n startkey: `${start}${groupId}`,\n endkey: `${start}${groupId}${UNICODE_MAX}`,\n }\n}\n\n/**\n * Gets parameters for retrieving groups.\n */\nexport function getGroupUsersParams(\n groupId: string,\n otherProps: UserGroupsViewParams = {}\n): DatabaseQueryOpts {\n if (!groupId) {\n groupId = \"\"\n }\n const { emailSearch, bookmark, ...props } = otherProps\n\n if (!emailSearch) {\n return {\n ...otherProps,\n startkey: `${GroupViewMode.SEARCH_BY_ID}${groupId}`,\n endkey: `${GroupViewMode.SEARCH_BY_ID}${groupId}${UNICODE_MAX}`,\n startkey_docid: bookmark,\n }\n }\n\n const params = {\n ...props,\n startkey: `${GroupViewMode.SEARCH_BY_EMAIL}${groupId}${\n bookmark || emailSearch\n }`,\n endkey: `${GroupViewMode.SEARCH_BY_EMAIL}${groupId}${emailSearch}${UNICODE_MAX}`,\n }\n return params\n}\n\n/**\n * Generates a new user group ID\n * @returns {string} The new user group ID which info can be stored under.\n */\nexport function generateUserGroupID() {\n return `${GROUP_PREFIX}${utils.newid()}`\n}\n\nexport async function getGroupUsers(\n groupId: string,\n params?: UserGroupsViewParams\n) {\n const db = tenancy.getGlobalDB()\n\n const userDocs = (await dbCore.queryView(\n dbCore.ViewName.USER_BY_GROUP,\n getGroupUsersParams(groupId, params),\n db,\n createGroupUserLookupView,\n { arrayResponse: true }\n )) as { userId: string; email: string }[]\n\n const users =\n userDocs.map((doc: any) => ({\n _id: doc.userId,\n email: doc.email,\n })) || []\n return users\n}\n\nasync function enrichGroup(group: UserGroup) {\n group.users = await getGroupUsers(group._id!)\n return group\n}\n\nasync function cleanupUsers(group: UserGroup) {\n // get the users that need cleaned up\n const enriched = await enrichGroup(group)\n const userIds = enriched.users?.map(user => user._id) as string[]\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n const toUpdate = []\n for (let user of users) {\n if (!user.userGroups) {\n continue\n }\n const lengthBefore = user.userGroups.length\n user.userGroups = user.userGroups.filter(groupId => groupId !== group._id)\n if (user.userGroups.length !== lengthBefore) {\n toUpdate.push(user)\n }\n }\n if (toUpdate.length) {\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n }\n}\n\nexport async function fetch() {\n const db = tenancy.getGlobalDB()\n try {\n const groups = (\n await db.allDocs(\n getUserGroupsParams(null, {\n include_docs: true,\n })\n )\n ).rows.map((row: any) => row.doc)\n const enrichedGroups = []\n for (let group of groups) {\n enrichedGroups.push(enrichGroup(group))\n }\n return await Promise.all(enrichedGroups)\n } catch (err) {\n throw err\n }\n}\n\nexport async function get(groupId: string) {\n const db = tenancy.getGlobalDB()\n try {\n const group = await db.get(groupId)\n return await enrichGroup(group)\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function getBulk(\n groupIds: string[],\n opts = { enriched: true }\n): Promise<UserGroup[]> {\n const db = tenancy.getGlobalDB()\n try {\n const groups = (\n await db.allDocs({\n keys: groupIds,\n include_docs: true,\n })\n ).rows.map((row: any) => row.doc)\n if (opts?.enriched) {\n const enrichedGroups: any = []\n for (let group of groups) {\n enrichedGroups.push(enrichGroup(group))\n }\n return await Promise.all(enrichedGroups)\n } else {\n return groups\n }\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function save(\n group: UserGroup\n): Promise<{ id: string; rev: string }> {\n const db = tenancy.getGlobalDB()\n\n return await db.put(group)\n}\n\nexport async function bulkSave(\n groups: UserGroup[]\n): Promise<{ id: string; rev?: string }[]> {\n const db = tenancy.getGlobalDB()\n return await db.bulkDocs(groups)\n}\n\nexport async function destroy(\n groupId: string,\n revision: string\n): Promise<{ id: string }> {\n const db = tenancy.getGlobalDB()\n const group = await db.get(groupId)\n let resp = await db.remove(groupId, revision)\n await cleanupUsers(group)\n return resp\n}\n\nexport async function getByName(name: string) {\n try {\n const groups = await dbCore.directCouchFind(tenancy.getGlobalDBName(), {\n selector: {\n name: {\n $regex: `^(?i)${name}$`,\n },\n },\n limit: 1,\n })\n const [group] = groups.rows\n if (!group) {\n return\n }\n return await enrichGroup(group)\n } catch (err: any) {\n throw err\n }\n}\n", "export function pagination<T>(\n response: any,\n opts?: { paginate?: boolean; pageSize: number }\n): { data: T[]; hasNextPage: boolean; nextPage?: string } {\n const data = response.rows.map((row: any) => {\n return row.doc ? row.doc : row\n })\n if (!opts?.paginate) {\n return { data, hasNextPage: false }\n }\n const hasNextPage = data.length > opts?.pageSize\n return {\n data: data.slice(0, opts?.pageSize),\n hasNextPage,\n nextPage: hasNextPage ? data[opts?.pageSize]?._id : undefined,\n }\n}\n", "import { tenancy, context, db as dbCore } from \"@budibase/backend-core\"\nconst { ViewName, AutomationViewMode, SEPARATOR, DocumentType, createView } =\n dbCore\nconst LOG_PREFIX = DocumentType.AUTOMATION_LOG + SEPARATOR\nconst APP_BACKUP_PREFIX = DocumentType.APP_BACKUP + SEPARATOR\n\n/**\n * A separate view that allows us to perform queries by the automation ID and time series, while the\n * main all_docs allows access to time series only\n */\nexport async function createLogByAutomationView() {\n const db = context.getProdAppDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${LOG_PREFIX}\")) {\n let autoId = doc.automationId + \"${SEPARATOR}\"\n let status = doc.status + \"${SEPARATOR}\"\n let autoKey = \"${AutomationViewMode.AUTOMATION}${SEPARATOR}\" + autoId + doc.createdAt\n let statusKey = \"${AutomationViewMode.STATUS}${SEPARATOR}\" + status + doc.createdAt\n let allKey = \"${AutomationViewMode.ALL}${SEPARATOR}\" + status + autoId + doc.createdAt\n emit(statusKey)\n emit(autoKey)\n emit(allKey)\n }\n }`\n await createView(db, viewJs, ViewName.AUTOMATION_LOGS)\n}\n\nexport async function createAppBackupTriggerView() {\n const db = tenancy.getGlobalDB()\n const viewJs = `function(doc) {\n if (doc._id.startsWith(\"${APP_BACKUP_PREFIX}\") && doc.type && doc.trigger) {\n let full = doc.appId + \"${SEPARATOR}\"\n full += doc.trigger.toLowerCase() + \"${SEPARATOR}\"\n full += doc.type.toLowerCase() + \"${SEPARATOR}\"\n emit(\"${APP_BACKUP_PREFIX}\" + full + doc.timestamp) \n }\n }`\n await createView(db, viewJs, ViewName.APP_BACKUP_BY_TRIGGER)\n}\n", "import {\n StaticQuotaName,\n MonthlyQuotaName,\n ConstantQuotaName,\n} from \"@budibase/types\"\n\nexport const UNLIMITED = -1\n\n// Static\n\nexport const rows = (value: number) => {\n return {\n [StaticQuotaName.ROWS]: {\n name: \"Rows\",\n value,\n triggers: [90, 100],\n },\n }\n}\n\nexport const apps = (value: number) => {\n return {\n [StaticQuotaName.APPS]: {\n name: \"Apps\",\n value,\n triggers: [100],\n },\n }\n}\n\nexport const users = (value: number) => {\n return {\n [StaticQuotaName.USERS]: {\n name: \"Users\",\n value,\n triggers: [80, 100],\n },\n }\n}\n\nexport const userGroups = (value: number) => {\n return {\n [StaticQuotaName.USER_GROUPS]: {\n name: \"User Groups\",\n value,\n triggers: [80, 100],\n },\n }\n}\n\nexport const plugins = (value: number) => {\n return {\n [StaticQuotaName.PLUGINS]: {\n name: \"Plugins\",\n value,\n triggers: [90, 100],\n },\n }\n}\n\n// Monthly\n\nexport const queries = (value: number) => {\n return {\n [MonthlyQuotaName.QUERIES]: {\n name: \"Queries\",\n value,\n triggers: [],\n },\n }\n}\n\nexport const automations = (value: number) => {\n return {\n [MonthlyQuotaName.AUTOMATIONS]: {\n name: \"Automations\",\n value,\n triggers: [80, 90, 100],\n },\n }\n}\n\nexport const dayPasses = (value: number) => {\n return {\n [MonthlyQuotaName.DAY_PASSES]: {\n name: \"Day Passes\",\n value,\n triggers: [80, 90, 100],\n },\n }\n}\n\n// Constant\n\nexport const automationLogRetentionDays = (value: number) => {\n return {\n [ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: {\n name: \"Automation Logs\",\n value,\n triggers: [], // n/a\n },\n }\n}\n\nexport const appBackupRetentionDays = (value: number) => {\n return {\n [ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS]: {\n name: \"App Backups\",\n value,\n triggers: [], // n/a\n },\n }\n}\n", "import { License, PlanModel, PlanType } from \"@budibase/types\"\nimport * as quotas from \"./quotas\"\n\nexport const UNLIMITED = -1\n\n/**\n * The license used when no license is present.\n */\nexport const CLOUD_FREE_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(200),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.apps(UNLIMITED),\n ...quotas.rows(2000),\n ...quotas.users(5),\n ...quotas.userGroups(0),\n ...quotas.plugins(10),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(1),\n ...quotas.appBackupRetentionDays(0),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n\n/**\n * The license used when no license is present.\n */\nexport const SELF_FREE_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(UNLIMITED),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.rows(UNLIMITED),\n ...quotas.apps(UNLIMITED),\n ...quotas.users(UNLIMITED),\n ...quotas.userGroups(0),\n ...quotas.plugins(10),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(1),\n ...quotas.appBackupRetentionDays(0),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n\n/**\n * Unlimited license to support unit tests.\n */\nexport const UNLIMITED_LICENSE: License = {\n features: [],\n quotas: {\n usage: {\n monthly: {\n ...quotas.queries(UNLIMITED),\n ...quotas.automations(UNLIMITED),\n ...quotas.dayPasses(UNLIMITED),\n },\n static: {\n ...quotas.apps(UNLIMITED),\n ...quotas.rows(UNLIMITED),\n ...quotas.users(UNLIMITED),\n ...quotas.userGroups(UNLIMITED),\n ...quotas.plugins(UNLIMITED),\n },\n },\n constant: {\n ...quotas.automationLogRetentionDays(UNLIMITED),\n ...quotas.appBackupRetentionDays(UNLIMITED),\n },\n },\n plan: {\n type: PlanType.FREE,\n usesInvoicing: false,\n model: PlanModel.PER_USER,\n },\n}\n", "import { env, objectStore, utils } from \"@budibase/backend-core\"\n\nimport fs from \"fs\"\nimport path from \"path\"\n\n/**\n * Retrieve the version to store against a license.\n * In local dev, a random id is used instead to facilitate easy license refreshing.\n */\nexport const getLicenseVersion = () => {\n if (env.isDev()) {\n const DEV_VER_FILENAME = \"dev-version.txt\"\n const verFile = path.join(objectStore.budibaseTempDir(), DEV_VER_FILENAME)\n if (fs.existsSync(verFile)) {\n return fs.readFileSync(verFile, \"utf8\")\n } else {\n const devVer = utils.newid()\n fs.writeFileSync(verFile, devVer)\n return devVer\n }\n } else {\n return getProVersion()\n }\n}\n\nexport const getProVersion = () => {\n const version = env.VERSION\n if (!version) {\n throw new Error(\"No budibase pro version was specified\")\n }\n return version\n}\n", "export const GENERIC_PAGE_SIZE = 9\n", "export * as licenses from \"./licenses\"\nexport * as quotas from \"./quotas\"\nexport * as versions from \"./version\"\nexport * from \"./misc\"\n", "import { ConstantQuotaName, QuotaType } from \"@budibase/types\"\nimport { licensing } from \"../../sdk\"\nimport { licenses } from \"../../constants\"\n\nconst MAX_DATE = new Date(8640000000000000).toISOString()\nconst ONE_DAY_MILLIS = 1000 * 60 * 60 * 24\n\nexport async function getOldestRetentionDate(quotaName: ConstantQuotaName) {\n const license = await licensing.cache.getCachedLicense()\n const retentionDays =\n license.quotas?.[QuotaType.CONSTANT]?.[quotaName]?.value || 0\n if (retentionDays === licenses.UNLIMITED) {\n return new Date(MAX_DATE).toISOString()\n } else {\n return new Date(\n new Date().getTime() - ONE_DAY_MILLIS * retentionDays\n ).toISOString()\n }\n}\n", "import {\n db as dbCore,\n tenancy,\n users as userCore,\n} from \"@budibase/backend-core\"\nimport {\n AppBackup,\n AppBackupFetchOpts,\n AppBackupMetadata,\n AppBackupTrigger,\n AppBackupType,\n ConstantQuotaName,\n PutResponse,\n} from \"@budibase/types\"\nimport { pagination } from \"./utils/pagination\"\nimport { createAppBackupTriggerView } from \"./utils/views\"\nimport { getOldestRetentionDate } from \"./utils/retention\"\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\n\ntype FilterOpts = {\n startDate?: string\n endDate?: string\n trigger?: AppBackupTrigger\n type?: AppBackupType\n}\n\nexport async function oldestBackupDate() {\n return getOldestRetentionDate(ConstantQuotaName.APP_BACKUPS_RETENTION_DAYS)\n}\n\nconst APP_BACKUP_PREFIX = `${dbCore.DocumentType.APP_BACKUP}${dbCore.SEPARATOR}`\n\nasync function getAppBackupParams(\n appId: string,\n filters: FilterOpts,\n otherProps: any = {}\n) {\n const maxStartDate = await oldestBackupDate()\n const prodAppId = dbCore.getProdAppID(appId)\n let startKey = prodAppId,\n endKey = prodAppId\n if (filters.trigger && filters.type) {\n let basePart = `${dbCore.SEPARATOR}${filters.trigger}`\n basePart += `${dbCore.SEPARATOR}${filters.type}`\n startKey += basePart\n endKey += basePart\n }\n // check start date within limits\n if (!filters.startDate || filters.startDate < maxStartDate) {\n filters.startDate = maxStartDate\n }\n if (filters.startDate) {\n endKey += `${dbCore.SEPARATOR}${filters.startDate}`\n }\n if (filters.endDate) {\n startKey += `${dbCore.SEPARATOR}${filters.endDate}`\n }\n return {\n ...otherProps,\n descending: true,\n startkey: `${APP_BACKUP_PREFIX}${startKey}${dbCore.UNICODE_MAX}`,\n endkey: `${APP_BACKUP_PREFIX}${endKey}`,\n }\n}\n\nasync function getAppBackupsByTrigger(\n db: any,\n params: any\n): Promise<AppBackup[]> {\n let backups: AppBackup[] = []\n try {\n const queryIndex = dbCore.getQueryIndex(\n dbCore.ViewName.APP_BACKUP_BY_TRIGGER\n )\n backups = await db.query(queryIndex, params)\n } catch (err: any) {\n if (err != null && err.error === \"not_found\") {\n await createAppBackupTriggerView()\n return getAppBackupsByTrigger(db, params)\n } else {\n throw err\n }\n }\n return backups\n}\n\nexport function generateAppBackupID(appId: string, timestamp: string) {\n return `${APP_BACKUP_PREFIX}${appId}${dbCore.SEPARATOR}${timestamp}`\n}\n\nexport async function fetchAppBackups(\n appId: string,\n opts: AppBackupFetchOpts = {}\n) {\n const db = tenancy.getGlobalDB()\n let backups\n const pageSize = opts.limit || GENERIC_PAGE_SIZE\n const params = await getAppBackupParams(appId, opts, {\n include_docs: true,\n limit: pageSize + 1,\n })\n if (opts.page) {\n params.startkey = opts.page\n }\n if (!opts.trigger || !opts.type) {\n backups = await db.allDocs(params)\n } else {\n backups = await getAppBackupsByTrigger(db, params)\n }\n const pageData = pagination<AppBackup>(backups, {\n paginate: opts.paginate,\n pageSize,\n })\n // add in users\n const userIds = [\n ...new Set(\n pageData.data\n .filter(backup => backup.createdBy)\n .map(backup => backup.createdBy!)\n ),\n ] as string[]\n const users = await userCore.bulkGetGlobalUsersById(userIds, {\n cleanup: true,\n })\n for (let user of users) {\n for (let data of pageData.data) {\n if (user?._id === data.createdBy) {\n data.createdBy = user\n }\n }\n }\n return pageData\n}\n\nexport async function storeAppBackupMetadata(\n metadata: AppBackupMetadata,\n opts: { filename?: string; docId?: string; docRev?: string } = {}\n) {\n const db = tenancy.getGlobalDB()\n const prodAppId = dbCore.getProdAppID(metadata.appId)\n let _id = generateAppBackupID(prodAppId, metadata.timestamp)\n const appBackupDoc: AppBackup = {\n ...metadata,\n _id,\n appId: prodAppId,\n name: metadata.name,\n }\n if (opts.filename) {\n appBackupDoc.filename = opts.filename\n }\n if (opts.docId && opts.docRev) {\n appBackupDoc._id = opts.docId\n appBackupDoc._rev = opts.docRev\n }\n if (metadata.createdBy) {\n appBackupDoc.createdBy = dbCore.getGlobalIDFromUserMetadataID(\n metadata.createdBy as string\n )\n }\n return (await db.put(appBackupDoc)) as PutResponse\n}\n\nexport async function updateAppBackupMetadata(backupId: string, name: string) {\n const db = tenancy.getGlobalDB()\n const metadata = (await db.get(backupId)) as AppBackup\n metadata.name = name\n return (await db.put(metadata)) as PutResponse\n}\n\nexport async function deleteAppBackupMetadata(backupId: string) {\n const db = tenancy.getGlobalDB()\n const backupDoc = await db.get(backupId)\n await db.remove(backupDoc._id, backupDoc._rev)\n}\n\nexport async function getAppBackupMetadata(backupId: string) {\n const db = tenancy.getGlobalDB()\n return (await db.get(backupId)) as AppBackup\n}\n", "import {\n EnvironmentVariablesDoc,\n EnvironmentVariablesDocDecrypted,\n} from \"@budibase/types\"\nimport { tenancy, StaticDatabases, encryption } from \"@budibase/backend-core\"\nimport LRU from \"lru-cache\"\n\nconst MAX_CACHE_ITEMS = 1000\nconst cache = new LRU<string, EnvironmentVariablesDocDecrypted>({\n max: MAX_CACHE_ITEMS,\n})\n\nexport function getEnvVarID() {\n return StaticDatabases.GLOBAL.docs.environmentVariables\n}\n\nexport function getCacheEnvVarID(rev?: string) {\n const tenantId = tenancy.getTenantId()\n return `${tenantId}/${getEnvVarID()}/${rev || \"\"}`\n}\n\nexport async function get(): Promise<EnvironmentVariablesDocDecrypted> {\n const id = getEnvVarID()\n const db = tenancy.getGlobalDB()\n let encrypted: EnvironmentVariablesDoc | undefined,\n notFound = false\n try {\n encrypted = (await db.get(id)) as EnvironmentVariablesDoc\n } catch (err: any) {\n if (err.status == 404) {\n notFound = true\n } else {\n throw err\n }\n }\n // now we have the document, can check the revision, see if we have it cached\n const cacheKey = getCacheEnvVarID(encrypted?._rev)\n const cached = cache.get(cacheKey)\n if (cached) {\n return cached\n }\n // wasn't found, decrypt and return\n let finalDoc: EnvironmentVariablesDocDecrypted\n if (!notFound && encrypted) {\n finalDoc = {\n ...encrypted,\n variables: JSON.parse(\n encryption.decrypt(\n encrypted.variables,\n encryption.SecretOption.ENCRYPTION\n )\n ),\n }\n } else {\n finalDoc = {\n _id: id,\n variables: {},\n }\n }\n cache.set(cacheKey, finalDoc)\n return finalDoc\n}\n\nexport async function update(\n doc: EnvironmentVariablesDocDecrypted\n): Promise<{ id: string; rev: string }> {\n const id = getEnvVarID()\n const db = tenancy.getGlobalDB()\n return await db.put({\n _id: doc._id || id,\n _rev: doc._rev || undefined,\n variables: encryption.encrypt(\n JSON.stringify(doc.variables),\n encryption.SecretOption.ENCRYPTION\n ),\n })\n}\n", "export * as quotas from \"./quotas\"\nexport * as licenseInfo from \"./licenseInfo\"\nexport * as groups from \"./groups\"\nexport * as backups from \"./backups\"\nexport * as environmentVariables from \"./environmentVariables\"\n", "import { API } from \"../../../utilities\"\nimport {\n GetLicenseRequest,\n License,\n LicenseActivateRequest,\n QuotaTriggeredRequest,\n QuotaUsageType,\n StaticQuotaName,\n} from \"@budibase/types\"\nimport {\n constants,\n env,\n events,\n HTTPError,\n installation,\n logging,\n tenancy,\n users,\n} from \"@budibase/backend-core\"\nimport { Response } from \"node-fetch\"\nimport * as db from \"../../../db\"\nimport { versions } from \"../../../constants\"\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\nconst getResponseErrorMessage = async (\n response: Response\n): Promise<string | undefined> => {\n try {\n const json = await response.json()\n if (json.message) {\n return json.message as string\n }\n } catch (e) {\n // do nothing\n }\n\n try {\n const text = await response.text()\n if (text) {\n return text\n }\n } catch (e) {\n // do nothing\n }\n}\n\nconst authAware = async <T>(fn: (authHeader: any) => Promise<T>) => {\n // don't send the request if self-hosted and no license key\n let licenseInfo\n let authHeader\n if (env.SELF_HOSTED) {\n licenseInfo = await db.licenseInfo.get()\n if (!licenseInfo) {\n return\n }\n authHeader = {\n [constants.Header.LICENSE_KEY]: licenseInfo.licenseKey,\n }\n } else {\n const tenantId = tenancy.getTenantId()\n authHeader = {\n [constants.Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n [constants.Header.TENANT_ID]: tenantId,\n }\n }\n\n return fn(authHeader)\n}\n\nlet _getLicense = async () => {\n return authAware(async (authHeader: any): Promise<License | undefined> => {\n const quotaUsage = await db.quotas.getQuotaUsage()\n\n // make sure user count is set\n if (quotaUsage.usageQuota.users == null) {\n const userCount = await users.getUserCount()\n console.info(`Syncing user count quota to ${userCount}`)\n quotaUsage.usageQuota.users = userCount\n await db.quotas.setUsage(\n userCount,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC\n )\n }\n\n const install = await installation.getInstallFromDB()\n const tenantId = tenancy.getTenantId()\n const installTenantId = await events.identification.getUniqueTenantId(\n tenantId\n )\n const installVersion = versions.getProVersion()\n\n const body: GetLicenseRequest = {\n quotaUsage,\n install: {\n id: install.installId,\n tenantId: installTenantId,\n version: installVersion,\n },\n }\n\n const response = await api.post(`/api/license`, {\n headers: { ...authHeader },\n body,\n })\n\n if (response.status === 404 || response.status === 403) {\n // no license for the tenant\n return\n }\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n throw new HTTPError(`Error getting license: ${message}`, response.status)\n }\n\n return response.json()\n })\n}\n\n// special case for mocking this function\n// in other services - can't mock this externally\n// whenever pro is bundled into a single file\nif (env.isJest()) {\n _getLicense = jest.fn()\n}\n\nexport const getLicense = _getLicense\n\nexport const triggerQuota = (body: QuotaTriggeredRequest) => {\n return authAware(async (authHeader: any) => {\n const response = await api.post(`/api/license/usage/triggered`, {\n headers: { ...authHeader },\n body,\n })\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n logging.logAlert(`Error triggering quota usage: ${message}`)\n }\n })\n}\n\nexport const activateLicenseKey = async (\n licenseKey: string\n): Promise<License | undefined> => {\n const installVersion = versions.getProVersion()\n\n const body: LicenseActivateRequest = {\n installVersion,\n }\n\n const response = await api.post(`/api/license/activate`, {\n headers: {\n [constants.Header.LICENSE_KEY]: licenseKey,\n },\n body,\n })\n\n // don't propagate the 403 to prevent logout\n if (response.status === 403) {\n throw new HTTPError(\"Invalid license key\", 400)\n }\n\n if (response.status !== 200) {\n const message = await getResponseErrorMessage(response)\n throw new HTTPError(\n `Error activating license key: ${message}`,\n response.status\n )\n }\n\n return response.json()\n}\n", "import fs from \"fs\"\nimport { join } from \"path\"\nimport { tmpdir } from \"os\"\nimport jwt from \"jsonwebtoken\"\nimport { License } from \"@budibase/types\"\nimport { env } from \"@budibase/backend-core\"\n\nconst SUB_DIRECTORY = env.isTest() ? \".budibase-test\" : \".budibase\"\nconst DIRECTORY = join(tmpdir(), SUB_DIRECTORY)\n\nconst OFFLINE_LICENSE_FILE = \"offline_license.txt\"\nconst LICENSE_FILE_PATH = join(DIRECTORY, OFFLINE_LICENSE_FILE)\n\nif (!fs.existsSync(DIRECTORY)) {\n fs.mkdirSync(DIRECTORY)\n}\n\nconst PUBLIC_KEY =\n \"-----BEGIN PUBLIC KEY-----\\n\" +\n \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvz3jePLCFBXZ19c8Dpkv\\n\" +\n \"XtSgOhKFOcvQdo/LV0KJRUzQWDPWuO4ILtBtnqhjtIzZH4CH0qCYBet5L6Qr4CM1\\n\" +\n \"l2HXiAD1Q2rlHNW9wDaYyKb1F5f+v4RyqCAyzlkwRdksmkLeECTboojNnmRCrE3C\\n\" +\n \"8suunQP5bEScqEY2kclqzSf8e6xqMzPUg3mL/pNa1iEv7TuLbU9nJfgR36l0WmZY\\n\" +\n \"94fWnSaT8OSXSqcxsaByf06gfS3HAoTJNc7eqz1Hf9fUORQGPUAnFK8cT3SfdA36\\n\" +\n \"d/o3ZWE1TTj1zYwlCLN5qRKr3hU8nC3xEYNEbkB9SfTRaOq9Q7P8WmfLkoCPm3pR\\n\" +\n \"mwIDAQAB\\n\" +\n \"-----END PUBLIC KEY-----\\n\"\n\nexport function getOfflineLicense(): License | undefined {\n try {\n return getOfflineLicenseFromDisk()\n } catch (e) {\n console.error(\"error retrieving offline license\", e)\n }\n}\n\nfunction getOfflineLicenseFromDisk(): License | undefined {\n if (fs.existsSync(LICENSE_FILE_PATH)) {\n const token = fs.readFileSync(LICENSE_FILE_PATH, { encoding: \"utf-8\" })\n return jwt.verify(token, PUBLIC_KEY, { algorithms: [\"RS256\"] }) as License\n }\n}\n\nexport function writeOfflineLicenseToDisk(signedLicense: string) {\n fs.writeFileSync(LICENSE_FILE_PATH, signedLicense, { encoding: \"utf-8\" })\n}\n\nexport function deleteOfflineLicense() {\n fs.rmSync(LICENSE_FILE_PATH, { force: true })\n}\n", "import * as licenseClient from \"./client\"\nimport * as db from \"../../../db\"\nimport * as Cache from \"../cache\"\nimport { licenses as constants } from \"../../../constants\"\nimport { env } from \"@budibase/backend-core\"\nimport { License } from \"@budibase/types\"\nimport * as offline from \"./offline\"\n\nexport const getLicenseInfo = async () => {\n return db.licenseInfo.get()\n}\n\nexport const deleteLicenseInfo = async () => {\n await db.licenseInfo.destroy()\n await Cache.refresh()\n}\n\nexport const activateLicenseKey = async (licenseKey: string) => {\n await licenseClient.activateLicenseKey(licenseKey)\n await db.licenseInfo.create(licenseKey)\n await Cache.refresh()\n}\n\nexport const getLicense = async () => {\n // try account portal first\n let license = await licenseClient.getLicense()\n\n // try offline license if not exists - limited to dev currently\n if (!license && env.isDev()) {\n license = offline.getOfflineLicense()\n }\n return license\n}\n\nexport const getFreeLicense = (): License => {\n if (env.SELF_HOSTED) {\n return constants.SELF_FREE_LICENSE\n } else {\n return constants.CLOUD_FREE_LICENSE\n }\n}\n", "export * from \"./licenses\"\nexport * as client from \"./client\"\nexport * as offline from \"./offline\"\n", "import { GetCachedLicenseOptions, CachedLicense } from \"../../../types\"\nimport * as Redis from \"./redis\"\nimport * as Licenses from \"../licenses\"\nimport { tenancy, env } from \"@budibase/backend-core\"\nimport { versions } from \"../../../constants\"\n\nconst EXPIRY_SECONDS = 3600\n\nexport const refresh = async () => {\n await invalidate()\n await getCachedLicense()\n}\n\nlet _getCachedLicense = async (\n ctx?: any,\n opts: GetCachedLicenseOptions = { refreshVersion: true }\n): Promise<CachedLicense> => {\n const currentVersion = versions.getLicenseVersion()\n const tenantId = tenancy.getTenantId()\n\n // try cache\n const client = await Redis.getClient()\n let license: CachedLicense | undefined = await client.get(tenantId)\n\n // wipe the license to re-populate as it doesn't match pro version\n if (license && license.version !== currentVersion && opts.refreshVersion) {\n console.log(\n `Refreshing license version from=${license.version} to=${currentVersion}`\n )\n // delete so that we don't re-read the same cached\n // version from account-portal on fetch (in cloud)\n await client.delete(tenantId)\n license = undefined\n }\n\n if (!license) {\n // no license - re-populate the cache\n const populate = opts.populateLicense\n ? opts.populateLicense\n : Licenses.getLicense\n license = await populate(tenantId)\n\n // still no license - use the free license\n if (!license) {\n const populateFree = opts.populateFreeLicense\n ? opts.populateFreeLicense\n : Licenses.getFreeLicense\n license = populateFree(ctx, tenantId)\n }\n\n // store the refresh time before caching\n license!.refreshedAt = new Date().toISOString()\n // add the version to the license\n license!.version = currentVersion\n await client.store(tenantId, license, EXPIRY_SECONDS)\n }\n\n return license!\n}\n\n// special case for re-using pro mocks\n// in other services - can't mock this externally\n// whenever pro is bundled into a single file\nif (env.isJest()) {\n _getCachedLicense = jest.fn()\n}\n\nexport const getCachedLicense = _getCachedLicense\n\nexport const invalidate = async () => {\n const tenantId = tenancy.getTenantId()\n const client = await Redis.getClient()\n await client.delete(tenantId)\n}\n", "export * from \"./cache\"\n", "export * as cache from \"./cache\"\nexport * from \"./licenses\"\n", "import { Feature } from \"@budibase/types\"\nimport { FeatureDisabledError, configs, env } from \"@budibase/backend-core\"\nimport { cache } from \"../licensing\"\nimport { SettingsInnerConfig } from \"@budibase/types\"\n\n// UTILS\n\nasync function isFeatureEnabled(featureFlag: Feature) {\n const license = await cache.getCachedLicense()\n return license?.features.includes(featureFlag)\n}\n\nexport async function checkFeature(featureFlag: Feature) {\n if (!(await isFeatureEnabled(featureFlag))) {\n throw new FeatureDisabledError(\n `${featureFlag} is not currently enabled`,\n featureFlag\n )\n }\n}\n\n// BACKUPS\n\nexport function checkBackups<Args extends any[], Return>(\n targetFunction: (...parameters: Args) => Return\n): (...parameters: Args) => Promise<Return> {\n return async (...parameters: Args) => {\n await checkFeature(Feature.APP_BACKUPS)\n return targetFunction(...parameters)\n }\n}\n\nexport async function isBackupsEnabled() {\n return isFeatureEnabled(Feature.APP_BACKUPS)\n}\n\n// BRANDING\n\nexport async function isBrandingEnabled() {\n return isFeatureEnabled(Feature.BRANDING)\n}\n\n// SSO\n\nexport async function isEnforceableSSO() {\n return isFeatureEnabled(Feature.ENFORCEABLE_SSO)\n}\n\nexport async function isSSOEnforced(opts?: {\n config: SettingsInnerConfig\n}): Promise<boolean> {\n // never enforced in maintenance mode\n if (env.ENABLE_SSO_MAINTENANCE_MODE) {\n return false\n }\n\n // never enforced if the feature is not enabled\n const enforceable = await isEnforceableSSO()\n if (!enforceable) {\n return false\n }\n\n // get the enforced setting from config\n let config\n if (opts?.config) {\n config = opts.config\n } else {\n config = await configs.getSettingsConfig()\n }\n return !!config.isSSOEnforced\n}\n\nexport const checkSCIM = async (): Promise<boolean> => {\n const featureFlag = Feature.SCIM\n\n const featureEnabled = await isFeatureEnabled(featureFlag)\n const scimConfig = await configs.getSCIMConfig()\n\n if (!featureEnabled || !scimConfig?.enabled) {\n throw new FeatureDisabledError(\n `${featureFlag} is not currently enabled`,\n featureFlag\n )\n }\n\n return true\n}\n", "export * from \"./features\"\n", "import { SettingsBrandingConfig, SettingsInnerConfig } from \"@budibase/types\"\nimport * as features from \"../features\"\n\nconst DEFAULT_BRANDING_CONFIG: SettingsBrandingConfig = {\n faviconUrl: undefined,\n faviconUrlEtag: undefined,\n\n emailBrandingEnabled: true,\n testimonialsEnabled: true,\n platformTitle: undefined,\n loginHeading: undefined,\n loginButton: undefined,\n\n metaDescription: undefined,\n metaImageUrl: undefined,\n metaTitle: undefined,\n}\n\nexport async function getBrandingConfig(\n config: SettingsInnerConfig & SettingsBrandingConfig\n): Promise<SettingsBrandingConfig> {\n // when branding is disabled we always return the default\n // values no matter what is in the database\n if (!(await features.isBrandingEnabled())) {\n return DEFAULT_BRANDING_CONFIG\n } else {\n return {\n faviconUrl: config.faviconUrl,\n faviconUrlEtag: config.faviconUrlEtag,\n emailBrandingEnabled: config.emailBrandingEnabled,\n testimonialsEnabled: config.testimonialsEnabled,\n platformTitle: config.platformTitle,\n loginHeading: config.loginHeading,\n loginButton: config.loginButton,\n metaDescription: config.metaDescription,\n metaImageUrl: config.metaImageUrl,\n metaTitle: config.metaTitle,\n }\n }\n}\n", "export * from \"./branding\"\n", "import { quotas as constants } from \"../../constants\"\nimport {\n APP_QUOTA_NAMES,\n ConstantQuotaName,\n isConstantQuota,\n isMonthlyQuota,\n isStaticQuota,\n LockName,\n LockType,\n MeteredQuotaName,\n MonthlyQuotaName,\n Quota,\n QuotaTriggeredRequest,\n QuotaTriggers,\n QuotaType,\n QuotaUsage,\n QuotaUsageType,\n StaticQuotaName,\n} from \"@budibase/types\"\nimport * as licensing from \"../licensing\"\nimport * as db from \"../../db\"\nimport {\n context,\n tenancy,\n UsageLimitError,\n locks,\n logging,\n ErrorCode,\n} from \"@budibase/backend-core\"\nimport { getQuotaUsage } from \"../../db/quotas\"\n\n// INCREMENT\n\ninterface IncrementOptions {\n /**\n * The function being wrapped by this quota usage.\n */\n fn?: () => Promise<any>\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * Turn on or off error logging when a quotas has been exceeded\n */\n suppressErrorLog?: boolean\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nexport const increment = (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts?: IncrementOptions\n) => {\n return tryIncrement(1, name, type, opts)\n}\n\nexport const incrementMany = (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts?: IncrementOptions\n) => {\n return tryIncrement(change, name, type, opts)\n}\n\nconst tryIncrement = async (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: IncrementOptions = {}\n) => {\n // dry run first to check that the quota is not exceeded\n await updateUsage(change, name, type, {\n dryRun: true,\n suppressErrorLog: opts.suppressErrorLog,\n id: opts.id,\n })\n\n // run the actual function\n let result\n if (opts.fn) {\n result = await opts.fn()\n }\n\n // increment the quota\n await updateUsage(change, name, type, {\n dryRun: false,\n valueFn: opts.valueFn,\n suppressErrorLog: opts.suppressErrorLog,\n id: opts.id,\n })\n\n return result\n}\n\n// DECREMENT\n\ninterface DecrementOptions {\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nexport const decrement = (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: DecrementOptions = {}\n) => {\n return updateUsage(-1, name, type, opts)\n}\n\nexport const decrementMany = (\n change: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: DecrementOptions = {}\n) => {\n return updateUsage(-change, name, type, opts)\n}\n\nexport const set = async (\n name: MeteredQuotaName,\n type: QuotaUsageType,\n value: number\n) => {\n return db.quotas.setUsage(value, name, type)\n}\n\ninterface UpdateUsageOptions {\n /**\n * If provided and true, the usage quota will not be updated.\n * Used to verify that a quota is not exceeded before running.\n */\n dryRun?: boolean\n /**\n * If provided, the new usage value will be calculated using this function.\n */\n valueFn?: () => Promise<number>\n /**\n * Turn on or off error logging when a quotas has been exceeded\n */\n suppressErrorLog?: boolean\n /**\n * If using a specific resource which has an ID, can pass this ID for granular quotas.\n */\n id?: string\n}\n\nconst getExistingTriggers = (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n quotaUsage: QuotaUsage\n): QuotaTriggers => {\n if (type == QuotaUsageType.STATIC) {\n const triggers = quotaUsage.usageQuota.triggers\n return triggers ? triggers[name as StaticQuotaName] || {} : {}\n } else {\n const currentMonthString = db.quotas.utils.getCurrentMonthString()\n const triggers = quotaUsage.monthly[currentMonthString].triggers\n return triggers ? triggers[name as MonthlyQuotaName] || {} : {}\n }\n}\n\nconst triggerQuota = async (\n name: MeteredQuotaName,\n quota: Quota,\n percentage: number,\n resetDate?: string\n) => {\n try {\n // use a lock so that we never send the email more than once\n // under high throughput where there may be stale reads\n await locks.doWithLock(\n {\n type: LockType.TRY_ONCE,\n name: LockName.TRIGGER_QUOTA,\n resource: name, // use the quota name for extra uniqueness on the lock\n ttl: 10000, // auto expire after 10 seconds\n },\n async () => {\n const request: QuotaTriggeredRequest = {\n percentage,\n name: quota.name,\n }\n if (resetDate) {\n request.resetDate = resetDate\n }\n await licensing.client.triggerQuota(request)\n }\n )\n } catch (e: any) {\n // swallow error so we don't interrupt quota update\n logging.logAlert(\"Error triggering quota\", e)\n }\n}\n\nconst checkTriggers = async (\n type: QuotaUsageType,\n name: MeteredQuotaName,\n totalValue: number,\n quota: Quota\n): Promise<QuotaTriggers> => {\n const usage = await getQuotaUsage()\n const resetDate =\n type === QuotaUsageType.MONTHLY ? usage.quotaReset : undefined\n const triggers = await getExistingTriggers(type, name, usage)\n\n const quotaTriggers = quota.triggers\n let percentage = (totalValue / quota.value) * 100\n if (percentage > 100) {\n // sometimes quotas may overflow - set back to 100% for below logic\n percentage = 100\n }\n\n for (const [index, triggerPercentage] of quotaTriggers.entries()) {\n // set the trigger time for all triggers this update applies to\n const isTriggered =\n percentage >= triggerPercentage && quota.value !== constants.UNLIMITED\n if (isTriggered) {\n // don't overwrite the time if already set\n if (!triggers[triggerPercentage]) {\n triggers[triggerPercentage] = new Date().toISOString()\n\n // send the trigger request for the highest trigger met by this update\n const nextTriggerPercentage = quotaTriggers[index + 1] || 100\n const nextIsTriggered = percentage >= nextTriggerPercentage\n const isAtTrigger = percentage === triggerPercentage // to account for 100%\n const sendNotification = !nextIsTriggered || isAtTrigger\n\n if (sendNotification) {\n await triggerQuota(name, quota, percentage, resetDate)\n }\n }\n } else {\n triggers[triggerPercentage] = undefined\n }\n }\n\n return triggers\n}\n\nexport const updateUsage = async (\n usageChange: number,\n name: MeteredQuotaName,\n type: QuotaUsageType,\n opts: UpdateUsageOptions = {}\n) => {\n let appId = null\n try {\n appId = context.getAppId()\n } catch (err) {\n // ignore error for now\n }\n // need an app ID for these\n const isAppQuota = APP_QUOTA_NAMES.includes(name)\n if (isAppQuota && !appId) {\n throw new Error(\"App context required for quota update\")\n }\n try {\n const licensedQuota = await getLicensedQuota(QuotaType.USAGE, name, type)\n let {\n total: totalValue,\n app: appValue,\n breakdown: breakdownValue,\n } = await db.quotas.getCurrentUsageValues(type, name, opts.id)\n\n // increment / decrement the quota\n totalValue += usageChange\n if (appValue != null) {\n appValue += usageChange\n }\n if (breakdownValue != null) {\n breakdownValue += usageChange\n }\n\n let triggers: QuotaTriggers = {}\n if (!opts.dryRun) {\n triggers = await checkTriggers(type, name, totalValue, licensedQuota)\n }\n\n if (\n licensedQuota.value !== constants.UNLIMITED &&\n totalValue > licensedQuota.value &&\n usageChange > 0 // allow for decrementing usage when the quota is already exceeded\n ) {\n throw new UsageLimitError(\n `Licensed ${licensedQuota.name} of ${licensedQuota.value} has been exceeded`,\n licensedQuota.name\n )\n }\n\n // never go negative if the quota has previously been exceeded\n totalValue = Math.max(0, totalValue)\n if (appValue) {\n appValue = Math.max(0, appValue)\n }\n if (breakdownValue) {\n breakdownValue = Math.max(0, breakdownValue)\n }\n\n if (opts.dryRun) {\n // exit early\n return\n }\n\n // if a value function is provided\n // use it to calculate the new value instead of incrementing / decrementing\n if (opts.valueFn) {\n totalValue = await opts.valueFn()\n appValue = totalValue\n }\n // update the usage quotas\n await db.quotas.setAllUsage(\n name,\n type,\n {\n total: totalValue,\n app: appValue,\n breakdown: breakdownValue,\n triggers,\n },\n opts\n )\n } catch (err: any) {\n if (!opts.suppressErrorLog) {\n console.error(`Error updating usage quotas for ${name}`, err)\n }\n // re-throw any error - if the error was caused by a usage limit being exceeded\n // this will prevent the subsequent operation e.g. create app, from running\n throw err\n }\n}\n\nexport const getLicensedQuota = async (\n quotaType: QuotaType,\n name: MonthlyQuotaName | StaticQuotaName | ConstantQuotaName,\n usageType?: QuotaUsageType\n): Promise<Quota> => {\n const license = await licensing.cache.getCachedLicense()\n\n if (!license) {\n const tenantId = tenancy.getTenantId()\n throw new Error(\"License not found for tenant id \" + tenantId)\n }\n\n if (usageType && isStaticQuota(quotaType, usageType, name)) {\n return license.quotas[quotaType as QuotaType.USAGE][\n usageType as QuotaUsageType.STATIC\n ][name]\n } else if (usageType && isMonthlyQuota(quotaType, usageType, name)) {\n return license.quotas[quotaType as QuotaType.USAGE][\n usageType as QuotaUsageType.MONTHLY\n ][name]\n } else if (isConstantQuota(quotaType, name)) {\n return license.quotas[quotaType as QuotaType.CONSTANT][name]\n } else {\n throw new Error(\"Invalid quota type\")\n }\n}\n\nexport const usageLimitIsExceeded = async (\n name: MeteredQuotaName,\n type: QuotaUsageType\n) => {\n try {\n await updateUsage(1, name, type, { dryRun: true })\n return false\n } catch (e: any) {\n if (e.code === ErrorCode.USAGE_LIMIT_EXCEEDED) {\n return true\n }\n throw e\n }\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\nimport { db } from \"@budibase/backend-core\"\n\ninterface AppOpts {\n appId?: string\n}\n\n// DEV\n\nconst getDevAppsCount = async () => {\n const apps = await db.getAllApps({ dev: true })\n return apps ? apps.length : 0\n}\n\nexport const addApp = async (addAppFn: any, { appId }: AppOpts = {}) => {\n return quotas.increment(StaticQuotaName.APPS, QuotaUsageType.STATIC, {\n fn: addAppFn,\n valueFn: getDevAppsCount,\n id: appId,\n })\n}\n\nexport const removeApp = async ({ appId }: AppOpts = {}) => {\n return quotas.decrement(StaticQuotaName.APPS, QuotaUsageType.STATIC, {\n valueFn: getDevAppsCount,\n id: appId,\n })\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, MonthlyQuotaName } from \"@budibase/types\"\n\ntype QueryOpts = {\n datasourceId?: string\n}\n\nexport const addQuery = async (\n runQueryFunction: any,\n { datasourceId }: QueryOpts = {}\n) => {\n return quotas.increment(MonthlyQuotaName.QUERIES, QuotaUsageType.MONTHLY, {\n fn: runQueryFunction,\n id: datasourceId,\n })\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\ntype RowOpts = {\n tableId?: string\n}\n\nexport const addRow = async (addRowFn: any, { tableId }: RowOpts = {}) => {\n return quotas.increment(StaticQuotaName.ROWS, QuotaUsageType.STATIC, {\n fn: addRowFn,\n id: tableId,\n })\n}\n\nexport const removeRow = async ({ tableId }: RowOpts = {}) => {\n return quotas.decrement(StaticQuotaName.ROWS, QuotaUsageType.STATIC, {\n id: tableId,\n })\n}\n\nexport const addRows = async (\n change: number,\n addRowsFn?: () => Promise<any>,\n { tableId }: RowOpts = {}\n) => {\n return quotas.incrementMany(\n change,\n StaticQuotaName.ROWS,\n QuotaUsageType.STATIC,\n { fn: addRowsFn, id: tableId }\n )\n}\n\nexport const removeRows = async (change: number, { tableId }: RowOpts = {}) => {\n return quotas.decrementMany(\n change,\n StaticQuotaName.ROWS,\n QuotaUsageType.STATIC,\n { id: tableId }\n )\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, MonthlyQuotaName } from \"@budibase/types\"\n\ntype AutomationOpts = {\n automationId?: string\n}\n\nexport const addAutomation = async (\n runAutomationFn: any,\n { automationId }: AutomationOpts = {}\n) => {\n return quotas.increment(\n MonthlyQuotaName.AUTOMATIONS,\n QuotaUsageType.MONTHLY,\n { fn: runAutomationFn, id: automationId }\n )\n}\n", "import * as quotas from \"./../quotas\"\nimport {\n BBContext,\n ContextUser,\n PlanType,\n MonthlyQuotaName,\n QuotaUsageType,\n} from \"@budibase/types\"\nimport { cache, tenancy, utils, env } from \"@budibase/backend-core\"\nimport { users } from \"../../..\"\n\nconst ONE_DAY = 1000 * 60 * 60 * 24\n\nexport async function checkDayPass(ctx: BBContext) {\n const user = ctx.user\n // may be unauthenticated or an internal api endpoint with no user id\n if (!user || !user._id) {\n return\n }\n let dayPassRecordedAt\n if (user.dayPassRecordedAt) {\n dayPassRecordedAt = new Date(user.dayPassRecordedAt)\n }\n\n const nowMinus1Day = new Date(Date.now() - ONE_DAY)\n // if day pass is being used for first time in over 24 hours\n if (\n !dayPassRecordedAt ||\n dayPassRecordedAt.getTime() < nowMinus1Day.getTime()\n ) {\n try {\n await recordActivityInAccountPortal(user)\n await recordDayPassOnQuotas()\n await recordDayPassTimeOnUser(user)\n } catch (e: any) {\n // if there was a usage limit error check if we are serving an app\n // if we are - redirect to home page - not allowed to view app\n // messaging on the page will indicate the problem\n if (e.code == \"usage_limit_exceeded\") {\n if (utils.isServingApp(ctx)) {\n ctx.redirect(\"/\")\n }\n } else {\n throw e\n }\n }\n }\n}\n\n/**\n * Increment the day pass quota count.\n */\nasync function recordDayPassOnQuotas() {\n return quotas.increment(MonthlyQuotaName.DAY_PASSES, QuotaUsageType.MONTHLY, {\n suppressErrorLog: true,\n })\n}\n\n/**\n * Record the time a day pass has been used on a user.\n */\nasync function recordDayPassTimeOnUser(user: ContextUser) {\n // load the db user to avoid any staleness from redis\n const db = tenancy.getGlobalDB()\n let dbUser = await db.get(user._id)\n\n // set the recorded time on the user\n const now = new Date()\n const nowString = new Date().toISOString()\n user.dayPassRecordedAt = nowString\n dbUser.dayPassRecordedAt = nowString\n\n try {\n console.log(`Recording day pass for user=${user._id}`)\n await db.put(dbUser)\n } catch (e: any) {\n if (e.status === 409) {\n console.warn(`Conflict recording day pass for user=${user._id}`)\n // multiple requests being sent at once are prone to conflicts\n // check if the time has already been updated correctly before throwing\n dbUser = await db.get(user._id)\n if (\n !dbUser.dayPassRecordedAt ||\n new Date(dbUser.dayPassRecordedAt).getDay() !== now.getDay()\n ) {\n console.error(`Day pass not recorded for user=${user._id}`)\n throw e\n } else {\n console.log(`Day pass already recorded for user=${user._id}`)\n }\n } else {\n throw e\n }\n }\n\n // reset the user cache - next request will populate\n await cache.user.invalidateUser(user._id!)\n}\n\nasync function recordActivityInAccountPortal(user: ContextUser) {\n // self-hosted free plans don't record activity\n if (env.SELF_HOSTED && user.license?.plan?.type === PlanType.FREE) {\n return\n }\n // skip activity if account portal is disabled in dev\n if (env.isDev() && env.DISABLE_ACCOUNT_PORTAL) {\n return\n }\n await users.createActivity(user._id!)\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nexport const addGroup = async <T>(addGroupFn: () => Promise<T>): Promise<T> => {\n return quotas.increment(StaticQuotaName.USER_GROUPS, QuotaUsageType.STATIC, {\n fn: addGroupFn,\n })\n}\n\nexport const removeGroup = async () => {\n return quotas.decrement(StaticQuotaName.USER_GROUPS, QuotaUsageType.STATIC)\n}\n", "import * as quotas from \"./../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nexport const addPlugin = async (addPluginFn: any) => {\n return quotas.increment(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC, {\n fn: addPluginFn,\n })\n}\n\nexport const removePlugin = async () => {\n return quotas.decrement(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC)\n}\n\nexport const updatePluginCount = async (count: number) => {\n return quotas.set(StaticQuotaName.PLUGINS, QuotaUsageType.STATIC, count)\n}\n", "import * as quotas from \"../quotas\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\nimport { users } from \"@budibase/backend-core\"\nimport * as licenseClient from \"../../licensing/licenses/client\"\n\nexport const addUsers = async <T>(\n change: number,\n addUsersFn?: () => Promise<T>\n): Promise<T> => {\n const res = await quotas.incrementMany(\n change,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC,\n {\n fn: addUsersFn,\n valueFn: users.getUserCount,\n }\n )\n\n // send a get license request to sync the user count to the account\n await licenseClient.getLicense()\n\n return res\n}\n\nexport const removeUsers = async (change: number) => {\n await quotas.decrementMany(\n change,\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC,\n {\n valueFn: users.getUserCount,\n }\n )\n\n // send a get license request to sync the user count to the account\n await licenseClient.getLicense()\n}\n", "export * from \"./apps\"\nexport * from \"./queries\"\nexport * from \"./rows\"\nexport * from \"./automations\"\nexport * from \"./dayPasses\"\nexport * from \"./groups\"\nexport * from \"./plugins\"\nexport * from \"./users\"\n", "export * from \"../../db/quotas\"\nexport * from \"./helpers\"\nexport * from \"./quotas\"\n", "import { API } from \"../../utilities\"\nimport * as db from \"../../db\"\nimport { Options } from \"../../types\"\nimport { Response } from \"node-fetch\"\nimport {\n PostAccountUserActivity,\n PostAccountUserActivityResponse,\n} from \"@budibase/types\"\nimport {\n env,\n constants,\n featureFlags,\n tenancy,\n logging,\n} from \"@budibase/backend-core\"\n\n// TODO: Migrate license client to use this new generic API\n\nconst api = new API(env.ACCOUNT_PORTAL_URL)\n\nexport const createActivity = async (\n userId: string,\n data: PostAccountUserActivity\n): Promise<PostAccountUserActivityResponse | undefined> => {\n const response = await send(\n (options: Options) => api.post(`/api/users/${userId}/activity`, options),\n {\n body: data,\n }\n )\n\n if (!response) {\n // not enabled - return\n return\n }\n\n if (response.status !== 201) {\n const text = await response.text()\n const message = `Error creating account user activity: ${text}`\n logging.logAlert(message)\n throw new Error(message)\n }\n\n return response.json()\n}\n\nconst send = async (\n requestFn: (options: Options) => Promise<Response>,\n baseOptions: Options\n) => {\n const isLicensingEnabled = await featureFlags.isEnabled(\n featureFlags.TenantFeatureFlag.LICENSING\n )\n\n if (isLicensingEnabled) {\n const headers = await authorizationHeaders()\n const options: Options = {\n ...baseOptions,\n headers: {\n ...baseOptions.headers,\n ...headers,\n },\n }\n return requestFn(options)\n }\n}\n\nconst authorizationHeaders = async (): Promise<{ [key: string]: string }> => {\n if (env.SELF_HOSTED) {\n const licenseInfo = await db.licenseInfo.get()\n if (licenseInfo) {\n const licenseKey = licenseInfo.licenseKey\n return {\n [constants.Header.LICENSE_KEY]: licenseKey,\n }\n } else {\n return {}\n }\n } else {\n const tenantId = tenancy.getTenantId()\n return {\n [constants.Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n [constants.Header.TENANT_ID]: tenantId,\n }\n }\n}\n", "export * from \"./api\"\n", "import { PostAccountUserActivity } from \"@budibase/types\"\nimport * as api from \"../api\"\n\nexport const createActivity = async (userId: string) => {\n const data: PostAccountUserActivity = {\n timestamp: Date.now(),\n }\n\n return api.createActivity(userId, data)\n}\n", "export * from \"./users\"\n", "import { logging } from \"@budibase/backend-core\"\n\nexport function randomDelay(fn: any) {\n return new Promise((resolve, reject) => {\n setTimeout(async () => {\n try {\n resolve(await fn())\n } catch (err) {\n reject(err)\n }\n }, Math.floor(Math.random() * 1000))\n })\n}\n\nexport async function backOff(fn: any, errMsg: string) {\n let attempts = 5,\n success = false,\n response,\n first = true\n for (; attempts > 0; attempts--) {\n try {\n if (first) {\n response = await fn()\n } else {\n response = await exports.randomDelay(fn)\n }\n success = true\n break\n } catch (err) {\n // ignore error here\n }\n }\n if (!success) {\n logging.logAlert(`Failed to backoff`, errMsg)\n }\n return response\n}\n", "import {\n AppMetadataErrors,\n Automation,\n AutomationLog,\n AutomationLogPage,\n AutomationResults,\n AutomationStatus,\n ConstantQuotaName,\n} from \"@budibase/types\"\nimport { createLogByAutomationView } from \"./utils/views\"\nimport { cache, context, db as dbUtils, logging } from \"@budibase/backend-core\"\nimport { backOff } from \"../utilities/delay\"\nimport { pagination } from \"./utils/pagination\"\nimport { getOldestRetentionDate } from \"./utils/retention\"\nconst {\n SEPARATOR,\n UNICODE_MAX,\n DocumentType,\n AutomationViewMode,\n ViewName,\n getQueryIndex,\n} = dbUtils\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\n\nconst EARLIEST_DATE = new Date(0).toISOString()\n// set a maximum number that can be expired at once, control the speed of reads/writes\nconst EXPIRED_LIMIT = 100\n\nexport const oldestLogDate = async () => {\n return getOldestRetentionDate(ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS)\n}\n\nfunction getAutomationLogParams(\n startDate: string,\n endDate: string,\n { status, automationId }: { status?: string; automationId?: string } = {},\n otherProps: any = {}\n) {\n const automationBase = automationId ? `${automationId}${SEPARATOR}` : \"\"\n const statusBase = status ? `${status}${SEPARATOR}` : \"\"\n let base\n if (status && automationId) {\n base = `${AutomationViewMode.ALL}${SEPARATOR}${statusBase}${automationBase}`\n } else if (status) {\n base = `${AutomationViewMode.STATUS}${SEPARATOR}${statusBase}`\n } else if (automationId) {\n base = `${AutomationViewMode.AUTOMATION}${SEPARATOR}${automationBase}`\n } else {\n base = `${DocumentType.AUTOMATION_LOG}${SEPARATOR}`\n }\n return {\n ...otherProps,\n descending: true,\n startkey: `${base}${endDate}${UNICODE_MAX}`,\n endkey: `${base}${startDate}`,\n }\n}\n\nexport function getStatus(results: AutomationResults) {\n let status = AutomationStatus.SUCCESS\n let first = true\n for (let step of results.steps) {\n const lcStatus = step.outputs?.status?.toLowerCase()\n const stoppedError = lcStatus === \"stopped_error\"\n // skip the trigger, its always successful if automation ran\n if (first && !stoppedError) {\n first = false\n continue\n }\n if (stoppedError) {\n status = AutomationStatus.STOPPED_ERROR\n break\n } else if (!step.outputs?.success) {\n status = AutomationStatus.ERROR\n break\n } else if (lcStatus === \"stopped\") {\n status = AutomationStatus.STOPPED\n break\n }\n }\n return status\n}\n\nexport function generateAutomationLogID(\n isoDate: string,\n status: string,\n automationId: string\n) {\n return `${DocumentType.AUTOMATION_LOG}${SEPARATOR}${isoDate}${SEPARATOR}${automationId}${SEPARATOR}${status}`\n}\n\nexport async function getAllLogs(\n startDate: string,\n endDate: string,\n opts: {\n docs: boolean\n status?: string\n paginate?: boolean\n page?: string\n limit?: number\n } = { docs: true }\n): Promise<AutomationLogPage> {\n let db = context.getProdAppDB()\n if (!(await db.exists())) {\n db = context.getDevAppDB()\n }\n let optional: any = { status: opts.status }\n let limit = opts?.limit\n ? opts.limit\n : opts?.paginate\n ? GENERIC_PAGE_SIZE + 1\n : undefined\n const params = getAutomationLogParams(startDate, endDate, optional, {\n include_docs: opts.docs,\n limit,\n })\n if (opts?.page) {\n params.startkey = opts.page\n }\n let response = await db.allDocs(params)\n return pagination<AutomationLog>(response, {\n paginate: opts?.paginate,\n pageSize: GENERIC_PAGE_SIZE,\n })\n}\n\nexport async function getLogsByView(\n startDate: string,\n endDate: string,\n viewParams: { automationId?: string; status?: string; page?: string } = {}\n): Promise<AutomationLogPage> {\n let db = context.getProdAppDB()\n if (!(await db.exists())) {\n db = context.getDevAppDB()\n }\n let response\n try {\n let optional = {\n automationId: viewParams?.automationId,\n status: viewParams?.status,\n }\n const params = getAutomationLogParams(startDate, endDate, optional, {\n include_docs: true,\n limit: GENERIC_PAGE_SIZE,\n })\n if (viewParams?.page) {\n params.startkey = viewParams.page\n }\n response = await db.query(getQueryIndex(ViewName.AUTOMATION_LOGS), params)\n } catch (err: any) {\n if (\n err != null &&\n (err.name === \"not_found\" || err.error === \"not_found\")\n ) {\n await createLogByAutomationView()\n return getLogsByView(startDate, endDate, viewParams)\n } else {\n throw err\n }\n }\n return pagination<AutomationLog>(response)\n}\n\nexport async function writeLog(\n automation: Automation,\n results: AutomationResults\n) {\n const db = context.getProdAppDB()\n const automationId = automation._id as string\n const name = automation.name\n const status = getStatus(results)\n const isoDate = new Date().toISOString()\n const id = generateAutomationLogID(isoDate, status, automationId)\n const log: AutomationLog = {\n // results contain automationId and status for view\n ...results,\n automationId,\n status,\n automationName: name,\n createdAt: isoDate,\n _id: id,\n }\n await db.put(log)\n return id\n}\n\nexport async function updateAppMetadataWithErrors(\n logIds: string[],\n { clearing } = { clearing: false }\n) {\n const db = context.getProdAppDB()\n // this will try multiple times with a delay between to update the metadata\n await backOff(async () => {\n const metadata = await db.get(dbUtils.DocumentType.APP_METADATA)\n for (let logId of logIds) {\n const parts = logId.split(dbUtils.SEPARATOR)\n const autoId = `${parts[parts.length - 3]}${dbUtils.SEPARATOR}${\n parts[parts.length - 2]\n }`\n let errors: AppMetadataErrors = {}\n if (metadata.automationErrors) {\n errors = metadata.automationErrors as AppMetadataErrors\n }\n if (!Array.isArray(errors[autoId])) {\n errors[autoId] = []\n }\n const idx = errors[autoId].indexOf(logId)\n if (clearing && idx !== -1) {\n errors[autoId].splice(idx, 1)\n } else {\n errors[autoId].push(logId)\n }\n // if clearing and reach zero, this will pass and will remove the element\n if (errors[autoId].length === 0) {\n delete errors[autoId]\n }\n metadata.automationErrors = errors\n }\n await db.put(metadata)\n // don't update cache until after DB put, make sure it has been stored successfully\n await cache.app.invalidateAppMetadata(metadata.appId, metadata)\n }, \"Failed to update app metadata with automation log error\")\n}\n\nexport async function getExpiredLogs(): Promise<AutomationLogPage> {\n const expiredEnd = await oldestLogDate()\n\n try {\n return await getAllLogs(EARLIEST_DATE, expiredEnd, {\n docs: false,\n paginate: false,\n limit: EXPIRED_LIMIT,\n })\n } catch (err) {\n return { data: [], hasNextPage: false }\n }\n}\n\nexport async function clearOldHistory() {\n const db = context.getProdAppDB()\n try {\n const expired = await getExpiredLogs()\n if (!expired.data || expired.data.length === 0) {\n return\n }\n const toDelete = expired.data.map((doc: any) => ({\n _id: doc.id,\n _rev: doc.value.rev,\n _deleted: true,\n }))\n const errorLogIds = expired.data\n .filter((doc: any) => {\n const parts = doc.id.split(dbUtils.SEPARATOR)\n const status = parts[parts.length - 1]\n return status === AutomationStatus.ERROR\n })\n .map((doc: any) => doc.id)\n await db.bulkDocs(toDelete)\n if (errorLogIds.length) {\n await updateAppMetadataWithErrors(errorLogIds, { clearing: true })\n }\n } catch (err) {\n logging.logAlert(\n `Failed to cleanup automation log history - Database \"${db.name}\"`,\n err\n )\n }\n}\n", "import {\n AutomationResults,\n AutomationStatus,\n Automation,\n AutomationLogPage,\n} from \"@budibase/types\"\nimport { context, db as dbUtils } from \"@budibase/backend-core\"\nimport {\n getAllLogs,\n getLogsByView,\n oldestLogDate as _oldestLogDate,\n writeLog,\n clearOldHistory,\n updateAppMetadataWithErrors,\n getStatus,\n} from \"../../../db/automations\"\n\nexport const oldestLogDate = _oldestLogDate\n\nasync function getLogs(\n startDate: string,\n status?: string,\n automationId?: string,\n page?: string\n): Promise<AutomationLogPage> {\n let response: AutomationLogPage\n let endDate = new Date().toISOString()\n const maxStartDate = await oldestLogDate()\n // check that the start date does not exceed license\n if (!startDate || startDate < maxStartDate) {\n startDate = maxStartDate\n }\n if (automationId || status) {\n response = await getLogsByView(startDate, endDate, {\n automationId,\n status,\n page,\n })\n } else {\n response = await getAllLogs(startDate, endDate, {\n status,\n page,\n docs: true,\n paginate: true,\n })\n }\n return response\n}\n\nexport interface LogSearchOptions {\n startDate: string\n status?: AutomationStatus\n automationId?: string\n page?: string\n}\n\nexport async function logSearch(options: LogSearchOptions) {\n // before querying logs, make sure old logs are cleared out\n await clearOldHistory()\n return await getLogs(\n options.startDate,\n options.status,\n options.automationId,\n options.page\n )\n}\n\nexport async function storeLog(\n automation: Automation,\n results: AutomationResults\n) {\n // can disable this if un-needed in self-host, also only do this for prod apps\n if (!dbUtils.isProdAppID(context.getAppId())) {\n return\n }\n const status = getStatus(results)\n const id = await writeLog(automation, results)\n // need to note on the app metadata that there is an error, store what the error is\n if (status === AutomationStatus.ERROR) {\n await updateAppMetadataWithErrors([id])\n }\n // clear up old logging for app\n await clearOldHistory()\n}\n", "// called logged to avoid IDEs detecting the \"logs\" directory as ignorable\nexport * as logs from \"./logging\"\n", "import { HTTPError } from \"@budibase/backend-core\"\n\nexport class GroupNameUnavailableError extends HTTPError {\n constructor(groupName: string) {\n super(`Group name \"${groupName}\" is unavailable`, 409)\n }\n}\n", "import {\n db as dbUtils,\n events,\n roles,\n users as usersCore,\n logging,\n cache,\n} from \"@budibase/backend-core\"\nimport { UserGroup, User } from \"@budibase/types\"\nimport * as db from \"../../db\"\nimport * as quotas from \"../quotas\"\nimport { GroupNameUnavailableError } from \"../../api/errors\"\n\nasync function findHighestRole(groups: UserGroup[], appId: string) {\n try {\n let potentialRoles: any[] = []\n for (let group of groups) {\n if (group.roles) {\n potentialRoles.push(group.roles[dbUtils.getProdAppID(appId)])\n }\n }\n const allRoleNumbersArr = await Promise.all(\n potentialRoles.map(async roleId => {\n return {\n [roleId]: await roles.roleToNumber(roleId),\n }\n })\n )\n let highestGroupRole\n let originalNum = 0\n const roleNumbersMap: {\n [key: string]: { roleId: string; roleNum: number }\n } = {}\n allRoleNumbersArr.forEach(entry => {\n const [roleId, roleNum] = Object.entries(entry)[0]\n roleNumbersMap[roleId] = { roleId, roleNum }\n })\n for (let { roleId, roleNum } of Object.values(roleNumbersMap)) {\n if (roleNum > originalNum) {\n originalNum = roleNum\n highestGroupRole = roleId\n }\n }\n return highestGroupRole\n } catch (error) {\n logging.logAlert(\n `Error finding higest role for ${groups.length} on app ${appId}`,\n error\n )\n throw error\n }\n}\n\nexport async function getGroupRoleId(\n user: User,\n appId: string,\n opts?: { groups?: UserGroup[] }\n) {\n // If the user is part of a group or groups, then we want to find the highest roleId for that user\n // within the group, and overwrite the user defined role, therefore providing group based access\n // on a user / app level\n if (!user.userGroups) {\n return null\n }\n\n let groupsToAdd: UserGroup[]\n if (opts?.groups) {\n groupsToAdd = opts.groups.filter(group =>\n user.userGroups!.includes(group._id!)\n )\n } else {\n groupsToAdd = await db.groups.getBulk(user.userGroups, {\n enriched: false,\n })\n }\n\n // if the user has a role for the app already, the group doesn't override it\n const prodAppId = dbUtils.getProdAppID(appId)\n if (user.roles?.[prodAppId]) {\n return user.roles[prodAppId]\n }\n\n // reduce the groups down to where the apps exist\n groupsToAdd = groupsToAdd.filter((group: UserGroup) => {\n if (!group?.roles) {\n return false\n }\n const appIds = Object.keys(group.roles)\n return appIds.includes(prodAppId)\n })\n\n return await findHighestRole(groupsToAdd, appId)\n}\n\nexport async function enrichUserRolesFromGroups(user: User) {\n if (!user || !user.userGroups) {\n return user\n }\n const retrievedGroups = await getBulk(user.userGroups, { enriched: false })\n let allGroupAppIds: string[] = []\n for (let group of retrievedGroups) {\n if (group?.roles) {\n allGroupAppIds = allGroupAppIds.concat(Object.keys(group.roles))\n }\n }\n // get the unique app IDs\n allGroupAppIds = [...new Set(allGroupAppIds)]\n for (let appId of allGroupAppIds) {\n if (user.roles[appId]) {\n continue\n }\n const role = await findHighestRole(retrievedGroups, appId)\n if (role) {\n user.roles[appId] = role\n }\n }\n return user\n}\n\nexport async function fetch() {\n return await db.groups.fetch()\n}\n\nexport async function get(id: string) {\n return (await db.groups.get(id)) as UserGroup\n}\n\nexport async function getBulk(ids: string[], opts = { enriched: true }) {\n return (await db.groups.getBulk(ids, opts)) as UserGroup[]\n}\n\nasync function guardNameAvailility(name: string) {\n const existingGroup = await db.groups.getByName(name)\n if (existingGroup) {\n throw new GroupNameUnavailableError(name)\n }\n}\n\nexport async function save(group: UserGroup) {\n let eventPromises = []\n // Config does not exist yet\n let isCreate = !group._id\n // make sure to clear out group users - these are enriched, should not be stored\n delete group.users\n\n db.groups.getUserGroupsParams\n if (!group._id) {\n group._id = db.groups.generateUserGroupID()\n await guardNameAvailility(group.name)\n eventPromises.push(events.group.created(group))\n } else {\n const oldGroup: UserGroup = await db.groups.get(group._id)\n if (oldGroup.name !== group.name) {\n await guardNameAvailility(group.name)\n }\n eventPromises.push(events.group.updated(group))\n if (JSON.stringify(oldGroup.roles) !== JSON.stringify(group.roles)) {\n eventPromises.push(events.group.permissionsEdited(group))\n }\n }\n\n try {\n await Promise.all(eventPromises)\n const saveGroup = () => {\n return db.groups.save(group)\n }\n if (isCreate) {\n return await quotas.addGroup(saveGroup)\n } else {\n return await saveGroup()\n }\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function remove(groupId: string, revision: string) {\n let group\n try {\n group = await db.groups.get(groupId)\n } catch (err) {\n throw new Error(\"Group not found\")\n }\n try {\n let resp = await db.groups.destroy(groupId, revision)\n await events.group.deleted(group)\n await quotas.removeGroup()\n return resp as any\n } catch (err: any) {\n throw err\n }\n}\n\nexport async function addUsers(groupId: string, userIds: string[]) {\n const group = await db.groups.get(groupId)\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n let toUpdate: User[] = []\n for (let user of users) {\n if (!user.userGroups) {\n user.userGroups = []\n }\n if (!user.userGroups.includes(groupId)) {\n user.userGroups.push(groupId)\n toUpdate.push(user)\n }\n }\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n\n let promises = []\n for (let userId of userIds) {\n promises.push(cache.user.invalidateUser(userId))\n }\n await Promise.all(promises)\n\n if (toUpdate.length) {\n await events.group.usersAdded(toUpdate.length, group)\n }\n return toUpdate\n}\n\nexport async function removeUsers(groupId: string, userIds: string[]) {\n const group = await db.groups.get(groupId)\n const users = await usersCore.bulkGetGlobalUsersById(userIds)\n let toUpdate: User[] = []\n for (let user of users) {\n if (!user.userGroups || !user.userGroups.includes(groupId)) {\n continue\n }\n const idx = user.userGroups.indexOf(groupId)\n user.userGroups.splice(idx, 1)\n toUpdate.push(user)\n }\n await usersCore.bulkUpdateGlobalUsers(toUpdate)\n\n let promises = []\n for (let userId of userIds) {\n promises.push(cache.user.invalidateUser(userId))\n }\n await Promise.all(promises)\n\n if (toUpdate.length) {\n await events.group.usersDeleted(toUpdate.length, group)\n }\n return toUpdate\n}\n\nexport async function updateGroupApps(\n groupId: string,\n opts: {\n appsToRemove?: { appId: string }[]\n appsToAdd?: { appId: string; roleId: string }[]\n }\n) {\n const group = await get(groupId)\n if (!group.roles) {\n group.roles = {}\n }\n if (opts.appsToAdd) {\n for (let add of opts.appsToAdd) {\n group.roles[add.appId] = add.roleId\n }\n }\n if (opts.appsToRemove) {\n for (let remove of opts.appsToRemove) {\n delete group.roles[remove.appId]\n }\n }\n return await save(group)\n}\n\nexport async function cleanupApp(appId: string) {\n const groupList = await fetch()\n const toUpdate = []\n for (let group of groupList) {\n if (!group.roles || !group.roles[appId]) {\n continue\n }\n delete group.roles[appId]\n toUpdate.push(group)\n }\n return await db.groups.bulkSave(toUpdate)\n}\n", "export * from \"./groups\"\n", "import fs from \"fs\"\nimport { join } from \"path\"\n\nexport function loadJSFile(directory: string, name: string) {\n return fs.readFileSync(join(directory, name), \"utf8\")\n}\n", "import { Plugin, PluginSource, PluginType } from \"@budibase/types\"\nimport { events } from \"@budibase/backend-core\"\nimport {\n objectStore,\n db as dbCore,\n tenancy,\n logging,\n} from \"@budibase/backend-core\"\nimport { loadJSFile } from \"../../utilities/fileSystem\"\nimport * as quotas from \"../quotas\"\n\nexport async function storePlugin(\n metadata: any,\n directory: any,\n source?: PluginSource\n) {\n const db = tenancy.getGlobalDB()\n const version = metadata.package.version,\n name = metadata.package.name,\n description = metadata.package.description,\n hash = metadata.schema.hash\n\n // first open the tarball into tmp directory\n const bucketPath = objectStore.getPluginS3Dir(name)\n const files = await objectStore.uploadDirectory(\n objectStore.ObjectStoreBuckets.PLUGINS,\n directory,\n bucketPath\n )\n const jsFile = files.find((file: any) => file.name.endsWith(\".js\"))\n const iconFile = files.find((file: any) => file.name.endsWith(\".svg\"))\n if (!jsFile) {\n throw new Error(`Plugin missing .js file.`)\n }\n // validate the JS for a datasource\n if (metadata.schema.type === PluginType.DATASOURCE) {\n const js = loadJSFile(directory, jsFile.name)\n try {\n // down the line we might need a better way to confirm JS file\n ;(0, eval)(js)\n } catch (err: any) {\n const message = err?.message ? err.message : JSON.stringify(err)\n throw new Error(`JS invalid: ${message}`)\n }\n }\n const iconFileName = iconFile ? iconFile.name : null\n const pluginId = dbCore.generatePluginID(name)\n\n // overwrite existing docs entirely if they exist\n let rev\n try {\n const existing = await db.get(pluginId)\n rev = existing._rev\n } catch (err) {\n rev = undefined\n }\n let doc: Plugin = {\n _id: pluginId,\n _rev: rev,\n ...metadata,\n name,\n version,\n hash,\n description,\n }\n if (iconFileName) {\n doc.iconFileName = iconFileName\n }\n\n if (source) {\n doc = {\n ...doc,\n source,\n }\n }\n\n const write = async () => {\n const response = await db.put(doc)\n await events.plugin.imported(doc)\n return {\n ...doc,\n _rev: response.rev,\n }\n }\n // it doesn't exist, update the quota\n if (!rev) {\n return await quotas.addPlugin(write)\n } else {\n return await write()\n }\n}\n\nexport async function deletePlugin(pluginId: string) {\n const db = tenancy.getGlobalDB()\n try {\n const plugin: Plugin = await db.get(pluginId)\n const bucketPath = objectStore.getPluginS3Dir(plugin.name)\n await objectStore.deleteFolder(\n objectStore.ObjectStoreBuckets.PLUGINS,\n bucketPath\n )\n\n await db.remove(pluginId, plugin._rev!)\n await events.plugin.deleted(plugin)\n await quotas.removePlugin()\n } catch (err: any) {\n const errMsg = err?.message ? err?.message : err\n throw new Error(`Failed to delete plugin: ${errMsg}`)\n }\n}\n\nexport async function checkPluginQuotas() {\n const db = tenancy.getGlobalDB()\n try {\n const allPlugins = await db.allDocs(dbCore.getPluginParams())\n const pluginCount = allPlugins.rows.length\n console.log(`Syncing plugin count: ${pluginCount}`)\n await quotas.updatePluginCount(pluginCount)\n } catch (err) {\n logging.logAlert(\"Unable to retrieve plugins for quota check\", err)\n }\n}\n", "import {\n AppEnvironment,\n EnvironmentVariableValue,\n Feature,\n} from \"@budibase/types\"\nimport { env } from \"@budibase/backend-core\"\nimport { environmentVariables } from \"../../db\"\nimport { licensing } from \"../../sdk\"\n\ntype VariableMap = { [key: string]: EnvironmentVariableValue }\n\nexport function isEncryptionKeyAvailable() {\n return !!env.ENCRYPTION_KEY\n}\n\nexport async function fetch(): Promise<string[]> {\n const doc = await environmentVariables.get()\n return Object.keys(doc.variables)\n}\n\nexport async function fetchValues(environment: AppEnvironment) {\n const doc = await environmentVariables.get()\n const decrypted = doc.variables\n\n const output: { [key: string]: string } = {}\n for (let [key, value] of Object.entries(decrypted)) {\n switch (environment) {\n case AppEnvironment.DEVELOPMENT:\n output[key] = value.development\n break\n case AppEnvironment.PRODUCTION:\n default:\n output[key] = value.production\n break\n }\n }\n return output\n}\n\nasync function changeValues(cb: (values: VariableMap) => VariableMap) {\n // only block access when updating values, let users fetch\n const license = await licensing.cache.getCachedLicense()\n if (!license.features.includes(Feature.ENVIRONMENT_VARIABLES)) {\n throw new Error(\n \"User does not have access to environment variables feature.\"\n )\n }\n const doc = await environmentVariables.get()\n doc.variables = cb(doc.variables)\n await environmentVariables.update(doc)\n}\n\nexport async function update(varName: string, value: EnvironmentVariableValue) {\n const checkName = isValid(varName)\n if (checkName) {\n await changeValues(values => {\n values[varName] = value\n return values\n })\n } else {\n throw new Error(\"Variable name has characters that are not allowed\")\n }\n}\n\nexport async function remove(varName: string) {\n await changeValues(values => {\n delete values[varName]\n return values\n })\n}\n\nexport function isValid(str: string) {\n return /^[a-zA-Z0-9-_]+$/.test(str)\n}\n", "export * from \"./environmentVariables\"\n", "import {\n DocumentType,\n SEPARATOR,\n utils,\n context,\n db as dbCore,\n logging,\n} from \"@budibase/backend-core\"\nimport {\n AuditLogDoc,\n SearchFilters,\n AuditLogSearchParams,\n SortOrder,\n SortType,\n SearchIndex,\n} from \"@budibase/types\"\nimport { createAuditLogSearchIndex } from \"./views\"\nimport { GENERIC_PAGE_SIZE } from \"../constants\"\nimport { Readable } from \"stream\"\nconst MemoryStream = require(\"memorystream\")\n\nfunction generateAuditLogID(timestamp: string) {\n return `${\n DocumentType.AUDIT_LOG\n }${SEPARATOR}${timestamp}${SEPARATOR}${utils.newid()}`\n}\n\nexport async function save(doc: AuditLogDoc) {\n if (!doc._id) {\n doc._id = generateAuditLogID(doc.timestamp)\n }\n try {\n const db = context.getAuditLogsDB()\n const response = await db.put(doc)\n return {\n ...doc,\n _rev: response.rev,\n }\n } catch (err: any) {\n logging.logAlert(\"Failed to write audit log\", err)\n }\n}\n\nexport async function search(search: SearchFilters, bookmark?: string) {\n const dbName = context.getAuditLogDBName()\n return await dbCore.paginatedSearch<AuditLogDoc>(\n dbName,\n SearchIndex.AUDIT,\n search,\n {\n disableEscaping: true,\n indexer: createAuditLogSearchIndex,\n limit: GENERIC_PAGE_SIZE,\n bookmark: bookmark,\n sort: \"timestamp\",\n sortOrder: SortOrder.DESCENDING,\n sortType: SortType.STRING,\n }\n )\n}\n\nexport function dump(params: AuditLogSearchParams): {\n promise: Promise<void>\n stream: Readable\n} {\n const db = context.getAuditLogsDB()\n const stream = new MemoryStream()\n // dump the database, re-creating what the lucene filter looks for\n const promise = db.dump(stream, {\n filter: doc => {\n const auditLog = doc as AuditLogDoc\n if (!auditLog._id?.startsWith(DocumentType.AUDIT_LOG)) {\n return false\n }\n // do this as an AND like operation\n let allMatched = true\n const matcher = (\n param: string[] | undefined,\n value: string | undefined\n ) => {\n if (!param || param.length === 0) {\n return\n }\n allMatched = !!(allMatched && value && param.includes(value))\n }\n matcher(params.userIds, auditLog.userId)\n matcher(params.appIds, auditLog.appId)\n matcher(params.events, auditLog.event)\n // they should have both been filled if one was filled\n if (params.startDate || params.endDate) {\n allMatched =\n allMatched &&\n auditLog.timestamp >= params.startDate! &&\n auditLog.timestamp <= params.endDate!\n }\n // this can't be quite the same as the whitespace search, but good enough\n if (params.fullSearch) {\n const json = JSON.stringify(doc)\n allMatched = allMatched && json.includes(params.fullSearch)\n }\n return allMatched\n },\n })\n const returnStream = new MemoryStream()\n // need to run the original stream through a transform to get to the newline\n // delimited JSON structure required\n stream.on(\"data\", (data: any) => {\n const json = JSON.parse(Buffer.from(data).toString())\n if (Array.isArray(json.docs)) {\n let str = \"\"\n for (let doc of json.docs) {\n str += JSON.stringify(doc) + \"\\n\"\n }\n returnStream.write(str)\n }\n })\n stream.on(\"end\", () => {\n returnStream.end()\n })\n return { promise, stream: returnStream }\n}\n", "class Helper {\n constructor(name, fn, useValueFallback = true) {\n this.name = name\n this.fn = fn\n this.useValueFallback = useValueFallback\n }\n\n register(handlebars) {\n // wrap the function so that no helper can cause handlebars to break\n handlebars.registerHelper(this.name, (value, info) => {\n let context = {}\n if (info && info.data && info.data.root) {\n context = info.data.root\n }\n const result = this.fn(value, context)\n if (result == null) {\n return this.useValueFallback ? value : null\n } else {\n return result\n }\n })\n }\n\n unregister(handlebars) {\n handlebars.unregisterHelper(this.name)\n }\n}\n\nmodule.exports = Helper\n", "const dayjs = require(\"dayjs\")\ndayjs.extend(require(\"dayjs/plugin/duration\"))\ndayjs.extend(require(\"dayjs/plugin/advancedFormat\"))\ndayjs.extend(require(\"dayjs/plugin/isoWeek\"))\ndayjs.extend(require(\"dayjs/plugin/weekYear\"))\ndayjs.extend(require(\"dayjs/plugin/weekOfYear\"))\ndayjs.extend(require(\"dayjs/plugin/relativeTime\"))\ndayjs.extend(require(\"dayjs/plugin/utc\"))\ndayjs.extend(require(\"dayjs/plugin/timezone\"))\n\n/**\n * This file was largely taken from the helper-date package - we did this for two reasons:\n * 1. It made use of both moment of date.js - this caused some weird bugs with some relatively simple\n * syntax and didn't offer much in return.\n * 2. Replacing moment with dayjs helps massively reduce bundle size.\n * The original package can be found here:\n * https://github.com/helpers/helper-date\n */\n\nfunction isOptions(val) {\n return typeof val === \"object\" && typeof val.hash === \"object\"\n}\n\nfunction isApp(thisArg) {\n return (\n typeof thisArg === \"object\" &&\n typeof thisArg.options === \"object\" &&\n typeof thisArg.app === \"object\"\n )\n}\n\nfunction getContext(thisArg, locals, options) {\n if (isOptions(thisArg)) {\n return getContext({}, locals, thisArg)\n }\n // ensure args are in the correct order\n if (isOptions(locals)) {\n return getContext(thisArg, options, locals)\n }\n const appContext = isApp(thisArg) ? thisArg.context : {}\n options = options || {}\n\n // if \"options\" is not handlebars options, merge it onto locals\n if (!isOptions(options)) {\n locals = Object.assign({}, locals, options)\n }\n // merge handlebars root data onto locals if specified on the hash\n if (isOptions(options) && options.hash.root === true) {\n locals = Object.assign({}, options.data.root, locals)\n }\n let context = Object.assign({}, appContext, locals, options.hash)\n if (!isApp(thisArg)) {\n context = Object.assign({}, thisArg, context)\n }\n if (isApp(thisArg) && thisArg.view && thisArg.view.data) {\n context = Object.assign({}, context, thisArg.view.data)\n }\n return context\n}\n\nfunction initialConfig(str, pattern, options) {\n if (isOptions(pattern)) {\n options = pattern\n pattern = null\n }\n\n if (isOptions(str)) {\n options = str\n pattern = null\n str = null\n }\n return { str, pattern, options }\n}\n\nfunction setLocale(str, pattern, options) {\n // if options is null then it'll get updated here\n const config = initialConfig(str, pattern, options)\n const defaults = { lang: \"en\", date: new Date(config.str) }\n // for now don't allow this to be configurable, don't pass in options\n const opts = getContext(this, defaults, {})\n\n // set the language to use\n dayjs.locale(opts.lang || opts.language)\n}\n\nmodule.exports.date = (str, pattern, options) => {\n const config = initialConfig(str, pattern, options)\n\n // if no args are passed, return a formatted date\n if (config.str == null && config.pattern == null) {\n dayjs.locale(\"en\")\n return dayjs().format(\"MMMM DD, YYYY\")\n }\n\n setLocale(config.str, config.pattern, config.options)\n\n let date = dayjs(new Date(config.str))\n if (typeof config.options === \"string\") {\n date =\n config.options.toLowerCase() === \"utc\"\n ? date.utc()\n : date.tz(config.options)\n } else {\n date = date.tz(dayjs.tz.guess())\n }\n if (config.pattern === \"\") {\n return date.toISOString()\n }\n return date.format(config.pattern)\n}\n\nmodule.exports.duration = (str, pattern, format) => {\n const config = initialConfig(str, pattern)\n\n setLocale(config.str, config.pattern)\n\n const duration = dayjs.duration(config.str, config.pattern)\n if (!isOptions(format)) {\n return duration.format(format)\n } else {\n return duration.humanize()\n }\n}\n", "module.exports.HelperFunctionBuiltin = [\n \"#if\",\n \"#unless\",\n \"#each\",\n \"#with\",\n \"lookup\",\n \"log\",\n \"blockHelperMissing\",\n \"each\",\n \"helperMissing\",\n \"if\",\n \"unless\",\n \"log\",\n \"lookup\",\n \"with\",\n]\n\nmodule.exports.HelperFunctionNames = {\n OBJECT: \"object\",\n ALL: \"all\",\n LITERAL: \"literal\",\n JS: \"js\",\n}\n\nmodule.exports.LITERAL_MARKER = \"%LITERAL%\"\n", "const helpers = require(\"@budibase/handlebars-helpers\")\nconst { date, duration } = require(\"./date\")\nconst { HelperFunctionBuiltin } = require(\"./constants\")\n\n/**\n * full list of supported helpers can be found here:\n * https://github.com/Budibase/handlebars-helpers\n */\n\nconst EXTERNAL_FUNCTION_COLLECTIONS = [\n \"math\",\n \"array\",\n \"number\",\n \"url\",\n \"string\",\n \"comparison\",\n \"object\",\n \"regex\",\n]\n\nconst ADDED_HELPERS = {\n date: date,\n duration: duration,\n}\n\nexports.externalCollections = EXTERNAL_FUNCTION_COLLECTIONS\nexports.addedHelpers = ADDED_HELPERS\n\nexports.registerAll = handlebars => {\n for (let [name, helper] of Object.entries(ADDED_HELPERS)) {\n handlebars.registerHelper(name, helper)\n }\n let externalNames = []\n for (let collection of EXTERNAL_FUNCTION_COLLECTIONS) {\n // collect information about helper\n let hbsHelperInfo = helpers[collection]()\n for (let entry of Object.entries(hbsHelperInfo)) {\n const name = entry[0]\n // skip built in functions and ones seen already\n if (\n HelperFunctionBuiltin.indexOf(name) !== -1 ||\n externalNames.indexOf(name) !== -1\n ) {\n continue\n }\n externalNames.push(name)\n }\n // attach it to our handlebars instance\n helpers[collection]({\n handlebars,\n })\n }\n // add date external functionality\n exports.externalHelperNames = externalNames.concat(Object.keys(ADDED_HELPERS))\n}\n\nexports.unregisterAll = handlebars => {\n for (let name of Object.keys(ADDED_HELPERS)) {\n handlebars.unregisterHelper(name)\n }\n for (let name of module.exports.externalHelperNames) {\n handlebars.unregisterHelper(name)\n }\n exports.externalHelperNames = []\n}\n\nexports.externalHelperNames = []\n", "const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g\n\nmodule.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g\nmodule.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g\nmodule.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g\n\n// originally this could be done with a single regex using look behinds\n// but safari does not support this feature\n// original regex: /(?<!{){{[^{}]+}}(?!})/g\nmodule.exports.findDoubleHbsInstances = string => {\n let copied = string\n const doubleRegex = new RegExp(exports.FIND_HBS_REGEX)\n const regex = new RegExp(exports.FIND_TRIPLE_HBS_REGEX)\n const tripleMatches = copied.match(regex)\n // remove triple braces\n if (tripleMatches) {\n tripleMatches.forEach(match => {\n copied = copied.replace(match, \"\")\n })\n }\n const doubleMatches = copied.match(doubleRegex)\n return doubleMatches ? doubleMatches : []\n}\n\nmodule.exports.isAlphaNumeric = char => {\n return char.match(ALPHA_NUMERIC_REGEX)\n}\n\nmodule.exports.swapStrings = (string, start, length, swap) => {\n return string.slice(0, start) + swap + string.slice(start + length)\n}\n\nmodule.exports.removeHandlebarsStatements = (\n string,\n replacement = \"Invalid binding\"\n) => {\n let regexp = new RegExp(exports.FIND_HBS_REGEX)\n let matches = string.match(regexp)\n if (matches == null) {\n return string\n }\n for (let match of matches) {\n const idx = string.indexOf(match)\n string = exports.swapStrings(string, idx, match.length, replacement)\n }\n return string\n}\n\nmodule.exports.btoa = plainText => {\n return Buffer.from(plainText, \"utf-8\").toString(\"base64\")\n}\n\nmodule.exports.atob = base64 => {\n return Buffer.from(base64, \"base64\").toString(\"utf-8\")\n}\n", "const externalHandlebars = require(\"./external\")\nconst helperList = require(\"@budibase/handlebars-helpers\")\n\nmodule.exports.getHelperList = () => {\n let constructed = []\n for (let collection of externalHandlebars.externalCollections) {\n constructed.push(helperList[collection]())\n }\n const fullMap = {}\n for (let collection of constructed) {\n for (let [key, func] of Object.entries(collection)) {\n fullMap[key] = func\n }\n }\n for (let key of Object.keys(externalHandlebars.addedHelpers)) {\n fullMap[key] = externalHandlebars.addedHelpers[key]\n }\n return fullMap\n}\n", "const { atob } = require(\"../utilities\")\nconst { cloneDeep } = require(\"lodash/fp\")\nconst { LITERAL_MARKER } = require(\"../helpers/constants\")\nconst { getHelperList } = require(\"./list\")\n\n// The method of executing JS scripts depends on the bundle being built.\n// This setter is used in the entrypoint (either index.cjs or index.mjs).\nlet runJS\nmodule.exports.setJSRunner = runner => (runJS = runner)\n\n// Helper utility to strip square brackets from a value\nconst removeSquareBrackets = value => {\n if (!value || typeof value !== \"string\") {\n return value\n }\n const regex = /\\[+(.+)]+/\n const matches = value.match(regex)\n if (matches && matches[1]) {\n return matches[1]\n }\n return value\n}\n\n// Our context getter function provided to JS code as $.\n// Extracts a value from context.\nconst getContextValue = (path, context) => {\n let data = context\n path.split(\".\").forEach(key => {\n if (data == null || typeof data !== \"object\") {\n return null\n }\n data = data[removeSquareBrackets(key)]\n })\n return data\n}\n\n// Evaluates JS code against a certain context\nmodule.exports.processJS = (handlebars, context) => {\n if (process && process.env.NO_JS) {\n throw new Error(\"JS disabled in environment.\")\n }\n try {\n // Wrap JS in a function and immediately invoke it.\n // This is required to allow the final `return` statement to be valid.\n const js = `function run(){${atob(handlebars)}};run();`\n\n // Our $ context function gets a value from context.\n // We clone the context to avoid mutation in the binding affecting real\n // app context.\n const sandboxContext = {\n $: path => getContextValue(path, cloneDeep(context)),\n helpers: getHelperList(),\n }\n\n // Create a sandbox with our context and run the JS\n const res = { data: runJS(js, sandboxContext) }\n return `{{${LITERAL_MARKER} js_result-${JSON.stringify(res)}}}`\n } catch (error) {\n return \"Error while executing JS\"\n }\n}\n", "const Helper = require(\"./Helper\")\nconst { SafeString } = require(\"handlebars\")\nconst externalHandlebars = require(\"./external\")\nconst { processJS } = require(\"./javascript\")\nconst {\n HelperFunctionNames,\n HelperFunctionBuiltin,\n LITERAL_MARKER,\n} = require(\"./constants\")\nconst { getHelperList } = require(\"./list\")\n\nconst HTML_SWAPS = {\n \"<\": \"<\",\n \">\": \">\",\n}\n\nfunction isObject(value) {\n if (value == null || typeof value !== \"object\") {\n return false\n }\n return (\n value.toString() === \"[object Object]\" ||\n (value.length > 0 && typeof value[0] === \"object\")\n )\n}\n\nconst HELPERS = [\n // external helpers\n new Helper(HelperFunctionNames.OBJECT, value => {\n return new SafeString(JSON.stringify(value))\n }),\n // javascript helper\n new Helper(HelperFunctionNames.JS, processJS, false),\n // this help is applied to all statements\n new Helper(HelperFunctionNames.ALL, (value, inputs) => {\n const { __opts } = inputs\n if (isObject(value)) {\n return new SafeString(JSON.stringify(value))\n }\n // null/undefined values produce bad results\n if (__opts && __opts.onlyFound && value == null) {\n return __opts.input\n }\n if (value == null || typeof value !== \"string\") {\n return value == null ? \"\" : value\n }\n if (value && value.string) {\n value = value.string\n }\n let text = value\n if (__opts && __opts.escapeNewlines) {\n text = value.replace(/\\n/g, \"\\\\n\")\n }\n text = new SafeString(text.replace(/&/g, \"&\"))\n if (text == null || typeof text !== \"string\") {\n return text\n }\n return text.replace(/[<>]/g, tag => {\n return HTML_SWAPS[tag] || tag\n })\n }),\n // adds a note for post-processor\n new Helper(HelperFunctionNames.LITERAL, value => {\n if (value === undefined) {\n return \"\"\n }\n const type = typeof value\n const outputVal = type === \"object\" ? JSON.stringify(value) : value\n return `{{${LITERAL_MARKER} ${type}-${outputVal}}}`\n }),\n]\n\nmodule.exports.HelperNames = () => {\n return Object.values(HelperFunctionNames).concat(\n HelperFunctionBuiltin,\n externalHandlebars.externalHelperNames\n )\n}\n\nmodule.exports.registerMinimum = handlebars => {\n for (let helper of HELPERS) {\n helper.register(handlebars)\n }\n}\n\nmodule.exports.registerAll = handlebars => {\n module.exports.registerMinimum(handlebars)\n // register imported helpers\n externalHandlebars.registerAll(handlebars)\n}\n\nmodule.exports.unregisterAll = handlebars => {\n for (let helper of HELPERS) {\n helper.unregister(handlebars)\n }\n // unregister all imported helpers\n externalHandlebars.unregisterAll(handlebars)\n}\n\nmodule.exports.getHelperList = getHelperList\n", "const { HelperNames } = require(\"../helpers\")\nconst { swapStrings, isAlphaNumeric } = require(\"../utilities\")\n\nconst FUNCTION_CASES = [\"#\", \"else\", \"/\"]\n\nconst PreprocessorNames = {\n SWAP_TO_DOT: \"swap-to-dot-notation\",\n FIX_FUNCTIONS: \"fix-functions\",\n FINALISE: \"finalise\",\n}\n\n/* eslint-disable no-unused-vars */\nclass Preprocessor {\n constructor(name, fn) {\n this.name = name\n this.fn = fn\n }\n\n process(fullString, statement, opts) {\n const output = this.fn(statement, opts)\n const idx = fullString.indexOf(statement)\n return swapStrings(fullString, idx, statement.length, output)\n }\n}\n\nmodule.exports.processors = [\n new Preprocessor(PreprocessorNames.SWAP_TO_DOT, statement => {\n let startBraceIdx = statement.indexOf(\"[\")\n let lastIdx = 0\n while (startBraceIdx !== -1) {\n // if the character previous to the literal specifier is alphanumeric this should happen\n if (isAlphaNumeric(statement.charAt(startBraceIdx - 1))) {\n statement = swapStrings(statement, startBraceIdx + lastIdx, 1, \".[\")\n }\n lastIdx = startBraceIdx + 1\n const nextBraceIdx = statement.substring(lastIdx + 1).indexOf(\"[\")\n startBraceIdx = nextBraceIdx > 0 ? lastIdx + 1 + nextBraceIdx : -1\n }\n return statement\n }),\n\n new Preprocessor(PreprocessorNames.FIX_FUNCTIONS, statement => {\n for (let specialCase of FUNCTION_CASES) {\n const toFind = `{ ${specialCase}`,\n replacement = `{${specialCase}`\n statement = statement.replace(new RegExp(toFind, \"g\"), replacement)\n }\n return statement\n }),\n\n new Preprocessor(PreprocessorNames.FINALISE, (statement, opts) => {\n const noHelpers = opts && opts.noHelpers\n let insideStatement = statement.slice(2, statement.length - 2)\n if (insideStatement.charAt(0) === \" \") {\n insideStatement = insideStatement.slice(1)\n }\n if (insideStatement.charAt(insideStatement.length - 1) === \" \") {\n insideStatement = insideStatement.slice(0, insideStatement.length - 1)\n }\n const possibleHelper = insideStatement.split(\" \")[0]\n // function helpers can't be wrapped\n for (let specialCase of FUNCTION_CASES) {\n if (possibleHelper.includes(specialCase)) {\n return statement\n }\n }\n const testHelper = possibleHelper.trim().toLowerCase()\n if (\n !noHelpers &&\n HelperNames().some(option => testHelper === option.toLowerCase())\n ) {\n insideStatement = `(${insideStatement})`\n }\n return `{{ all ${insideStatement} }}`\n }),\n]\n\nmodule.exports.PreprocessorNames = PreprocessorNames\n", "const { LITERAL_MARKER } = require(\"../helpers/constants\")\n\nconst PostProcessorNames = {\n CONVERT_LITERALS: \"convert-literals\",\n}\n\n/* eslint-disable no-unused-vars */\nclass Postprocessor {\n constructor(name, fn) {\n this.name = name\n this.fn = fn\n }\n\n process(statement) {\n return this.fn(statement)\n }\n}\n\nmodule.exports.PostProcessorNames = PostProcessorNames\n\nmodule.exports.processors = [\n new Postprocessor(PostProcessorNames.CONVERT_LITERALS, statement => {\n if (typeof statement !== \"string\" || !statement.includes(LITERAL_MARKER)) {\n return statement\n }\n const splitMarkerIndex = statement.indexOf(\"-\")\n const type = statement.substring(12, splitMarkerIndex)\n const value = statement.substring(\n splitMarkerIndex + 1,\n statement.length - 2\n )\n switch (type) {\n case \"string\":\n return value\n case \"number\":\n return parseFloat(value)\n case \"boolean\":\n return value === \"true\"\n case \"object\":\n return JSON.parse(value)\n case \"js_result\":\n // We use the literal helper to process the result of JS expressions\n // as we want to be able to return any types.\n // We wrap the value in an abject to be able to use undefined properly.\n return JSON.parse(value).data\n }\n return value\n }),\n]\n", "const { FIND_HBS_REGEX } = require(\"../utilities\")\nconst preprocessor = require(\"./preprocessor\")\nconst postprocessor = require(\"./postprocessor\")\n\nfunction process(output, processors, opts) {\n for (let processor of processors) {\n // if a literal statement has occurred stop\n if (typeof output !== \"string\") {\n break\n }\n // re-run search each time incase previous processor updated/removed a match\n let regexp = new RegExp(FIND_HBS_REGEX)\n let matches = output.match(regexp)\n if (matches == null) {\n continue\n }\n for (let match of matches) {\n output = processor.process(output, match, opts)\n }\n }\n return output\n}\n\nmodule.exports.preprocess = (string, opts) => {\n let processors = preprocessor.processors\n if (opts.noFinalise) {\n processors = processors.filter(\n processor => processor.name !== preprocessor.PreprocessorNames.FINALISE\n )\n }\n return process(string, processors, opts)\n}\nmodule.exports.postprocess = string => {\n let processors = postprocessor.processors\n return process(string, processors)\n}\n", "{\n \"math\": {\n \"abs\": {\n \"args\": [\n \"a\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ abs 12012.1000 }} -> 12012.1\",\n \"description\": \"<p>Return the magnitude of <code>a</code>.</p>\\n\"\n },\n \"add\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ add 1 2 }} -> 3\",\n \"description\": \"<p>Return the sum of <code>a</code> plus <code>b</code>.</p>\\n\"\n },\n \"avg\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ avg 1 2 3 4 5 }} -> 3\",\n \"description\": \"<p>Returns the average of all numbers in the given array.</p>\\n\"\n },\n \"ceil\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ ceil 1.2 }} -> 2\",\n \"description\": \"<p>Get the <code>Math.ceil()</code> of the given value.</p>\\n\"\n },\n \"divide\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ divide 10 5 }} -> 2\",\n \"description\": \"<p>Divide <code>a</code> by <code>b</code></p>\\n\"\n },\n \"floor\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ floor 1.2 }} -> 1\",\n \"description\": \"<p>Get the <code>Math.floor()</code> of the given value.</p>\\n\"\n },\n \"minus\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ subtract 10 5 }} -> 5\",\n \"description\": \"<p>Return the product of <code>a</code> minus <code>b</code>.</p>\\n\"\n },\n \"modulo\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ modulo 10 5 }} -> 0\",\n \"description\": \"<p>Get the remainder of a division operation.</p>\\n\"\n },\n \"multiply\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ multiply 10 5 }} -> 50\",\n \"description\": \"<p>Return the product of <code>a</code> times <code>b</code>.</p>\\n\"\n },\n \"plus\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ plus 10 5 }} -> 15\",\n \"description\": \"<p>Add <code>a</code> by <code>b</code>.</p>\\n\"\n },\n \"random\": {\n \"args\": [\n \"min\",\n \"max\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ random 0 20 }} -> 10\",\n \"description\": \"<p>Generate a random number between two values</p>\\n\"\n },\n \"remainder\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ remainder 10 6 }} -> 4\",\n \"description\": \"<p>Get the remainder when <code>a</code> is divided by <code>b</code>.</p>\\n\"\n },\n \"round\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ round 10.3 }} -> 10\",\n \"description\": \"<p>Round the given number.</p>\\n\"\n },\n \"subtract\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ subtract 10 5 }} -> 5\",\n \"description\": \"<p>Return the product of <code>a</code> minus <code>b</code>.</p>\\n\"\n },\n \"sum\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ sum [1, 2, 3] }} -> 6\",\n \"description\": \"<p>Returns the sum of all numbers in the given array.</p>\\n\"\n },\n \"times\": {\n \"args\": [\n \"a\",\n \"b\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ times 10 5 }} -> 50\",\n \"description\": \"<p>Multiply number <code>a</code> by number <code>b</code>.</p>\\n\"\n }\n },\n \"array\": {\n \"after\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ after [1, 2, 3] 1}} -> [3]\",\n \"description\": \"<p>Returns all of the items in an array after the specified index. Opposite of <a href=\\\"#before\\\">before</a>.</p>\\n\"\n },\n \"arrayify\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ arrayify 'foo' }} -> ['foo']\",\n \"description\": \"<p>Cast the given <code>value</code> to an array.</p>\\n\"\n },\n \"before\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ before [1, 2, 3] 2}} -> [1, 2]\",\n \"description\": \"<p>Return all of the items in the collection before the specified count. Opposite of <a href=\\\"#after\\\">after</a>.</p>\\n\"\n },\n \"eachIndex\": {\n \"args\": [\n \"array\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#eachIndex [1, 2, 3]}} {{item}} is {{index}} {{/eachIndex}}\",\n \"description\": \"<p>Iterates the array, listing an item and the index of it.</p>\\n\"\n },\n \"filter\": {\n \"args\": [\n \"array\",\n \"value\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#filter [1, 2, 3] 2}}2 Found{{else}}2 not found{{/filter}}\",\n \"description\": \"<p>Block helper that filters the given array and renders the block for values that evaluate to <code>true</code>, otherwise the inverse block is returned.</p>\\n\"\n },\n \"first\": {\n \"args\": [\n \"array\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{first [1, 2, 3, 4] 2}} -> [1, 2]\",\n \"description\": \"<p>Returns the first item, or first <code>n</code> items of an array.</p>\\n\"\n },\n \"forEach\": {\n \"args\": [\n \"array\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{#forEach [{ 'name': 'John' }] }} {{ name }} {{/forEach}}\",\n \"description\": \"<p>Iterates over each item in an array and exposes the current item in the array as context to the inner block. In addition to the current array item, the helper exposes the following variables to the inner block: - <code>index</code> - <code>total</code> - <code>isFirst</code> - <code>isLast</code> Also, <code>@index</code> is exposed as a private variable, and additional private variables may be defined as hash arguments.</p>\\n\"\n },\n \"inArray\": {\n \"args\": [\n \"array\",\n \"value\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#inArray [1, 2, 3] 2}} 2 exists {{else}} 2 does not exist {{/inArray}} -> 2 exists\",\n \"description\": \"<p>Block helper that renders the block if an array has the given <code>value</code>. Optionally specify an inverse block to render when the array does not have the given value.</p>\\n\"\n },\n \"isArray\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{isArray [1, 2]}} -> true\",\n \"description\": \"<p>Returns true if <code>value</code> is an es5 array.</p>\\n\"\n },\n \"itemAt\": {\n \"args\": [\n \"array\",\n \"idx\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{itemAt [1, 2, 3] 1}} -> 2\",\n \"description\": \"<p>Returns the item from <code>array</code> at index <code>idx</code>.</p>\\n\"\n },\n \"join\": {\n \"args\": [\n \"array\",\n \"separator\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{join [1, 2, 3]}} -> '1, 2, 3'\",\n \"description\": \"<p>Join all elements of array into a string, optionally using a given separator.</p>\\n\"\n },\n \"equalsLength\": {\n \"args\": [\n \"value\",\n \"length\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{equalsLength '[1,2,3]' 3}} -> true\",\n \"description\": \"<p>Returns true if the the length of the given <code>value</code> is equal to the given <code>length</code>. Can be used as a block or inline helper.</p>\\n\"\n },\n \"last\": {\n \"args\": [\n \"value\",\n \"n\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{last [1, 2, 3]}} -> 3\",\n \"description\": \"<p>Returns the last item, or last <code>n</code> items of an array or string. Opposite of <a href=\\\"#first\\\">first</a>.</p>\\n\"\n },\n \"length\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{length '[1, 2, 3]'}} -> 3\",\n \"description\": \"<p>Returns the length of the given string or array.</p>\\n\"\n },\n \"lengthEqual\": {\n \"args\": [\n \"value\",\n \"length\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{equalsLength '[1,2,3]' 3}} -> true\",\n \"description\": \"<p>Returns true if the the length of the given <code>value</code> is equal to the given <code>length</code>. Can be used as a block or inline helper.</p>\\n\"\n },\n \"map\": {\n \"args\": [\n \"array\",\n \"fn\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{map [1, 2, 3] double}} -> [2, 4, 6]\",\n \"description\": \"<p>Returns a new array, created by calling <code>function</code> on each element of the given <code>array</code>. For example,</p>\\n\"\n },\n \"pluck\": {\n \"args\": [\n \"collection\",\n \"prop\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{pluck [{ 'name': 'Bob' }] 'name' }} -> ['Bob']\",\n \"description\": \"<p>Map over the given object or array or objects and create an array of values from the given <code>prop</code>. Dot-notation may be used (as a string) to get nested properties.</p>\\n\"\n },\n \"reverse\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{reverse [1, 2, 3]}} -> [3, 2, 1]\",\n \"description\": \"<p>Reverse the elements in an array, or the characters in a string.</p>\\n\"\n },\n \"some\": {\n \"args\": [\n \"array\",\n \"iter\",\n \"provided\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#some [1, 'b', 3] isString}} string found {{else}} No string found {{/some}} -> string found\",\n \"description\": \"<p>Block helper that returns the block if the callback returns true for some value in the given array.</p>\\n\"\n },\n \"sort\": {\n \"args\": [\n \"array\",\n \"key\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ sort ['b', 'a', 'c'] }} -> ['a', 'b', 'c']\",\n \"description\": \"<p>Sort the given <code>array</code>. If an array of objects is passed, you may optionally pass a <code>key</code> to sort on as the second argument. You may alternatively pass a sorting function as the second argument.</p>\\n\"\n },\n \"sortBy\": {\n \"args\": [\n \"array\",\n \"props\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ sortBy [{a: 'zzz'}, {a: 'aaa'}] 'a' }} -> [{'a':'aaa'}, {'a':'zzz'}]\",\n \"description\": \"<p>Sort an <code>array</code>. If an array of objects is passed, you may optionally pass a <code>key</code> to sort on as the second argument. You may alternatively pass a sorting function as the second argument.</p>\\n\"\n },\n \"withAfter\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withAfter [1, 2, 3] 1 }} {{this}} {{/withAfter}}\",\n \"description\": \"<p>Use the items in the array <em>after</em> the specified index as context inside a block. Opposite of <a href=\\\"#withBefore\\\">withBefore</a>.</p>\\n\"\n },\n \"withBefore\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withBefore [1, 2, 3] 2 }} {{this}} {{/withBefore}}\",\n \"description\": \"<p>Use the items in the array <em>before</em> the specified index as context inside a block. Opposite of <a href=\\\"#withAfter\\\">withAfter</a>.</p>\\n\"\n },\n \"withFirst\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{ withFirst [1, 2, 3] }} {{this}} {{/withFirst}}\",\n \"description\": \"<p>Use the first item in a collection inside a handlebars block expression. Opposite of <a href=\\\"#withLast\\\">withLast</a>.</p>\\n\"\n },\n \"withGroup\": {\n \"args\": [\n \"array\",\n \"size\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withGroup [1, 2, 3, 4] 2}} {{#each this}} {{.}} {{each}} <br> {{/withGroup}} -> 1,2<br> 3,4<br>\",\n \"description\": \"<p>Block helper that groups array elements by given group <code>size</code>.</p>\\n\"\n },\n \"withLast\": {\n \"args\": [\n \"array\",\n \"idx\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withLast [1, 2, 3, 4]}} {{this}} {{/withLast}} -> 4\",\n \"description\": \"<p>Use the last item or <code>n</code> items in an array as context inside a block. Opposite of <a href=\\\"#withFirst\\\">withFirst</a>.</p>\\n\"\n },\n \"withSort\": {\n \"args\": [\n \"array\",\n \"prop\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#withSort ['b', 'a', 'c']}} {{this}} {{/withSort}} -> abc\",\n \"description\": \"<p>Block helper that sorts a collection and exposes the sorted collection as context inside the block.</p>\\n\"\n },\n \"unique\": {\n \"args\": [\n \"array\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#each (unique ['a', 'a', 'c', 'b', 'e', 'e']) }} {{.}} {{/each}} -> acbe\",\n \"description\": \"<p>Block helper that return an array with all duplicate values removed. Best used along with a <a href=\\\"#each\\\">each</a> helper.</p>\\n\"\n }\n },\n \"number\": {\n \"bytes\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ bytes 1386 }} -> 1.4Kb\",\n \"description\": \"<p>Format a number to it's equivalent in bytes. If a string is passed, it's length will be formatted and returned. <strong>Examples:</strong> - <code>'foo' => 3 B</code> - <code>13661855 => 13.66 MB</code> - <code>825399 => 825.39 kB</code> - <code>1396 => 1.4 kB</code></p>\\n\"\n },\n \"addCommas\": {\n \"args\": [\n \"num\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ addCommas 1000000 }} -> 1,000,000\",\n \"description\": \"<p>Add commas to numbers</p>\\n\"\n },\n \"phoneNumber\": {\n \"args\": [\n \"num\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ phoneNumber 8005551212 }} -> (800) 555-1212\",\n \"description\": \"<p>Convert a string or number to a formatted phone number.</p>\\n\"\n },\n \"toAbbr\": {\n \"args\": [\n \"number\",\n \"precision\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toAbbr 10123 2 }} -> 10.12k\",\n \"description\": \"<p>Abbreviate numbers to the given number of <code>precision</code>. This for general numbers, not size in bytes.</p>\\n\"\n },\n \"toExponential\": {\n \"args\": [\n \"number\",\n \"fractionDigits\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toExponential 10123 2 }} -> 101e+4\",\n \"description\": \"<p>Returns a string representing the given number in exponential notation.</p>\\n\"\n },\n \"toFixed\": {\n \"args\": [\n \"number\",\n \"digits\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ toFixed 1.1234 2 }} -> 1.12\",\n \"description\": \"<p>Formats the given number using fixed-point notation.</p>\\n\"\n },\n \"toFloat\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Convert input to a float.</p>\\n\"\n },\n \"toInt\": {\n \"args\": [\n \"number\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Convert input to an integer.</p>\\n\"\n },\n \"toPrecision\": {\n \"args\": [\n \"number\",\n \"precision\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{toPrecision '1.1234' 2}}\",\n \"description\": \"<p>Returns a string representing the <code>Number</code> object to the specified precision.</p>\\n\"\n }\n },\n \"url\": {\n \"encodeURI\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ encodeURI 'https://myurl?Hello There' }} -> https://myurl?Hello%20There\",\n \"description\": \"<p>Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.</p>\\n\"\n },\n \"escape\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ escape 'https://myurl?Hello+There' }} -> https://myurl?Hello%20There\",\n \"description\": \"<p>Escape the given string by replacing characters with escape sequences. Useful for allowing the string to be used in a URL, etc.</p>\\n\"\n },\n \"decodeURI\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ escape 'https://myurl?Hello%20There' }} -> https://myurl?Hello+There\",\n \"description\": \"<p>Decode a Uniform Resource Identifier (URI) component.</p>\\n\"\n },\n \"url_encode\": {\n \"args\": [],\n \"numArgs\": 0,\n \"description\": \"<p>Alias for <a href=\\\"#encodeuri\\\">encodeURI</a>.</p>\\n\"\n },\n \"url_decode\": {\n \"args\": [],\n \"numArgs\": 0,\n \"description\": \"<p>Alias for <a href=\\\"#decodeuri\\\">decodeURI</a>.</p>\\n\"\n },\n \"urlResolve\": {\n \"args\": [\n \"base\",\n \"href\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ urlResolve 'https://myurl' '/api/test' }} -> https://myurl/api/test\",\n \"description\": \"<p>Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag.</p>\\n\"\n },\n \"urlParse\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ urlParse 'https://myurl/api/test' }}\",\n \"description\": \"<p>Parses a <code>url</code> string into an object.</p>\\n\"\n },\n \"stripQuerystring\": {\n \"args\": [\n \"url\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ stripQueryString 'https://myurl/api/test?foo=bar' }} -> 'https://myurl/api/test'\",\n \"description\": \"<p>Strip the query string from the given <code>url</code>.</p>\\n\"\n },\n \"stripProtocol\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ stripProtocol 'https://myurl/api/test' }} -> 'myurl/api/test'\",\n \"description\": \"<p>Strip protocol from a <code>url</code>. Useful for displaying media that may have an 'http' protocol on secure connections.</p>\\n\"\n }\n },\n \"string\": {\n \"append\": {\n \"args\": [\n \"str\",\n \"suffix\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{append 'index' '.html'}} -> index.html\",\n \"description\": \"<p>Append the specified <code>suffix</code> to the given string.</p>\\n\"\n },\n \"camelcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{camelcase 'foo bar baz'}} -> fooBarBaz\",\n \"description\": \"<p>camelCase the characters in the given <code>string</code>.</p>\\n\"\n },\n \"capitalize\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{capitalize 'foo bar baz'}} -> Foo bar baz\",\n \"description\": \"<p>Capitalize the first word in a sentence.</p>\\n\"\n },\n \"capitalizeAll\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ capitalizeAll 'foo bar baz'}} -> Foo Bar Baz\",\n \"description\": \"<p>Capitalize all words in a string.</p>\\n\"\n },\n \"center\": {\n \"args\": [\n \"str\",\n \"spaces\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ center 'test' 1}} -> ' test '\",\n \"description\": \"<p>Center a string using non-breaking spaces</p>\\n\"\n },\n \"chop\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{ chop ' ABC '}} -> 'ABC'\",\n \"description\": \"<p>Like trim, but removes both extraneous whitespace <strong>and non-word characters</strong> from the beginning and end of a string.</p>\\n\"\n },\n \"dashcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{dashcase 'a-b-c d_e'}} -> a-b-c-d-e\",\n \"description\": \"<p>dash-case the characters in <code>string</code>. Replaces non-word characters and periods with hyphens.</p>\\n\"\n },\n \"dotcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{dotcase 'a-b-c d_e'}} -> a.b.c.d.e\",\n \"description\": \"<p>dot.case the characters in <code>string</code>.</p>\\n\"\n },\n \"downcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{downcase 'aBcDeF'}} -> abcdef\",\n \"description\": \"<p>Lowercase all of the characters in the given string. Alias for <a href=\\\"#lowercase\\\">lowercase</a>.</p>\\n\"\n },\n \"ellipsis\": {\n \"args\": [\n \"str\",\n \"length\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{ellipsis 'foo bar baz' 7}} -> foo bar\u2026\",\n \"description\": \"<p>Truncates a string to the specified <code>length</code>, and appends it with an elipsis, <code>\u2026</code>.</p>\\n\"\n },\n \"hyphenate\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{hyphenate 'foo bar baz qux'}} -> foo-bar-baz-qux\",\n \"description\": \"<p>Replace spaces in a string with hyphens.</p>\\n\"\n },\n \"isString\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{isString 'foo'}} -> true\",\n \"description\": \"<p>Return true if <code>value</code> is a string.</p>\\n\"\n },\n \"lowercase\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{lowercase 'Foo BAR baZ'}} -> foo bar baz\",\n \"description\": \"<p>Lowercase all characters in the given string.</p>\\n\"\n },\n \"occurrences\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{occurrences 'foo bar foo bar baz' 'foo'}} -> 2\",\n \"description\": \"<p>Return the number of occurrences of <code>substring</code> within the given <code>string</code>.</p>\\n\"\n },\n \"pascalcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{pascalcase 'foo bar baz'}} -> FooBarBaz\",\n \"description\": \"<p>PascalCase the characters in <code>string</code>.</p>\\n\"\n },\n \"pathcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{pathcase 'a-b-c d_e'}} -> a/b/c/d/e\",\n \"description\": \"<p>path/case the characters in <code>string</code>.</p>\\n\"\n },\n \"plusify\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{plusify 'foo bar baz'}} -> foo+bar+baz\",\n \"description\": \"<p>Replace spaces in the given string with pluses.</p>\\n\"\n },\n \"prepend\": {\n \"args\": [\n \"str\",\n \"prefix\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{prepend 'bar' 'foo-'}} -> foo-bar\",\n \"description\": \"<p>Prepends the given <code>string</code> with the specified <code>prefix</code>.</p>\\n\"\n },\n \"raw\": {\n \"args\": [\n \"options\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{{{#raw}}}} {{foo}} {{{{/raw}}}} -> {{foo}}\",\n \"description\": \"<p>Render a block without processing mustache templates inside the block.</p>\\n\"\n },\n \"remove\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{remove 'a b a b a b' 'a '}} -> b b b\",\n \"description\": \"<p>Remove all occurrences of <code>substring</code> from the given <code>str</code>.</p>\\n\"\n },\n \"removeFirst\": {\n \"args\": [\n \"str\",\n \"substring\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{remove 'a b a b a b' 'a'}} -> b a b a b\",\n \"description\": \"<p>Remove the first occurrence of <code>substring</code> from the given <code>str</code>.</p>\\n\"\n },\n \"replace\": {\n \"args\": [\n \"str\",\n \"a\",\n \"b\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{replace 'a b a b a b' 'a' 'z'}} -> z b z b z b\",\n \"description\": \"<p>Replace all occurrences of substring <code>a</code> with substring <code>b</code>.</p>\\n\"\n },\n \"replaceFirst\": {\n \"args\": [\n \"str\",\n \"a\",\n \"b\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{replace 'a b a b a b' 'a' 'z'}} -> z b a b a b\",\n \"description\": \"<p>Replace the first occurrence of substring <code>a</code> with substring <code>b</code>.</p>\\n\"\n },\n \"sentence\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{sentence 'hello world. goodbye world.'}} -> Hello world. Goodbye world.\",\n \"description\": \"<p>Sentence case the given string</p>\\n\"\n },\n \"snakecase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{snakecase 'a-b-c d_e'}} -> a_b_c_d_e\",\n \"description\": \"<p>snake_case the characters in the given <code>string</code>.</p>\\n\"\n },\n \"split\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{split 'a,b,c'}} -> ['a', 'b', 'c']\",\n \"description\": \"<p>Split <code>string</code> by the given <code>character</code>.</p>\\n\"\n },\n \"startsWith\": {\n \"args\": [\n \"prefix\",\n \"testString\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#startsWith 'Goodbye' 'Hello, world!'}} Yep {{else}} Nope {{/startsWith}} -> Nope\",\n \"description\": \"<p>Tests whether a string begins with the given prefix.</p>\\n\"\n },\n \"titleize\": {\n \"args\": [\n \"str\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{#titleize 'this is title case' }} -> This Is Title Case\",\n \"description\": \"<p>Title case the given string.</p>\\n\"\n },\n \"trim\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trim ' ABC ' }} -> ABC\",\n \"description\": \"<p>Removes extraneous whitespace from the beginning and end of a string.</p>\\n\"\n },\n \"trimLeft\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trimLeft ' ABC ' }} -> 'ABC '\",\n \"description\": \"<p>Removes extraneous whitespace from the beginning of a string.</p>\\n\"\n },\n \"trimRight\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{trimRight ' ABC ' }} -> ' ABC '\",\n \"description\": \"<p>Removes extraneous whitespace from the end of a string.</p>\\n\"\n },\n \"truncate\": {\n \"args\": [\n \"str\",\n \"limit\",\n \"suffix\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{truncate 'foo bar baz' 7 }} -> foo bar\",\n \"description\": \"<p>Truncate a string to the specified <code>length</code>. Also see <a href=\\\"#ellipsis\\\">ellipsis</a>.</p>\\n\"\n },\n \"truncateWords\": {\n \"args\": [\n \"str\",\n \"limit\",\n \"suffix\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{truncateWords 'foo bar baz' 1 }} -> foo\",\n \"description\": \"<p>Truncate a string to have the specified number of words. Also see <a href=\\\"#truncate\\\">truncate</a>.</p>\\n\"\n },\n \"upcase\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"example\": \"{{upcase 'aBcDef'}} -> ABCDEF\",\n \"description\": \"<p>Uppercase all of the characters in the given string. Alias for <a href=\\\"#uppercase\\\">uppercase</a>.</p>\\n\"\n },\n \"uppercase\": {\n \"args\": [\n \"str\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{uppercase 'aBcDef'}} -> ABCDEF\",\n \"description\": \"<p>Uppercase all of the characters in the given string. If used as a block helper it will uppercase the entire block. This helper does not support inverse blocks.</p>\\n\"\n }\n },\n \"comparison\": {\n \"and\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#and great magnificent}}both{{else}}no{{/and}}\",\n \"description\": \"<p>Helper that renders the block if <strong>both</strong> of the given values are truthy. If an inverse block is specified it will be rendered when falsy. Works as a block helper, inline helper or subexpression.</p>\\n\"\n },\n \"compare\": {\n \"args\": [\n \"a\",\n \"operator\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 4,\n \"example\": \"{{compare 10 '<' 5 }} -> true\",\n \"description\": \"<p>Render a block when a comparison of the first and third arguments returns true. The second argument is the [arithemetic operator][operators] to use. You may also optionally specify an inverse block to render when falsy.</p>\\n\"\n },\n \"contains\": {\n \"args\": [\n \"collection\",\n \"value\",\n \"[startIndex=0]\",\n \"options\"\n ],\n \"numArgs\": 4,\n \"example\": \"{{#contains ['a', 'b', 'c'] 'd'}} This will not be rendered. {{else}} This will be rendered. {{/contains}}\",\n \"description\": \"<p>Block helper that renders the block if <code>collection</code> has the given <code>value</code>, using strict equality (<code>===</code>) for comparison, otherwise the inverse block is rendered (if specified). If a <code>startIndex</code> is specified and is negative, it is used as the offset from the end of the collection.</p>\\n\"\n },\n \"default\": {\n \"args\": [\n \"value\",\n \"defaultValue\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{default null null 'default'}} -> default\",\n \"description\": \"<p>Returns the first value that is not undefined, otherwise the 'default' value is returned.</p>\\n\"\n },\n \"eq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#eq 3 3}} equal{{else}} not equal{{/eq}} -> equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=''</code> hash argument for the second value.</p>\\n\"\n },\n \"gt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#gt 4 3}} greater than{{else}} not greater than{{/gt}} -> greater than\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>greater than</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=''</code> hash argument for the second value.</p>\\n\"\n },\n \"gte\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#gte 4 3}} greater than or equal{{else}} not greater than{{/gte}} -> greater than or equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>greater than or equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=''</code> hash argument for the second value.</p>\\n\"\n },\n \"has\": {\n \"args\": [\n \"val\",\n \"pattern\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#has 'foobar' 'foo'}} has it{{else}} doesn't{{/has}} -> has it\",\n \"description\": \"<p>Block helper that renders a block if <code>value</code> has <code>pattern</code>. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"isFalsey\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{isFalsey '' }} -> true\",\n \"description\": \"<p>Returns true if the given <code>value</code> is falsey. Uses the [falsey][] library for comparisons. Please see that library for more information or to report bugs with this helper.</p>\\n\"\n },\n \"isTruthy\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{isTruthy '12' }} -> true\",\n \"description\": \"<p>Returns true if the given <code>value</code> is truthy. Uses the [falsey][] library for comparisons. Please see that library for more information or to report bugs with this helper.</p>\\n\"\n },\n \"ifEven\": {\n \"args\": [\n \"number\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#ifEven 2}} even {{else}} odd {{/ifEven}} -> even\",\n \"description\": \"<p>Return true if the given value is an even number.</p>\\n\"\n },\n \"ifNth\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#ifNth 10 2}} remainder {{else}} no remainder {{/ifNth}} -> remainder\",\n \"description\": \"<p>Conditionally renders a block if the remainder is zero when <code>a</code> operand is divided by <code>b</code>. If an inverse block is specified it will be rendered when the remainder is <strong>not zero</strong>.</p>\\n\"\n },\n \"ifOdd\": {\n \"args\": [\n \"value\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#ifOdd 3}} odd {{else}} even {{/ifOdd}} -> odd\",\n \"description\": \"<p>Block helper that renders a block if <code>value</code> is <strong>an odd number</strong>. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"is\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#is 3 3}} is {{else}} is not {{/is}} -> is\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. Similar to <a href=\\\"#eq\\\">eq</a> but does not do strict equality.</p>\\n\"\n },\n \"isnt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#isnt 3 3}} isnt {{else}} is {{/isnt}} -> is\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>not equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. Similar to <a href=\\\"#unlesseq\\\">unlessEq</a> but does not use strict equality for comparisons.</p>\\n\"\n },\n \"lt\": {\n \"args\": [\n \"context\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#lt 2 3}} less than {{else}} more than or equal {{/lt}} -> less than\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>less than</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=''</code> hash argument for the second value.</p>\\n\"\n },\n \"lte\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#lte 2 3}} less than or equal {{else}} more than {{/lte}} -> less than or equal\",\n \"description\": \"<p>Block helper that renders a block if <code>a</code> is <strong>less than or equal to</strong> <code>b</code>. If an inverse block is specified it will be rendered when falsy. You may optionally use the <code>compare=''</code> hash argument for the second value.</p>\\n\"\n },\n \"neither\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#neither null null}} both falsey {{else}} both not falsey {{/neither}} -> both falsey\",\n \"description\": \"<p>Block helper that renders a block if <strong>neither of</strong> the given values are truthy. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"not\": {\n \"args\": [\n \"val\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#not undefined }} falsey {{else}} not falsey {{/not}} -> falsey\",\n \"description\": \"<p>Returns true if <code>val</code> is falsey. Works as a block or inline helper.</p>\\n\"\n },\n \"or\": {\n \"args\": [\n \"arguments\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{#or 1 2 undefined }} at least one truthy {{else}} all falsey {{/or}} -> at least one truthy\",\n \"description\": \"<p>Block helper that renders a block if <strong>any of</strong> the given values is truthy. If an inverse block is specified it will be rendered when falsy.</p>\\n\"\n },\n \"unlessEq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessEq 2 1 }} not equal {{else}} equal {{/unlessEq}} -> not equal\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is equal to <code>b</code></strong>.</p>\\n\"\n },\n \"unlessGt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessGt 20 1 }} not greater than {{else}} greater than {{/unlessGt}} -> greater than\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is greater than <code>b</code></strong>.</p>\\n\"\n },\n \"unlessLt\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessLt 20 1 }} greater than or equal {{else}} less than {{/unlessLt}} -> greater than or equal\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is less than <code>b</code></strong>.</p>\\n\"\n },\n \"unlessGteq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessGteq 20 1 }} less than {{else}} greater than or equal to {{/unlessGteq}} -> greater than or equal to\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is greater than or equal to <code>b</code></strong>.</p>\\n\"\n },\n \"unlessLteq\": {\n \"args\": [\n \"a\",\n \"b\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"example\": \"{{#unlessLteq 20 1 }} greater than {{else}} less than or equal to {{/unlessLteq}} -> greater than\",\n \"description\": \"<p>Block helper that always renders the inverse block <strong>unless <code>a</code> is less than or equal to <code>b</code></strong>.</p>\\n\"\n }\n },\n \"object\": {\n \"extend\": {\n \"args\": [\n \"objects\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Extend the context with the properties of other objects. A shallow merge is performed to avoid mutating the context.</p>\\n\"\n },\n \"forIn\": {\n \"args\": [\n \"context\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Block helper that iterates over the properties of an object, exposing each key and value on the context.</p>\\n\"\n },\n \"forOwn\": {\n \"args\": [\n \"obj\",\n \"options\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Block helper that iterates over the <strong>own</strong> properties of an object, exposing each key and value on the context.</p>\\n\"\n },\n \"toPath\": {\n \"args\": [\n \"prop\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Take arguments and, if they are string or number, convert them to a dot-delineated object property path.</p>\\n\"\n },\n \"get\": {\n \"args\": [\n \"prop\",\n \"context\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"description\": \"<p>Use property paths (<code>a.b.c</code>) to get a value or nested value from the context. Works as a regular helper or block helper.</p>\\n\"\n },\n \"getObject\": {\n \"args\": [\n \"prop\",\n \"context\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Use property paths (<code>a.b.c</code>) to get an object from the context. Differs from the <code>get</code> helper in that this helper will return the actual object, including the given property key. Also, this helper does not work as a block helper.</p>\\n\"\n },\n \"hasOwn\": {\n \"args\": [\n \"key\",\n \"context\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Return true if <code>key</code> is an own, enumerable property of the given <code>context</code> object.</p>\\n\"\n },\n \"isObject\": {\n \"args\": [\n \"value\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Return true if <code>value</code> is an object.</p>\\n\"\n },\n \"JSONparse\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Parses the given string using <code>JSON.parse</code>.</p>\\n\"\n },\n \"JSONstringify\": {\n \"args\": [\n \"obj\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Stringify an object using <code>JSON.stringify</code>.</p>\\n\"\n },\n \"merge\": {\n \"args\": [\n \"object\",\n \"objects\"\n ],\n \"numArgs\": 2,\n \"description\": \"<p>Deeply merge the properties of the given <code>objects</code> with the context object.</p>\\n\"\n },\n \"parseJSON\": {\n \"args\": [\n \"string\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Parses the given string using <code>JSON.parse</code>.</p>\\n\"\n },\n \"pick\": {\n \"args\": [\n \"properties\",\n \"context\",\n \"options\"\n ],\n \"numArgs\": 3,\n \"description\": \"<p>Pick properties from the context object.</p>\\n\"\n },\n \"stringify\": {\n \"args\": [\n \"obj\"\n ],\n \"numArgs\": 1,\n \"description\": \"<p>Stringify an object using <code>JSON.stringify</code>.</p>\\n\"\n }\n },\n \"date\": {\n \"date\": {\n \"args\": [\n \"datetime\",\n \"format\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{date now \\\"DD-MM-YYYY\\\" \\\"America/New_York\\\" }} -> 21-01-2021\",\n \"description\": \"<p>Format a date using moment.js date formatting - the timezone is optional and uses the tz database.</p>\\n\"\n },\n \"duration\": {\n \"args\": [\n \"time\",\n \"durationType\"\n ],\n \"numArgs\": 2,\n \"example\": \"{{duration timeLeft \\\"seconds\\\"}} -> a few seconds\",\n \"description\": \"<p>Produce a humanized duration left/until given an amount of time and the type of time measurement.</p>\\n\"\n }\n }\n}\n", "const { getHelperList } = require(\"../helpers\")\n\nfunction getLayers(fullBlock) {\n let layers = []\n while (fullBlock.length) {\n const start = fullBlock.lastIndexOf(\"(\"),\n end = fullBlock.indexOf(\")\")\n let layer\n if (start === -1 || end === -1) {\n layer = fullBlock.trim()\n fullBlock = \"\"\n } else {\n const untrimmed = fullBlock.substring(start, end + 1)\n layer = untrimmed.substring(1, untrimmed.length - 1).trim()\n fullBlock =\n fullBlock.slice(0, start) +\n fullBlock.slice(start + untrimmed.length + 1, fullBlock.length)\n }\n layers.push(layer)\n }\n return layers\n}\n\nfunction getVariable(variableName) {\n if (!variableName || typeof variableName !== \"string\") {\n return variableName\n }\n // it is an array\n const arrayOrObject = [\",\", \"{\", \":\"]\n let contains = false\n arrayOrObject.forEach(char => {\n if (variableName.includes(char)) {\n contains = true\n }\n })\n if (variableName.startsWith(\"[\") && contains) {\n return variableName\n }\n // it is just a number\n if (!isNaN(parseFloat(variableName))) {\n return variableName\n }\n if (variableName.startsWith(\"'\") || variableName.startsWith('\"')) {\n return variableName\n }\n // extract variable\n return `$(\"${variableName}\")`\n}\n\nfunction buildList(parts, value) {\n function build() {\n return parts\n .map(part => (part.startsWith(\"helper\") ? part : getVariable(part)))\n .join(\", \")\n }\n if (!value) {\n return parts.length > 1 ? `${build()}` : build()\n } else {\n return parts.length === 0 ? value : `${value}, ${build()}`\n }\n}\n\nfunction splitBySpace(layer) {\n const parts = []\n let started = null,\n endChar = null,\n last = 0\n function add(str) {\n const startsWith = [\"]\"]\n while (startsWith.indexOf(str.substring(0, 1)) !== -1) {\n str = str.substring(1, str.length)\n }\n if (str.length > 0) {\n parts.push(str.trim())\n }\n }\n const continuationChars = [\"[\", \"'\", '\"']\n for (let index = 0; index < layer.length; index++) {\n const char = layer[index]\n if (continuationChars.indexOf(char) !== -1 && started == null) {\n started = index\n endChar = char === \"[\" ? \"]\" : char\n } else if (\n char === endChar &&\n started != null &&\n layer[index + 1] !== \".\"\n ) {\n add(layer.substring(started, index + 1))\n started = null\n endChar = null\n last = index + 1\n } else if (started == null && char === \" \") {\n add(layer.substring(last, index))\n last = index\n }\n }\n if (\n (!layer.startsWith(\"[\") || parts.length === 0) &&\n last !== layer.length - 1\n ) {\n add(layer.substring(last, layer.length))\n }\n return parts\n}\n\nmodule.exports.convertHBSBlock = (block, blockNumber) => {\n const braceLength = block[2] === \"{\" ? 3 : 2\n block = block.substring(braceLength, block.length - braceLength).trim()\n const layers = getLayers(block)\n\n let value = null\n const list = getHelperList()\n for (let layer of layers) {\n const parts = splitBySpace(layer)\n if (value || parts.length > 1) {\n // first of layer should always be the helper\n const helper = parts.splice(0, 1)\n if (list[helper]) {\n value = `helpers.${helper}(${buildList(parts, value)})`\n }\n }\n // no helpers\n else {\n value = getVariable(parts[0])\n }\n }\n // split by space will remove square brackets\n return { variable: `var${blockNumber}`, value }\n}\n", "const handlebars = require(\"handlebars\")\nconst { registerAll, registerMinimum } = require(\"./helpers/index\")\nconst processors = require(\"./processors\")\nconst { atob, btoa } = require(\"./utilities\")\nconst manifest = require(\"../manifest.json\")\nconst {\n FIND_HBS_REGEX,\n FIND_ANY_HBS_REGEX,\n findDoubleHbsInstances,\n} = require(\"./utilities\")\nconst { convertHBSBlock } = require(\"./conversion\")\n\nconst hbsInstance = handlebars.create()\nregisterAll(hbsInstance)\nconst hbsInstanceNoHelpers = handlebars.create()\nregisterMinimum(hbsInstanceNoHelpers)\nconst defaultOpts = {\n noHelpers: false,\n cacheTemplates: false,\n noEscaping: false,\n escapeNewlines: false,\n noFinalise: false,\n}\n\n/**\n * Utility function to check if the object is valid.\n */\nfunction testObject(object) {\n // JSON stringify will fail if there are any cycles, stops infinite recursion\n try {\n JSON.stringify(object)\n } catch (err) {\n throw \"Unable to process inputs to JSON, cannot recurse\"\n }\n}\n\n/**\n * Creates a HBS template function for a given string, and optionally caches it.\n */\nlet templateCache = {}\nfunction createTemplate(string, opts) {\n opts = { ...defaultOpts, ...opts }\n\n // Finalising adds a helper, can't do this with no helpers\n const key = `${string}-${JSON.stringify(opts)}`\n\n // Reuse the cached template is possible\n if (opts.cacheTemplates && templateCache[key]) {\n return templateCache[key]\n }\n\n string = processors.preprocess(string, opts)\n\n // Optionally disable built in HBS escaping\n if (opts.noEscaping) {\n string = exports.disableEscaping(string)\n }\n\n // This does not throw an error when template can't be fulfilled,\n // have to try correct beforehand\n const instance = opts.noHelpers ? hbsInstanceNoHelpers : hbsInstance\n const template = instance.compile(string, {\n strict: false,\n })\n templateCache[key] = template\n return template\n}\n\n/**\n * Given an input object this will recurse through all props to try and update any handlebars statements within.\n * @param {object|array} object The input structure which is to be recursed, it is important to note that\n * if the structure contains any cycles then this will fail.\n * @param {object} context The context that handlebars should fill data from.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {Promise<object|array>} The structure input, as fully updated as possible.\n */\nmodule.exports.processObject = async (object, context, opts) => {\n testObject(object)\n for (let key of Object.keys(object || {})) {\n if (object[key] != null) {\n let val = object[key]\n if (typeof val === \"string\") {\n object[key] = await module.exports.processString(\n object[key],\n context,\n opts\n )\n } else if (typeof val === \"object\") {\n object[key] = await module.exports.processObject(\n object[key],\n context,\n opts\n )\n }\n }\n }\n return object\n}\n\n/**\n * This will process a single handlebars containing string. If the string passed in has no valid handlebars statements\n * then nothing will occur.\n * @param {string} string The template string which is the filled from the context object.\n * @param {object} context An object of information which will be used to enrich the string.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {Promise<string>} The enriched string, all templates should have been replaced if they can be.\n */\nmodule.exports.processString = async (string, context, opts) => {\n // TODO: carry out any async calls before carrying out async call\n return module.exports.processStringSync(string, context, opts)\n}\n\n/**\n * Given an input object this will recurse through all props to try and update any handlebars statements within. This is\n * a pure sync call and therefore does not have the full functionality of the async call.\n * @param {object|array} object The input structure which is to be recursed, it is important to note that\n * if the structure contains any cycles then this will fail.\n * @param {object} context The context that handlebars should fill data from.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {object|array} The structure input, as fully updated as possible.\n */\nmodule.exports.processObjectSync = (object, context, opts) => {\n testObject(object)\n for (let key of Object.keys(object || {})) {\n let val = object[key]\n if (typeof val === \"string\") {\n object[key] = module.exports.processStringSync(object[key], context, opts)\n } else if (typeof val === \"object\") {\n object[key] = module.exports.processObjectSync(object[key], context, opts)\n }\n }\n return object\n}\n\n/**\n * This will process a single handlebars containing string. If the string passed in has no valid handlebars statements\n * then nothing will occur. This is a pure sync call and therefore does not have the full functionality of the async call.\n * @param {string} string The template string which is the filled from the context object.\n * @param {object} context An object of information which will be used to enrich the string.\n * @param {object|undefined} [opts] optional - specify some options for processing.\n * @returns {string} The enriched string, all templates should have been replaced if they can be.\n */\nmodule.exports.processStringSync = (string, context, opts) => {\n // Take a copy of input in case of error\n const input = string\n if (typeof string !== \"string\") {\n throw \"Cannot process non-string types.\"\n }\n function process(stringPart) {\n const template = createTemplate(stringPart, opts)\n const now = Math.floor(Date.now() / 1000) * 1000\n return processors.postprocess(\n template({\n now: new Date(now).toISOString(),\n __opts: {\n ...opts,\n input: stringPart,\n },\n ...context,\n })\n )\n }\n try {\n if (opts && opts.onlyFound) {\n const blocks = exports.findHBSBlocks(string)\n for (let block of blocks) {\n const outcome = process(block)\n string = string.replace(block, outcome)\n }\n return string\n } else {\n return process(string)\n }\n } catch (err) {\n return input\n }\n}\n\n/**\n * By default with expressions like {{ name }} handlebars will escape various\n * characters, which can be problematic. To fix this we use the syntax {{{ name }}},\n * this function will find any double braces and switch to triple.\n * @param string the string to have double HBS statements converted to triple.\n */\nmodule.exports.disableEscaping = string => {\n const matches = findDoubleHbsInstances(string)\n if (matches == null) {\n return string\n }\n\n // find the unique set\n const unique = [...new Set(matches)]\n for (let match of unique) {\n // add a negative lookahead to exclude any already\n const regex = new RegExp(`${match}(?!})`, \"g\")\n string = string.replace(regex, `{${match}}`)\n }\n return string\n}\n\n/**\n * Simple utility function which makes sure that a templating property has been wrapped in literal specifiers correctly.\n * @param {string} property The property which is to be wrapped.\n * @returns {string} The wrapped property ready to be added to a templating string.\n */\nmodule.exports.makePropSafe = property => {\n return `[${property}]`.replace(\"[[\", \"[\").replace(\"]]\", \"]\")\n}\n\n/**\n * Checks whether or not a template string contains totally valid syntax (simply tries running it)\n * @param string The string to test for valid syntax - this may contain no templates and will be considered valid.\n * @param [opts] optional - specify some options for processing.\n * @returns {boolean} Whether or not the input string is valid.\n */\nmodule.exports.isValid = (string, opts) => {\n const validCases = [\n \"string\",\n \"number\",\n \"object\",\n \"array\",\n \"cannot read property\",\n \"undefined\",\n \"json at position 0\",\n ]\n // this is a portion of a specific string always output by handlebars in the case of a syntax error\n const invalidCases = [`expecting '`]\n // don't really need a real context to check if its valid\n const context = {}\n try {\n const template = createTemplate(string, {\n ...opts,\n noFinalise: true,\n })\n template(context)\n return true\n } catch (err) {\n const msg = err && err.message ? err.message : err\n if (!msg) {\n return false\n }\n const invalidCase = invalidCases.some(invalidCase =>\n msg.toLowerCase().includes(invalidCase)\n )\n const validCase = validCases.some(validCase =>\n msg.toLowerCase().includes(validCase)\n )\n // special case for maths functions - don't have inputs yet\n return validCase && !invalidCase\n }\n}\n\n/**\n * We have generated a static manifest file from the helpers that this string templating package makes use of.\n * This manifest provides information about each of the helpers and how it can be used.\n * @returns The manifest JSON which has been generated from the helpers.\n */\nmodule.exports.getManifest = () => {\n return manifest\n}\n\n/**\n * Checks if a HBS expression is a valid JS HBS expression\n * @param handlebars the HBS expression to check\n * @returns {boolean} whether the expression is JS or not\n */\nmodule.exports.isJSBinding = handlebars => {\n return module.exports.decodeJSBinding(handlebars) != null\n}\n\n/**\n * Encodes a raw JS string as a JS HBS expression\n * @param javascript the JS code to encode\n * @returns {string} the JS HBS expression\n */\nmodule.exports.encodeJSBinding = javascript => {\n return `{{ js \"${btoa(javascript)}\" }}`\n}\n\n/**\n * Decodes a JS HBS expression to the raw JS code\n * @param handlebars the JS HBS expression\n * @returns {string|null} the raw JS code\n */\nmodule.exports.decodeJSBinding = handlebars => {\n if (!handlebars || typeof handlebars !== \"string\") {\n return null\n }\n\n // JS is only valid if it is the only HBS expression\n if (!handlebars.trim().startsWith(\"{{ js \")) {\n return null\n }\n\n const captureJSRegex = new RegExp(/{{ js \"(.*)\" }}/)\n const match = handlebars.match(captureJSRegex)\n if (!match || match.length < 2) {\n return null\n }\n return atob(match[1])\n}\n\n/**\n * Same as the doesContainString function, but will check for all the strings\n * before confirming it contains.\n * @param {string} template The template string to search.\n * @param {string[]} strings The strings to look for.\n * @returns {boolean} Will return true if all strings found in HBS statement.\n */\nmodule.exports.doesContainStrings = (template, strings) => {\n let regexp = new RegExp(FIND_HBS_REGEX)\n let matches = template.match(regexp)\n if (matches == null) {\n return false\n }\n for (let match of matches) {\n let hbs = match\n if (exports.isJSBinding(match)) {\n hbs = exports.decodeJSBinding(match)\n }\n let allFound = true\n for (let string of strings) {\n if (!hbs.includes(string)) {\n allFound = false\n }\n }\n if (allFound) {\n return true\n }\n }\n return false\n}\n\n/**\n * Given a string, this will return any {{ binding }} or {{{ binding }}} type\n * statements.\n * @param {string} string The string to search within.\n * @return {string[]} The found HBS blocks.\n */\nmodule.exports.findHBSBlocks = string => {\n if (!string || typeof string !== \"string\") {\n return []\n }\n let regexp = new RegExp(FIND_ANY_HBS_REGEX)\n let matches = string.match(regexp)\n if (matches == null) {\n return []\n }\n return matches\n}\n\n/**\n * This function looks in the supplied template for handlebars instances, if they contain\n * JS the JS will be decoded and then the supplied string will be looked for. For example\n * if the template \"Hello, your name is {{ related }}\" this function would return that true\n * for the string \"related\" but not for \"name\" as it is not within the handlebars statement.\n * @param {string} template A template string to search for handlebars instances.\n * @param {string} string The word or sentence to search for.\n * @returns {boolean} The this return true if the string is found, false if not.\n */\nmodule.exports.doesContainString = (template, string) => {\n return exports.doesContainStrings(template, [string])\n}\n\nmodule.exports.convertToJS = hbs => {\n const blocks = exports.findHBSBlocks(hbs)\n let js = \"return `\",\n prevBlock = null\n const variables = {}\n if (blocks.length === 0) {\n js += hbs\n }\n let count = 1\n for (let block of blocks) {\n let stringPart = hbs\n if (prevBlock) {\n stringPart = stringPart.split(prevBlock)[1]\n }\n stringPart = stringPart.split(block)[0]\n prevBlock = block\n const { variable, value } = convertHBSBlock(block, count++)\n variables[variable] = value\n js += `${stringPart.split()}\\${${variable}}`\n }\n let varBlock = \"\"\n for (let [variable, value] of Object.entries(variables)) {\n varBlock += `const ${variable} = ${value};\\n`\n }\n js += \"`;\"\n return `${varBlock}${js}`\n}\n", "const templates = require(\"./index.js\")\n\n/**\n * CJS entrypoint for rollup\n */\nmodule.exports.isValid = templates.isValid\nmodule.exports.makePropSafe = templates.makePropSafe\nmodule.exports.getManifest = templates.getManifest\nmodule.exports.isJSBinding = templates.isJSBinding\nmodule.exports.encodeJSBinding = templates.encodeJSBinding\nmodule.exports.decodeJSBinding = templates.decodeJSBinding\nmodule.exports.processStringSync = templates.processStringSync\nmodule.exports.processObjectSync = templates.processObjectSync\nmodule.exports.processString = templates.processString\nmodule.exports.processObject = templates.processObject\nmodule.exports.doesContainStrings = templates.doesContainStrings\nmodule.exports.doesContainString = templates.doesContainString\nmodule.exports.disableEscaping = templates.disableEscaping\nmodule.exports.findHBSBlocks = templates.findHBSBlocks\nmodule.exports.convertToJS = templates.convertToJS\n\nif (!process.env.NO_JS) {\n const { VM } = require(\"vm2\")\n const { setJSRunner } = require(\"./helpers/javascript\")\n /**\n * Use vm2 to run JS scripts in a node env\n */\n setJSRunner((js, context) => {\n const vm = new VM({\n sandbox: context,\n timeout: 1000\n })\n return vm.run(js)\n })\n}\n", "import { licensing } from \"../../sdk\"\nimport {\n Feature,\n AuditLogSearchParams,\n Event,\n AuditedEventFriendlyName,\n SearchFilters,\n AuditLogResourceStatus,\n FallbackInfo,\n DeletedResourceInfo,\n} from \"@budibase/types\"\nconst {\n processStringSync,\n findHBSBlocks,\n} = require(\"@budibase/string-templates\")\nimport { constants, db as dbCore } from \"@budibase/backend-core\"\n\nconst MIN_DATE = constants.MIN_VALID_DATE.toISOString()\nconst MAX_DATE = constants.MAX_VALID_DATE.toISOString()\n\nexport enum ResourceType {\n USER = \"user\",\n APP = \"app\",\n}\n\nexport function fillDates(params: AuditLogSearchParams) {\n if (params.startDate || params.endDate) {\n params.startDate = params.startDate || MIN_DATE\n params.endDate = params.endDate || MAX_DATE\n }\n return params\n}\n\nexport function getSearchFilters(params: AuditLogSearchParams) {\n // look for prod app IDs in audit log documents\n if (Array.isArray(params.appIds)) {\n params.appIds = params.appIds.map(appId => dbCore.getProdAppID(appId))\n }\n // escape events characters, still events just with escapes\n if (Array.isArray(params.events)) {\n params.events = params.events.map(\n event => escapeCharacter(event, [\":\"]) as Event\n )\n }\n const filter: SearchFilters = {}\n function addStringParams(key: string, params: string[] | undefined) {\n if (params?.length) {\n filter.oneOf = {\n ...filter.oneOf,\n [key]: params,\n }\n }\n }\n addStringParams(\"userId\", params.userIds)\n addStringParams(\"appId\", params.appIds)\n addStringParams(\"event\", params.events)\n\n if (params.fullSearch) {\n const search = escapeCharacter(params.fullSearch, [\":\", \" \"])\n // utilises a whitespace search\n filter.equal = {\n all: `(\"${search}\" OR ${search}*)`,\n }\n }\n if (params.startDate || params.endDate) {\n params = fillDates(params)\n filter.range = {\n timestamp: {\n high: params.endDate!,\n low: params.startDate!,\n },\n }\n }\n // no parameters, search for anything\n if (Object.keys(filter).length === 0) {\n filter.notEmpty = {\n event: true,\n }\n }\n return filter\n}\n\nexport function escapeCharacter(str: string, characters: string[]) {\n for (let character of characters) {\n str = str.replace(new RegExp(character, \"g\"), `\\\\${character}`)\n }\n return str\n}\n\nexport function deleted(\n id: string,\n resourceType: ResourceType,\n fallbackInfo?: FallbackInfo\n) {\n const deleteInfo: DeletedResourceInfo = {\n _id: id,\n status: AuditLogResourceStatus.DELETED,\n }\n switch (resourceType) {\n case ResourceType.APP:\n deleteInfo.name = fallbackInfo?.appName\n break\n case ResourceType.USER:\n deleteInfo.email = fallbackInfo?.email\n break\n }\n return deleteInfo\n}\n\nexport function removeTemplateStrings(friendlyName: string) {\n const blocks = findHBSBlocks(friendlyName)\n // remove any HBS blocks\n for (let block of blocks) {\n const quoted = ` \"${block}\"`\n friendlyName = friendlyName.replace(\n friendlyName.includes(quoted) ? quoted : ` ${block}`,\n \"\"\n )\n // Remove template strings\n friendlyName = processStringSync(friendlyName, {})\n }\n return friendlyName\n}\n\nexport async function auditLogsEnabled() {\n const license = await licensing.cache.getCachedLicense()\n return license.features.includes(Feature.AUDIT_LOGS)\n}\n\nexport function getEventFriendlyName(event: Event, metadata: any) {\n const friendly = AuditedEventFriendlyName[event]\n if (!friendly) {\n throw new Error(\"No friendly name found.\")\n }\n let processed = processStringSync(friendly, metadata)\n // this will occur if no enrichment could be found\n if (processed.includes(`\"\"`)) {\n processed = removeTemplateStrings(friendly)\n }\n return processed\n}\n", "import {\n AuditedEventFriendlyName,\n AuditLogDoc,\n AuditLogEnriched,\n AuditLogSearchParams,\n AuditLogSystemUser,\n AuditWriteOpts,\n Event,\n FallbackInfo,\n SearchFilters,\n} from \"@budibase/types\"\nimport * as auditLogs from \"../../db/auditLogs\"\nimport {\n cache,\n db as dbCore,\n users,\n utils,\n logging,\n} from \"@budibase/backend-core\"\nimport { Readable } from \"stream\"\nimport {\n auditLogsEnabled,\n deleted,\n fillDates,\n getEventFriendlyName,\n getSearchFilters,\n removeTemplateStrings,\n ResourceType,\n} from \"./utils\"\n\nexport async function write(\n event: Event,\n metadata: any,\n opts?: AuditWriteOpts\n): Promise<AuditLogDoc | undefined> {\n if (!(await auditLogsEnabled()) || !utils.isAudited(event)) {\n return\n }\n const friendly = getEventFriendlyName(event, metadata)\n let date = new Date()\n if (opts?.timestamp) {\n date = new Date(opts.timestamp)\n }\n const doc: AuditLogDoc = {\n timestamp: date.toISOString(),\n event,\n name: friendly,\n userId: opts?.userId || AuditLogSystemUser,\n metadata: {\n ...metadata,\n ...opts?.hostInfo,\n },\n }\n const fallback: FallbackInfo = {}\n // audit logs always use prod app ID\n try {\n if (opts?.appId) {\n doc.appId = dbCore.getProdAppID(opts.appId)\n const appMetadata = await cache.app.getAppMetadata(opts.appId)\n fallback.appName = appMetadata.name\n }\n if (opts?.userId) {\n const user = await users.getById(opts?.userId as string)\n fallback.email = user.email\n }\n } catch (err) {\n logging.logAlert(\n \"Failed to retrieve fallback information for audit log\",\n err\n )\n }\n doc.fallback = fallback\n return await auditLogs.save(doc)\n}\n\nasync function enrich(logs: AuditLogDoc[]): Promise<AuditLogEnriched[]> {\n const allUserIds = logs.map(log => log.userId)\n const hasAppIdLogs = logs.filter(log => log.appId)\n // get the dev app ID - enrich with dev app info as prod app may not exist\n const allAppIds = hasAppIdLogs.map(log =>\n dbCore.getDevAppID(log.appId as string)\n )\n const userList = await users.bulkGetGlobalUsersById(\n [...new Set(allUserIds)],\n { cleanup: true }\n )\n const appList = await dbCore.getAppsByIDs([...new Set(allAppIds)])\n\n let enriched: AuditLogEnriched[] = []\n for (let log of logs) {\n const user = userList.find(user => user?._id === log.userId)\n const app = appList.find(app => dbCore.isSameAppID(app?.appId, log.appId))\n const enrichedLog: AuditLogEnriched = {\n event: log.event,\n timestamp: log.timestamp,\n name: log.name,\n metadata: log.metadata,\n user: user || deleted(log.userId, ResourceType.USER, log.fallback),\n }\n if (log.appId) {\n enrichedLog.app =\n app || deleted(log.appId, ResourceType.APP, log.fallback)\n }\n enriched.push(enrichedLog)\n }\n return enriched\n}\n\nexport async function fetch(params: AuditLogSearchParams) {\n if (!(await auditLogsEnabled())) {\n throw new Error(\"Audit logs not available - license required.\")\n }\n\n const filter: SearchFilters = getSearchFilters(params)\n\n const response = await auditLogs.search(filter, params.bookmark)\n return {\n hasNextPage: response.hasNextPage,\n bookmark: response.bookmark,\n data: await enrich(response.rows),\n }\n}\n\n// like the fetch, but without pagination (uses filtered replication)\nexport function download(params: AuditLogSearchParams): {\n promise: Promise<void>\n stream: Readable\n} {\n params = fillDates(params)\n return auditLogs.dump(params)\n}\n\nexport function definitions() {\n const entries = Object.entries(AuditedEventFriendlyName).filter(\n entry => entry[1] != undefined\n )\n const events: Record<string, string> = {}\n for (let entry of entries) {\n events[entry[0]] = removeTemplateStrings(entry[1] as string)\n }\n return events\n}\n", "export * from \"./auditLogs\"\n", "import { queue } from \"@budibase/backend-core\"\nimport { AppBackupQueueData } from \"@budibase/types\"\nimport { Queue } from \"bull\"\n\nlet backupQueue: Queue<AppBackupQueueData>\n\nexport function init() {\n backupQueue = queue.createQueue<AppBackupQueueData>(queue.JobQueue.APP_BACKUP)\n}\n\nexport function getBackupQueue() {\n return backupQueue\n}\n", "import { objectStore, events } from \"@budibase/backend-core\"\nimport {\n AppBackupContents,\n AppBackupFetchOpts,\n AppBackupMetadata,\n AppBackupStatus,\n AppBackupTrigger,\n AppBackupType,\n} from \"@budibase/types\"\nimport { backups } from \"../../db\"\nimport { getBackupQueue } from \"./queue\"\nimport * as features from \"../features\"\n\nasync function storeAppBackupMetadata(\n metadata: AppBackupMetadata,\n opts: { filename?: string } = {}\n) {\n return backups.storeAppBackupMetadata(metadata, opts)\n}\n\nfunction getTimestamps(status: AppBackupStatus) {\n const timestamp = new Date().toISOString()\n switch (status) {\n case AppBackupStatus.COMPLETE:\n case AppBackupStatus.FAILED:\n return { timestamp, finishedAt: timestamp }\n case AppBackupStatus.STARTED:\n return { timestamp, startedAt: timestamp }\n case AppBackupStatus.PENDING:\n return { timestamp, createdAt: timestamp }\n }\n}\n\nasync function updateBackupStatus(\n id: string,\n rev: string,\n status: AppBackupStatus,\n contents?: AppBackupContents,\n filename?: string\n) {\n const backup: AppBackupMetadata = await getAppBackup(id)\n // keep backup event timestamp up to date with when it completes/fails\n return await backups.storeAppBackupMetadata(\n {\n ...backup,\n ...getTimestamps(status),\n contents,\n status,\n type: AppBackupType.BACKUP,\n },\n { filename, docId: id, docRev: rev }\n )\n}\n\nasync function updateRestoreStatus(\n id: string,\n rev: string,\n status: AppBackupStatus\n) {\n const restore: AppBackupMetadata = await getAppBackup(id)\n // keep restore event timestamp up to date with when it completes/fails\n return await backups.storeAppBackupMetadata(\n {\n ...restore,\n ...getTimestamps(status),\n status,\n type: AppBackupType.RESTORE,\n trigger: AppBackupTrigger.MANUAL,\n },\n { docId: id, docRev: rev }\n )\n}\n\nasync function getAppBackup(backupId: string) {\n return backups.getAppBackupMetadata(backupId)\n}\n\nasync function updateAppBackup(backupId: string, backupName: string) {\n return backups.updateAppBackupMetadata(backupId, backupName)\n}\n\nasync function deleteAppBackup(backupId: string) {\n const metadata = await backups.getAppBackupMetadata(backupId)\n if (metadata.filename) {\n await objectStore.deleteFile(\n objectStore.ObjectStoreBuckets.BACKUPS,\n metadata.filename\n )\n }\n return backups.deleteAppBackupMetadata(backupId)\n}\n\nasync function fetchAppBackups(appId: string, opts?: AppBackupFetchOpts) {\n return backups.fetchAppBackups(appId, opts)\n}\n\nasync function downloadAppBackup(backupId: string) {\n const metadata = await backups.getAppBackupMetadata(backupId)\n if (!metadata.filename) {\n throw new Error(\"Backup incomplete - cannot download.\")\n }\n const path = await objectStore.retrieveToTmp(\n objectStore.ObjectStoreBuckets.BACKUPS,\n metadata.filename\n )\n return { metadata, path }\n}\n\nasync function triggerAppBackup(\n appId: string,\n trigger: AppBackupTrigger,\n opts: { createdBy?: string; name?: string } = {}\n): Promise<string | undefined> {\n // store immediately, get rev and id as incomplete\n let backup\n try {\n backup = await storeAppBackupMetadata({\n appId,\n trigger,\n timestamp: new Date().toISOString(),\n status: AppBackupStatus.PENDING,\n type: AppBackupType.BACKUP,\n ...opts,\n })\n } catch (err: any) {\n // there already is a backup for this exact millisecond, no need\n // for a new one\n if (err.status === 409) {\n return\n } else {\n throw err\n }\n }\n // kick off job\n await getBackupQueue().add({\n docId: backup.id,\n docRev: backup.rev,\n appId,\n export: {\n trigger,\n ...opts,\n },\n })\n await events.backup.appBackupTriggered(\n appId,\n backup.id,\n AppBackupType.BACKUP,\n trigger,\n opts?.name as string\n )\n return backup.id\n}\n\nasync function triggerAppRestore(\n appId: string,\n backupId: string,\n nameForBackup: string,\n createdBy?: string\n): Promise<{ restoreId: string; metadata: any } | void> {\n const metadata = await getAppBackup(backupId)\n // store immediately, get rev and id as incomplete\n let restore\n try {\n restore = await storeAppBackupMetadata({\n appId,\n timestamp: new Date().toISOString(),\n status: AppBackupStatus.PENDING,\n type: AppBackupType.RESTORE,\n createdBy,\n })\n } catch (err: any) {\n // there already is a restore for this exact millisecond, no need\n // for a new one\n if (err?.status === 409) {\n return\n } else {\n throw err\n }\n }\n await getBackupQueue().add({\n appId,\n docId: restore.id,\n docRev: restore.rev,\n import: {\n nameForBackup,\n backupId,\n createdBy,\n },\n })\n return { restoreId: restore.id, metadata }\n}\n\n/**\n * Rather than exporting functions directly from licensed sdks,\n * we use the licensed function wrapper to apply license restrictions\n * with minimal interference to internal logic.\n */\nconst pkg = {\n isEnabled: features.isBackupsEnabled,\n triggerAppRestore: features.checkBackups(triggerAppRestore),\n triggerAppBackup: features.checkBackups(triggerAppBackup),\n downloadAppBackup: features.checkBackups(downloadAppBackup),\n fetchAppBackups: features.checkBackups(fetchAppBackups),\n storeAppBackupMetadata: features.checkBackups(storeAppBackupMetadata),\n updateBackupStatus: features.checkBackups(updateBackupStatus),\n updateRestoreStatus: features.checkBackups(updateRestoreStatus),\n getAppBackup: features.checkBackups(getAppBackup),\n updateAppBackup: features.checkBackups(updateAppBackup),\n deleteAppBackup: features.checkBackups(deleteAppBackup),\n}\n\nexport default pkg\n", "import {\n db as dbCore,\n logging,\n objectStore,\n tenancy,\n} from \"@budibase/backend-core\"\nimport backups from \"./backup\"\nimport {\n AppBackupContents,\n AppBackupQueueData,\n AppBackupStatus,\n AppBackupTrigger,\n AppBackupType,\n} from \"@budibase/types\"\nimport { getBackupQueue } from \"./queue\"\nimport { Job } from \"bull\"\nimport fs from \"fs\"\nimport { BackupProcessingOpts } from \"../../types\"\n\nexport async function init(opts: BackupProcessingOpts) {\n await getBackupQueue().process(async (job: Job) => {\n const data = job.data as AppBackupQueueData\n try {\n if (data.export) {\n return exportProcessor(job, opts)\n } else if (data.import) {\n return importProcessor(job, opts)\n }\n } catch (err: any) {\n logging.logAlert(\n `Failed to perform backup for app ID: ${data.appId}`,\n err\n )\n }\n })\n}\n\ntype RunBackupOpts = {\n processing: BackupProcessingOpts\n doc?: { id: string; rev: string }\n createdBy?: string\n name?: string\n}\n\nasync function removeExistingApp(devId: string) {\n const devDb = dbCore.getDB(devId, { skip_setup: true })\n await devDb.destroy()\n}\n\nasync function runBackup(\n trigger: AppBackupTrigger,\n tenantId: string,\n appId: string,\n opts: RunBackupOpts\n) {\n const devAppId = dbCore.getDevAppID(appId),\n prodAppId = dbCore.getProdAppID(appId)\n const timestamp = new Date().toISOString()\n const updateMetadata = async (\n status: AppBackupStatus,\n updateOpts?: { filename?: string; contents?: AppBackupContents }\n ) => {\n if (opts?.doc) {\n await backups.updateBackupStatus(\n opts.doc.id,\n opts.doc.rev,\n status,\n updateOpts?.contents,\n updateOpts?.filename\n )\n } else {\n await backups.storeAppBackupMetadata(\n {\n appId: prodAppId,\n timestamp,\n trigger,\n status,\n name: opts?.name,\n type: AppBackupType.BACKUP,\n contents: updateOpts?.contents,\n createdBy: opts?.createdBy,\n },\n { filename: updateOpts?.filename }\n )\n }\n }\n try {\n const tarPath = await opts.processing.exportAppFn(devAppId, { tar: true })\n const contents = await opts.processing.statsFn(devAppId)\n let filename = `${prodAppId}/backup-${timestamp}.tar.gz`\n const bucket = objectStore.ObjectStoreBuckets.BACKUPS\n await objectStore.upload({\n path: tarPath,\n type: \"application/gzip\",\n bucket,\n filename,\n metadata: {\n name: opts?.name,\n trigger,\n timestamp,\n appId: prodAppId,\n },\n })\n await updateMetadata(AppBackupStatus.COMPLETE, { filename, contents })\n // clear up the tarball after uploading it\n if (fs.existsSync(tarPath)) {\n fs.rmSync(tarPath)\n }\n } catch (err) {\n logging.logAlert(\"App backup error\", err)\n await updateMetadata(AppBackupStatus.FAILED)\n }\n}\n\nasync function importProcessor(job: Job, opts: BackupProcessingOpts) {\n const data: AppBackupQueueData = job.data\n const appId = data.appId,\n backupId = data.import!.backupId,\n nameForBackup = data.import!.nameForBackup,\n createdBy = data.import!.createdBy\n const tenantId = tenancy.getTenantIDFromAppID(appId) as string\n return tenancy.doInTenant(tenantId, async () => {\n const devAppId = dbCore.getDevAppID(appId)\n const { rev } = await backups.updateRestoreStatus(\n data.docId,\n data.docRev,\n AppBackupStatus.STARTED\n )\n // initially export the current state to disk - incase something goes wrong\n await runBackup(AppBackupTrigger.RESTORING, tenantId, appId, {\n processing: opts,\n createdBy,\n name: nameForBackup,\n })\n // get the backup ready on disk\n const { path } = await backups.downloadAppBackup(backupId)\n // start by removing app database and contents of bucket - which will be updated\n await removeExistingApp(devAppId)\n let status = AppBackupStatus.COMPLETE\n try {\n await opts.importAppFn(devAppId, dbCore.getDB(devAppId), {\n file: {\n type: \"application/gzip\",\n path,\n },\n key: path,\n })\n } catch (err) {\n logging.logAlert(\"App restore error\", err)\n status = AppBackupStatus.FAILED\n }\n await backups.updateRestoreStatus(data.docId, rev, status)\n })\n}\n\nasync function exportProcessor(job: Job, opts: BackupProcessingOpts) {\n const data: AppBackupQueueData = job.data\n const appId = data.appId,\n trigger = data.export!.trigger,\n name = data.export!.name\n const tenantId = tenancy.getTenantIDFromAppID(appId) as string\n await tenancy.doInTenant(tenantId, async () => {\n const { rev } = await backups.updateBackupStatus(\n data.docId,\n data.docRev,\n AppBackupStatus.STARTED\n )\n return runBackup(trigger, tenantId, appId, {\n processing: opts,\n doc: { id: data.docId, rev },\n name,\n })\n })\n}\n", "import backups from \"./backup\"\nimport * as processing from \"./processing\"\nimport { BackupInitOpts } from \"../../types\"\nimport { init as queueInit, getBackupQueue } from \"./queue\"\n\nconst init = async (opts: BackupInitOpts) => {\n queueInit()\n await processing.init(opts.processing)\n}\n\nexport default {\n ...backups,\n processing,\n init,\n getBackupQueue,\n}\n", "import { db as dbCore } from \"@budibase/backend-core\"\n\nexport async function appExists(appId: string) {\n const allAppIds = (await dbCore.getAllApps({\n all: true,\n idsOnly: true,\n })) as string[]\n return allAppIds.includes(appId)\n}\n", "export * from \"./apps\"\n", "import {\n db as dbCore,\n tenancy,\n users as usersCore,\n} from \"@budibase/backend-core\"\nimport { SaveUserOpts, SearchIndex, User } from \"@budibase/types\"\n\nexport interface ScimUserServiceConfig {\n functions: {\n saveUser: (user: User, opts?: SaveUserOpts) => Promise<User>\n removeUser: (id: string) => Promise<void>\n }\n}\n\nexport interface GetUsersFilters {\n equal?: Record<string, any>\n}\n\ninterface GetParams {\n pageSize: number\n skip?: number\n filters?: GetUsersFilters\n}\n\nclass ScimUserService {\n saveUser: (user: User, opts?: SaveUserOpts) => Promise<User>\n removeUser: (id: string) => Promise<void>\n\n constructor(config: ScimUserServiceConfig) {\n this.saveUser = config.functions.saveUser\n this.removeUser = config.functions.removeUser\n }\n\n get = async (\n params: GetParams\n ): Promise<{ users: User[]; total: number }> => {\n const db = tenancy.getGlobalDB()\n\n const builder = new dbCore.QueryBuilder<User>(db.name, SearchIndex.USER)\n builder.setIndexBuilder(dbCore.searchIndexes.createUserIndex)\n builder.setLimit(params.pageSize)\n builder.addEqual(\"scimInfo.isSync\", true)\n\n for (const [key, value] of Object.entries(params.filters?.equal ?? {})) {\n builder.addEqual(key, value)\n }\n\n builder.setSort(\"_id\")\n builder.setSkip(params.skip)\n\n const docs = await builder.run()\n\n return {\n users: docs.rows,\n total: docs.totalRows,\n }\n }\n\n find = async (id: string) => {\n const user = await usersCore.getById(id)\n return user\n }\n\n create = async (user: User) => {\n return await this.saveUser(user, { requirePassword: false })\n }\n\n update = async (user: User) => {\n return await this.saveUser(user, { requirePassword: false })\n }\n\n remove = async (id: string) => {\n return await this.removeUser(id)\n }\n}\n\nexport const init = (config: ScimUserServiceConfig) => {\n service = new ScimUserService(config)\n}\n\nlet service: ScimUserService\n\nexport const get = (query: GetParams) => service.get(query)\nexport const find = (id: string) => service.find(id)\nexport const create = (user: User) => service.create(user)\nexport const update = (user: User) => service.update(user)\nexport const remove = (id: string) => service.remove(id)\n", "import backups from \"./backups\"\nimport { InitOpts } from \"../types\"\nimport { init as initScimUserService } from \"./scim/users\"\n\nexport const init = async (opts: InitOpts) => {\n if (opts.scimUserServiceConfig) {\n initScimUserService(opts.scimUserServiceConfig)\n }\n if (opts.backups) {\n await backups.init(opts.backups)\n }\n}\n", "export * as scimUsers from \"./users\"\n", "export * as branding from \"./branding\"\nexport * as licensing from \"./licensing\"\nexport * as quotas from \"./quotas\"\nexport * as users from \"./users\"\nexport * as automations from \"./automations\"\nexport * as features from \"./features\"\nexport * as groups from \"./groups\"\nexport * as plugins from \"./plugins\"\nexport * as environmentVariables from \"./environmentVariables\"\nexport * as auditLogs from \"./auditLogs\"\nexport { default as backups } from \"./backups\"\nexport * as utils from \"./utils\"\nexport * from \"./init\"\nexport * from \"./scim\"\n", "import { LicenseMiddlewareOptions } from \"../types\"\nimport { SELF_FREE_LICENSE } from \"../constants/licenses\"\nimport { env } from \"@budibase/backend-core\"\nimport { quotas, licensing as licenses } from \"../sdk\"\nimport { utils } from \"@budibase/backend-core\"\nimport { QuotaUsageType, StaticQuotaName } from \"@budibase/types\"\n\nconst licensing = (\n opts: LicenseMiddlewareOptions = {\n checkDayPasses: true,\n checkUsersLimit: true,\n refreshVersion: true,\n }\n) => {\n return async (ctx: any, next: any) => {\n const licensingCheck = opts.licensingCheck\n ? opts.licensingCheck\n : () => !!ctx.user\n\n if (licensingCheck(ctx)) {\n if (env.SELF_HOSTED && env.DEFAULT_LICENSE) {\n ctx.user.license = SELF_FREE_LICENSE\n return next()\n }\n\n // set the license on the current user\n ctx.user.license = await licenses.cache.getCachedLicense(ctx, {\n populateLicense: opts.populateLicense,\n populateFreeLicense: opts.populateFreeLicense,\n refreshVersion: opts.refreshVersion,\n })\n\n // check day passes for the current user\n if (opts.checkDayPasses) {\n await quotas.checkDayPass(ctx)\n }\n\n // check user limit for the current user\n if (\n opts.checkUsersLimit &&\n (utils.isServingApp(ctx) ||\n utils.isServingBuilder(ctx) ||\n utils.isServingBuilderPreview(ctx) ||\n utils.isPublicApiRequest(ctx))\n ) {\n await quotas.usageLimitIsExceeded(\n StaticQuotaName.USERS,\n QuotaUsageType.STATIC\n )\n }\n }\n\n return next()\n }\n}\n\nexport default licensing\n", "import { Next } from \"koa\"\nimport { Feature } from \"@budibase/types\"\nimport * as features from \"../sdk/features\"\n\nexport const requireFeature = (featureFlag: Feature) => {\n return async (ctx: any, next: Next) => {\n await features.checkFeature(featureFlag)\n await next()\n }\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { Next } from \"koa\"\n\nexport const doInScimContext = async (ctx: any, next: Next) => {\n await context.doInScimContext(next)\n}\n", "import { Next } from \"koa\"\nimport * as features from \"../sdk/features\"\n\nexport const requireSCIM = async (ctx: any, next: Next) => {\n await features.checkSCIM()\n await next()\n}\n", "export { default as licensing } from \"./licensing\"\nexport * as feature from \"./feature\"\nexport * from \"./doInScimContext\"\nexport * from \"./requireSCIM\"\n", "import {\n UserGroup,\n UserCtx,\n Ctx,\n SearchGroupRequest,\n SearchGroupResponse,\n SearchUserGroupResponse,\n DatabaseQueryOpts,\n} from \"@budibase/types\"\nimport * as groups from \"../../../sdk/groups\"\nimport { getGroupUsers } from \"../../../db/groups\"\n\nexport const save = async (ctx: UserCtx) => {\n const group: UserGroup = ctx.request.body\n group.name = group.name.trim()\n\n // don't allow updating the roles through this endpoint\n delete group.roles\n if (group._id) {\n const oldGroup = await groups.get(group._id)\n group.roles = oldGroup.roles\n }\n const response = await groups.save(group)\n ctx.body = {\n _id: response.id,\n _rev: response.rev,\n }\n}\n\nexport const updateGroupUsers = async (ctx: UserCtx) => {\n const groupId = ctx.params.id\n const toAdd = ctx.request.body.add,\n toRemove = ctx.request.body.remove\n if (\n (toAdd && !Array.isArray(toAdd)) ||\n (toRemove && !Array.isArray(toRemove))\n ) {\n ctx.throw(400, \"Must supply a list of users to add or to remove\")\n }\n let added, removed\n if (toAdd) {\n added = await groups.addUsers(groupId, toAdd)\n }\n if (toRemove) {\n removed = await groups.removeUsers(groupId, toRemove)\n }\n ctx.body = { added, removed }\n}\n\nexport const updateGroupApps = async (ctx: UserCtx) => {\n const groupId = ctx.params.id\n const toAdd = ctx.request.body.add,\n toRemove = ctx.request.body.remove\n if (\n (toAdd && !Array.isArray(toAdd)) ||\n (toRemove && !Array.isArray(toRemove))\n ) {\n ctx.throw(\n 400,\n \"Must supply a list of objects, with appId and roleId to add or remove\"\n )\n }\n ctx.body = await groups.updateGroupApps(groupId, {\n appsToAdd: toAdd,\n appsToRemove: toRemove,\n })\n}\n\nexport const fetch = async (\n ctx: Ctx<SearchGroupRequest, SearchGroupResponse>\n) => {\n ctx.body = { data: await groups.fetch() }\n}\n\nexport const destroy = async (ctx: UserCtx) => {\n const { id, rev } = ctx.params\n try {\n await groups.remove(id, rev)\n ctx.body = { message: \"Group deleted successfully\" }\n } catch (err: any) {\n ctx.throw(err.status, err)\n }\n}\n\n/**\n * Gets a group by ID from the global database.\n */\nexport const find = async (ctx: UserCtx) => {\n try {\n ctx.body = await groups.get(ctx.params.id)\n } catch (err: any) {\n ctx.throw(err.status, err)\n }\n}\n\nexport const searchUsers = async (ctx: Ctx<{}, SearchUserGroupResponse>) => {\n const { pageSize = 10, bookmark, emailSearch } = ctx.request.query as any\n const groupId = ctx.params.id\n\n const params: DatabaseQueryOpts = { limit: pageSize + 1 }\n\n const users = await getGroupUsers(groupId, {\n ...params,\n emailSearch,\n bookmark,\n })\n\n const nextBookmark = emailSearch\n ? users[pageSize]?.email\n : users[pageSize]?._id\n const hasNextPage = !!nextBookmark\n\n ctx.body = {\n users: users.slice(0, pageSize),\n bookmark: nextBookmark,\n hasNextPage,\n }\n}\n", "import {\n AppEnvironment,\n CreateEnvironmentVariableRequest,\n GetEnvironmentVariablesResponse,\n StatusEnvironmentVariableResponse,\n UpdateEnvironmentVariableRequest,\n UserCtx,\n} from \"@budibase/types\"\nimport { environmentVariables } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\n\nexport async function status(\n ctx: UserCtx<void, StatusEnvironmentVariableResponse>\n) {\n ctx.body = {\n encryptionKeyAvailable: environmentVariables.isEncryptionKeyAvailable(),\n }\n}\n\nexport async function fetch(\n ctx: UserCtx<void, GetEnvironmentVariablesResponse>\n) {\n ctx.body = {\n variables: await environmentVariables.fetch(),\n }\n}\n\nexport async function create(\n ctx: UserCtx<CreateEnvironmentVariableRequest, void>\n) {\n const { name, production, development } = ctx.request.body\n await environmentVariables.update(name, { production, development })\n const environments = [AppEnvironment.PRODUCTION]\n if (production !== development) {\n environments.push(AppEnvironment.DEVELOPMENT)\n }\n await events.environmentVariable.created(name, environments)\n ctx.status = 200\n}\n\nexport async function update(\n ctx: UserCtx<UpdateEnvironmentVariableRequest, void>\n) {\n const { production, development } = ctx.request.body\n const varName = ctx.params.varName\n await environmentVariables.update(varName, { production, development })\n ctx.status = 200\n}\n\nexport async function destroy(ctx: UserCtx<void, void>) {\n const varName = ctx.params.varName\n await environmentVariables.remove(varName)\n await events.environmentVariable.deleted(varName)\n ctx.status = 200\n}\n", "export * as groups from \"./groups\"\nexport * as environmentVariables from \"./environmentVariables\"\n", "import { groups } from \"../../controllers/global\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { feature } from \"../../../middleware\"\nimport { Feature } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction buildGroupSaveValidation() {\n return auth.joiValidator.body(\n Joi.object({\n _id: Joi.string().optional(),\n _rev: Joi.string().optional(),\n color: Joi.string().required(),\n icon: Joi.string().required(),\n name: Joi.string().trim().required().max(50),\n role: Joi.string().optional(),\n users: Joi.array().optional(),\n apps: Joi.array().optional(),\n roles: Joi.object().optional(),\n createdAt: Joi.string().optional(),\n updatedAt: Joi.string().optional(),\n }).required()\n )\n}\n\nrouter\n .post(\n \"/api/global/groups\",\n auth.adminOnly,\n feature.requireFeature(Feature.USER_GROUPS),\n buildGroupSaveValidation(),\n groups.save\n )\n .get(\n \"/api/global/groups\",\n feature.requireFeature(Feature.USER_GROUPS),\n groups.fetch\n )\n\n .delete(\n \"/api/global/groups/:id/:rev\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.destroy\n )\n .get(\n \"/api/global/groups/:id\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.find\n )\n .get(\n \"/api/global/groups/:id/users\",\n feature.requireFeature(Feature.USER_GROUPS),\n auth.adminOnly,\n groups.searchUsers\n )\n // these endpoints adjust existing groups\n .post(\n \"/api/global/groups/:id/users\",\n auth.adminOnly,\n feature.requireFeature(Feature.USER_GROUPS),\n groups.updateGroupUsers\n )\n .post(\n \"/api/global/groups/:id/apps\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.USER_GROUPS),\n groups.updateGroupApps\n )\n\nexport default router\n", "import * as controllers from \"../../controllers/global/environmentVariables\"\nimport { auth } from \"@budibase/backend-core\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\n\nconst router: Router = new Router()\n\nfunction buildEnvVarUpdateValidator() {\n return auth.joiValidator.body(\n Joi.object({\n name: Joi.string().optional(),\n production: Joi.string().required(),\n development: Joi.string().required(),\n })\n )\n}\n\nrouter\n .get(\"/api/env/variables/status\", auth.builderOrAdmin, controllers.status)\n .get(\"/api/env/variables\", auth.builderOrAdmin, controllers.fetch)\n .post(\n \"/api/env/variables\",\n auth.builderOrAdmin,\n buildEnvVarUpdateValidator(),\n controllers.create\n )\n .patch(\n \"/api/env/variables/:varName\",\n auth.builderOrAdmin,\n buildEnvVarUpdateValidator(),\n controllers.update\n )\n .delete(\n \"/api/env/variables/:varName\",\n auth.builderOrAdmin,\n controllers.destroy\n )\n\nexport default router\n", "import {\n SearchAuditLogsRequest,\n SearchAuditLogsResponse,\n DownloadAuditLogsRequest,\n DefinitionsAuditLogsResponse,\n AuditLogSearchParams,\n UserCtx,\n} from \"@budibase/types\"\nimport { auditLogs } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\nimport { Readable } from \"stream\"\n\nexport async function search(\n ctx: UserCtx<SearchAuditLogsRequest, SearchAuditLogsResponse>\n) {\n const search: AuditLogSearchParams = ctx.request.body\n const fetched = await auditLogs.fetch(search)\n await events.auditLog.filtered(search)\n ctx.body = fetched\n}\n\nexport async function download(\n ctx: UserCtx<DownloadAuditLogsRequest, Readable>\n) {\n const search: AuditLogSearchParams = ctx.request.body\n const { stream } = auditLogs.download(search)\n await events.auditLog.downloaded(search)\n ctx.attachment(`audit-logs-${Date.now()}.log`)\n ctx.body = stream\n}\n\nexport async function definitions(\n ctx: UserCtx<void, DefinitionsAuditLogsResponse>\n) {\n ctx.body = {\n events: auditLogs.definitions(),\n }\n}\n", "import * as controllers from \"../../controllers/global/auditLogs\"\nimport { Event } from \"@budibase/types\"\nimport { auth, middleware } from \"@budibase/backend-core\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\n\nfunction buildAuditLogSearchValidator() {\n return auth.joiValidator.body(\n Joi.object({\n userIds: Joi.array().items(Joi.string()).optional(),\n appIds: Joi.array().items(Joi.string()).optional(),\n events: Joi.array()\n .items(Joi.string().valid(...Object.values(Event)))\n .optional(),\n startDate: Joi.string().optional().allow(\"\"),\n endDate: Joi.string().optional().allow(\"\"),\n fullSearch: Joi.string().optional().allow(\"\"),\n bookmark: Joi.string().optional().allow(\"\"),\n })\n )\n}\n\nconst router: Router = new Router()\n\nrouter\n .post(\n \"/api/global/auditlogs/search\",\n auth.adminOnly,\n buildAuditLogSearchValidator(),\n controllers.search\n )\n .get(\n \"/api/global/auditlogs/download\",\n auth.adminOnly,\n // convert query string param to body\n middleware.querystringToBody,\n buildAuditLogSearchValidator(),\n controllers.download\n )\n .get(\n \"/api/global/auditlogs/definitions\",\n auth.adminOnly,\n controllers.definitions\n )\n\nexport default router\n", "import {\n CreateAppBackupRequest,\n SearchAppBackupsRequest,\n UpdateAppBackupRequest,\n AppBackupTrigger,\n UserCtx,\n} from \"@budibase/types\"\nimport { backups, utils } from \"../../../sdk\"\nimport { events } from \"@budibase/backend-core\"\nimport fs from \"fs\"\n\nasync function checkAppID(ctx: UserCtx, appId: string) {\n if (!(await utils.appExists(appId))) {\n ctx.throw(400, `Provided app ID: ${appId} - is invalid.`)\n }\n}\n\nexport async function manualBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const body = ctx.request.body as CreateAppBackupRequest\n const createdBy = ctx.user?._id\n const backupId = await backups.triggerAppBackup(\n appId,\n AppBackupTrigger.MANUAL,\n {\n name: body.name,\n createdBy,\n }\n )\n if (!backupId) {\n ctx.throw(500, \"Unable to start backup.\")\n }\n ctx.body = {\n backupId,\n message: \"Backup triggered - process starting.\",\n }\n}\n\nexport async function importBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const nameForBackup = ctx.request.body.name\n const response = await backups.triggerAppRestore(\n appId,\n backupId,\n nameForBackup,\n ctx.user?._id\n )\n if (!response) {\n ctx.throw(500, \"Unable to start restore.\")\n }\n await events.backup.appBackupRestored(response.metadata)\n ctx.body = {\n restoredId: response?.restoreId,\n message: \"Restore triggered - process starting.\",\n }\n}\n\nexport async function deleteBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n await backups.deleteAppBackup(backupId)\n ctx.body = {\n message: \"Backup deleted successfully.\",\n }\n}\n\nexport async function fetchBackups(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const body = ctx.request.body as SearchAppBackupsRequest\n if (body?.trigger) {\n body.trigger = body.trigger.toLowerCase() as AppBackupTrigger\n if (!Object.values(AppBackupTrigger).includes(body.trigger)) {\n ctx.throw(400, \"Provided trigger is not a valid option.\")\n }\n }\n ctx.body = await backups.fetchAppBackups(appId, {\n paginate: true,\n ...body,\n })\n}\n\nexport async function updateBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const body = ctx.request.body as UpdateAppBackupRequest\n ctx.body = await backups.updateAppBackup(backupId, body.name)\n}\n\nexport async function downloadBackup(ctx: UserCtx) {\n const appId = ctx.params.appId\n await checkAppID(ctx, appId)\n const backupId = ctx.params.backupId\n const { metadata, path } = await backups.downloadAppBackup(backupId)\n ctx.attachment(`backup-${metadata.timestamp}.tar.gz`)\n ctx.body = fs.createReadStream(path)\n}\n", "import * as backups from \"../../controllers/apps/backups\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { AppBackupTrigger, AppBackupType } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction validateBackupSearch() {\n return auth.joiValidator.body(\n Joi.object({\n trigger: Joi.string().valid(...Object.values(AppBackupTrigger)),\n type: Joi.string().valid(...Object.values(AppBackupType)),\n startDate: Joi.date(),\n endDate: Joi.date(),\n page: Joi.string(),\n })\n )\n}\n\nrouter\n .post(\"/api/apps/:appId/backups\", auth.builderOrAdmin, backups.manualBackup)\n .post(\n \"/api/apps/:appId/backups/search\",\n auth.builderOrAdmin,\n validateBackupSearch(),\n backups.fetchBackups\n )\n .get(\n \"/api/apps/:appId/backups/:backupId/file\",\n auth.builderOrAdmin,\n backups.downloadBackup\n )\n .patch(\n \"/api/apps/:appId/backups/:backupId\",\n auth.builderOrAdmin,\n backups.updateBackup\n )\n .delete(\n \"/api/apps/:appId/backups/:backupId\",\n auth.builderOrAdmin,\n backups.deleteBackup\n )\n .post(\n \"/api/apps/:appId/backups/:backupId/import\",\n auth.builderOrAdmin,\n backups.importBackup\n )\n\nexport default router\n", "import {\n BBContext,\n CreateScheduleRequest,\n UpdateScheduleRequest,\n} from \"@budibase/types\"\n\n/**\n * This file is a work in progress - to be filled out\n * in a future update.\n */\n\nexport function createSchedule(ctx: BBContext) {\n const body = ctx.body as CreateScheduleRequest\n ctx.status = 501\n}\n\nexport function fetchSchedules(ctx: BBContext) {\n const type = ctx.params.type\n ctx.status = 501\n}\n\nexport function updateSchedule(ctx: BBContext) {\n const scheduleId = ctx.params.scheduleId\n const body = ctx.body as UpdateScheduleRequest\n ctx.status = 501\n}\n\nexport function deleteSchedule(ctx: BBContext) {\n const scheduleId = ctx.params.scheduleId\n ctx.status = 501\n}\n", "import * as schedules from \"../../controllers/schedules\"\nimport Router from \"@koa/router\"\nimport Joi from \"joi\"\nimport { feature } from \"../../../middleware\"\nimport { Feature, ScheduleType, ScheduleRepeatPeriod } from \"@budibase/types\"\nimport { auth } from \"@budibase/backend-core\"\n\nconst router: Router = new Router()\n\nfunction validateSchedulesCreateOrUpdate() {\n return auth.joiValidator.body(\n Joi.object({\n type: Joi.string()\n .valid(...Object.keys(ScheduleType))\n .required(),\n name: Joi.string().required(),\n startDate: Joi.date().required(),\n repeat: Joi.string()\n .valid(...Object.keys(ScheduleRepeatPeriod))\n .required(),\n metadata: Joi.alternatives().conditional(\".type\", {\n switch: [\n {\n is: ScheduleType.APP_BACKUP,\n then: {\n apps: Joi.array().items(Joi.string()).required(),\n },\n },\n ],\n }),\n })\n )\n}\n\nrouter\n .get(\n \"/api/schedules/:type\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n schedules.fetchSchedules\n )\n .put(\n \"/api/schedules/:scheduleId\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n validateSchedulesCreateOrUpdate(),\n schedules.updateSchedule\n )\n .delete(\n \"/api/schedules/:scheduleId\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n schedules.deleteSchedule\n )\n .post(\n \"/api/schedules\",\n auth.builderOrAdmin,\n feature.requireFeature(Feature.APP_BACKUPS),\n validateSchedulesCreateOrUpdate(),\n schedules.createSchedule\n )\n\nexport default router\n", "import { patchBodyValidation, scimPatch } from \"scim-patch\"\nimport {\n Ctx,\n ScimUserListResponse,\n ScimCreateUserRequest,\n ScimUserResponse,\n ScimUpdateRequest,\n} from \"@budibase/types\"\nimport { mappers } from \"../../../../\"\nimport { scimUsers } from \"../../../../sdk\"\nimport { EmailUnavailableError } from \"@budibase/backend-core\"\n\nfunction tryGetQueryAsNumber(ctx: Ctx, name: string) {\n const value = ctx.request.query[name]\n if (value === undefined) {\n return undefined\n }\n\n return +value\n}\n\nexport const get = async (ctx: Ctx<void, ScimUserListResponse>) => {\n const pageSize = tryGetQueryAsNumber(ctx, \"pageSize\") ?? 20\n const skip = tryGetQueryAsNumber(ctx, \"startIndex\")\n\n let filters\n if (ctx.request.query.filter) {\n filters = mappers.user.userFilters(ctx.request.query.filter as string)\n }\n\n const getResponse = await scimUsers.get({ pageSize, skip, filters })\n ctx.body = {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n totalResults: getResponse.total,\n Resources: getResponse.users.map(mappers.user.toScimUserResponse),\n startIndex: (skip || 0) + 1,\n itemsPerPage: pageSize,\n }\n}\n\nexport const find = async (ctx: Ctx<void, ScimUserResponse>) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const user = await scimUsers.find(id)\n ctx.body = mappers.user.toScimUserResponse(user)\n}\n\nexport const create = async (\n ctx: Ctx<ScimCreateUserRequest, ScimUserResponse>\n) => {\n const userToCreate = mappers.user.fromScimUser(ctx.request.body)\n try {\n const user = await scimUsers.create(userToCreate)\n ctx.body = mappers.user.toScimUserResponse(user)\n } catch (e) {\n if (e instanceof EmailUnavailableError) {\n ctx.throw(409, \"Email already in use\")\n }\n\n throw e\n }\n}\n\nfunction isDeactivation(request: ScimUpdateRequest) {\n const activeFieldChange = request.Operations.find(\n o => (o.op === \"Replace\" || o.op === \"replace\") && o.path === \"active\"\n )\n if (!activeFieldChange) {\n return false\n }\n\n return (\n activeFieldChange.value === false ||\n activeFieldChange.value?.toLowerCase?.() === \"false\"\n )\n}\n\nexport const update = async (ctx: Ctx<ScimUpdateRequest, ScimUserResponse>) => {\n const user = await scimUsers.find(ctx.params.id)\n if (!user) {\n ctx.throw(404)\n }\n\n const scimUser = mappers.user.toScimUserResponse(user)\n\n const patchs = ctx.request.body\n try {\n patchBodyValidation(patchs)\n } catch (error) {\n // Here if there are an error in you SCIM request.\n }\n\n if (isDeactivation(patchs)) {\n return remove(ctx)\n }\n\n let patchedScimUser\n try {\n patchedScimUser = scimPatch(scimUser, patchs.Operations)\n } catch (error) {\n // Here if there is an error during the patch.\n }\n\n if (!patchedScimUser) {\n ctx.throw(500)\n }\n\n const userToUpdate = mappers.user.fromScimUser(patchedScimUser)\n await scimUsers.update(userToUpdate)\n\n ctx.body = mappers.user.toScimUserResponse(userToUpdate)\n}\n\nexport const remove = async (ctx: Ctx) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n await scimUsers.remove(id)\n ctx.status = 204\n}\n", "export const OperatorOptions = {\n Equals: {\n value: \"equal\",\n label: \"Equals\",\n },\n NotEquals: {\n value: \"notEqual\",\n label: \"Not equals\",\n },\n Empty: {\n value: \"empty\",\n label: \"Is empty\",\n },\n NotEmpty: {\n value: \"notEmpty\",\n label: \"Is not empty\",\n },\n StartsWith: {\n value: \"string\",\n label: \"Starts with\",\n },\n Like: {\n value: \"fuzzy\",\n label: \"Like\",\n },\n MoreThan: {\n value: \"rangeLow\",\n label: \"More than or equal to\",\n },\n LessThan: {\n value: \"rangeHigh\",\n label: \"Less than or equal to\",\n },\n Contains: {\n value: \"contains\",\n label: \"Contains\",\n },\n NotContains: {\n value: \"notContains\",\n label: \"Does not contain\",\n },\n In: {\n value: \"oneOf\",\n label: \"Is in\",\n },\n ContainsAny: {\n value: \"containsAny\",\n label: \"Has any\",\n },\n}\n\nexport const SqlNumberTypeRangeMap = {\n integer: {\n max: 2147483647,\n min: -2147483648,\n },\n int: {\n max: 2147483647,\n min: -2147483648,\n },\n smallint: {\n max: 32767,\n min: -32768,\n },\n mediumint: {\n max: 8388607,\n min: -8388608,\n },\n}\n", "/**\n * Gets a key within an object. The key supports dot syntax for retrieving deep\n * fields - e.g. \"a.b.c\".\n * Exact matches of keys with dots in them take precedence over nested keys of\n * the same path - e.g. getting \"a.b\" from { \"a.b\": \"foo\", a: { b: \"bar\" } }\n * will return \"foo\" over \"bar\".\n * @param obj the object\n * @param key the key\n * @return {*|null} the value or null if a value was not found for this key\n */\nexport const deepGet = (obj: { [x: string]: any }, key: string) => {\n if (!obj || !key) {\n return null\n }\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return obj[key]\n }\n const split = key.split(\".\")\n for (let i = 0; i < split.length; i++) {\n obj = obj?.[split[i]]\n }\n return obj\n}\n", "import { SourceName } from \"@budibase/types\"\n\nexport function isGoogleSheets(type: SourceName) {\n return type === SourceName.GOOGLE_SHEETS\n}\n", "export * from \"./helpers\"\nexport * from \"./integrations\"\n", "import { Datasource, FieldType, SortDirection, SortType } from \"@budibase/types\"\nimport { OperatorOptions, SqlNumberTypeRangeMap } from \"./constants\"\nimport { deepGet } from \"./helpers\"\n\nconst HBS_REGEX = /{{([^{].*?)}}/g\n\n/**\n * Returns the valid operator options for a certain data type\n * @param type the data type\n */\nexport const getValidOperatorsForType = (\n type: FieldType,\n field: string,\n datasource: Datasource & { tableId: any } // TODO: is this table id ever populated?\n) => {\n const Op = OperatorOptions\n const stringOps = [\n Op.Equals,\n Op.NotEquals,\n Op.StartsWith,\n Op.Like,\n Op.Empty,\n Op.NotEmpty,\n Op.In,\n ]\n const numOps = [\n Op.Equals,\n Op.NotEquals,\n Op.MoreThan,\n Op.LessThan,\n Op.Empty,\n Op.NotEmpty,\n Op.In,\n ]\n let ops: {\n value: string\n label: string\n }[] = []\n if (type === \"string\") {\n ops = stringOps\n } else if (type === \"number\") {\n ops = numOps\n } else if (type === \"options\") {\n ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In]\n } else if (type === \"array\") {\n ops = [Op.Contains, Op.NotContains, Op.Empty, Op.NotEmpty, Op.ContainsAny]\n } else if (type === \"boolean\") {\n ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty]\n } else if (type === \"longform\") {\n ops = stringOps\n } else if (type === \"datetime\") {\n ops = numOps\n } else if (type === \"formula\") {\n ops = stringOps.concat([Op.MoreThan, Op.LessThan])\n }\n\n // Only allow equal/not equal for _id in SQL tables\n const externalTable = datasource?.tableId?.includes(\"datasource_plus\")\n if (field === \"_id\" && externalTable) {\n ops = [Op.Equals, Op.NotEquals, Op.In]\n }\n\n return ops\n}\n\n/**\n * Operators which do not support empty strings as values\n */\nexport const NoEmptyFilterStrings = [\n OperatorOptions.StartsWith.value,\n OperatorOptions.Like.value,\n OperatorOptions.Equals.value,\n OperatorOptions.NotEquals.value,\n OperatorOptions.Contains.value,\n OperatorOptions.NotContains.value,\n] as (keyof QueryFields)[]\n\n/**\n * Removes any fields that contain empty strings that would cause inconsistent\n * behaviour with how backend tables are filtered (no value means no filter).\n */\nconst cleanupQuery = (query: Query) => {\n if (!query) {\n return query\n }\n for (let filterField of NoEmptyFilterStrings) {\n if (!query[filterField]) {\n continue\n }\n\n for (let [key, value] of Object.entries(query[filterField]!)) {\n if (value == null || value === \"\") {\n delete query[filterField]![key]\n }\n }\n }\n return query\n}\n\n/**\n * Removes a numeric prefix on field names designed to give fields uniqueness\n */\nconst removeKeyNumbering = (key: string) => {\n if (typeof key === \"string\" && key.match(/\\d[0-9]*:/g) != null) {\n const parts = key.split(\":\")\n parts.shift()\n return parts.join(\":\")\n } else {\n return key\n }\n}\n\ntype Filter = {\n operator: keyof Query\n field: string\n type: any\n value: any\n externalType: keyof typeof SqlNumberTypeRangeMap\n}\n\ntype Query = QueryFields & QueryConfig\ntype QueryFields = {\n string?: {\n [key: string]: string\n }\n fuzzy?: {\n [key: string]: string\n }\n range?: {\n [key: string]: {\n high: number | string\n low: number | string\n }\n }\n equal?: {\n [key: string]: any\n }\n notEqual?: {\n [key: string]: any\n }\n empty?: {\n [key: string]: any\n }\n notEmpty?: {\n [key: string]: any\n }\n oneOf?: {\n [key: string]: any[]\n }\n contains?: {\n [key: string]: any[]\n }\n notContains?: {\n [key: string]: any[]\n }\n containsAny?: {\n [key: string]: any[]\n }\n}\n\ntype QueryConfig = {\n allOr?: boolean\n}\n\ntype QueryFieldsType = keyof QueryFields\n\n/**\n * Builds a lucene JSON query from the filter structure generated in the builder\n * @param filter the builder filter structure\n */\nexport const buildLuceneQuery = (filter: Filter[]) => {\n let query: Query = {\n string: {},\n fuzzy: {},\n range: {},\n equal: {},\n notEqual: {},\n empty: {},\n notEmpty: {},\n contains: {},\n notContains: {},\n oneOf: {},\n containsAny: {},\n }\n if (Array.isArray(filter)) {\n filter.forEach(expression => {\n let { operator, field, type, value, externalType } = expression\n const isHbs =\n typeof value === \"string\" && (value.match(HBS_REGEX) || []).length > 0\n // Parse all values into correct types\n if (operator === \"allOr\") {\n query.allOr = true\n return\n }\n if (\n type === \"datetime\" &&\n !isHbs &&\n operator !== \"empty\" &&\n operator !== \"notEmpty\"\n ) {\n // Ensure date value is a valid date and parse into correct format\n if (!value) {\n return\n }\n try {\n value = new Date(value).toISOString()\n } catch (error) {\n return\n }\n }\n if (type === \"number\" && typeof value === \"string\") {\n if (operator === \"oneOf\") {\n value = value.split(\",\").map(item => parseFloat(item))\n } else if (!isHbs) {\n value = parseFloat(value)\n }\n }\n if (type === \"boolean\") {\n value = `${value}`?.toLowerCase() === \"true\"\n }\n if (\n [\"contains\", \"notContains\", \"containsAny\"].includes(operator) &&\n type === \"array\" &&\n typeof value === \"string\"\n ) {\n value = value.split(\",\")\n }\n if (operator.startsWith(\"range\") && query.range) {\n const minint =\n SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER\n const maxint =\n SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER\n if (!query.range[field]) {\n query.range[field] = {\n low: type === \"number\" ? minint : \"0000-00-00T00:00:00.000Z\",\n high: type === \"number\" ? maxint : \"9999-00-00T00:00:00.000Z\",\n }\n }\n if ((operator as any) === \"rangeLow\" && value != null && value !== \"\") {\n query.range[field].low = value\n } else if (\n (operator as any) === \"rangeHigh\" &&\n value != null &&\n value !== \"\"\n ) {\n query.range[field].high = value\n }\n } else if (query[operator]) {\n if (type === \"boolean\") {\n // Transform boolean filters to cope with null.\n // \"equals false\" needs to be \"not equals true\"\n // \"not equals false\" needs to be \"equals true\"\n if (operator === \"equal\" && value === false) {\n query.notEqual = query.notEqual || {}\n query.notEqual[field] = true\n } else if (operator === \"notEqual\" && value === false) {\n query.equal = query.equal || {}\n query.equal[field] = true\n } else {\n query[operator] = query[operator] || {}\n query[operator]![field] = value\n }\n } else {\n query[operator] = query[operator] || {}\n query[operator]![field] = value\n }\n }\n })\n }\n return query\n}\n\n/**\n * Performs a client-side lucene search on an array of data\n * @param docs the data\n * @param query the JSON lucene query\n */\nexport const runLuceneQuery = (docs: any[], query?: Query) => {\n if (!docs || !Array.isArray(docs)) {\n return []\n }\n if (!query) {\n return docs\n }\n\n // Make query consistent first\n query = cleanupQuery(query)\n\n // Iterates over a set of filters and evaluates a fail function against a doc\n const match =\n (\n type: QueryFieldsType,\n failFn: (docValue: any, testValue: any) => boolean\n ) =>\n (doc: any) => {\n const filters = Object.entries(query![type] || {})\n for (let i = 0; i < filters.length; i++) {\n const [key, testValue] = filters[i]\n const docValue = deepGet(doc, removeKeyNumbering(key))\n if (failFn(docValue, testValue)) {\n return false\n }\n }\n return true\n }\n\n // Process a string match (fails if the value does not start with the string)\n const stringMatch = match(\"string\", (docValue: string, testValue: string) => {\n return (\n !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase())\n )\n })\n\n // Process a fuzzy match (treat the same as starts with when running locally)\n const fuzzyMatch = match(\"fuzzy\", (docValue: string, testValue: string) => {\n return (\n !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase())\n )\n })\n\n // Process a range match\n const rangeMatch = match(\n \"range\",\n (\n docValue: string | number | null,\n testValue: { low: number; high: number }\n ) => {\n return (\n docValue == null ||\n docValue === \"\" ||\n +docValue < testValue.low ||\n +docValue > testValue.high\n )\n }\n )\n\n // Process an equal match (fails if the value is different)\n const equalMatch = match(\n \"equal\",\n (docValue: any, testValue: string | null) => {\n return testValue != null && testValue !== \"\" && docValue !== testValue\n }\n )\n\n // Process a not-equal match (fails if the value is the same)\n const notEqualMatch = match(\n \"notEqual\",\n (docValue: any, testValue: string | null) => {\n return testValue != null && testValue !== \"\" && docValue === testValue\n }\n )\n\n // Process an empty match (fails if the value is not empty)\n const emptyMatch = match(\"empty\", (docValue: string | null) => {\n return docValue != null && docValue !== \"\"\n })\n\n // Process a not-empty match (fails is the value is empty)\n const notEmptyMatch = match(\"notEmpty\", (docValue: string | null) => {\n return docValue == null || docValue === \"\"\n })\n\n // Process an includes match (fails if the value is not included)\n const oneOf = match(\"oneOf\", (docValue: any, testValue: any) => {\n if (typeof testValue === \"string\") {\n testValue = testValue.split(\",\")\n if (typeof docValue === \"number\") {\n testValue = testValue.map((item: string) => parseFloat(item))\n }\n }\n return !testValue?.includes(docValue)\n })\n\n const containsAny = match(\"containsAny\", (docValue: any, testValue: any) => {\n return !docValue?.includes(...testValue)\n })\n\n const contains = match(\n \"contains\",\n (docValue: string | any[], testValue: any[]) => {\n return !testValue?.every((item: any) => docValue?.includes(item))\n }\n )\n\n const notContains = match(\n \"notContains\",\n (docValue: string | any[], testValue: any[]) => {\n return testValue?.every((item: any) => docValue?.includes(item))\n }\n )\n\n // Match a document against all criteria\n const docMatch = (doc: any) => {\n return (\n stringMatch(doc) &&\n fuzzyMatch(doc) &&\n rangeMatch(doc) &&\n equalMatch(doc) &&\n notEqualMatch(doc) &&\n emptyMatch(doc) &&\n notEmptyMatch(doc) &&\n oneOf(doc) &&\n contains(doc) &&\n containsAny(doc) &&\n notContains(doc)\n )\n }\n\n // Process all docs\n return docs.filter(docMatch)\n}\n\n/**\n * Performs a client-side sort from the equivalent server-side lucene sort\n * parameters.\n * @param docs the data\n * @param sort the sort column\n * @param sortOrder the sort order (\"ascending\" or \"descending\")\n * @param sortType the type of sort (\"string\" or \"number\")\n */\nexport const luceneSort = (\n docs: any[],\n sort: string,\n sortOrder: SortDirection,\n sortType = SortType.STRING\n) => {\n if (!sort || !sortOrder || !sortType) {\n return docs\n }\n const parse =\n sortType === \"string\" ? (x: any) => `${x}` : (x: string) => parseFloat(x)\n return docs\n .slice()\n .sort((a: { [x: string]: any }, b: { [x: string]: any }) => {\n const colA = parse(a[sort])\n const colB = parse(b[sort])\n if (sortOrder.toLowerCase() === \"descending\") {\n return colA > colB ? -1 : 1\n } else {\n return colA > colB ? 1 : -1\n }\n })\n}\n\n/**\n * Limits the specified docs to the specified number of rows from the equivalent\n * server-side lucene limit parameters.\n * @param docs the data\n * @param limit the number of docs to limit to\n */\nexport const luceneLimit = (docs: any[], limit: string) => {\n const numLimit = parseFloat(limit)\n if (isNaN(numLimit)) {\n return docs\n }\n return docs.slice(0, numLimit)\n}\n", "export function unreachable(\n value: never,\n message = `No such case in exhaustive switch: ${value}`\n) {\n throw new Error(message)\n}\n", "export * from \"./constants\"\nexport * as dataFilters from \"./filters\"\nexport * as helpers from \"./helpers\"\nexport * as utils from \"./utils\"\n", "import _ from \"lodash\"\nimport {\n Ctx,\n ScimCreateGroupRequest,\n ScimGroupListResponse,\n ScimGroupResponse,\n ScimUpdateRequest,\n UserGroup,\n} from \"@budibase/types\"\nimport { utils } from \"@budibase/shared-core\"\nimport { patchBodyValidation, scimPatch } from \"scim-patch\"\nimport { groups, mappers, scimUsers } from \"../../../../\"\nimport { filter, parse } from \"scim2-parse-filter\"\n\nfunction cleanResponse(group: ScimGroupResponse, excludedAttributes: string) {\n for (const attr of (excludedAttributes as string).split(\",\")) {\n delete (group as any)[attr]\n }\n}\n\nexport const get = async (ctx: Ctx<void, ScimGroupListResponse>) => {\n const fetchedGroups = await groups.fetch()\n let result = fetchedGroups.map(mappers.group.toScimGroupResponse)\n\n const { filter: reqFilter, excludedAttributes } = ctx.request.query\n\n if (reqFilter) {\n const filterFunc = filter(parse(reqFilter as string))\n result = result.filter(filterFunc)\n }\n\n if (excludedAttributes) {\n result.forEach((g: any) => {\n cleanResponse(g, excludedAttributes as string)\n })\n }\n\n ctx.body = {\n schemas: [\"urn:ietf:params:scim:api:messages:2.0:ListResponse\"],\n totalResults: result.length,\n Resources: result,\n startIndex: 1,\n itemsPerPage: result.length,\n }\n}\n\nexport const create = async (\n ctx: Ctx<ScimCreateGroupRequest, ScimGroupResponse>\n) => {\n const groupToCreate = mappers.group.fromScimGroup(ctx.request.body)\n const createdGroup = await groups.save(groupToCreate)\n const group = await groups.get(createdGroup!.id)\n ctx.body = mappers.group.toScimGroupResponse(group)\n}\n\nexport const find = async (ctx: Ctx<void, ScimGroupResponse>) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const group = await groups.get(id)\n const response = mappers.group.toScimGroupResponse(group)\n\n const { excludedAttributes } = ctx.request.query\n if (excludedAttributes) {\n cleanResponse(response, excludedAttributes as string)\n }\n\n ctx.body = response\n}\n\nexport const remove = async (ctx: Ctx) => {\n const { id } = ctx.params\n if (typeof id !== \"string\") {\n ctx.throw(404)\n }\n\n const { _rev } = await groups.get(id)\n await groups.remove(id, _rev!)\n ctx.status = 204\n}\n\nexport const update = async (\n ctx: Ctx<ScimUpdateRequest, ScimGroupResponse>\n) => {\n const { id } = ctx.params\n const group = await groups.get(id)\n if (!group) {\n ctx.throw(404)\n }\n\n const scimGroup = mappers.group.toScimGroupResponse(group)\n\n const patchs = ctx.request.body\n try {\n // Validate request\n patchBodyValidation(patchs)\n } catch (error) {\n ctx.throw(400)\n }\n\n const { true: memberOps, false: fieldOps } = _.groupBy(\n patchs.Operations,\n p => p.path === \"members\"\n )\n\n if (fieldOps?.length) {\n const patchedScimGroup = scimPatch(scimGroup, fieldOps)\n if (!patchedScimGroup) {\n ctx.throw(500)\n }\n\n const groupToUpdate: UserGroup = {\n ...mappers.group.fromScimGroup(patchedScimGroup),\n _rev: group._rev,\n }\n await groups.save(groupToUpdate)\n }\n\n if (memberOps?.length) {\n const usersToAdd = []\n const usersToRemove = []\n for (const { op, value } of memberOps) {\n switch (op) {\n case \"add\":\n case \"Add\":\n for (const u of value) {\n usersToAdd.push(await scimUsers.find(u.value))\n }\n break\n case \"remove\":\n case \"Remove\":\n for (const u of value) {\n usersToRemove.push(await scimUsers.find(u.value))\n }\n break\n case \"replace\":\n case \"Replace\":\n throw new Error(\"Replacing members is not allowed\")\n default:\n utils.unreachable(op)\n }\n }\n\n if (usersToAdd.length) {\n await groups.addUsers(\n id,\n usersToAdd.map(u => u._id!)\n )\n }\n if (usersToRemove.length) {\n await groups.removeUsers(\n id,\n usersToRemove.map(u => u._id!)\n )\n }\n }\n\n ctx.body = mappers.group.toScimGroupResponse(await groups.get(id))\n}\n", "import Router from \"@koa/router\"\nimport { requireSCIM, doInScimContext } from \"../../../middleware\"\n\nimport * as userController from \"../../controllers/global/scim/users\"\nimport * as groupController from \"../../controllers/global/scim/groups\"\n\nconst router: Router = new Router({\n prefix: \"/api/global/scim/v2\",\n})\n\n// @ts-ignore - this produces a type error on account portal unit tests\nrouter.use(requireSCIM)\nrouter.use(doInScimContext)\n\nrouter.get(\"/users\", userController.get)\nrouter.get(\"/users/:id\", userController.find)\nrouter.post(\"/users\", userController.create)\nrouter.patch(\"/users/:id\", userController.update)\nrouter.delete(\"/users/:id\", userController.remove)\n\nrouter.get(\"/groups\", groupController.get)\nrouter.post(\"/groups\", groupController.create)\nrouter.get(\"/groups/:id\", groupController.find)\nrouter.delete(\"/groups/:id\", groupController.remove)\nrouter.patch(\"/groups/:id\", groupController.update)\n\nexport default router\n", "export { default as groups } from \"./routes/global/groups\"\nexport { default as environmentVariables } from \"./routes/global/environmentVariables\"\nexport { default as auditLogs } from \"./routes/global/auditLogs\"\nexport { default as appBackups } from \"./routes/apps/backups\"\nexport { default as schedules } from \"./routes/schedules\"\nexport { default as scim } from \"./routes/global/scim\"\n", "import {\n ScimUserResponse,\n ScimCreateUserRequest,\n User,\n UserStatus,\n} from \"@budibase/types\"\nimport { Filter, parse } from \"scim2-parse-filter\"\nimport { GetUsersFilters } from \"../sdk/scim/users\"\nimport { utils } from \"@budibase/backend-core\"\n\nexport const toScimUserResponse = (user: User): ScimUserResponse => {\n const { isSync, roles, ...scimInfo } = user.scimInfo || ({} as any)\n\n const response = {\n ...scimInfo,\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:User\"],\n id: user._id!,\n meta: {\n resourceType: \"User\",\n created: new Date(user.createdAt!),\n lastModified: new Date(user.updatedAt!),\n },\n active: user.status === UserStatus.ACTIVE,\n } as ScimUserResponse\n\n if (user.firstName || user.lastName) {\n response.name = {\n formatted: [user.firstName, user.lastName].filter(s => s).join(\" \"),\n familyName: user.lastName,\n givenName: user.firstName,\n }\n }\n\n return response\n}\n\nconst isScimUserResponse = (\n user: ScimUserResponse | ScimCreateUserRequest\n): user is ScimUserResponse => {\n return !!(user as ScimUserResponse)?.id\n}\n\nfunction tryGetEmail(\n user: ScimUserResponse | ScimCreateUserRequest\n): string | undefined {\n if (utils.validEmail(user.userName)) {\n return user.userName\n }\n\n if (!user.emails) {\n return undefined\n }\n\n return user.emails.find(x => x.primary)?.value || user.emails[0]?.value\n}\n\nexport const fromScimUser = (\n scimUser: ScimUserResponse | ScimCreateUserRequest\n): User => {\n const existingUser = isScimUserResponse(scimUser) ? scimUser : undefined\n\n const email = tryGetEmail(scimUser)\n if (!email) {\n throw new Error(\"Email is required\")\n }\n\n let isActive\n switch (scimUser.active) {\n case \"True\":\n case \"true\":\n case true:\n isActive = true\n break\n case \"False\":\n case \"false\":\n case false:\n isActive = false\n break\n default:\n ;(function unreachable(\n value: never,\n message = `No such case in exhaustive switch: ${value}`\n ) {\n throw new Error(message)\n })(scimUser.active)\n }\n\n const u: User = {\n // This is actually not required, but required in the types\n tenantId: \"\",\n _id: existingUser?.id,\n userId: existingUser?.id,\n email,\n firstName: scimUser.name?.givenName,\n lastName: scimUser.name?.familyName,\n scimInfo: {\n ...scimUser,\n isSync: true,\n },\n roles: {},\n status: isActive ? UserStatus.ACTIVE : UserStatus.INACTIVE,\n createdAt: existingUser?.meta.created.getTime(),\n updatedAt: existingUser?.meta.lastModified.toISOString(),\n }\n return u\n}\n\nexport const userFilters = (filter: string): GetUsersFilters => {\n const filters: GetUsersFilters = {\n equal: {},\n }\n\n const parsed = parse(filter)\n\n function parseFilters(filter: Filter) {\n switch (filter.op) {\n case \"eq\":\n const attribute = filter.attrPath\n let attributeToMap\n switch (attribute) {\n case \"emails.value\":\n attributeToMap = \"email\"\n break\n default:\n attributeToMap = `scimInfo.${attribute}`\n }\n\n filters.equal![attributeToMap] = filter.compValue\n break\n case \"and\":\n for (const f of filter.filters) {\n parseFilters(f)\n }\n break\n default:\n console.warn(\"Filter not handled\", { filter })\n }\n }\n\n parseFilters(parsed)\n\n return filters\n}\n", "import {\n ScimCreateGroupRequest,\n ScimGroupResponse,\n UserGroup,\n} from \"@budibase/types\"\n\nexport const toScimGroupResponse = (group: UserGroup): ScimGroupResponse => {\n return {\n schemas: [\"urn:ietf:params:scim:schemas:core:2.0:Group\"],\n id: group._id!,\n externalId: group.scimInfo!.externalId,\n meta: {\n resourceType: \"Group\",\n created: new Date(group.createdAt!),\n lastModified: new Date(group.updatedAt!),\n },\n displayName: group.name,\n members: group.users?.map(u => ({ value: u._id })),\n }\n}\n\nconst isScimGroup = (\n group: ScimGroupResponse | ScimCreateGroupRequest\n): group is ScimGroupResponse => {\n return !!(group as ScimGroupResponse)?.id\n}\n\nexport const fromScimGroup = (\n group: ScimGroupResponse | ScimCreateGroupRequest\n): UserGroup => {\n const existingGroup = isScimGroup(group) ? group : undefined\n\n const g: UserGroup = {\n _id: existingGroup?.id,\n name: group.displayName,\n scimInfo: {\n externalId: group.externalId,\n isSync: true,\n },\n icon: \"UserGroup\",\n color: \"var(--spectrum-global-color-blue-600)\",\n createdAt: existingGroup?.meta.created.getTime(),\n updatedAt: existingGroup?.meta.lastModified.toISOString(),\n }\n return g\n}\n", "export * as user from \"./users\"\nexport * as group from \"./groups\"\n", "export * from \"./types\"\nexport * from \"./sdk\"\nexport * as sdk from \"./sdk\"\nexport * as constants from \"./constants\"\nexport * as middleware from \"./middleware\"\nexport * as api from \"./api\"\nexport * as mappers from \"./mappers\"\n", "const { v4 } = require(\"uuid\")\n\nexport default function (): string {\n return v4().replace(/-/g, \"\")\n}\n", "import newid from \"./newid\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\ntype Optional = string | null\n\nexport const AppStatus = {\n DEV: \"development\",\n ALL: \"all\",\n DEPLOYED: \"published\",\n}\n\nexport const BudibaseInternalDB = {\n _id: \"bb_internal\",\n type: dbCore.BUDIBASE_DATASOURCE_TYPE,\n name: \"Budibase DB\",\n source: \"BUDIBASE\",\n config: {},\n}\n\nexport const SEPARATOR = dbCore.SEPARATOR\nexport const StaticDatabases = dbCore.StaticDatabases\nexport const DocumentType = dbCore.DocumentType\nexport const APP_PREFIX = dbCore.APP_PREFIX\nexport const APP_DEV_PREFIX = dbCore.APP_DEV_PREFIX\nexport const isDevAppID = dbCore.isDevAppID\nexport const isProdAppID = dbCore.isProdAppID\nexport const USER_METDATA_PREFIX = `${DocumentType.ROW}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`\nexport const LINK_USER_METADATA_PREFIX = `${DocumentType.LINK}${SEPARATOR}${dbCore.InternalTable.USER_METADATA}${SEPARATOR}`\nexport const TABLE_ROW_PREFIX = `${DocumentType.ROW}${SEPARATOR}${DocumentType.TABLE}`\nexport const AUTOMATION_LOG_PREFIX = `${DocumentType.AUTOMATION_LOG}${SEPARATOR}`\nexport const ViewName = dbCore.ViewName\nexport const InternalTables = dbCore.InternalTable\nexport const UNICODE_MAX = dbCore.UNICODE_MAX\nexport const generateAppID = dbCore.generateAppID\nexport const generateDevAppID = dbCore.getDevelopmentAppID\nexport const generateRoleID = dbCore.generateRoleID\nexport const getRoleParams = dbCore.getRoleParams\nexport const getQueryIndex = dbCore.getQueryIndex\nexport const getDocParams = dbCore.getDocParams\nexport const getRowParams = dbCore.getRowParams\nexport const generateRowID = dbCore.generateRowID\nexport const getUserMetadataParams = dbCore.getUserMetadataParams\nexport const generateUserMetadataID = dbCore.generateUserMetadataID\nexport const getGlobalIDFromUserMetadataID =\n dbCore.getGlobalIDFromUserMetadataID\n\n/**\n * Gets parameters for retrieving tables, this is a utility function for the getDocParams function.\n */\nexport function getTableParams(tableId?: Optional, otherProps = {}) {\n return getDocParams(DocumentType.TABLE, tableId, otherProps)\n}\n\n/**\n * Generates a new table ID.\n * @returns {string} The new table ID which the table doc can be stored under.\n */\nexport function generateTableID() {\n return `${DocumentType.TABLE}${SEPARATOR}${newid()}`\n}\n\n/**\n * Given a row ID this will find the table ID within it (only works for internal tables).\n * @param {string} rowId The ID of the row.\n * @returns {string} The table ID.\n */\nexport function getTableIDFromRowID(rowId: string) {\n const components = rowId\n .split(DocumentType.TABLE + SEPARATOR)[1]\n .split(SEPARATOR)\n return `${DocumentType.TABLE}${SEPARATOR}${components[0]}`\n}\n\n/**\n * Gets parameters for retrieving automations, this is a utility function for the getDocParams function.\n */\nexport function getAutomationParams(\n automationId?: Optional,\n otherProps: any = {}\n) {\n return getDocParams(DocumentType.AUTOMATION, automationId, otherProps)\n}\n\n/**\n * Generates a new automation ID.\n * @returns {string} The new automation ID which the automation doc can be stored under.\n */\nexport function generateAutomationID() {\n return `${DocumentType.AUTOMATION}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a new link doc ID. This is currently not usable with the alldocs call,\n * instead a view is built to make walking to tree easier.\n * @param {string} tableId1 The ID of the linker table.\n * @param {string} tableId2 The ID of the linked table.\n * @param {string} rowId1 The ID of the linker row.\n * @param {string} rowId2 The ID of the linked row.\n * @param {string} fieldName1 The name of the field in the linker row.\n * @param {string} fieldName2 the name of the field in the linked row.\n * @returns {string} The new link doc ID which the automation doc can be stored under.\n */\nexport function generateLinkID(\n tableId1: string,\n tableId2: string,\n rowId1: string,\n rowId2: string,\n fieldName1: string,\n fieldName2: string\n) {\n const tables = `${SEPARATOR}${tableId1}${SEPARATOR}${tableId2}`\n const rows = `${SEPARATOR}${rowId1}${SEPARATOR}${rowId2}`\n const fields = `${SEPARATOR}${fieldName1}${SEPARATOR}${fieldName2}`\n return `${DocumentType.LINK}${tables}${rows}${fields}`\n}\n\n/**\n * Gets parameters for retrieving link docs, this is a utility function for the getDocParams function.\n */\nexport function getLinkParams(otherProps: any = {}) {\n return getDocParams(DocumentType.LINK, null, otherProps)\n}\n\n/**\n * Generates a new layout ID.\n * @returns {string} The new layout ID which the layout doc can be stored under.\n */\nexport function generateLayoutID(id?: string) {\n return `${DocumentType.LAYOUT}${SEPARATOR}${id || newid()}`\n}\n\n/**\n * Gets parameters for retrieving layout, this is a utility function for the getDocParams function.\n */\nexport function getLayoutParams(layoutId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.LAYOUT, layoutId, otherProps)\n}\n\n/**\n * Generates a new screen ID.\n * @returns {string} The new screen ID which the screen doc can be stored under.\n */\nexport function generateScreenID() {\n return `${DocumentType.SCREEN}${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving screens, this is a utility function for the getDocParams function.\n */\nexport function getScreenParams(screenId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.SCREEN, screenId, otherProps)\n}\n\n/**\n * Generates a new webhook ID.\n * @returns {string} The new webhook ID which the webhook doc can be stored under.\n */\nexport function generateWebhookID() {\n return `${DocumentType.WEBHOOK}${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving a webhook, this is a utility function for the getDocParams function.\n */\nexport function getWebhookParams(webhookId?: Optional, otherProps: any = {}) {\n return getDocParams(DocumentType.WEBHOOK, webhookId, otherProps)\n}\n\n/**\n * Generates a new datasource ID.\n * @returns {string} The new datasource ID which the webhook doc can be stored under.\n */\nexport function generateDatasourceID({ plus = false } = {}) {\n return `${\n plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE\n }${SEPARATOR}${newid()}`\n}\n\n/**\n * Gets parameters for retrieving a datasource, this is a utility function for the getDocParams function.\n */\nexport function getDatasourceParams(\n datasourceId?: Optional,\n otherProps: any = {}\n) {\n return getDocParams(DocumentType.DATASOURCE, datasourceId, otherProps)\n}\n\n/**\n * Generates a new query ID.\n * @returns {string} The new query ID which the query doc can be stored under.\n */\nexport function generateQueryID(datasourceId: string) {\n return `${\n DocumentType.QUERY\n }${SEPARATOR}${datasourceId}${SEPARATOR}${newid()}`\n}\n\n/**\n * Generates a metadata ID for automations, used to track errors in recurring\n * automations etc.\n */\nexport function generateAutomationMetadataID(automationId: string) {\n return `${DocumentType.AUTOMATION_METADATA}${SEPARATOR}${automationId}`\n}\n\n/**\n * Retrieve all automation metadata in an app database.\n */\nexport function getAutomationMetadataParams(otherProps: any = {}) {\n return getDocParams(DocumentType.AUTOMATION_METADATA, null, otherProps)\n}\n\n/**\n * Gets parameters for retrieving a query, this is a utility function for the getDocParams function.\n */\nexport function getQueryParams(datasourceId?: Optional, otherProps: any = {}) {\n if (datasourceId == null) {\n return getDocParams(DocumentType.QUERY, null, otherProps)\n }\n\n return getDocParams(\n DocumentType.QUERY,\n `${datasourceId}${SEPARATOR}`,\n otherProps\n )\n}\n\n/**\n * Generates a new flag document ID.\n * @returns {string} The ID of the flag document that was generated.\n */\nexport function generateUserFlagID(userId: string) {\n return `${DocumentType.USER_FLAG}${SEPARATOR}${userId}`\n}\n\nexport function generateMetadataID(type: string, entityId: string) {\n return `${DocumentType.METADATA}${SEPARATOR}${type}${SEPARATOR}${entityId}`\n}\n\nexport function getMetadataParams(\n type: string,\n entityId?: Optional,\n otherProps: any = {}\n) {\n let docId = `${type}${SEPARATOR}`\n if (entityId != null) {\n docId += entityId\n }\n return getDocParams(DocumentType.METADATA, docId, otherProps)\n}\n\nexport function generateMemoryViewID(viewName: string) {\n return `${DocumentType.MEM_VIEW}${SEPARATOR}${viewName}`\n}\n\nexport function getMemoryViewParams(otherProps: any = {}) {\n return getDocParams(DocumentType.MEM_VIEW, null, otherProps)\n}\n\nexport function generatePluginID(name: string) {\n return `${DocumentType.PLUGIN}${SEPARATOR}${name}`\n}\n\n/**\n * This can be used with the db.allDocs to get a list of IDs\n */\nexport function getMultiIDParams(ids: string[]) {\n return {\n keys: ids,\n include_docs: true,\n }\n}\n", "import env from \"../environment\"\nimport { context } from \"@budibase/backend-core\"\nimport { generateMetadataID } from \"../db/utils\"\nimport { Document } from \"@budibase/types\"\nimport stream from \"stream\"\nconst Readable = stream.Readable\n\nexport function wait(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nexport const isDev = env.isDev\n\nexport const NUMBER_REGEX = /^[+-]?([0-9]*[.])?[0-9]+$/g\n\nexport function removeFromArray(array: any[], element: any) {\n const index = array.indexOf(element)\n if (index !== -1) {\n array.splice(index, 1)\n }\n return array\n}\n\n/**\n * Makes sure that a URL has the correct number of slashes, while maintaining the\n * http(s):// double slashes.\n * @param {string} url The URL to test and remove any extra double slashes.\n * @return {string} The updated url.\n */\nexport function checkSlashesInUrl(url: string) {\n return url.replace(/(https?:\\/\\/)|(\\/)+/g, \"$1$2\")\n}\n\nexport async function updateEntityMetadata(\n type: string,\n entityId: string,\n updateFn: any\n) {\n const db = context.getAppDB()\n const id = generateMetadataID(type, entityId)\n // read it to see if it exists, we'll overwrite it no matter what\n let rev, metadata: Document\n try {\n const oldMetadata = await db.get(id)\n rev = oldMetadata._rev\n metadata = updateFn(oldMetadata)\n } catch (err) {\n rev = null\n metadata = updateFn({})\n }\n metadata._id = id\n if (rev) {\n metadata._rev = rev\n }\n const response = await db.put(metadata)\n return {\n ...metadata,\n _id: id,\n _rev: response.rev,\n }\n}\n\nexport async function saveEntityMetadata(\n type: string,\n entityId: string,\n metadata: Document\n) {\n return updateEntityMetadata(type, entityId, () => {\n return metadata\n })\n}\n\nexport async function deleteEntityMetadata(type: string, entityId: string) {\n const db = context.getAppDB()\n const id = generateMetadataID(type, entityId)\n let rev\n try {\n const metadata = await db.get(id)\n if (metadata) {\n rev = metadata._rev\n }\n } catch (err) {\n // don't need to error if it doesn't exist\n }\n if (id && rev) {\n await db.remove(id, rev)\n }\n}\n\nexport function escapeDangerousCharacters(string: string) {\n return string\n .replace(/[\\\\]/g, \"\\\\\\\\\")\n .replace(/[\\b]/g, \"\\\\b\")\n .replace(/[\\f]/g, \"\\\\f\")\n .replace(/[\\n]/g, \"\\\\n\")\n .replace(/[\\r]/g, \"\\\\r\")\n .replace(/[\\t]/g, \"\\\\t\")\n}\n\nexport function stringToReadStream(string: string) {\n return new Readable({\n read() {\n this.push(string)\n this.push(null)\n },\n })\n}\n\nexport function formatBytes(bytes: string) {\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n const byteIncrements = 1024\n let unit = 0\n let size = parseInt(bytes, 10) || 0\n while (size >= byteIncrements && ++unit) {\n size /= byteIncrements\n }\n return `${size.toFixed(size < 10 && unit > 0 ? 1 : 0)}${units[unit]}`\n}\n\nexport function convertBookmark(bookmark: string) {\n const IS_NUMBER = /^\\d+\\.?\\d*$/\n if (typeof bookmark === \"string\" && bookmark.match(IS_NUMBER)) {\n return parseFloat(bookmark)\n }\n return bookmark\n}\n\nexport function isQsTrue(param: string) {\n if (typeof param === \"string\") {\n return param.toLowerCase() === \"true\"\n } else {\n return param === true\n }\n}\n", "import { objectStore, roles, constants } from \"@budibase/backend-core\"\nimport { FieldType as FieldTypes } from \"@budibase/types\"\nexport { FieldType as FieldTypes, RelationshipTypes } from \"@budibase/types\"\n\nexport enum FilterTypes {\n STRING = \"string\",\n FUZZY = \"fuzzy\",\n RANGE = \"range\",\n EQUAL = \"equal\",\n NOT_EQUAL = \"notEqual\",\n EMPTY = \"empty\",\n NOT_EMPTY = \"notEmpty\",\n CONTAINS = \"contains\",\n NOT_CONTAINS = \"notContains\",\n ONE_OF = \"oneOf\",\n}\n\nexport const NoEmptyFilterStrings = [\n FilterTypes.STRING,\n FilterTypes.FUZZY,\n FilterTypes.EQUAL,\n FilterTypes.NOT_EQUAL,\n FilterTypes.CONTAINS,\n FilterTypes.NOT_CONTAINS,\n]\n\nexport const CanSwitchTypes = [\n [FieldTypes.JSON, FieldTypes.ARRAY],\n [\n FieldTypes.STRING,\n FieldTypes.OPTIONS,\n FieldTypes.LONGFORM,\n FieldTypes.BARCODEQR,\n ],\n [FieldTypes.BOOLEAN, FieldTypes.NUMBER],\n]\n\nexport const SwitchableTypes = CanSwitchTypes.reduce((prev, current) =>\n prev ? prev.concat(current) : current\n)\n\nexport enum FormulaTypes {\n STATIC = \"static\",\n DYNAMIC = \"dynamic\",\n}\n\nexport enum AuthTypes {\n APP = \"app\",\n BUILDER = \"builder\",\n EXTERNAL = \"external\",\n}\n\nexport enum DataSourceOperation {\n CREATE = \"CREATE\",\n READ = \"READ\",\n UPDATE = \"UPDATE\",\n DELETE = \"DELETE\",\n BULK_CREATE = \"BULK_CREATE\",\n CREATE_TABLE = \"CREATE_TABLE\",\n UPDATE_TABLE = \"UPDATE_TABLE\",\n DELETE_TABLE = \"DELETE_TABLE\",\n}\n\nexport enum DatasourceAuthTypes {\n GOOGLE = \"google\",\n}\n\nexport enum SortDirection {\n ASCENDING = \"ASCENDING\",\n DESCENDING = \"DESCENDING\",\n}\n\nexport const USERS_TABLE_SCHEMA = {\n _id: \"ta_users\",\n type: \"table\",\n views: {},\n name: \"Users\",\n // TODO: ADMIN PANEL - when implemented this doesn't need to be carried out\n schema: {\n email: {\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n email: true,\n length: {\n maximum: \"\",\n },\n presence: true,\n },\n fieldName: \"email\",\n name: \"email\",\n },\n firstName: {\n name: \"firstName\",\n fieldName: \"firstName\",\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n },\n },\n lastName: {\n name: \"lastName\",\n fieldName: \"lastName\",\n type: FieldTypes.STRING,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n },\n },\n roleId: {\n fieldName: \"roleId\",\n name: \"roleId\",\n type: FieldTypes.OPTIONS,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n inclusion: Object.values(roles.BUILTIN_ROLE_IDS),\n },\n },\n status: {\n fieldName: \"status\",\n name: \"status\",\n type: FieldTypes.OPTIONS,\n constraints: {\n type: FieldTypes.STRING,\n presence: false,\n inclusion: Object.values(constants.UserStatus),\n },\n },\n },\n primaryDisplay: \"email\",\n}\n\nexport enum AutoFieldSubTypes {\n CREATED_BY = \"createdBy\",\n CREATED_AT = \"createdAt\",\n UPDATED_BY = \"updatedBy\",\n UPDATED_AT = \"updatedAt\",\n AUTO_ID = \"autoID\",\n}\n\nexport enum AutoFieldDefaultNames {\n CREATED_BY = \"Created By\",\n CREATED_AT = \"Created At\",\n UPDATED_BY = \"Updated By\",\n UPDATED_AT = \"Updated At\",\n AUTO_ID = \"Auto ID\",\n}\n\nexport const OBJ_STORE_DIRECTORY = \"/prod-budi-app-assets\"\nexport enum BaseQueryVerbs {\n CREATE = \"create\",\n READ = \"read\",\n UPDATE = \"update\",\n DELETE = \"delete\",\n}\n\nexport enum MetadataTypes {\n AUTOMATION_TEST_INPUT = \"automationTestInput\",\n AUTOMATION_TEST_HISTORY = \"automationTestHistory\",\n}\n\nexport enum InvalidColumns {\n ID = \"_id\",\n REV = \"_rev\",\n TABLE_ID = \"tableId\",\n}\n\nexport enum BuildSchemaErrors {\n NO_KEY = \"no_key\",\n INVALID_COLUMN = \"invalid_column\",\n}\n\nexport enum AutomationErrors {\n INCORRECT_TYPE = \"INCORRECT_TYPE\",\n MAX_ITERATIONS = \"MAX_ITERATIONS_REACHED\",\n FAILURE_CONDITION = \"FAILURE_CONDITION_MET\",\n}\n\n// pass through the list from the auth/core lib\nexport const ObjectStoreBuckets = objectStore.ObjectStoreBuckets\nexport const MAX_AUTOMATION_RECURRING_ERRORS = 5\nexport const GOOGLE_SHEETS_PRIMARY_KEY = \"rowNumber\"\n", "import { objectStore } from \"@budibase/backend-core\"\n\nexport const budibaseTempDir = objectStore.budibaseTempDir\n", "import path from \"path\"\n\n// this simply runs all of our path join and resolve functions through\n// a central location incase we need to add some protection to file paths\n\n/**\n * Exactly the same as path.join\n * @param args Any number of string arguments to add to a path\n * @returns {string} The final path ready to use\n */\nexport function join(...args: any) {\n return path.join(...args)\n}\n\n/**\n * Exactly the same as path.resolve\n * @param args Any number of string arguments to add to a path\n * @returns {string} The final path ready to use\n */\nexport function resolve(...args: any) {\n return path.resolve(...args)\n}\n", "import { PathLike } from \"fs\"\nimport fs from \"fs\"\nimport { budibaseTempDir } from \"../budibaseDir\"\nimport { join } from \"path\"\nimport env from \"../../environment\"\nimport tar from \"tar\"\nimport environment from \"../../environment\"\nconst uuid = require(\"uuid/v4\")\n\nexport const TOP_LEVEL_PATH =\n environment.TOP_LEVEL_PATH || join(__dirname, \"..\", \"..\", \"..\")\n\n/**\n * Upon first startup of instance there may not be everything we need in tmp directory, set it up.\n */\nexport const init = () => {\n const tempDir = budibaseTempDir()\n if (!fs.existsSync(tempDir)) {\n // some test cases fire this quickly enough that\n // synchronous cases can end up here at the same time\n try {\n fs.mkdirSync(tempDir)\n } catch (err: any) {\n if (!err || err.code !== \"EEXIST\") {\n throw err\n }\n }\n }\n}\n\n/**\n * Checks if the system is currently in development mode and if it is makes sure\n * everything required to function is ready.\n */\nexport const checkDevelopmentEnvironment = () => {\n if (!env.isDev() || env.isTest()) {\n return\n }\n if (!fs.existsSync(budibaseTempDir())) {\n fs.mkdirSync(budibaseTempDir())\n }\n let error\n if (!fs.existsSync(join(process.cwd(), \".env\"))) {\n error = \"Must run via yarn once to generate environment.\"\n }\n if (error) {\n console.error(error)\n process.exit(-1)\n }\n}\n\n/**\n * Used to retrieve a handlebars file from the system which will be used as a template.\n * This is allowable as the template handlebars files should be static and identical across\n * the cluster.\n * @param {string} path The path to the handlebars file which is to be loaded.\n * @returns {string} The loaded handlebars file as a string - loaded as utf8.\n */\nexport const loadHandlebarsFile = (path: PathLike) => {\n return fs.readFileSync(path, \"utf8\")\n}\n\n/**\n * When return a file from the API need to write the file to the system temporarily so we\n * can create a read stream to send.\n * @param {string} contents the contents of the file which is to be returned from the API.\n * @return {Object} the read stream which can be put into the koa context body.\n */\nexport const apiFileReturn = (contents: any) => {\n const path = join(budibaseTempDir(), uuid())\n fs.writeFileSync(path, contents)\n return fs.createReadStream(path)\n}\n\nexport const streamFile = (path: string) => {\n return fs.createReadStream(path)\n}\n\n/**\n * Writes the provided contents to a temporary file, which can be used briefly.\n * @param {string} fileContents contents which will be written to a temp file.\n * @return {string} the path to the temp file.\n */\nexport const storeTempFile = (fileContents: any) => {\n const path = join(budibaseTempDir(), uuid())\n fs.writeFileSync(path, fileContents)\n return path\n}\n\n/**\n * Utility function for getting a file read stream - a simple in memory buffered read\n * stream doesn't work for pouchdb.\n */\nexport const stringToFileStream = (contents: any) => {\n const path = storeTempFile(contents)\n return fs.createReadStream(path)\n}\n\n/**\n * Creates a temp file and returns it from the API.\n * @param {string} fileContents the contents to be returned in file.\n */\nexport const sendTempFile = (fileContents: any) => {\n const path = storeTempFile(fileContents)\n return fs.createReadStream(path)\n}\n\n/**\n * All file reads come through here just to make sure all of them make sense\n * allows a centralised location to check logic is all good.\n */\nexport const readFileSync = (filepath: PathLike, options = \"utf8\") => {\n // @ts-ignore\n return fs.readFileSync(filepath, options)\n}\n\nexport const createTempFolder = (item: any) => {\n const path = join(budibaseTempDir(), item)\n try {\n // remove old tmp directories automatically - don't combine\n if (fs.existsSync(path)) {\n fs.rmSync(path, { recursive: true, force: true })\n }\n fs.mkdirSync(path)\n } catch (err: any) {\n throw new Error(`Path cannot be created: ${err.message}`)\n }\n\n return path\n}\n\nexport const extractTarball = async (fromFilePath: string, toPath: string) => {\n await tar.extract({\n file: fromFilePath,\n C: toPath,\n })\n}\n\n/**\n * Find for a file recursively from start path applying filter, return first match\n */\nexport const findFileRec = (startPath: PathLike, filter: string): any => {\n if (!fs.existsSync(startPath)) {\n return\n }\n\n const files = fs.readdirSync(startPath)\n for (let i = 0, len = files.length; i < len; i++) {\n // @ts-ignore\n const filename = join(startPath, files[i])\n const stat = fs.lstatSync(filename)\n\n if (stat.isDirectory()) {\n return findFileRec(filename, filter)\n } else if (filename.endsWith(filter)) {\n return filename\n }\n }\n}\n\n/**\n * Remove a folder which is not empty from the file system\n */\nexport const deleteFolderFileSystem = (path: PathLike) => {\n if (!fs.existsSync(path)) {\n return\n }\n\n fs.rmSync(path, { recursive: true, force: true })\n}\n", "import path, { join } from \"path\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport fs from \"fs\"\nimport { objectStore } from \"@budibase/backend-core\"\nimport { resolve } from \"../centralPath\"\nimport env from \"../../environment\"\nimport { TOP_LEVEL_PATH } from \"./filesystem\"\n\nexport function devClientLibPath() {\n return require.resolve(\"@budibase/client\")\n}\n\n/**\n * Client library paths in the object store:\n * Previously, the entire client library package was downloaded from NPM\n * as a tarball and extracted to the object store, even though only the manifest\n * was ever needed. Therefore we need to support old apps which may still have\n * the manifest at this location for the first update.\n *\n * The new paths for the in-use version are:\n * {appId}/manifest.json\n * {appId}/budibase-client.js\n *\n * The paths for the backups are:\n * {appId}/manifest.json.bak\n * {appId}/budibase-client.js.bak\n *\n * We don't rely on NPM at all any more, as when updating to the latest version\n * we pull both the manifest and client bundle from the server's dependencies\n * in the local file system.\n */\n\n/**\n * Backs up the current client library version by copying both the manifest\n * and client bundle to .bak extensions in the object store. Only the one\n * previous version is stored as a backup, which can be reverted to.\n * @param appId The app ID to backup\n * @returns {Promise<void>}\n */\nexport async function backupClientLibrary(appId: string) {\n // Copy existing manifest to tmp\n let tmpManifestPath\n try {\n // Try to load the manifest from the new file location\n tmpManifestPath = await objectStore.retrieveToTmp(\n ObjectStoreBuckets.APPS,\n join(appId, \"manifest.json\")\n )\n } catch (error) {\n // Fallback to loading it from the old location for old apps\n tmpManifestPath = await objectStore.retrieveToTmp(\n ObjectStoreBuckets.APPS,\n join(\n appId,\n \"node_modules\",\n \"budibase\",\n \"standard-components\",\n \"package\",\n \"manifest.json\"\n )\n )\n }\n\n // Copy existing client lib to tmp\n const tmpClientPath = await objectStore.retrieveToTmp(\n ObjectStoreBuckets.APPS,\n join(appId, \"budibase-client.js\")\n )\n\n // Upload manifest and client library as backups\n const manifestUpload = objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n filename: join(appId, \"manifest.json.bak\"),\n path: tmpManifestPath,\n type: \"application/json\",\n })\n const clientUpload = objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n filename: join(appId, \"budibase-client.js.bak\"),\n path: tmpClientPath,\n type: \"application/javascript\",\n })\n await Promise.all([manifestUpload, clientUpload])\n}\n\n/**\n * Uploads the latest version of the component manifest and the client library\n * to the object store, overwriting the existing version.\n * @param appId The app ID to update\n * @returns {Promise<void>}\n */\nexport async function updateClientLibrary(appId: string) {\n let manifest, client\n\n if (env.isDev()) {\n const clientPath = devClientLibPath()\n // Load the symlinked version in dev which is always the newest\n manifest = join(path.dirname(path.dirname(clientPath)), \"manifest.json\")\n client = clientPath\n } else {\n // Load the bundled version in prod\n manifest = resolve(TOP_LEVEL_PATH, \"client\", \"manifest.json\")\n client = resolve(TOP_LEVEL_PATH, \"client\", \"budibase-client.js\")\n }\n\n // Upload latest manifest and client library\n const manifestUpload = objectStore.streamUpload(\n ObjectStoreBuckets.APPS,\n join(appId, \"manifest.json\"),\n fs.createReadStream(manifest),\n {\n ContentType: \"application/json\",\n }\n )\n const clientUpload = objectStore.streamUpload(\n ObjectStoreBuckets.APPS,\n join(appId, \"budibase-client.js\"),\n fs.createReadStream(client),\n {\n ContentType: \"application/javascript\",\n }\n )\n await Promise.all([manifestUpload, clientUpload])\n}\n\n/**\n * Reverts the version of the client library and manifest to the previously\n * used version for an app.\n * @param appId The app ID to revert\n * @returns {Promise<void>}\n */\nexport async function revertClientLibrary(appId: string) {\n // Copy backups manifest to tmp directory\n const tmpManifestPath = await objectStore.retrieveToTmp(\n ObjectStoreBuckets.APPS,\n join(appId, \"manifest.json.bak\")\n )\n\n // Copy backup client lib to tmp\n const tmpClientPath = await objectStore.retrieveToTmp(\n ObjectStoreBuckets.APPS,\n join(appId, \"budibase-client.js.bak\")\n )\n\n // Upload backups as new versions\n const manifestUpload = objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n filename: join(appId, \"manifest.json\"),\n path: tmpManifestPath,\n type: \"application/json\",\n })\n const clientUpload = objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n filename: join(appId, \"budibase-client.js\"),\n path: tmpClientPath,\n type: \"application/javascript\",\n })\n await Promise.all([manifestUpload, clientUpload])\n}\n", "import { budibaseTempDir } from \"../budibaseDir\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport { updateClientLibrary } from \"./clientLibrary\"\nimport env from \"../../environment\"\nimport { objectStore, context } from \"@budibase/backend-core\"\nimport { TOP_LEVEL_PATH } from \"./filesystem\"\n\nexport const NODE_MODULES_PATH = join(TOP_LEVEL_PATH, \"node_modules\")\n\n/**\n * Uploads the latest client library to the object store.\n * @param {string} appId The ID of the app which is being created.\n * @return {Promise<void>} once promise completes app resources should be ready in object store.\n */\nexport const createApp = async (appId: string) => {\n await updateClientLibrary(appId)\n}\n\n/**\n * Removes all of the assets created for an app in the object store.\n * @param {string} appId The ID of the app which is being deleted.\n * @return {Promise<void>} once promise completes the app resources will be removed from object store.\n */\nexport const deleteApp = async (appId: string) => {\n await objectStore.deleteFolder(ObjectStoreBuckets.APPS, `${appId}/`)\n}\n\n/**\n * Retrieves component libraries from object store (or tmp symlink if in local)\n */\nexport const getComponentLibraryManifest = async (library: string) => {\n const appId = context.getAppId()\n const filename = \"manifest.json\"\n\n if (env.isDev() || env.isTest()) {\n const path = join(TOP_LEVEL_PATH, \"packages/client\", filename)\n // always load from new so that updates are refreshed\n delete require.cache[require.resolve(path)]\n return require(path)\n }\n\n if (!appId) {\n throw new Error(\"No app ID found - cannot get component libraries\")\n }\n\n let resp\n let path\n try {\n // Try to load the manifest from the new file location\n path = join(appId, filename)\n resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path)\n } catch (error) {\n console.error(\n `component-manifest-objectstore=failed appId=${appId} path=${path}`,\n error\n )\n // Fallback to loading it from the old location for old apps\n path = join(appId, \"node_modules\", library, \"package\", filename)\n resp = await objectStore.retrieve(ObjectStoreBuckets.APPS, path)\n }\n if (typeof resp !== \"string\") {\n resp = resp.toString(\"utf8\")\n }\n return JSON.parse(resp)\n}\n\n/**\n * Given a set of app IDs makes sure file system is cleared of any of their temp info.\n */\nexport const cleanup = (appIds: string[]) => {\n for (let appId of appIds) {\n const path = join(budibaseTempDir(), appId)\n if (fs.existsSync(path)) {\n fs.rmdirSync(path, { recursive: true })\n }\n }\n}\n", "import { Plugin } from \"@budibase/types\"\nimport { budibaseTempDir } from \"../budibaseDir\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport { objectStore } from \"@budibase/backend-core\"\n\nconst DATASOURCE_PATH = join(budibaseTempDir(), \"datasource\")\nconst AUTOMATION_PATH = join(budibaseTempDir(), \"automation\")\n\nexport const getPluginMetadata = async (path: string) => {\n let metadata: any = {}\n try {\n const pkg = fs.readFileSync(join(path, \"package.json\"), \"utf8\")\n const schema = fs.readFileSync(join(path, \"schema.json\"), \"utf8\")\n\n metadata.schema = JSON.parse(schema)\n metadata.package = JSON.parse(pkg)\n\n if (\n !metadata.package.name ||\n !metadata.package.version ||\n !metadata.package.description\n ) {\n throw new Error(\n \"package.json is missing one of 'name', 'version' or 'description'.\"\n )\n }\n } catch (err: any) {\n throw new Error(\n `Unable to process schema.json/package.json in plugin. ${err.message}`\n )\n }\n\n return { metadata, directory: path }\n}\n\nasync function getPluginImpl(path: string, plugin: Plugin) {\n const hash = plugin.schema?.hash\n if (!fs.existsSync(path)) {\n fs.mkdirSync(path)\n }\n const filename = join(path, plugin.name)\n const metadataName = `${filename}.bbmetadata`\n if (fs.existsSync(filename)) {\n const currentHash = fs.readFileSync(metadataName, \"utf8\")\n // if hash is the same return the file, otherwise remove it and re-download\n if (currentHash === hash) {\n return require(filename)\n } else {\n console.log(`Updating plugin: ${plugin.name}`)\n delete require.cache[require.resolve(filename)]\n fs.unlinkSync(filename)\n }\n }\n const pluginKey = objectStore.getPluginJSKey(plugin)\n const pluginJs = await objectStore.retrieve(\n objectStore.ObjectStoreBuckets.PLUGINS,\n pluginKey\n )\n\n fs.writeFileSync(filename, pluginJs)\n fs.writeFileSync(metadataName, hash)\n\n return require(filename)\n}\n\nexport const getDatasourcePlugin = async (plugin: Plugin) => {\n return getPluginImpl(DATASOURCE_PATH, plugin)\n}\n\nexport const getAutomationPlugin = async (plugin: Plugin) => {\n return getPluginImpl(AUTOMATION_PATH, plugin)\n}\n", "import fs from \"fs\"\nimport { join } from \"path\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport { objectStore } from \"@budibase/backend-core\"\n\n/**\n * This function manages temporary template files which are stored by Koa.\n * @param {Object} template The template object retrieved from the Koa context object.\n * @returns {Object} Returns an fs read stream which can be loaded into the database.\n */\nexport const getTemplateStream = async (template: any) => {\n if (template.file) {\n return fs.createReadStream(template.file.path)\n } else {\n const [type, name] = template.key.split(\"/\")\n const tmpPath = await downloadTemplate(type, name)\n return fs.createReadStream(join(tmpPath, name, \"db\", \"dump.txt\"))\n }\n}\n\n/**\n * Retrieves a template and pipes it to minio as well as making it available temporarily.\n * @param {string} type The type of template which is to be retrieved.\n * @param name\n * @return {Promise<*>}\n */\nexport const downloadTemplate = async (type: string, name: string) => {\n const DEFAULT_TEMPLATES_BUCKET =\n \"prod-budi-templates.s3-eu-west-1.amazonaws.com\"\n const templateUrl = `https://${DEFAULT_TEMPLATES_BUCKET}/templates/${type}/${name}.tar.gz`\n return objectStore.downloadTarball(\n templateUrl,\n ObjectStoreBuckets.TEMPLATES,\n type\n )\n}\n", "export * from \"./app\"\nexport * from \"./clientLibrary\"\nexport * from \"./filesystem\"\nexport * from \"./plugin\"\nexport * from \"./template\"\n", "export const DB_EXPORT_FILE = \"db.txt\"\nexport const GLOBAL_DB_EXPORT_FILE = \"global.txt\"\nexport const STATIC_APP_FILES = [\"manifest.json\", \"budibase-client.js\"]\n", "import { db as dbCore, objectStore } from \"@budibase/backend-core\"\nimport { budibaseTempDir } from \"../../../utilities/budibaseDir\"\nimport { streamFile, createTempFolder } from \"../../../utilities/fileSystem\"\nimport { ObjectStoreBuckets } from \"../../../constants\"\nimport {\n AUTOMATION_LOG_PREFIX,\n LINK_USER_METADATA_PREFIX,\n TABLE_ROW_PREFIX,\n USER_METDATA_PREFIX,\n} from \"../../../db/utils\"\nimport {\n DB_EXPORT_FILE,\n GLOBAL_DB_EXPORT_FILE,\n STATIC_APP_FILES,\n} from \"./constants\"\nimport fs from \"fs\"\nimport { join } from \"path\"\nimport env from \"../../../environment\"\n\nconst uuid = require(\"uuid/v4\")\nconst tar = require(\"tar\")\nconst MemoryStream = require(\"memorystream\")\n\ninterface DBDumpOpts {\n filter?: any\n exportPath?: string\n}\n\ninterface ExportOpts extends DBDumpOpts {\n tar?: boolean\n excludeRows?: boolean\n excludeLogs?: boolean\n}\n\nfunction tarFilesToTmp(tmpDir: string, files: string[]) {\n const exportFile = join(budibaseTempDir(), `${uuid()}.tar.gz`)\n tar.create(\n {\n sync: true,\n gzip: true,\n file: exportFile,\n recursive: true,\n cwd: tmpDir,\n },\n files\n )\n return exportFile\n}\n\n/**\n * Exports a DB to either file or a variable (memory).\n * @param {string} dbName the DB which is to be exported.\n * @param {object} opts various options for the export, e.g. whether to stream,\n * a filter function or the name of the export.\n * @return {*} either a readable stream or a string\n */\nexport async function exportDB(dbName: string, opts: DBDumpOpts = {}) {\n const exportOpts = {\n filter: opts?.filter,\n batch_size: 1000,\n batch_limit: 5,\n style: \"main_only\",\n }\n return dbCore.doWithDB(dbName, async (db: any) => {\n // Write the dump to file if required\n if (opts?.exportPath) {\n const path = opts?.exportPath\n const writeStream = fs.createWriteStream(path)\n await db.dump(writeStream, exportOpts)\n return path\n } else {\n // Stringify the dump in memory if required\n const memStream = new MemoryStream()\n let appString = \"\"\n memStream.on(\"data\", (chunk: any) => {\n appString += chunk.toString()\n })\n await db.dump(memStream, exportOpts)\n return appString\n }\n })\n}\n\nfunction defineFilter(excludeRows?: boolean, excludeLogs?: boolean) {\n const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX]\n if (excludeRows) {\n ids.push(TABLE_ROW_PREFIX)\n }\n if (excludeLogs) {\n ids.push(AUTOMATION_LOG_PREFIX)\n }\n return (doc: any) =>\n !ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr)\n}\n\n/**\n * Local utility to back up the database state for an app, excluding global user\n * data or user relationships.\n * @param {string} appId The app to back up\n * @param {object} config Config to send to export DB/attachment export\n * @returns {*} either a string or a stream of the backup\n */\nexport async function exportApp(appId: string, config?: ExportOpts) {\n const prodAppId = dbCore.getProdAppID(appId)\n const appPath = `${prodAppId}/`\n // export bucket contents\n let tmpPath = createTempFolder(uuid())\n if (!env.isTest()) {\n // write just the static files\n if (config?.excludeRows) {\n for (let path of STATIC_APP_FILES) {\n const contents = await objectStore.retrieve(\n ObjectStoreBuckets.APPS,\n join(appPath, path)\n )\n fs.writeFileSync(join(tmpPath, path), contents)\n }\n }\n // get all of the files\n else {\n tmpPath = await objectStore.retrieveDirectory(\n ObjectStoreBuckets.APPS,\n appPath\n )\n }\n }\n const downloadedPath = join(tmpPath, appPath)\n if (fs.existsSync(downloadedPath)) {\n const allFiles = fs.readdirSync(downloadedPath)\n for (let file of allFiles) {\n const path = join(downloadedPath, file)\n // move out of app directory, simplify structure\n fs.renameSync(path, join(downloadedPath, \"..\", file))\n }\n // remove the old app directory created by object export\n fs.rmdirSync(downloadedPath)\n }\n // enforce an export of app DB to the tmp path\n const dbPath = join(tmpPath, DB_EXPORT_FILE)\n await exportDB(appId, {\n filter: defineFilter(config?.excludeRows, config?.excludeLogs),\n exportPath: dbPath,\n })\n // if tar requested, return where the tarball is\n if (config?.tar) {\n // now the tmpPath contains both the DB export and attachments, tar this\n const tarPath = tarFilesToTmp(tmpPath, fs.readdirSync(tmpPath))\n // cleanup the tmp export files as tarball returned\n fs.rmSync(tmpPath, { recursive: true, force: true })\n return tarPath\n }\n // tar not requested, turn the directory where export is\n else {\n return tmpPath\n }\n}\n\n/**\n * Streams a backup of the database state for an app\n * @param {string} appId The ID of the app which is to be backed up.\n * @param {boolean} excludeRows Flag to state whether the export should include data.\n * @returns {*} a readable stream of the backup which is written in real time\n */\nexport async function streamExportApp(appId: string, excludeRows: boolean) {\n const tmpPath = await exportApp(appId, {\n excludeRows,\n excludeLogs: true,\n tar: true,\n })\n return streamFile(tmpPath)\n}\n", "import { db as dbCore, objectStore } from \"@budibase/backend-core\"\nimport { Database, Row } from \"@budibase/types\"\nimport { getAutomationParams, TABLE_ROW_PREFIX } from \"../../../db/utils\"\nimport { budibaseTempDir } from \"../../../utilities/budibaseDir\"\nimport { DB_EXPORT_FILE, GLOBAL_DB_EXPORT_FILE } from \"./constants\"\nimport { downloadTemplate } from \"../../../utilities/fileSystem\"\nimport { ObjectStoreBuckets } from \"../../../constants\"\nimport { join } from \"path\"\nimport fs from \"fs\"\nimport sdk from \"../../\"\nimport {\n Automation,\n AutomationTriggerStepId,\n RowAttachment,\n} from \"@budibase/types\"\nconst uuid = require(\"uuid/v4\")\nconst tar = require(\"tar\")\n\ntype TemplateType = {\n file?: {\n type: string\n path: string\n }\n key?: string\n}\n\nfunction rewriteAttachmentUrl(appId: string, attachment: RowAttachment) {\n // URL looks like: /prod-budi-app-assets/appId/attachments/file.csv\n const urlParts = attachment.key.split(\"/\")\n // remove the app ID\n urlParts.shift()\n // add new app ID\n urlParts.unshift(appId)\n const key = urlParts.join(\"/\")\n return {\n ...attachment,\n key,\n url: \"\", // calculated on retrieval using key\n }\n}\n\nexport async function updateAttachmentColumns(prodAppId: string, db: Database) {\n // iterate through attachment documents and update them\n const tables = await sdk.tables.getAllInternalTables(db)\n let updatedRows: Row[] = []\n for (let table of tables) {\n const { rows, columns } = await sdk.rows.getRowsWithAttachments(\n db.name,\n table\n )\n updatedRows = updatedRows.concat(\n rows.map(row => {\n for (let column of columns) {\n if (Array.isArray(row[column])) {\n row[column] = row[column].map((attachment: RowAttachment) =>\n rewriteAttachmentUrl(prodAppId, attachment)\n )\n }\n }\n return row\n })\n )\n }\n // write back the updated attachments\n await db.bulkDocs(updatedRows)\n}\n\nasync function updateAutomations(prodAppId: string, db: Database) {\n const automations = (\n await db.allDocs(\n getAutomationParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc) as Automation[]\n const devAppId = dbCore.getDevAppID(prodAppId)\n let toSave: Automation[] = []\n for (let automation of automations) {\n const oldDevAppId = automation.appId,\n oldProdAppId = dbCore.getProdAppID(automation.appId)\n if (\n automation.definition.trigger?.stepId === AutomationTriggerStepId.WEBHOOK\n ) {\n const old = automation.definition.trigger.inputs\n automation.definition.trigger.inputs = {\n schemaUrl: old.schemaUrl.replace(oldDevAppId, devAppId),\n triggerUrl: old.triggerUrl.replace(oldProdAppId, prodAppId),\n }\n }\n automation.appId = devAppId\n toSave.push(automation)\n }\n await db.bulkDocs(toSave)\n}\n\n/**\n * This function manages temporary template files which are stored by Koa.\n * @param {Object} template The template object retrieved from the Koa context object.\n * @returns {Object} Returns a fs read stream which can be loaded into the database.\n */\nasync function getTemplateStream(template: TemplateType) {\n if (template.file && template.file.type !== \"text/plain\") {\n throw new Error(\"Cannot import a non-text based file.\")\n }\n if (template.file) {\n return fs.createReadStream(template.file.path)\n } else if (template.key) {\n const [type, name] = template.key.split(\"/\")\n const tmpPath = await downloadTemplate(type, name)\n return fs.createReadStream(join(tmpPath, name, \"db\", \"dump.txt\"))\n }\n}\n\nexport function untarFile(file: { path: string }) {\n const tmpPath = join(budibaseTempDir(), uuid())\n fs.mkdirSync(tmpPath)\n // extract the tarball\n tar.extract({\n sync: true,\n cwd: tmpPath,\n file: file.path,\n })\n return tmpPath\n}\n\nexport function getGlobalDBFile(tmpPath: string) {\n return fs.readFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), \"utf8\")\n}\n\nexport function getListOfAppsInMulti(tmpPath: string) {\n return fs.readdirSync(tmpPath).filter(dir => dir !== GLOBAL_DB_EXPORT_FILE)\n}\n\nexport async function importApp(\n appId: string,\n db: Database,\n template: TemplateType\n) {\n let prodAppId = dbCore.getProdAppID(appId)\n let dbStream: any\n const isTar = template.file && template?.file?.type?.endsWith(\"gzip\")\n const isDirectory =\n template.file && fs.lstatSync(template.file.path).isDirectory()\n if (template.file && (isTar || isDirectory)) {\n const tmpPath = isTar ? untarFile(template.file) : template.file.path\n const contents = fs.readdirSync(tmpPath)\n // have to handle object import\n if (contents.length) {\n let promises = []\n let excludedFiles = [GLOBAL_DB_EXPORT_FILE, DB_EXPORT_FILE]\n for (let filename of contents) {\n const path = join(tmpPath, filename)\n if (excludedFiles.includes(filename)) {\n continue\n }\n filename = join(prodAppId, filename)\n if (fs.lstatSync(path).isDirectory()) {\n promises.push(\n objectStore.uploadDirectory(ObjectStoreBuckets.APPS, path, filename)\n )\n } else {\n promises.push(\n objectStore.upload({\n bucket: ObjectStoreBuckets.APPS,\n path,\n filename,\n })\n )\n }\n }\n await Promise.all(promises)\n }\n dbStream = fs.createReadStream(join(tmpPath, DB_EXPORT_FILE))\n } else {\n dbStream = await getTemplateStream(template)\n }\n // @ts-ignore\n const { ok } = await db.load(dbStream)\n if (!ok) {\n throw \"Error loading database dump from template.\"\n }\n await updateAttachmentColumns(prodAppId, db)\n await updateAutomations(prodAppId, db)\n return ok\n}\n", "import { context, db as dbCore } from \"@budibase/backend-core\"\nimport { Database } from \"@budibase/types\"\nimport {\n getDatasourceParams,\n getTableParams,\n getAutomationParams,\n getScreenParams,\n} from \"../../../db/utils\"\n\nasync function runInContext(appId: string, cb: any, db?: Database) {\n if (db) {\n return cb(db)\n } else {\n const devAppId = dbCore.getDevAppID(appId)\n return context.doInAppContext(devAppId, () => {\n const db = context.getAppDB()\n return cb(db)\n })\n }\n}\n\nexport async function calculateDatasourceCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const datasourceList = await db.allDocs(getDatasourceParams())\n const tableList = await db.allDocs(getTableParams())\n return datasourceList.rows.length + tableList.rows.length\n },\n db\n )\n}\n\nexport async function calculateAutomationCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const automationList = await db.allDocs(getAutomationParams())\n return automationList.rows.length\n },\n db\n )\n}\n\nexport async function calculateScreenCount(appId: string, db?: Database) {\n return runInContext(\n appId,\n async (db: Database) => {\n const screenList = await db.allDocs(getScreenParams())\n return screenList.rows.length\n },\n db\n )\n}\n\nexport async function calculateBackupStats(appId: string) {\n return runInContext(appId, async (db: Database) => {\n const promises = []\n promises.push(calculateDatasourceCount(appId, db))\n promises.push(calculateAutomationCount(appId, db))\n promises.push(calculateScreenCount(appId, db))\n const responses = await Promise.all(promises)\n return {\n datasources: responses[0],\n automations: responses[1],\n screens: responses[2],\n }\n })\n}\n", "import * as exportApps from \"./exports\"\nimport * as importApps from \"./imports\"\nimport * as statistics from \"./statistics\"\n\nexport default {\n ...exportApps,\n ...importApps,\n ...statistics,\n}\n", "import { SourceName, SqlQuery, Datasource, Table } from \"@budibase/types\"\nimport { DocumentType, SEPARATOR } from \"../db/utils\"\nimport { FieldTypes, BuildSchemaErrors, InvalidColumns } from \"../constants\"\n\nconst DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`\nconst ROW_ID_REGEX = /^\\[.*]$/g\nconst ENCODED_SPACE = encodeURIComponent(\" \")\n\nconst SQL_NUMBER_TYPE_MAP = {\n integer: FieldTypes.NUMBER,\n int: FieldTypes.NUMBER,\n decimal: FieldTypes.NUMBER,\n smallint: FieldTypes.NUMBER,\n real: FieldTypes.NUMBER,\n float: FieldTypes.NUMBER,\n numeric: FieldTypes.NUMBER,\n mediumint: FieldTypes.NUMBER,\n dec: FieldTypes.NUMBER,\n double: FieldTypes.NUMBER,\n fixed: FieldTypes.NUMBER,\n \"double precision\": FieldTypes.NUMBER,\n number: FieldTypes.NUMBER,\n binary_float: FieldTypes.NUMBER,\n binary_double: FieldTypes.NUMBER,\n money: FieldTypes.NUMBER,\n smallmoney: FieldTypes.NUMBER,\n}\n\nconst SQL_DATE_TYPE_MAP = {\n timestamp: FieldTypes.DATETIME,\n time: FieldTypes.DATETIME,\n datetime: FieldTypes.DATETIME,\n smalldatetime: FieldTypes.DATETIME,\n date: FieldTypes.DATETIME,\n}\n\nconst SQL_DATE_ONLY_TYPES = [\"date\"]\nconst SQL_TIME_ONLY_TYPES = [\"time\"]\n\nconst SQL_STRING_TYPE_MAP = {\n varchar: FieldTypes.STRING,\n char: FieldTypes.STRING,\n nchar: FieldTypes.STRING,\n nvarchar: FieldTypes.STRING,\n ntext: FieldTypes.STRING,\n enum: FieldTypes.STRING,\n blob: FieldTypes.STRING,\n long: FieldTypes.STRING,\n text: FieldTypes.STRING,\n bigint: FieldTypes.STRING,\n}\n\nconst SQL_BOOLEAN_TYPE_MAP = {\n boolean: FieldTypes.BOOLEAN,\n bit: FieldTypes.BOOLEAN,\n tinyint: FieldTypes.BOOLEAN,\n}\n\nconst SQL_MISC_TYPE_MAP = {\n json: FieldTypes.JSON,\n}\n\nconst SQL_TYPE_MAP = {\n ...SQL_NUMBER_TYPE_MAP,\n ...SQL_DATE_TYPE_MAP,\n ...SQL_STRING_TYPE_MAP,\n ...SQL_BOOLEAN_TYPE_MAP,\n ...SQL_MISC_TYPE_MAP,\n}\n\nexport enum SqlClient {\n MS_SQL = \"mssql\",\n POSTGRES = \"pg\",\n MY_SQL = \"mysql2\",\n ORACLE = \"oracledb\",\n}\n\nexport function isExternalTable(tableId: string) {\n return tableId.includes(DocumentType.DATASOURCE)\n}\n\nexport function buildExternalTableId(datasourceId: string, tableName: string) {\n // encode spaces\n if (tableName.includes(\" \")) {\n tableName = encodeURIComponent(tableName)\n }\n return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`\n}\n\nexport function breakExternalTableId(tableId: string | undefined) {\n if (!tableId) {\n return {}\n }\n const parts = tableId.split(DOUBLE_SEPARATOR)\n let datasourceId = parts.shift()\n // if they need joined\n let tableName = parts.join(DOUBLE_SEPARATOR)\n // if contains encoded spaces, decode it\n if (tableName.includes(ENCODED_SPACE)) {\n tableName = decodeURIComponent(tableName)\n }\n return { datasourceId, tableName }\n}\n\nexport function generateRowIdField(keyProps: any[] = []) {\n if (!Array.isArray(keyProps)) {\n keyProps = [keyProps]\n }\n // this conserves order and types\n // we have to swap the double quotes to single quotes for use in HBS statements\n // when using the literal helper the double quotes can break things\n return encodeURIComponent(JSON.stringify(keyProps).replace(/\"/g, \"'\"))\n}\n\nexport function isRowId(field: any) {\n return (\n Array.isArray(field) ||\n (typeof field === \"string\" && field.match(ROW_ID_REGEX) != null)\n )\n}\n\nexport function convertRowId(field: any) {\n if (Array.isArray(field)) {\n return field[0]\n }\n if (typeof field === \"string\" && field.match(ROW_ID_REGEX) != null) {\n return field.substring(1, field.length - 1)\n }\n return field\n}\n\n// should always return an array\nexport function breakRowIdField(_id: string | { _id: string }): any[] {\n if (!_id) {\n return []\n }\n // have to replace on the way back as we swapped out the double quotes\n // when encoding, but JSON can't handle the single quotes\n const id = typeof _id === \"string\" ? _id : _id._id\n const decoded: string = decodeURIComponent(id).replace(/'/g, '\"')\n try {\n const parsed = JSON.parse(decoded)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch (err) {\n // wasn't json - likely was handlebars for a many to many\n return [_id]\n }\n}\n\nexport function convertSqlType(type: string) {\n let foundType = FieldTypes.STRING\n const lcType = type.toLowerCase()\n let matchingTypes = []\n for (let [external, internal] of Object.entries(SQL_TYPE_MAP)) {\n if (lcType.includes(external)) {\n matchingTypes.push({ external, internal })\n }\n }\n //Set the foundType based the longest match\n if (matchingTypes.length > 0) {\n foundType = matchingTypes.reduce((acc, val) => {\n return acc.external.length >= val.external.length ? acc : val\n }).internal\n }\n const schema: any = { type: foundType }\n if (foundType === FieldTypes.DATETIME) {\n schema.dateOnly = SQL_DATE_ONLY_TYPES.includes(lcType)\n schema.timeOnly = SQL_TIME_ONLY_TYPES.includes(lcType)\n }\n return schema\n}\n\nexport function getSqlQuery(query: SqlQuery | string): SqlQuery {\n if (typeof query === \"string\") {\n return { sql: query }\n } else {\n return query\n }\n}\n\nexport function isSQL(datasource: Datasource): boolean {\n if (!datasource || !datasource.source) {\n return false\n }\n const SQL = [\n SourceName.POSTGRES,\n SourceName.SQL_SERVER,\n SourceName.MYSQL,\n SourceName.ORACLE,\n ]\n return SQL.indexOf(datasource.source) !== -1\n}\n\nexport function isIsoDateString(str: string) {\n if (!/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}Z/.test(str)) {\n return false\n }\n let d = new Date(str)\n return d.toISOString() === str\n}\n\n/**\n * This function will determine whether a column is a relationship and whether it\n * is currently valid. The reason for the validity check is that tables can be deleted\n * outside of Budibase control and if this is the case it will break Budibase relationships.\n * The tableIds is a list passed down from the main finalise tables function, which is\n * based on the tables that have just been fetched. This will only really be used on subsequent\n * fetches to the first one - if the user is periodically refreshing Budibase knowledge of tables.\n * @param column The column to check, to see if it is a valid relationship.\n * @param tableIds The IDs of the tables which currently exist.\n */\nexport function shouldCopyRelationship(\n column: { type: string; tableId?: string },\n tableIds: string[]\n) {\n return (\n column.type === FieldTypes.LINK &&\n column.tableId &&\n tableIds.includes(column.tableId)\n )\n}\n\n/**\n * Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean\n * types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make\n * sure that these get copied over when tables are fetched. Also checks whether they are still valid, if a\n * column has changed type in the external database then copying it over may not be possible.\n * @param column The column to check for options or boolean type.\n * @param fetchedColumn The fetched column to check for the type in the external database.\n */\nexport function shouldCopySpecialColumn(\n column: { type: string },\n fetchedColumn: { type: string } | undefined\n) {\n const isFormula = column.type === FieldTypes.FORMULA\n const specialTypes = [\n FieldTypes.OPTIONS,\n FieldTypes.LONGFORM,\n FieldTypes.ARRAY,\n FieldTypes.FORMULA,\n ]\n // column has been deleted, remove - formulas will never exist, always copy\n if (!isFormula && column && !fetchedColumn) {\n return false\n }\n const fetchedIsNumber =\n !fetchedColumn || fetchedColumn.type === FieldTypes.NUMBER\n return (\n specialTypes.indexOf(column.type as FieldTypes) !== -1 ||\n (fetchedIsNumber && column.type === FieldTypes.BOOLEAN)\n )\n}\n\n/**\n * Looks for columns which need to be copied over into the new table definitions, like relationships\n * and options types.\n * @param tableName The name of the table which is being checked.\n * @param table The specific table which is being checked.\n * @param entities All the tables that existed before - the old table definitions.\n * @param tableIds The IDs of the tables which exist now, to check if anything has been removed.\n */\nfunction copyExistingPropsOver(\n tableName: string,\n table: Table,\n entities: { [key: string]: any },\n tableIds: [string]\n) {\n if (entities && entities[tableName]) {\n if (entities[tableName]?.primaryDisplay) {\n table.primaryDisplay = entities[tableName].primaryDisplay\n }\n if (entities[tableName]?.created) {\n table.created = entities[tableName]?.created\n }\n const existingTableSchema = entities[tableName].schema\n for (let key in existingTableSchema) {\n if (!existingTableSchema.hasOwnProperty(key)) {\n continue\n }\n const column = existingTableSchema[key]\n if (\n shouldCopyRelationship(column, tableIds) ||\n shouldCopySpecialColumn(column, table.schema[key])\n ) {\n table.schema[key] = existingTableSchema[key]\n }\n }\n }\n return table\n}\n\n/**\n * Look through the final table definitions to see if anything needs to be\n * copied over from the old and if any errors have occurred mark them so\n * that the user can be made aware.\n * @param tables The list of tables that have been retrieved from the external database.\n * @param entities The old list of tables, if there was any to look for definitions in.\n */\nexport function finaliseExternalTables(\n tables: { [key: string]: any },\n entities: { [key: string]: any }\n) {\n const invalidColumns = Object.values(InvalidColumns)\n let finalTables: { [key: string]: any } = {}\n const errors: { [key: string]: string } = {}\n // @ts-ignore\n const tableIds: [string] = Object.values(tables).map(table => table._id)\n for (let [name, table] of Object.entries(tables)) {\n const schemaFields = Object.keys(table.schema)\n // make sure every table has a key\n if (table.primary == null || table.primary.length === 0) {\n errors[name] = BuildSchemaErrors.NO_KEY\n continue\n } else if (\n schemaFields.find(field =>\n invalidColumns.includes(field as InvalidColumns)\n )\n ) {\n errors[name] = BuildSchemaErrors.INVALID_COLUMN\n continue\n }\n // make sure all previous props have been added back\n finalTables[name] = copyExistingPropsOver(name, table, entities, tableIds)\n }\n // sort the tables by name\n finalTables = Object.entries(finalTables)\n .sort(([a], [b]) => a.localeCompare(b))\n .reduce((r, [k, v]) => ({ ...r, [k]: v }), {})\n return { tables: finalTables, errors }\n}\n", "import { environmentVariables } from \"@budibase/pro\"\nimport { context, db as dbCore } from \"@budibase/backend-core\"\nimport { AppEnvironment } from \"@budibase/types\"\n\nexport async function getEnvironmentVariables() {\n let envVars = context.getEnvironmentVariables()\n if (!envVars) {\n const appId = context.getAppId()\n const appEnv = dbCore.isDevAppID(appId)\n ? AppEnvironment.DEVELOPMENT\n : AppEnvironment.PRODUCTION\n\n envVars = await environmentVariables.fetchValues(appEnv)\n }\n return envVars\n}\n", "import { Knex, knex } from \"knex\"\nimport { Operation, QueryJson, RenameColumn, Table } from \"@budibase/types\"\nimport { breakExternalTableId } from \"../utils\"\nimport SchemaBuilder = Knex.SchemaBuilder\nimport CreateTableBuilder = Knex.CreateTableBuilder\nimport { FieldTypes, RelationshipTypes } from \"../../constants\"\n\nfunction generateSchema(\n schema: CreateTableBuilder,\n table: Table,\n tables: Record<string, Table>,\n oldTable: null | Table = null,\n renamed?: RenameColumn\n) {\n let primaryKey = table && table.primary ? table.primary[0] : null\n const columns = Object.values(table.schema)\n // all columns in a junction table will be meta\n let metaCols = columns.filter(col => col.meta)\n let isJunction = metaCols.length === columns.length\n // can't change primary once its set for now\n if (primaryKey && !oldTable && !isJunction) {\n schema.increments(primaryKey).primary()\n } else if (!oldTable && isJunction) {\n schema.primary(metaCols.map(col => col.name))\n }\n\n // check if any columns need added\n const foreignKeys = Object.values(table.schema).map(col => col.foreignKey)\n for (let [key, column] of Object.entries(table.schema)) {\n // skip things that are already correct\n const oldColumn = oldTable ? oldTable.schema[key] : null\n if (\n (oldColumn && oldColumn.type) ||\n (primaryKey === key && !isJunction) ||\n renamed?.updated === key\n ) {\n continue\n }\n switch (column.type) {\n case FieldTypes.STRING:\n case FieldTypes.OPTIONS:\n case FieldTypes.LONGFORM:\n case FieldTypes.BARCODEQR:\n schema.text(key)\n break\n case FieldTypes.NUMBER:\n // if meta is specified then this is a junction table entry\n if (column.meta && column.meta.toKey && column.meta.toTable) {\n const { toKey, toTable } = column.meta\n schema.integer(key).unsigned()\n schema.foreign(key).references(`${toTable}.${toKey}`)\n } else if (foreignKeys.indexOf(key) === -1) {\n schema.float(key)\n }\n break\n case FieldTypes.BOOLEAN:\n schema.boolean(key)\n break\n case FieldTypes.DATETIME:\n schema.datetime(key, {\n useTz: !column.ignoreTimezones,\n })\n break\n case FieldTypes.ARRAY:\n schema.json(key)\n break\n case FieldTypes.LINK:\n // this side of the relationship doesn't need any SQL work\n if (\n column.relationshipType !== RelationshipTypes.MANY_TO_ONE &&\n column.relationshipType !== RelationshipTypes.MANY_TO_MANY\n ) {\n if (!column.foreignKey || !column.tableId) {\n throw \"Invalid relationship schema\"\n }\n const { tableName } = breakExternalTableId(column.tableId)\n // @ts-ignore\n const relatedTable = tables[tableName]\n if (!relatedTable) {\n throw \"Referenced table doesn't exist\"\n }\n const relatedPrimary = relatedTable.primary[0]\n const externalType = relatedTable.schema[relatedPrimary].externalType\n if (externalType) {\n schema.specificType(column.foreignKey, externalType)\n } else {\n schema.integer(column.foreignKey).unsigned()\n }\n\n schema\n .foreign(column.foreignKey)\n .references(`${tableName}.${relatedPrimary}`)\n }\n break\n }\n }\n\n if (renamed) {\n schema.renameColumn(renamed.old, renamed.updated)\n }\n\n // need to check if any columns have been deleted\n if (oldTable) {\n const deletedColumns = Object.entries(oldTable.schema)\n .filter(\n ([key, schema]) =>\n schema.type !== FieldTypes.LINK &&\n schema.type !== FieldTypes.FORMULA &&\n table.schema[key] == null\n )\n .map(([key]) => key)\n deletedColumns.forEach(key => {\n if (renamed?.old === key) {\n return\n }\n if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {\n schema.dropForeign(key)\n }\n schema.dropColumn(key)\n })\n }\n\n return schema\n}\n\nfunction buildCreateTable(\n knex: SchemaBuilder,\n table: Table,\n tables: Record<string, Table>\n): SchemaBuilder {\n return knex.createTable(table.name, schema => {\n generateSchema(schema, table, tables)\n })\n}\n\nfunction buildUpdateTable(\n knex: SchemaBuilder,\n table: Table,\n tables: Record<string, Table>,\n oldTable: Table,\n renamed: RenameColumn\n): SchemaBuilder {\n return knex.alterTable(table.name, schema => {\n generateSchema(schema, table, tables, oldTable, renamed)\n })\n}\n\nfunction buildDeleteTable(knex: SchemaBuilder, table: Table): SchemaBuilder {\n return knex.dropTable(table.name)\n}\n\nclass SqlTableQueryBuilder {\n private readonly sqlClient: string\n\n // pass through client to get flavour of SQL\n constructor(client: string) {\n this.sqlClient = client\n }\n\n getSqlClient(): string {\n return this.sqlClient\n }\n\n /**\n * @param json the input JSON structure from which an SQL query will be built.\n * @return {string} the operation that was found in the JSON.\n */\n _operation(json: QueryJson): Operation {\n return json.endpoint.operation\n }\n\n _tableQuery(json: QueryJson): any {\n let client = knex({ client: this.sqlClient }).schema\n if (json?.endpoint?.schema) {\n client = client.withSchema(json.endpoint.schema)\n }\n\n let query\n if (!json.table || !json.meta || !json.meta.tables) {\n throw \"Cannot execute without table being specified\"\n }\n switch (this._operation(json)) {\n case Operation.CREATE_TABLE:\n query = buildCreateTable(client, json.table, json.meta.tables)\n break\n case Operation.UPDATE_TABLE:\n if (!json.meta || !json.meta.table) {\n throw \"Must specify old table for update\"\n }\n query = buildUpdateTable(\n client,\n json.table,\n json.meta.tables,\n json.meta.table,\n json.meta.renamed!\n )\n break\n case Operation.DELETE_TABLE:\n query = buildDeleteTable(client, json.table)\n break\n default:\n throw \"Table operation is of unknown type\"\n }\n return query.toSQL()\n }\n}\n\nexport default SqlTableQueryBuilder\n", "import { Knex, knex } from \"knex\"\nimport {\n Operation,\n QueryJson,\n RelationshipsJson,\n SearchFilters,\n SortDirection,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\nimport { QueryOptions } from \"../../definitions/datasource\"\nimport { isIsoDateString, SqlClient } from \"../utils\"\nimport SqlTableQueryBuilder from \"./sqlTable\"\nimport environment from \"../../environment\"\n\nconst envLimit = environment.SQL_MAX_ROWS\n ? parseInt(environment.SQL_MAX_ROWS)\n : null\nconst BASE_LIMIT = envLimit || 5000\n\ntype KnexQuery = Knex.QueryBuilder | Knex\n// these are invalid dates sent by the client, need to convert them to a real max date\nconst MIN_ISO_DATE = \"0000-00-00T00:00:00.000Z\"\nconst MAX_ISO_DATE = \"9999-00-00T00:00:00.000Z\"\n\nfunction likeKey(client: string, key: string): string {\n let start: string, end: string\n switch (client) {\n case SqlClient.MY_SQL:\n start = end = \"`\"\n break\n case SqlClient.ORACLE:\n case SqlClient.POSTGRES:\n start = end = '\"'\n break\n case SqlClient.MS_SQL:\n start = \"[\"\n end = \"]\"\n break\n default:\n throw \"Unknown client\"\n }\n const parts = key.split(\".\")\n key = parts.map(part => `${start}${part}${end}`).join(\".\")\n return key\n}\n\nfunction parse(input: any) {\n if (Array.isArray(input)) {\n return JSON.stringify(input)\n }\n if (input == undefined) {\n return null\n }\n if (typeof input !== \"string\") {\n return input\n }\n if (input === MAX_ISO_DATE || input === MIN_ISO_DATE) {\n return null\n }\n if (isIsoDateString(input)) {\n return new Date(input)\n }\n return input\n}\n\nfunction parseBody(body: any) {\n for (let [key, value] of Object.entries(body)) {\n body[key] = parse(value)\n }\n return body\n}\n\nfunction parseFilters(filters: SearchFilters | undefined): SearchFilters {\n if (!filters) {\n return {}\n }\n for (let [key, value] of Object.entries(filters)) {\n let parsed\n if (typeof value === \"object\") {\n parsed = parseFilters(value)\n } else {\n parsed = parse(value)\n }\n // @ts-ignore\n filters[key] = parsed\n }\n return filters\n}\n\nfunction generateSelectStatement(\n json: QueryJson,\n knex: Knex\n): (string | Knex.Raw)[] | \"*\" {\n const { resource, meta } = json\n\n if (!resource) {\n return \"*\"\n }\n\n const schema = meta?.table?.schema\n return resource.fields.map(field => {\n const fieldNames = field.split(/\\./g)\n const tableName = fieldNames[0]\n const columnName = fieldNames[1]\n if (\n columnName &&\n schema?.[columnName] &&\n knex.client.config.client === SqlClient.POSTGRES\n ) {\n const externalType = schema[columnName].externalType\n if (externalType?.includes(\"money\")) {\n return knex.raw(\n `\"${tableName}\".\"${columnName}\"::money::numeric as \"${field}\"`\n )\n }\n }\n return `${field} as ${field}`\n })\n}\n\nclass InternalBuilder {\n private readonly client: string\n\n constructor(client: string) {\n this.client = client\n }\n\n // right now we only do filters on the specific table being queried\n addFilters(\n query: KnexQuery,\n filters: SearchFilters | undefined,\n opts: { relationship?: boolean; tableName?: string }\n ): KnexQuery {\n function iterate(\n structure: { [key: string]: any },\n fn: (key: string, value: any) => void\n ) {\n for (let [key, value] of Object.entries(structure)) {\n const updatedKey = dbCore.removeKeyNumbering(key)\n const isRelationshipField = updatedKey.includes(\".\")\n if (!opts.relationship && !isRelationshipField) {\n fn(`${opts.tableName}.${updatedKey}`, value)\n }\n if (opts.relationship && isRelationshipField) {\n fn(updatedKey, value)\n }\n }\n }\n\n const like = (key: string, value: any) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n // postgres supports ilike, nothing else does\n if (this.client === SqlClient.POSTGRES) {\n query = query[fnc](key, \"ilike\", `%${value}%`)\n } else {\n const rawFnc = `${fnc}Raw`\n // @ts-ignore\n query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [\n `%${value.toLowerCase()}%`,\n ])\n }\n }\n\n const contains = (mode: object, any: boolean = false) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n const rawFnc = `${fnc}Raw`\n const not = mode === filters?.notContains ? \"NOT \" : \"\"\n function stringifyArray(value: Array<any>, quoteStyle = '\"'): string {\n for (let i in value) {\n if (typeof value[i] === \"string\") {\n value[i] = `${quoteStyle}${value[i]}${quoteStyle}`\n }\n }\n return `[${value.join(\",\")}]`\n }\n if (this.client === SqlClient.POSTGRES) {\n iterate(mode, (key: string, value: Array<any>) => {\n const wrap = any ? \"\" : \"'\"\n const containsOp = any ? \"\\\\?| array\" : \"@>\"\n const fieldNames = key.split(/\\./g)\n const tableName = fieldNames[0]\n const columnName = fieldNames[1]\n // @ts-ignore\n query = query[rawFnc](\n `${not}\"${tableName}\".\"${columnName}\"::jsonb ${containsOp} ${wrap}${stringifyArray(\n value,\n any ? \"'\" : '\"'\n )}${wrap}`\n )\n })\n } else if (this.client === SqlClient.MY_SQL) {\n const jsonFnc = any ? \"JSON_OVERLAPS\" : \"JSON_CONTAINS\"\n iterate(mode, (key: string, value: Array<any>) => {\n // @ts-ignore\n query = query[rawFnc](\n `${not}${jsonFnc}(${key}, '${stringifyArray(value)}')`\n )\n })\n } else {\n const andOr = mode === filters?.containsAny ? \" OR \" : \" AND \"\n iterate(mode, (key: string, value: Array<any>) => {\n let statement = \"\"\n for (let i in value) {\n if (typeof value[i] === \"string\") {\n value[i] = `%\"${value[i].toLowerCase()}\"%`\n } else {\n value[i] = `%${value[i]}%`\n }\n statement +=\n (statement ? andOr : \"\") +\n `LOWER(${likeKey(this.client, key)}) LIKE ?`\n }\n // @ts-ignore\n query = query[rawFnc](`${not}(${statement})`, value)\n })\n }\n }\n\n if (!filters) {\n return query\n }\n filters = parseFilters(filters)\n // if all or specified in filters, then everything is an or\n const allOr = filters.allOr\n if (filters.oneOf) {\n iterate(filters.oneOf, (key, array) => {\n const fnc = allOr ? \"orWhereIn\" : \"whereIn\"\n query = query[fnc](key, Array.isArray(array) ? array : [array])\n })\n }\n if (filters.string) {\n iterate(filters.string, (key, value) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n // postgres supports ilike, nothing else does\n if (this.client === SqlClient.POSTGRES) {\n query = query[fnc](key, \"ilike\", `${value}%`)\n } else {\n const rawFnc = `${fnc}Raw`\n // @ts-ignore\n query = query[rawFnc](`LOWER(${likeKey(this.client, key)}) LIKE ?`, [\n `${value.toLowerCase()}%`,\n ])\n }\n })\n }\n if (filters.fuzzy) {\n iterate(filters.fuzzy, like)\n }\n if (filters.range) {\n iterate(filters.range, (key, value) => {\n const isEmptyObject = (val: any) => {\n return (\n val &&\n Object.keys(val).length === 0 &&\n Object.getPrototypeOf(val) === Object.prototype\n )\n }\n if (isEmptyObject(value.low)) {\n value.low = \"\"\n }\n if (isEmptyObject(value.high)) {\n value.high = \"\"\n }\n if (value.low && value.high) {\n // Use a between operator if we have 2 valid range values\n const fnc = allOr ? \"orWhereBetween\" : \"whereBetween\"\n query = query[fnc](key, [value.low, value.high])\n } else if (value.low) {\n // Use just a single greater than operator if we only have a low\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc](key, \">\", value.low)\n } else if (value.high) {\n // Use just a single less than operator if we only have a high\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc](key, \"<\", value.high)\n }\n })\n }\n if (filters.equal) {\n iterate(filters.equal, (key, value) => {\n const fnc = allOr ? \"orWhere\" : \"where\"\n query = query[fnc]({ [key]: value })\n })\n }\n if (filters.notEqual) {\n iterate(filters.notEqual, (key, value) => {\n const fnc = allOr ? \"orWhereNot\" : \"whereNot\"\n query = query[fnc]({ [key]: value })\n })\n }\n if (filters.empty) {\n iterate(filters.empty, key => {\n const fnc = allOr ? \"orWhereNull\" : \"whereNull\"\n query = query[fnc](key)\n })\n }\n if (filters.notEmpty) {\n iterate(filters.notEmpty, key => {\n const fnc = allOr ? \"orWhereNotNull\" : \"whereNotNull\"\n query = query[fnc](key)\n })\n }\n if (filters.contains) {\n contains(filters.contains)\n }\n if (filters.notContains) {\n contains(filters.notContains)\n }\n if (filters.containsAny) {\n contains(filters.containsAny, true)\n }\n return query\n }\n\n addSorting(query: KnexQuery, json: QueryJson): KnexQuery {\n let { sort, paginate } = json\n const table = json.meta?.table\n if (sort) {\n for (let [key, value] of Object.entries(sort)) {\n const direction =\n value.direction === SortDirection.ASCENDING ? \"asc\" : \"desc\"\n query = query.orderBy(`${table?.name}.${key}`, direction)\n }\n } else if (this.client === SqlClient.MS_SQL && paginate?.limit) {\n // @ts-ignore\n query = query.orderBy(`${table?.name}.${table?.primary[0]}`)\n }\n return query\n }\n\n addRelationships(\n query: KnexQuery,\n fromTable: string,\n relationships: RelationshipsJson[] | undefined,\n schema: string | undefined\n ): KnexQuery {\n if (!relationships) {\n return query\n }\n const tableSets: Record<string, [any]> = {}\n // aggregate into table sets (all the same to tables)\n for (let relationship of relationships) {\n const keyObj: { toTable: string; throughTable: string | undefined } = {\n toTable: relationship.tableName,\n throughTable: undefined,\n }\n if (relationship.through) {\n keyObj.throughTable = relationship.through\n }\n const key = JSON.stringify(keyObj)\n if (tableSets[key]) {\n tableSets[key].push(relationship)\n } else {\n tableSets[key] = [relationship]\n }\n }\n for (let [key, relationships] of Object.entries(tableSets)) {\n const { toTable, throughTable } = JSON.parse(key)\n const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable\n const throughTableWithSchema = schema\n ? `${schema}.${throughTable}`\n : throughTable\n if (!throughTable) {\n // @ts-ignore\n query = query.leftJoin(toTableWithSchema, function () {\n for (let relationship of relationships) {\n const from = relationship.from,\n to = relationship.to\n // @ts-ignore\n this.orOn(`${fromTable}.${from}`, \"=\", `${toTable}.${to}`)\n }\n })\n } else {\n query = query\n // @ts-ignore\n .leftJoin(throughTableWithSchema, function () {\n for (let relationship of relationships) {\n const fromPrimary = relationship.fromPrimary\n const from = relationship.from\n // @ts-ignore\n this.orOn(\n `${fromTable}.${fromPrimary}`,\n \"=\",\n `${throughTable}.${from}`\n )\n }\n })\n .leftJoin(toTableWithSchema, function () {\n for (let relationship of relationships) {\n const toPrimary = relationship.toPrimary\n const to = relationship.to\n // @ts-ignore\n this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`)\n }\n })\n }\n }\n return query.limit(BASE_LIMIT)\n }\n\n create(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, body } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n const parsedBody = parseBody(body)\n // make sure no null values in body for creation\n for (let [key, value] of Object.entries(parsedBody)) {\n if (value == null) {\n delete parsedBody[key]\n }\n }\n\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.insert(parsedBody)\n } else {\n return query.insert(parsedBody).returning(\"*\")\n }\n }\n\n bulkCreate(knex: Knex, json: QueryJson): KnexQuery {\n const { endpoint, body } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n if (!Array.isArray(body)) {\n return query\n }\n const parsedBody = body.map(row => parseBody(row))\n return query.insert(parsedBody)\n }\n\n read(knex: Knex, json: QueryJson, limit: number): KnexQuery {\n let { endpoint, resource, filters, paginate, relationships } = json\n const tableName = endpoint.entityId\n // select all if not specified\n if (!resource) {\n resource = { fields: [] }\n }\n let selectStatement: string | (string | Knex.Raw)[] = \"*\"\n // handle select\n if (resource.fields && resource.fields.length > 0) {\n // select the resources as the format \"table.columnName\" - this is what is provided\n // by the resource builder further up\n selectStatement = generateSelectStatement(json, knex)\n }\n let foundLimit = limit || BASE_LIMIT\n // handle pagination\n let foundOffset: number | null = null\n if (paginate && paginate.page && paginate.limit) {\n // @ts-ignore\n const page = paginate.page <= 1 ? 0 : paginate.page - 1\n const offset = page * paginate.limit\n foundLimit = paginate.limit\n foundOffset = offset\n } else if (paginate && paginate.limit) {\n foundLimit = paginate.limit\n }\n // start building the query\n let query: KnexQuery = knex(tableName).limit(foundLimit)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n if (foundOffset) {\n query = query.offset(foundOffset)\n }\n query = this.addFilters(query, filters, { tableName })\n // add sorting to pre-query\n query = this.addSorting(query, json)\n // @ts-ignore\n let preQuery: KnexQuery = knex({\n // @ts-ignore\n [tableName]: query,\n }).select(selectStatement)\n // have to add after as well (this breaks MS-SQL)\n if (this.client !== SqlClient.MS_SQL) {\n preQuery = this.addSorting(preQuery, json)\n }\n // handle joins\n query = this.addRelationships(\n preQuery,\n tableName,\n relationships,\n endpoint.schema\n )\n return this.addFilters(query, filters, { relationship: true })\n }\n\n update(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, body, filters } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n const parsedBody = parseBody(body)\n query = this.addFilters(query, filters, { tableName: endpoint.entityId })\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.update(parsedBody)\n } else {\n return query.update(parsedBody).returning(\"*\")\n }\n }\n\n delete(knex: Knex, json: QueryJson, opts: QueryOptions): KnexQuery {\n const { endpoint, filters } = json\n let query: KnexQuery = knex(endpoint.entityId)\n if (endpoint.schema) {\n query = query.withSchema(endpoint.schema)\n }\n query = this.addFilters(query, filters, { tableName: endpoint.entityId })\n // mysql can't use returning\n if (opts.disableReturning) {\n return query.delete()\n } else {\n return query.delete().returning(generateSelectStatement(json, knex))\n }\n }\n}\n\nclass SqlQueryBuilder extends SqlTableQueryBuilder {\n private readonly limit: number\n // pass through client to get flavour of SQL\n constructor(client: string, limit: number = BASE_LIMIT) {\n super(client)\n this.limit = limit\n }\n\n /**\n * @param json The JSON query DSL which is to be converted to SQL.\n * @param opts extra options which are to be passed into the query builder, e.g. disableReturning\n * which for the sake of mySQL stops adding the returning statement to inserts, updates and deletes.\n * @return {{ sql: string, bindings: object }} the query ready to be passed to the driver.\n */\n _query(json: QueryJson, opts: QueryOptions = {}) {\n const sqlClient = this.getSqlClient()\n const client = knex({ client: sqlClient })\n let query\n const builder = new InternalBuilder(sqlClient)\n switch (this._operation(json)) {\n case Operation.CREATE:\n query = builder.create(client, json, opts)\n break\n case Operation.READ:\n query = builder.read(client, json, this.limit)\n break\n case Operation.UPDATE:\n query = builder.update(client, json, opts)\n break\n case Operation.DELETE:\n query = builder.delete(client, json, opts)\n break\n case Operation.BULK_CREATE:\n query = builder.bulkCreate(client, json)\n break\n case Operation.CREATE_TABLE:\n case Operation.UPDATE_TABLE:\n case Operation.DELETE_TABLE:\n return this._tableQuery(json)\n default:\n throw `Operation type is not supported by SQL query builder`\n }\n\n // @ts-ignore\n return query.toSQL().toNative()\n }\n\n async getReturningRow(queryFn: Function, json: QueryJson) {\n if (!json.extra || !json.extra.idFilter) {\n return {}\n }\n const input = this._query({\n endpoint: {\n ...json.endpoint,\n operation: Operation.READ,\n },\n resource: {\n fields: [],\n },\n filters: json.extra.idFilter,\n paginate: {\n limit: 1,\n },\n meta: json.meta,\n })\n return queryFn(input, Operation.READ)\n }\n\n // when creating if an ID has been inserted need to make sure\n // the id filter is enriched with it before trying to retrieve the row\n checkLookupKeys(id: any, json: QueryJson) {\n if (!id || !json.meta?.table || !json.meta.table.primary) {\n return json\n }\n const primaryKey = json.meta.table.primary?.[0]\n json.extra = {\n idFilter: {\n equal: {\n [primaryKey]: id,\n },\n },\n }\n return json\n }\n\n // this function recreates the returning functionality of postgres\n async queryWithReturning(\n json: QueryJson,\n queryFn: Function,\n processFn: Function = (result: any) => result\n ) {\n const sqlClient = this.getSqlClient()\n const operation = this._operation(json)\n const input = this._query(json, { disableReturning: true })\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await queryFn(query, operation))\n }\n return responses\n }\n let row\n // need to manage returning, a feature mySQL can't do\n if (operation === Operation.DELETE) {\n row = processFn(await this.getReturningRow(queryFn, json))\n }\n const response = await queryFn(input, operation)\n const results = processFn(response)\n // same as delete, manage returning\n if (operation === Operation.CREATE || operation === Operation.UPDATE) {\n let id\n if (sqlClient === SqlClient.MS_SQL) {\n id = results?.[0].id\n } else if (sqlClient === SqlClient.MY_SQL) {\n id = results?.insertId\n }\n row = processFn(\n await this.getReturningRow(queryFn, this.checkLookupKeys(id, json))\n )\n }\n if (operation !== Operation.READ) {\n return row\n }\n return results.length ? results : [{ [operation.toLowerCase()]: true }]\n }\n}\n\nexport default SqlQueryBuilder\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n QueryJson,\n SqlQuery,\n Table,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { PostgresColumn } from \"./base/types\"\nimport { escapeDangerousCharacters } from \"../utilities\"\n\nimport { Client, types } from \"pg\"\n\n// Return \"date\" and \"timestamp\" types as plain strings.\n// This lets us reference the original stored timezone.\n// types is undefined when running in a test env for some reason.\nif (types) {\n types.setTypeParser(1114, (val: any) => val) // timestamp\n types.setTypeParser(1082, (val: any) => val) // date\n types.setTypeParser(1184, (val: any) => val) // timestampz\n}\n\nconst JSON_REGEX = /'{.*}'::json/s\n\ninterface PostgresConfig {\n host: string\n port: number\n database: string\n user: string\n password: string\n schema: string\n ssl?: boolean\n ca?: string\n rejectUnauthorized?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://node-postgres.com\",\n plus: true,\n friendlyName: \"PostgreSQL\",\n type: \"Relational\",\n description:\n \"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n default: 5432,\n },\n database: {\n type: DatasourceFieldType.STRING,\n default: \"postgres\",\n required: true,\n },\n user: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n default: \"root\",\n required: true,\n },\n schema: {\n type: DatasourceFieldType.STRING,\n default: \"public\",\n required: true,\n },\n ssl: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n ca: {\n type: DatasourceFieldType.LONGFORM,\n default: false,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass PostgresIntegration extends Sql implements DatasourcePlus {\n private readonly client: Client\n private readonly config: PostgresConfig\n private index: number = 1\n private open: boolean\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n COLUMNS_SQL!: string\n\n PRIMARY_KEYS_SQL = () => `\n SELECT pg_namespace.nspname table_schema\n , pg_class.relname table_name\n , pg_attribute.attname primary_key\n FROM pg_class\n JOIN pg_index ON pg_class.oid = pg_index.indrelid AND pg_index.indisprimary\n JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = ANY(pg_index.indkey)\n JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace\n WHERE pg_namespace.nspname = '${this.config.schema}';\n `\n\n constructor(config: PostgresConfig) {\n super(SqlClient.POSTGRES)\n this.config = config\n\n let newConfig = {\n ...this.config,\n ssl: this.config.ssl\n ? {\n rejectUnauthorized: this.config.rejectUnauthorized,\n ca: this.config.ca,\n }\n : undefined,\n }\n this.client = new Client(newConfig)\n this.open = false\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.openConnection()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n } finally {\n await this.closeConnection()\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return `$${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return parts.join(\" || \")\n }\n\n async openConnection() {\n await this.client.connect()\n if (!this.config.schema) {\n this.config.schema = \"public\"\n }\n await this.client.query(`SET search_path TO ${this.config.schema}`)\n this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`\n this.open = true\n }\n\n closeConnection() {\n const pg = this\n return new Promise<void>((resolve, reject) => {\n this.client.end((err: any) => {\n pg.open = false\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n })\n }\n\n async internalQuery(query: SqlQuery, close: boolean = true) {\n if (!this.open) {\n await this.openConnection()\n }\n const client = this.client\n this.index = 1\n // need to handle a specific issue with json data types in postgres,\n // new lines inside the JSON data will break it\n if (query && query.sql) {\n const matches = query.sql.match(JSON_REGEX)\n if (matches && matches.length > 0) {\n for (let match of matches) {\n const escaped = escapeDangerousCharacters(match)\n query.sql = query.sql.replace(match, escaped)\n }\n }\n }\n try {\n return await client.query(query.sql, query.bindings || [])\n } catch (err) {\n await this.closeConnection()\n // @ts-ignore\n throw new Error(err)\n } finally {\n if (close) {\n await this.closeConnection()\n }\n }\n }\n\n /**\n * Fetches the tables from the postgres table and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n let tableKeys: { [key: string]: string[] } = {}\n await this.openConnection()\n try {\n const primaryKeysResponse = await this.client.query(\n this.PRIMARY_KEYS_SQL()\n )\n for (let table of primaryKeysResponse.rows) {\n const tableName = table.table_name\n if (!tableKeys[tableName]) {\n tableKeys[tableName] = []\n }\n const key = table.column_name || table.primary_key\n // only add the unique keys\n if (key && tableKeys[tableName].indexOf(key) === -1) {\n tableKeys[tableName].push(key)\n }\n }\n } catch (err) {\n tableKeys = {}\n }\n\n try {\n const columnsResponse: { rows: PostgresColumn[] } =\n await this.client.query(this.COLUMNS_SQL)\n\n const tables: { [key: string]: Table } = {}\n\n for (let column of columnsResponse.rows) {\n const tableName: string = column.table_name\n const columnName: string = column.column_name\n\n // table key doesn't exist yet\n if (!tables[tableName] || !tables[tableName].schema) {\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: tableKeys[tableName] || [],\n name: tableName,\n schema: {},\n }\n }\n\n const identity = !!(\n column.identity_generation ||\n column.identity_start ||\n column.identity_increment\n )\n const hasDefault = column.column_default != null\n const hasNextVal =\n typeof column.column_default === \"string\" &&\n column.column_default.startsWith(\"nextval\")\n const isGenerated =\n column.is_generated && column.is_generated !== \"NEVER\"\n const isAuto: boolean = hasNextVal || identity || isGenerated\n const required = column.is_nullable === \"NO\"\n const constraints = {\n presence: required && !hasDefault && !isGenerated,\n }\n tables[tableName].schema[columnName] = {\n autocolumn: isAuto,\n name: columnName,\n constraints,\n ...convertSqlType(column.data_type),\n externalType: column.data_type,\n }\n }\n\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n } finally {\n await this.closeConnection()\n }\n }\n\n async getTableNames() {\n try {\n await this.openConnection()\n const columnsResponse: { rows: PostgresColumn[] } =\n await this.client.query(this.COLUMNS_SQL)\n return columnsResponse.rows.map(row => row.table_name)\n } finally {\n await this.closeConnection()\n }\n }\n\n async create(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ created: true }]\n }\n\n async read(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows\n }\n\n async update(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows.length ? response.rows : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const operation = this._operation(json).toLowerCase()\n const input = this._query(json)\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await this.internalQuery(query, false))\n }\n await this.closeConnection()\n return responses\n } else {\n const response = await this.internalQuery(input)\n return response.rows.length ? response.rows : [{ [operation]: true }]\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: PostgresIntegration,\n}\n", "import { merge } from \"lodash\"\nimport env from \"../environment\"\n\nexport const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : \"eu-west-1\"\n\nconst TableInfo = {\n API_KEYS: {\n name: \"beta-api-key-table\",\n primary: \"pk\",\n },\n USERS: {\n name: \"prod-budi-table\",\n primary: \"pk\",\n sort: \"sk\",\n },\n}\n\nlet docClient: any = null\n\ntype GetOpts = {\n primary: string\n sort?: string\n otherProps?: any\n}\n\ntype UpdateOpts = {\n primary: string\n sort?: string\n expression?: string\n condition?: string\n names?: string[]\n values?: any[]\n exists?: boolean\n otherProps?: any\n}\n\ntype PutOpts = {\n item: any\n otherProps?: any\n}\n\nclass Table {\n _name: string\n _primary: string\n _sort?: string\n\n constructor(tableInfo: { name: string; primary: string; sort?: string }) {\n if (!tableInfo.name || !tableInfo.primary) {\n throw \"Table info must specify a name and a primary key\"\n }\n this._name = tableInfo.name\n this._primary = tableInfo.primary\n this._sort = tableInfo.sort\n }\n\n async get({ primary, sort, otherProps }: GetOpts) {\n let params = {\n TableName: this._name,\n Key: {\n [this._primary]: primary,\n },\n }\n if (this._sort && sort) {\n params.Key[this._sort] = sort\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n let response = await docClient.get(params).promise()\n return response.Item\n }\n\n async update({\n primary,\n sort,\n expression,\n condition,\n names,\n values,\n exists,\n otherProps,\n }: UpdateOpts) {\n let params: any = {\n TableName: this._name,\n Key: {\n [this._primary]: primary,\n },\n ExpressionAttributeNames: names,\n ExpressionAttributeValues: values,\n UpdateExpression: expression,\n }\n if (condition) {\n params.ConditionExpression = condition\n }\n if (this._sort && sort) {\n params.Key[this._sort] = sort\n }\n if (exists) {\n params.ExpressionAttributeNames[\"#PRIMARY\"] = this._primary\n if (params.ConditionExpression) {\n params.ConditionExpression += \" AND \"\n }\n params.ConditionExpression += \"attribute_exists(#PRIMARY)\"\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n return docClient.update(params).promise()\n }\n\n async put({ item, otherProps }: PutOpts) {\n if (\n item[this._primary] == null ||\n (this._sort && item[this._sort] == null)\n ) {\n throw \"Cannot put item without primary and sort key (if required)\"\n }\n let params = {\n TableName: this._name,\n Item: item,\n }\n if (otherProps) {\n params = merge(params, otherProps)\n }\n return docClient.put(params).promise()\n }\n}\n\nexport function init(endpoint: string) {\n let AWS = require(\"aws-sdk\")\n let docClientParams: any = {\n correctClockSkew: true,\n region: AWS_REGION,\n }\n if (endpoint) {\n docClientParams.endpoint = endpoint\n } else if (env.DYNAMO_ENDPOINT) {\n docClientParams.endpoint = env.DYNAMO_ENDPOINT\n }\n docClient = new AWS.DynamoDB.DocumentClient(docClientParams)\n}\n\nif (!env.isProd() && !env.isJest()) {\n env._set(\"AWS_ACCESS_KEY_ID\", \"KEY_ID\")\n env._set(\"AWS_SECRET_ACCESS_KEY\", \"SECRET_KEY\")\n init(\"http://localhost:8333\")\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport AWS from \"aws-sdk\"\nimport { AWS_REGION } from \"../db/dynamoClient\"\nimport { DocumentClient } from \"aws-sdk/clients/dynamodb\"\n\ninterface DynamoDBConfig {\n region: string\n accessKeyId: string\n secretAccessKey: string\n endpoint?: string\n currentClockSkew?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/dabit3/dynamodb-documentclient-cheat-sheet\",\n description:\n \"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.\",\n friendlyName: \"DynamoDB\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n region: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"us-east-1\",\n },\n accessKeyId: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n secretAccessKey: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n endpoint: {\n type: DatasourceFieldType.STRING,\n required: false,\n default: \"https://dynamodb.us-east-1.amazonaws.com\",\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n scan: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n describe: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n get: {\n type: QueryType.FIELDS,\n customisable: true,\n readable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass DynamoDBIntegration implements IntegrationBase {\n private config: DynamoDBConfig\n private client\n\n constructor(config: DynamoDBConfig) {\n this.config = config\n\n // User is using a local dynamoDB endpoint, don't auth with remote\n if (this.config?.endpoint?.includes(\"localhost\")) {\n // @ts-ignore\n this.config = {}\n }\n\n this.config = {\n ...this.config,\n currentClockSkew: true,\n region: config.region || AWS_REGION,\n endpoint: config.endpoint || undefined,\n }\n this.client = new AWS.DynamoDB.DocumentClient(this.config)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const scanRes = await new AWS.DynamoDB(this.config).listTables().promise()\n response.connected = !!scanRes.$response\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async create(query: {\n table: string\n json: Omit<DocumentClient.PutItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.put(params).promise()\n }\n\n async read(query: { table: string; json: object; index: null | string }) {\n const params = {\n TableName: query.table,\n IndexName: query.index ? query.index : undefined,\n ...query.json,\n }\n const response = await this.client.query(params).promise()\n if (response.Items) {\n return response.Items\n }\n return response\n }\n\n async scan(query: { table: string; json: object; index: null | string }) {\n const params = {\n TableName: query.table,\n IndexName: query.index ? query.index : undefined,\n ...query.json,\n }\n const response = await this.client.scan(params).promise()\n if (response.Items) {\n return response.Items\n }\n return response\n }\n\n async describe(query: { table: string }): Promise<any> {\n const params = {\n TableName: query.table,\n }\n return new AWS.DynamoDB(this.config).describeTable(params).promise()\n }\n\n async get(query: {\n table: string\n json: Omit<DocumentClient.GetItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.get(params).promise()\n }\n\n async update(query: {\n table: string\n json: Omit<DocumentClient.UpdateItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.update(params).promise()\n }\n\n async delete(query: {\n table: string\n json: Omit<DocumentClient.DeleteItemInput, \"TableName\">\n }) {\n const params = {\n TableName: query.table,\n ...query.json,\n }\n return this.client.delete(params).promise()\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: DynamoDBIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n MongoClient,\n ObjectId,\n Filter,\n UpdateFilter,\n FindOneAndUpdateOptions,\n UpdateOptions,\n OperationOptions,\n MongoClientOptions,\n} from \"mongodb\"\nimport environment from \"../environment\"\n\ninterface MongoDBConfig {\n connectionString: string\n db: string\n tlsCertificateFile: string\n tlsCertificateKeyFile: string\n tlsCAFile: string\n}\n\ninterface MongoDBQuery {\n json: object | string\n extra: {\n [key: string]: string\n }\n}\n\nconst getSchema = () => {\n let schema = {\n docs: \"https://github.com/mongodb/node-mongodb-native\",\n friendlyName: \"MongoDB\",\n type: \"Non-relational\",\n description:\n \"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n connectionString: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"mongodb://localhost:27017\",\n display: \"Connection string\",\n },\n db: {\n type: DatasourceFieldType.STRING,\n required: true,\n display: \"DB\",\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n delete: {\n type: QueryType.JSON,\n },\n aggregate: {\n type: QueryType.JSON,\n readable: true,\n steps: [\n {\n key: \"$addFields\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$bucket\",\n template: `{\n \"groupBy\": \"\",\n \"boundaries\": [],\n \"default\": \"\",\n \"output\": {}\n }`,\n },\n {\n key: \"$bucketAuto\",\n template: `{\n \"groupBy\": \"\",\n \"buckets\": 1,\n \"output\": {},\n \"granularity\": \"R5\"\n }`,\n },\n {\n key: \"$changeStream\",\n template: `{\n \"allChangesForCluster\": true,\n \"fullDocument\": \"\",\n \"fullDocumentBeforeChange\": \"\",\n \"resumeAfter\": 1,\n \"showExpandedEvents\": true,\n \"startAfter\": {},\n \"startAtOperationTime\": \"\"\n }`,\n },\n {\n key: \"$collStats\",\n template: `{\n \"latencyStats\": { \"histograms\": true } },\n \"storageStats\": { \"scale\": 1 } },\n \"count\": {},\n \"queryExecStats\": {}\n }`,\n },\n {\n key: \"$count\",\n template: ``,\n },\n {\n key: \"$densify\",\n template: `{\n \"field\": \"\",\n \"partitionByFields\": [],\n \"range\": {\n \"step\": 1,\n \"unit\": 1,\n \"bounds\": \"full\"\n }\n }`,\n },\n {\n key: \"$documents\",\n template: `[]`,\n },\n {\n key: \"$facet\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$fill\",\n template: `{\n \"partitionBy\": \"\",\n \"partitionByFields\": [],\n \"sortBy\": {},\n \"output\": {}\n }`,\n },\n {\n key: \"$geoNear\",\n template: `{\n \"near\": { \n \"type\": \"Point\", \n \"coordinates\": [ \n -73.98142, 40.71782\n ] \n },\n \"key\": \"location\",\n \"distanceField\": \"dist.calculated\",\n \"query\": { \"category\": \"Parks\" }\n }`,\n },\n {\n key: \"$graphLookup\",\n template: `{\n \"from\": \"\",\n \"startWith\": \"\",\n \"connectFromField\": \"\",\n \"connectToField\": \"\",\n \"as\": \"\",\n \"maxDepth\": 1,\n \"depthField\": \"\",\n \"restrictSearchWithMatch\": {}\n }`,\n },\n {\n key: \"$group\",\n template: `{\n \"_id\": \"\"\n }`,\n },\n {\n key: \"$indexStats\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$limit\",\n template: `1`,\n },\n {\n key: \"$listLocalSessions\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$listSessions\",\n template: `{\\n\\t\\n}`,\n },\n {\n key: \"$lookup\",\n template: `{\n \"from\": \"\",\n \"localField\": \"\",\n \"foreignField\": \"\",\n \"as\": \"\"\n }`,\n },\n {\n key: \"$match\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$merge\",\n template: `{\n \"into\": {},\n \"on\": \"_id\",\n \"whenMatched\": \"replace\",\n \"whenNotMatched\": \"insert\"\n }`,\n },\n {\n key: \"$out\",\n template: `{\n \"db\": \"\",\n \"coll\": \"\"\n }`,\n },\n {\n key: \"$planCacheStats\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$project\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$redact\",\n template: \"\",\n },\n {\n key: \"$replaceRoot\",\n template: `{ \"newRoot\": \"\" }`,\n },\n {\n key: \"$replaceWith\",\n template: ``,\n },\n {\n key: \"$sample\",\n template: `{ \"size\": 3 }`,\n },\n {\n key: \"$set\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$setWindowFields\",\n template: `{\n \"partitionBy\": \"\",\n \"sortBy\": {},\n \"output\": {}\n }`,\n },\n {\n key: \"$skip\",\n template: `1`,\n },\n {\n key: \"$sort\",\n template: \"{\\n\\t\\n}\",\n },\n {\n key: \"$sortByCount\",\n template: \"\",\n },\n {\n key: \"$unionWith\",\n template: `{\n \"coll\": \"\",\n \"pipeline\": []\n }`,\n },\n {\n key: \"$unset\",\n template: \"\",\n },\n {\n key: \"$unwind\",\n template: `{\n \"path\": \"\",\n \"includeArrayIndex\": \"\",\n \"preserveNullAndEmptyArrays\": true\n }`,\n },\n ],\n },\n },\n extra: {\n collection: {\n displayName: \"Collection\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n actionType: {\n displayName: \"Query Type\",\n type: DatasourceFieldType.LIST,\n required: true,\n data: {\n read: [\"find\", \"findOne\", \"findOneAndUpdate\", \"count\", \"distinct\"],\n create: [\"insertOne\", \"insertMany\"],\n update: [\"updateOne\", \"updateMany\"],\n delete: [\"deleteOne\", \"deleteMany\"],\n aggregate: [\"json\", \"pipeline\"],\n },\n },\n },\n }\n if (environment.SELF_HOSTED) {\n schema.datasource = {\n ...schema.datasource,\n //@ts-ignore\n tls: {\n type: DatasourceFieldType.FIELD_GROUP,\n display: \"Configure SSL\",\n fields: {\n tlsCertificateFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"Certificate file path\",\n },\n tlsCertificateKeyFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"Certificate Key file path\",\n },\n tlsCAFile: {\n type: DatasourceFieldType.STRING,\n required: false,\n display: \"CA file path\",\n },\n },\n },\n }\n }\n return schema\n}\n\nconst SCHEMA: Integration = getSchema()\n\nclass MongoIntegration implements IntegrationBase {\n private config: MongoDBConfig\n private client: any\n\n constructor(config: MongoDBConfig) {\n this.config = config\n const options: MongoClientOptions = {\n tlsCertificateFile: config.tlsCertificateFile || undefined,\n tlsCertificateKeyFile: config.tlsCertificateKeyFile || undefined,\n tlsCAFile: config.tlsCAFile || undefined,\n }\n this.client = new MongoClient(config.connectionString, options)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.connect()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async connect() {\n return this.client.connect()\n }\n\n createObjectIds(json: any): object {\n const self = this\n function interpolateObjectIds(json: any) {\n for (let field of Object.keys(json)) {\n if (json[field] instanceof Object) {\n json[field] = self.createObjectIds(json[field])\n }\n if (\n typeof json[field] === \"string\" &&\n json[field].toLowerCase().startsWith(\"objectid\")\n ) {\n const id = json[field].match(/(?<=objectid\\(['\"]).*(?=['\"]\\))/gi)?.[0]\n if (id) {\n json[field] = ObjectId.createFromHexString(id)\n }\n }\n }\n return json\n }\n\n if (Array.isArray(json)) {\n for (let i = 0; i < json.length; i++) {\n json[i] = interpolateObjectIds(json[i])\n }\n return json\n }\n return interpolateObjectIds(json)\n }\n\n parseQueryParams(params: string, mode: string) {\n let queryParams = []\n let openCount = 0\n let inQuotes = false\n let i = 0\n let startIndex = 0\n for (let c of params) {\n if (c === '\"' && i > 0 && params[i - 1] !== \"\\\\\") {\n inQuotes = !inQuotes\n }\n if (c === \"{\" && !inQuotes) {\n openCount++\n if (openCount === 1) {\n startIndex = i\n }\n } else if (c === \"}\" && !inQuotes) {\n if (openCount === 1) {\n queryParams.push(JSON.parse(params.substring(startIndex, i + 1)))\n }\n openCount--\n }\n i++\n }\n let group1 = queryParams[0] ?? {}\n let group2 = queryParams[1] ?? {}\n let group3 = queryParams[2] ?? {}\n if (mode === \"update\") {\n return {\n filter: group1,\n update: group2,\n options: group3,\n }\n }\n return {\n filter: group1,\n options: group2,\n }\n }\n\n async create(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let json = this.createObjectIds(query.json)\n\n // For mongodb we add an extra actionType to specify\n // which method we want to call on the collection\n switch (query.extra.actionType) {\n case \"insertOne\": {\n return await collection.insertOne(json)\n }\n case \"insertMany\": {\n return await collection.insertMany(json)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for create`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async read(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let json = this.createObjectIds(query.json)\n\n switch (query.extra.actionType) {\n case \"find\": {\n return await collection.find(json).toArray()\n }\n case \"findOne\": {\n return await collection.findOne(json)\n }\n case \"findOneAndUpdate\": {\n if (typeof query.json === \"string\") {\n json = this.parseQueryParams(query.json, \"update\")\n }\n let findAndUpdateJson = this.createObjectIds(json) as {\n filter: Filter<any>\n update: UpdateFilter<any>\n options: FindOneAndUpdateOptions\n }\n return await collection.findOneAndUpdate(\n findAndUpdateJson.filter,\n findAndUpdateJson.update,\n findAndUpdateJson.options\n )\n }\n case \"count\": {\n return await collection.countDocuments(json)\n }\n case \"distinct\": {\n return await collection.distinct(json)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for read`\n )\n }\n }\n } catch (err) {\n console.error(\"Error querying mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async update(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let queryJson = query.json\n if (typeof queryJson === \"string\") {\n queryJson = this.parseQueryParams(queryJson, \"update\")\n }\n let json = this.createObjectIds(queryJson) as {\n filter: Filter<any>\n update: UpdateFilter<any>\n options: object\n }\n\n switch (query.extra.actionType) {\n case \"updateOne\": {\n return await collection.updateOne(\n json.filter,\n json.update,\n json.options as UpdateOptions\n )\n }\n case \"updateMany\": {\n return await collection.updateMany(\n json.filter,\n json.update,\n json.options as UpdateOptions\n )\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for update`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async delete(query: MongoDBQuery) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let queryJson = query.json\n if (typeof queryJson === \"string\") {\n queryJson = this.parseQueryParams(queryJson, \"delete\")\n }\n let json = this.createObjectIds(queryJson) as {\n filter: Filter<any>\n options: OperationOptions\n }\n if (!json.options) {\n json = {\n filter: json,\n options: {},\n }\n }\n\n switch (query.extra.actionType) {\n case \"deleteOne\": {\n return await collection.deleteOne(json.filter, json.options)\n }\n case \"deleteMany\": {\n return await collection.deleteMany(json.filter, json.options)\n }\n default: {\n throw new Error(\n `actionType ${query.extra.actionType} does not exist on DB for delete`\n )\n }\n }\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async aggregate(query: {\n json: object\n steps: any[]\n extra: { [key: string]: string }\n }) {\n try {\n await this.connect()\n const db = this.client.db(this.config.db)\n const collection = db.collection(query.extra.collection)\n let response = []\n if (query.extra?.actionType === \"pipeline\") {\n for await (const doc of collection.aggregate(\n query.steps.map(({ key, value }) => {\n let temp: any = {}\n temp[key] = JSON.parse(value.value)\n return this.createObjectIds(temp)\n })\n )) {\n response.push(doc)\n }\n } else {\n const stages: Array<any> = query.json as Array<any>\n for await (const doc of collection.aggregate(\n stages ? this.createObjectIds(stages) : []\n )) {\n response.push(doc)\n }\n }\n return response\n } catch (err) {\n console.error(\"Error writing to mongodb\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: MongoIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport { Client, ClientOptions } from \"@elastic/elasticsearch\"\n\ninterface ElasticsearchConfig {\n url: string\n ssl?: boolean\n ca?: string\n rejectUnauthorized?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html\",\n description:\n \"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.\",\n friendlyName: \"ElasticSearch\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"http://localhost:9200\",\n },\n ssl: {\n type: DatasourceFieldType.BOOLEAN,\n default: false,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n ca: {\n type: DatasourceFieldType.LONGFORM,\n default: false,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n index: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass ElasticSearchIntegration implements IntegrationBase {\n private config: ElasticsearchConfig\n private client\n\n constructor(config: ElasticsearchConfig) {\n this.config = config\n\n const clientConfig: ClientOptions = {\n node: this.config.url,\n }\n\n if (this.config.ssl) {\n clientConfig.ssl = {\n rejectUnauthorized: this.config.rejectUnauthorized,\n ca: this.config.ca || undefined,\n }\n }\n\n this.client = new Client(clientConfig)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.info()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { index: string; json: object }) {\n const { index, json } = query\n\n try {\n const result = await this.client.index({\n index,\n body: json,\n })\n return result.body\n } catch (err) {\n console.error(\"Error writing to elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async read(query: { index: string; json: object }) {\n const { index, json } = query\n try {\n const result = await this.client.search({\n index: index,\n body: json,\n })\n return result.body.hits.hits.map(({ _source }: any) => _source)\n } catch (err) {\n console.error(\"Error querying elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async update(query: { id: string; index: string; json: object }) {\n const { id, index, json } = query\n try {\n const result = await this.client.update({\n id,\n index,\n body: json,\n })\n return result.body\n } catch (err) {\n console.error(\"Error querying elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n\n async delete(query: { id: string; index: string }) {\n const { id, index } = query\n try {\n const result = await this.client.delete({\n id,\n index,\n })\n return result.body\n } catch (err) {\n console.error(\"Error deleting from elasticsearch\", err)\n throw err\n } finally {\n await this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: ElasticSearchIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Document,\n Integration,\n IntegrationBase,\n QueryType,\n} from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\n\ninterface CouchDBConfig {\n url: string\n database: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://docs.couchdb.org/en/stable/\",\n friendlyName: \"CouchDB\",\n type: \"Non-relational\",\n description:\n \"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"http://localhost:5984\",\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n get: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n id: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n },\n}\n\nclass CouchDBIntegration implements IntegrationBase {\n private readonly client: dbCore.DatabaseImpl\n\n constructor(config: CouchDBConfig) {\n this.client = dbCore.DatabaseWithConnection(config.database, config.url)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const result = await this.query(\"exists\", \"validation error\", {})\n response.connected = result === true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async query(\n command: string,\n errorMsg: string,\n query: { json?: object; id?: string }\n ) {\n try {\n return await (this.client as any)[command](query.id || query.json)\n } catch (err) {\n console.error(errorMsg, err)\n throw err\n }\n }\n\n private parse(query: { json: string | object }) {\n return typeof query.json === \"string\" ? JSON.parse(query.json) : query.json\n }\n\n async create(query: { json: string | object }) {\n const parsed = this.parse(query)\n return this.query(\"post\", \"Error writing to couchDB\", { json: parsed })\n }\n\n async read(query: { json: string | object }) {\n const parsed = this.parse(query)\n const result = await this.query(\"allDocs\", \"Error querying couchDB\", {\n json: {\n include_docs: true,\n ...parsed,\n },\n })\n return result.rows.map((row: { doc: object }) => row.doc)\n }\n\n async update(query: { json: string | object }) {\n const parsed: Document = this.parse(query)\n if (!parsed?._rev && parsed?._id) {\n const oldDoc = await this.get({ id: parsed._id })\n parsed._rev = oldDoc._rev\n }\n return this.query(\"put\", \"Error updating couchDB document\", {\n json: parsed,\n })\n }\n\n async get(query: { id: string }) {\n return this.query(\"get\", \"Error retrieving couchDB document by ID\", {\n id: query.id,\n })\n }\n\n async delete(query: { id: string }) {\n const doc = await this.query(\"get\", \"Cannot find doc to be deleted\", query)\n return this.query(\"remove\", \"Error deleting couchDB document\", {\n json: doc,\n })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: CouchDBIntegration,\n}\n", "import {\n DatasourceFieldType,\n Integration,\n Operation,\n Table,\n TableSchema,\n QueryJson,\n QueryType,\n SqlQuery,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { MSSQLTablesResponse, MSSQLColumn } from \"./base/types\"\nconst sqlServer = require(\"mssql\")\nconst DEFAULT_SCHEMA = \"dbo\"\n\ninterface MSSQLConfig {\n user: string\n password: string\n server: string\n port: number | string\n database: string\n schema: string\n encrypt?: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/tediousjs/node-mssql\",\n plus: true,\n description:\n \"Microsoft SQL Server is a relational database management system developed by Microsoft. \",\n friendlyName: \"MS SQL Server\",\n type: \"Relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n user: {\n type: DatasourceFieldType.STRING,\n required: true,\n default: \"localhost\",\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n server: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: false,\n default: 1433,\n },\n database: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n },\n schema: {\n type: DatasourceFieldType.STRING,\n default: DEFAULT_SCHEMA,\n },\n encrypt: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass SqlServerIntegration extends Sql implements DatasourcePlus {\n private readonly config: MSSQLConfig\n private index: number = 0\n private readonly pool: any\n private client: any\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n MASTER_TABLES = [\n \"spt_fallback_db\",\n \"spt_fallback_dev\",\n \"spt_fallback_usg\",\n \"spt_monitor\",\n \"MSreplication_options\",\n ]\n TABLES_SQL =\n \"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'\"\n\n constructor(config: MSSQLConfig) {\n super(SqlClient.MS_SQL)\n this.config = config\n const clientCfg = {\n ...this.config,\n options: {\n encrypt: this.config.encrypt,\n enableArithAbort: true,\n },\n }\n delete clientCfg.encrypt\n if (!this.pool) {\n this.pool = new sqlServer.ConnectionPool(clientCfg)\n }\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.connect()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return `@p${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return `concat(${parts.join(\", \")})`\n }\n\n async connect() {\n try {\n this.client = await this.pool.connect()\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n }\n }\n\n async internalQuery(\n query: SqlQuery,\n operation: string | undefined = undefined\n ) {\n const client = this.client\n const request = client.request()\n this.index = 0\n try {\n if (Array.isArray(query.bindings)) {\n let count = 0\n for (let binding of query.bindings) {\n request.input(`p${count++}`, binding)\n }\n }\n // this is a hack to get the inserted ID back,\n // no way to do this with Knex nicely\n const sql =\n operation === Operation.CREATE\n ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`\n : query.sql\n return await request.query(sql)\n } catch (err) {\n // @ts-ignore\n throw new Error(err)\n }\n }\n\n getDefinitionSQL(tableName: string) {\n return `select *\n from INFORMATION_SCHEMA.COLUMNS\n where TABLE_NAME='${tableName}'`\n }\n\n getConstraintsSQL(tableName: string) {\n return `SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC \n INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU\n ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' \n AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME \n AND KU.table_name='${tableName}'\n ORDER BY \n KU.TABLE_NAME,\n KU.ORDINAL_POSITION;`\n }\n\n getAutoColumnsSQL(tableName: string) {\n return `SELECT \n COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed') \n AS IS_COMPUTED,\n COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity')\n AS IS_IDENTITY,\n *\n FROM INFORMATION_SCHEMA.COLUMNS\n WHERE TABLE_NAME='${tableName}'`\n }\n\n async runSQL(sql: string) {\n return (await this.internalQuery(getSqlQuery(sql))).recordset\n }\n\n /**\n * Fetches the tables from the sql server database and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n await this.connect()\n let tableInfo: MSSQLTablesResponse[] = await this.runSQL(this.TABLES_SQL)\n if (tableInfo == null || !Array.isArray(tableInfo)) {\n throw \"Unable to get list of tables in database\"\n }\n\n const schema = this.config.schema || DEFAULT_SCHEMA\n const tableNames = tableInfo\n .filter((record: any) => record.TABLE_SCHEMA === schema)\n .map((record: any) => record.TABLE_NAME)\n .filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)\n\n const tables: Record<string, Table> = {}\n for (let tableName of tableNames) {\n // get the column definition (type)\n const definition = await this.runSQL(this.getDefinitionSQL(tableName))\n // find primary key constraints\n const constraints = await this.runSQL(this.getConstraintsSQL(tableName))\n // find the computed and identity columns (auto columns)\n const columns: MSSQLColumn[] = await this.runSQL(\n this.getAutoColumnsSQL(tableName)\n )\n const primaryKeys = constraints\n .filter(\n (constraint: any) => constraint.CONSTRAINT_TYPE === \"PRIMARY KEY\"\n )\n .map((constraint: any) => constraint.COLUMN_NAME)\n const autoColumns = columns\n .filter(col => col.IS_COMPUTED || col.IS_IDENTITY)\n .map(col => col.COLUMN_NAME)\n const requiredColumns = columns\n .filter(col => col.IS_NULLABLE === \"NO\")\n .map(col => col.COLUMN_NAME)\n\n let schema: TableSchema = {}\n for (let def of definition) {\n const name = def.COLUMN_NAME\n if (typeof name !== \"string\") {\n continue\n }\n const hasDefault = def.COLUMN_DEFAULT\n const isAuto = !!autoColumns.find(col => col === name)\n const required = !!requiredColumns.find(col => col === name)\n schema[name] = {\n autocolumn: isAuto,\n name: name,\n constraints: {\n presence: required && !isAuto && !hasDefault,\n },\n ...convertSqlType(def.DATA_TYPE),\n externalType: def.DATA_TYPE,\n }\n }\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: primaryKeys,\n name: tableName,\n schema,\n }\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async queryTableNames() {\n let tableInfo: MSSQLTablesResponse[] = await this.runSQL(this.TABLES_SQL)\n const schema = this.config.schema || DEFAULT_SCHEMA\n return tableInfo\n .filter((record: any) => record.TABLE_SCHEMA === schema)\n .map((record: any) => record.TABLE_NAME)\n .filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)\n }\n\n async getTableNames() {\n await this.connect()\n return this.queryTableNames()\n }\n\n async read(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset\n }\n\n async create(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ created: true }]\n }\n\n async update(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n await this.connect()\n const response = await this.internalQuery(getSqlQuery(query))\n return response.recordset || [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const schema = this.config.schema\n await this.connect()\n if (schema && schema !== DEFAULT_SCHEMA && json?.endpoint) {\n json.endpoint.schema = schema\n }\n const operation = this._operation(json)\n const queryFn = (query: any, op: string) => this.internalQuery(query, op)\n const processFn = (result: any) =>\n result.recordset ? result.recordset : [{ [operation]: true }]\n return this.queryWithReturning(json, queryFn, processFn)\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: SqlServerIntegration,\n}\n", "import {\n Integration,\n QueryType,\n IntegrationBase,\n DatasourceFieldType,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport AWS from \"aws-sdk\"\nimport csv from \"csvtojson\"\n\ninterface S3Config {\n region: string\n accessKeyId: string\n secretAccessKey: string\n s3ForcePathStyle: boolean\n endpoint?: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html\",\n description:\n \"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.\",\n friendlyName: \"Amazon S3\",\n type: \"Object store\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n region: {\n type: \"string\",\n required: false,\n default: \"us-east-1\",\n },\n accessKeyId: {\n type: \"password\",\n required: true,\n },\n secretAccessKey: {\n type: \"password\",\n required: true,\n },\n endpoint: {\n type: \"string\",\n required: false,\n },\n signatureVersion: {\n type: \"string\",\n required: false,\n default: \"v4\",\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n display: \"New Bucket\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n location: {\n required: true,\n default: \"us-east-1\",\n type: DatasourceFieldType.STRING,\n },\n grantFullControl: {\n display: \"Grant full control\",\n type: DatasourceFieldType.STRING,\n },\n grantRead: {\n display: \"Grant read\",\n type: DatasourceFieldType.STRING,\n },\n grantReadAcp: {\n display: \"Grant read ACP\",\n type: DatasourceFieldType.STRING,\n },\n grantWrite: {\n display: \"Grant write\",\n type: DatasourceFieldType.STRING,\n },\n grantWriteAcp: {\n display: \"Grant write ACP\",\n type: DatasourceFieldType.STRING,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n delimiter: {\n type: DatasourceFieldType.STRING,\n },\n marker: {\n type: DatasourceFieldType.STRING,\n },\n maxKeys: {\n type: DatasourceFieldType.NUMBER,\n display: \"Max Keys\",\n },\n prefix: {\n type: DatasourceFieldType.STRING,\n },\n },\n },\n readCsv: {\n displayName: \"Read CSV\",\n type: QueryType.FIELDS,\n readable: true,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n bucket: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n delete: {\n type: DatasourceFieldType.JSON,\n required: true,\n },\n },\n },\n },\n extra: {\n acl: {\n required: false,\n displayName: \"ACL\",\n type: DatasourceFieldType.LIST,\n data: {\n create: [\n \"private\",\n \"public-read\",\n \"public-read-write\",\n \"authenticated-read\",\n ],\n },\n },\n },\n}\n\nclass S3Integration implements IntegrationBase {\n private readonly config: S3Config\n private client\n\n constructor(config: S3Config) {\n this.config = config\n if (this.config.endpoint) {\n this.config.s3ForcePathStyle = true\n } else {\n delete this.config.endpoint\n }\n\n this.client = new AWS.S3(this.config)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.listBuckets().promise()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async create(query: {\n bucket: string\n location: string\n grantFullControl: string\n grantRead: string\n grantReadAcp: string\n grantWrite: string\n grantWriteAcp: string\n extra: {\n acl: string\n }\n }) {\n let params: any = {\n Bucket: query.bucket,\n ACL: query.extra?.acl,\n GrantFullControl: query.grantFullControl,\n GrantRead: query.grantRead,\n GrantReadACP: query.grantReadAcp,\n GrantWrite: query.grantWrite,\n GrantWriteACP: query.grantWriteAcp,\n }\n if (query.location) {\n params[\"CreateBucketConfiguration\"] = {\n LocationConstraint: query.location,\n }\n }\n return await this.client.createBucket(params).promise()\n }\n\n async read(query: {\n bucket: string\n delimiter: string\n expectedBucketOwner: string\n marker: string\n maxKeys: number\n prefix: string\n }) {\n const response = await this.client\n .listObjects({\n Bucket: query.bucket,\n Delimiter: query.delimiter,\n Marker: query.marker,\n MaxKeys: query.maxKeys,\n Prefix: query.prefix,\n })\n .promise()\n return response.Contents\n }\n\n async readCsv(query: { bucket: string; key: string }) {\n const stream = this.client\n .getObject({\n Bucket: query.bucket,\n Key: query.key,\n })\n .createReadStream()\n\n let csvError = false\n return new Promise((resolve, reject) => {\n stream.on(\"error\", (err: Error) => {\n reject(err)\n })\n const response = csv()\n .fromStream(stream)\n .on(\"error\", () => {\n csvError = true\n })\n stream.on(\"finish\", () => {\n resolve(response)\n })\n }).catch(err => {\n if (csvError) {\n throw new Error(\"Could not read CSV\")\n } else {\n throw err\n }\n })\n }\n\n async delete(query: { bucket: string; delete: string }) {\n return await this.client\n .deleteObjects({\n Bucket: query.bucket,\n Delete: JSON.parse(query.delete),\n })\n .promise()\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: S3Integration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Integration,\n IntegrationBase,\n QueryType,\n} from \"@budibase/types\"\n\nimport Airtable from \"airtable\"\n\ninterface AirtableConfig {\n apiKey: string\n base: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://airtable.com/api\",\n description:\n \"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.\",\n friendlyName: \"Airtable\",\n type: \"Spreadsheet\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n apiKey: {\n type: DatasourceFieldType.PASSWORD,\n default: \"enter api key\",\n required: true,\n },\n base: {\n type: DatasourceFieldType.STRING,\n default: \"mybase\",\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n view: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n numRecords: {\n type: DatasourceFieldType.NUMBER,\n default: 10,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n customisable: true,\n fields: {\n id: {\n display: \"Record ID\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n table: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.JSON,\n },\n },\n}\n\nclass AirtableIntegration implements IntegrationBase {\n private config: AirtableConfig\n private client\n\n constructor(config: AirtableConfig) {\n this.config = config\n this.client = new Airtable(config).base(config.base)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n const mockTable = Date.now().toString()\n try {\n await this.client.makeRequest({\n path: `/${mockTable}`,\n })\n\n return { connected: true }\n } catch (e: any) {\n if (\n e.message ===\n `Could not find table ${mockTable} in application ${this.config.base}`\n ) {\n // The request managed to check the application, so the credentials are valid\n return { connected: true }\n }\n\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { table: any; json: any }) {\n const { table, json } = query\n\n try {\n return await this.client(table).create([\n {\n fields: json,\n },\n ])\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n\n async read(query: { table: any; numRecords: any; view: any }) {\n try {\n const records = await this.client(query.table)\n .select({ maxRecords: query.numRecords || 10, view: query.view })\n .firstPage()\n // @ts-ignore\n return records.map(({ fields }) => fields)\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n return []\n }\n }\n\n async update(query: { table: any; id: any; json: any }) {\n const { table, id, json } = query\n\n try {\n return await this.client(table).update([\n {\n id,\n fields: json,\n },\n ])\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n\n async delete(query: { table: any; ids: any }) {\n try {\n return await this.client(query.table).destroy(query.ids)\n } catch (err) {\n console.error(\"Error writing to airtable\", err)\n throw err\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: AirtableIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n QueryJson,\n SqlQuery,\n Table,\n TableSchema,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n getSqlQuery,\n SqlClient,\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n} from \"./utils\"\nimport dayjs from \"dayjs\"\nimport { NUMBER_REGEX } from \"../utilities\"\nimport Sql from \"./base/sql\"\nimport { MySQLColumn } from \"./base/types\"\n\nimport mysql from \"mysql2/promise\"\n\ninterface MySQLConfig extends mysql.ConnectionOptions {\n database: string\n rejectUnauthorized: boolean\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/sidorares/node-mysql2\",\n plus: true,\n friendlyName: \"MySQL\",\n type: \"Relational\",\n description:\n \"MySQL Database Service is a fully managed database service to deploy cloud-native applications. \",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n default: 3306,\n required: false,\n },\n user: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n default: \"root\",\n required: true,\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n ssl: {\n type: DatasourceFieldType.OBJECT,\n required: false,\n },\n rejectUnauthorized: {\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nfunction bindingTypeCoerce(bindings: any[]) {\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i]\n if (typeof binding !== \"string\") {\n continue\n }\n const matches = binding.match(NUMBER_REGEX)\n // check if number first\n if (matches && matches[0] !== \"\" && !isNaN(Number(matches[0]))) {\n bindings[i] = parseFloat(binding)\n }\n // if not a number, see if it is a date - important to do in this order as any\n // integer will be considered a valid date\n else if (\n /^\\d/.test(binding) &&\n dayjs(binding).isValid() &&\n !binding.includes(\",\")\n ) {\n bindings[i] = dayjs(binding).toDate()\n }\n }\n return bindings\n}\n\nclass MySQLIntegration extends Sql implements DatasourcePlus {\n private config: MySQLConfig\n private client?: mysql.Connection\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n constructor(config: MySQLConfig) {\n super(SqlClient.MY_SQL)\n this.config = config\n if (config.ssl && Object.keys(config.ssl).length === 0) {\n delete config.ssl\n }\n // make sure this defaults to true\n if (\n config.rejectUnauthorized != null &&\n !config.rejectUnauthorized &&\n config.ssl &&\n typeof config.ssl !== \"string\"\n ) {\n config.ssl.rejectUnauthorized = config.rejectUnauthorized\n }\n // @ts-ignore\n delete config.rejectUnauthorized\n this.config = {\n ...config,\n multipleStatements: true,\n typeCast: function (field: any, next: any) {\n if (\n field.type == \"DATETIME\" ||\n field.type === \"DATE\" ||\n field.type === \"TIMESTAMP\" ||\n field.type === \"LONGLONG\"\n ) {\n return field.string()\n }\n if (field.type === \"BIT\" && field.length === 1) {\n return field.buffer()?.[0]\n }\n return next()\n },\n }\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n const [result] = await this.internalQuery(\n { sql: \"SELECT 1+1 AS checkRes\" },\n { connect: true }\n )\n response.connected = result?.checkRes == 2\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n getBindingIdentifier(): string {\n return \"?\"\n }\n\n getStringConcat(parts: string[]): string {\n return `concat(${parts.join(\", \")})`\n }\n\n async connect() {\n this.client = await mysql.createConnection(this.config)\n }\n\n async disconnect() {\n await this.client!.end()\n }\n\n async internalQuery(\n query: SqlQuery,\n opts: { connect?: boolean; disableCoercion?: boolean } = {\n connect: true,\n disableCoercion: false,\n }\n ): Promise<any[] | any> {\n try {\n if (opts?.connect) {\n await this.connect()\n }\n const baseBindings = query.bindings || []\n const bindings = opts?.disableCoercion\n ? baseBindings\n : bindingTypeCoerce(baseBindings)\n // Node MySQL is callback based, so we must wrap our call in a promise\n const response = await this.client!.query(query.sql, bindings)\n return response[0]\n } finally {\n if (opts?.connect && this.client) {\n await this.disconnect()\n }\n }\n }\n\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n const tables: { [key: string]: Table } = {}\n await this.connect()\n\n try {\n // get the tables first\n const tableNames = await this.queryTableNames()\n for (let tableName of tableNames) {\n const primaryKeys = []\n const schema: TableSchema = {}\n const descResp: MySQLColumn[] = await this.internalQuery(\n { sql: `DESCRIBE \\`${tableName}\\`;` },\n { connect: false }\n )\n for (let column of descResp) {\n const columnName = column.Field\n if (column.Key === \"PRI\" && primaryKeys.indexOf(column.Key) === -1) {\n primaryKeys.push(columnName)\n }\n const hasDefault = column.Default != null\n const isAuto: boolean =\n typeof column.Extra === \"string\" &&\n (column.Extra === \"auto_increment\" ||\n column.Extra.toLowerCase().includes(\"generated\"))\n const required = column.Null !== \"YES\"\n const constraints = {\n presence: required && !isAuto && !hasDefault,\n }\n schema[columnName] = {\n name: columnName,\n autocolumn: isAuto,\n constraints,\n ...convertSqlType(column.Type),\n externalType: column.Type,\n }\n }\n if (!tables[tableName]) {\n tables[tableName] = {\n _id: buildExternalTableId(datasourceId, tableName),\n primary: primaryKeys,\n name: tableName,\n schema,\n }\n }\n }\n } finally {\n await this.disconnect()\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async queryTableNames() {\n const database = this.config.database\n const tablesResp: Record<string, string>[] = await this.internalQuery(\n { sql: \"SHOW TABLES;\" },\n { connect: false }\n )\n return tablesResp.map(\n (obj: any) =>\n obj[`Tables_in_${database}`] ||\n obj[`Tables_in_${database.toLowerCase()}`]\n )\n }\n\n async getTableNames() {\n await this.connect()\n try {\n return this.queryTableNames()\n } finally {\n await this.disconnect()\n }\n }\n\n async create(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ created: true }]\n }\n\n async read(query: SqlQuery | string) {\n return this.internalQuery(getSqlQuery(query))\n }\n\n async update(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string) {\n const results = await this.internalQuery(getSqlQuery(query))\n return results.length ? results : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n await this.connect()\n try {\n const queryFn = (query: any) =>\n this.internalQuery(query, { connect: false, disableCoercion: true })\n return await this.queryWithReturning(json, queryFn)\n } finally {\n await this.disconnect()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: MySQLIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\n\nimport { Database, aql } from \"arangojs\"\n\ninterface ArangodbConfig {\n url: string\n username: string\n password: string\n databaseName: string\n collection: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/arangodb/arangojs\",\n friendlyName: \"ArangoDB\",\n type: \"Non-relational\",\n description:\n \"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. \",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n default: \"http://localhost:8529\",\n required: true,\n },\n username: {\n type: DatasourceFieldType.STRING,\n default: \"root\",\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n databaseName: {\n type: DatasourceFieldType.STRING,\n default: \"_system\",\n required: true,\n },\n collection: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n read: {\n type: QueryType.SQL,\n },\n create: {\n type: QueryType.JSON,\n },\n },\n}\n\nclass ArangoDBIntegration implements IntegrationBase {\n private config: ArangodbConfig\n private client\n\n constructor(config: ArangodbConfig) {\n const newConfig = {\n url: config.url,\n databaseName: config.databaseName,\n auth: {\n username: config.username,\n password: config.password,\n },\n }\n\n this.config = config\n this.client = new Database(newConfig)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.get()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n }\n return response\n }\n\n async read(query: { sql: any }) {\n try {\n const result = await this.client.query(query.sql)\n return result.all()\n } catch (err) {\n // @ts-ignore\n console.error(\"Error querying arangodb\", err.message)\n throw err\n } finally {\n this.client.close()\n }\n }\n\n async create(query: { json: any }) {\n const clc = this.client.collection(this.config.collection)\n try {\n const result = await this.client.query(\n aql`INSERT ${query.json} INTO ${clc} RETURN NEW`\n )\n return result.all()\n } catch (err) {\n // @ts-ignore\n console.error(\"Error querying arangodb\", err.message)\n throw err\n } finally {\n this.client.close()\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: ArangoDBIntegration,\n}\n", "import {\n Integration,\n DatasourceFieldType,\n QueryType,\n PaginationConfig,\n IntegrationBase,\n PaginationValues,\n RestQueryFields as RestQuery,\n RestConfig,\n RestAuthType,\n RestBasicAuthConfig,\n RestBearerAuthConfig,\n} from \"@budibase/types\"\nimport { get } from \"lodash\"\nimport * as https from \"https\"\nimport qs from \"querystring\"\nimport fetch from \"node-fetch\"\nimport { formatBytes } from \"../utilities\"\nimport { performance } from \"perf_hooks\"\nimport FormData from \"form-data\"\nimport { URLSearchParams } from \"url\"\nimport { blacklist } from \"@budibase/backend-core\"\n\nconst BodyTypes = {\n NONE: \"none\",\n FORM_DATA: \"form\",\n XML: \"xml\",\n ENCODED: \"encoded\",\n JSON: \"json\",\n TEXT: \"text\",\n}\n\nconst coreFields = {\n path: {\n type: DatasourceFieldType.STRING,\n display: \"URL\",\n },\n queryString: {\n type: DatasourceFieldType.STRING,\n },\n headers: {\n type: DatasourceFieldType.OBJECT,\n },\n enabledHeaders: {\n type: DatasourceFieldType.OBJECT,\n },\n requestBody: {\n type: DatasourceFieldType.JSON,\n },\n bodyType: {\n type: DatasourceFieldType.STRING,\n enum: Object.values(BodyTypes),\n },\n pagination: {\n type: DatasourceFieldType.OBJECT,\n },\n}\n\nconst { parseStringPromise: xmlParser, Builder: XmlBuilder } = require(\"xml2js\")\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/node-fetch/node-fetch\",\n description:\n \"With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.\",\n friendlyName: \"REST API\",\n type: \"API\",\n datasource: {\n url: {\n type: DatasourceFieldType.STRING,\n default: \"\",\n required: false,\n deprecated: true,\n },\n defaultHeaders: {\n type: DatasourceFieldType.OBJECT,\n required: false,\n default: {},\n },\n rejectUnauthorized: {\n display: \"Reject Unauthorized\",\n type: DatasourceFieldType.BOOLEAN,\n default: true,\n required: false,\n },\n },\n query: {\n create: {\n readable: true,\n displayName: \"POST\",\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n read: {\n displayName: \"GET\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n update: {\n displayName: \"PUT\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n patch: {\n displayName: \"PATCH\",\n readable: true,\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n delete: {\n displayName: \"DELETE\",\n type: QueryType.FIELDS,\n fields: coreFields,\n },\n },\n}\n\nclass RestIntegration implements IntegrationBase {\n private config: RestConfig\n private headers: {\n [key: string]: string\n } = {}\n private startTimeMs: number = performance.now()\n\n constructor(config: RestConfig) {\n this.config = config\n }\n\n async parseResponse(response: any, pagination: PaginationConfig | null) {\n let data, raw, headers\n const contentType = response.headers.get(\"content-type\") || \"\"\n try {\n if (contentType.includes(\"application/json\")) {\n data = await response.json()\n raw = JSON.stringify(data)\n } else if (\n contentType.includes(\"text/xml\") ||\n contentType.includes(\"application/xml\")\n ) {\n const rawXml = await response.text()\n data =\n (await xmlParser(rawXml, {\n explicitArray: false,\n trim: true,\n explicitRoot: false,\n })) || {}\n // there is only one structure, its an array, return the array so it appears as rows\n const keys = Object.keys(data)\n if (keys.length === 1 && Array.isArray(data[keys[0]])) {\n data = data[keys[0]]\n }\n raw = rawXml\n } else if (contentType.includes(\"application/pdf\")) {\n data = await response.arrayBuffer() // Save PDF as ArrayBuffer\n raw = Buffer.from(data)\n } else {\n data = await response.text()\n raw = data\n }\n } catch (err) {\n throw \"Failed to parse response body.\"\n }\n const size = formatBytes(\n response.headers.get(\"content-length\") || Buffer.byteLength(raw, \"utf8\")\n )\n const time = `${Math.round(performance.now() - this.startTimeMs)}ms`\n headers = response.headers.raw()\n for (let [key, value] of Object.entries(headers)) {\n headers[key] = Array.isArray(value) ? value[0] : value\n }\n\n // Check if a pagination cursor exists in the response\n let nextCursor = null\n if (pagination?.responseParam) {\n nextCursor = get(data, pagination.responseParam)\n }\n\n return {\n data,\n info: {\n code: response.status,\n size,\n time,\n },\n extra: {\n raw,\n headers,\n },\n pagination: {\n cursor: nextCursor,\n },\n }\n }\n\n getUrl(\n path: string,\n queryString: string,\n pagination: PaginationConfig | null,\n paginationValues: PaginationValues | null\n ): string {\n // Add pagination params to query string if required\n if (pagination?.location === \"query\" && paginationValues) {\n const { pageParam, sizeParam } = pagination\n const params = new URLSearchParams()\n\n // Append page number or cursor param if configured\n if (pageParam && paginationValues.page != null) {\n params.append(pageParam, paginationValues.page as string)\n }\n\n // Append page size param if configured\n if (sizeParam && paginationValues.limit != null) {\n params.append(sizeParam, String(paginationValues.limit))\n }\n\n // Prepend query string with pagination params\n let paginationString = params.toString()\n if (paginationString) {\n queryString = `${paginationString}&${queryString}`\n }\n }\n\n if (queryString) {\n // make sure the query string is fully encoded\n queryString = \"?\" + qs.encode(qs.decode(queryString))\n }\n const main = `${path}${queryString}`\n\n let complete = main\n if (this.config.url && !main.startsWith(\"http\")) {\n complete = !this.config.url ? main : `${this.config.url}/${main}`\n }\n if (!complete.startsWith(\"http\")) {\n complete = `http://${complete}`\n }\n return complete\n }\n\n addBody(\n bodyType: string,\n body: string | any,\n input: any,\n pagination: PaginationConfig | null,\n paginationValues: PaginationValues | null\n ) {\n if (!input.headers) {\n input.headers = {}\n }\n if (bodyType === BodyTypes.NONE) {\n return input\n }\n let error,\n object: any = {},\n string = \"\"\n try {\n if (body) {\n string = typeof body !== \"string\" ? JSON.stringify(body) : body\n object = typeof body === \"object\" ? body : JSON.parse(body)\n }\n } catch (err) {\n error = err\n }\n\n // Util to add pagination values to a certain body type\n const addPaginationToBody = (insertFn: Function) => {\n if (pagination?.location === \"body\") {\n if (pagination?.pageParam && paginationValues?.page != null) {\n insertFn(pagination.pageParam, paginationValues.page)\n }\n if (pagination?.sizeParam && paginationValues?.limit != null) {\n insertFn(pagination.sizeParam, paginationValues.limit)\n }\n }\n }\n\n switch (bodyType) {\n case BodyTypes.TEXT:\n // content type defaults to plaintext\n input.body = string\n break\n case BodyTypes.ENCODED:\n const params = new URLSearchParams()\n for (let [key, value] of Object.entries(object)) {\n params.append(key, value as string)\n }\n addPaginationToBody((key: string, value: any) => {\n params.append(key, value)\n })\n input.body = params\n break\n case BodyTypes.FORM_DATA:\n const form = new FormData()\n for (let [key, value] of Object.entries(object)) {\n form.append(key, value)\n }\n addPaginationToBody((key: string, value: any) => {\n form.append(key, value)\n })\n input.body = form\n break\n case BodyTypes.XML:\n if (object != null && Object.keys(object).length) {\n string = new XmlBuilder().buildObject(object)\n }\n input.body = string\n input.headers[\"Content-Type\"] = \"application/xml\"\n break\n case BodyTypes.JSON:\n // if JSON error, throw it\n if (error) {\n throw \"Invalid JSON for request body\"\n }\n addPaginationToBody((key: string, value: any) => {\n object[key] = value\n })\n input.body = JSON.stringify(object)\n input.headers[\"Content-Type\"] = \"application/json\"\n break\n }\n return input\n }\n\n getAuthHeaders(authConfigId: string): { [key: string]: any } {\n let headers: any = {}\n\n if (this.config.authConfigs && authConfigId) {\n const authConfig = this.config.authConfigs.filter(\n c => c._id === authConfigId\n )[0]\n // check the config still exists before proceeding\n // if not - do nothing\n if (authConfig) {\n let config\n switch (authConfig.type) {\n case RestAuthType.BASIC:\n config = authConfig.config as RestBasicAuthConfig\n headers.Authorization = `Basic ${Buffer.from(\n `${config.username}:${config.password}`\n ).toString(\"base64\")}`\n break\n case RestAuthType.BEARER:\n config = authConfig.config as RestBearerAuthConfig\n headers.Authorization = `Bearer ${config.token}`\n break\n }\n }\n }\n\n return headers\n }\n\n async _req(query: RestQuery) {\n const {\n path = \"\",\n queryString = \"\",\n headers = {},\n method = \"GET\",\n disabledHeaders,\n bodyType,\n requestBody,\n authConfigId,\n pagination,\n paginationValues,\n } = query\n const authHeaders = this.getAuthHeaders(authConfigId)\n\n this.headers = {\n ...this.config.defaultHeaders,\n ...headers,\n ...authHeaders,\n }\n\n if (disabledHeaders) {\n for (let headerKey of Object.keys(this.headers)) {\n if (disabledHeaders[headerKey]) {\n delete this.headers[headerKey]\n }\n }\n }\n\n let input: any = { method, headers: this.headers }\n input = this.addBody(\n bodyType,\n requestBody,\n input,\n pagination,\n paginationValues\n )\n\n if (this.config.rejectUnauthorized == false) {\n input.agent = new https.Agent({\n rejectUnauthorized: false,\n })\n }\n\n // Deprecated by rejectUnauthorized\n if (this.config.legacyHttpParser) {\n // https://github.com/nodejs/node/issues/43798\n input.extraHttpOptions = { insecureHTTPParser: true }\n }\n\n this.startTimeMs = performance.now()\n const url = this.getUrl(path, queryString, pagination, paginationValues)\n if (await blacklist.isBlacklisted(url)) {\n throw new Error(\"Cannot connect to URL.\")\n }\n const response = await fetch(url, input)\n return await this.parseResponse(response, pagination)\n }\n\n async create(opts: RestQuery) {\n return this._req({ ...opts, method: \"POST\" })\n }\n\n async read(opts: RestQuery) {\n return this._req({ ...opts, method: \"GET\" })\n }\n\n async update(opts: RestQuery) {\n return this._req({ ...opts, method: \"PUT\" })\n }\n\n async patch(opts: RestQuery) {\n return this._req({ ...opts, method: \"PATCH\" })\n }\n\n async delete(opts: RestQuery) {\n return this._req({ ...opts, method: \"DELETE\" })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: RestIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n DatasourcePlus,\n FieldType,\n Integration,\n Operation,\n PaginationJson,\n QueryJson,\n QueryType,\n Row,\n SearchFilters,\n SortJson,\n Table,\n TableRequest,\n} from \"@budibase/types\"\nimport { OAuth2Client } from \"google-auth-library\"\nimport { buildExternalTableId, finaliseExternalTables } from \"./utils\"\nimport { GoogleSpreadsheet, GoogleSpreadsheetRow } from \"google-spreadsheet\"\nimport fetch from \"node-fetch\"\nimport { configs, HTTPError } from \"@budibase/backend-core\"\nimport { dataFilters } from \"@budibase/shared-core\"\nimport { GOOGLE_SHEETS_PRIMARY_KEY } from \"../constants\"\n\ninterface GoogleSheetsConfig {\n spreadsheetId: string\n auth: OAuthClientConfig\n}\n\ninterface OAuthClientConfig {\n appId: string\n accessToken: string\n refreshToken: string\n}\n\ninterface AuthTokenRequest {\n client_id: string\n client_secret: string\n refresh_token: string\n}\n\ninterface AuthTokenResponse {\n access_token: string\n}\n\nconst ALLOWED_TYPES = [\n FieldType.STRING,\n FieldType.FORMULA,\n FieldType.NUMBER,\n FieldType.LONGFORM,\n FieldType.DATETIME,\n FieldType.OPTIONS,\n FieldType.BOOLEAN,\n FieldType.BARCODEQR,\n]\n\nconst SCHEMA: Integration = {\n plus: true,\n auth: {\n type: \"google\",\n },\n relationships: false,\n docs: \"https://developers.google.com/sheets/api/quickstart/nodejs\",\n description:\n \"Create and collaborate on online spreadsheets in real-time and from any device.\",\n friendlyName: \"Google Sheets\",\n type: \"Spreadsheet\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n spreadsheetId: {\n display: \"Google Sheet URL\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n row: {\n type: QueryType.JSON,\n required: true,\n },\n },\n },\n read: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n update: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n rowIndex: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n row: {\n type: QueryType.JSON,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n sheet: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n rowIndex: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n },\n },\n },\n },\n}\n\nclass GoogleSheetsIntegration implements DatasourcePlus {\n private readonly config: GoogleSheetsConfig\n private client: GoogleSpreadsheet\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n constructor(config: GoogleSheetsConfig) {\n this.config = config\n const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId)\n this.client = new GoogleSpreadsheet(spreadsheetId)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.connect()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n getBindingIdentifier() {\n return \"\"\n }\n\n getStringConcat(parts: string[]) {\n return \"\"\n }\n\n /**\n * Pull the spreadsheet ID out from a valid google sheets URL\n * @param spreadsheetId - the URL or standard spreadsheetId of the google sheet\n * @returns spreadsheet Id of the google sheet\n */\n cleanSpreadsheetUrl(spreadsheetId: string) {\n if (!spreadsheetId) {\n throw new Error(\n \"You must set a spreadsheet ID in your configuration to fetch tables.\"\n )\n }\n const parts = spreadsheetId.split(\"/\")\n return parts.length > 5 ? parts[5] : spreadsheetId\n }\n\n async fetchAccessToken(\n payload: AuthTokenRequest\n ): Promise<AuthTokenResponse> {\n const response = await fetch(\"https://www.googleapis.com/oauth2/v4/token\", {\n method: \"POST\",\n body: JSON.stringify({\n ...payload,\n grant_type: \"refresh_token\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n\n const json = await response.json()\n\n if (response.status !== 200) {\n throw new Error(\n `Error authenticating with google sheets. ${json.error_description}`\n )\n }\n\n return json\n }\n\n async connect() {\n try {\n // Initialise oAuth client\n let googleConfig = await configs.getGoogleDatasourceConfig()\n if (!googleConfig) {\n throw new HTTPError(\"Google config not found\", 400)\n }\n\n const oauthClient = new OAuth2Client({\n clientId: googleConfig.clientID,\n clientSecret: googleConfig.clientSecret,\n })\n\n const tokenResponse = await this.fetchAccessToken({\n client_id: googleConfig.clientID,\n client_secret: googleConfig.clientSecret,\n refresh_token: this.config.auth.refreshToken,\n })\n\n oauthClient.setCredentials({\n refresh_token: this.config.auth.refreshToken,\n access_token: tokenResponse.access_token,\n })\n\n this.client.useOAuth2Client(oauthClient)\n await this.client.loadInfo()\n } catch (err: any) {\n // this happens for xlsx imports\n if (err.message?.includes(\"operation is not supported\")) {\n err.message =\n \"This operation is not supported - XLSX sheets must be converted.\"\n }\n console.error(\"Error connecting to google sheets\", err)\n throw err\n }\n }\n\n async getTableNames(): Promise<string[]> {\n await this.connect()\n const sheets = this.client.sheetsByIndex\n return sheets.map(s => s.title)\n }\n\n getTableSchema(title: string, headerValues: string[], id?: string) {\n // base table\n const table: Table = {\n name: title,\n primary: [GOOGLE_SHEETS_PRIMARY_KEY],\n schema: {},\n }\n if (id) {\n table._id = id\n }\n // build schema from headers\n for (let header of headerValues) {\n table.schema[header] = {\n name: header,\n type: FieldType.STRING,\n }\n }\n return table\n }\n\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n // not fully configured yet\n if (!this.config.auth) {\n return\n }\n await this.connect()\n const sheets = this.client.sheetsByIndex\n const tables: Record<string, Table> = {}\n for (let sheet of sheets) {\n // must fetch rows to determine schema\n await sheet.getRows()\n\n const id = buildExternalTableId(datasourceId, sheet.title)\n tables[sheet.title] = this.getTableSchema(\n sheet.title,\n sheet.headerValues,\n id\n )\n }\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async query(json: QueryJson) {\n const sheet = json.endpoint.entityId\n switch (json.endpoint.operation) {\n case Operation.CREATE:\n return this.create({ sheet, row: json.body as Row })\n case Operation.BULK_CREATE:\n return this.createBulk({ sheet, rows: json.body as Row[] })\n case Operation.READ:\n return this.read({ ...json, sheet })\n case Operation.UPDATE:\n return this.update({\n // exclude the header row and zero index\n rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,\n sheet,\n row: json.body,\n })\n case Operation.DELETE:\n return this.delete({\n // exclude the header row and zero index\n rowIndex: json.extra?.idFilter?.equal?.rowNumber - 2,\n sheet,\n })\n case Operation.CREATE_TABLE:\n return this.createTable(json?.table?.name)\n case Operation.UPDATE_TABLE:\n return this.updateTable(json.table!)\n case Operation.DELETE_TABLE:\n return this.deleteTable(json?.table?.name)\n default:\n throw new Error(\n `GSheets integration does not support \"${json.endpoint.operation}\".`\n )\n }\n }\n\n buildRowObject(headers: string[], values: string[], rowNumber: number) {\n const rowObject: { rowNumber: number; [key: string]: any } = { rowNumber }\n for (let i = 0; i < headers.length; i++) {\n rowObject._id = rowNumber\n rowObject[headers[i]] = values[i]\n }\n return rowObject\n }\n\n async createTable(name?: string) {\n if (!name) {\n throw new Error(\"Must provide name for new sheet.\")\n }\n try {\n await this.connect()\n return await this.client.addSheet({ title: name, headerValues: [name] })\n } catch (err) {\n console.error(\"Error creating new table in google sheets\", err)\n throw err\n }\n }\n\n async updateTable(table: TableRequest) {\n await this.connect()\n const sheet = this.client.sheetsByTitle[table.name]\n await sheet.loadHeaderRow()\n\n if (table._rename) {\n const headers = []\n for (let header of sheet.headerValues) {\n if (header === table._rename.old) {\n headers.push(table._rename.updated)\n } else {\n headers.push(header)\n }\n }\n try {\n await sheet.setHeaderRow(headers)\n } catch (err) {\n console.error(\"Error updating column name in google sheets\", err)\n throw err\n }\n } else {\n const updatedHeaderValues = [...sheet.headerValues]\n\n // add new column - doesn't currently exist\n for (let [key, column] of Object.entries(table.schema)) {\n if (!ALLOWED_TYPES.includes(column.type)) {\n throw new Error(\n `Column type: ${column.type} not allowed for GSheets integration.`\n )\n }\n if (\n !sheet.headerValues.includes(key) &&\n column.type !== FieldType.FORMULA\n ) {\n updatedHeaderValues.push(key)\n }\n }\n\n // clear out deleted columns\n for (let key of sheet.headerValues) {\n if (!Object.keys(table.schema).includes(key)) {\n const idx = updatedHeaderValues.indexOf(key)\n updatedHeaderValues.splice(idx, 1)\n }\n }\n\n try {\n await sheet.setHeaderRow(updatedHeaderValues)\n } catch (err) {\n console.error(\"Error updating table in google sheets\", err)\n throw err\n }\n }\n }\n\n async deleteTable(sheet: any) {\n try {\n await this.connect()\n const sheetToDelete = this.client.sheetsByTitle[sheet]\n return await sheetToDelete.delete()\n } catch (err) {\n console.error(\"Error deleting table in google sheets\", err)\n throw err\n }\n }\n\n async create(query: { sheet: string; row: any }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rowToInsert =\n typeof query.row === \"string\" ? JSON.parse(query.row) : query.row\n const row = await sheet.addRow(rowToInsert)\n return [\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),\n ]\n } catch (err) {\n console.error(\"Error writing to google sheets\", err)\n throw err\n }\n }\n\n async createBulk(query: { sheet: string; rows: any[] }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n let rowsToInsert = []\n for (let row of query.rows) {\n rowsToInsert.push(typeof row === \"string\" ? JSON.parse(row) : row)\n }\n const rows = await sheet.addRows(rowsToInsert)\n return rows.map(row =>\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber)\n )\n } catch (err) {\n console.error(\"Error bulk writing to google sheets\", err)\n throw err\n }\n }\n\n async read(query: {\n sheet: string\n filters?: SearchFilters\n sort?: SortJson\n paginate?: PaginationJson\n }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n let rows: GoogleSpreadsheetRow[] = []\n if (query.paginate) {\n const limit = query.paginate.limit || 100\n let page: number =\n typeof query.paginate.page === \"number\"\n ? query.paginate.page\n : parseInt(query.paginate.page || \"1\")\n rows = await sheet.getRows({\n limit,\n offset: (page - 1) * limit,\n })\n } else {\n rows = await sheet.getRows()\n }\n const filtered = dataFilters.runLuceneQuery(rows, query.filters)\n const headerValues = sheet.headerValues\n let response = []\n for (let row of filtered) {\n response.push(\n this.buildRowObject(headerValues, row._rawData, row._rowNumber)\n )\n }\n\n if (query.sort) {\n if (Object.keys(query.sort).length !== 1) {\n console.warn(\"Googlesheets does not support multiple sorting\", {\n sortInfo: query.sort,\n })\n }\n const [sortField, sortInfo] = Object.entries(query.sort)[0]\n response = dataFilters.luceneSort(\n response,\n sortField,\n sortInfo.direction,\n sortInfo.type\n )\n }\n\n return response\n } catch (err) {\n console.error(\"Error reading from google sheets\", err)\n throw err\n }\n }\n\n async update(query: { sheet: string; rowIndex: number; row: any }) {\n try {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rows = await sheet.getRows()\n const row = rows[query.rowIndex]\n if (row) {\n const updateValues =\n typeof query.row === \"string\" ? JSON.parse(query.row) : query.row\n for (let key in updateValues) {\n row[key] = updateValues[key]\n }\n await row.save()\n return [\n this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber),\n ]\n } else {\n throw new Error(\"Row does not exist.\")\n }\n } catch (err) {\n console.error(\"Error reading from google sheets\", err)\n throw err\n }\n }\n\n async delete(query: { sheet: string; rowIndex: number }) {\n await this.connect()\n const sheet = this.client.sheetsByTitle[query.sheet]\n const rows = await sheet.getRows()\n const row = rows[query.rowIndex]\n if (row) {\n await row.delete()\n return [{ deleted: query.rowIndex }]\n } else {\n throw new Error(\"Row does not exist.\")\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: GoogleSheetsIntegration,\n}\n", "import {\n DatasourceFieldType,\n Integration,\n QueryType,\n IntegrationBase,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport { Firestore, WhereFilterOp } from \"@google-cloud/firestore\"\n\ninterface FirebaseConfig {\n email: string\n privateKey: string\n projectId: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://firebase.google.com/docs/firestore/quickstart\",\n friendlyName: \"Firestore\",\n type: \"Non-relational\",\n description:\n \"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n email: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n privateKey: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n projectId: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.JSON,\n },\n read: {\n type: QueryType.JSON,\n },\n update: {\n type: QueryType.JSON,\n },\n delete: {\n type: QueryType.JSON,\n },\n },\n extra: {\n collection: {\n displayName: \"Collection\",\n type: DatasourceFieldType.STRING,\n required: true,\n },\n filterField: {\n displayName: \"Filter field\",\n type: DatasourceFieldType.STRING,\n required: false,\n },\n filter: {\n displayName: \"Filter comparison\",\n type: DatasourceFieldType.LIST,\n required: false,\n data: {\n read: [\n \"==\",\n \"<\",\n \"<=\",\n \"!=\",\n \">=\",\n \">\",\n \"array-contains\",\n \"in\",\n \"not-in\",\n \"array-contains-any\",\n ],\n },\n },\n filterValue: {\n displayName: \"Filter value\",\n type: DatasourceFieldType.STRING,\n required: false,\n },\n },\n}\n\nclass FirebaseIntegration implements IntegrationBase {\n private config: FirebaseConfig\n private client: Firestore\n\n constructor(config: FirebaseConfig) {\n this.config = config\n this.client = new Firestore({\n projectId: config.projectId,\n credentials: {\n client_email: config.email,\n private_key: config.privateKey?.replace(/\\\\n/g, \"\\n\"),\n },\n })\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.listCollections()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async create(query: { json: object; extra: { [key: string]: string } }) {\n try {\n const documentReference = this.client\n .collection(query.extra.collection)\n .doc()\n await documentReference.set({ ...query.json, id: documentReference.id })\n const snapshot = await documentReference.get()\n return snapshot.data()\n } catch (err) {\n console.error(\"Error writing to Firestore\", err)\n throw err\n }\n }\n\n async read(query: { json: object; extra: { [key: string]: string } }) {\n try {\n let snapshot\n const collectionRef = this.client.collection(query.extra.collection)\n if (\n query.extra.filterField &&\n query.extra.filter &&\n query.extra.filterValue\n ) {\n snapshot = await collectionRef\n .where(\n query.extra.filterField,\n query.extra.filter as WhereFilterOp,\n query.extra.filterValue\n )\n .get()\n } else {\n snapshot = await collectionRef.get()\n }\n const result: any[] = []\n snapshot.forEach(doc => result.push(doc.data()))\n\n return result\n } catch (err) {\n console.error(\"Error querying Firestore\", err)\n throw err\n }\n }\n\n async update(query: {\n json: Record<string, any>\n extra: { [key: string]: string }\n }) {\n try {\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .update(query.json)\n\n return (\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .get()\n ).data()\n } catch (err) {\n console.error(\"Error writing to Firestore\", err)\n throw err\n }\n }\n\n async delete(query: {\n json: { id: string }\n extra: { [key: string]: string }\n }) {\n try {\n await this.client\n .collection(query.extra.collection)\n .doc(query.json.id)\n .delete()\n return true\n } catch (err) {\n console.error(\"Error deleting from Firestore\", err)\n throw err\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: FirebaseIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n DatasourceFieldType,\n Integration,\n QueryType,\n} from \"@budibase/types\"\nimport Redis from \"ioredis\"\n\ninterface RedisConfig {\n host: string\n port: number\n username: string\n password?: string\n db?: number\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://redis.io/docs/\",\n description:\n \"Redis is a caching tool, providing powerful key-value store capabilities.\",\n friendlyName: \"Redis\",\n type: \"Non-relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n host: {\n type: \"string\",\n required: true,\n default: \"localhost\",\n },\n port: {\n type: \"number\",\n required: true,\n default: 6379,\n },\n username: {\n type: \"string\",\n required: false,\n },\n password: {\n type: \"password\",\n required: false,\n },\n db: {\n type: \"number\",\n required: false,\n display: \"DB\",\n default: 0,\n },\n },\n query: {\n create: {\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n value: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n ttl: {\n type: DatasourceFieldType.NUMBER,\n },\n },\n },\n read: {\n readable: true,\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n delete: {\n type: QueryType.FIELDS,\n fields: {\n key: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n },\n },\n command: {\n readable: true,\n displayName: \"Redis Command\",\n type: QueryType.JSON,\n },\n },\n}\n\nclass RedisIntegration {\n private readonly config: RedisConfig\n private client\n\n constructor(config: RedisConfig) {\n this.config = config\n this.client = new Redis({\n host: this.config.host,\n port: this.config.port,\n username: this.config.username,\n password: this.config.password,\n db: this.config.db,\n })\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n try {\n await this.client.ping()\n response.connected = true\n } catch (e: any) {\n response.error = e.message as string\n } finally {\n await this.disconnect()\n }\n return response\n }\n\n async disconnect() {\n return this.client.quit()\n }\n\n async redisContext(query: Function) {\n try {\n return await query()\n } catch (err) {\n throw new Error(`Redis error: ${err}`)\n } finally {\n await this.disconnect()\n }\n }\n\n async create(query: { key: string; value: string; ttl: number }) {\n return this.redisContext(async () => {\n const response = await this.client.set(query.key, query.value)\n if (query.ttl) {\n await this.client.expire(query.key, query.ttl)\n }\n return response\n })\n }\n\n async read(query: { key: string }) {\n return this.redisContext(async () => {\n return await this.client.get(query.key)\n })\n }\n\n async delete(query: { key: string }) {\n return this.redisContext(async () => {\n return await this.client.del(query.key)\n })\n }\n\n async command(query: { json: string }) {\n return this.redisContext(async () => {\n // commands split line by line\n const commands = query.json.trim().split(\"\\n\")\n let pipelineCommands = []\n\n // process each command separately\n for (let command of commands) {\n const tokenised = command.trim().split(\" \")\n // Pipeline only accepts lower case commands\n tokenised[0] = tokenised[0].toLowerCase()\n pipelineCommands.push(tokenised)\n }\n\n const pipeline = this.client.pipeline(pipelineCommands)\n const result = await pipeline.exec()\n\n return result.map((output: string | string[]) => output[1])\n })\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: RedisIntegration,\n}\n", "import {\n ConnectionInfo,\n DatasourceFeature,\n Integration,\n QueryType,\n SqlQuery,\n} from \"@budibase/types\"\nimport { Snowflake } from \"snowflake-promise\"\n\ninterface SnowflakeConfig {\n account: string\n username: string\n password: string\n warehouse: string\n database: string\n schema: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://developers.snowflake.com/\",\n description:\n \"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.\",\n friendlyName: \"Snowflake\",\n type: \"Relational\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n },\n datasource: {\n account: {\n type: \"string\",\n required: true,\n },\n username: {\n type: \"string\",\n required: true,\n },\n password: {\n type: \"password\",\n required: true,\n },\n warehouse: {\n type: \"string\",\n required: true,\n },\n database: {\n type: \"string\",\n required: true,\n },\n schema: {\n type: \"string\",\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nclass SnowflakeIntegration {\n private client: Snowflake\n\n constructor(config: SnowflakeConfig) {\n this.client = new Snowflake(config)\n }\n\n async testConnection(): Promise<ConnectionInfo> {\n try {\n await this.client.connect()\n return { connected: true }\n } catch (e: any) {\n return {\n connected: false,\n error: e.message as string,\n }\n }\n }\n\n async internalQuery(query: SqlQuery) {\n await this.client.connect()\n try {\n return await this.client.execute(query.sql)\n } catch (err: any) {\n throw err?.message.split(\":\")[1] || err?.message\n }\n }\n\n async create(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async read(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async update(query: SqlQuery) {\n return this.internalQuery(query)\n }\n\n async delete(query: SqlQuery) {\n return this.internalQuery(query)\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: SnowflakeIntegration,\n}\n", "import {\n DatasourceFieldType,\n Integration,\n Operation,\n QueryJson,\n QueryType,\n SqlQuery,\n Table,\n DatasourcePlus,\n DatasourceFeature,\n ConnectionInfo,\n} from \"@budibase/types\"\nimport {\n buildExternalTableId,\n convertSqlType,\n finaliseExternalTables,\n getSqlQuery,\n SqlClient,\n} from \"./utils\"\nimport Sql from \"./base/sql\"\nimport { FieldTypes } from \"../constants\"\nimport {\n BindParameters,\n Connection,\n ConnectionAttributes,\n ExecuteOptions,\n Result,\n} from \"oracledb\"\nimport { OracleTable, OracleColumn, OracleColumnsResponse } from \"./base/types\"\nlet oracledb: any\ntry {\n oracledb = require(\"oracledb\")\n oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT\n} catch (err) {\n console.log(\"ORACLEDB is not installed\")\n}\n\ninterface OracleConfig {\n host: string\n port: number\n database: string\n user: string\n password: string\n}\n\nconst SCHEMA: Integration = {\n docs: \"https://github.com/oracle/node-oracledb\",\n plus: true,\n friendlyName: \"Oracle\",\n type: \"Relational\",\n description:\n \"Oracle Database is an object-relational database management system developed by Oracle Corporation\",\n features: {\n [DatasourceFeature.CONNECTION_CHECKING]: true,\n [DatasourceFeature.FETCH_TABLE_NAMES]: true,\n },\n datasource: {\n host: {\n type: DatasourceFieldType.STRING,\n default: \"localhost\",\n required: true,\n },\n port: {\n type: DatasourceFieldType.NUMBER,\n required: true,\n default: 1521,\n },\n database: {\n type: DatasourceFieldType.STRING,\n required: true,\n display: \"Service Name\",\n },\n user: {\n type: DatasourceFieldType.STRING,\n required: true,\n },\n password: {\n type: DatasourceFieldType.PASSWORD,\n required: true,\n },\n },\n query: {\n create: {\n type: QueryType.SQL,\n },\n read: {\n type: QueryType.SQL,\n },\n update: {\n type: QueryType.SQL,\n },\n delete: {\n type: QueryType.SQL,\n },\n },\n}\n\nconst UNSUPPORTED_TYPES = [\"BLOB\", \"CLOB\", \"NCLOB\"]\n\nconst OracleContraintTypes = {\n PRIMARY: \"P\",\n NOT_NULL_OR_CHECK: \"C\",\n FOREIGN_KEY: \"R\",\n UNIQUE: \"U\",\n}\n\nclass OracleIntegration extends Sql implements DatasourcePlus {\n private readonly config: OracleConfig\n private index: number = 1\n\n public tables: Record<string, Table> = {}\n public schemaErrors: Record<string, string> = {}\n\n private readonly COLUMNS_SQL = `\n SELECT\n tabs.table_name,\n cols.column_name,\n cols.data_type,\n cols.data_default,\n cols.column_id,\n cons.constraint_name,\n cons.constraint_type,\n cons.r_constraint_name,\n cons.search_condition\n FROM\n user_tables tabs\n JOIN \n user_tab_columns cols\n ON tabs.table_name = cols.table_name \n LEFT JOIN \n user_cons_columns col_cons\n ON cols.column_name = col_cons.column_name\n AND cols.table_name = col_cons.table_name\n LEFT JOIN \n user_constraints cons\n ON col_cons.constraint_name = cons.constraint_name\n AND cons.table_name = cols.table_name\n WHERE\n (cons.status = 'ENABLED'\n OR cons.status IS NULL)\n `\n constructor(config: OracleConfig) {\n super(SqlClient.ORACLE)\n this.config = config\n }\n\n getBindingIdentifier(): string {\n return `:${this.index++}`\n }\n\n getStringConcat(parts: string[]): string {\n return parts.join(\" || \")\n }\n\n static isInstalled() {\n return oracledb != null\n }\n\n /**\n * Map the flat tabular columns and constraints data into a nested object\n */\n private mapColumns(result: Result<OracleColumnsResponse>): {\n [key: string]: OracleTable\n } {\n const oracleTables: { [key: string]: OracleTable } = {}\n\n if (result.rows) {\n result.rows.forEach(row => {\n const tableName = row.TABLE_NAME\n const columnName = row.COLUMN_NAME\n const dataType = row.DATA_TYPE\n const dataDefault = row.DATA_DEFAULT\n const columnId = row.COLUMN_ID\n const constraintName = row.CONSTRAINT_NAME\n const constraintType = row.CONSTRAINT_TYPE\n const relatedConstraintName = row.R_CONSTRAINT_NAME\n const searchCondition = row.SEARCH_CONDITION\n\n let table = oracleTables[tableName]\n if (!table) {\n table = {\n name: tableName,\n columns: {},\n }\n oracleTables[tableName] = table\n }\n\n let column = table.columns[columnName]\n if (!column) {\n column = {\n name: columnName,\n type: dataType,\n default: dataDefault,\n id: columnId,\n constraints: {},\n }\n table.columns[columnName] = column\n }\n\n if (constraintName && constraintType) {\n let constraint = column.constraints[constraintName]\n if (!constraint) {\n constraint = {\n name: constraintName,\n type: constraintType,\n relatedConstraintName: relatedConstraintName,\n searchCondition: searchCondition,\n }\n }\n column.constraints[constraintName] = constraint\n }\n })\n }\n\n return oracleTables\n }\n\n private static isSupportedColumn(column: OracleColumn) {\n return !UNSUPPORTED_TYPES.includes(column.type)\n }\n\n private static isAutoColumn(column: OracleColumn) {\n return !!(\n column.default && column.default.toLowerCase().includes(\"nextval\")\n )\n }\n\n /**\n * No native boolean in oracle. Best we can do is to check if a manual 1 or 0 number constraint has been set up\n * This matches the default behaviour for generating DDL used in knex.\n */\n private isBooleanType(column: OracleColumn): boolean {\n return (\n column.type.toLowerCase() === \"number\" &&\n Object.values(column.constraints).filter(c => {\n if (\n c.type === OracleContraintTypes.NOT_NULL_OR_CHECK &&\n c.searchCondition\n ) {\n const condition = c.searchCondition\n .replace(/\\s/g, \"\") // remove spaces\n .replace(/[']+/g, \"\") // remove quotes\n if (condition.includes(\"in(0,1)\") || condition.includes(\"in(1,0)\")) {\n return true\n }\n }\n return false\n }).length > 0\n )\n }\n\n private internalConvertType(column: OracleColumn): { type: FieldTypes } {\n if (this.isBooleanType(column)) {\n return { type: FieldTypes.BOOLEAN }\n }\n\n return convertSqlType(column.type)\n }\n\n /**\n * Fetches the tables from the oracle table and assigns them to the datasource.\n * @param {*} datasourceId - datasourceId to fetch\n * @param entities - the tables that are to be built\n */\n async buildSchema(datasourceId: string, entities: Record<string, Table>) {\n const columnsResponse = await this.internalQuery<OracleColumnsResponse>({\n sql: this.COLUMNS_SQL,\n })\n const oracleTables = this.mapColumns(columnsResponse)\n\n const tables: { [key: string]: Table } = {}\n\n // iterate each table\n Object.values(oracleTables).forEach(oracleTable => {\n let table = tables[oracleTable.name]\n if (!table) {\n table = {\n _id: buildExternalTableId(datasourceId, oracleTable.name),\n primary: [],\n name: oracleTable.name,\n schema: {},\n }\n tables[oracleTable.name] = table\n }\n\n // iterate each column on the table\n Object.values(oracleTable.columns)\n // remove columns that we can't read / save\n .filter(oracleColumn =>\n OracleIntegration.isSupportedColumn(oracleColumn)\n )\n // match the order of the columns in the db\n .sort((c1, c2) => c1.id - c2.id)\n .forEach(oracleColumn => {\n const columnName = oracleColumn.name\n let fieldSchema = table.schema[columnName]\n if (!fieldSchema) {\n fieldSchema = {\n autocolumn: OracleIntegration.isAutoColumn(oracleColumn),\n name: columnName,\n constraints: {\n presence: false,\n },\n ...this.internalConvertType(oracleColumn),\n }\n table.schema[columnName] = fieldSchema\n }\n\n // iterate each constraint on the column\n Object.values(oracleColumn.constraints).forEach(oracleConstraint => {\n if (oracleConstraint.type === OracleContraintTypes.PRIMARY) {\n table.primary!.push(columnName)\n } else if (\n oracleConstraint.type === OracleContraintTypes.NOT_NULL_OR_CHECK\n ) {\n table.schema[columnName].constraints = {\n presence: true,\n }\n }\n })\n })\n })\n\n const final = finaliseExternalTables(tables, entities)\n this.tables = final.tables\n this.schemaErrors = final.errors\n }\n\n async getTableNames() {\n const columnsResponse = await this.internalQuery<OracleColumnsResponse>({\n sql: this.COLUMNS_SQL,\n })\n return (columnsResponse.rows || []).map(row => row.TABLE_NAME)\n }\n\n async testConnection() {\n const response: ConnectionInfo = {\n connected: false,\n }\n let connection\n try {\n connection = await this.getConnection()\n response.connected = true\n } catch (err: any) {\n response.connected = false\n response.error = err.message\n } finally {\n if (connection) {\n try {\n await connection.close()\n } catch (err: any) {\n response.connected = false\n response.error = err.message\n }\n }\n }\n return response\n }\n\n private async internalQuery<T>(query: SqlQuery): Promise<Result<T>> {\n let connection\n try {\n this.index = 1\n connection = await this.getConnection()\n\n const options: ExecuteOptions = { autoCommit: true }\n const bindings: BindParameters = query.bindings || []\n\n return await connection.execute<T>(query.sql, bindings, options)\n } finally {\n if (connection) {\n try {\n await connection.close()\n } catch (err) {\n console.error(err)\n }\n }\n }\n }\n\n private getConnection = async (): Promise<Connection> => {\n //connectString : \"(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))(CONNECT_DATA =(SID= ORCL)))\"\n const connectString = `${this.config.host}:${this.config.port || 1521}/${\n this.config.database\n }`\n const attributes: ConnectionAttributes = {\n user: this.config.user,\n password: this.config.password,\n connectString,\n }\n return oracledb.getConnection(attributes)\n }\n\n async create(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery<any>(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ created: true }]\n }\n\n async read(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery<any>(getSqlQuery(query))\n return response.rows ? response.rows : []\n }\n\n async update(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ updated: true }]\n }\n\n async delete(query: SqlQuery | string): Promise<any[]> {\n const response = await this.internalQuery(getSqlQuery(query))\n return response.rows && response.rows.length\n ? response.rows\n : [{ deleted: true }]\n }\n\n async query(json: QueryJson) {\n const operation = this._operation(json)\n const input = this._query(json, { disableReturning: true })\n if (Array.isArray(input)) {\n const responses = []\n for (let query of input) {\n responses.push(await this.internalQuery(query))\n }\n return responses\n } else {\n // read the row to be deleted up front for the return\n let deletedRows\n if (operation === Operation.DELETE) {\n const queryFn = (query: any) => this.internalQuery(query)\n deletedRows = await this.getReturningRow(queryFn, json)\n }\n\n // run the query\n const response = await this.internalQuery(input)\n\n // get the results or return the created / updated / deleted row\n if (deletedRows?.rows?.length) {\n return deletedRows.rows\n } else if (response.rows?.length) {\n return response.rows\n } else {\n // get the last row that was updated\n if (\n response.lastRowid &&\n json.endpoint?.entityId &&\n operation !== Operation.DELETE\n ) {\n const lastRow = await this.internalQuery({\n sql: `SELECT * FROM \\\"${json.endpoint.entityId}\\\" WHERE ROWID = '${response.lastRowid}'`,\n })\n return lastRow.rows\n } else {\n return [{ [operation.toLowerCase()]: true }]\n }\n }\n }\n }\n}\n\nexport default {\n schema: SCHEMA,\n integration: OracleIntegration,\n}\n", "import postgres from \"./postgres\"\nimport dynamodb from \"./dynamodb\"\nimport mongodb from \"./mongodb\"\nimport elasticsearch from \"./elasticsearch\"\nimport couchdb from \"./couchdb\"\nimport sqlServer from \"./microsoftSqlServer\"\nimport s3 from \"./s3\"\nimport airtable from \"./airtable\"\nimport mysql from \"./mysql\"\nimport arangodb from \"./arangodb\"\nimport rest from \"./rest\"\nimport googlesheets from \"./googlesheets\"\nimport firebase from \"./firebase\"\nimport redis from \"./redis\"\nimport snowflake from \"./snowflake\"\nimport oracle from \"./oracle\"\nimport { SourceName, Integration, PluginType } from \"@budibase/types\"\nimport { getDatasourcePlugin } from \"../utilities/fileSystem\"\nimport env from \"../environment\"\nimport { cloneDeep } from \"lodash\"\nimport sdk from \"../sdk\"\n\nconst DEFINITIONS: Record<SourceName, Integration | undefined> = {\n [SourceName.POSTGRES]: postgres.schema,\n [SourceName.DYNAMODB]: dynamodb.schema,\n [SourceName.MONGODB]: mongodb.schema,\n [SourceName.ELASTICSEARCH]: elasticsearch.schema,\n [SourceName.COUCHDB]: couchdb.schema,\n [SourceName.SQL_SERVER]: sqlServer.schema,\n [SourceName.S3]: s3.schema,\n [SourceName.AIRTABLE]: airtable.schema,\n [SourceName.MYSQL]: mysql.schema,\n [SourceName.ARANGODB]: arangodb.schema,\n [SourceName.REST]: rest.schema,\n [SourceName.FIRESTORE]: firebase.schema,\n [SourceName.GOOGLE_SHEETS]: googlesheets.schema,\n [SourceName.REDIS]: redis.schema,\n [SourceName.SNOWFLAKE]: snowflake.schema,\n [SourceName.ORACLE]: undefined,\n}\n\nconst INTEGRATIONS: Record<SourceName, any> = {\n [SourceName.POSTGRES]: postgres.integration,\n [SourceName.DYNAMODB]: dynamodb.integration,\n [SourceName.MONGODB]: mongodb.integration,\n [SourceName.ELASTICSEARCH]: elasticsearch.integration,\n [SourceName.COUCHDB]: couchdb.integration,\n [SourceName.SQL_SERVER]: sqlServer.integration,\n [SourceName.S3]: s3.integration,\n [SourceName.AIRTABLE]: airtable.integration,\n [SourceName.MYSQL]: mysql.integration,\n [SourceName.ARANGODB]: arangodb.integration,\n [SourceName.REST]: rest.integration,\n [SourceName.FIRESTORE]: firebase.integration,\n [SourceName.GOOGLE_SHEETS]: googlesheets.integration,\n [SourceName.REDIS]: redis.integration,\n [SourceName.FIRESTORE]: firebase.integration,\n [SourceName.SNOWFLAKE]: snowflake.integration,\n [SourceName.ORACLE]: undefined,\n}\n\n// optionally add oracle integration if the oracle binary can be installed\nif (\n process.arch &&\n !process.arch.startsWith(\"arm\") &&\n oracle.integration.isInstalled()\n) {\n DEFINITIONS[SourceName.ORACLE] = oracle.schema\n INTEGRATIONS[SourceName.ORACLE] = oracle.integration\n}\n\nexport async function getDefinition(\n source: SourceName\n): Promise<Integration | undefined> {\n // check if its integrated, faster\n const definition = DEFINITIONS[source]\n if (definition) {\n return definition\n }\n const allDefinitions = await getDefinitions()\n return allDefinitions[source]\n}\n\nexport async function getDefinitions() {\n const pluginSchemas: { [key: string]: Integration } = {}\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)\n // extract the actual schema from each custom\n for (let plugin of plugins) {\n const sourceId = plugin.name\n pluginSchemas[sourceId] = {\n ...plugin.schema[\"schema\"],\n custom: true,\n }\n if (plugin.iconUrl) {\n pluginSchemas[sourceId].iconUrl = plugin.iconUrl\n }\n }\n }\n return {\n ...cloneDeep(DEFINITIONS),\n ...pluginSchemas,\n }\n}\n\nexport async function getIntegration(integration: SourceName) {\n if (INTEGRATIONS[integration]) {\n return INTEGRATIONS[integration]\n }\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)\n for (let plugin of plugins) {\n if (plugin.name === integration) {\n // need to use commonJS require due to its dynamic runtime nature\n const retrieved = await getDatasourcePlugin(plugin)\n if (retrieved.integration) {\n return retrieved.integration\n } else {\n return retrieved\n }\n }\n }\n }\n throw new Error(\"No datasource implementation found.\")\n}\n\nexport default {\n getDefinitions,\n getIntegration,\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { findHBSBlocks, processObjectSync } from \"@budibase/string-templates\"\nimport {\n Datasource,\n DatasourceFieldType,\n Integration,\n PASSWORD_REPLACEMENT,\n RestAuthConfig,\n RestAuthType,\n RestBasicAuthConfig,\n SourceName,\n} from \"@budibase/types\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { getEnvironmentVariables } from \"../../utils\"\nimport { getDefinitions, getDefinition } from \"../../../integrations\"\nimport _ from \"lodash\"\n\nconst ENV_VAR_PREFIX = \"env.\"\n\nexport function checkDatasourceTypes(schema: Integration, config: any) {\n for (let key of Object.keys(config)) {\n if (!schema.datasource[key]) {\n continue\n }\n const type = schema.datasource[key].type\n if (\n type === DatasourceFieldType.NUMBER &&\n typeof config[key] === \"string\"\n ) {\n config[key] = parseFloat(config[key])\n }\n }\n return config\n}\n\nasync function enrichDatasourceWithValues(datasource: Datasource) {\n const cloned = cloneDeep(datasource)\n const env = await getEnvironmentVariables()\n const processed = processObjectSync(\n cloned,\n { env },\n { onlyFound: true }\n ) as Datasource\n const definition = await getDefinition(processed.source)\n processed.config = checkDatasourceTypes(definition!, processed.config)\n return {\n datasource: processed,\n envVars: env as Record<string, string>,\n }\n}\n\nexport async function enrich(datasource: Datasource) {\n const { datasource: response } = await enrichDatasourceWithValues(datasource)\n return response\n}\n\nexport async function get(\n datasourceId: string,\n opts?: { enriched: boolean }\n): Promise<Datasource> {\n const appDb = context.getAppDB()\n const datasource = await appDb.get(datasourceId)\n if (opts?.enriched) {\n return (await enrichDatasourceWithValues(datasource)).datasource\n } else {\n return datasource\n }\n}\n\nexport async function getWithEnvVars(datasourceId: string) {\n const appDb = context.getAppDB()\n const datasource = await appDb.get(datasourceId)\n return enrichDatasourceWithValues(datasource)\n}\n\nfunction hasAuthConfigs(datasource: Datasource) {\n return datasource.source === SourceName.REST && datasource.config?.authConfigs\n}\n\nfunction useEnvVars(str: any) {\n if (typeof str !== \"string\") {\n return false\n }\n const blocks = findHBSBlocks(str)\n return blocks.find(block => block.includes(ENV_VAR_PREFIX)) != null\n}\n\nexport async function removeSecrets(datasources: Datasource[]) {\n const definitions = await getDefinitions()\n for (let datasource of datasources) {\n const schema = definitions[datasource.source]\n if (!schema) {\n continue\n }\n if (datasource.config) {\n // strip secrets from response, so they don't show in the network request\n if (datasource.config.auth) {\n delete datasource.config.auth\n }\n // specific to REST datasources, contains passwords\n if (hasAuthConfigs(datasource)) {\n const configs = datasource.config.authConfigs as RestAuthConfig[]\n for (let config of configs) {\n if (config.type !== RestAuthType.BASIC) {\n continue\n }\n const basic = config.config as RestBasicAuthConfig\n if (!useEnvVars(basic.password)) {\n basic.password = PASSWORD_REPLACEMENT\n }\n }\n }\n // remove general passwords\n for (let key of Object.keys(datasource.config)) {\n if (\n schema.datasource?.[key]?.type === DatasourceFieldType.PASSWORD &&\n !useEnvVars(datasource.config[key])\n ) {\n datasource.config[key] = PASSWORD_REPLACEMENT\n }\n }\n }\n }\n return datasources\n}\n\nexport async function removeSecretSingle(datasource: Datasource) {\n return (await removeSecrets([datasource]))[0]\n}\n\nexport function mergeConfigs(update: Datasource, old: Datasource) {\n if (!update.config) {\n return update\n }\n // specific to REST datasources, fix the auth configs again if required\n if (hasAuthConfigs(update)) {\n const configs = update.config.authConfigs as RestAuthConfig[]\n const oldConfigs = old.config?.authConfigs as RestAuthConfig[]\n for (let config of configs) {\n if (config.type !== RestAuthType.BASIC) {\n continue\n }\n const basic = config.config as RestBasicAuthConfig\n const oldBasic = oldConfigs.find(old => old.name === config.name)\n ?.config as RestBasicAuthConfig\n if (basic.password === PASSWORD_REPLACEMENT) {\n basic.password = oldBasic.password\n }\n }\n }\n\n if (old.config?.auth) {\n update.config = _.merge(old.config, update.config)\n }\n\n // update back to actual passwords for everything else\n for (let [key, value] of Object.entries(update.config)) {\n if (value !== PASSWORD_REPLACEMENT) {\n continue\n }\n if (old.config?.[key]) {\n update.config[key] = old.config?.[key]\n } else {\n delete update.config[key]\n }\n }\n return update\n}\n", "import * as datasources from \"./datasources\"\n\nexport default {\n ...datasources,\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { BudibaseInternalDB, getTableParams } from \"../../../db/utils\"\nimport {\n breakExternalTableId,\n isExternalTable,\n isSQL,\n} from \"../../../integrations/utils\"\nimport { Table, Database } from \"@budibase/types\"\nimport datasources from \"../datasources\"\n\nasync function getAllInternalTables(db?: Database): Promise<Table[]> {\n if (!db) {\n db = context.getAppDB()\n }\n const internalTables = await db.allDocs(\n getTableParams(null, {\n include_docs: true,\n })\n )\n return internalTables.rows.map((tableDoc: any) => ({\n ...tableDoc.doc,\n type: \"internal\",\n sourceId: tableDoc.doc.sourceId || BudibaseInternalDB._id,\n }))\n}\n\nasync function getAllExternalTables(\n datasourceId: any\n): Promise<Record<string, Table>> {\n const db = context.getAppDB()\n const datasource = await datasources.get(datasourceId, { enriched: true })\n if (!datasource || !datasource.entities) {\n throw \"Datasource is not configured fully.\"\n }\n return datasource.entities\n}\n\nasync function getExternalTable(\n datasourceId: any,\n tableName: any\n): Promise<Table> {\n const entities = await getAllExternalTables(datasourceId)\n return entities[tableName]\n}\n\nasync function getTable(tableId: any): Promise<Table> {\n const db = context.getAppDB()\n if (isExternalTable(tableId)) {\n let { datasourceId, tableName } = breakExternalTableId(tableId)\n const datasource = await datasources.get(datasourceId!)\n const table = await getExternalTable(datasourceId, tableName)\n return { ...table, sql: isSQL(datasource) }\n } else {\n return db.get(tableId)\n }\n}\n\nexport default {\n getAllInternalTables,\n getAllExternalTables,\n getExternalTable,\n getTable,\n}\n", "import { Webhook, WebhookActionType } from \"@budibase/types\"\nimport { db as dbCore, context } from \"@budibase/backend-core\"\nimport { generateWebhookID } from \"../../../db/utils\"\n\nfunction isWebhookID(id: string) {\n return id.startsWith(dbCore.DocumentType.WEBHOOK)\n}\n\nexport function newDoc(\n name: string,\n type: WebhookActionType,\n target: string\n): Webhook {\n return {\n live: true,\n name,\n action: {\n type,\n target,\n },\n }\n}\n\nexport async function save(webhook: Webhook) {\n const db = context.getAppDB()\n // check that the webhook exists\n if (webhook._id && isWebhookID(webhook._id)) {\n await db.get(webhook._id)\n } else {\n webhook._id = generateWebhookID()\n }\n const response = await db.put(webhook)\n webhook._rev = response.rev\n return webhook\n}\n\nexport async function destroy(id: string, rev: string) {\n const db = context.getAppDB()\n if (!id || !isWebhookID(id)) {\n throw new Error(\"Provided webhook ID is not valid.\")\n }\n return await db.remove(id, rev)\n}\n", "import * as webhook from \"./webhook\"\n\nexport default {\n webhook,\n}\n", "import { getMultiIDParams, getGlobalIDFromUserMetadataID } from \"../db/utils\"\nimport {\n roles,\n db as dbCore,\n cache,\n tenancy,\n context,\n} from \"@budibase/backend-core\"\nimport env from \"../environment\"\nimport { groups } from \"@budibase/pro\"\nimport { UserCtx, ContextUser, User, UserGroup } from \"@budibase/types\"\nimport { global } from \"yargs\"\n\nexport function updateAppRole(\n user: ContextUser,\n { appId }: { appId?: string } = {}\n) {\n appId = appId || context.getAppId()\n\n if (!user || (!user.roles && !user.userGroups)) {\n return user\n }\n // if in an multi-tenancy environment make sure roles are never updated\n if (env.MULTI_TENANCY && appId && !tenancy.isUserInAppTenant(appId, user)) {\n delete user.builder\n delete user.admin\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n return user\n }\n // always use the deployed app\n if (appId && user.roles) {\n user.roleId = user.roles[dbCore.getProdAppID(appId)]\n }\n // if a role wasn't found then either set as admin (builder) or public (everyone else)\n if (!user.roleId && user.builder && user.builder.global) {\n user.roleId = roles.BUILTIN_ROLE_IDS.ADMIN\n } else if (!user.roleId && !user?.userGroups?.length) {\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n }\n\n delete user.roles\n return user\n}\n\nasync function checkGroupRoles(\n user: ContextUser,\n opts: { appId?: string; groups?: UserGroup[] } = {}\n) {\n if (user.roleId && user.roleId !== roles.BUILTIN_ROLE_IDS.PUBLIC) {\n return user\n }\n if (opts.appId) {\n user.roleId = await groups.getGroupRoleId(user as User, opts.appId, {\n groups: opts.groups,\n })\n }\n // final fallback, simply couldn't find a role - user must be public\n if (!user.roleId) {\n user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n }\n return user\n}\n\nexport async function processUser(\n user: ContextUser,\n opts: { appId?: string; groups?: UserGroup[] } = {}\n) {\n if (user) {\n delete user.password\n }\n const appId = opts.appId || context.getAppId()\n user = updateAppRole(user, { appId })\n if (!user.roleId && user?.userGroups?.length) {\n user = await checkGroupRoles(user, { appId, groups: opts?.groups })\n }\n\n return user\n}\n\nexport async function getCachedSelf(ctx: UserCtx, appId: string) {\n // this has to be tenant aware, can't depend on the context to find it out\n // running some middlewares before the tenancy causes context to break\n const user = await cache.user.getUser(ctx.user?._id!)\n return processUser(user, { appId })\n}\n\nexport async function getRawGlobalUser(userId: string) {\n const db = tenancy.getGlobalDB()\n return db.get(getGlobalIDFromUserMetadataID(userId))\n}\n\nexport async function getGlobalUser(userId: string) {\n const appId = context.getAppId()\n let user = await getRawGlobalUser(userId)\n return processUser(user, { appId })\n}\n\nexport async function getGlobalUsers(\n userIds?: string[],\n opts?: { noProcessing?: boolean }\n) {\n const appId = context.getAppId()\n const db = tenancy.getGlobalDB()\n let globalUsers\n if (userIds) {\n globalUsers = (await db.allDocs(getMultiIDParams(userIds))).rows.map(\n row => row.doc\n )\n } else {\n globalUsers = (\n await db.allDocs(\n dbCore.getGlobalUserParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n }\n globalUsers = globalUsers\n .filter(user => user != null)\n .map(user => {\n delete user.password\n delete user.forceResetPassword\n return user\n })\n if (!appId) {\n return globalUsers\n }\n\n if (opts?.noProcessing) {\n return globalUsers\n } else {\n // pass in the groups, meaning we don't actually need to retrieve them for\n // each user individually\n const allGroups = await groups.fetch()\n return Promise.all(\n globalUsers.map(user => processUser(user, { groups: allGroups }))\n )\n }\n}\n\nexport async function getGlobalUsersFromMetadata(users: ContextUser[]) {\n const globalUsers = await getGlobalUsers(users.map(user => user._id!))\n return users.map(user => {\n const globalUser = globalUsers.find(\n globalUser => globalUser && user._id?.includes(globalUser._id)\n )\n return {\n ...globalUser,\n // doing user second overwrites the id and rev (always metadata)\n ...user,\n }\n })\n}\n", "import env from \"../../../environment\"\nimport {\n db as dbCore,\n context,\n docUpdates,\n constants,\n logging,\n roles,\n} from \"@budibase/backend-core\"\nimport { User, ContextUser, UserGroup } from \"@budibase/types\"\nimport { sdk as proSdk } from \"@budibase/pro\"\nimport sdk from \"../../\"\nimport { getGlobalUsers, processUser } from \"../../../utilities/global\"\nimport { generateUserMetadataID, InternalTables } from \"../../../db/utils\"\n\ntype DeletedUser = { _id: string; deleted: boolean }\n\nasync function syncUsersToApp(\n appId: string,\n users: (User | DeletedUser)[],\n groups: UserGroup[]\n) {\n if (!(await dbCore.dbExists(appId))) {\n return\n }\n await context.doInAppContext(appId, async () => {\n const db = context.getAppDB()\n for (let user of users) {\n let ctxUser = user as ContextUser\n let deletedUser = false\n const metadataId = generateUserMetadataID(user._id!)\n if ((user as DeletedUser).deleted) {\n deletedUser = true\n }\n\n // make sure role is correct\n if (!deletedUser) {\n ctxUser = await processUser(ctxUser, { appId, groups })\n }\n let roleId = ctxUser.roleId\n if (roleId === roles.BUILTIN_ROLE_IDS.PUBLIC) {\n roleId = undefined\n }\n\n let metadata\n try {\n metadata = await db.get(metadataId)\n } catch (err: any) {\n if (err.status !== 404) {\n throw err\n }\n // no metadata and user is to be deleted, can skip\n // no role - user isn't in app anyway\n if (!roleId) {\n continue\n } else if (!deletedUser) {\n // doesn't exist yet, creating it\n metadata = {\n tableId: InternalTables.USER_METADATA,\n }\n }\n }\n\n // the user doesn't exist, or doesn't have a role anymore\n // get rid of their metadata\n if (deletedUser || !roleId) {\n await db.remove(metadata)\n continue\n }\n\n // assign the roleId for the metadata doc\n if (roleId) {\n metadata.roleId = roleId\n }\n\n let combined = sdk.users.combineMetadataAndUser(ctxUser, metadata)\n // if no combined returned, there are no updates to make\n if (combined) {\n await db.put(combined)\n }\n }\n })\n}\n\nexport async function syncUsersToAllApps(userIds: string[]) {\n // list of users, if one has been deleted it will be undefined in array\n const users = (await getGlobalUsers(userIds, {\n noProcessing: true,\n })) as User[]\n const groups = await proSdk.groups.fetch()\n const finalUsers: (User | DeletedUser)[] = []\n for (let userId of userIds) {\n const user = users.find(user => user._id === userId)\n if (!user) {\n finalUsers.push({ _id: userId, deleted: true })\n } else {\n finalUsers.push(user)\n }\n }\n const devAppIds = await dbCore.getDevAppIDs()\n let promises = []\n for (let devAppId of devAppIds) {\n const prodAppId = dbCore.getProdAppID(devAppId)\n for (let appId of [prodAppId, devAppId]) {\n promises.push(syncUsersToApp(appId, finalUsers, groups))\n }\n }\n const resp = await Promise.allSettled(promises)\n const failed = resp.filter(promise => promise.status === \"rejected\")\n if (failed.length > 0) {\n const reasons = failed.map(fail => (fail as PromiseRejectedResult).reason)\n logging.logAlert(\"Failed to sync users to apps\", reasons)\n }\n}\n\nexport async function syncApp(\n appId: string,\n opts?: { automationOnly?: boolean }\n) {\n if (env.DISABLE_AUTO_PROD_APP_SYNC) {\n return {\n message:\n \"App sync disabled. You can reenable with the DISABLE_AUTO_PROD_APP_SYNC environment variable.\",\n }\n }\n\n if (dbCore.isProdAppID(appId)) {\n throw new Error(\"This action cannot be performed for production apps\")\n }\n\n // replicate prod to dev\n const prodAppId = dbCore.getProdAppID(appId)\n\n // specific case, want to make sure setup is skipped\n const prodDb = context.getProdAppDB({ skip_setup: true })\n const exists = await prodDb.exists()\n\n let error\n if (exists) {\n const replication = new dbCore.Replication({\n source: prodAppId,\n target: appId,\n })\n try {\n const replOpts = replication.appReplicateOpts()\n if (opts?.automationOnly) {\n replOpts.filter = (doc: any) =>\n doc._id.startsWith(dbCore.DocumentType.AUTOMATION)\n }\n await replication.replicate(replOpts)\n } catch (err) {\n error = err\n } finally {\n await replication.close()\n }\n }\n\n // sync the users - kept for safe keeping\n await sdk.users.syncGlobalUsers()\n\n if (error) {\n throw error\n } else {\n return {\n message: \"App sync completed successfully.\",\n }\n }\n}\n", "const URL_REGEX_SLASH = /\\/|\\\\/g\n\nexport function getAppUrl(opts?: { name?: string; url?: string }) {\n // construct the url\n let url\n if (opts?.url) {\n // if the url is provided, use that\n url = encodeURI(opts?.url)\n } else if (opts?.name) {\n // otherwise use the name\n url = encodeURI(`${opts?.name}`)\n }\n if (url) {\n url = `/${url.replace(URL_REGEX_SLASH, \"\")}`.toLowerCase()\n }\n return url as string\n}\n", "import * as sync from \"./sync\"\nimport * as utils from \"./utils\"\n\nexport default {\n ...sync,\n ...utils,\n}\n", "import { getEnvironmentVariables } from \"../../utils\"\nimport { processStringSync } from \"@budibase/string-templates\"\n\nexport async function enrichContext(\n fields: Record<string, any>,\n inputs = {}\n): Promise<Record<string, any>> {\n const enrichedQuery: Record<string, any> = Array.isArray(fields) ? [] : {}\n if (!fields || !inputs) {\n return enrichedQuery\n }\n const env = await getEnvironmentVariables()\n const parameters = { ...inputs, env }\n // enrich the fields with dynamic parameters\n for (let key of Object.keys(fields)) {\n if (fields[key] == null) {\n continue\n }\n if (typeof fields[key] === \"object\") {\n // enrich nested fields object\n enrichedQuery[key] = await enrichContext(fields[key], parameters)\n } else if (typeof fields[key] === \"string\") {\n // enrich string value as normal\n enrichedQuery[key] = processStringSync(fields[key], parameters, {\n noEscaping: true,\n noHelpers: true,\n escapeNewlines: true,\n })\n } else {\n enrichedQuery[key] = fields[key]\n }\n }\n if (\n enrichedQuery.json ||\n enrichedQuery.customData ||\n enrichedQuery.requestBody\n ) {\n try {\n enrichedQuery.json = JSON.parse(\n enrichedQuery.json ||\n enrichedQuery.customData ||\n enrichedQuery.requestBody\n )\n } catch (err) {\n // no json found, ignore\n }\n delete enrichedQuery.customData\n }\n return enrichedQuery\n}\n", "import * as queries from \"./queries\"\n\nexport default {\n ...queries,\n}\n", "import { CouchFindOptions, Table, Row } from \"@budibase/types\"\nimport { db as dbCore } from \"@budibase/backend-core\"\nimport { DocumentType, SEPARATOR } from \"../../../db/utils\"\nimport { FieldTypes } from \"../../../constants\"\n\n// default limit - seems to work well for performance\nexport const FIND_LIMIT = 25\n\nfunction generateAttachmentFindParams(\n tableId: string,\n attachmentCols: string[],\n bookmark: null | string\n) {\n const params: CouchFindOptions = {\n selector: {\n $or: attachmentCols.map(col => ({ [col]: { $exists: true } })),\n _id: {\n $regex: `^${DocumentType.ROW}${SEPARATOR}${tableId}`,\n },\n },\n limit: FIND_LIMIT,\n }\n if (bookmark) {\n params.bookmark = bookmark\n }\n return params\n}\n\nexport async function getRowsWithAttachments(appId: string, table: Table) {\n // iterate through attachment documents and update them\n const db = dbCore.getDB(appId)\n const attachmentCols: string[] = []\n for (let [key, column] of Object.entries(table.schema)) {\n if (column.type === FieldTypes.ATTACHMENT) {\n attachmentCols.push(key)\n }\n }\n // no attachment columns, nothing to do\n if (attachmentCols.length === 0) {\n return { rows: [], columns: [] }\n }\n let bookmark: null | string = null,\n rowsLength = 0,\n rowList: Row[] = []\n do {\n const params = generateAttachmentFindParams(\n table._id!,\n attachmentCols,\n bookmark\n )\n // use the CouchDB Mango query API to lookup rows that have attachments\n const resp = await dbCore.directCouchFind(db.name, params)\n bookmark = resp.bookmark\n rowsLength = resp.rows.length\n const rows = resp.rows\n rowList = rowList.concat(rows)\n } while (rowsLength === FIND_LIMIT)\n // write back the updated attachments\n return { rows: rowList, columns: attachmentCols }\n}\n", "import { db as dbCore, context } from \"@budibase/backend-core\"\nimport { Database, Row } from \"@budibase/types\"\nimport { getRowParams } from \"../../../db/utils\"\n\nexport async function getAllInternalRows(appId?: string) {\n let db: Database\n if (appId) {\n db = dbCore.getDB(appId)\n } else {\n db = context.getAppDB()\n }\n const response = await db.allDocs(\n getRowParams(null, null, {\n include_docs: true,\n })\n )\n return response.rows.map(row => row.doc) as Row[]\n}\n", "import * as attachments from \"./attachments\"\nimport * as rows from \"./rows\"\n\nexport default {\n ...attachments,\n ...rows,\n}\n", "import { getGlobalUsers } from \"../../utilities/global\"\nimport { context, roles as rolesCore } from \"@budibase/backend-core\"\nimport {\n getGlobalIDFromUserMetadataID,\n generateUserMetadataID,\n getUserMetadataParams,\n InternalTables,\n} from \"../../db/utils\"\nimport { isEqual } from \"lodash\"\nimport { ContextUser, UserMetadata, User } from \"@budibase/types\"\n\nexport function combineMetadataAndUser(\n user: ContextUser,\n metadata: UserMetadata | UserMetadata[]\n) {\n const metadataId = generateUserMetadataID(user._id!)\n const found = Array.isArray(metadata)\n ? metadata.find(doc => doc._id === metadataId)\n : metadata\n // skip users with no access\n if (\n user.roleId == null ||\n user.roleId === rolesCore.BUILTIN_ROLE_IDS.PUBLIC\n ) {\n // If it exists and it should not, we must remove it\n if (found?._id) {\n return { ...found, _deleted: true }\n }\n return null\n }\n delete user._rev\n const newDoc = {\n ...user,\n _id: metadataId,\n tableId: InternalTables.USER_METADATA,\n }\n // copy rev over for the purposes of equality check\n if (found) {\n newDoc._rev = found._rev\n }\n // clear fields that shouldn't be in metadata\n delete newDoc.password\n delete newDoc.forceResetPassword\n delete newDoc.roles\n if (found == null || !isEqual(newDoc, found)) {\n return {\n ...found,\n ...newDoc,\n }\n }\n return null\n}\n\nexport async function rawUserMetadata() {\n const db = context.getAppDB()\n return (\n await db.allDocs(\n getUserMetadataParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n}\n\nexport async function syncGlobalUsers() {\n // sync user metadata\n const db = context.getAppDB()\n const resp = await Promise.all([getGlobalUsers(), rawUserMetadata()])\n const users = resp[0] as User[]\n const metadata = resp[1] as UserMetadata[]\n const toWrite = []\n for (let user of users) {\n const combined = combineMetadataAndUser(user, metadata)\n if (combined) {\n toWrite.push(combined)\n }\n }\n let foundEmails: string[] = []\n for (let data of metadata) {\n if (!data._id) {\n continue\n }\n const alreadyExisting = data.email && foundEmails.indexOf(data.email) !== -1\n const globalId = getGlobalIDFromUserMetadataID(data._id)\n if (!users.find(user => user._id === globalId) || alreadyExisting) {\n toWrite.push({ ...data, _deleted: true })\n }\n if (data.email) {\n foundEmails.push(data.email)\n }\n }\n await db.bulkDocs(toWrite)\n}\n", "import * as utils from \"./utils\"\n\nexport default {\n ...utils,\n}\n", "import {\n createTempFolder,\n getPluginMetadata,\n extractTarball,\n} from \"../../../utilities/fileSystem\"\n\nexport async function fileUpload(file: { name: string; path: string }) {\n if (!file.name.endsWith(\".tar.gz\")) {\n throw new Error(\"Plugin must be compressed into a gzipped tarball.\")\n }\n const path = createTempFolder(file.name.split(\".tar.gz\")[0])\n await extractTarball(file.path, path)\n\n return await getPluginMetadata(path)\n}\n", "import { redis } from \"@budibase/backend-core\"\nimport { getGlobalIDFromUserMetadataID } from \"../db/utils\"\nimport { ContextUser } from \"@budibase/types\"\n\nconst APP_DEV_LOCK_SECONDS = 600\nconst AUTOMATION_TEST_FLAG_SECONDS = 60\nlet devAppClient: any, debounceClient: any, flagClient: any\n\n// we init this as we want to keep the connection open all the time\n// reduces the performance hit\nexport async function init() {\n devAppClient = new redis.Client(redis.utils.Databases.DEV_LOCKS)\n debounceClient = new redis.Client(redis.utils.Databases.DEBOUNCE)\n flagClient = new redis.Client(redis.utils.Databases.FLAGS)\n await devAppClient.init()\n await debounceClient.init()\n await flagClient.init()\n}\n\nexport async function shutdown() {\n if (devAppClient) await devAppClient.finish()\n if (debounceClient) await debounceClient.finish()\n if (flagClient) await flagClient.finish()\n // shutdown core clients\n await redis.clients.shutdown()\n console.log(\"Redis shutdown\")\n}\n\nexport async function doesUserHaveLock(devAppId: string, user: ContextUser) {\n const value = await devAppClient.get(devAppId)\n if (!value) {\n return true\n }\n // make sure both IDs are global\n const expected = getGlobalIDFromUserMetadataID(value._id)\n const userId = getGlobalIDFromUserMetadataID(user._id!)\n return expected === userId\n}\n\nexport async function getLocksById(appIds: string[]) {\n return await devAppClient.bulkGet(appIds)\n}\n\nexport async function updateLock(devAppId: string, user: ContextUser) {\n // make sure always global user ID\n const globalId = getGlobalIDFromUserMetadataID(user._id!)\n const inputUser = {\n ...user,\n userId: globalId,\n _id: globalId,\n lockedAt: new Date().getTime(),\n }\n\n await devAppClient.store(devAppId, inputUser, APP_DEV_LOCK_SECONDS)\n}\n\nexport async function clearLock(devAppId: string, user: ContextUser) {\n const value = await devAppClient.get(devAppId)\n if (!value) {\n return\n }\n const userId = getGlobalIDFromUserMetadataID(user._id!)\n if (value._id !== userId) {\n throw \"User does not hold lock, cannot clear it.\"\n }\n await devAppClient.delete(devAppId)\n}\n\nexport async function checkDebounce(id: string) {\n return debounceClient.get(id)\n}\n\nexport async function setDebounce(id: string, seconds: number) {\n await debounceClient.store(id, \"debouncing\", seconds)\n}\n\nexport async function setTestFlag(id: string) {\n await flagClient.store(id, { testing: true }, AUTOMATION_TEST_FLAG_SECONDS)\n}\n\nexport async function checkTestFlag(id: string) {\n const flag = await flagClient.get(id)\n return !!(flag && flag.testing)\n}\n\nexport async function clearTestFlag(id: string) {\n await devAppClient.delete(id)\n}\n", "import {\n APP_DEV_PREFIX,\n DocumentType,\n getGlobalIDFromUserMetadataID,\n} from \"../db/utils\"\nimport {\n doesUserHaveLock,\n updateLock,\n checkDebounce,\n setDebounce,\n} from \"../utilities/redis\"\nimport { db as dbCore, cache, permissions } from \"@budibase/backend-core\"\nimport { BBContext, Database } from \"@budibase/types\"\n\nconst DEBOUNCE_TIME_SEC = 30\n\n/************************************************** *\n * This middleware has been broken out of the *\n * \"authorized\" middleware as it had nothing to do *\n * with authorization, but requires the perms *\n * imparted by it. This middleware shouldn't *\n * be called directly, it should always be called *\n * through the authorized middleware *\n ****************************************************/\n\nasync function checkDevAppLocks(ctx: BBContext) {\n const appId = ctx.appId\n\n // if any public usage, don't proceed\n if (!ctx.user?._id && !ctx.user?.userId) {\n return\n }\n\n // not a development app, don't need to do anything\n if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {\n return\n }\n if (!(await doesUserHaveLock(appId, ctx.user))) {\n ctx.throw(400, \"User does not hold app lock.\")\n }\n\n // they do have lock, update it\n await updateLock(appId, ctx.user)\n}\n\nasync function updateAppUpdatedAt(ctx: BBContext) {\n const appId = ctx.appId\n // if debouncing skip this update\n // get methods also aren't updating\n if (ctx.method === \"GET\" || (await checkDebounce(appId))) {\n return\n }\n await dbCore.doWithDB(appId, async (db: Database) => {\n const metadata = await db.get(DocumentType.APP_METADATA)\n metadata.updatedAt = new Date().toISOString()\n\n metadata.updatedBy = getGlobalIDFromUserMetadataID(ctx.user?.userId!)\n\n const response = await db.put(metadata)\n metadata._rev = response.rev\n await cache.app.invalidateAppMetadata(appId, metadata)\n // set a new debounce record with a short TTL\n await setDebounce(appId, DEBOUNCE_TIME_SEC)\n })\n}\n\nexport default async function builder(ctx: BBContext) {\n const appId = ctx.appId\n // this only functions within an app context\n if (!appId) {\n return\n }\n\n // check authenticated\n if (!ctx.isAuthenticated) {\n return ctx.throw(403, \"Session not authenticated\")\n }\n\n const referer = ctx.headers[\"referer\"]\n\n const overviewPath = \"/builder/portal/overview/\"\n const overviewContext = !referer ? false : referer.includes(overviewPath)\n if (overviewContext) {\n return\n }\n\n const hasAppId = !referer ? false : referer.includes(appId)\n const editingApp = referer ? hasAppId : false\n // check this is a builder call and editing\n if (!editingApp) {\n return\n }\n // check locks\n await checkDevAppLocks(ctx)\n // set updated at time on app\n await updateAppUpdatedAt(ctx)\n}\n", "import { BBContext } from \"@budibase/types\"\n\nconst WEBHOOK_ENDPOINTS = new RegExp(\n [\"webhooks/trigger\", \"webhooks/schema\"].join(\"|\")\n)\n\nexport function isWebhookEndpoint(ctx: BBContext) {\n return WEBHOOK_ENDPOINTS.test(ctx.request.url)\n}\n", "import { roles, permissions, auth, context } from \"@budibase/backend-core\"\nimport { Role } from \"@budibase/types\"\nimport builderMiddleware from \"./builder\"\nimport { isWebhookEndpoint } from \"./utils\"\n\nfunction hasResource(ctx: any) {\n return ctx.resourceId != null\n}\n\nconst csrf = auth.buildCsrfMiddleware()\n\n/**\n * Apply authorization to the requested resource:\n * - If this is a builder resource the user must be a builder.\n * - Builders can access all resources.\n * - Otherwise the user must have the required role.\n */\nconst checkAuthorized = async (\n ctx: any,\n resourceRoles: any,\n permType: any,\n permLevel: any\n) => {\n // check if this is a builder api and the user is not a builder\n const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global\n const isBuilderApi = permType === permissions.PermissionType.BUILDER\n if (isBuilderApi && !isBuilder) {\n return ctx.throw(403, \"Not Authorized\")\n }\n\n // check for resource authorization\n if (!isBuilder) {\n await checkAuthorizedResource(ctx, resourceRoles, permType, permLevel)\n }\n}\n\nconst checkAuthorizedResource = async (\n ctx: any,\n resourceRoles: any,\n permType: any,\n permLevel: any\n) => {\n // get the user's roles\n const roleId = ctx.roleId || roles.BUILTIN_ROLE_IDS.PUBLIC\n const userRoles = (await roles.getUserRoleHierarchy(roleId, {\n idOnly: false,\n })) as Role[]\n const permError = \"User does not have permission\"\n // check if the user has the required role\n if (resourceRoles.length > 0) {\n // deny access if the user doesn't have the required resource role\n const found = userRoles.find(\n (role: any) => resourceRoles.indexOf(role._id) !== -1\n )\n if (!found) {\n ctx.throw(403, permError)\n }\n // fallback to the base permissions when no resource roles are found\n } else if (\n !permissions.doesHaveBasePermission(permType, permLevel, userRoles)\n ) {\n ctx.throw(403, permError)\n }\n}\n\nexport default (\n permType: any,\n permLevel: any = null,\n opts = { schema: false }\n ) =>\n async (ctx: any, next: any) => {\n // webhooks don't need authentication, each webhook unique\n // also internal requests (between services) don't need authorized\n if (isWebhookEndpoint(ctx) || ctx.internal) {\n return next()\n }\n\n if (!ctx.user) {\n return ctx.throw(403, \"No user info found\")\n }\n\n // get the resource roles\n let resourceRoles: any = []\n let otherLevelRoles: any = []\n const otherLevel =\n permLevel === permissions.PermissionLevel.READ\n ? permissions.PermissionLevel.WRITE\n : permissions.PermissionLevel.READ\n const appId = context.getAppId()\n if (appId && hasResource(ctx)) {\n resourceRoles = await roles.getRequiredResourceRole(permLevel, ctx)\n if (opts && opts.schema) {\n otherLevelRoles = await roles.getRequiredResourceRole(otherLevel, ctx)\n }\n }\n\n // if the resource is public, proceed\n if (\n resourceRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC) ||\n (otherLevelRoles &&\n otherLevelRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC))\n ) {\n return next()\n }\n\n // check authenticated\n if (!ctx.isAuthenticated) {\n return ctx.throw(403, \"Session not authenticated\")\n }\n\n // check general builder stuff, this middleware is a good way\n // to find API endpoints which are builder focused\n if (permType === permissions.PermissionType.BUILDER) {\n await builderMiddleware(ctx)\n }\n\n try {\n // check authorized\n await checkAuthorized(ctx, resourceRoles, permType, permLevel)\n } catch (err) {\n // this is a schema, check if\n if (opts && opts.schema && permLevel) {\n await checkAuthorized(ctx, otherLevelRoles, permType, otherLevel)\n } else {\n throw err\n }\n }\n\n // csrf protection\n return csrf(ctx, next)\n }\n", "import {\n utils,\n constants,\n roles,\n tenancy,\n context,\n} from \"@budibase/backend-core\"\nimport { generateUserMetadataID, isDevAppID } from \"../db/utils\"\nimport { getCachedSelf } from \"../utilities/global\"\nimport env from \"../environment\"\nimport { isWebhookEndpoint } from \"./utils\"\nimport { UserCtx } from \"@budibase/types\"\n\nexport default async (ctx: UserCtx, next: any) => {\n // try to get the appID from the request\n let requestAppId = await utils.getAppIdFromCtx(ctx)\n if (!requestAppId) {\n return next()\n }\n\n // deny access to application preview\n if (!env.isTest()) {\n if (\n isDevAppID(requestAppId) &&\n !isWebhookEndpoint(ctx) &&\n (!ctx.user || !ctx.user.builder || !ctx.user.builder.global)\n ) {\n return ctx.redirect(\"/\")\n }\n }\n\n let appId: string | undefined,\n roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n if (!ctx.user?._id) {\n // not logged in, try to set a cookie for public apps\n appId = requestAppId\n } else if (requestAppId != null) {\n // Different App ID means cookie needs reset, or if the same public user has logged in\n const globalUser = await getCachedSelf(ctx, requestAppId)\n appId = requestAppId\n // retrieving global user gets the right role\n roleId = globalUser.roleId || roleId\n\n // Allow builders to specify their role via a header\n const isBuilder =\n globalUser && globalUser.builder && globalUser.builder.global\n const isDevApp = appId && isDevAppID(appId)\n const roleHeader =\n ctx.request &&\n (ctx.request.headers[constants.Header.PREVIEW_ROLE] as string)\n if (isBuilder && isDevApp && roleHeader) {\n // Ensure the role is valid by ensuring a definition exists\n try {\n if (roleHeader) {\n await roles.getRole(roleHeader)\n roleId = roleHeader\n\n // Delete admin and builder flags so that the specified role is honoured\n delete ctx.user.builder\n delete ctx.user.admin\n }\n } catch (error) {\n // Swallow error and do nothing\n }\n }\n }\n\n // nothing more to do\n if (!appId) {\n return next()\n }\n\n return context.doInAppContext(appId, async () => {\n let skipCookie = false\n // if the user not in the right tenant then make sure they have no permissions\n // need to judge this only based on the request app ID,\n if (\n env.MULTI_TENANCY &&\n ctx.user?._id &&\n requestAppId &&\n !tenancy.isUserInAppTenant(requestAppId, ctx.user)\n ) {\n // don't error, simply remove the users rights (they are a public user)\n delete ctx.user.builder\n delete ctx.user.admin\n delete ctx.user.roles\n ctx.isAuthenticated = false\n roleId = roles.BUILTIN_ROLE_IDS.PUBLIC\n skipCookie = true\n }\n\n ctx.appId = appId\n if (roleId) {\n ctx.roleId = roleId\n const globalId = ctx.user ? ctx.user._id : undefined\n const userId = ctx.user\n ? generateUserMetadataID(ctx.user._id!)\n : undefined\n ctx.user = {\n ...ctx.user!,\n // override userID with metadata one\n _id: userId,\n userId,\n globalId,\n roleId,\n role: await roles.getRole(roleId),\n }\n }\n\n return next()\n })\n}\n", "import { Server } from \"socket.io\"\nimport http from \"http\"\nimport Koa from \"koa\"\nimport Cookies from \"cookies\"\nimport { userAgent } from \"koa-useragent\"\nimport { auth } from \"@budibase/backend-core\"\nimport currentApp from \"../middleware/currentapp\"\n\nexport default class Socket {\n io: Server\n\n constructor(\n app: Koa,\n server: http.Server,\n path: string,\n additionalMiddlewares?: any[]\n ) {\n this.io = new Server(server, {\n path,\n })\n\n // Attach default middlewares\n const authenticate = auth.buildAuthMiddleware([], {\n publicAllowed: true,\n })\n const middlewares = [\n userAgent,\n authenticate,\n currentApp,\n ...(additionalMiddlewares || []),\n ]\n\n // Apply middlewares\n this.io.use(async (socket, next) => {\n // Build fake koa context\n const res = new http.ServerResponse(socket.request)\n const ctx: any = {\n ...app.createContext(socket.request, res),\n\n // Additional overrides needed to make our middlewares work with this\n // fake koa context\n cookies: new Cookies(socket.request, res),\n get: (field: string) => socket.request.headers[field],\n throw: (code: number, message: string) => {\n throw new Error(message)\n },\n\n // Needed for koa-useragent middleware\n headers: socket.request.headers,\n header: socket.request.headers,\n\n // We don't really care about the path since it will never contain\n // an app ID\n path: \"/socket\",\n }\n\n // Run all koa middlewares\n try {\n for (let [idx, middleware] of middlewares.entries()) {\n await middleware(ctx, () => {\n if (idx === middlewares.length - 1) {\n // Middlewares are finished.\n // Extract some data from our enriched koa context to persist\n // as metadata for the socket\n socket.data.user = {\n id: ctx.user._id,\n email: ctx.user.email,\n }\n next()\n }\n })\n }\n } catch (error: any) {\n next(error)\n }\n })\n }\n\n // Emit an event to all sockets\n emit(event: string, payload: any) {\n this.io.sockets.emit(event, payload)\n }\n}\n", "import authorized from \"../middleware/authorized\"\nimport Socket from \"./websocket\"\nimport { permissions } from \"@budibase/backend-core\"\nimport http from \"http\"\nimport Koa from \"koa\"\n\nexport default class GridSocket extends Socket {\n constructor(app: Koa, server: http.Server) {\n super(app, server, \"/socket/grid\", [authorized(permissions.BUILDER)])\n\n this.io.on(\"connection\", socket => {\n const user = socket.data.user\n console.log(`Spreadsheet user connected: ${user?.id}`)\n\n // Socket state\n let currentRoom: string\n\n // Initial identification of connected spreadsheet\n socket.on(\"select-table\", async (tableId, callback) => {\n // Leave current room\n if (currentRoom) {\n socket.to(currentRoom).emit(\"user-disconnect\", socket.data.user)\n socket.leave(currentRoom)\n }\n\n // Join new room\n currentRoom = tableId\n socket.join(currentRoom)\n socket.to(currentRoom).emit(\"user-update\", socket.data.user)\n\n // Reply with all users in current room\n const sockets = await this.io.in(currentRoom).fetchSockets()\n callback({\n users: sockets.map(socket => socket.data.user),\n id: user.id,\n })\n })\n\n // Handle users selecting a new cell\n socket.on(\"select-cell\", cellId => {\n socket.data.user.selectedCellId = cellId\n if (currentRoom) {\n socket.to(currentRoom).emit(\"user-update\", socket.data.user)\n }\n })\n\n // Disconnection cleanup\n socket.on(\"disconnect\", () => {\n if (currentRoom) {\n socket.to(currentRoom).emit(\"user-disconnect\", socket.data.user)\n }\n })\n })\n }\n}\n", "import Socket from \"./websocket\"\nimport authorized from \"../middleware/authorized\"\nimport http from \"http\"\nimport Koa from \"koa\"\nimport { permissions } from \"@budibase/backend-core\"\n\nexport default class ClientAppWebsocket extends Socket {\n constructor(app: Koa, server: http.Server) {\n super(app, server, \"/socket/client\", [authorized(permissions.BUILDER)])\n }\n}\n", "import http from \"http\"\nimport Koa from \"koa\"\nimport GridSocket from \"./grid\"\nimport ClientAppSocket from \"./client\"\n\nlet clientAppSocket: ClientAppSocket\nlet gridSocket: GridSocket\n\nexport const initialise = (app: Koa, server: http.Server) => {\n clientAppSocket = new ClientAppSocket(app, server)\n gridSocket = new GridSocket(app, server)\n}\n\nexport { clientAppSocket, gridSocket }\n", "import { FileType, Plugin, PluginSource, PluginType } from \"@budibase/types\"\nimport {\n db as dbCore,\n objectStore,\n plugins as pluginCore,\n tenancy,\n} from \"@budibase/backend-core\"\nimport { fileUpload } from \"../../api/controllers/plugin/file\"\nimport env from \"../../environment\"\nimport { clientAppSocket } from \"../../websockets\"\nimport { sdk as pro } from \"@budibase/pro\"\n\nexport async function fetch(type?: PluginType) {\n const db = tenancy.getGlobalDB()\n const response = await db.allDocs(\n dbCore.getPluginParams(null, {\n include_docs: true,\n })\n )\n let plugins = response.rows.map((row: any) => row.doc) as Plugin[]\n plugins = objectStore.enrichPluginURLs(plugins)\n if (type) {\n return plugins.filter((plugin: Plugin) => plugin.schema?.type === type)\n } else {\n return plugins\n }\n}\n\nexport async function processUploaded(plugin: FileType, source?: PluginSource) {\n const { metadata, directory } = await fileUpload(plugin)\n pluginCore.validate(metadata?.schema)\n\n // Only allow components in cloud\n if (!env.SELF_HOSTED && metadata?.schema?.type !== PluginType.COMPONENT) {\n throw new Error(\"Only component plugins are supported outside of self-host\")\n }\n\n const doc = await pro.plugins.storePlugin(metadata, directory, source)\n clientAppSocket.emit(\"plugin-update\", { name: doc.name, hash: doc.hash })\n return doc\n}\n", "import * as plugins from \"./plugins\"\n\nexport default {\n ...plugins,\n}\n", "import { default as backups } from \"./app/backups\"\nimport { default as tables } from \"./app/tables\"\nimport { default as automations } from \"./app/automations\"\nimport { default as applications } from \"./app/applications\"\nimport { default as datasources } from \"./app/datasources\"\nimport { default as queries } from \"./app/queries\"\nimport { default as rows } from \"./app/rows\"\nimport { default as users } from \"./users\"\nimport { default as plugins } from \"./plugins\"\n\nconst sdk = {\n backups,\n tables,\n automations,\n applications,\n rows,\n users,\n datasources,\n queries,\n plugins,\n}\n\n// default export for TS\nexport default sdk\n", "import { AutomationResults, AutomationStep } from \"@budibase/types\"\n\nexport enum LoopStepType {\n ARRAY = \"Array\",\n STRING = \"String\",\n}\n\nexport interface LoopStep extends AutomationStep {\n inputs: {\n option: LoopStepType\n [key: string]: any\n }\n}\n\nexport interface LoopInput {\n binding: string[] | string\n}\n\nexport interface TriggerOutput {\n metadata?: any\n appId?: string\n timestamp?: number\n}\n\nexport interface AutomationContext extends AutomationResults {\n steps: any[]\n env?: Record<string, string>\n trigger: any\n}\n", "import {\n decodeJSBinding,\n isJSBinding,\n encodeJSBinding,\n} from \"@budibase/string-templates\"\nimport sdk from \"../sdk\"\nimport { Row } from \"@budibase/types\"\nimport { LoopStep, LoopStepType, LoopInput } from \"../definitions/automations\"\n\n/**\n * When values are input to the system generally they will be of type string as this is required for template strings.\n * This can generate some odd scenarios as the Schema of the automation requires a number but the builder might supply\n * a string with template syntax to get the number from the rest of the context. To support this the server has to\n * make sure that the post template statement can be cast into the correct type, this function does this for numbers\n * and booleans.\n *\n * @param {object} inputs An object of inputs, please note this will not recurse down into any objects within, it simply\n * cleanses the top level inputs, however it can be used by recursively calling it deeper into the object structures if\n * the schema is known.\n * @param {object} schema The defined schema of the inputs, in the form of JSON schema. The schema definition of an\n * automation is the likely use case of this, however validate.js syntax can be converted closely enough to use this by\n * wrapping the schema properties in a top level \"properties\" object.\n * @returns {object} The inputs object which has had all the various types supported by this function converted to their\n * primitive types.\n */\nexport function cleanInputValues(inputs: Record<string, any>, schema?: any) {\n if (schema == null) {\n return inputs\n }\n for (let inputKey of Object.keys(inputs)) {\n let input = inputs[inputKey]\n if (typeof input !== \"string\") {\n continue\n }\n let propSchema = schema.properties[inputKey]\n if (!propSchema) {\n continue\n }\n if (propSchema.type === \"boolean\") {\n let lcInput = input.toLowerCase()\n if (lcInput === \"true\") {\n inputs[inputKey] = true\n }\n if (lcInput === \"false\") {\n inputs[inputKey] = false\n }\n }\n if (propSchema.type === \"number\") {\n let floatInput = parseFloat(input)\n if (!isNaN(floatInput)) {\n inputs[inputKey] = floatInput\n }\n }\n }\n //Check if input field for Update Row should be a relationship and cast to array\n for (let key in inputs.row) {\n if (\n inputs.schema?.[key]?.type === \"link\" &&\n inputs.row[key] &&\n typeof inputs.row[key] === \"string\"\n ) {\n try {\n inputs.row[key] = JSON.parse(inputs.row[key])\n } catch (e) {\n //Link is not an array or object, so continue\n }\n }\n }\n return inputs\n}\n\n/**\n * Given a row input like a save or update row we need to clean the inputs against a schema that is not part of\n * the automation but is instead part of the Table/Table. This function will get the table schema and use it to instead\n * perform the cleanInputValues function on the input row.\n *\n * @param {string} tableId The ID of the Table/Table which the schema is to be retrieved for.\n * @param {object} row The input row structure which requires clean-up after having been through template statements.\n * @returns {Promise<Object>} The cleaned up rows object, will should now have all the required primitive types.\n */\nexport async function cleanUpRow(tableId: string, row: Row) {\n let table = await sdk.tables.getTable(tableId)\n return cleanInputValues(row, { properties: table.schema })\n}\n\nexport function getError(err: any) {\n if (err == null) {\n return \"No error provided.\"\n }\n if (\n typeof err === \"object\" &&\n (err.toString == null || err.toString() === \"[object Object]\")\n ) {\n return JSON.stringify(err)\n }\n return typeof err !== \"string\" ? err.toString() : err\n}\n\nexport function substituteLoopStep(hbsString: string, substitute: string) {\n let checkForJS = isJSBinding(hbsString)\n let substitutedHbsString = \"\"\n let open = checkForJS ? `$(\"` : \"{{\"\n let closed = checkForJS ? `\")` : \"}}\"\n if (checkForJS) {\n hbsString = decodeJSBinding(hbsString) as string\n }\n let pointer = 0,\n openPointer = 0,\n closedPointer = 0\n while (pointer < hbsString?.length) {\n openPointer = hbsString.indexOf(open, pointer)\n closedPointer = hbsString.indexOf(closed, pointer) + 2\n if (openPointer < 0 || closedPointer < 0) {\n substitutedHbsString += hbsString.substring(pointer)\n break\n }\n let before = hbsString.substring(pointer, openPointer)\n let block = hbsString\n .substring(openPointer, closedPointer)\n .replace(/loop/, substitute)\n substitutedHbsString += before + block\n pointer = closedPointer\n }\n if (checkForJS) {\n substitutedHbsString = encodeJSBinding(substitutedHbsString)\n }\n return substitutedHbsString\n}\n\nexport function stringSplit(value: string | string[]) {\n if (value == null || Array.isArray(value)) {\n return value || []\n }\n if (value.split(\"\\n\").length > 1) {\n value = value.split(\"\\n\")\n } else {\n value = value.split(\",\")\n }\n return value\n}\n\nexport function typecastForLooping(loopStep: LoopStep, input: LoopInput) {\n if (!input || !input.binding) {\n return null\n }\n try {\n switch (loopStep.inputs.option) {\n case LoopStepType.ARRAY:\n if (typeof input.binding === \"string\") {\n return JSON.parse(input.binding)\n }\n break\n case LoopStepType.STRING:\n if (Array.isArray(input.binding)) {\n return input.binding.join(\",\")\n }\n break\n }\n } catch (err) {\n throw new Error(\"Unable to cast to correct type\")\n }\n return input.binding\n}\n", "import { InternalTables } from \"../db/utils\"\nimport { getGlobalUser } from \"./global\"\nimport { context, db as dbCore, roles } from \"@budibase/backend-core\"\nimport { BBContext } from \"@budibase/types\"\n\nexport async function getFullUser(ctx: BBContext, userId: string) {\n const global = await getGlobalUser(userId)\n let metadata: any = {}\n\n // always prefer the user metadata _id and _rev\n delete global._id\n delete global._rev\n\n try {\n // this will throw an error if the db doesn't exist, or there is no appId\n const db = context.getAppDB()\n metadata = await db.get(userId)\n } catch (err) {\n // it is fine if there is no user metadata yet\n }\n delete metadata.csrfToken\n return {\n ...metadata,\n ...global,\n roleId: global.roleId || roles.BUILTIN_ROLE_IDS.PUBLIC,\n tableId: InternalTables.USER_METADATA,\n // make sure the ID is always a local ID, not a global one\n _id: userId,\n }\n}\n\nexport function publicApiUserFix(ctx: BBContext) {\n if (!ctx.request.body) {\n return ctx\n }\n if (!ctx.request.body._id && ctx.params.userId) {\n ctx.request.body._id = ctx.params.userId\n }\n if (!ctx.request.body.roles) {\n ctx.request.body.roles = {}\n } else {\n const newRoles: { [key: string]: any } = {}\n for (let [appId, role] of Object.entries(ctx.request.body.roles)) {\n newRoles[dbCore.getProdAppID(appId)] = role\n }\n ctx.request.body.roles = newRoles\n }\n return ctx\n}\n", "import { generateUserMetadataID, generateUserFlagID } from \"../../db/utils\"\nimport { InternalTables } from \"../../db/utils\"\nimport { getGlobalUsers } from \"../../utilities/global\"\nimport { getFullUser } from \"../../utilities/users\"\nimport { context } from \"@budibase/backend-core\"\nimport { UserCtx } from \"@budibase/types\"\nimport sdk from \"../../sdk\"\n\nexport async function fetchMetadata(ctx: UserCtx) {\n const global = await getGlobalUsers()\n const metadata = await sdk.users.rawUserMetadata()\n const users = []\n for (let user of global) {\n // find the metadata that matches up to the global ID\n const info = metadata.find(meta => meta._id.includes(user._id))\n // remove these props, not for the correct DB\n users.push({\n ...user,\n ...info,\n tableId: InternalTables.USER_METADATA,\n // make sure the ID is always a local ID, not a global one\n _id: generateUserMetadataID(user._id),\n })\n }\n ctx.body = users\n}\n\nexport async function updateSelfMetadata(ctx: UserCtx) {\n // overwrite the ID with current users\n ctx.request.body._id = ctx.user?._id\n // make sure no stale rev\n delete ctx.request.body._rev\n // make sure no csrf token\n delete ctx.request.body.csrfToken\n await updateMetadata(ctx)\n}\n\nexport async function updateMetadata(ctx: UserCtx) {\n const db = context.getAppDB()\n const user = ctx.request.body\n // this isn't applicable to the user\n delete user.roles\n const metadata = {\n tableId: InternalTables.USER_METADATA,\n ...user,\n }\n ctx.body = await db.put(metadata)\n}\n\nexport async function destroyMetadata(ctx: UserCtx) {\n const db = context.getAppDB()\n try {\n const dbUser = await db.get(ctx.params.id)\n await db.remove(dbUser._id, dbUser._rev)\n } catch (err) {\n // error just means the global user has no config in this app\n }\n ctx.body = {\n message: `User metadata ${ctx.params.id} deleted.`,\n }\n}\n\nexport async function findMetadata(ctx: UserCtx) {\n ctx.body = await getFullUser(ctx, ctx.params.id)\n}\n\nexport async function setFlag(ctx: UserCtx) {\n const userId = ctx.user?._id\n const { flag, value } = ctx.request.body\n if (!flag) {\n ctx.throw(400, \"Must supply a 'flag' field in request body.\")\n }\n const flagDocId = generateUserFlagID(userId!)\n const db = context.getAppDB()\n let doc\n try {\n doc = await db.get(flagDocId)\n } catch (err) {\n doc = { _id: flagDocId }\n }\n doc[flag] = value || true\n await db.put(doc)\n ctx.body = { message: \"Flag set successfully\" }\n}\n\nexport async function getFlags(ctx: UserCtx) {\n const userId = ctx.user?._id\n const docId = generateUserFlagID(userId!)\n const db = context.getAppDB()\n let doc\n try {\n doc = await db.get(docId)\n } catch (err) {\n doc = { _id: docId }\n }\n ctx.body = doc\n}\n", "import { QueryJson, Datasource } from \"@budibase/types\"\nimport { getIntegration } from \"../index\"\nimport sdk from \"../../sdk\"\n\nexport async function makeExternalQuery(\n datasource: Datasource,\n json: QueryJson\n) {\n datasource = await sdk.datasources.enrich(datasource)\n const Integration = await getIntegration(datasource.source)\n // query is the opinionated function\n if (Integration.prototype.query) {\n const integration = new Integration(datasource.config)\n return integration.query(json)\n } else {\n throw \"Datasource does not support query.\"\n }\n}\n", "import { Row, TableSchema } from \"@budibase/types\"\n\nexport function csv(headers: string[], rows: Row[]) {\n let csv = headers.map(key => `\"${key}\"`).join(\",\")\n\n for (let row of rows) {\n csv = `${csv}\\n${headers\n .map(header => {\n let val = row[header]\n val =\n typeof val === \"object\" && !(val instanceof Date)\n ? `\"${JSON.stringify(val).replace(/\"/g, \"'\")}\"`\n : val !== undefined\n ? `\"${val}\"`\n : \"\"\n return val.trim()\n })\n .join(\",\")}`\n }\n return csv\n}\n\nexport function json(rows: Row[]) {\n return JSON.stringify(rows, undefined, 2)\n}\n\nexport function jsonWithSchema(schema: TableSchema, rows: Row[]) {\n const newSchema: TableSchema = {}\n Object.values(schema).forEach(column => {\n if (!column.autocolumn) {\n newSchema[column.name] = column\n }\n })\n return JSON.stringify({ schema: newSchema, rows }, undefined, 2)\n}\n\nexport enum Format {\n CSV = \"csv\",\n JSON = \"json\",\n JSON_WITH_SCHEMA = \"jsonWithSchema\",\n}\n\nexport function isFormat(format: any): format is Format {\n return Object.values(Format).includes(format as Format)\n}\n", "import { InternalTables } from \"../../../db/utils\"\nimport * as userController from \"../user\"\nimport { FieldTypes } from \"../../../constants\"\nimport { context } from \"@budibase/backend-core\"\nimport { makeExternalQuery } from \"../../../integrations/base/query\"\nimport { Row, Table } from \"@budibase/types\"\nimport { Format } from \"../view/exporters\"\nimport { UserCtx } from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\nconst validateJs = require(\"validate.js\")\nconst { cloneDeep } = require(\"lodash/fp\")\n\nvalidateJs.extend(validateJs.validators.datetime, {\n parse: function (value: string) {\n return new Date(value).getTime()\n },\n // Input is a unix timestamp\n format: function (value: string) {\n return new Date(value).toISOString()\n },\n})\n\nexport async function getDatasourceAndQuery(json: any) {\n const datasourceId = json.endpoint.datasourceId\n const datasource = await sdk.datasources.get(datasourceId)\n return makeExternalQuery(datasource, json)\n}\n\nexport async function findRow(ctx: UserCtx, tableId: string, rowId: string) {\n const db = context.getAppDB()\n let row\n // TODO remove special user case in future\n if (tableId === InternalTables.USER_METADATA) {\n ctx.params = {\n id: rowId,\n }\n await userController.findMetadata(ctx)\n row = ctx.body\n } else {\n row = await db.get(rowId)\n }\n if (row.tableId !== tableId) {\n throw \"Supplied tableId does not match the rows tableId\"\n }\n return row\n}\n\nexport async function validate({\n tableId,\n row,\n table,\n}: {\n tableId?: string\n row: Row\n table?: Table\n}) {\n let fetchedTable: Table\n if (!table) {\n fetchedTable = await sdk.tables.getTable(tableId)\n } else {\n fetchedTable = table\n }\n const errors: any = {}\n for (let fieldName of Object.keys(fetchedTable.schema)) {\n const column = fetchedTable.schema[fieldName]\n const constraints = cloneDeep(column.constraints)\n const type = column.type\n // formulas shouldn't validated, data will be deleted anyway\n if (type === FieldTypes.FORMULA || column.autocolumn) {\n continue\n }\n // special case for options, need to always allow unselected (empty)\n if (type === FieldTypes.OPTIONS && constraints.inclusion) {\n constraints.inclusion.push(null, \"\")\n }\n let res\n\n // Validate.js doesn't seem to handle array\n if (type === FieldTypes.ARRAY && row[fieldName]) {\n if (row[fieldName].length) {\n if (!Array.isArray(row[fieldName])) {\n row[fieldName] = row[fieldName].split(\",\")\n }\n row[fieldName].map((val: any) => {\n if (\n !constraints.inclusion.includes(val) &&\n constraints.inclusion.length !== 0\n ) {\n errors[fieldName] = \"Field not in list\"\n }\n })\n } else if (constraints.presence && row[fieldName].length === 0) {\n // non required MultiSelect creates an empty array, which should not throw errors\n errors[fieldName] = [`${fieldName} is required`]\n }\n } else if (\n (type === FieldTypes.ATTACHMENT || type === FieldTypes.JSON) &&\n typeof row[fieldName] === \"string\"\n ) {\n // this should only happen if there is an error\n try {\n const json = JSON.parse(row[fieldName])\n if (type === FieldTypes.ATTACHMENT) {\n if (Array.isArray(json)) {\n row[fieldName] = json\n } else {\n errors[fieldName] = [`Must be an array`]\n }\n }\n } catch (err) {\n errors[fieldName] = [`Contains invalid JSON`]\n }\n } else {\n res = validateJs.single(row[fieldName], constraints)\n }\n if (res) errors[fieldName] = res\n }\n return { valid: Object.keys(errors).length === 0, errors }\n}\n\nexport function cleanExportRows(\n rows: any[],\n schema: any,\n format: string,\n columns: string[]\n) {\n let cleanRows = [...rows]\n\n const relationships = Object.entries(schema)\n .filter((entry: any[]) => entry[1].type === FieldTypes.LINK)\n .map(entry => entry[0])\n\n relationships.forEach(column => {\n cleanRows.forEach(row => {\n delete row[column]\n })\n delete schema[column]\n })\n\n if (format === Format.CSV) {\n // Intended to append empty values in export\n const schemaKeys = Object.keys(schema)\n for (let key of schemaKeys) {\n if (columns?.length && columns.indexOf(key) > 0) {\n continue\n }\n for (let row of cleanRows) {\n if (row[key] == null) {\n row[key] = undefined\n }\n }\n }\n }\n\n return cleanRows\n}\n", "import { execSync } from \"child_process\"\nimport { processStringSync } from \"@budibase/string-templates\"\nimport * as automationUtils from \"../automationUtils\"\nimport environment from \"../../environment\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Bash Scripting\",\n tagline: \"Execute a bash command\",\n icon: \"JourneyEvent\",\n description: \"Run a bash script\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.EXECUTE_BASH,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n code: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.CODE,\n title: \"Code\",\n },\n },\n required: [\"code\"],\n },\n outputs: {\n properties: {\n stdout: {\n type: AutomationIOType.STRING,\n description: \"Standard output of your bash command or script\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the command was successful\",\n },\n },\n required: [\"stdout\"],\n },\n },\n}\n\nexport async function run({ inputs, context }: AutomationStepInput) {\n if (inputs.code == null) {\n return {\n stdout: \"Budibase bash automation failed: Invalid inputs\",\n }\n }\n\n try {\n const command = processStringSync(inputs.code, context)\n\n let stdout,\n success = true\n try {\n stdout = execSync(command, {\n timeout: environment.QUERY_THREAD_TIMEOUT || 500,\n }).toString()\n } catch (err: any) {\n stdout = err.message\n success = false\n }\n\n return {\n stdout,\n success,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import { Configuration, OpenAIApi } from \"openai\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\nimport * as automationUtils from \"../automationUtils\"\nimport environment from \"../../environment\"\n\nenum Model {\n GPT_35_TURBO = \"gpt-3.5-turbo\",\n // will only work with api keys that have access to the GPT4 API\n GPT_4 = \"gpt-4\",\n}\n\nexport const definition: AutomationStepSchema = {\n name: \"OpenAI\",\n tagline: \"Send prompts to ChatGPT\",\n icon: \"Algorithm\",\n description: \"Interact with the OpenAI ChatGPT API.\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.OPENAI,\n inputs: {\n prompt: \"\",\n },\n schema: {\n inputs: {\n properties: {\n prompt: {\n type: AutomationIOType.STRING,\n title: \"Prompt\",\n },\n model: {\n type: AutomationIOType.STRING,\n title: \"Model\",\n enum: Object.values(Model),\n },\n },\n required: [\"prompt\", \"model\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n response: {\n type: AutomationIOType.STRING,\n description: \"What was output\",\n },\n },\n required: [\"success\", \"response\"],\n },\n },\n}\n\nexport async function run({ inputs, context }: AutomationStepInput) {\n if (!environment.OPENAI_API_KEY) {\n return {\n success: false,\n response:\n \"OpenAI API Key not configured - please add the OPENAI_API_KEY environment variable.\",\n }\n }\n\n if (inputs.prompt == null) {\n return {\n success: false,\n response: \"Budibase OpenAI Automation Failed: No prompt supplied\",\n }\n }\n\n try {\n const configuration = new Configuration({\n apiKey: environment.OPENAI_API_KEY,\n })\n\n const openai = new OpenAIApi(configuration)\n\n const completion = await openai.createChatCompletion({\n model: inputs.model,\n messages: [\n {\n role: \"user\",\n content: inputs.prompt,\n },\n ],\n })\n\n const response = completion?.data?.choices[0]?.message?.content\n\n return {\n response,\n success: true,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import { default as threadUtils } from \"./utils\"\nimport { Job } from \"bull\"\nthreadUtils.threadSetup()\nimport {\n isRecurring,\n disableCronById,\n isErrorInOutput,\n} from \"../automations/utils\"\nimport * as actions from \"../automations/actions\"\nimport * as automationUtils from \"../automations/automationUtils\"\nimport { default as AutomationEmitter } from \"../events/AutomationEmitter\"\nimport { generateAutomationMetadataID, isProdAppID } from \"../db/utils\"\nimport { definitions as triggerDefs } from \"../automations/triggerInfo\"\nimport { AutomationErrors, MAX_AUTOMATION_RECURRING_ERRORS } from \"../constants\"\nimport { storeLog } from \"../automations/logging\"\nimport {\n Automation,\n AutomationStep,\n AutomationStatus,\n AutomationMetadata,\n AutomationJob,\n} from \"@budibase/types\"\nimport {\n LoopStep,\n LoopInput,\n TriggerOutput,\n AutomationContext,\n} from \"../definitions/automations\"\nimport { WorkerCallback } from \"./definitions\"\nimport { context, logging } from \"@budibase/backend-core\"\nimport { processObject } from \"@budibase/string-templates\"\nimport { cloneDeep } from \"lodash/fp\"\nimport * as sdkUtils from \"../sdk/utils\"\nimport env from \"../environment\"\nconst FILTER_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.FILTER.stepId\nconst LOOP_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.LOOP.stepId\nconst CRON_STEP_ID = triggerDefs.CRON.stepId\nconst STOPPED_STATUS = { success: true, status: AutomationStatus.STOPPED }\n\nfunction getLoopIterations(loopStep: LoopStep, input: LoopInput) {\n const binding = automationUtils.typecastForLooping(loopStep, input)\n if (!binding) {\n return 0\n }\n if (Array.isArray(binding)) {\n return binding.length\n }\n if (typeof binding === \"string\") {\n return automationUtils.stringSplit(binding).length\n }\n return 0\n}\n\n/**\n * The automation orchestrator is a class responsible for executing automations.\n * It handles the context of the automation and makes sure each step gets the correct\n * inputs and handles any outputs.\n */\nclass Orchestrator {\n _chainCount: number\n _appId: string\n _automation: Automation\n _emitter: any\n _context: AutomationContext\n _job: Job\n executionOutput: AutomationContext\n\n constructor(job: AutomationJob) {\n let automation = job.data.automation\n let triggerOutput = job.data.event\n const metadata = triggerOutput.metadata\n this._chainCount = metadata ? metadata.automationChainCount! : 0\n this._appId = triggerOutput.appId as string\n this._job = job\n const triggerStepId = automation.definition.trigger.stepId\n triggerOutput = this.cleanupTriggerOutputs(triggerStepId, triggerOutput)\n // remove from context\n delete triggerOutput.appId\n delete triggerOutput.metadata\n // step zero is never used as the template string is zero indexed for customer facing\n this._context = { steps: [{}], trigger: triggerOutput }\n this._automation = automation\n // create an emitter which has the chain count for this automation run in it, so it can block\n // excessive chaining if required\n this._emitter = new AutomationEmitter(this._chainCount + 1)\n this.executionOutput = { trigger: {}, steps: [] }\n // setup the execution output\n const triggerId = automation.definition.trigger.id\n this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)\n }\n\n cleanupTriggerOutputs(stepId: string, triggerOutput: TriggerOutput) {\n if (stepId === CRON_STEP_ID) {\n triggerOutput.timestamp = Date.now()\n }\n return triggerOutput\n }\n\n async getStepFunctionality(stepId: string) {\n let step = await actions.getAction(stepId)\n if (step == null) {\n throw `Cannot find automation step by name ${stepId}`\n }\n return step\n }\n\n async getMetadata(): Promise<AutomationMetadata> {\n const metadataId = generateAutomationMetadataID(this._automation._id!)\n const db = context.getAppDB()\n let metadata: AutomationMetadata\n try {\n metadata = await db.get(metadataId)\n } catch (err) {\n metadata = {\n _id: metadataId,\n errorCount: 0,\n }\n }\n return metadata\n }\n\n async stopCron(reason: string) {\n if (!this._job.opts.repeat) {\n return\n }\n logging.logWarn(\n `CRON disabled reason=${reason} - ${this._appId}/${this._automation._id}`\n )\n const automation = this._automation\n const trigger = automation.definition.trigger\n await disableCronById(this._job.id)\n this.updateExecutionOutput(\n trigger.id,\n trigger.stepId,\n {},\n {\n status: AutomationStatus.STOPPED_ERROR,\n success: false,\n }\n )\n await storeLog(automation, this.executionOutput)\n }\n\n async checkIfShouldStop(metadata: AutomationMetadata): Promise<boolean> {\n if (!metadata.errorCount || !this._job.opts.repeat) {\n return false\n }\n if (metadata.errorCount >= MAX_AUTOMATION_RECURRING_ERRORS) {\n await this.stopCron(\"errors\")\n return true\n }\n return false\n }\n\n async updateMetadata(metadata: AutomationMetadata) {\n const output = this.executionOutput,\n automation = this._automation\n if (!output || !isRecurring(automation)) {\n return\n }\n const count = metadata.errorCount\n const isError = isErrorInOutput(output)\n // nothing to do in this scenario, escape\n if (!count && !isError) {\n return\n }\n if (isError) {\n metadata.errorCount = count ? count + 1 : 1\n } else {\n metadata.errorCount = 0\n }\n const db = context.getAppDB()\n try {\n await db.put(metadata)\n } catch (err) {\n logging.logAlertWithInfo(\n \"Failed to write automation metadata\",\n db.name,\n automation._id!,\n err\n )\n }\n }\n\n updateExecutionOutput(id: string, stepId: string, inputs: any, outputs: any) {\n const stepObj = { id, stepId, inputs, outputs }\n // replacing trigger when disabling CRON\n if (\n stepId === CRON_STEP_ID &&\n outputs.status === AutomationStatus.STOPPED_ERROR\n ) {\n this.executionOutput.trigger = stepObj\n this.executionOutput.steps = [stepObj]\n return\n }\n // first entry is always the trigger (constructor)\n if (\n this.executionOutput.steps.length === 0 ||\n this.executionOutput.trigger.id === id\n ) {\n this.executionOutput.trigger = stepObj\n }\n this.executionOutput.steps.push(stepObj)\n }\n\n updateContextAndOutput(\n loopStepNumber: number | undefined,\n step: AutomationStep,\n output: any,\n result: { success: boolean; status: string }\n ) {\n if (!loopStepNumber) {\n throw new Error(\"No loop step number provided.\")\n }\n this.executionOutput.steps.splice(loopStepNumber, 0, {\n id: step.id,\n stepId: step.stepId,\n outputs: {\n ...output,\n success: result.success,\n status: result.status,\n },\n inputs: step.inputs,\n })\n this._context.steps.splice(loopStepNumber, 0, {\n ...output,\n success: result.success,\n status: result.status,\n })\n }\n\n async execute() {\n // this will retrieve from context created at start of thread\n this._context.env = await sdkUtils.getEnvironmentVariables()\n let automation = this._automation\n let stopped = false\n let loopStep: AutomationStep | undefined = undefined\n\n let stepCount = 0\n let loopStepNumber: any = undefined\n let loopSteps: LoopStep[] | undefined = []\n let metadata\n let wasLoopStep = false\n // check if this is a recurring automation,\n if (isProdAppID(this._appId) && isRecurring(automation)) {\n metadata = await this.getMetadata()\n const shouldStop = await this.checkIfShouldStop(metadata)\n if (shouldStop) {\n return\n }\n }\n\n for (let step of automation.definition.steps) {\n stepCount++\n let input: any,\n iterations = 1,\n iterationCount = 0\n\n if (step.stepId === LOOP_STEP_ID) {\n loopStep = step\n loopStepNumber = stepCount\n continue\n }\n\n if (loopStep) {\n input = await processObject(loopStep.inputs, this._context)\n iterations = getLoopIterations(loopStep as LoopStep, input)\n }\n for (let index = 0; index < iterations; index++) {\n let originalStepInput = cloneDeep(step.inputs)\n // Handle if the user has set a max iteration count or if it reaches the max limit set by us\n if (loopStep && input.binding) {\n let newInput: any = await processObject(\n loopStep.inputs,\n cloneDeep(this._context)\n )\n\n let tempOutput = { items: loopSteps, iterations: iterationCount }\n try {\n newInput.binding = automationUtils.typecastForLooping(\n loopStep as LoopStep,\n newInput\n )\n } catch (err) {\n this.updateContextAndOutput(loopStepNumber, step, tempOutput, {\n status: AutomationErrors.INCORRECT_TYPE,\n success: false,\n })\n loopSteps = undefined\n loopStep = undefined\n break\n }\n\n let item = []\n if (\n typeof loopStep.inputs.binding === \"string\" &&\n loopStep.inputs.option === \"String\"\n ) {\n item = automationUtils.stringSplit(newInput.binding)\n } else if (Array.isArray(loopStep.inputs.binding)) {\n item = loopStep.inputs.binding\n }\n this._context.steps[loopStepNumber] = {\n currentItem: item[index],\n }\n\n // The \"Loop\" binding in the front end is \"fake\", so replace it here so the context can understand it\n // Pretty hacky because we need to account for the row object\n for (let [key, value] of Object.entries(originalStepInput)) {\n if (typeof value === \"object\") {\n for (let [innerKey, innerValue] of Object.entries(\n originalStepInput[key]\n )) {\n if (typeof innerValue === \"string\") {\n originalStepInput[key][innerKey] =\n automationUtils.substituteLoopStep(\n innerValue,\n `steps.${loopStepNumber}`\n )\n } else if (typeof value === \"object\") {\n for (let [innerObject, innerValue] of Object.entries(\n originalStepInput[key][innerKey]\n )) {\n originalStepInput[key][innerKey][innerObject] =\n automationUtils.substituteLoopStep(\n innerValue as string,\n `steps.${loopStepNumber}`\n )\n }\n }\n }\n } else {\n if (typeof value === \"string\") {\n originalStepInput[key] = automationUtils.substituteLoopStep(\n value,\n `steps.${loopStepNumber}`\n )\n }\n }\n }\n if (\n index === env.AUTOMATION_MAX_ITERATIONS ||\n index === parseInt(loopStep.inputs.iterations)\n ) {\n this.updateContextAndOutput(loopStepNumber, step, tempOutput, {\n status: AutomationErrors.MAX_ITERATIONS,\n success: true,\n })\n loopSteps = undefined\n loopStep = undefined\n break\n }\n\n let isFailure = false\n const currentItem = this._context.steps[loopStepNumber]?.currentItem\n if (currentItem && typeof currentItem === \"object\") {\n isFailure = Object.keys(currentItem).some(value => {\n return currentItem[value] === loopStep?.inputs.failure\n })\n } else {\n isFailure = currentItem && currentItem === loopStep.inputs.failure\n }\n\n if (isFailure) {\n this.updateContextAndOutput(loopStepNumber, step, tempOutput, {\n status: AutomationErrors.FAILURE_CONDITION,\n success: false,\n })\n loopSteps = undefined\n loopStep = undefined\n break\n }\n }\n\n // execution stopped, record state for that\n if (stopped) {\n this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS)\n continue\n }\n\n // If it's a loop step, we need to manually add the bindings to the context\n let stepFn = await this.getStepFunctionality(step.stepId)\n let inputs = await processObject(originalStepInput, this._context)\n inputs = automationUtils.cleanInputValues(inputs, step.schema.inputs)\n\n try {\n // appId is always passed\n const outputs = await stepFn({\n inputs: inputs,\n appId: this._appId,\n emitter: this._emitter,\n context: this._context,\n })\n\n this._context.steps[stepCount] = outputs\n // if filter causes us to stop execution don't break the loop, set a var\n // so that we can finish iterating through the steps and record that it stopped\n if (step.stepId === FILTER_STEP_ID && !outputs.result) {\n stopped = true\n this.updateExecutionOutput(step.id, step.stepId, step.inputs, {\n ...outputs,\n ...STOPPED_STATUS,\n })\n continue\n }\n if (loopStep && loopSteps) {\n loopSteps.push(outputs)\n } else {\n this.updateExecutionOutput(\n step.id,\n step.stepId,\n step.inputs,\n outputs\n )\n }\n } catch (err) {\n console.error(`Automation error - ${step.stepId} - ${err}`)\n return err\n }\n\n if (loopStep) {\n iterationCount++\n if (index === iterations - 1) {\n loopStep = undefined\n this._context.steps.splice(loopStepNumber, 1)\n break\n }\n }\n }\n\n if (loopStep && iterations === 0) {\n loopStep = undefined\n this.executionOutput.steps.splice(loopStepNumber + 1, 0, {\n id: step.id,\n stepId: step.stepId,\n outputs: { status: AutomationStatus.NO_ITERATIONS, success: true },\n inputs: {},\n })\n\n this._context.steps.splice(loopStepNumber, 1)\n iterations = 1\n }\n\n // Delete the step after the loop step as it's irrelevant, since information is included\n // in the loop step\n if (wasLoopStep && !loopStep) {\n this._context.steps.splice(loopStepNumber + 1, 1)\n wasLoopStep = false\n }\n if (loopSteps && loopSteps.length) {\n let tempOutput = {\n success: true,\n items: loopSteps,\n iterations: iterationCount,\n }\n this.executionOutput.steps.splice(loopStepNumber + 1, 0, {\n id: step.id,\n stepId: step.stepId,\n outputs: tempOutput,\n inputs: step.inputs,\n })\n this._context.steps[loopStepNumber] = tempOutput\n\n wasLoopStep = true\n loopSteps = []\n }\n }\n\n // store the logs for the automation run\n await storeLog(this._automation, this.executionOutput)\n if (isProdAppID(this._appId) && isRecurring(automation) && metadata) {\n await this.updateMetadata(metadata)\n }\n return this.executionOutput\n }\n}\n\nexport function execute(job: Job, callback: WorkerCallback) {\n const appId = job.data.event.appId\n if (!appId) {\n throw new Error(\"Unable to execute, event doesn't contain app ID.\")\n }\n return context.doInAppContext(appId, async () => {\n const envVars = await sdkUtils.getEnvironmentVariables()\n // put into automation thread for whole context\n await context.doInEnvironmentContext(envVars, async () => {\n const automationOrchestrator = new Orchestrator(job)\n try {\n const response = await automationOrchestrator.execute()\n callback(null, response)\n } catch (err) {\n callback(err)\n }\n })\n })\n}\n\nexport const removeStalled = async (job: Job) => {\n const appId = job.data.event.appId\n if (!appId) {\n throw new Error(\"Unable to execute, event doesn't contain app ID.\")\n }\n await context.doInAppContext(appId, async () => {\n const automationOrchestrator = new Orchestrator(job)\n await automationOrchestrator.stopCron(\"stalled\")\n })\n}\n", "import { QueryVariable } from \"./definitions\"\nimport env from \"../environment\"\nimport * as db from \"../db\"\nimport { redis, db as dbCore } from \"@budibase/backend-core\"\n\nconst VARIABLE_TTL_SECONDS = 3600\nlet client: any\n\nasync function getClient() {\n if (!client) {\n client = await new redis.Client(redis.utils.Databases.QUERY_VARS).init()\n }\n return client\n}\n\nprocess.on(\"exit\", async () => {\n if (client) {\n await client.finish()\n }\n})\n\nfunction makeVariableKey(queryId: string, variable: string) {\n return `${queryId}${dbCore.SEPARATOR}${variable}`\n}\n\nexport function threadSetup() {\n // don't run this if not threading\n if (env.isTest() || env.DISABLE_THREADING || !env.isInThread()) {\n return\n }\n db.init()\n}\n\nexport async function checkCacheForDynamicVariable(\n queryId: string,\n variable: string\n) {\n const cache = await getClient()\n return cache.get(makeVariableKey(queryId, variable))\n}\n\nexport async function invalidateDynamicVariables(cachedVars: QueryVariable[]) {\n const cache = await getClient()\n let promises = []\n for (let variable of cachedVars) {\n promises.push(\n cache.delete(makeVariableKey(variable.queryId, variable.name))\n )\n }\n await Promise.all(promises)\n}\n\nexport async function storeDynamicVariable(\n queryId: string,\n variable: string,\n value: any\n) {\n const cache = await getClient()\n await cache.store(\n makeVariableKey(queryId, variable),\n value,\n VARIABLE_TTL_SECONDS\n )\n}\n\nexport function formatResponse(resp: any) {\n if (typeof resp === \"string\") {\n try {\n resp = JSON.parse(resp)\n } catch (err) {\n resp = { response: resp }\n }\n }\n return resp\n}\n\nexport function hasExtraData(response: any) {\n return (\n typeof response === \"object\" &&\n !Array.isArray(response) &&\n response &&\n response.data != null &&\n response.info != null\n )\n}\n\nexport default {\n hasExtraData,\n formatResponse,\n storeDynamicVariable,\n invalidateDynamicVariables,\n checkCacheForDynamicVariable,\n threadSetup,\n}\n", "import * as core from \"@budibase/backend-core\"\nimport env from \"../environment\"\n\nexport function init() {\n const dbConfig: any = {\n replication: true,\n find: true,\n }\n\n if (env.isTest() && !env.COUCH_DB_URL) {\n dbConfig.inMemory = true\n dbConfig.allDbs = true\n }\n\n core.init({ db: dbConfig })\n}\n", "import workerFarm from \"worker-farm\"\nimport env from \"../environment\"\nimport { AutomationJob } from \"@budibase/types\"\nimport { QueryEvent } from \"./definitions\"\n\nexport const ThreadType = {\n QUERY: \"query\",\n AUTOMATION: \"automation\",\n}\n\nfunction typeToFile(type: any) {\n let filename = null\n switch (type) {\n case ThreadType.QUERY:\n filename = \"./query\"\n break\n case ThreadType.AUTOMATION:\n filename = \"./automation\"\n break\n default:\n throw \"Unknown thread type\"\n }\n // have to use require here, to make it work with worker-farm\n return require.resolve(filename)\n}\n\nexport class Thread {\n type: any\n count: any\n workers: any\n timeoutMs: any\n disableThreading: boolean\n\n static workerRefs: any[] = []\n\n constructor(type: any, opts: any = { timeoutMs: null, count: 1 }) {\n this.type = type\n this.count = opts.count ? opts.count : 1\n this.disableThreading = this.shouldDisableThreading()\n if (!this.disableThreading) {\n const workerOpts: any = {\n autoStart: true,\n maxConcurrentWorkers: this.count,\n workerOptions: {\n env: {\n ...process.env,\n FORKED_PROCESS: \"1\",\n },\n },\n }\n if (opts.timeoutMs) {\n this.timeoutMs = opts.timeoutMs\n workerOpts.maxCallTime = opts.timeoutMs\n }\n this.workers = workerFarm(workerOpts, typeToFile(type), [\"execute\"])\n Thread.workerRefs.push(this.workers)\n }\n }\n\n shouldDisableThreading(): boolean {\n return !!(\n env.isTest() ||\n env.DISABLE_THREADING ||\n this.count === 0 ||\n env.isInThread()\n )\n }\n\n run(job: AutomationJob | QueryEvent) {\n const timeout = this.timeoutMs\n return new Promise((resolve, reject) => {\n function fire(worker: any) {\n worker.execute(job, (err: any, response: any) => {\n if (err && err.type === \"TimeoutError\") {\n reject(\n new Error(`Query response time exceeded ${timeout}ms timeout.`)\n )\n } else if (err) {\n reject(err)\n } else {\n resolve(response)\n }\n })\n }\n // if in test then don't use threading\n if (this.disableThreading) {\n import(typeToFile(this.type)).then((thread: any) => {\n fire(thread)\n })\n } else {\n fire(this.workers)\n }\n })\n }\n\n static stopThreads() {\n return new Promise<void>(resolve => {\n if (Thread.workerRefs.length === 0) {\n resolve()\n }\n let count = 0\n function complete() {\n count++\n if (count >= Thread.workerRefs.length) {\n resolve()\n }\n }\n for (let worker of Thread.workerRefs) {\n workerFarm.end(worker, complete)\n }\n Thread.workerRefs = []\n })\n }\n\n static async shutdown() {\n await Thread.stopThreads()\n console.log(\"Threads shutdown\")\n }\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"App Action\",\n event: \"app:trigger\",\n icon: \"Apps\",\n tagline: \"Automation fired from the frontend\",\n description: \"Trigger an automation from an action inside your app\",\n stepId: AutomationTriggerStepId.APP,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n fields: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.TRIGGER_SCHEMA,\n title: \"Fields\",\n },\n },\n required: [],\n },\n outputs: {\n properties: {\n fields: {\n type: AutomationIOType.OBJECT,\n description: \"Fields submitted from the app frontend\",\n customType: AutomationCustomIOType.TRIGGER_SCHEMA,\n },\n },\n required: [\"fields\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"Cron Trigger\",\n event: \"cron:trigger\",\n icon: \"Clock\",\n tagline: \"Cron Trigger (<b>{{inputs.cron}}</b>)\",\n description: \"Triggers automation on a cron schedule.\",\n stepId: AutomationTriggerStepId.CRON,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n cron: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.CRON,\n title: \"Expression\",\n },\n },\n required: [\"cron\"],\n },\n outputs: {\n properties: {\n timestamp: {\n type: AutomationIOType.NUMBER,\n description: \"Timestamp the cron was executed\",\n },\n },\n required: [\"timestamp\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"Row Deleted\",\n event: \"row:delete\",\n icon: \"TableRowRemoveCenter\",\n tagline: \"Row is deleted from {{inputs.enriched.table.name}}\",\n description: \"Fired when a row is deleted from your database\",\n stepId: AutomationTriggerStepId.ROW_DELETED,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n title: \"Table\",\n },\n },\n required: [\"tableId\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The row that was deleted\",\n },\n },\n required: [\"row\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"Row Created\",\n event: \"row:save\",\n icon: \"TableRowAddBottom\",\n tagline: \"Row is added to {{inputs.enriched.table.name}}\",\n description: \"Fired when a row is added to your database\",\n stepId: AutomationTriggerStepId.ROW_SAVED,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n title: \"Table\",\n },\n },\n required: [\"tableId\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The new row that was created\",\n },\n id: {\n type: AutomationIOType.STRING,\n description: \"Row ID - can be used for updating\",\n },\n revision: {\n type: AutomationIOType.STRING,\n description: \"Revision of row\",\n },\n },\n required: [\"row\", \"id\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"Row Updated\",\n event: \"row:update\",\n icon: \"Refresh\",\n tagline: \"Row is updated in {{inputs.enriched.table.name}}\",\n description: \"Fired when a row is updated in your database\",\n stepId: AutomationTriggerStepId.ROW_UPDATED,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n title: \"Table\",\n },\n },\n required: [\"tableId\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The row that was updated\",\n },\n id: {\n type: AutomationIOType.STRING,\n description: \"Row ID - can be used for updating\",\n },\n revision: {\n type: AutomationIOType.STRING,\n description: \"Revision of row\",\n },\n },\n required: [\"row\", \"id\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import {\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepType,\n AutomationTriggerSchema,\n AutomationTriggerStepId,\n} from \"@budibase/types\"\n\nexport const definition: AutomationTriggerSchema = {\n name: \"Webhook\",\n event: \"web:trigger\",\n icon: \"Send\",\n tagline: \"Webhook endpoint is hit\",\n description: \"Trigger an automation when a HTTP POST webhook is hit\",\n stepId: AutomationTriggerStepId.WEBHOOK,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n schemaUrl: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.WEBHOOK_URL,\n title: \"Schema URL\",\n },\n triggerUrl: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.WEBHOOK_URL,\n title: \"Trigger URL\",\n },\n },\n required: [\"schemaUrl\", \"triggerUrl\"],\n },\n outputs: {\n properties: {\n body: {\n type: AutomationIOType.OBJECT,\n description: \"Body of the request which hit the webhook\",\n },\n },\n required: [\"body\"],\n },\n },\n type: AutomationStepType.TRIGGER,\n}\n", "import * as app from \"./app\"\nimport * as cron from \"./cron\"\nimport * as rowDeleted from \"./rowDeleted\"\nimport * as rowSaved from \"./rowSaved\"\nimport * as rowUpdated from \"./rowUpdated\"\nimport * as webhook from \"./webhook\"\n\nexport const definitions = {\n ROW_SAVED: rowSaved.definition,\n ROW_UPDATED: rowUpdated.definition,\n ROW_DELETED: rowDeleted.definition,\n WEBHOOK: webhook.definition,\n APP: app.definition,\n CRON: cron.definition,\n}\n", "import { BullAdapter } from \"@bull-board/api/bullAdapter\"\nimport { KoaAdapter } from \"@bull-board/koa\"\nimport { queue } from \"@budibase/backend-core\"\nimport * as automation from \"../threads/automation\"\nimport { backups } from \"@budibase/pro\"\nimport { createBullBoard } from \"@bull-board/api\"\nimport BullQueue from \"bull\"\n\nexport const automationQueue: BullQueue.Queue = queue.createQueue(\n queue.JobQueue.AUTOMATION,\n { removeStalledCb: automation.removeStalled }\n)\n\nconst PATH_PREFIX = \"/bulladmin\"\n\nexport async function init() {\n // Set up queues for bull board admin\n const backupQueue = await backups.getBackupQueue()\n const queues = [automationQueue]\n if (backupQueue) {\n queues.push(backupQueue)\n }\n const adapters = []\n const serverAdapter: any = new KoaAdapter()\n for (let queue of queues) {\n adapters.push(new BullAdapter(queue))\n }\n createBullBoard({\n queues: adapters,\n serverAdapter,\n })\n serverAdapter.setBasePath(PATH_PREFIX)\n return serverAdapter.registerPlugin()\n}\n\nexport async function shutdown() {\n await queue.shutdown()\n}\n", "import { Thread, ThreadType } from \"../threads\"\nimport { definitions } from \"./triggerInfo\"\nimport { automationQueue } from \"./bullboard\"\nimport newid from \"../db/newid\"\nimport { updateEntityMetadata } from \"../utilities\"\nimport { MetadataTypes } from \"../constants\"\nimport { db as dbCore, context } from \"@budibase/backend-core\"\nimport { getAutomationMetadataParams } from \"../db/utils\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { quotas } from \"@budibase/pro\"\nimport { Automation, AutomationJob, WebhookActionType } from \"@budibase/types\"\nimport sdk from \"../sdk\"\n\nconst REBOOT_CRON = \"@reboot\"\nconst WH_STEP_ID = definitions.WEBHOOK.stepId\nconst CRON_STEP_ID = definitions.CRON.stepId\nconst Runner = new Thread(ThreadType.AUTOMATION)\n\nfunction loggingArgs(job: AutomationJob) {\n return [\n {\n _logKey: \"automation\",\n trigger: job.data.automation.definition.trigger.event,\n },\n {\n _logKey: \"bull\",\n jobId: job.id,\n },\n ]\n}\n\nexport async function processEvent(job: AutomationJob) {\n const appId = job.data.event.appId!\n const automationId = job.data.automation._id!\n const task = async () => {\n try {\n // need to actually await these so that an error can be captured properly\n console.log(\"automation running\", ...loggingArgs(job))\n\n const runFn = () => Runner.run(job)\n const result = await quotas.addAutomation(runFn, {\n automationId,\n })\n console.log(\"automation completed\", ...loggingArgs(job))\n return result\n } catch (err) {\n console.error(`automation was unable to run`, err, ...loggingArgs(job))\n return { err }\n }\n }\n\n return await context.doInAutomationContext({ appId, automationId, task })\n}\n\nexport async function updateTestHistory(\n appId: any,\n automation: any,\n history: any\n) {\n return updateEntityMetadata(\n MetadataTypes.AUTOMATION_TEST_HISTORY,\n automation._id,\n (metadata: any) => {\n if (metadata && Array.isArray(metadata.history)) {\n metadata.history.push(history)\n } else {\n metadata = {\n history: [history],\n }\n }\n return metadata\n }\n )\n}\n\nexport function removeDeprecated(definitions: any) {\n const base = cloneDeep(definitions)\n for (let key of Object.keys(base)) {\n if (base[key].deprecated) {\n delete base[key]\n }\n }\n return base\n}\n\n// end the repetition and the job itself\nexport async function disableAllCrons(appId: any) {\n const promises = []\n const jobs = await automationQueue.getRepeatableJobs()\n for (let job of jobs) {\n if (job.key.includes(`${appId}_cron`)) {\n promises.push(automationQueue.removeRepeatableByKey(job.key))\n if (job.id) {\n promises.push(automationQueue.removeJobs(job.id))\n }\n }\n }\n return Promise.all(promises)\n}\n\nexport async function disableCronById(jobId: number | string) {\n const repeatJobs = await automationQueue.getRepeatableJobs()\n for (let repeatJob of repeatJobs) {\n if (repeatJob.id === jobId) {\n await automationQueue.removeRepeatableByKey(repeatJob.key)\n }\n }\n console.log(`jobId=${jobId} disabled`)\n}\n\nexport async function clearMetadata() {\n const db = context.getProdAppDB()\n const automationMetadata = (\n await db.allDocs(\n getAutomationMetadataParams({\n include_docs: true,\n })\n )\n ).rows.map((row: any) => row.doc)\n for (let metadata of automationMetadata) {\n metadata._deleted = true\n }\n await db.bulkDocs(automationMetadata)\n}\n\nexport function isCronTrigger(auto: Automation) {\n return (\n auto &&\n auto.definition.trigger &&\n auto.definition.trigger.stepId === CRON_STEP_ID\n )\n}\n\nexport function isRebootTrigger(auto: Automation) {\n const trigger = auto ? auto.definition.trigger : null\n return isCronTrigger(auto) && trigger?.inputs.cron === REBOOT_CRON\n}\n\n/**\n * This function handles checking of any cron jobs that need to be enabled/updated.\n * @param {string} appId The ID of the app in which we are checking for webhooks\n * @param {object|undefined} automation The automation object to be updated.\n */\nexport async function enableCronTrigger(appId: any, automation: Automation) {\n const trigger = automation ? automation.definition.trigger : null\n\n // need to create cron job\n if (\n isCronTrigger(automation) &&\n !isRebootTrigger(automation) &&\n trigger?.inputs.cron\n ) {\n // make a job id rather than letting Bull decide, makes it easier to handle on way out\n const jobId = `${appId}_cron_${newid()}`\n const job: any = await automationQueue.add(\n {\n automation,\n event: { appId, timestamp: Date.now() },\n },\n { repeat: { cron: trigger.inputs.cron }, jobId }\n )\n // Assign cron job ID from bull so we can remove it later if the cron trigger is removed\n trigger.cronJobId = job.id\n // can't use getAppDB here as this is likely to be called from dev app,\n // but this call could be for dev app or prod app, need to just use what\n // was passed in\n await dbCore.doWithDB(appId, async (db: any) => {\n const response = await db.put(automation)\n automation._id = response.id\n automation._rev = response.rev\n })\n }\n return automation\n}\n\n/**\n * This function handles checking if any webhooks need to be created or deleted for automations.\n * @param {string} appId The ID of the app in which we are checking for webhooks\n * @param {object|undefined} oldAuto The old automation object if updating/deleting\n * @param {object|undefined} newAuto The new automation object if creating/updating\n * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be\n * written to DB (this does not write to DB as it would be wasteful to repeat).\n */\nexport async function checkForWebhooks({ oldAuto, newAuto }: any) {\n const appId = context.getAppId()\n if (!appId) {\n throw new Error(\"Unable to check webhooks - no app ID in context.\")\n }\n const oldTrigger = oldAuto ? oldAuto.definition.trigger : null\n const newTrigger = newAuto ? newAuto.definition.trigger : null\n const triggerChanged =\n oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id\n function isWebhookTrigger(auto: any) {\n return (\n auto &&\n auto.definition.trigger &&\n auto.definition.trigger.stepId === WH_STEP_ID\n )\n }\n // need to delete webhook\n if (\n isWebhookTrigger(oldAuto) &&\n (!isWebhookTrigger(newAuto) || triggerChanged) &&\n oldTrigger.webhookId\n ) {\n try {\n let db = context.getAppDB()\n // need to get the webhook to get the rev\n const webhook = await db.get(oldTrigger.webhookId)\n // might be updating - reset the inputs to remove the URLs\n if (newTrigger) {\n delete newTrigger.webhookId\n newTrigger.inputs = {}\n }\n await sdk.automations.webhook.destroy(webhook._id, webhook._rev)\n } catch (err) {\n // don't worry about not being able to delete, if it doesn't exist all good\n }\n }\n // need to create webhook\n if (\n (!isWebhookTrigger(oldAuto) || triggerChanged) &&\n isWebhookTrigger(newAuto)\n ) {\n const webhook = await sdk.automations.webhook.save(\n sdk.automations.webhook.newDoc(\n \"Automation webhook\",\n WebhookActionType.AUTOMATION,\n newAuto._id\n )\n )\n const id = webhook._id\n newTrigger.webhookId = id\n // the app ID has to be development for this endpoint\n // it can only be used when building the app\n // but the trigger endpoint will always be used in production\n const prodAppId = dbCore.getProdAppID(appId)\n newTrigger.inputs = {\n schemaUrl: `api/webhooks/schema/${appId}/${id}`,\n triggerUrl: `api/webhooks/trigger/${prodAppId}/${id}`,\n }\n }\n return newAuto\n}\n\n/**\n * When removing an app/unpublishing it need to make sure automations are cleaned up (cron).\n * @param appId {string} the app that is being removed.\n * @return {Promise<void>} clean is complete if this succeeds.\n */\nexport async function cleanupAutomations(appId: any) {\n await disableAllCrons(appId)\n}\n\n/**\n * Checks if the supplied automation is of a recurring type.\n * @param automation The automation to check.\n * @return {boolean} if it is recurring (cron).\n */\nexport function isRecurring(automation: Automation) {\n return automation.definition.trigger.stepId === definitions.CRON.stepId\n}\n\nexport function isErrorInOutput(output: {\n steps: { outputs?: { success: boolean } }[]\n}) {\n let first = true,\n error = false\n for (let step of output.steps) {\n // skip the trigger, its always successful if automation ran\n if (first) {\n first = false\n continue\n }\n if (!step.outputs?.success) {\n error = true\n }\n }\n return error\n}\n", "import fetch from \"node-fetch\"\nimport env from \"../environment\"\nimport { checkSlashesInUrl } from \"./index\"\nimport {\n db as dbCore,\n constants,\n tenancy,\n logging,\n env as coreEnv,\n} from \"@budibase/backend-core\"\nimport { updateAppRole } from \"./global\"\nimport { BBContext, User } from \"@budibase/types\"\n\nexport function request(ctx?: BBContext, request?: any) {\n if (!request.headers) {\n request.headers = {}\n }\n if (!ctx) {\n request.headers[constants.Header.API_KEY] = coreEnv.INTERNAL_API_KEY\n if (tenancy.isTenantIdSet()) {\n request.headers[constants.Header.TENANT_ID] = tenancy.getTenantId()\n }\n }\n if (request.body && Object.keys(request.body).length > 0) {\n request.headers[\"Content-Type\"] = \"application/json\"\n request.body =\n typeof request.body === \"object\"\n ? JSON.stringify(request.body)\n : request.body\n } else {\n delete request.body\n }\n if (ctx && ctx.headers) {\n request.headers = ctx.headers\n }\n\n // add x-budibase-correlation-id header\n logging.correlation.setHeader(request.headers)\n\n return request\n}\n\nasync function checkResponse(\n response: any,\n errorMsg: string,\n { ctx }: { ctx?: BBContext } = {}\n) {\n if (response.status !== 200) {\n let error\n try {\n error = await response.json()\n } catch (err) {\n error = await response.text()\n }\n const msg = `Unable to ${errorMsg} - ${\n error.message ? error.message : error\n }`\n if (ctx) {\n ctx.throw(400, msg)\n } else {\n throw msg\n }\n }\n return response.json()\n}\n\n// have to pass in the tenant ID as this could be coming from an automation\nexport async function sendSmtpEmail(\n to: string,\n from: string,\n subject: string,\n contents: string,\n cc: string,\n bcc: string,\n automation: boolean\n) {\n // tenant ID will be set in header\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`),\n request(undefined, {\n method: \"POST\",\n body: {\n email: to,\n from,\n contents,\n subject,\n cc,\n bcc,\n purpose: \"custom\",\n automation,\n },\n })\n )\n return checkResponse(response, \"send email\")\n}\n\nexport async function getGlobalSelf(ctx: BBContext, appId?: string) {\n const endpoint = `/api/global/self`\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + endpoint),\n // we don't want to use API key when getting self\n request(ctx, { method: \"GET\" })\n )\n let json = await checkResponse(response, \"get self globally\", { ctx })\n if (appId) {\n json = updateAppRole(json)\n }\n return json\n}\n\nexport async function removeAppFromUserRoles(ctx: BBContext, appId: string) {\n const prodAppId = dbCore.getProdAppID(appId)\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + `/api/global/roles/${prodAppId}`),\n request(ctx, {\n method: \"DELETE\",\n })\n )\n return checkResponse(response, \"remove app role\")\n}\n\nexport async function allGlobalUsers(ctx: BBContext) {\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + \"/api/global/users\"),\n // we don't want to use API key when getting self\n request(ctx, { method: \"GET\" })\n )\n return checkResponse(response, \"get users\", { ctx })\n}\n\nexport async function saveGlobalUser(ctx: BBContext) {\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + \"/api/global/users\"),\n // we don't want to use API key when getting self\n request(ctx, { method: \"POST\", body: ctx.request.body })\n )\n return checkResponse(response, \"save user\", { ctx })\n}\n\nexport async function deleteGlobalUser(ctx: BBContext) {\n const response = await fetch(\n checkSlashesInUrl(\n env.WORKER_URL + `/api/global/users/${ctx.params.userId}`\n ),\n // we don't want to use API key when getting self\n request(ctx, { method: \"DELETE\" })\n )\n return checkResponse(response, \"delete user\", { ctx })\n}\n\nexport async function readGlobalUser(ctx: BBContext): Promise<User> {\n const response = await fetch(\n checkSlashesInUrl(\n env.WORKER_URL + `/api/global/users/${ctx.params.userId}`\n ),\n // we don't want to use API key when getting self\n request(ctx, { method: \"GET\" })\n )\n return checkResponse(response, \"get user\", { ctx })\n}\n\nexport async function createAdminUser(\n email: string,\n password: string,\n tenantId: string\n) {\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + \"/api/global/users/init\"),\n request(undefined, { method: \"POST\", body: { email, password, tenantId } })\n )\n return checkResponse(response, \"create admin user\")\n}\n\nexport async function getChecklist() {\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + \"/api/global/configs/checklist\"),\n request(undefined, { method: \"GET\" })\n )\n return checkResponse(response, \"get checklist\")\n}\n\nexport async function generateApiKey(userId: string) {\n const response = await fetch(\n checkSlashesInUrl(env.WORKER_URL + \"/api/global/self/api_key\"),\n request(undefined, { method: \"POST\", body: { userId } })\n )\n return checkResponse(response, \"generate API key\")\n}\n", "import { sendSmtpEmail } from \"../../utilities/workerRequests\"\nimport * as automationUtils from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n description: \"Send an email using SMTP\",\n tagline: \"Send SMTP email to {{inputs.to}}\",\n icon: \"Email\",\n name: \"Send Email (SMTP)\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.SEND_EMAIL_SMTP,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n to: {\n type: AutomationIOType.STRING,\n title: \"Send To\",\n },\n from: {\n type: AutomationIOType.STRING,\n title: \"Send From\",\n },\n cc: {\n type: AutomationIOType.STRING,\n title: \"CC\",\n },\n bcc: {\n type: AutomationIOType.STRING,\n title: \"BCC\",\n },\n subject: {\n type: AutomationIOType.STRING,\n title: \"Email Subject\",\n },\n contents: {\n type: AutomationIOType.STRING,\n title: \"HTML Contents\",\n },\n },\n required: [\"to\", \"from\", \"subject\", \"contents\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the email was sent\",\n },\n response: {\n type: AutomationIOType.OBJECT,\n description: \"A response from the email client, this may be an error\",\n },\n },\n required: [\"success\"],\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n let { to, from, subject, contents, cc, bcc } = inputs\n if (!contents) {\n contents = \"<h1>No content</h1>\"\n }\n to = to || undefined\n try {\n let response = await sendSmtpEmail(\n to,\n from,\n subject,\n contents,\n cc,\n bcc,\n true\n )\n return {\n success: true,\n response,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import { quotas } from \"@budibase/pro\"\nimport * as internal from \"./internal\"\nimport * as external from \"./external\"\nimport { isExternalTable } from \"../../../integrations/utils\"\nimport { Ctx } from \"@budibase/types\"\nimport * as utils from \"./utils\"\n\nfunction pickApi(tableId: any) {\n if (isExternalTable(tableId)) {\n return external\n }\n return internal\n}\n\nfunction getTableId(ctx: any) {\n if (ctx.request.body && ctx.request.body.tableId) {\n return ctx.request.body.tableId\n }\n if (ctx.params && ctx.params.tableId) {\n return ctx.params.tableId\n }\n if (ctx.params && ctx.params.viewName) {\n return ctx.params.viewName\n }\n}\n\nexport async function patch(ctx: any): Promise<any> {\n const appId = ctx.appId\n const tableId = getTableId(ctx)\n const body = ctx.request.body\n // if it doesn't have an _id then its save\n if (body && !body._id) {\n return save(ctx)\n }\n try {\n const { row, table } = await quotas.addQuery(\n () => pickApi(tableId).patch(ctx),\n {\n datasourceId: tableId,\n }\n )\n if (!row) {\n ctx.throw(404, \"Row not found\")\n }\n ctx.status = 200\n ctx.eventEmitter &&\n ctx.eventEmitter.emitRow(`row:update`, appId, row, table)\n ctx.message = `${table.name} updated successfully.`\n ctx.body = row\n } catch (err) {\n ctx.throw(400, err)\n }\n}\n\nexport const save = async (ctx: any) => {\n const appId = ctx.appId\n const tableId = getTableId(ctx)\n const body = ctx.request.body\n // if it has an ID already then its a patch\n if (body && body._id) {\n return patch(ctx)\n }\n const { row, table } = await quotas.addRow(() =>\n quotas.addQuery(() => pickApi(tableId).save(ctx), {\n datasourceId: tableId,\n })\n )\n ctx.status = 200\n ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)\n ctx.message = `${table.name} saved successfully`\n ctx.body = row\n}\nexport async function fetchView(ctx: any) {\n const tableId = getTableId(ctx)\n ctx.body = await quotas.addQuery(() => pickApi(tableId).fetchView(ctx), {\n datasourceId: tableId,\n })\n}\n\nexport async function fetch(ctx: any) {\n const tableId = getTableId(ctx)\n ctx.body = await quotas.addQuery(() => pickApi(tableId).fetch(ctx), {\n datasourceId: tableId,\n })\n}\n\nexport async function find(ctx: any) {\n const tableId = getTableId(ctx)\n ctx.body = await quotas.addQuery(() => pickApi(tableId).find(ctx), {\n datasourceId: tableId,\n })\n}\n\nexport async function destroy(ctx: any) {\n const appId = ctx.appId\n const inputs = ctx.request.body\n const tableId = getTableId(ctx)\n let response, row\n if (inputs.rows) {\n let { rows } = await quotas.addQuery(\n () => pickApi(tableId).bulkDestroy(ctx),\n {\n datasourceId: tableId,\n }\n )\n await quotas.removeRows(rows.length)\n response = rows\n for (let row of rows) {\n ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)\n }\n } else {\n let resp = await quotas.addQuery(() => pickApi(tableId).destroy(ctx), {\n datasourceId: tableId,\n })\n await quotas.removeRow()\n response = resp.response\n row = resp.row\n ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)\n }\n ctx.status = 200\n // for automations include the row that was deleted\n ctx.row = row || {}\n ctx.body = response\n}\n\nexport async function search(ctx: any) {\n const tableId = getTableId(ctx)\n ctx.status = 200\n ctx.body = await quotas.addQuery(() => pickApi(tableId).search(ctx), {\n datasourceId: tableId,\n })\n}\n\nexport async function validate(ctx: Ctx) {\n const tableId = getTableId(ctx)\n // external tables are hard to validate currently\n if (isExternalTable(tableId)) {\n ctx.body = { valid: true }\n } else {\n ctx.body = await utils.validate({\n row: ctx.request.body,\n tableId,\n })\n }\n}\n\nexport async function fetchEnrichedRow(ctx: any) {\n const tableId = getTableId(ctx)\n ctx.body = await quotas.addQuery(\n () => pickApi(tableId).fetchEnrichedRow(ctx),\n {\n datasourceId: tableId,\n }\n )\n}\n\nexport const exportRows = async (ctx: any) => {\n const tableId = getTableId(ctx)\n ctx.body = await quotas.addQuery(() => pickApi(tableId).exportRows(ctx), {\n datasourceId: tableId,\n })\n}\n", "import * as linkRows from \"../../../db/linkedRows\"\nimport {\n generateRowID,\n getRowParams,\n getTableIDFromRowID,\n DocumentType,\n InternalTables,\n} from \"../../../db/utils\"\nimport * as userController from \"../user\"\nimport {\n inputProcessing,\n outputProcessing,\n cleanupAttachments,\n} from \"../../../utilities/rowProcessor\"\nimport { FieldTypes } from \"../../../constants\"\nimport * as utils from \"./utils\"\nimport { fullSearch, paginatedSearch } from \"./internalSearch\"\nimport { getGlobalUsersFromMetadata } from \"../../../utilities/global\"\nimport * as inMemoryViews from \"../../../db/inMemoryView\"\nimport env from \"../../../environment\"\nimport {\n migrateToInMemoryView,\n migrateToDesignView,\n getFromDesignDoc,\n getFromMemoryDoc,\n} from \"../view/utils\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { context, db as dbCore } from \"@budibase/backend-core\"\nimport { finaliseRow, updateRelatedFormula } from \"./staticFormula\"\nimport { csv, json, jsonWithSchema, Format } from \"../view/exporters\"\nimport { apiFileReturn } from \"../../../utilities/fileSystem\"\nimport {\n UserCtx,\n Database,\n LinkDocumentValue,\n Row,\n Table,\n} from \"@budibase/types\"\n\nimport { cleanExportRows } from \"./utils\"\n\nconst CALCULATION_TYPES = {\n SUM: \"sum\",\n COUNT: \"count\",\n STATS: \"stats\",\n}\n\nasync function getView(db: Database, viewName: string) {\n let mainGetter = env.SELF_HOSTED ? getFromDesignDoc : getFromMemoryDoc\n let secondaryGetter = env.SELF_HOSTED ? getFromMemoryDoc : getFromDesignDoc\n let migration = env.SELF_HOSTED ? migrateToDesignView : migrateToInMemoryView\n let viewInfo,\n migrate = false\n try {\n viewInfo = await mainGetter(db, viewName)\n } catch (err: any) {\n // check if it can be retrieved from design doc (needs migrated)\n if (err.status !== 404) {\n viewInfo = null\n } else {\n viewInfo = await secondaryGetter(db, viewName)\n migrate = !!viewInfo\n }\n }\n if (migrate) {\n await migration(db, viewName)\n }\n if (!viewInfo) {\n throw \"View does not exist.\"\n }\n return viewInfo\n}\n\nasync function getRawTableData(ctx: UserCtx, db: Database, tableId: string) {\n let rows\n if (tableId === InternalTables.USER_METADATA) {\n await userController.fetchMetadata(ctx)\n rows = ctx.body\n } else {\n const response = await db.allDocs(\n getRowParams(tableId, null, {\n include_docs: true,\n })\n )\n rows = response.rows.map(row => row.doc)\n }\n return rows as Row[]\n}\n\nexport async function patch(ctx: UserCtx) {\n const db = context.getAppDB()\n const inputs = ctx.request.body\n const tableId = inputs.tableId\n const isUserTable = tableId === InternalTables.USER_METADATA\n let oldRow\n try {\n let dbTable = await db.get(tableId)\n oldRow = await outputProcessing(\n dbTable,\n await utils.findRow(ctx, tableId, inputs._id)\n )\n } catch (err) {\n if (isUserTable) {\n // don't include the rev, it'll be the global rev\n // this time\n oldRow = {\n _id: inputs._id,\n }\n } else {\n throw \"Row does not exist\"\n }\n }\n let dbTable = await db.get(tableId)\n // need to build up full patch fields before coerce\n let combinedRow: any = cloneDeep(oldRow)\n for (let key of Object.keys(inputs)) {\n if (!dbTable.schema[key]) continue\n combinedRow[key] = inputs[key]\n }\n\n // need to copy the table so it can be differenced on way out\n const tableClone = cloneDeep(dbTable)\n\n // this returns the table and row incase they have been updated\n let { table, row } = inputProcessing(ctx.user, tableClone, combinedRow)\n const validateResult = await utils.validate({\n row,\n table,\n })\n\n if (!validateResult.valid) {\n ctx.throw(400, { validation: validateResult.errors })\n }\n\n // returned row is cleaned and prepared for writing to DB\n row = (await linkRows.updateLinks({\n eventType: linkRows.EventType.ROW_UPDATE,\n row,\n tableId: row.tableId,\n table,\n })) as Row\n // check if any attachments removed\n await cleanupAttachments(table, { oldRow, row })\n\n if (isUserTable) {\n // the row has been updated, need to put it into the ctx\n ctx.request.body = row\n await userController.updateMetadata(ctx)\n return { row: ctx.body, table }\n }\n\n return finaliseRow(table, row, {\n oldTable: dbTable,\n updateFormula: true,\n })\n}\n\nexport async function save(ctx: UserCtx) {\n const db = context.getAppDB()\n let inputs = ctx.request.body\n inputs.tableId = ctx.params.tableId\n\n if (!inputs._rev && !inputs._id) {\n inputs._id = generateRowID(inputs.tableId)\n }\n\n // this returns the table and row incase they have been updated\n const dbTable = await db.get(inputs.tableId)\n\n // need to copy the table so it can be differenced on way out\n const tableClone = cloneDeep(dbTable)\n\n let { table, row } = inputProcessing(ctx.user, tableClone, inputs)\n\n const validateResult = await utils.validate({\n row,\n table,\n })\n\n if (!validateResult.valid) {\n throw { validation: validateResult.errors }\n }\n\n // make sure link rows are up to date\n row = (await linkRows.updateLinks({\n eventType: linkRows.EventType.ROW_SAVE,\n row,\n tableId: row.tableId,\n table,\n })) as Row\n\n return finaliseRow(table, row, {\n oldTable: dbTable,\n updateFormula: true,\n })\n}\n\nexport async function fetchView(ctx: UserCtx) {\n const viewName = decodeURIComponent(ctx.params.viewName)\n\n // if this is a table view being looked for just transfer to that\n if (viewName.startsWith(DocumentType.TABLE)) {\n ctx.params.tableId = viewName\n return fetch(ctx)\n }\n\n const db = context.getAppDB()\n const { calculation, group, field } = ctx.query\n const viewInfo = await getView(db, viewName)\n let response\n if (env.SELF_HOSTED) {\n response = await db.query(`database/${viewName}`, {\n include_docs: !calculation,\n group: !!group,\n })\n } else {\n const tableId = viewInfo.meta.tableId\n const data = await getRawTableData(ctx, db, tableId)\n response = await inMemoryViews.runView(\n viewInfo,\n calculation as string,\n !!group,\n data\n )\n }\n\n let rows\n if (!calculation) {\n response.rows = response.rows.map(row => row.doc)\n let table\n try {\n table = await db.get(viewInfo.meta.tableId)\n } catch (err) {\n /* istanbul ignore next */\n table = {\n schema: {},\n }\n }\n rows = await outputProcessing(table, response.rows)\n }\n\n if (calculation === CALCULATION_TYPES.STATS) {\n response.rows = response.rows.map(row => ({\n group: row.key,\n field,\n ...row.value,\n avg: row.value.sum / row.value.count,\n }))\n rows = response.rows\n }\n\n if (\n calculation === CALCULATION_TYPES.COUNT ||\n calculation === CALCULATION_TYPES.SUM\n ) {\n rows = response.rows.map(row => ({\n group: row.key,\n field,\n value: row.value,\n }))\n }\n return rows\n}\n\nexport async function fetch(ctx: UserCtx) {\n const db = context.getAppDB()\n\n const tableId = ctx.params.tableId\n let table = await db.get(tableId)\n let rows = await getRawTableData(ctx, db, tableId)\n return outputProcessing(table, rows)\n}\n\nexport async function find(ctx: UserCtx) {\n const db = dbCore.getDB(ctx.appId)\n const table = await db.get(ctx.params.tableId)\n let row = await utils.findRow(ctx, ctx.params.tableId, ctx.params.rowId)\n row = await outputProcessing(table, row)\n return row\n}\n\nexport async function destroy(ctx: UserCtx) {\n const db = context.getAppDB()\n const { _id } = ctx.request.body\n let row = await db.get(_id)\n let _rev = ctx.request.body._rev || row._rev\n\n if (row.tableId !== ctx.params.tableId) {\n throw \"Supplied tableId doesn't match the row's tableId\"\n }\n const table = await db.get(row.tableId)\n // update the row to include full relationships before deleting them\n row = await outputProcessing(table, row, { squash: false })\n // now remove the relationships\n await linkRows.updateLinks({\n eventType: linkRows.EventType.ROW_DELETE,\n row,\n tableId: row.tableId,\n })\n // remove any attachments that were on the row from object storage\n await cleanupAttachments(table, { row })\n // remove any static formula\n await updateRelatedFormula(table, row)\n\n let response\n if (ctx.params.tableId === InternalTables.USER_METADATA) {\n ctx.params = {\n id: _id,\n }\n await userController.destroyMetadata(ctx)\n response = ctx.body\n } else {\n response = await db.remove(_id, _rev)\n }\n return { response, row }\n}\n\nexport async function bulkDestroy(ctx: UserCtx) {\n const db = context.getAppDB()\n const tableId = ctx.params.tableId\n const table = await db.get(tableId)\n let { rows } = ctx.request.body\n\n // before carrying out any updates, make sure the rows are ready to be returned\n // they need to be the full rows (including previous relationships) for automations\n const processedRows = (await outputProcessing(table, rows, {\n squash: false,\n })) as Row[]\n\n // remove the relationships first\n let updates: Promise<any>[] = processedRows.map(row =>\n linkRows.updateLinks({\n eventType: linkRows.EventType.ROW_DELETE,\n row,\n tableId: row.tableId,\n })\n )\n if (tableId === InternalTables.USER_METADATA) {\n updates = updates.concat(\n processedRows.map(row => {\n ctx.params = {\n id: row._id,\n }\n return userController.destroyMetadata(ctx)\n })\n )\n } else {\n await db.bulkDocs(processedRows.map(row => ({ ...row, _deleted: true })))\n }\n // remove any attachments that were on the rows from object storage\n await cleanupAttachments(table, { rows: processedRows })\n await updateRelatedFormula(table, processedRows)\n await Promise.all(updates)\n return { response: { ok: true }, rows: processedRows }\n}\n\nexport async function search(ctx: UserCtx) {\n // Fetch the whole table when running in cypress, as search doesn't work\n if (!env.COUCH_DB_URL && env.isCypress()) {\n return { rows: await fetch(ctx) }\n }\n\n const { tableId } = ctx.params\n const db = context.getAppDB()\n const { paginate, query, ...params } = ctx.request.body\n params.version = ctx.version\n params.tableId = tableId\n\n let table\n if (params.sort && !params.sortType) {\n table = await db.get(tableId)\n const schema = table.schema\n const sortField = schema[params.sort]\n params.sortType = sortField.type == \"number\" ? \"number\" : \"string\"\n }\n\n let response\n if (paginate) {\n response = await paginatedSearch(query, params)\n } else {\n response = await fullSearch(query, params)\n }\n\n // Enrich search results with relationships\n if (response.rows && response.rows.length) {\n // enrich with global users if from users table\n if (tableId === InternalTables.USER_METADATA) {\n response.rows = await getGlobalUsersFromMetadata(response.rows)\n }\n table = table || (await db.get(tableId))\n response.rows = await outputProcessing(table, response.rows)\n }\n\n return response\n}\n\nexport async function exportRows(ctx: UserCtx) {\n const db = context.getAppDB()\n const table = await db.get(ctx.params.tableId)\n const rowIds = ctx.request.body.rows\n let format = ctx.query.format\n if (typeof format !== \"string\") {\n ctx.throw(400, \"Format parameter is not valid\")\n }\n const { columns, query } = ctx.request.body\n\n let result\n if (rowIds) {\n let response = (\n await db.allDocs({\n include_docs: true,\n keys: rowIds,\n })\n ).rows.map(row => row.doc)\n\n result = await outputProcessing(table, response)\n } else if (query) {\n let searchResponse = await search(ctx)\n result = searchResponse.rows\n }\n\n let rows: Row[] = []\n let schema = table.schema\n\n // Filter data to only specified columns if required\n if (columns && columns.length) {\n for (let i = 0; i < result.length; i++) {\n rows[i] = {}\n for (let column of columns) {\n rows[i][column] = result[i][column]\n }\n }\n } else {\n rows = result\n }\n\n let exportRows = cleanExportRows(rows, schema, format, columns)\n if (format === Format.CSV) {\n ctx.attachment(\"export.csv\")\n return apiFileReturn(csv(Object.keys(rows[0]), exportRows))\n } else if (format === Format.JSON) {\n ctx.attachment(\"export.json\")\n return apiFileReturn(json(exportRows))\n } else if (format === Format.JSON_WITH_SCHEMA) {\n ctx.attachment(\"export.json\")\n return apiFileReturn(jsonWithSchema(schema, exportRows))\n } else {\n throw \"Format not recognised\"\n }\n}\n\nexport async function fetchEnrichedRow(ctx: UserCtx) {\n const db = context.getAppDB()\n const tableId = ctx.params.tableId\n const rowId = ctx.params.rowId\n // need table to work out where links go in row\n let [table, row] = await Promise.all([\n db.get(tableId),\n utils.findRow(ctx, tableId, rowId),\n ])\n // get the link docs\n const linkVals = (await linkRows.getLinkDocuments({\n tableId,\n rowId,\n })) as LinkDocumentValue[]\n // look up the actual rows based on the ids\n let response = (\n await db.allDocs({\n include_docs: true,\n keys: linkVals.map(linkVal => linkVal.id),\n })\n ).rows.map(row => row.doc)\n // group responses by table\n let groups: any = {},\n tables: Record<string, Table> = {}\n for (let row of response) {\n if (!row.tableId) {\n row.tableId = getTableIDFromRowID(row._id)\n }\n const linkedTableId = row.tableId\n if (groups[linkedTableId] == null) {\n groups[linkedTableId] = [row]\n tables[linkedTableId] = await db.get(linkedTableId)\n } else {\n groups[linkedTableId].push(row)\n }\n }\n let linkedRows: Row[] = []\n for (let [tableId, rows] of Object.entries(groups)) {\n // need to include the IDs in these rows for any links they may have\n linkedRows = linkedRows.concat(\n await outputProcessing(tables[tableId], rows as Row[])\n )\n }\n\n // insert the link rows in the correct place throughout the main row\n for (let fieldName of Object.keys(table.schema)) {\n let field = table.schema[fieldName]\n if (field.type === FieldTypes.LINK) {\n // find the links that pertain to this field, get their indexes\n const linkIndexes = linkVals\n .filter(link => link.fieldName === fieldName)\n .map(link => linkVals.indexOf(link))\n // find the rows that the links state are linked to this field\n row[fieldName] = linkedRows.filter((linkRow, index) =>\n linkIndexes.includes(index)\n )\n }\n }\n return row\n}\n", "import { ViewName, getQueryIndex } from \"../utils\"\nimport { FieldTypes } from \"../../constants\"\nimport { createLinkView } from \"../views/staticViews\"\nimport { context, logging } from \"@budibase/backend-core\"\nimport {\n FieldSchema,\n LinkDocument,\n LinkDocumentValue,\n Table,\n} from \"@budibase/types\"\nexport { createLinkView } from \"../views/staticViews\"\n\n/**\n * Only needed so that boolean parameters are being used for includeDocs\n * @type {{EXCLUDE: boolean, INCLUDE: boolean}}\n */\nexport const IncludeDocs = {\n INCLUDE: true,\n EXCLUDE: false,\n}\n\n/**\n * Gets the linking documents, not the linked documents themselves.\n * @param {string} args.tableId The table which we are searching for linked rows against.\n * @param {string|null} args.fieldName The name of column/field which is being altered, only looking for\n * linking documents that are related to it. If this is not specified then the table level will be assumed.\n * @param {string|null} args.rowId The ID of the row which we want to find linking documents for -\n * if this is not specified then it will assume table or field level depending on whether the\n * field name has been specified.\n * @param {boolean|null} args.includeDocs whether to include docs in the response call, this is considerably slower so only\n * use this if actually interested in the docs themselves.\n * @returns {Promise<object[]>} This will return an array of the linking documents that were found\n * (if any).\n */\nexport async function getLinkDocuments(args: {\n tableId?: string\n rowId?: string\n includeDocs?: any\n}): Promise<LinkDocumentValue[] | LinkDocument[]> {\n const { tableId, rowId, includeDocs } = args\n const db = context.getAppDB()\n let params: any\n if (rowId != null) {\n params = { key: [tableId, rowId] }\n }\n // only table is known\n else {\n params = { startKey: [tableId], endKey: [tableId, {}] }\n }\n params.include_docs = !!includeDocs\n try {\n let linkRows = (await db.query(getQueryIndex(ViewName.LINK), params)).rows\n // filter to get unique entries\n const foundIds: string[] = []\n linkRows = linkRows.filter(link => {\n // make sure anything unique is the correct key\n if (\n (tableId && link.key[0] !== tableId) ||\n (rowId && link.key[1] !== rowId)\n ) {\n return false\n }\n const unique = foundIds.indexOf(link.id) === -1\n if (unique) {\n foundIds.push(link.id)\n }\n return unique\n })\n\n if (includeDocs) {\n return linkRows.map(row => row.doc) as LinkDocument[]\n } else {\n return linkRows.map(row => row.value) as LinkDocumentValue[]\n }\n } catch (err: any) {\n // check if the view doesn't exist, it should for all new instances\n if (err != null && err.name === \"not_found\") {\n await createLinkView()\n return getLinkDocuments(arguments[0])\n } else {\n /* istanbul ignore next */\n logging.logAlert(\"Failed to get link documents\", err)\n throw err\n }\n }\n}\n\nexport function getUniqueByProp(array: any[], prop: string) {\n return array.filter((obj, pos, arr) => {\n return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos\n })\n}\n\nexport function getLinkedTableIDs(table: Table) {\n return Object.values(table.schema)\n .filter((column: FieldSchema) => column.type === FieldTypes.LINK)\n .map(column => column.tableId)\n}\n\nexport async function getLinkedTable(id: string, tables: Table[]) {\n const db = context.getAppDB()\n let linkedTable = tables.find(table => table._id === id)\n if (linkedTable) {\n return linkedTable\n }\n linkedTable = await db.get(id)\n if (linkedTable) {\n tables.push(linkedTable)\n }\n return linkedTable\n}\n\nexport function getRelatedTableForField(table: Table, fieldName: string) {\n // look to see if its on the table, straight in the schema\n const field = table.schema[fieldName]\n if (field != null) {\n return field.tableId\n }\n for (let column of Object.values(table.schema)) {\n if (column.type === FieldTypes.LINK && column.fieldName === fieldName) {\n return column.tableId\n }\n }\n return null\n}\n", "import { context } from \"@budibase/backend-core\"\nimport { DocumentType, SEPARATOR, ViewName } from \"../utils\"\nimport { LinkDocument, Row, SearchIndex } from \"@budibase/types\"\nconst SCREEN_PREFIX = DocumentType.SCREEN + SEPARATOR\n\n/**************************************************\n * INFORMATION *\n * This file exists purely to keep views separate *\n * from the rest of the codebase, the reason *\n * being that they affect coverage and any *\n * functions written in this file cannot import *\n * or make use of any constants/variables that *\n * aren't defined as part of the map function *\n * itself. *\n **************************************************/\n\n/**\n * Creates the link view for the instance, this will overwrite the existing one, but this should only\n * be called if it is found that the view does not exist.\n * @returns {Promise<void>} The view now exists, please note that the next view of this query will actually build it,\n * so it may be slow.\n */\nexport async function createLinkView() {\n const db = context.getAppDB()\n const designDoc = await db.get(\"_design/database\")\n const view = {\n map: function (doc: LinkDocument) {\n // everything in this must remain constant as its going to Pouch, no external variables\n if (doc.type === \"link\") {\n let doc1 = doc.doc1\n let doc2 = doc.doc2\n // eslint-disable-next-line no-undef\n // @ts-ignore\n emit([doc1.tableId, doc1.rowId], {\n id: doc2.rowId,\n thisId: doc1.rowId,\n fieldName: doc1.fieldName,\n })\n // if linking to same table can't emit twice\n if (doc1.tableId !== doc2.tableId) {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n emit([doc2.tableId, doc2.rowId], {\n id: doc1.rowId,\n thisId: doc2.rowId,\n fieldName: doc2.fieldName,\n })\n }\n }\n }.toString(),\n }\n designDoc.views = {\n ...designDoc.views,\n [ViewName.LINK]: view,\n }\n await db.put(designDoc)\n}\n\nexport async function createRoutingView() {\n const db = context.getAppDB()\n const designDoc = await db.get(\"_design/database\")\n const view = {\n // if using variables in a map function need to inject them before use\n map: `function(doc) {\n if (doc._id.startsWith(\"${SCREEN_PREFIX}\")) {\n emit(doc._id, {\n id: doc._id,\n routing: doc.routing,\n })\n }\n }`,\n }\n designDoc.views = {\n ...designDoc.views,\n [ViewName.ROUTING]: view,\n }\n await db.put(designDoc)\n}\n\nasync function searchIndex(indexName: string, fnString: string) {\n const db = context.getAppDB()\n const designDoc = await db.get(\"_design/database\")\n designDoc.indexes = {\n [indexName]: {\n index: fnString,\n analyzer: \"keyword\",\n },\n }\n await db.put(designDoc)\n}\n\nexport async function createAllSearchIndex() {\n await searchIndex(\n SearchIndex.ROWS,\n function (doc: Row) {\n function idx(input: Row, prev?: string) {\n for (let key of Object.keys(input)) {\n let idxKey = prev != null ? `${prev}.${key}` : key\n idxKey = idxKey.replace(/ /g, \"_\")\n if (Array.isArray(input[key])) {\n for (let val of input[key]) {\n if (typeof val !== \"object\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, val, { store: true })\n }\n }\n } else if (key === \"_id\" || key === \"_rev\" || input[key] == null) {\n continue\n }\n if (typeof input[key] === \"string\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key].toLowerCase(), { store: true })\n } else if (typeof input[key] !== \"object\") {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(idxKey, input[key], { store: true })\n } else {\n idx(input[key], idxKey)\n }\n }\n }\n if (doc._id!.startsWith(\"ro_\")) {\n // eslint-disable-next-line no-undef\n // @ts-ignore\n index(\"default\", doc._id)\n idx(doc)\n }\n }.toString()\n )\n}\n", "import { IncludeDocs, getLinkDocuments } from \"./linkUtils\"\nimport { InternalTables, getUserMetadataParams } from \"../utils\"\nimport Sentry from \"@sentry/node\"\nimport { FieldTypes } from \"../../constants\"\nimport { context } from \"@budibase/backend-core\"\nimport LinkDocument from \"./LinkDocument\"\nimport {\n Database,\n FieldSchema,\n LinkDocumentValue,\n RelationshipTypes,\n Row,\n Table,\n} from \"@budibase/types\"\n\ntype LinkControllerOpts = {\n tableId?: string\n row?: Row\n table?: Table\n oldTable?: Table\n}\n\nclass LinkController {\n _db: Database\n _tableId?: string\n _row?: Row\n _table?: Table\n _oldTable?: Table\n\n constructor({ tableId, row, table, oldTable }: LinkControllerOpts) {\n this._db = context.getAppDB()\n this._tableId = tableId\n this._row = row\n this._table = table\n this._oldTable = oldTable\n }\n\n /**\n * Retrieves the table, if it was not already found in the eventData.\n * @returns {Promise<object>} This will return a table based on the event data, either\n * if it was in the event already, or it uses the specified tableId to get it.\n */\n async table() {\n if (this._table == null) {\n this._table =\n this._table == null ? await this._db.get(this._tableId) : this._table\n }\n return this._table!\n }\n\n /**\n * Checks if the table this was constructed with has any linking columns currently.\n * If the table has not been retrieved this will retrieve it based on the eventData.\n * @params {object|null} table If a table that is not known to the link controller is to be tested.\n * @returns {Promise<boolean>} True if there are any linked fields, otherwise it will return\n * false.\n */\n async doesTableHaveLinkedFields(table?: Table) {\n if (table == null) {\n table = await this.table()\n }\n for (let fieldName of Object.keys(table.schema)) {\n const { type } = table.schema[fieldName]\n if (type === FieldTypes.LINK) {\n return true\n }\n }\n return false\n }\n\n /**\n * Utility function for main getLinkDocuments function - refer to it for functionality.\n */\n getRowLinkDocs(rowId: string) {\n return getLinkDocuments({\n tableId: this._tableId,\n rowId,\n includeDocs: IncludeDocs.INCLUDE,\n })\n }\n\n /**\n * Utility function for main getLinkDocuments function - refer to it for functionality.\n */\n async getTableLinkDocs() {\n return (await getLinkDocuments({\n tableId: this._tableId,\n includeDocs: IncludeDocs.INCLUDE,\n })) as LinkDocument[]\n }\n\n /**\n * Makes sure the passed in table schema contains valid relationship structures.\n */\n validateTable(table: Table) {\n const usedAlready = []\n for (let schema of Object.values(table.schema)) {\n if (schema.type !== FieldTypes.LINK) {\n continue\n }\n const unique = schema.tableId! + schema?.fieldName\n if (usedAlready.indexOf(unique) !== -1) {\n throw new Error(\n \"Cannot re-use the linked column name for a linked table.\"\n )\n }\n usedAlready.push(unique)\n }\n }\n\n /**\n * Returns whether the two link schemas are equal (in the important parts, not a pure equality check)\n */\n areLinkSchemasEqual(linkSchema1: FieldSchema, linkSchema2: FieldSchema) {\n const compareFields = [\n \"name\",\n \"type\",\n \"tableId\",\n \"fieldName\",\n \"autocolumn\",\n \"relationshipType\",\n ]\n for (let field of compareFields) {\n // @ts-ignore\n if (linkSchema1[field] !== linkSchema2[field]) {\n return false\n }\n }\n return true\n }\n\n /**\n * Given the link field of this table, and the link field of the linked table, this makes sure\n * the state of relationship type is accurate on both.\n */\n handleRelationshipType(linkerField: FieldSchema, linkedField: FieldSchema) {\n if (\n !linkerField.relationshipType ||\n linkerField.relationshipType === RelationshipTypes.MANY_TO_MANY\n ) {\n linkedField.relationshipType = RelationshipTypes.MANY_TO_MANY\n // make sure by default all are many to many (if not specified)\n linkerField.relationshipType = RelationshipTypes.MANY_TO_MANY\n } else if (linkerField.relationshipType === RelationshipTypes.MANY_TO_ONE) {\n // Ensure that the other side of the relationship is locked to one record\n linkedField.relationshipType = RelationshipTypes.ONE_TO_MANY\n } else if (linkerField.relationshipType === RelationshipTypes.ONE_TO_MANY) {\n linkedField.relationshipType = RelationshipTypes.MANY_TO_ONE\n }\n return { linkerField, linkedField }\n }\n\n // all operations here will assume that the table\n // this operation is related to has linked rows\n /**\n * When a row is saved this will carry out the necessary operations to make sure\n * the link has been created/updated.\n * @returns {Promise<object>} returns the row that has been cleaned and prepared to be written to the DB - links\n * have also been created.\n */\n async rowSaved() {\n const table = await this.table()\n const row = this._row!\n const operations = []\n // get link docs to compare against\n const linkDocs = (await this.getRowLinkDocs(row._id!)) as LinkDocument[]\n for (let fieldName of Object.keys(table.schema)) {\n // get the links this row wants to make\n const rowField = row[fieldName]\n const field = table.schema[fieldName]\n if (field.type === FieldTypes.LINK && rowField != null) {\n // check which links actual pertain to the update in this row\n const thisFieldLinkDocs = linkDocs.filter(\n linkDoc =>\n linkDoc.doc1.fieldName === fieldName ||\n linkDoc.doc2.fieldName === fieldName\n )\n const linkDocIds = thisFieldLinkDocs.map(linkDoc => {\n return linkDoc.doc1.rowId === row._id\n ? linkDoc.doc2.rowId\n : linkDoc.doc1.rowId\n })\n\n // if 1:N, ensure that this ID is not already attached to another record\n const linkedTable = await this._db.get(field.tableId)\n const linkedSchema = linkedTable.schema[field.fieldName!]\n\n // We need to map the global users to metadata in each app for relationships\n if (field.tableId === InternalTables.USER_METADATA) {\n const users = await this._db.allDocs(getUserMetadataParams(null, {}))\n const metadataRequired = rowField.filter(\n (userId: string) => !users.rows.some(user => user.id === userId)\n )\n\n // ensure non-existing user metadata is created in the app DB\n await this._db.bulkDocs(\n metadataRequired.map((userId: string) => ({ _id: userId }))\n )\n }\n\n // iterate through the link IDs in the row field, see if any don't exist already\n for (let linkId of rowField) {\n if (\n linkedSchema?.relationshipType === RelationshipTypes.ONE_TO_MANY\n ) {\n let links = (\n (await getLinkDocuments({\n tableId: field.tableId,\n rowId: linkId,\n includeDocs: IncludeDocs.EXCLUDE,\n })) as LinkDocumentValue[]\n ).filter(\n link =>\n link.id !== row._id && link.fieldName === linkedSchema.name\n )\n\n // The 1 side of 1:N is already related to something else\n // You must remove the existing relationship\n if (links.length > 0) {\n throw new Error(\n `1:N Relationship Error: Record already linked to another.`\n )\n }\n }\n\n if (linkId && linkId !== \"\" && linkDocIds.indexOf(linkId) === -1) {\n // first check the doc we're linking to exists\n try {\n await this._db.get(linkId)\n } catch (err) {\n // skip links that don't exist\n continue\n }\n operations.push(\n new LinkDocument(\n table._id!,\n fieldName,\n row._id!,\n field.tableId!,\n field.fieldName!,\n linkId\n )\n )\n }\n }\n // find the docs that need to be deleted\n let toDeleteDocs = thisFieldLinkDocs\n .filter(doc => {\n let correctDoc =\n doc.doc1.fieldName === fieldName ? doc.doc2 : doc.doc1\n return rowField.indexOf(correctDoc.rowId) === -1\n })\n .map(doc => {\n return { ...doc, _deleted: true }\n })\n // now add the docs to be deleted to the bulk operation\n operations.push(...toDeleteDocs)\n // remove the field from this row, link doc will be added to row on way out\n delete row[fieldName]\n }\n }\n await this._db.bulkDocs(operations)\n return row\n }\n\n /**\n * When a row is deleted this will carry out the necessary operations to make sure\n * any links that existed have been removed.\n * @returns {Promise<object>} The operation has been completed and the link documents should now\n * be accurate. This also returns the row that was deleted.\n */\n async rowDeleted() {\n const row = this._row!\n // need to get the full link docs to be be able to delete it\n const linkDocs = await this.getRowLinkDocs(row._id!)\n if (linkDocs.length === 0) {\n return null\n }\n const toDelete = linkDocs.map(doc => {\n return {\n ...doc,\n _deleted: true,\n }\n })\n await this._db.bulkDocs(toDelete)\n return row\n }\n\n /**\n * Remove a field from a table as well as any linked rows that pertained to it.\n * @param {string} fieldName The field to be removed from the table.\n * @returns {Promise<void>} The table has now been updated.\n */\n async removeFieldFromTable(fieldName: string) {\n let oldTable = this._oldTable\n let field = oldTable?.schema[fieldName] as FieldSchema\n const linkDocs = await this.getTableLinkDocs()\n let toDelete = linkDocs.filter(linkDoc => {\n let correctFieldName =\n linkDoc.doc1.tableId === oldTable?._id\n ? linkDoc.doc1.fieldName\n : linkDoc.doc2.fieldName\n return correctFieldName === fieldName\n })\n await this._db.bulkDocs(\n toDelete.map(doc => {\n return {\n ...doc,\n _deleted: true,\n }\n })\n )\n // remove schema from other table\n let linkedTable = await this._db.get(field.tableId)\n if (field.fieldName) {\n delete linkedTable.schema[field.fieldName]\n }\n await this._db.put(linkedTable)\n }\n\n /**\n * When a table is saved this will carry out the necessary operations to make sure\n * any linked tables are notified and updated correctly.\n * @returns {Promise<object>} The operation has been completed and the link documents should now\n * be accurate. Also returns the table that was operated on.\n */\n async tableSaved() {\n const table = await this.table()\n // validate the table first\n this.validateTable(table)\n const schema = table.schema\n for (let fieldName of Object.keys(schema)) {\n const field = schema[fieldName]\n if (field.type === FieldTypes.LINK && field.fieldName) {\n // handle this in a separate try catch, want\n // the put to bubble up as an error, if can't update\n // table for some reason\n let linkedTable\n try {\n linkedTable = await this._db.get(field.tableId)\n } catch (err) {\n /* istanbul ignore next */\n continue\n }\n const fields = this.handleRelationshipType(field, {\n name: field.fieldName,\n type: FieldTypes.LINK,\n // these are the props of the table that initiated the link\n tableId: table._id,\n fieldName: fieldName,\n })\n\n // update table schema after checking relationship types\n schema[fieldName] = fields.linkerField\n const linkedField = fields.linkedField\n\n if (field.autocolumn) {\n linkedField.autocolumn = field.autocolumn\n linkedField.subtype = field.subtype\n }\n\n // check the linked table to make sure we aren't overwriting an existing column\n const existingSchema = linkedTable.schema[field.fieldName]\n if (\n existingSchema != null &&\n !this.areLinkSchemasEqual(existingSchema, linkedField)\n ) {\n throw new Error(\"Cannot overwrite existing column.\")\n }\n // create the link field in the other table\n linkedTable.schema[field.fieldName] = linkedField\n const response = await this._db.put(linkedTable)\n // special case for when linking back to self, make sure rev updated\n if (linkedTable._id === table._id) {\n table._rev = response.rev\n }\n }\n }\n return table\n }\n\n /**\n * Update a table, this means if a field is removed need to handle removing from other table and removing\n * any link docs that pertained to it.\n * @returns {Promise<Object>} The table which has been saved, same response as with the tableSaved function.\n */\n async tableUpdated() {\n const oldTable = this._oldTable\n // first start by checking if any link columns have been deleted\n const newTable = await this.table()\n for (let fieldName of Object.keys(oldTable?.schema || {})) {\n const field = oldTable?.schema[fieldName] as FieldSchema\n // this field has been removed from the table schema\n if (\n field.type === FieldTypes.LINK &&\n newTable.schema[fieldName] == null\n ) {\n await this.removeFieldFromTable(fieldName)\n }\n }\n // now handle as if its a new save\n return this.tableSaved()\n }\n\n /**\n * When a table is deleted this will carry out the necessary operations to make sure\n * any linked tables have the joining column correctly removed as well as removing any\n * now stale linking documents.\n * @returns {Promise<object>} The operation has been completed and the link documents should now\n * be accurate. Also returns the table that was operated on.\n */\n async tableDeleted() {\n const table = await this.table()\n const schema = table.schema\n for (let fieldName of Object.keys(schema)) {\n const field = schema[fieldName]\n try {\n if (field.type === FieldTypes.LINK && field.fieldName) {\n const linkedTable = await this._db.get(field.tableId)\n delete linkedTable.schema[field.fieldName]\n await this._db.put(linkedTable)\n }\n } catch (err) {\n /* istanbul ignore next */\n Sentry.captureException(err)\n }\n }\n // need to get the full link docs to delete them\n const linkDocs = await this.getTableLinkDocs()\n if (linkDocs.length === 0) {\n return null\n }\n // get link docs for this table and configure for deletion\n const toDelete = linkDocs.map(doc => {\n return {\n ...doc,\n _deleted: true,\n }\n })\n await this._db.bulkDocs(toDelete)\n return table\n }\n}\n\nexport default LinkController\n", "import { generateLinkID } from \"../utils\"\nimport { FieldTypes } from \"../../constants\"\nimport { LinkDocument } from \"@budibase/types\"\n\n/**\n * Creates a new link document structure which can be put to the database. It is important to\n * note that while this talks about linker/linked the link is bi-directional and for all intent\n * and purposes it does not matter from which direction the link was initiated.\n * @param {string} tableId1 The ID of the first table (the linker).\n * @param {string} tableId2 The ID of the second table (the linked).\n * @param {string} fieldName1 The name of the field in the linker table.\n * @param {string} fieldName2 The name of the field in the linked table.\n * @param {string} rowId1 The ID of the row which is acting as the linker.\n * @param {string} rowId2 The ID of the row which is acting as the linked.\n * @constructor\n */\nclass LinkDocumentImpl implements LinkDocument {\n _id: string\n type: string\n doc1: {\n rowId: string\n fieldName: string\n tableId: string\n }\n doc2: {\n rowId: string\n fieldName: string\n tableId: string\n }\n constructor(\n tableId1: string,\n fieldName1: string,\n rowId1: string,\n tableId2: string,\n fieldName2: string,\n rowId2: string\n ) {\n this._id = generateLinkID(\n tableId1,\n tableId2,\n rowId1,\n rowId2,\n fieldName1,\n fieldName2\n )\n this.type = FieldTypes.LINK\n this.doc1 = {\n tableId: tableId1,\n fieldName: fieldName1,\n rowId: rowId1,\n }\n this.doc2 = {\n tableId: tableId2,\n fieldName: fieldName2,\n rowId: rowId2,\n }\n }\n}\n\nexport default LinkDocumentImpl\n", "import LinkController from \"./LinkController\"\nimport {\n IncludeDocs,\n getLinkDocuments,\n createLinkView,\n getUniqueByProp,\n getRelatedTableForField,\n getLinkedTableIDs,\n getLinkedTable,\n} from \"./linkUtils\"\nimport { flatten } from \"lodash\"\nimport { FieldTypes } from \"../../constants\"\nimport { getMultiIDParams, USER_METDATA_PREFIX } from \"../utils\"\nimport { partition } from \"lodash\"\nimport { getGlobalUsersFromMetadata } from \"../../utilities/global\"\nimport { processFormulas } from \"../../utilities/rowProcessor\"\nimport { context } from \"@budibase/backend-core\"\nimport { Table, Row, LinkDocumentValue } from \"@budibase/types\"\n\nexport { IncludeDocs, getLinkDocuments, createLinkView } from \"./linkUtils\"\n\n/**\n * This functionality makes sure that when rows with links are created, updated or deleted they are processed\n * correctly - making sure that no stale links are left around and that all links have been made successfully.\n */\n\nexport const EventType = {\n ROW_SAVE: \"row:save\",\n ROW_UPDATE: \"row:update\",\n ROW_DELETE: \"row:delete\",\n TABLE_SAVE: \"table:save\",\n TABLE_UPDATED: \"table:updated\",\n TABLE_DELETE: \"table:delete\",\n}\n\nfunction clearRelationshipFields(table: Table, rows: Row[]) {\n for (let [key, field] of Object.entries(table.schema)) {\n if (field.type === FieldTypes.LINK) {\n rows = rows.map(row => {\n delete row[key]\n return row\n })\n }\n }\n return rows\n}\n\nasync function getLinksForRows(rows: Row[]) {\n const tableIds = [...new Set(rows.map(el => el.tableId))]\n // start by getting all the link values for performance reasons\n const promises = tableIds.map(tableId =>\n getLinkDocuments({\n tableId: tableId,\n includeDocs: IncludeDocs.EXCLUDE,\n })\n )\n const responses = flatten(\n (await Promise.all(promises)) as LinkDocumentValue[][]\n )\n // have to get unique as the previous table query can\n // return duplicates, could be querying for both tables in a relation\n return getUniqueByProp(\n responses\n .filter(el => el != null)\n // create a unique ID which we can use for getting only unique ones\n .map(el => ({ ...el, unique: el.id + el.thisId + el.fieldName })),\n \"unique\"\n )\n}\n\nasync function getFullLinkedDocs(links: LinkDocumentValue[]) {\n // create DBs\n const db = context.getAppDB()\n const linkedRowIds = links.map(link => link.id)\n const uniqueRowIds = [...new Set(linkedRowIds)]\n let dbRows = (await db.allDocs(getMultiIDParams(uniqueRowIds))).rows.map(\n row => row.doc\n )\n // convert the unique db rows back to a full list of linked rows\n const linked = linkedRowIds\n .map(id => dbRows.find(row => row && row._id === id))\n .filter(row => row != null)\n // need to handle users as specific cases\n let [users, other] = partition(linked, linkRow =>\n linkRow._id.startsWith(USER_METDATA_PREFIX)\n )\n users = await getGlobalUsersFromMetadata(users)\n return [...other, ...users]\n}\n\n/**\n * Update link documents for a row or table - this is to be called by the API controller when a change is occurring.\n * @param {string} args.eventType states what type of change which is occurring, means this can be expanded upon in the\n * future quite easily (all updates go through one function).\n * @param {string} args.tableId The ID of the of the table which is being changed.\n * @param {object|undefined} args.row The row which is changing, e.g. created, updated or deleted.\n * @param {object|undefined} args.table If the table has already been retrieved this can be used to reduce database gets.\n * @param {object|undefined} args.oldTable If the table is being updated then the old table can be provided for differencing.\n * @returns {Promise<object>} When the update is complete this will respond successfully. Returns the row for\n * row operations and the table for table operations.\n */\nexport async function updateLinks(args: {\n tableId?: string\n eventType: string\n row?: Row\n table?: Table\n oldTable?: Table\n}) {\n const { eventType, row, tableId, table, oldTable } = args\n const baseReturnObj = row == null ? table : row\n // make sure table ID is set\n if (tableId == null && table != null) {\n args.tableId = table._id!\n }\n let linkController = new LinkController(args)\n try {\n if (\n !(await linkController.doesTableHaveLinkedFields(table)) &&\n (oldTable == null ||\n !(await linkController.doesTableHaveLinkedFields(oldTable)))\n ) {\n return baseReturnObj\n }\n } catch (err) {\n return baseReturnObj\n }\n switch (eventType) {\n case EventType.ROW_SAVE:\n case EventType.ROW_UPDATE:\n return await linkController.rowSaved()\n case EventType.ROW_DELETE:\n return await linkController.rowDeleted()\n case EventType.TABLE_SAVE:\n return await linkController.tableSaved()\n case EventType.TABLE_UPDATED:\n return await linkController.tableUpdated()\n case EventType.TABLE_DELETE:\n return await linkController.tableDeleted()\n default:\n throw \"Type of event is not known, linked row handler requires update.\"\n }\n}\n\n/**\n * Given a table and a list of rows this will retrieve all of the attached docs and enrich them into the row.\n * This is required for formula fields, this may only be utilised internally (for now).\n * @param {object} table The table from which the rows originated.\n * @param {array<object>} rows The rows which are to be enriched.\n * @return {Promise<*>} returns the rows with all of the enriched relationships on it.\n */\nexport async function attachFullLinkedDocs(table: Table, rows: Row[]) {\n const linkedTableIds = getLinkedTableIDs(table)\n if (linkedTableIds.length === 0) {\n return rows\n }\n // get all the links\n const links = (await getLinksForRows(rows)).filter(link =>\n rows.some(row => row._id === link.thisId)\n )\n // clear any existing links that could be dupe'd\n rows = clearRelationshipFields(table, rows)\n // now get the docs and combine into the rows\n let linked = await getFullLinkedDocs(links)\n const linkedTables: Table[] = []\n for (let row of rows) {\n for (let link of links.filter(link => link.thisId === row._id)) {\n if (row[link.fieldName] == null) {\n row[link.fieldName] = []\n }\n const linkedRow = linked.find(row => row._id === link.id)\n if (linkedRow) {\n const linkedTableId =\n linkedRow.tableId || getRelatedTableForField(table, link.fieldName)\n const linkedTable = await getLinkedTable(linkedTableId, linkedTables)\n if (linkedTable) {\n row[link.fieldName].push(processFormulas(linkedTable, linkedRow))\n }\n }\n }\n }\n return rows\n}\n\n/**\n * This function will take the given enriched rows and squash the links to only contain the primary display field.\n * @param {object} table The table from which the rows originated.\n * @param {array<object>} enriched The pre-enriched rows (full docs) which are to be squashed.\n * @returns {Promise<Array>} The rows after having their links squashed to only contain the ID and primary display.\n */\nexport async function squashLinksToPrimaryDisplay(\n table: Table,\n enriched: Row[]\n) {\n // will populate this as we find them\n const linkedTables = [table]\n for (let row of enriched) {\n // this only fetches the table if its not already in array\n const rowTable = await getLinkedTable(row.tableId!, linkedTables)\n for (let [column, schema] of Object.entries(rowTable?.schema || {})) {\n if (schema.type !== FieldTypes.LINK || !Array.isArray(row[column])) {\n continue\n }\n const newLinks = []\n for (let link of row[column]) {\n const linkTblId = link.tableId || getRelatedTableForField(table, column)\n const linkedTable = await getLinkedTable(linkTblId, linkedTables)\n const obj: any = { _id: link._id }\n if (linkedTable?.primaryDisplay && link[linkedTable.primaryDisplay]) {\n obj.primaryDisplay = link[linkedTable.primaryDisplay]\n }\n newLinks.push(obj)\n }\n row[column] = newLinks\n }\n }\n return enriched\n}\n", "import * as linkRows from \"../../db/linkedRows\"\nimport { FieldTypes, AutoFieldSubTypes } from \"../../constants\"\nimport { processFormulas, fixAutoColumnSubType } from \"./utils\"\nimport { ObjectStoreBuckets } from \"../../constants\"\nimport { context, db as dbCore, objectStore } from \"@budibase/backend-core\"\nimport { InternalTables } from \"../../db/utils\"\nimport { TYPE_TRANSFORM_MAP } from \"./map\"\nimport { Row, RowAttachment, Table, ContextUser } from \"@budibase/types\"\nconst { cloneDeep } = require(\"lodash/fp\")\nexport * from \"./utils\"\n\ntype AutoColumnProcessingOpts = {\n reprocessing?: boolean\n noAutoRelationships?: boolean\n}\n\nconst BASE_AUTO_ID = 1\n\n/**\n * Given the old state of the row and the new one after an update, this will\n * find the keys that have been removed in the updated row.\n */\nfunction getRemovedAttachmentKeys(\n oldRow: Row,\n row: Row,\n attachmentKey: string\n) {\n if (!oldRow[attachmentKey]) {\n return []\n }\n const oldKeys = oldRow[attachmentKey].map((attachment: any) => attachment.key)\n // no attachments in new row, all removed\n if (!row[attachmentKey]) {\n return oldKeys\n }\n const newKeys = row[attachmentKey].map((attachment: any) => attachment.key)\n return oldKeys.filter((key: string) => newKeys.indexOf(key) === -1)\n}\n\n/**\n * This will update any auto columns that are found on the row/table with the correct information based on\n * time now and the current logged in user making the request.\n * @param {Object} user The user to be used for an appId as well as the createdBy and createdAt fields.\n * @param {Object} table The table which is to be used for the schema, as well as handling auto IDs incrementing.\n * @param {Object} row The row which is to be updated with information for the auto columns.\n * @param {Object} opts specific options for function to carry out optional features.\n * @returns {{row: Object, table: Object}} The updated row and table, the table may need to be updated\n * for automatic ID purposes.\n */\nexport function processAutoColumn(\n user: ContextUser | null,\n table: Table,\n row: Row,\n opts?: AutoColumnProcessingOpts\n) {\n let noUser = !user || !user.userId\n let isUserTable = table._id === InternalTables.USER_METADATA\n let now = new Date().toISOString()\n // if a row doesn't have a revision then it doesn't exist yet\n const creating = !row._rev\n // check its not user table, or whether any of the processing options have been disabled\n const shouldUpdateUserFields =\n !isUserTable && !opts?.reprocessing && !opts?.noAutoRelationships && !noUser\n for (let [key, schema] of Object.entries(table.schema)) {\n if (!schema.autocolumn) {\n continue\n }\n if (!schema.subtype) {\n schema = fixAutoColumnSubType(schema)\n }\n switch (schema.subtype) {\n case AutoFieldSubTypes.CREATED_BY:\n if (creating && shouldUpdateUserFields && user) {\n row[key] = [user.userId]\n }\n break\n case AutoFieldSubTypes.CREATED_AT:\n if (creating) {\n row[key] = now\n }\n break\n case AutoFieldSubTypes.UPDATED_BY:\n if (shouldUpdateUserFields && user) {\n row[key] = [user.userId]\n }\n break\n case AutoFieldSubTypes.UPDATED_AT:\n row[key] = now\n break\n case AutoFieldSubTypes.AUTO_ID:\n if (creating) {\n schema.lastID = !schema.lastID ? BASE_AUTO_ID : schema.lastID + 1\n row[key] = schema.lastID\n }\n break\n }\n }\n return { table, row }\n}\n\n/**\n * This will coerce a value to the correct types based on the type transform map\n * @param {object} row The value to coerce\n * @param {object} type The type fo coerce to\n * @returns {object} The coerced value\n */\nexport function coerce(row: any, type: string) {\n // no coercion specified for type, skip it\n if (!TYPE_TRANSFORM_MAP[type]) {\n return row\n }\n // eslint-disable-next-line no-prototype-builtins\n if (TYPE_TRANSFORM_MAP[type].hasOwnProperty(row)) {\n // @ts-ignore\n return TYPE_TRANSFORM_MAP[type][row]\n } else if (TYPE_TRANSFORM_MAP[type].parse) {\n // @ts-ignore\n return TYPE_TRANSFORM_MAP[type].parse(row)\n }\n\n return row\n}\n\n/**\n * Given an input route this function will apply all the necessary pre-processing to it, such as coercion\n * of column values or adding auto-column values.\n * @param {object} user the user which is performing the input.\n * @param {object} row the row which is being created/updated.\n * @param {object} table the table which the row is being saved to.\n * @param {object} opts some input processing options (like disabling auto-column relationships).\n * @returns {object} the row which has been prepared to be written to the DB.\n */\nexport function inputProcessing(\n user: ContextUser | null,\n table: Table,\n row: Row,\n opts?: AutoColumnProcessingOpts\n) {\n let clonedRow = cloneDeep(row)\n\n const dontCleanseKeys = [\"type\", \"_id\", \"_rev\", \"tableId\"]\n for (let [key, value] of Object.entries(clonedRow)) {\n const field = table.schema[key]\n // cleanse fields that aren't in the schema\n if (!field) {\n if (dontCleanseKeys.indexOf(key) === -1) {\n delete clonedRow[key]\n }\n continue\n }\n // remove any formula values, they are to be generated\n if (field.type === FieldTypes.FORMULA) {\n delete clonedRow[key]\n }\n // otherwise coerce what is there to correct types\n else {\n clonedRow[key] = coerce(value, field.type)\n }\n\n // remove any attachment urls, they are generated on read\n if (field.type === FieldTypes.ATTACHMENT) {\n const attachments = clonedRow[key]\n if (attachments?.length) {\n attachments.forEach((attachment: RowAttachment) => {\n delete attachment.url\n })\n }\n }\n }\n\n if (!clonedRow._id || !clonedRow._rev) {\n clonedRow._id = row._id\n clonedRow._rev = row._rev\n }\n\n // handle auto columns - this returns an object like {table, row}\n return processAutoColumn(user, table, clonedRow, opts)\n}\n\n/**\n * This function enriches the input rows with anything they are supposed to contain, for example\n * link records or attachment links.\n * @param {object} table the table from which these rows came from originally, this is used to determine\n * the schema of the rows and then enrich.\n * @param {object[]|object} rows the rows which are to be enriched.\n * @param {object} opts used to set some options for the output, such as disabling relationship squashing.\n * @returns {object[]|object} the enriched rows will be returned.\n */\nexport async function outputProcessing(\n table: Table,\n rows: Row[] | Row,\n opts = { squash: true }\n) {\n let wasArray = true\n if (!(rows instanceof Array)) {\n rows = [rows]\n wasArray = false\n }\n // attach any linked row information\n let enriched = await linkRows.attachFullLinkedDocs(table, rows as Row[])\n\n // process formulas\n enriched = processFormulas(table, enriched, { dynamic: true }) as Row[]\n\n // set the attachments URLs\n for (let [property, column] of Object.entries(table.schema)) {\n if (column.type === FieldTypes.ATTACHMENT) {\n for (let row of enriched) {\n if (row[property] == null || !Array.isArray(row[property])) {\n continue\n }\n row[property].forEach((attachment: RowAttachment) => {\n attachment.url = objectStore.getAppFileUrl(attachment.key)\n })\n }\n }\n }\n if (opts.squash) {\n enriched = await linkRows.squashLinksToPrimaryDisplay(table, enriched)\n }\n return wasArray ? enriched : enriched[0]\n}\n\n/**\n * Clean up any attachments that were attached to a row.\n * @param {object} table The table from which a row is being removed.\n * @param {any} row optional - the row being removed.\n * @param {any} rows optional - if multiple rows being deleted can do this in bulk.\n * @param {any} oldRow optional - if updating a row this will determine the difference.\n * @param {any} oldTable optional - if updating a table, can supply the old table to look for\n * deleted attachment columns.\n * @return {Promise<void>} When all attachments have been removed this will return.\n */\nexport async function cleanupAttachments(\n table: Table,\n {\n row,\n rows,\n oldRow,\n oldTable,\n }: { row?: Row; rows?: Row[]; oldRow?: Row; oldTable?: Table }\n): Promise<any> {\n const appId = context.getAppId()\n if (!dbCore.isProdAppID(appId)) {\n const prodAppId = dbCore.getProdAppID(appId!)\n // if prod exists, then don't allow deleting\n const exists = await dbCore.dbExists(prodAppId)\n if (exists) {\n return\n }\n }\n let files: string[] = []\n function addFiles(row: Row, key: string) {\n if (row[key]) {\n files = files.concat(row[key].map((attachment: any) => attachment.key))\n }\n }\n const schemaToUse = oldTable ? oldTable.schema : table.schema\n for (let [key, schema] of Object.entries(schemaToUse)) {\n if (schema.type !== FieldTypes.ATTACHMENT) {\n continue\n }\n // old table had this column, new table doesn't - delete it\n if (rows && oldTable && !table.schema[key]) {\n rows.forEach(row => addFiles(row, key))\n } else if (oldRow && row) {\n // if updating, need to manage the differences\n files = files.concat(getRemovedAttachmentKeys(oldRow, row, key))\n } else if (row) {\n addFiles(row, key)\n } else if (rows) {\n rows.forEach(row => addFiles(row, key))\n }\n }\n if (files.length > 0) {\n await objectStore.deleteFiles(ObjectStoreBuckets.APPS, files)\n }\n}\n", "import {\n AutoFieldDefaultNames,\n AutoFieldSubTypes,\n FieldTypes,\n FormulaTypes,\n} from \"../../constants\"\nimport { processStringSync } from \"@budibase/string-templates\"\nimport { FieldSchema, FieldType, Row, Table } from \"@budibase/types\"\n\n/**\n * If the subtype has been lost for any reason this works out what\n * subtype the auto column should be.\n */\nexport function fixAutoColumnSubType(column: FieldSchema) {\n if (!column.autocolumn || !column.name || column.subtype) {\n return column\n }\n // the columns which get auto generated\n if (column.name.endsWith(AutoFieldDefaultNames.CREATED_BY)) {\n column.subtype = AutoFieldSubTypes.CREATED_BY\n } else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_BY)) {\n column.subtype = AutoFieldSubTypes.UPDATED_BY\n } else if (column.name.endsWith(AutoFieldDefaultNames.CREATED_AT)) {\n column.subtype = AutoFieldSubTypes.CREATED_AT\n } else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_AT)) {\n column.subtype = AutoFieldSubTypes.UPDATED_AT\n } else if (column.name.endsWith(AutoFieldDefaultNames.AUTO_ID)) {\n column.subtype = AutoFieldSubTypes.AUTO_ID\n }\n return column\n}\n\n/**\n * Looks through the rows provided and finds formulas - which it then processes.\n */\nexport function processFormulas(\n table: Table,\n rows: Row[] | Row,\n { dynamic, contextRows }: any = { dynamic: true }\n) {\n const single = !Array.isArray(rows)\n let rowArray: Row[]\n if (single) {\n rowArray = [rows]\n contextRows = contextRows ? [contextRows] : contextRows\n } else {\n rowArray = rows\n }\n for (let [column, schema] of Object.entries(table.schema)) {\n const isStatic = schema.formulaType === FormulaTypes.STATIC\n if (\n schema.type !== FieldTypes.FORMULA ||\n schema.formula == null ||\n (dynamic && isStatic) ||\n (!dynamic && !isStatic)\n ) {\n continue\n }\n // iterate through rows and process formula\n for (let i = 0; i < rowArray.length; i++) {\n let row = rowArray[i]\n let context = contextRows ? contextRows[i] : row\n rowArray[i] = {\n ...row,\n [column]: processStringSync(schema.formula, context),\n }\n }\n }\n return single ? rowArray[0] : rowArray\n}\n\n/**\n * Processes any date columns and ensures that those without the ignoreTimezones\n * flag set are parsed as UTC rather than local time.\n */\nexport function processDates(table: Table, rows: Row[]) {\n let datesWithTZ = []\n for (let [column, schema] of Object.entries(table.schema)) {\n if (schema.type !== FieldTypes.DATETIME) {\n continue\n }\n if (!schema.timeOnly && !schema.ignoreTimezones) {\n datesWithTZ.push(column)\n }\n }\n\n for (let row of rows) {\n for (let col of datesWithTZ) {\n if (row[col] && typeof row[col] === \"string\" && !row[col].endsWith(\"Z\")) {\n row[col] = new Date(row[col]).toISOString()\n }\n }\n }\n return rows\n}\n", "// @ts-nocheck\nimport { FieldTypes } from \"../../constants\"\nimport { logging } from \"@budibase/backend-core\"\n\nconst parseArrayString = value => {\n if (typeof value === \"string\") {\n if (value === \"\") {\n return []\n }\n let result\n try {\n result = JSON.parse(value.replace(/'/g, '\"'))\n return result\n } catch (e) {\n logging.logAlert(\"Could not parse row value\", e)\n }\n }\n return value\n}\n\n/**\n * A map of how we convert various properties in rows to each other based on the row type.\n */\nexport const TYPE_TRANSFORM_MAP: any = {\n [FieldTypes.LINK]: {\n \"\": [],\n [null]: [],\n [undefined]: undefined,\n parse: link => {\n if (Array.isArray(link) && typeof link[0] === \"object\") {\n return link.map(el => (el && el._id ? el._id : el))\n }\n if (typeof link === \"string\") {\n return [link]\n }\n return link\n },\n },\n [FieldTypes.OPTIONS]: {\n \"\": null,\n [null]: null,\n [undefined]: undefined,\n },\n [FieldTypes.ARRAY]: {\n [null]: [],\n [undefined]: undefined,\n parse: parseArrayString,\n },\n [FieldTypes.STRING]: {\n \"\": \"\",\n [null]: \"\",\n [undefined]: undefined,\n },\n [FieldTypes.BARCODEQR]: {\n \"\": \"\",\n [null]: \"\",\n [undefined]: undefined,\n },\n [FieldTypes.FORMULA]: {\n \"\": \"\",\n [null]: \"\",\n [undefined]: undefined,\n },\n [FieldTypes.LONGFORM]: {\n \"\": \"\",\n [null]: \"\",\n [undefined]: undefined,\n },\n [FieldTypes.NUMBER]: {\n \"\": null,\n [null]: null,\n [undefined]: undefined,\n parse: n => parseFloat(n),\n },\n [FieldTypes.DATETIME]: {\n \"\": null,\n [undefined]: undefined,\n [null]: null,\n parse: date => {\n if (date instanceof Date) {\n return date.toISOString()\n }\n return date\n },\n },\n [FieldTypes.ATTACHMENT]: {\n [null]: [],\n [undefined]: undefined,\n parse: parseArrayString,\n },\n [FieldTypes.BOOLEAN]: {\n \"\": null,\n [null]: null,\n [undefined]: undefined,\n true: true,\n false: false,\n },\n [FieldTypes.AUTO]: {\n parse: () => undefined,\n },\n [FieldTypes.JSON]: {\n parse: input => {\n try {\n if (input === \"\") {\n return undefined\n }\n return JSON.parse(input)\n } catch (err) {\n return input\n }\n },\n },\n}\n", "import { db as dbCore, context, SearchParams } from \"@budibase/backend-core\"\nimport { SearchFilters, Row, SearchIndex } from \"@budibase/types\"\n\nexport async function paginatedSearch(\n query: SearchFilters,\n params: SearchParams<Row>\n) {\n const appId = context.getAppId()\n return dbCore.paginatedSearch(appId!, SearchIndex.ROWS, query, params)\n}\n\nexport async function fullSearch(\n query: SearchFilters,\n params: SearchParams<Row>\n) {\n const appId = context.getAppId()\n return dbCore.fullSearch(appId!, SearchIndex.ROWS, query, params)\n}\n", "import newid from \"./newid\"\nimport { Row, View, Document } from \"@budibase/types\"\n\n// bypass the main application db config\n// use in memory pouchdb directly\nimport { db as dbCore } from \"@budibase/backend-core\"\nconst Pouch = dbCore.getPouch({ inMemory: true })\n\nexport async function runView(\n view: View,\n calculation: string,\n group: boolean,\n data: Row[]\n) {\n // use a different ID each time for the DB, make sure they\n // are always unique for each query, don't want overlap\n // which could cause 409s\n const db = new Pouch(newid())\n try {\n // write all the docs to the in memory Pouch (remove revs)\n await db.bulkDocs(\n data.map(row => ({\n ...row,\n _rev: undefined,\n }))\n )\n let fn = (doc: Document, emit: any) => emit(doc._id)\n // BUDI-7060 -> indirect eval call appears to cause issues in cloud\n eval(\"fn = \" + view?.map?.replace(\"function (doc)\", \"function (doc, emit)\"))\n const queryFns: any = {\n meta: view.meta,\n map: fn,\n }\n if (view.reduce) {\n queryFns.reduce = view.reduce\n }\n const response: { rows: Row[] } = await db.query(queryFns, {\n include_docs: !calculation,\n group: !!group,\n })\n // need to fix the revs to be totally accurate\n for (let row of response.rows) {\n if (!row._rev || !row._id) {\n continue\n }\n const found = data.find(possible => possible._id === row._id)\n if (found) {\n row._rev = found._rev\n }\n }\n return response\n } finally {\n await db.destroy()\n await dbCore.closePouchDB(db)\n }\n}\n", "import {\n ViewName,\n generateMemoryViewID,\n getMemoryViewParams,\n DocumentType,\n SEPARATOR,\n} from \"../../../db/utils\"\nimport env from \"../../../environment\"\nimport { context } from \"@budibase/backend-core\"\nimport viewBuilder from \"./viewBuilder\"\nimport { Database } from \"@budibase/types\"\n\nexport async function getView(viewName: string) {\n const db = context.getAppDB()\n if (env.SELF_HOSTED) {\n const designDoc = await db.get(\"_design/database\")\n return designDoc.views[viewName]\n } else {\n // This is a table view, don't read the view from the DB\n if (viewName.startsWith(DocumentType.TABLE + SEPARATOR)) {\n return null\n }\n\n try {\n const viewDoc = await db.get(generateMemoryViewID(viewName))\n return viewDoc.view\n } catch (err: any) {\n // Return null when PouchDB doesn't found the view\n if (err.status === 404) {\n return null\n }\n\n throw err\n }\n }\n}\n\nexport async function getViews() {\n const db = context.getAppDB()\n const response = []\n if (env.SELF_HOSTED) {\n const designDoc = await db.get(\"_design/database\")\n for (let name of Object.keys(designDoc.views)) {\n // Only return custom views, not built ins\n const viewNames = Object.values(ViewName) as string[]\n if (viewNames.indexOf(name) !== -1) {\n continue\n }\n response.push({\n name,\n ...designDoc.views[name],\n })\n }\n } else {\n const views = (\n await db.allDocs(\n getMemoryViewParams({\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n for (let viewDoc of views) {\n response.push({\n name: viewDoc.name,\n ...viewDoc.view,\n })\n }\n }\n return response\n}\n\nexport async function saveView(\n originalName: string | null,\n viewName: string,\n viewTemplate: any\n) {\n const db = context.getAppDB()\n if (env.SELF_HOSTED) {\n const designDoc = await db.get(\"_design/database\")\n designDoc.views = {\n ...designDoc.views,\n [viewName]: viewTemplate,\n }\n // view has been renamed\n if (originalName) {\n delete designDoc.views[originalName]\n }\n await db.put(designDoc)\n } else {\n const id = generateMemoryViewID(viewName)\n const originalId = originalName ? generateMemoryViewID(originalName) : null\n const viewDoc: any = {\n _id: id,\n view: viewTemplate,\n name: viewName,\n tableId: viewTemplate.meta.tableId,\n }\n try {\n const old = await db.get(id)\n if (originalId) {\n const originalDoc = await db.get(originalId)\n await db.remove(originalDoc._id, originalDoc._rev)\n }\n if (old && old._rev) {\n viewDoc._rev = old._rev\n }\n } catch (err) {\n // didn't exist, just skip\n }\n await db.put(viewDoc)\n }\n}\n\nexport async function deleteView(viewName: string) {\n const db = context.getAppDB()\n if (env.SELF_HOSTED) {\n const designDoc = await db.get(\"_design/database\")\n const view = designDoc.views[viewName]\n delete designDoc.views[viewName]\n await db.put(designDoc)\n return view\n } else {\n const id = generateMemoryViewID(viewName)\n const viewDoc = await db.get(id)\n await db.remove(viewDoc._id, viewDoc._rev)\n return viewDoc.view\n }\n}\n\nexport async function migrateToInMemoryView(db: Database, viewName: string) {\n // delete the view initially\n const designDoc = await db.get(\"_design/database\")\n // run the view back through the view builder to update it\n const view = viewBuilder(designDoc.views[viewName].meta)\n delete designDoc.views[viewName]\n await db.put(designDoc)\n await exports.saveView(db, null, viewName, view)\n}\n\nexport async function migrateToDesignView(db: Database, viewName: string) {\n let view = await db.get(generateMemoryViewID(viewName))\n const designDoc = await db.get(\"_design/database\")\n designDoc.views[viewName] = viewBuilder(view.view.meta)\n await db.put(designDoc)\n await db.remove(view._id, view._rev)\n}\n\nexport async function getFromDesignDoc(db: Database, viewName: string) {\n const designDoc = await db.get(\"_design/database\")\n let view = designDoc.views[viewName]\n if (view == null) {\n throw { status: 404, message: \"Unable to get view\" }\n }\n return view\n}\n\nexport async function getFromMemoryDoc(db: Database, viewName: string) {\n let view = await db.get(generateMemoryViewID(viewName))\n if (view) {\n view = view.view\n } else {\n throw { status: 404, message: \"Unable to get view\" }\n }\n return view\n}\n", "import { ViewFilter } from \"@budibase/types\"\n\ntype ViewTemplateOpts = {\n field: string\n tableId: string\n groupBy: string\n filters: ViewFilter[]\n calculation: string\n groupByMulti: boolean\n}\n\nconst TOKEN_MAP: Record<string, string> = {\n EQUALS: \"===\",\n NOT_EQUALS: \"!==\",\n LT: \"<\",\n LTE: \"<=\",\n MT: \">\",\n MTE: \">=\",\n CONTAINS: \"includes\",\n AND: \"&&\",\n OR: \"||\",\n}\n\nconst CONDITIONS: Record<string, string> = {\n EMPTY: \"EMPTY\",\n NOT_EMPTY: \"NOT_EMPTY\",\n CONTAINS: \"CONTAINS\",\n}\n\nfunction isEmptyExpression(key: string) {\n return `(\n doc[\"${key}\"] === undefined ||\n doc[\"${key}\"] === null ||\n doc[\"${key}\"] === \"\" ||\n (Array.isArray(doc[\"${key}\"]) && doc[\"${key}\"].length === 0)\n )`\n}\n\nconst GROUP_PROPERTY: Record<string, { type: string }> = {\n group: {\n type: \"string\",\n },\n}\n\nconst GROUP_PROPERTY_MULTI: Record<string, { type: string }> = {\n group: {\n type: \"array\",\n },\n}\n\nconst FIELD_PROPERTY: Record<string, { type: string }> = {\n field: {\n type: \"string\",\n },\n}\n\nconst SCHEMA_MAP: Record<string, any> = {\n sum: {\n field: \"string\",\n value: \"number\",\n },\n count: {\n field: \"string\",\n value: \"number\",\n },\n stats: {\n sum: {\n type: \"number\",\n },\n min: {\n type: \"number\",\n },\n max: {\n type: \"number\",\n },\n count: {\n type: \"number\",\n },\n sumsqr: {\n type: \"number\",\n },\n avg: {\n type: \"number\",\n },\n },\n}\n\n/**\n * Iterates through the array of filters to create a JS\n * expression that gets used in a CouchDB view.\n * @param {Array} filters - an array of filter objects\n * @returns {String} JS Expression\n */\nfunction parseFilterExpression(filters: ViewFilter[]) {\n const expression = []\n\n let first = true\n for (let filter of filters) {\n if (!first && filter.conjunction) {\n expression.push(TOKEN_MAP[filter.conjunction])\n }\n\n if (filter.condition === CONDITIONS.CONTAINS) {\n expression.push(\n `doc[\"${filter.key}\"].${TOKEN_MAP[filter.condition]}(\"${filter.value}\")`\n )\n } else if (filter.condition === CONDITIONS.EMPTY) {\n expression.push(isEmptyExpression(filter.key))\n } else if (filter.condition === CONDITIONS.NOT_EMPTY) {\n expression.push(`!${isEmptyExpression(filter.key)}`)\n } else {\n const value =\n typeof filter.value == \"string\" ? `\"${filter.value}\"` : filter.value\n\n expression.push(\n `doc[\"${filter.key}\"] ${TOKEN_MAP[filter.condition]} ${value}`\n )\n }\n first = false\n }\n\n return expression.join(\" \")\n}\n\n/**\n * Returns a CouchDB compliant emit() expression that is used to emit the\n * correct key/value pairs for custom views.\n * @param {String?} field - field to use for calculations, if any\n * @param {String?} groupBy - field to group calculation results on, if any\n */\nfunction parseEmitExpression(field: string, groupBy: string) {\n return `emit(doc[\"${groupBy || \"_id\"}\"], doc[\"${field}\"]);`\n}\n\n/**\n * Return a fully parsed CouchDB compliant view definition\n * that will be stored in the design document in the database.\n *\n * @param {Object} viewDefinition - the JSON definition for a custom view.\n * field: field that calculations will be performed on\n * tableId: tableId of the table this view was created from\n * groupBy: field that calculations will be grouped by. Field must be present for this to be useful\n * filters: Array of filter objects containing predicates that are parsed into a JS expression\n * calculation: an optional calculation to be performed over the view data.\n */\nexport default function (\n { field, tableId, groupBy, filters = [], calculation }: ViewTemplateOpts,\n groupByMulti?: boolean\n) {\n // first filter can't have a conjunction\n if (filters && filters.length > 0 && filters[0].conjunction) {\n delete filters[0].conjunction\n }\n\n let schema = null,\n statFilter = null\n\n let groupBySchema = groupByMulti ? GROUP_PROPERTY_MULTI : GROUP_PROPERTY\n\n if (calculation) {\n schema = {\n ...(groupBy ? groupBySchema : FIELD_PROPERTY),\n ...SCHEMA_MAP[calculation],\n }\n if (\n !filters.find(\n filter =>\n filter.key === field && filter.condition === CONDITIONS.NOT_EMPTY\n )\n ) {\n statFilter = parseFilterExpression([\n { key: field, condition: CONDITIONS.NOT_EMPTY },\n ])\n }\n }\n\n const parsedFilters = parseFilterExpression(filters)\n const filterExpression = parsedFilters ? `&& (${parsedFilters})` : \"\"\n\n const emitExpression = parseEmitExpression(field, groupBy)\n const tableExpression = `doc.tableId === \"${tableId}\"`\n const coreExpression = statFilter\n ? `(${tableExpression} && ${statFilter})`\n : tableExpression\n const reduction = field && calculation ? { reduce: `_${calculation}` } : {}\n\n return {\n meta: {\n field,\n tableId,\n groupBy,\n filters,\n schema,\n calculation,\n },\n map: `function (doc) {\n if (${coreExpression} ${filterExpression}) {\n ${emitExpression}\n }\n }`,\n ...reduction,\n }\n}\n", "import { getRowParams } from \"../../../db/utils\"\nimport {\n outputProcessing,\n processAutoColumn,\n processFormulas,\n} from \"../../../utilities/rowProcessor\"\nimport { FieldTypes, FormulaTypes } from \"../../../constants\"\nimport { context } from \"@budibase/backend-core\"\nimport { Table, Row } from \"@budibase/types\"\nconst { isEqual } = require(\"lodash\")\nconst { cloneDeep } = require(\"lodash/fp\")\n\n/**\n * This function runs through a list of enriched rows, looks at the rows which\n * are related and then checks if they need the state of their formulas\n * updated.\n * NOTE: this will only for affect static formulas.\n */\nexport async function updateRelatedFormula(\n table: Table,\n enrichedRows: Row[] | Row\n) {\n const db = context.getAppDB()\n // no formula to update, we're done\n if (!table.relatedFormula) {\n return\n }\n let promises: Promise<any>[] = []\n for (let enrichedRow of Array.isArray(enrichedRows)\n ? enrichedRows\n : [enrichedRows]) {\n // the related rows by tableId\n let relatedRows: Record<string, Row[]> = {}\n for (let [key, field] of Object.entries(enrichedRow)) {\n const columnDefinition = table.schema[key]\n if (columnDefinition && columnDefinition.type === FieldTypes.LINK) {\n const relatedTableId = columnDefinition.tableId!\n if (!relatedRows[relatedTableId]) {\n relatedRows[relatedTableId] = []\n }\n // filter down to the rows which are not already included in related\n const currentIds = relatedRows[relatedTableId].map(row => row._id)\n const uniqueRelatedRows = field.filter(\n (row: Row) => !currentIds.includes(row._id)\n )\n relatedRows[relatedTableId] =\n relatedRows[relatedTableId].concat(uniqueRelatedRows)\n }\n }\n for (let tableId of table.relatedFormula) {\n let relatedTable: Table\n try {\n // no rows to update, skip\n if (!relatedRows[tableId] || relatedRows[tableId].length === 0) {\n continue\n }\n relatedTable = await db.get(tableId)\n } catch (err) {\n // no error scenario, table doesn't seem to exist anymore, ignore\n }\n for (let column of Object.values(relatedTable!.schema)) {\n // needs updated in related rows\n if (\n column.type === FieldTypes.FORMULA &&\n column.formulaType === FormulaTypes.STATIC\n ) {\n // re-enrich rows for all the related, don't update the related formula for them\n promises = promises.concat(\n relatedRows[tableId].map(related =>\n finaliseRow(relatedTable, related, {\n updateFormula: false,\n })\n )\n )\n break\n }\n }\n }\n }\n await Promise.all(promises)\n}\n\nexport async function updateAllFormulasInTable(table: Table) {\n const db = context.getAppDB()\n // start by getting the raw rows (which will be written back to DB after update)\n let rows = (\n await db.allDocs(\n getRowParams(table._id, null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n // now enrich the rows, note the clone so that we have the base state of the\n // rows so that we don't write any of the enriched information back\n let enrichedRows = await outputProcessing(table, cloneDeep(rows), {\n squash: false,\n })\n const updatedRows = []\n for (let row of rows) {\n // find the enriched row, if found process the formulas\n const enrichedRow = enrichedRows.find(\n (enriched: any) => enriched._id === row._id\n )\n if (enrichedRow) {\n const processed = processFormulas(table, cloneDeep(row), {\n dynamic: false,\n contextRows: enrichedRow,\n })\n // values have changed, need to add to bulk docs to update\n if (!isEqual(processed, row)) {\n updatedRows.push(processed)\n }\n }\n }\n await db.bulkDocs(updatedRows)\n}\n\n/**\n * This function runs at the end of the save/patch functions of the row controller, all this\n * really does is enrich the row, handle any static formula processing, then return the enriched\n * row. The reason we need to return the enriched row is that the automation row created trigger\n * expects the row to be totally enriched/contain all relationships.\n */\nexport async function finaliseRow(\n table: Table,\n row: Row,\n { oldTable, updateFormula }: { oldTable?: Table; updateFormula: boolean } = {\n updateFormula: true,\n }\n) {\n const db = context.getAppDB()\n row.type = \"row\"\n // process the row before return, to include relationships\n let enrichedRow = (await outputProcessing(table, cloneDeep(row), {\n squash: false,\n })) as Row\n // use enriched row to generate formulas for saving, specifically only use as context\n row = processFormulas(table, row, {\n dynamic: false,\n contextRows: enrichedRow,\n })\n // don't worry about rev, tables handle rev/lastID updates\n // if another row has been written since processing this will\n // handle the auto ID clash\n if (oldTable && !isEqual(oldTable, table)) {\n try {\n await db.put(table)\n } catch (err: any) {\n if (err.status === 409) {\n const updatedTable = await db.get(table._id)\n let response = processAutoColumn(null, updatedTable, row, {\n reprocessing: true,\n })\n await db.put(response.table)\n row = response.row\n } else {\n throw err\n }\n }\n }\n const response = await db.put(row)\n // for response, calculate the formulas for the enriched row\n enrichedRow._rev = response.rev\n enrichedRow = await processFormulas(table, enrichedRow, { dynamic: false })\n // this updates the related formulas in other rows based on the relations to this row\n if (updateFormula) {\n await updateRelatedFormula(table, enrichedRow)\n }\n return { row: enrichedRow, table }\n}\n", "import {\n SortDirection,\n FieldTypes,\n NoEmptyFilterStrings,\n} from \"../../../constants\"\nimport {\n breakExternalTableId,\n breakRowIdField,\n} from \"../../../integrations/utils\"\nimport { ExternalRequest, RunConfig } from \"./ExternalRequest\"\nimport * as exporters from \"../view/exporters\"\nimport { apiFileReturn } from \"../../../utilities/fileSystem\"\nimport {\n Operation,\n UserCtx,\n Row,\n PaginationJson,\n Table,\n Datasource,\n IncludeRelationship,\n SortJson,\n} from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\nimport * as utils from \"./utils\"\n\nconst { cleanExportRows } = require(\"./utils\")\n\nexport async function handleRequest(\n operation: Operation,\n tableId: string,\n opts?: RunConfig\n) {\n // make sure the filters are cleaned up, no empty strings for equals, fuzzy or string\n if (opts && opts.filters) {\n for (let filterField of NoEmptyFilterStrings) {\n if (!opts.filters[filterField]) {\n continue\n }\n // @ts-ignore\n for (let [key, value] of Object.entries(opts.filters[filterField])) {\n if (!value || value === \"\") {\n // @ts-ignore\n delete opts.filters[filterField][key]\n }\n }\n }\n }\n return new ExternalRequest(operation, tableId, opts?.datasource).run(\n opts || {}\n )\n}\n\nexport async function patch(ctx: UserCtx) {\n const inputs = ctx.request.body\n const tableId = ctx.params.tableId\n const id = inputs._id\n // don't save the ID to db\n delete inputs._id\n const validateResult = await utils.validate({\n row: inputs,\n tableId,\n })\n if (!validateResult.valid) {\n throw { validation: validateResult.errors }\n }\n return handleRequest(Operation.UPDATE, tableId, {\n id: breakRowIdField(id),\n row: inputs,\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })\n}\n\nexport async function save(ctx: UserCtx) {\n const inputs = ctx.request.body\n const tableId = ctx.params.tableId\n const validateResult = await utils.validate({\n row: inputs,\n tableId,\n })\n if (!validateResult.valid) {\n throw { validation: validateResult.errors }\n }\n return handleRequest(Operation.CREATE, tableId, {\n row: inputs,\n includeSqlRelationships: IncludeRelationship.EXCLUDE,\n })\n}\n\nexport async function fetchView(ctx: UserCtx) {\n // there are no views in external datasources, shouldn't ever be called\n // for now just fetch\n const split = ctx.params.viewName.split(\"all_\")\n ctx.params.tableId = split[1] ? split[1] : split[0]\n return fetch(ctx)\n}\n\nexport async function fetch(ctx: UserCtx) {\n const tableId = ctx.params.tableId\n return handleRequest(Operation.READ, tableId, {\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })\n}\n\nexport async function find(ctx: UserCtx) {\n const id = ctx.params.rowId\n const tableId = ctx.params.tableId\n const response = (await handleRequest(Operation.READ, tableId, {\n id: breakRowIdField(id),\n includeSqlRelationships: IncludeRelationship.EXCLUDE,\n })) as Row[]\n return response ? response[0] : response\n}\n\nexport async function destroy(ctx: UserCtx) {\n const tableId = ctx.params.tableId\n const id = ctx.request.body._id\n const { row } = (await handleRequest(Operation.DELETE, tableId, {\n id: breakRowIdField(id),\n includeSqlRelationships: IncludeRelationship.EXCLUDE,\n })) as { row: Row }\n return { response: { ok: true }, row }\n}\n\nexport async function bulkDestroy(ctx: UserCtx) {\n const { rows } = ctx.request.body\n const tableId = ctx.params.tableId\n let promises: Promise<Row[] | { row: Row; table: Table }>[] = []\n for (let row of rows) {\n promises.push(\n handleRequest(Operation.DELETE, tableId, {\n id: breakRowIdField(row._id),\n includeSqlRelationships: IncludeRelationship.EXCLUDE,\n })\n )\n }\n const responses = (await Promise.all(promises)) as { row: Row }[]\n return { response: { ok: true }, rows: responses.map(resp => resp.row) }\n}\n\nexport async function search(ctx: UserCtx) {\n const tableId = ctx.params.tableId\n const { paginate, query, ...params } = ctx.request.body\n let { bookmark, limit } = params\n if (!bookmark && paginate) {\n bookmark = 1\n }\n let paginateObj = {}\n\n if (paginate) {\n paginateObj = {\n // add one so we can track if there is another page\n limit: limit,\n page: bookmark,\n }\n } else if (params && limit) {\n paginateObj = {\n limit: limit,\n }\n }\n let sort: SortJson | undefined\n if (params.sort) {\n const direction =\n params.sortOrder === \"descending\"\n ? SortDirection.DESCENDING\n : SortDirection.ASCENDING\n sort = {\n [params.sort]: { direction },\n }\n }\n try {\n const rows = (await handleRequest(Operation.READ, tableId, {\n filters: query,\n sort,\n paginate: paginateObj as PaginationJson,\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })) as Row[]\n let hasNextPage = false\n if (paginate && rows.length === limit) {\n const nextRows = (await handleRequest(Operation.READ, tableId, {\n filters: query,\n sort,\n paginate: {\n limit: 1,\n page: bookmark * limit + 1,\n },\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })) as Row[]\n hasNextPage = nextRows.length > 0\n }\n // need wrapper object for bookmarks etc when paginating\n return { rows, hasNextPage, bookmark: bookmark + 1 }\n } catch (err: any) {\n if (err.message && err.message.includes(\"does not exist\")) {\n throw new Error(\n `Table updated externally, please re-fetch - ${err.message}`\n )\n } else {\n throw err\n }\n }\n}\n\nexport async function exportRows(ctx: UserCtx) {\n const { datasourceId, tableName } = breakExternalTableId(ctx.params.tableId)\n const format = ctx.query.format\n const { columns } = ctx.request.body\n const datasource = await sdk.datasources.get(datasourceId!)\n if (!datasource || !datasource.entities) {\n ctx.throw(400, \"Datasource has not been configured for plus API.\")\n }\n\n if (ctx.request.body.rows) {\n ctx.request.body = {\n query: {\n oneOf: {\n _id: ctx.request.body.rows.map(\n (row: string) => JSON.parse(decodeURI(row))[0]\n ),\n },\n },\n }\n }\n\n let result = await search(ctx)\n let rows: Row[] = []\n\n // Filter data to only specified columns if required\n\n if (columns && columns.length) {\n for (let i = 0; i < result.rows.length; i++) {\n rows[i] = {}\n for (let column of columns) {\n rows[i][column] = result.rows[i][column]\n }\n }\n } else {\n rows = result.rows\n }\n\n if (!tableName) {\n ctx.throw(400, \"Could not find table name.\")\n }\n let schema = datasource.entities[tableName].schema\n let exportRows = cleanExportRows(rows, schema, format, columns)\n\n let headers = Object.keys(schema)\n\n // @ts-ignore\n const exporter = exporters[format]\n const filename = `export.${format}`\n\n // send down the file\n ctx.attachment(filename)\n return apiFileReturn(exporter(headers, exportRows))\n}\n\nexport async function fetchEnrichedRow(ctx: UserCtx) {\n const id = ctx.params.rowId\n const tableId = ctx.params.tableId\n const { datasourceId, tableName } = breakExternalTableId(tableId)\n const datasource: Datasource = await sdk.datasources.get(datasourceId!)\n if (!tableName) {\n ctx.throw(400, \"Unable to find table.\")\n }\n if (!datasource || !datasource.entities) {\n ctx.throw(400, \"Datasource has not been configured for plus API.\")\n }\n const tables = datasource.entities\n const response = (await handleRequest(Operation.READ, tableId, {\n id,\n datasource,\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })) as Row[]\n const table: Table = tables[tableName]\n const row = response[0]\n // this seems like a lot of work, but basically we need to dig deeper for the enrich\n // for a single row, there is probably a better way to do this with some smart multi-layer joins\n for (let [fieldName, field] of Object.entries(table.schema)) {\n if (\n field.type !== FieldTypes.LINK ||\n !row[fieldName] ||\n row[fieldName].length === 0\n ) {\n continue\n }\n const links = row[fieldName]\n const linkedTableId = field.tableId\n const linkedTableName = breakExternalTableId(linkedTableId).tableName!\n const linkedTable = tables[linkedTableName]\n // don't support composite keys right now\n const linkedIds = links.map((link: Row) => breakRowIdField(link._id!)[0])\n const primaryLink = linkedTable.primary?.[0] as string\n row[fieldName] = await handleRequest(Operation.READ, linkedTableId!, {\n tables,\n filters: {\n oneOf: {\n [primaryLink]: linkedIds,\n },\n },\n includeSqlRelationships: IncludeRelationship.INCLUDE,\n })\n }\n return row\n}\n", "import {\n Datasource,\n FieldSchema,\n FieldType,\n FilterType,\n IncludeRelationship,\n Operation,\n PaginationJson,\n RelationshipsJson,\n RelationshipTypes,\n Row,\n SearchFilters,\n SortJson,\n SortType,\n Table,\n} from \"@budibase/types\"\nimport {\n breakExternalTableId,\n breakRowIdField,\n convertRowId,\n generateRowIdField,\n isRowId,\n isSQL,\n} from \"../../../integrations/utils\"\nimport { getDatasourceAndQuery } from \"./utils\"\nimport { FieldTypes } from \"../../../constants\"\nimport { processObjectSync } from \"@budibase/string-templates\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { processDates, processFormulas } from \"../../../utilities/rowProcessor\"\nimport { db as dbCore } from \"@budibase/backend-core\"\nimport sdk from \"../../../sdk\"\n\nexport interface ManyRelationship {\n tableId?: string\n id?: string\n isUpdate?: boolean\n key: string\n [key: string]: any\n}\n\nexport interface RunConfig {\n id?: any[]\n filters?: SearchFilters\n sort?: SortJson\n paginate?: PaginationJson\n datasource?: Datasource\n row?: Row\n rows?: Row[]\n tables?: Record<string, Table>\n includeSqlRelationships?: IncludeRelationship\n}\n\nfunction buildFilters(\n id: string | undefined | string[],\n filters: SearchFilters,\n table: Table\n) {\n const primary = table.primary\n // if passed in array need to copy for shifting etc\n let idCopy: undefined | string | any[] = cloneDeep(id)\n if (filters) {\n // need to map over the filters and make sure the _id field isn't present\n let prefix = 1\n for (let operator of Object.values(filters)) {\n for (let field of Object.keys(operator || {})) {\n if (dbCore.removeKeyNumbering(field) === \"_id\") {\n if (primary) {\n const parts = breakRowIdField(operator[field])\n for (let field of primary) {\n operator[`${prefix}:${field}`] = parts.shift()\n }\n prefix++\n }\n // make sure this field doesn't exist on any filter\n delete operator[field]\n }\n }\n }\n }\n // there is no id, just use the user provided filters\n if (!idCopy || !table) {\n return filters\n }\n // if used as URL parameter it will have been joined\n if (!Array.isArray(idCopy)) {\n idCopy = breakRowIdField(idCopy)\n }\n const equal: any = {}\n if (primary && idCopy) {\n for (let field of primary) {\n // work through the ID and get the parts\n equal[field] = idCopy.shift()\n }\n }\n return {\n equal,\n }\n}\n\n/**\n * This function checks the incoming parameters to make sure all the inputs are\n * valid based on on the table schema. The main thing this is looking for is when a\n * user has made use of the _id field of a row for a foreign key or a search parameter.\n * In these cases the key will be sent up as [1], rather than 1. In these cases we will\n * simplify it down to the requirements. This function is quite complex as we try to be\n * relatively restrictive over what types of columns we will perform this action for.\n */\nfunction cleanupConfig(config: RunConfig, table: Table): RunConfig {\n const primaryOptions = [\n FieldTypes.STRING,\n FieldTypes.LONGFORM,\n FieldTypes.OPTIONS,\n FieldTypes.NUMBER,\n ]\n // filter out fields which cannot be keys\n const fieldNames = Object.entries(table.schema)\n .filter(schema => primaryOptions.find(val => val === schema[1].type))\n .map(([fieldName]) => fieldName)\n const iterateObject = (obj: { [key: string]: any }) => {\n for (let [field, value] of Object.entries(obj)) {\n if (fieldNames.find(name => name === field) && isRowId(value)) {\n obj[field] = convertRowId(value)\n }\n }\n }\n // check the row and filters to make sure they aren't a key of some sort\n if (config.filters) {\n for (let [key, filter] of Object.entries(config.filters)) {\n // oneOf is an array, don't iterate it\n if (\n typeof filter !== \"object\" ||\n Object.keys(filter).length === 0 ||\n key === FilterType.ONE_OF\n ) {\n continue\n }\n iterateObject(filter)\n }\n }\n if (config.row) {\n iterateObject(config.row)\n }\n\n return config\n}\n\nfunction generateIdForRow(\n row: Row | undefined,\n table: Table,\n isLinked: boolean = false\n): string {\n const primary = table.primary\n if (!row || !primary) {\n return \"\"\n }\n // build id array\n let idParts = []\n for (let field of primary) {\n let fieldValue = extractFieldValue({\n row,\n tableName: table.name,\n fieldName: field,\n isLinked,\n })\n if (fieldValue) {\n idParts.push(fieldValue)\n }\n }\n if (idParts.length === 0) {\n return \"\"\n }\n return generateRowIdField(idParts)\n}\n\nfunction getEndpoint(tableId: string | undefined, operation: string) {\n if (!tableId) {\n return {}\n }\n const { datasourceId, tableName } = breakExternalTableId(tableId)\n return {\n datasourceId,\n entityId: tableName,\n operation,\n }\n}\n\n// need to handle table name + field or just field, depending on if relationships used\nfunction extractFieldValue({\n row,\n tableName,\n fieldName,\n isLinked,\n}: {\n row: Row\n tableName: string\n fieldName: string\n isLinked: boolean\n}) {\n let value = row[`${tableName}.${fieldName}`]\n if (value == null && !isLinked) {\n value = row[fieldName]\n }\n return value\n}\n\nfunction basicProcessing({\n row,\n table,\n isLinked,\n}: {\n row: Row\n table: Table\n isLinked: boolean\n}): Row {\n const thisRow: Row = {}\n // filter the row down to what is actually the row (not joined)\n for (let field of Object.values(table.schema)) {\n const fieldName = field.name\n\n const value = extractFieldValue({\n row,\n tableName: table.name,\n fieldName,\n isLinked,\n })\n\n // all responses include \"select col as table.col\" so that overlaps are handled\n if (value != null) {\n thisRow[fieldName] = value\n }\n }\n thisRow._id = generateIdForRow(row, table, isLinked)\n thisRow.tableId = table._id\n thisRow._rev = \"rev\"\n return processFormulas(table, thisRow)\n}\n\nfunction fixArrayTypes(row: Row, table: Table) {\n for (let [fieldName, schema] of Object.entries(table.schema)) {\n if (\n schema.type === FieldTypes.ARRAY &&\n typeof row[fieldName] === \"string\"\n ) {\n try {\n row[fieldName] = JSON.parse(row[fieldName])\n } catch (err) {\n // couldn't convert back to array, ignore\n delete row[fieldName]\n }\n }\n }\n return row\n}\n\nfunction isOneSide(field: FieldSchema) {\n return (\n field.relationshipType && field.relationshipType.split(\"-\")[0] === \"one\"\n )\n}\n\nexport class ExternalRequest {\n private operation: Operation\n private tableId: string\n private datasource?: Datasource\n private tables: { [key: string]: Table } = {}\n\n constructor(operation: Operation, tableId: string, datasource?: Datasource) {\n this.operation = operation\n this.tableId = tableId\n this.datasource = datasource\n if (datasource && datasource.entities) {\n this.tables = datasource.entities\n }\n }\n\n getTable(tableId: string | undefined): Table | undefined {\n if (!tableId) {\n throw \"Table ID is unknown, cannot find table\"\n }\n const { tableName } = breakExternalTableId(tableId)\n if (tableName) {\n return this.tables[tableName]\n }\n }\n\n inputProcessing(row: Row | undefined, table: Table) {\n if (!row) {\n return { row, manyRelationships: [] }\n }\n // we don't really support composite keys for relationships, this is why [0] is used\n // @ts-ignore\n const tablePrimary: string = table.primary[0]\n let newRow: Row = {},\n manyRelationships: ManyRelationship[] = []\n for (let [key, field] of Object.entries(table.schema)) {\n // if set already, or not set just skip it\n if (\n row[key] == null ||\n newRow[key] ||\n field.autocolumn ||\n field.type === FieldTypes.FORMULA\n ) {\n continue\n }\n // if its an empty string then it means return the column to null (if possible)\n if (row[key] === \"\") {\n newRow[key] = null\n continue\n }\n // parse floats/numbers\n if (field.type === FieldTypes.NUMBER && !isNaN(parseFloat(row[key]))) {\n newRow[key] = parseFloat(row[key])\n }\n // if its not a link then just copy it over\n if (field.type !== FieldTypes.LINK) {\n newRow[key] = row[key]\n continue\n }\n const { tableName: linkTableName } = breakExternalTableId(field?.tableId)\n // table has to exist for many to many\n if (!linkTableName || !this.tables[linkTableName]) {\n continue\n }\n const linkTable = this.tables[linkTableName]\n // @ts-ignore\n const linkTablePrimary = linkTable.primary[0]\n // one to many\n if (isOneSide(field)) {\n let id = row[key][0]\n if (typeof row[key] === \"string\") {\n id = decodeURIComponent(row[key]).match(/\\[(.*?)\\]/)?.[1]\n }\n newRow[field.foreignKey || linkTablePrimary] = breakRowIdField(id)[0]\n }\n // many to many\n else if (field.through) {\n // we're not inserting a doc, will be a bunch of update calls\n const otherKey: string = field.throughFrom || linkTablePrimary\n const thisKey: string = field.throughTo || tablePrimary\n row[key].forEach((relationship: any) => {\n manyRelationships.push({\n tableId: field.through || field.tableId,\n isUpdate: false,\n key: otherKey,\n [otherKey]: breakRowIdField(relationship)[0],\n // leave the ID for enrichment later\n [thisKey]: `{{ literal ${tablePrimary} }}`,\n })\n })\n }\n // many to one\n else {\n const thisKey: string = \"id\"\n // @ts-ignore\n const otherKey: string = field.fieldName\n row[key].forEach((relationship: any) => {\n manyRelationships.push({\n tableId: field.tableId,\n isUpdate: true,\n key: otherKey,\n [thisKey]: breakRowIdField(relationship)[0],\n // leave the ID for enrichment later\n [otherKey]: `{{ literal ${tablePrimary} }}`,\n })\n })\n }\n }\n // we return the relationships that may need to be created in the through table\n // we do this so that if the ID is generated by the DB it can be inserted\n // after the fact\n return { row: newRow, manyRelationships }\n }\n\n squashRelationshipColumns(\n table: Table,\n row: Row,\n relationships: RelationshipsJson[]\n ): Row {\n for (let relationship of relationships) {\n const linkedTable = this.tables[relationship.tableName]\n if (!linkedTable || !row[relationship.column]) {\n continue\n }\n const display = linkedTable.primaryDisplay\n for (let key of Object.keys(row[relationship.column])) {\n let relatedRow: Row = row[relationship.column][key]\n // add this row as context for the relationship\n for (let col of Object.values(linkedTable.schema)) {\n if (col.type === FieldType.LINK && col.tableId === table._id) {\n relatedRow[col.name] = [row]\n }\n }\n relatedRow = processFormulas(linkedTable, relatedRow)\n const relatedDisplay = display ? relatedRow[display] : undefined\n row[relationship.column][key] = {\n primaryDisplay: relatedDisplay || \"Invalid display column\",\n _id: relatedRow._id,\n }\n }\n }\n return row\n }\n\n /**\n * This iterates through the returned rows and works out what elements of the rows\n * actually match up to another row (based on primary keys) - this is pretty specific\n * to SQL and the way that SQL relationships are returned based on joins.\n * This is complicated, but the idea is that when a SQL query returns all the relations\n * will be separate rows, with all of the data in each row. We have to decipher what comes\n * from where (which tables) and how to convert that into budibase columns.\n */\n updateRelationshipColumns(\n table: Table,\n row: Row,\n rows: { [key: string]: Row },\n relationships: RelationshipsJson[]\n ) {\n const columns: { [key: string]: any } = {}\n for (let relationship of relationships) {\n const linkedTable = this.tables[relationship.tableName]\n if (!linkedTable) {\n continue\n }\n const fromColumn = `${table.name}.${relationship.from}`\n const toColumn = `${linkedTable.name}.${relationship.to}`\n // this is important when working with multiple relationships\n // between the same tables, don't want to overlap/multiply the relations\n if (\n !relationship.through &&\n row[fromColumn]?.toString() !== row[toColumn]?.toString()\n ) {\n continue\n }\n\n let linked = basicProcessing({ row, table: linkedTable, isLinked: true })\n if (!linked._id) {\n continue\n }\n columns[relationship.column] = linked\n }\n for (let [column, related] of Object.entries(columns)) {\n if (!row._id) {\n continue\n }\n const rowId: string = row._id\n if (!Array.isArray(rows[rowId][column])) {\n rows[rowId][column] = []\n }\n // make sure relationship hasn't been found already\n if (\n !rows[rowId][column].find(\n (relation: Row) => relation._id === related._id\n )\n ) {\n rows[rowId][column].push(related)\n }\n }\n return rows\n }\n\n outputProcessing(\n rows: Row[] = [],\n table: Table,\n relationships: RelationshipsJson[]\n ) {\n if (!rows || rows.length === 0 || rows[0].read === true) {\n return []\n }\n let finalRows: { [key: string]: Row } = {}\n for (let row of rows) {\n const rowId = generateIdForRow(row, table)\n row._id = rowId\n // this is a relationship of some sort\n if (finalRows[rowId]) {\n finalRows = this.updateRelationshipColumns(\n table,\n row,\n finalRows,\n relationships\n )\n continue\n }\n const thisRow = fixArrayTypes(\n basicProcessing({ row, table, isLinked: false }),\n table\n )\n if (thisRow._id == null) {\n throw \"Unable to generate row ID for SQL rows\"\n }\n finalRows[thisRow._id] = thisRow\n // do this at end once its been added to the final rows\n finalRows = this.updateRelationshipColumns(\n table,\n row,\n finalRows,\n relationships\n )\n }\n\n // Process some additional data types\n let finalRowArray = Object.values(finalRows)\n finalRowArray = processDates(table, finalRowArray)\n finalRowArray = processFormulas(table, finalRowArray) as Row[]\n\n return finalRowArray.map((row: Row) =>\n this.squashRelationshipColumns(table, row, relationships)\n )\n }\n\n /**\n * Gets the list of relationship JSON structures based on the columns in the table,\n * this will be used by the underlying library to build whatever relationship mechanism\n * it has (e.g. SQL joins).\n */\n buildRelationships(table: Table): RelationshipsJson[] {\n const relationships = []\n for (let [fieldName, field] of Object.entries(table.schema)) {\n if (field.type !== FieldTypes.LINK) {\n continue\n }\n const { tableName: linkTableName } = breakExternalTableId(field.tableId)\n // no table to link to, this is not a valid relationships\n if (!linkTableName || !this.tables[linkTableName]) {\n continue\n }\n const linkTable = this.tables[linkTableName]\n if (!table.primary || !linkTable.primary) {\n continue\n }\n const definition: any = {\n // if no foreign key specified then use the name of the field in other table\n from: field.foreignKey || table.primary[0],\n to: field.fieldName,\n tableName: linkTableName,\n // need to specify where to put this back into\n column: fieldName,\n }\n if (field.through) {\n const { tableName: throughTableName } = breakExternalTableId(\n field.through\n )\n definition.through = throughTableName\n // don't support composite keys for relationships\n definition.from = field.throughTo || table.primary[0]\n definition.to = field.throughFrom || linkTable.primary[0]\n definition.fromPrimary = table.primary[0]\n definition.toPrimary = linkTable.primary[0]\n }\n relationships.push(definition)\n }\n return relationships\n }\n\n /**\n * This is a cached lookup, of relationship records, this is mainly for creating/deleting junction\n * information.\n */\n async lookupRelations(tableId: string, row: Row) {\n const related: { [key: string]: any } = {}\n const { tableName } = breakExternalTableId(tableId)\n if (!tableName) {\n return related\n }\n const table = this.tables[tableName]\n // @ts-ignore\n const primaryKey = table.primary[0]\n // make a new request to get the row with all its relationships\n // we need this to work out if any relationships need removed\n for (let field of Object.values(table.schema)) {\n if (\n field.type !== FieldTypes.LINK ||\n !field.fieldName ||\n isOneSide(field)\n ) {\n continue\n }\n const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY\n const tableId = isMany ? field.through : field.tableId\n const { tableName: relatedTableName } = breakExternalTableId(tableId)\n // @ts-ignore\n const linkPrimaryKey = this.tables[relatedTableName].primary[0]\n const manyKey = field.throughTo || primaryKey\n const lookupField = isMany ? primaryKey : field.foreignKey\n const fieldName = isMany ? manyKey : field.fieldName\n if (!lookupField || !row[lookupField]) {\n continue\n }\n const response = await getDatasourceAndQuery({\n endpoint: getEndpoint(tableId, Operation.READ),\n filters: {\n equal: {\n [fieldName]: row[lookupField],\n },\n },\n })\n // this is the response from knex if no rows found\n const rows = !response[0].read ? response : []\n const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName\n related[storeTo] = { rows, isMany, tableId }\n }\n return related\n }\n\n /**\n * Once a row has been written we may need to update a many field, e.g. updating foreign keys\n * in a bunch of rows in another table, or inserting/deleting rows from a junction table (many to many).\n * This is quite a complex process and is handled by this function, there are a few things going on here:\n * 1. If updating foreign keys its relatively simple, just create a filter for the row that needs updated\n * and write the various components.\n * 2. If junction table, then we lookup what exists already, write what doesn't exist, work out what\n * isn't supposed to exist anymore and delete those. This is better than the usual method of delete them\n * all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail).\n */\n async handleManyRelationships(\n mainTableId: string,\n row: Row,\n relationships: ManyRelationship[]\n ) {\n // if we're creating (in a through table) need to wipe the existing ones first\n const promises = []\n const related = await this.lookupRelations(mainTableId, row)\n for (let relationship of relationships) {\n const { key, tableId, isUpdate, id, ...rest } = relationship\n const body: { [key: string]: any } = processObjectSync(rest, row, {})\n const linkTable = this.getTable(tableId)\n const relationshipPrimary = linkTable?.primary || []\n const linkPrimary = relationshipPrimary[0]\n if (!linkTable || !linkPrimary) {\n return\n }\n\n const linkSecondary = relationshipPrimary[1]\n\n const rows = related[key]?.rows || []\n\n function relationshipMatchPredicate({\n row,\n linkPrimary,\n linkSecondary,\n }: {\n row: { [key: string]: any }\n linkPrimary: string\n linkSecondary?: string\n }) {\n const matchesPrimaryLink =\n row[linkPrimary] === relationship.id ||\n row[linkPrimary] === body?.[linkPrimary]\n if (!matchesPrimaryLink || !linkSecondary) {\n return matchesPrimaryLink\n }\n\n const matchesSecondayLink = row[linkSecondary] === body?.[linkSecondary]\n return matchesPrimaryLink && matchesSecondayLink\n }\n\n const existingRelationship = rows.find((row: { [key: string]: any }) =>\n relationshipMatchPredicate({ row, linkPrimary, linkSecondary })\n )\n const operation = isUpdate ? Operation.UPDATE : Operation.CREATE\n if (!existingRelationship) {\n promises.push(\n getDatasourceAndQuery({\n endpoint: getEndpoint(tableId, operation),\n // if we're doing many relationships then we're writing, only one response\n body,\n filters: buildFilters(id, {}, linkTable),\n })\n )\n } else {\n // remove the relationship from cache so it isn't adjusted again\n rows.splice(rows.indexOf(existingRelationship), 1)\n }\n }\n // finally cleanup anything that needs to be removed\n for (let [colName, { isMany, rows, tableId }] of Object.entries(related)) {\n const table: Table | undefined = this.getTable(tableId)\n // if its not the foreign key skip it, nothing to do\n if (\n !table ||\n (!isMany && table.primary && table.primary.indexOf(colName) !== -1)\n ) {\n continue\n }\n for (let row of rows) {\n const filters = buildFilters(generateIdForRow(row, table), {}, table)\n // safety check, if there are no filters on deletion bad things happen\n if (Object.keys(filters).length !== 0) {\n const op = isMany ? Operation.DELETE : Operation.UPDATE\n const body = isMany ? null : { [colName]: null }\n promises.push(\n getDatasourceAndQuery({\n endpoint: getEndpoint(tableId, op),\n body,\n filters,\n })\n )\n }\n }\n }\n await Promise.all(promises)\n }\n\n /**\n * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which\n * you have column overlap in relationships, e.g. we join a few different tables and they all have the\n * concept of an ID, but for some of them it will be null (if they say don't have a relationship).\n * Creating the specific list of fields that we desire, and excluding the ones that are no use to us\n * is more performant and has the added benefit of protecting against this scenario.\n */\n buildFields(table: Table, includeRelations: boolean) {\n function extractRealFields(table: Table, existing: string[] = []) {\n return Object.entries(table.schema)\n .filter(\n column =>\n column[1].type !== FieldTypes.LINK &&\n column[1].type !== FieldTypes.FORMULA &&\n !existing.find((field: string) => field === column[0])\n )\n .map(column => `${table.name}.${column[0]}`)\n }\n let fields = extractRealFields(table)\n for (let field of Object.values(table.schema)) {\n if (field.type !== FieldTypes.LINK || !includeRelations) {\n continue\n }\n const { tableName: linkTableName } = breakExternalTableId(field.tableId)\n if (linkTableName) {\n const linkTable = this.tables[linkTableName]\n if (linkTable) {\n const linkedFields = extractRealFields(linkTable, fields)\n fields = fields.concat(linkedFields)\n }\n }\n }\n return fields\n }\n\n async run(config: RunConfig) {\n const { operation, tableId } = this\n let { datasourceId, tableName } = breakExternalTableId(tableId)\n if (!tableName) {\n throw \"Unable to run without a table name\"\n }\n if (!this.datasource) {\n this.datasource = await sdk.datasources.get(datasourceId!)\n if (!this.datasource || !this.datasource.entities) {\n throw \"No tables found, fetch tables before query.\"\n }\n this.tables = this.datasource.entities\n }\n const table = this.tables[tableName]\n let isSql = isSQL(this.datasource)\n if (!table) {\n throw `Unable to process query, table \"${tableName}\" not defined.`\n }\n // look for specific components of config which may not be considered acceptable\n let { id, row, filters, sort, paginate, rows } = cleanupConfig(\n config,\n table\n )\n //if the sort column is a formula, remove it\n for (let sortColumn of Object.keys(sort || {})) {\n if (!sort?.[sortColumn]) {\n continue\n }\n switch (table.schema[sortColumn]?.type) {\n case FieldType.FORMULA:\n delete sort?.[sortColumn]\n break\n case FieldType.NUMBER:\n sort[sortColumn].type = SortType.number\n break\n }\n }\n filters = buildFilters(id, filters || {}, table)\n const relationships = this.buildRelationships(table)\n\n const includeSqlRelationships =\n config.includeSqlRelationships === IncludeRelationship.INCLUDE\n\n // clean up row on ingress using schema\n const processed = this.inputProcessing(row, table)\n row = processed.row\n if (\n operation === Operation.DELETE &&\n (filters == null || Object.keys(filters).length === 0)\n ) {\n throw \"Deletion must be filtered\"\n }\n let json = {\n endpoint: {\n datasourceId,\n entityId: tableName,\n operation,\n },\n resource: {\n // have to specify the fields to avoid column overlap (for SQL)\n fields: isSql ? this.buildFields(table, includeSqlRelationships) : [],\n },\n filters,\n sort,\n paginate,\n relationships,\n body: row || rows,\n // pass an id filter into extra, purely for mysql/returning\n extra: {\n idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),\n },\n meta: {\n table,\n },\n }\n\n // can't really use response right now\n const response = await getDatasourceAndQuery(json)\n // handle many to many relationships now if we know the ID (could be auto increment)\n if (operation !== Operation.READ && processed.manyRelationships) {\n await this.handleManyRelationships(\n table._id || \"\",\n response[0],\n processed.manyRelationships\n )\n }\n const output = this.outputProcessing(response, table, relationships)\n // if reading it'll just be an array of rows, return whole thing\n return operation === Operation.READ && Array.isArray(response)\n ? output\n : { row: output[0], table }\n }\n}\n", "import { save } from \"../../api/controllers/row\"\nimport { cleanUpRow, getError } from \"../automationUtils\"\nimport { buildCtx } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Create Row\",\n tagline: \"Create a {{inputs.enriched.table.name}} row\",\n icon: \"TableRowAddBottom\",\n description: \"Add a row to your database\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.CREATE_ROW,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n },\n },\n customType: AutomationCustomIOType.ROW,\n title: \"Table\",\n required: [\"tableId\"],\n },\n },\n required: [\"row\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The new row\",\n },\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The response from the table\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the row creation was successful\",\n },\n id: {\n type: AutomationIOType.STRING,\n description: \"The identifier of the new row\",\n },\n revision: {\n type: AutomationIOType.STRING,\n description: \"The revision of the new row\",\n },\n },\n required: [\"success\", \"id\", \"revision\"],\n },\n },\n}\n\nexport async function run({ inputs, appId, emitter }: AutomationStepInput) {\n if (inputs.row == null || inputs.row.tableId == null) {\n return {\n success: false,\n response: {\n message: \"Invalid inputs\",\n },\n }\n }\n // have to clean up the row, remove the table from it\n const ctx: any = buildCtx(appId, emitter, {\n body: inputs.row,\n params: {\n tableId: inputs.row.tableId,\n },\n })\n\n try {\n inputs.row = await cleanUpRow(inputs.row.tableId, inputs.row)\n await save(ctx)\n return {\n row: inputs.row,\n response: ctx.body,\n id: ctx.body._id,\n revision: ctx.body._rev,\n success: ctx.status === 200,\n }\n } catch (err) {\n return {\n success: false,\n response: getError(err),\n }\n }\n}\n", "import { EventEmitter } from \"events\"\n\nexport async function getFetchResponse(fetched: any) {\n let status = fetched.status,\n message\n const contentType = fetched.headers.get(\"content-type\")\n try {\n if (contentType && contentType.indexOf(\"application/json\") !== -1) {\n message = await fetched.json()\n } else {\n message = await fetched.text()\n }\n } catch (err) {\n message = \"Failed to retrieve response\"\n }\n return { status, message }\n}\n\n// need to make sure all ctx structures have the\n// throw added to them, so that controllers don't\n// throw a ctx.throw undefined when error occurs\n// opts can contain, body, params and version\nexport function buildCtx(\n appId: string,\n emitter?: EventEmitter | null,\n opts: any = {}\n) {\n const ctx: any = {\n appId,\n user: { appId },\n eventEmitter: emitter,\n throw: (code: string, error: any) => {\n throw error\n },\n }\n if (opts.body) {\n ctx.request = { body: opts.body }\n }\n if (opts.params) {\n ctx.params = opts.params\n }\n if (opts.version) {\n ctx.version = opts.version\n }\n return ctx\n}\n", "import * as rowController from \"../../api/controllers/row\"\nimport * as automationUtils from \"../automationUtils\"\nimport { buildCtx } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Update Row\",\n tagline: \"Update a {{inputs.enriched.table.name}} row\",\n icon: \"Refresh\",\n description: \"Update a row in your database\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.UPDATE_ROW,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n meta: {\n type: AutomationIOType.OBJECT,\n title: \"Field settings\",\n },\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n title: \"Table\",\n },\n rowId: {\n type: AutomationIOType.STRING,\n title: \"Row ID\",\n },\n },\n required: [\"row\", \"rowId\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The updated row\",\n },\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The response from the table\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n id: {\n type: AutomationIOType.STRING,\n description: \"The identifier of the updated row\",\n },\n revision: {\n type: AutomationIOType.STRING,\n description: \"The revision of the updated row\",\n },\n },\n required: [\"success\", \"id\", \"revision\"],\n },\n },\n}\n\nexport async function run({ inputs, appId, emitter }: AutomationStepInput) {\n if (inputs.rowId == null || inputs.row == null) {\n return {\n success: false,\n response: {\n message: \"Invalid inputs\",\n },\n }\n }\n const tableId = inputs.row.tableId\n\n // clear any undefined, null or empty string properties so that they aren't updated\n for (let propKey of Object.keys(inputs.row)) {\n if (\n (inputs.row[propKey] == null || inputs.row[propKey] === \"\") &&\n !inputs.meta?.fields?.[propKey]?.clearRelationships\n ) {\n delete inputs.row[propKey]\n }\n }\n\n // have to clean up the row, remove the table from it\n const ctx: any = buildCtx(appId, emitter, {\n body: {\n ...inputs.row,\n _id: inputs.rowId,\n },\n params: {\n rowId: inputs.rowId,\n tableId: tableId,\n },\n })\n\n try {\n if (tableId) {\n inputs.row = await automationUtils.cleanUpRow(tableId, inputs.row)\n }\n await rowController.patch(ctx)\n return {\n row: ctx.body,\n response: ctx.message,\n id: ctx.body._id,\n revision: ctx.body._rev,\n success: ctx.status === 200,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import { destroy } from \"../../api/controllers/row\"\nimport { buildCtx } from \"./utils\"\nimport { getError } from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n AutomationIOType,\n AutomationCustomIOType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n description: \"Delete a row from your database\",\n icon: \"TableRowRemoveCenter\",\n name: \"Delete Row\",\n tagline: \"Delete a {{inputs.enriched.table.name}} row\",\n type: AutomationStepType.ACTION,\n stepId: AutomationActionStepId.DELETE_ROW,\n internal: true,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n title: \"Table\",\n },\n id: {\n type: AutomationIOType.STRING,\n title: \"Row ID\",\n },\n },\n required: [\"tableId\", \"id\"],\n },\n outputs: {\n properties: {\n row: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.ROW,\n description: \"The deleted row\",\n },\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The response from the table\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the deletion was successful\",\n },\n },\n required: [\"row\", \"success\"],\n },\n },\n}\n\nexport async function run({ inputs, appId, emitter }: AutomationStepInput) {\n if (inputs.id == null) {\n return {\n success: false,\n response: {\n message: \"Invalid inputs\",\n },\n }\n }\n\n let ctx: any = buildCtx(appId, emitter, {\n body: {\n _id: inputs.id,\n _rev: inputs.revision,\n },\n params: {\n tableId: inputs.tableId,\n },\n })\n\n try {\n await destroy(ctx)\n return {\n response: ctx.body,\n row: ctx.row,\n success: ctx.status === 200,\n }\n } catch (err) {\n return {\n success: false,\n response: getError(err),\n }\n }\n}\n", "import fetch from \"node-fetch\"\nimport { VM, VMScript } from \"vm2\"\nconst JS_TIMEOUT_MS = 1000\n\nclass ScriptRunner {\n vm: VM\n results: { out: string }\n script: VMScript\n\n constructor(script: string, context: any) {\n const code = `let fn = () => {\\n${script}\\n}; results.out = fn();`\n this.vm = new VM({\n timeout: JS_TIMEOUT_MS,\n })\n this.results = { out: \"\" }\n this.vm.setGlobals(context)\n this.vm.setGlobal(\"fetch\", fetch)\n this.vm.setGlobal(\"results\", this.results)\n this.script = new VMScript(code)\n }\n\n execute() {\n this.vm.run(this.script)\n return this.results.out\n }\n}\n\nexport default ScriptRunner\n", "import ScriptRunner from \"../../utilities/scriptRunner\"\nimport { BBContext } from \"@budibase/types\"\n\nexport async function execute(ctx: BBContext) {\n const { script, context } = ctx.request.body\n const runner = new ScriptRunner(script, context)\n ctx.body = runner.execute()\n}\n\nexport async function save(ctx: BBContext) {\n ctx.throw(501, \"Not currently implemented\")\n}\n", "import * as scriptController from \"../../api/controllers/script\"\nimport { buildCtx } from \"./utils\"\nimport * as automationUtils from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"JS Scripting\",\n tagline: \"Execute JavaScript Code\",\n icon: \"Code\",\n description: \"Run a piece of JavaScript code in your automation\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.EXECUTE_SCRIPT,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n code: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.CODE,\n title: \"Code\",\n },\n },\n required: [\"code\"],\n },\n outputs: {\n properties: {\n value: {\n type: AutomationIOType.STRING,\n description: \"The result of the return statement\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n },\n required: [\"success\"],\n },\n },\n}\n\nexport async function run({\n inputs,\n appId,\n context,\n emitter,\n}: AutomationStepInput) {\n if (inputs.code == null) {\n return {\n success: false,\n response: {\n message: \"Invalid inputs\",\n },\n }\n }\n\n const ctx: any = buildCtx(appId, emitter, {\n body: {\n script: inputs.code,\n context,\n },\n })\n\n try {\n await scriptController.execute(ctx)\n return {\n success: true,\n value: ctx.body,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import { generateQueryID, getQueryParams, isProdAppID } from \"../../../db/utils\"\nimport { BaseQueryVerbs, FieldTypes } from \"../../../constants\"\nimport { Thread, ThreadType } from \"../../../threads\"\nimport { save as saveDatasource } from \"../datasource\"\nimport { RestImporter } from \"./import\"\nimport { invalidateDynamicVariables } from \"../../../threads/utils\"\nimport env from \"../../../environment\"\nimport { quotas } from \"@budibase/pro\"\nimport { events, context, utils, constants } from \"@budibase/backend-core\"\nimport sdk from \"../../../sdk\"\nimport { QueryEvent } from \"../../../threads/definitions\"\n\nconst Runner = new Thread(ThreadType.QUERY, {\n timeoutMs: env.QUERY_THREAD_TIMEOUT || 10000,\n})\n\n// simple function to append \"readable\" to all read queries\nfunction enrichQueries(input: any) {\n const wasArray = Array.isArray(input)\n const queries = wasArray ? input : [input]\n for (let query of queries) {\n if (query.queryVerb === BaseQueryVerbs.READ) {\n query.readable = true\n }\n }\n return wasArray ? queries : queries[0]\n}\n\nexport async function fetch(ctx: any) {\n const db = context.getAppDB()\n\n const body = await db.allDocs(\n getQueryParams(null, {\n include_docs: true,\n })\n )\n\n ctx.body = enrichQueries(body.rows.map((row: any) => row.doc))\n}\n\nconst _import = async (ctx: any) => {\n const body = ctx.request.body\n const data = body.data\n\n const importer = new RestImporter(data)\n await importer.init()\n\n let datasourceId\n if (!body.datasourceId) {\n // construct new datasource\n const info: any = await importer.getInfo()\n let datasource = {\n type: \"datasource\",\n source: \"REST\",\n config: {\n url: info.url,\n defaultHeaders: [],\n rejectUnauthorized: true,\n },\n name: info.name,\n }\n // save the datasource\n const datasourceCtx = { ...ctx }\n datasourceCtx.request.body.datasource = datasource\n await saveDatasource(datasourceCtx)\n datasourceId = datasourceCtx.body.datasource._id\n } else {\n // use existing datasource\n datasourceId = body.datasourceId\n }\n\n const importResult = await importer.importQueries(datasourceId)\n\n ctx.body = {\n ...importResult,\n datasourceId,\n }\n ctx.status = 200\n}\nexport { _import as import }\n\nexport async function save(ctx: any) {\n const db = context.getAppDB()\n const query = ctx.request.body\n\n const datasource = await sdk.datasources.get(query.datasourceId)\n\n let eventFn\n if (!query._id) {\n query._id = generateQueryID(query.datasourceId)\n eventFn = () => events.query.created(datasource, query)\n } else {\n eventFn = () => events.query.updated(datasource, query)\n }\n\n const response = await db.put(query)\n await eventFn()\n query._rev = response.rev\n\n ctx.body = query\n ctx.message = `Query ${query.name} saved successfully.`\n}\n\nexport async function find(ctx: any) {\n const db = context.getAppDB()\n const query = enrichQueries(await db.get(ctx.params.queryId))\n // remove properties that could be dangerous in real app\n if (isProdAppID(ctx.appId)) {\n delete query.fields\n delete query.parameters\n }\n ctx.body = query\n}\n\n//Required to discern between OIDC OAuth config entries\nfunction getOAuthConfigCookieId(ctx: any) {\n if (ctx.user.providerType === constants.Config.OIDC) {\n return utils.getCookie(ctx, constants.Cookie.OIDC_CONFIG)\n }\n}\n\nfunction getAuthConfig(ctx: any) {\n const authCookie = utils.getCookie(ctx, constants.Cookie.Auth)\n let authConfigCtx: any = {}\n authConfigCtx[\"configId\"] = getOAuthConfigCookieId(ctx)\n authConfigCtx[\"sessionId\"] = authCookie ? authCookie.sessionId : null\n return authConfigCtx\n}\n\nexport async function preview(ctx: any) {\n const { datasource, envVars } = await sdk.datasources.getWithEnvVars(\n ctx.request.body.datasourceId\n )\n const query = ctx.request.body\n // preview may not have a queryId as it hasn't been saved, but if it does\n // this stops dynamic variables from calling the same query\n const { fields, parameters, queryVerb, transformer, queryId } = query\n\n const authConfigCtx: any = getAuthConfig(ctx)\n\n try {\n const inputs: QueryEvent = {\n appId: ctx.appId,\n datasource,\n queryVerb,\n fields,\n parameters,\n transformer,\n queryId,\n // have to pass down to the thread runner - can't put into context now\n environmentVariables: envVars,\n ctx: {\n user: ctx.user,\n auth: { ...authConfigCtx },\n },\n }\n const runFn = () => Runner.run(inputs)\n\n const { rows, keys, info, extra } = await quotas.addQuery(runFn, {\n datasourceId: datasource._id,\n })\n const schemaFields: any = {}\n if (rows?.length > 0) {\n for (let key of [...new Set(keys)] as string[]) {\n const field = rows[0][key]\n let type = typeof field,\n fieldType = FieldTypes.STRING\n if (field)\n switch (type) {\n case \"boolean\":\n schemaFields[key] = FieldTypes.BOOLEAN\n break\n case \"object\":\n if (field instanceof Date) {\n fieldType = FieldTypes.DATETIME\n } else if (Array.isArray(field)) {\n fieldType = FieldTypes.ARRAY\n } else {\n fieldType = FieldTypes.JSON\n }\n break\n case \"number\":\n fieldType = FieldTypes.NUMBER\n break\n }\n schemaFields[key] = fieldType\n }\n }\n // remove configuration before sending event\n delete datasource.config\n await events.query.previewed(datasource, query)\n ctx.body = {\n rows,\n schemaFields,\n info,\n extra,\n }\n } catch (err) {\n ctx.throw(400, err)\n }\n}\n\nasync function execute(\n ctx: any,\n opts: any = { rowsOnly: false, isAutomation: false }\n) {\n const db = context.getAppDB()\n\n const query = await db.get(ctx.params.queryId)\n const { datasource, envVars } = await sdk.datasources.getWithEnvVars(\n query.datasourceId\n )\n\n let authConfigCtx: any = {}\n if (!opts.isAutomation) {\n authConfigCtx = getAuthConfig(ctx)\n }\n const enrichedParameters = ctx.request.body.parameters || {}\n // make sure parameters are fully enriched with defaults\n if (query && query.parameters) {\n for (let parameter of query.parameters) {\n if (!enrichedParameters[parameter.name]) {\n enrichedParameters[parameter.name] = parameter.default\n }\n }\n }\n\n // call the relevant CRUD method on the integration class\n try {\n const inputs: QueryEvent = {\n appId: ctx.appId,\n datasource,\n queryVerb: query.queryVerb,\n fields: query.fields,\n pagination: ctx.request.body.pagination,\n parameters: enrichedParameters,\n transformer: query.transformer,\n queryId: ctx.params.queryId,\n // have to pass down to the thread runner - can't put into context now\n environmentVariables: envVars,\n ctx: {\n user: ctx.user,\n auth: { ...authConfigCtx },\n },\n }\n const runFn = () => Runner.run(inputs)\n\n const { rows, pagination, extra, info } = await quotas.addQuery(runFn, {\n datasourceId: datasource._id,\n })\n // remove the raw from execution incase transformer being used to hide data\n if (extra?.raw) {\n delete extra.raw\n }\n if (opts && opts.rowsOnly) {\n ctx.body = rows\n } else {\n ctx.body = { data: rows, pagination, ...extra, ...info }\n }\n } catch (err) {\n ctx.throw(400, err)\n }\n}\n\nexport async function executeV1(ctx: any) {\n return execute(ctx, { rowsOnly: true, isAutomation: false })\n}\n\nexport async function executeV2(\n ctx: any,\n { isAutomation }: { isAutomation?: boolean } = {}\n) {\n return execute(ctx, { rowsOnly: false, isAutomation })\n}\n\nconst removeDynamicVariables = async (queryId: any) => {\n const db = context.getAppDB()\n const query = await db.get(queryId)\n const datasource = await sdk.datasources.get(query.datasourceId)\n const dynamicVariables = datasource.config?.dynamicVariables as any[]\n\n if (dynamicVariables) {\n // delete dynamic variables from the datasource\n datasource.config!.dynamicVariables = dynamicVariables!.filter(\n (dv: any) => dv.queryId !== queryId\n )\n await db.put(datasource)\n\n // invalidate the deleted variables\n const variablesToDelete = dynamicVariables!.filter(\n (dv: any) => dv.queryId === queryId\n )\n await invalidateDynamicVariables(variablesToDelete)\n }\n}\n\nexport async function destroy(ctx: any) {\n const db = context.getAppDB()\n const queryId = ctx.params.queryId\n await removeDynamicVariables(queryId)\n const query = await db.get(queryId)\n const datasource = await sdk.datasources.get(query.datasourceId)\n await db.remove(ctx.params.queryId, ctx.params.revId)\n ctx.message = `Query deleted.`\n ctx.status = 200\n await events.query.deleted(datasource, query)\n}\n", "import {\n generateDatasourceID,\n getDatasourceParams,\n getQueryParams,\n DocumentType,\n BudibaseInternalDB,\n getTableParams,\n} from \"../../db/utils\"\nimport { destroy as tableDestroy } from \"./table/internal\"\nimport { BuildSchemaErrors, InvalidColumns } from \"../../constants\"\nimport { getIntegration } from \"../../integrations\"\nimport { getDatasourceAndQuery } from \"./row/utils\"\nimport { invalidateDynamicVariables } from \"../../threads/utils\"\nimport { db as dbCore, context, events } from \"@budibase/backend-core\"\nimport {\n UserCtx,\n Datasource,\n Row,\n CreateDatasourceResponse,\n UpdateDatasourceResponse,\n CreateDatasourceRequest,\n VerifyDatasourceRequest,\n VerifyDatasourceResponse,\n FetchDatasourceInfoResponse,\n IntegrationBase,\n DatasourcePlus,\n} from \"@budibase/types\"\nimport sdk from \"../../sdk\"\n\nfunction getErrorTables(errors: any, errorType: string) {\n return Object.entries(errors)\n .filter(entry => entry[1] === errorType)\n .map(([name]) => name)\n}\n\nfunction updateError(error: any, newError: any, tables: string[]) {\n if (!error) {\n error = \"\"\n }\n if (error.length > 0) {\n error += \"\\n\"\n }\n error += `${newError} ${tables.join(\", \")}`\n return error\n}\n\nasync function getConnector(\n datasource: Datasource\n): Promise<IntegrationBase | DatasourcePlus> {\n const Connector = await getIntegration(datasource.source)\n // can't enrich if it doesn't have an ID yet\n if (datasource._id) {\n datasource = await sdk.datasources.enrich(datasource)\n }\n // Connect to the DB and build the schema\n return new Connector(datasource.config)\n}\n\nasync function buildSchemaHelper(datasource: Datasource) {\n const connector = (await getConnector(datasource)) as DatasourcePlus\n await connector.buildSchema(datasource._id!, datasource.entities!)\n\n const errors = connector.schemaErrors\n let error = null\n if (errors && Object.keys(errors).length > 0) {\n const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY)\n const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN)\n if (noKey.length) {\n error = updateError(\n error,\n \"No primary key constraint found for the following:\",\n noKey\n )\n }\n if (invalidCol.length) {\n const invalidCols = Object.values(InvalidColumns).join(\", \")\n error = updateError(\n error,\n `Cannot use columns ${invalidCols} found in following:`,\n invalidCol\n )\n }\n }\n return { tables: connector.tables, error }\n}\n\nexport async function fetch(ctx: UserCtx) {\n // Get internal tables\n const db = context.getAppDB()\n const internalTables = await db.allDocs(\n getTableParams(null, {\n include_docs: true,\n })\n )\n\n const internal = internalTables.rows.reduce((acc: any, row: Row) => {\n const sourceId = row.doc.sourceId || \"bb_internal\"\n acc[sourceId] = acc[sourceId] || []\n acc[sourceId].push(row.doc)\n return acc\n }, {})\n\n const bbInternalDb = {\n ...BudibaseInternalDB,\n }\n\n // Get external datasources\n const datasources = (\n await db.allDocs(\n getDatasourceParams(null, {\n include_docs: true,\n })\n )\n ).rows.map(row => row.doc)\n\n const allDatasources: Datasource[] = await sdk.datasources.removeSecrets([\n bbInternalDb,\n ...datasources,\n ])\n\n for (let datasource of allDatasources) {\n if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {\n datasource.entities = internal[datasource._id!]\n }\n }\n\n ctx.body = [bbInternalDb, ...datasources]\n}\n\nexport async function verify(\n ctx: UserCtx<VerifyDatasourceRequest, VerifyDatasourceResponse>\n) {\n const { datasource } = ctx.request.body\n let existingDatasource: undefined | Datasource\n if (datasource._id) {\n existingDatasource = await sdk.datasources.get(datasource._id)\n }\n let enrichedDatasource = datasource\n if (existingDatasource) {\n enrichedDatasource = sdk.datasources.mergeConfigs(\n datasource,\n existingDatasource\n )\n }\n const connector = await getConnector(enrichedDatasource)\n if (!connector.testConnection) {\n ctx.throw(400, \"Connection information verification not supported\")\n }\n const response = await connector.testConnection()\n\n ctx.body = {\n connected: response.connected,\n error: response.error,\n }\n}\n\nexport async function information(\n ctx: UserCtx<void, FetchDatasourceInfoResponse>\n) {\n const datasourceId = ctx.params.datasourceId\n const datasource = await sdk.datasources.get(datasourceId, { enriched: true })\n const connector = (await getConnector(datasource)) as DatasourcePlus\n if (!connector.getTableNames) {\n ctx.throw(400, \"Table name fetching not supported by datasource\")\n }\n const tableNames = await connector.getTableNames()\n ctx.body = {\n tableNames,\n }\n}\n\nexport async function buildSchemaFromDb(ctx: UserCtx) {\n const db = context.getAppDB()\n const datasource = await sdk.datasources.get(ctx.params.datasourceId)\n const tablesFilter = ctx.request.body.tablesFilter\n\n let { tables, error } = await buildSchemaHelper(datasource)\n if (tablesFilter) {\n if (!datasource.entities) {\n datasource.entities = {}\n }\n for (let key in tables) {\n if (\n tablesFilter.some(\n (filter: any) => filter.toLowerCase() === key.toLowerCase()\n )\n ) {\n datasource.entities[key] = tables[key]\n }\n }\n } else {\n datasource.entities = tables\n }\n\n setDefaultDisplayColumns(datasource)\n const dbResp = await db.put(datasource)\n datasource._rev = dbResp.rev\n const cleanedDatasource = await sdk.datasources.removeSecretSingle(datasource)\n\n const response: any = { datasource: cleanedDatasource }\n if (error) {\n response.error = error\n }\n ctx.body = response\n}\n\n/**\n * Make sure all datasource entities have a display name selected\n */\nfunction setDefaultDisplayColumns(datasource: Datasource) {\n //\n for (let entity of Object.values(datasource.entities || {})) {\n if (entity.primaryDisplay) {\n continue\n }\n const notAutoColumn = Object.values(entity.schema).find(\n schema => !schema.autocolumn\n )\n if (notAutoColumn) {\n entity.primaryDisplay = notAutoColumn.name\n }\n }\n}\n\n/**\n * Check for variables that have been updated or removed and invalidate them.\n */\nasync function invalidateVariables(\n existingDatasource: Datasource,\n updatedDatasource: Datasource\n) {\n const existingVariables: any = existingDatasource.config?.dynamicVariables\n const updatedVariables: any = updatedDatasource.config?.dynamicVariables\n const toInvalidate = []\n\n if (!existingVariables) {\n return\n }\n\n if (!updatedVariables) {\n // invalidate all\n toInvalidate.push(...existingVariables)\n } else {\n // invaldate changed / removed\n existingVariables.forEach((existing: any) => {\n const unchanged = updatedVariables.find(\n (updated: any) =>\n existing.name === updated.name &&\n existing.queryId === updated.queryId &&\n existing.value === updated.value\n )\n if (!unchanged) {\n toInvalidate.push(existing)\n }\n })\n }\n await invalidateDynamicVariables(toInvalidate)\n}\n\nexport async function update(ctx: UserCtx<any, UpdateDatasourceResponse>) {\n const db = context.getAppDB()\n const datasourceId = ctx.params.datasourceId\n let datasource = await sdk.datasources.get(datasourceId)\n const auth = datasource.config?.auth\n await invalidateVariables(datasource, ctx.request.body)\n\n const isBudibaseSource = datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE\n\n const dataSourceBody = isBudibaseSource\n ? { name: ctx.request.body?.name }\n : ctx.request.body\n\n datasource = {\n ...datasource,\n ...sdk.datasources.mergeConfigs(dataSourceBody, datasource),\n }\n if (auth && !ctx.request.body.auth) {\n // don't strip auth config from DB\n datasource.config!.auth = auth\n }\n\n const response = await db.put(datasource)\n await events.datasource.updated(datasource)\n datasource._rev = response.rev\n\n // Drain connection pools when configuration is changed\n if (datasource.source && !isBudibaseSource) {\n const source = await getIntegration(datasource.source)\n if (source && source.pool) {\n await source.pool.end()\n }\n }\n\n ctx.status = 200\n ctx.message = \"Datasource saved successfully.\"\n ctx.body = {\n datasource: await sdk.datasources.removeSecretSingle(datasource),\n }\n}\n\nexport async function save(\n ctx: UserCtx<CreateDatasourceRequest, CreateDatasourceResponse>\n) {\n const db = context.getAppDB()\n const plus = ctx.request.body.datasource.plus\n const fetchSchema = ctx.request.body.fetchSchema\n\n const datasource = {\n _id: generateDatasourceID({ plus }),\n ...ctx.request.body.datasource,\n type: plus ? DocumentType.DATASOURCE_PLUS : DocumentType.DATASOURCE,\n }\n\n let schemaError = null\n if (fetchSchema) {\n const { tables, error } = await buildSchemaHelper(datasource)\n schemaError = error\n datasource.entities = tables\n setDefaultDisplayColumns(datasource)\n }\n\n const dbResp = await db.put(datasource)\n await events.datasource.created(datasource)\n datasource._rev = dbResp.rev\n\n // Drain connection pools when configuration is changed\n if (datasource.source) {\n const source = await getIntegration(datasource.source)\n if (source && source.pool) {\n await source.pool.end()\n }\n }\n\n const response: CreateDatasourceResponse = {\n datasource: await sdk.datasources.removeSecretSingle(datasource),\n }\n if (schemaError) {\n response.error = schemaError\n }\n ctx.body = response\n}\n\nasync function destroyInternalTablesBySourceId(datasourceId: string) {\n const db = context.getAppDB()\n\n // Get all internal tables\n const internalTables = await db.allDocs(\n getTableParams(null, {\n include_docs: true,\n })\n )\n\n // Filter by datasource and return the docs.\n const datasourceTableDocs = internalTables.rows.reduce(\n (acc: any, table: any) => {\n if (table.doc.sourceId == datasourceId) {\n acc.push(table.doc)\n }\n return acc\n },\n []\n )\n\n // Destroy the tables.\n for (const table of datasourceTableDocs) {\n await tableDestroy({\n params: {\n tableId: table._id,\n },\n })\n }\n}\n\nexport async function destroy(ctx: UserCtx) {\n const db = context.getAppDB()\n const datasourceId = ctx.params.datasourceId\n\n const datasource = await sdk.datasources.get(datasourceId)\n // Delete all queries for the datasource\n\n if (datasource.type === dbCore.BUDIBASE_DATASOURCE_TYPE) {\n await destroyInternalTablesBySourceId(datasourceId)\n } else {\n const queries = await db.allDocs(getQueryParams(datasourceId, null))\n await db.bulkDocs(\n queries.rows.map((row: any) => ({\n _id: row.id,\n _rev: row.value.rev,\n _deleted: true,\n }))\n )\n }\n\n // delete the datasource\n await db.remove(datasourceId, ctx.params.revId)\n await events.datasource.deleted(datasource)\n\n ctx.message = `Datasource deleted.`\n ctx.status = 200\n}\n\nexport async function find(ctx: UserCtx) {\n const database = context.getAppDB()\n const datasource = await database.get(ctx.params.datasourceId)\n ctx.body = await sdk.datasources.removeSecretSingle(datasource)\n}\n\n// dynamic query functionality\nexport async function query(ctx: UserCtx) {\n const queryJson = ctx.request.body\n try {\n ctx.body = await getDatasourceAndQuery(queryJson)\n } catch (err: any) {\n ctx.throw(400, err)\n }\n}\n", "import { updateLinks, EventType } from \"../../../db/linkedRows\"\nimport { getRowParams, generateTableID } from \"../../../db/utils\"\nimport { FieldTypes } from \"../../../constants\"\nimport { TableSaveFunctions, hasTypeChanged, handleDataImport } from \"./utils\"\nimport { context } from \"@budibase/backend-core\"\nimport env from \"../../../environment\"\nimport {\n cleanupAttachments,\n fixAutoColumnSubType,\n} from \"../../../utilities/rowProcessor\"\nimport { runStaticFormulaChecks } from \"./bulkFormula\"\nimport { Table } from \"@budibase/types\"\nimport { quotas } from \"@budibase/pro\"\nimport { isEqual } from \"lodash\"\nimport { cloneDeep } from \"lodash/fp\"\nimport sdk from \"../../../sdk\"\n\nfunction checkAutoColumns(table: Table, oldTable: Table) {\n if (!table.schema) {\n return table\n }\n for (let [key, schema] of Object.entries(table.schema)) {\n if (!schema.autocolumn || schema.subtype) {\n continue\n }\n const oldSchema = oldTable && oldTable.schema[key]\n if (oldSchema && oldSchema.subtype) {\n table.schema[key].subtype = oldSchema.subtype\n } else {\n table.schema[key] = fixAutoColumnSubType(schema)\n }\n }\n return table\n}\n\nexport async function save(ctx: any) {\n const db = context.getAppDB()\n const { rows, ...rest } = ctx.request.body\n let tableToSave = {\n type: \"table\",\n _id: generateTableID(),\n views: {},\n ...rest,\n }\n\n // if the table obj had an _id then it will have been retrieved\n let oldTable\n if (ctx.request.body && ctx.request.body._id) {\n oldTable = await db.get(ctx.request.body._id)\n }\n\n // check all types are correct\n if (hasTypeChanged(tableToSave, oldTable)) {\n ctx.throw(400, \"A column type has changed.\")\n }\n // check that subtypes have been maintained\n tableToSave = checkAutoColumns(tableToSave, oldTable)\n\n // saving a table is a complex operation, involving many different steps, this\n // has been broken out into a utility to make it more obvious/easier to manipulate\n const tableSaveFunctions = new TableSaveFunctions({\n user: ctx.user,\n oldTable,\n importRows: rows,\n })\n tableToSave = await tableSaveFunctions.before(tableToSave)\n\n // make sure that types don't change of a column, have to remove\n // the column if you want to change the type\n if (oldTable && oldTable.schema) {\n for (let propKey of Object.keys(tableToSave.schema)) {\n let oldColumn = oldTable.schema[propKey]\n if (oldColumn && oldColumn.type === \"internal\") {\n oldColumn.type = \"auto\"\n }\n }\n }\n\n // Don't rename if the name is the same\n let { _rename } = tableToSave\n /* istanbul ignore next */\n if (_rename && _rename.old === _rename.updated) {\n _rename = null\n delete tableToSave._rename\n }\n\n // rename row fields when table column is renamed\n /* istanbul ignore next */\n if (_rename && tableToSave.schema[_rename.updated].type === FieldTypes.LINK) {\n ctx.throw(400, \"Cannot rename a linked column.\")\n }\n\n tableToSave = await tableSaveFunctions.mid(tableToSave)\n\n // update schema of non-statistics views when new columns are added\n for (let view in tableToSave.views) {\n const tableView = tableToSave.views[view]\n if (!tableView) continue\n\n if (tableView.schema.group || tableView.schema.field) continue\n tableView.schema = tableToSave.schema\n }\n\n // update linked rows\n try {\n const linkResp: any = await updateLinks({\n eventType: oldTable ? EventType.TABLE_UPDATED : EventType.TABLE_SAVE,\n table: tableToSave,\n oldTable: oldTable,\n })\n if (linkResp != null && linkResp._rev) {\n tableToSave._rev = linkResp._rev\n }\n } catch (err) {\n ctx.throw(400, err)\n }\n\n // don't perform any updates until relationships have been\n // checked by the updateLinks function\n const updatedRows = tableSaveFunctions.getUpdatedRows()\n if (updatedRows && updatedRows.length !== 0) {\n await db.bulkDocs(updatedRows)\n }\n let result = await db.put(tableToSave)\n tableToSave._rev = result.rev\n const savedTable = cloneDeep(tableToSave)\n\n tableToSave = await tableSaveFunctions.after(tableToSave)\n // the table may be updated as part of the table save after functionality - need to write it\n if (!isEqual(savedTable, tableToSave)) {\n result = await db.put(tableToSave)\n tableToSave._rev = result.rev\n }\n // has to run after, make sure it has _id\n await runStaticFormulaChecks(tableToSave, { oldTable, deletion: false })\n return tableToSave\n}\n\nexport async function destroy(ctx: any) {\n const db = context.getAppDB()\n const tableToDelete = await db.get(ctx.params.tableId)\n\n // Delete all rows for that table\n const rowsData = await db.allDocs(\n getRowParams(ctx.params.tableId, null, {\n include_docs: true,\n })\n )\n await db.bulkDocs(\n rowsData.rows.map((row: any) => ({ ...row.doc, _deleted: true }))\n )\n await quotas.removeRows(rowsData.rows.length, {\n tableId: ctx.params.tableId,\n })\n\n // update linked rows\n await updateLinks({\n eventType: EventType.TABLE_DELETE,\n table: tableToDelete,\n })\n\n // don't remove the table itself until very end\n await db.remove(tableToDelete._id, tableToDelete._rev)\n\n // remove table search index\n if (!env.isTest() || env.COUCH_DB_URL) {\n const currentIndexes = await db.getIndexes()\n const existingIndex = currentIndexes.indexes.find(\n (existing: any) => existing.name === `search:${ctx.params.tableId}`\n )\n if (existingIndex) {\n await db.deleteIndex(existingIndex)\n }\n }\n\n // has to run after, make sure it has _id\n await runStaticFormulaChecks(tableToDelete, {\n deletion: true,\n })\n await cleanupAttachments(tableToDelete, {\n rows: rowsData.rows.map((row: any) => row.doc),\n })\n return tableToDelete\n}\n\nexport async function bulkImport(ctx: any) {\n const db = context.getAppDB()\n const table = await sdk.tables.getTable(ctx.params.tableId)\n const { rows, identifierFields } = ctx.request.body\n await handleDataImport(ctx.user, table, rows, identifierFields)\n return table\n}\n", "import { FieldTypes } from \"../constants\"\n\ninterface SchemaColumn {\n readonly name: string\n readonly type: FieldTypes\n readonly autocolumn?: boolean\n readonly constraints?: {\n presence: boolean\n }\n}\n\ninterface Schema {\n readonly [index: string]: SchemaColumn\n}\n\ninterface Row {\n [index: string]: any\n}\n\ntype Rows = Array<Row>\n\ninterface SchemaValidation {\n [index: string]: boolean\n}\n\ninterface ValidationResults {\n schemaValidation: SchemaValidation\n allValid: boolean\n invalidColumns: Array<string>\n}\n\nconst PARSERS: any = {\n [FieldTypes.NUMBER]: (attribute?: string) => {\n if (!attribute) {\n return attribute\n }\n return Number(attribute)\n },\n [FieldTypes.DATETIME]: (attribute?: string) => {\n if (!attribute) {\n return attribute\n }\n return new Date(attribute).toISOString()\n },\n}\n\nexport function isSchema(schema: any): schema is Schema {\n return (\n typeof schema === \"object\" &&\n Object.values(schema).every(rawColumn => {\n const column = rawColumn as SchemaColumn\n\n return (\n column !== null &&\n typeof column === \"object\" &&\n typeof column.type === \"string\" &&\n Object.values(FieldTypes).includes(column.type as FieldTypes)\n )\n })\n )\n}\n\nexport function isRows(rows: any): rows is Rows {\n return Array.isArray(rows) && rows.every(row => typeof row === \"object\")\n}\n\nexport function validate(rows: Rows, schema: Schema): ValidationResults {\n const results: ValidationResults = {\n schemaValidation: {},\n allValid: false,\n invalidColumns: [],\n }\n\n rows.forEach(row => {\n Object.entries(row).forEach(([columnName, columnData]) => {\n const columnType = schema[columnName]?.type\n const isAutoColumn = schema[columnName]?.autocolumn\n\n // If the columnType is not a string, then it's not present in the schema, and should be added to the invalid columns array\n if (typeof columnType !== \"string\") {\n results.invalidColumns.push(columnName)\n } else if (\n columnData == null &&\n !schema[columnName].constraints?.presence\n ) {\n results.schemaValidation[columnName] = true\n } else if (\n // If there's no data for this field don't bother with further checks\n // If the field is already marked as invalid there's no need for further checks\n results.schemaValidation[columnName] === false ||\n columnData == null ||\n isAutoColumn\n ) {\n return\n } else if (\n columnType === FieldTypes.NUMBER &&\n isNaN(Number(columnData))\n ) {\n // If provided must be a valid number\n results.schemaValidation[columnName] = false\n } else if (\n // If provided must be a valid date\n columnType === FieldTypes.DATETIME &&\n isNaN(new Date(columnData).getTime())\n ) {\n results.schemaValidation[columnName] = false\n } else {\n results.schemaValidation[columnName] = true\n }\n })\n })\n\n results.allValid =\n Object.values(results.schemaValidation).length > 0 &&\n Object.values(results.schemaValidation).every(column => column)\n\n // Select unique values\n results.invalidColumns = [...new Set(results.invalidColumns)]\n return results\n}\n\nexport function parse(rows: Rows, schema: Schema): Rows {\n return rows.map(row => {\n const parsedRow: Row = {}\n\n Object.entries(row).forEach(([columnName, columnData]) => {\n if (!(columnName in schema) || schema[columnName]?.autocolumn) {\n // Objects can be present in the row data but not in the schema, so make sure we don't proceed in such a case\n return\n }\n\n const columnType = schema[columnName].type\n\n if (columnType === FieldTypes.NUMBER) {\n // If provided must be a valid number\n parsedRow[columnName] = columnData ? Number(columnData) : columnData\n } else if (columnType === FieldTypes.DATETIME) {\n // If provided must be a valid date\n parsedRow[columnName] = columnData\n ? new Date(columnData).toISOString()\n : columnData\n } else {\n parsedRow[columnName] = columnData\n }\n })\n\n return parsedRow\n })\n}\n", "import { parse, isSchema, isRows } from \"../../../utilities/schema\"\nimport { getRowParams, generateRowID, InternalTables } from \"../../../db/utils\"\nimport { isEqual } from \"lodash\"\nimport {\n AutoFieldSubTypes,\n FieldTypes,\n GOOGLE_SHEETS_PRIMARY_KEY,\n} from \"../../../constants\"\nimport {\n inputProcessing,\n cleanupAttachments,\n} from \"../../../utilities/rowProcessor\"\nimport {\n USERS_TABLE_SCHEMA,\n SwitchableTypes,\n CanSwitchTypes,\n} from \"../../../constants\"\nimport { getViews, saveView } from \"../view/utils\"\nimport viewTemplate from \"../view/viewBuilder\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { quotas } from \"@budibase/pro\"\nimport { events, context } from \"@budibase/backend-core\"\nimport {\n ContextUser,\n Database,\n Datasource,\n SourceName,\n Table,\n} from \"@budibase/types\"\n\nexport async function clearColumns(table: any, columnNames: any) {\n const db: Database = context.getAppDB()\n const rows = await db.allDocs(\n getRowParams(table._id, null, {\n include_docs: true,\n })\n )\n return (await db.bulkDocs(\n rows.rows.map(({ doc }: any) => {\n columnNames.forEach((colName: any) => delete doc[colName])\n return doc\n })\n )) as { id: string; _rev?: string }[]\n}\n\nexport async function checkForColumnUpdates(oldTable: any, updatedTable: any) {\n const db = context.getAppDB()\n let updatedRows = []\n const rename = updatedTable._rename\n let deletedColumns: any = []\n if (oldTable && oldTable.schema && updatedTable.schema) {\n deletedColumns = Object.keys(oldTable.schema).filter(\n colName => updatedTable.schema[colName] == null\n )\n }\n // check for renaming of columns or deleted columns\n if (rename || deletedColumns.length !== 0) {\n // Update all rows\n const rows = await db.allDocs(\n getRowParams(updatedTable._id, null, {\n include_docs: true,\n })\n )\n const rawRows = rows.rows.map(({ doc }: any) => doc)\n updatedRows = rawRows.map((row: any) => {\n row = cloneDeep(row)\n if (rename) {\n row[rename.updated] = row[rename.old]\n delete row[rename.old]\n } else if (deletedColumns.length !== 0) {\n deletedColumns.forEach((colName: any) => delete row[colName])\n }\n return row\n })\n\n // cleanup any attachments from object storage for deleted attachment columns\n await cleanupAttachments(updatedTable, { oldTable, rows: rawRows })\n // Update views\n await checkForViewUpdates(updatedTable, rename, deletedColumns)\n delete updatedTable._rename\n }\n return { rows: updatedRows, table: updatedTable }\n}\n\n// makes sure the passed in table isn't going to reset the auto ID\nexport function makeSureTableUpToDate(table: any, tableToSave: any) {\n if (!table) {\n return tableToSave\n }\n // sure sure rev is up to date\n tableToSave._rev = table._rev\n // make sure auto IDs are always updated - these are internal\n // so the client may not know they have changed\n let field: any\n let column: any\n for ([field, column] of Object.entries(table.schema)) {\n if (\n column.autocolumn &&\n column.subtype === AutoFieldSubTypes.AUTO_ID &&\n tableToSave.schema[field]\n ) {\n tableToSave.schema[field].lastID = column.lastID\n }\n }\n return tableToSave\n}\n\nexport function importToRows(\n data: any[],\n table: Table,\n user: ContextUser | null = null\n) {\n let originalTable = table\n let finalData: any = []\n for (let i = 0; i < data.length; i++) {\n let row = data[i]\n row._id = generateRowID(table._id!)\n row.tableId = table._id\n\n // We use a reference to table here and update it after input processing,\n // so that we can auto increment auto IDs in imported data properly\n const processed = inputProcessing(user, table, row, {\n noAutoRelationships: true,\n })\n row = processed.row\n table = processed.table\n\n // However here we must reference the original table, as we want to mutate\n // the real schema of the table passed in, not the clone used for\n // incrementing auto IDs\n for (const [fieldName, schema] of Object.entries(originalTable.schema)) {\n const rowVal = Array.isArray(row[fieldName])\n ? row[fieldName]\n : [row[fieldName]]\n if (\n (schema.type === FieldTypes.OPTIONS ||\n schema.type === FieldTypes.ARRAY) &&\n row[fieldName]\n ) {\n let merged = [...schema.constraints!.inclusion!, ...rowVal]\n let superSet = new Set(merged)\n schema.constraints!.inclusion = Array.from(superSet)\n schema.constraints!.inclusion.sort()\n }\n }\n\n finalData.push(row)\n }\n return finalData\n}\n\nexport async function handleDataImport(\n user: any,\n table: any,\n rows: any,\n identifierFields: Array<string> = []\n) {\n const schema: unknown = table.schema\n\n if (!rows || !isRows(rows) || !isSchema(schema)) {\n return table\n }\n\n const db = context.getAppDB()\n const data = parse(rows, schema)\n\n let finalData: any = importToRows(data, table, user)\n\n //Set IDs of finalData to match existing row if an update is expected\n if (identifierFields.length > 0) {\n const allDocs = await db.allDocs(\n getRowParams(table._id, null, {\n include_docs: true,\n })\n )\n allDocs.rows\n .map(existingRow => existingRow.doc)\n .forEach((doc: any) => {\n finalData.forEach((finalItem: any) => {\n let match = true\n for (const field of identifierFields) {\n if (finalItem[field] !== doc[field]) {\n match = false\n break\n }\n }\n if (match) {\n finalItem._id = doc._id\n finalItem._rev = doc._rev\n }\n })\n })\n }\n\n await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {\n tableId: table._id,\n })\n\n await events.rows.imported(table, finalData.length)\n return table\n}\n\nexport async function handleSearchIndexes(table: any) {\n const db = context.getAppDB()\n // create relevant search indexes\n if (table.indexes && table.indexes.length > 0) {\n const currentIndexes = await db.getIndexes()\n const indexName = `search:${table._id}`\n\n const existingIndex = currentIndexes.indexes.find(\n (existing: any) => existing.name === indexName\n )\n\n if (existingIndex) {\n const currentFields = existingIndex.def.fields.map(\n (field: any) => Object.keys(field)[0]\n )\n\n // if index fields have changed, delete the original index\n if (!isEqual(currentFields, table.indexes)) {\n await db.deleteIndex(existingIndex)\n // create/recreate the index with fields\n await db.createIndex({\n index: {\n fields: table.indexes,\n name: indexName,\n ddoc: \"search_ddoc\",\n type: \"json\",\n },\n })\n }\n } else {\n // create/recreate the index with fields\n await db.createIndex({\n index: {\n fields: table.indexes,\n name: indexName,\n ddoc: \"search_ddoc\",\n type: \"json\",\n },\n })\n }\n }\n return table\n}\n\nexport function checkStaticTables(table: any) {\n // check user schema has all required elements\n if (table._id === InternalTables.USER_METADATA) {\n for (let [key, schema] of Object.entries(USERS_TABLE_SCHEMA.schema)) {\n // check if the schema exists on the table to be created/updated\n if (table.schema[key] == null) {\n table.schema[key] = schema\n }\n }\n }\n return table\n}\n\nclass TableSaveFunctions {\n db: any\n user: any\n oldTable: any\n importRows: any\n rows: any\n\n constructor({ user, oldTable, importRows }: any) {\n this.db = context.getAppDB()\n this.user = user\n this.oldTable = oldTable\n this.importRows = importRows\n // any rows that need updated\n this.rows = []\n }\n\n // before anything is done\n async before(table: any) {\n if (this.oldTable) {\n table = makeSureTableUpToDate(this.oldTable, table)\n }\n table = checkStaticTables(table)\n return table\n }\n\n // when confirmed valid\n async mid(table: any) {\n let response = await checkForColumnUpdates(this.oldTable, table)\n this.rows = this.rows.concat(response.rows)\n return table\n }\n\n // after saving\n async after(table: any) {\n table = await handleSearchIndexes(table)\n table = await handleDataImport(this.user, table, this.importRows)\n return table\n }\n\n getUpdatedRows() {\n return this.rows\n }\n}\n\nexport async function checkForViewUpdates(\n table: any,\n rename: any,\n deletedColumns: any\n) {\n const views = await getViews()\n const tableViews = views.filter(view => view.meta.tableId === table._id)\n\n // Check each table view to see if impacted by this table action\n for (let view of tableViews) {\n let needsUpdated = false\n\n // First check for renames, otherwise check for deletions\n if (rename) {\n // Update calculation field if required\n if (view.meta.field === rename.old) {\n view.meta.field = rename.updated\n needsUpdated = true\n }\n\n // Update group by field if required\n if (view.meta.groupBy === rename.old) {\n view.meta.groupBy = rename.updated\n needsUpdated = true\n }\n\n // Update filters if required\n if (view.meta.filters) {\n view.meta.filters.forEach((filter: any) => {\n if (filter.key === rename.old) {\n filter.key = rename.updated\n needsUpdated = true\n }\n })\n }\n } else if (deletedColumns) {\n deletedColumns.forEach((column: any) => {\n // Remove calculation statement if required\n if (view.meta.field === column) {\n delete view.meta.field\n delete view.meta.calculation\n delete view.meta.groupBy\n needsUpdated = true\n }\n\n // Remove group by field if required\n if (view.meta.groupBy === column) {\n delete view.meta.groupBy\n needsUpdated = true\n }\n\n // Remove filters referencing deleted field if required\n if (view.meta.filters && view.meta.filters.length) {\n const initialLength = view.meta.filters.length\n view.meta.filters = view.meta.filters.filter((filter: any) => {\n return filter.key !== column\n })\n if (initialLength !== view.meta.filters.length) {\n needsUpdated = true\n }\n }\n })\n }\n\n // Update view if required\n if (needsUpdated) {\n const groupByField: any = Object.values(table.schema).find(\n (field: any) => field.name == view.groupBy\n )\n const newViewTemplate = viewTemplate(\n view.meta,\n groupByField?.type === FieldTypes.ARRAY\n )\n await saveView(null, view.name, newViewTemplate)\n if (!newViewTemplate.meta.schema) {\n newViewTemplate.meta.schema = table.schema\n }\n table.views[view.name] = newViewTemplate.meta\n }\n }\n}\n\nexport function generateForeignKey(column: any, relatedTable: any) {\n return `fk_${relatedTable.name}_${column.fieldName}`\n}\n\nexport function generateJunctionTableName(\n column: any,\n table: any,\n relatedTable: any\n) {\n return `jt_${table.name}_${relatedTable.name}_${column.name}_${column.fieldName}`\n}\n\nexport function foreignKeyStructure(keyName: any, meta?: any) {\n const structure: any = {\n type: FieldTypes.NUMBER,\n constraints: {},\n name: keyName,\n }\n if (meta) {\n structure.meta = meta\n }\n return structure\n}\n\nexport function areSwitchableTypes(type1: any, type2: any) {\n if (\n SwitchableTypes.indexOf(type1) === -1 &&\n SwitchableTypes.indexOf(type2) === -1\n ) {\n return false\n }\n for (let option of CanSwitchTypes) {\n const index1 = option.indexOf(type1),\n index2 = option.indexOf(type2)\n if (index1 !== -1 && index2 !== -1 && index1 !== index2) {\n return true\n }\n }\n return false\n}\n\nexport function hasTypeChanged(table: any, oldTable: any) {\n if (!oldTable) {\n return false\n }\n let key: any\n let field: any\n for ([key, field] of Object.entries(oldTable.schema)) {\n const oldType = field.type\n if (!table.schema[key]) {\n continue\n }\n const newType = table.schema[key].type\n if (oldType !== newType && !areSwitchableTypes(oldType, newType)) {\n return true\n }\n }\n return false\n}\n\n// used for external tables, some of them will have static schemas that need\n// to be hard set\nexport function setStaticSchemas(datasource: Datasource, table: Table) {\n // GSheets is a specific case - only ever has a static primary key\n if (table && datasource.source === SourceName.GOOGLE_SHEETS) {\n table.primary = [GOOGLE_SHEETS_PRIMARY_KEY]\n // if there is an id column, remove it, should never exist in GSheets\n delete table.schema?.id\n }\n return table\n}\n\nconst _TableSaveFunctions = TableSaveFunctions\nexport { _TableSaveFunctions as TableSaveFunctions }\n", "import { FieldTypes, FormulaTypes } from \"../../../constants\"\nimport { clearColumns } from \"./utils\"\nimport { doesContainStrings } from \"@budibase/string-templates\"\nimport { cloneDeep } from \"lodash/fp\"\nimport { isEqual, uniq } from \"lodash\"\nimport { updateAllFormulasInTable } from \"../row/staticFormula\"\nimport { context } from \"@budibase/backend-core\"\nimport { FieldSchema, Table } from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\n\nfunction isStaticFormula(column: FieldSchema) {\n return (\n column.type === FieldTypes.FORMULA &&\n column.formulaType === FormulaTypes.STATIC\n )\n}\n\n/**\n * This retrieves the formula columns from a table schema that use a specified column name\n * in the formula.\n */\nfunction getFormulaThatUseColumn(table: Table, columnNames: string[] | string) {\n let formula: string[] = []\n columnNames = Array.isArray(columnNames) ? columnNames : [columnNames]\n for (let column of Object.values(table.schema)) {\n // not a static formula, or doesn't contain a relationship\n if (!isStaticFormula(column)) {\n continue\n }\n if (!doesContainStrings(column?.formula ?? \"\", columnNames)) {\n continue\n }\n formula.push(column.name)\n }\n return formula\n}\n\n/**\n * This functions checks for when a related table, column or related column is deleted, if any\n * tables need to have the formula column removed.\n */\nasync function checkIfFormulaNeedsCleared(\n table: Table,\n { oldTable, deletion }: { oldTable?: Table; deletion?: boolean }\n) {\n // start by retrieving all tables, remove the current table from the list\n const tables = (await sdk.tables.getAllInternalTables()).filter(\n tbl => tbl._id !== table._id\n )\n const schemaToUse = oldTable ? oldTable.schema : table.schema\n let removedColumns = Object.values(schemaToUse).filter(\n column => deletion || !table.schema[column.name]\n )\n // remove any formula columns that used related columns\n for (let removed of removedColumns) {\n let tableToUse: Table | undefined = table\n // if relationship, get the related table\n if (removed.type === FieldTypes.LINK) {\n tableToUse = tables.find(table => table._id === removed.tableId)\n }\n if (!tableToUse) {\n continue\n }\n const columnsToDelete = getFormulaThatUseColumn(tableToUse, removed.name)\n if (columnsToDelete.length > 0) {\n await clearColumns(table, columnsToDelete)\n }\n // need a special case, where a column has been removed from this table, but was used\n // in a different, related tables formula\n if (!table.relatedFormula) {\n continue\n }\n for (let relatedTableId of table.relatedFormula) {\n const relatedColumns = Object.values(table.schema).filter(\n column => column.tableId === relatedTableId\n )\n const relatedTable = tables.find(table => table._id === relatedTableId)\n // look to see if the column was used in a relationship formula,\n // relationships won't be used for this\n if (relatedTable && relatedColumns && removed.type !== FieldTypes.LINK) {\n let relatedFormulaToRemove: string[] = []\n for (let column of relatedColumns) {\n relatedFormulaToRemove = relatedFormulaToRemove.concat(\n getFormulaThatUseColumn(relatedTable, [\n column.fieldName!,\n removed.name,\n ])\n )\n }\n if (relatedFormulaToRemove.length > 0) {\n await clearColumns(relatedTable, uniq(relatedFormulaToRemove))\n }\n }\n }\n }\n}\n\n/**\n * This function adds a note to related tables that they are\n * used in a static formula - so that the link controller\n * can manage hydrating related rows formula fields. This is\n * specifically only for static formula.\n */\nasync function updateRelatedFormulaLinksOnTables(\n table: Table,\n { deletion }: { deletion?: boolean } = {}\n) {\n const tableId: string = table._id!\n const db = context.getAppDB()\n // start by retrieving all tables, remove the current table from the list\n const tables = (await sdk.tables.getAllInternalTables()).filter(\n tbl => tbl._id !== tableId\n )\n // clone the tables, so we can compare at end\n const initialTables = cloneDeep(tables)\n // first find the related column names\n const relatedColumns = Object.values(table.schema).filter(\n col => col.type === FieldTypes.LINK\n )\n // we start by removing the formula field from all tables\n for (let otherTable of tables) {\n if (!otherTable.relatedFormula) {\n continue\n }\n const index = otherTable.relatedFormula.indexOf(tableId)\n if (index !== -1) {\n otherTable.relatedFormula.splice(index, 1)\n }\n }\n // if deleting, just remove the table IDs, don't try add\n if (!deletion) {\n for (let relatedCol of relatedColumns) {\n let columns = getFormulaThatUseColumn(table, relatedCol.name)\n if (!columns || columns.length === 0) {\n continue\n }\n const relatedTable = tables.find(\n related => related._id === relatedCol.tableId\n )\n // check if the table is already in the list of related formula, if it isn't, then add it\n if (\n relatedTable &&\n (!relatedTable.relatedFormula ||\n !relatedTable.relatedFormula.includes(tableId))\n ) {\n relatedTable.relatedFormula = relatedTable.relatedFormula\n ? [...relatedTable.relatedFormula, tableId]\n : [tableId]\n }\n }\n }\n // now we just need to compare all the tables and see if any need saved\n for (let initial of initialTables) {\n const found = tables.find(tbl => initial._id === tbl._id)\n if (found && !isEqual(initial, found)) {\n await db.put(found)\n }\n }\n}\n\nasync function checkIfFormulaUpdated(\n table: Table,\n { oldTable }: { oldTable?: Table }\n) {\n // look to see if any formula values have changed\n const shouldUpdate = Object.values(table.schema).find(\n column =>\n isStaticFormula(column) &&\n (!oldTable ||\n !oldTable.schema[column.name] ||\n !isEqual(oldTable.schema[column.name], column))\n )\n // if a static formula column has updated, then need to run the update\n if (shouldUpdate != null) {\n await updateAllFormulasInTable(table)\n }\n}\n\nexport async function runStaticFormulaChecks(\n table: Table,\n { oldTable, deletion }: { oldTable?: Table; deletion?: boolean }\n) {\n await updateRelatedFormulaLinksOnTables(table, { deletion })\n await checkIfFormulaNeedsCleared(table, { oldTable, deletion })\n if (!deletion) {\n await checkIfFormulaUpdated(table, { oldTable })\n }\n}\n", "import { auth } from \"@budibase/backend-core\"\nimport Joi from \"joi\"\n\nconst OPTIONAL_STRING = Joi.string().optional().allow(null).allow(\"\")\n\nexport function queryValidation() {\n return Joi.object({\n _id: Joi.string(),\n _rev: Joi.string(),\n name: Joi.string().required(),\n fields: Joi.object().required(),\n datasourceId: Joi.string().required(),\n readable: Joi.boolean(),\n parameters: Joi.array().items(\n Joi.object({\n name: Joi.string(),\n default: Joi.string().allow(\"\"),\n })\n ),\n queryVerb: Joi.string().allow().required(),\n extra: Joi.object().optional(),\n schema: Joi.object({}).required().unknown(true),\n transformer: OPTIONAL_STRING,\n flags: Joi.object().optional(),\n }).unknown(true)\n}\n\nexport function generateQueryValidation() {\n // prettier-ignore\n return auth.joiValidator.body(queryValidation())\n}\n\nexport function generateQueryPreviewValidation() {\n // prettier-ignore\n return auth.joiValidator.body(Joi.object({\n _id: OPTIONAL_STRING,\n _rev: OPTIONAL_STRING,\n readable: Joi.boolean().optional(),\n fields: Joi.object().required(),\n queryVerb: Joi.string().required(),\n name: OPTIONAL_STRING,\n flags: Joi.object().optional(),\n schema: Joi.object().optional(),\n extra: Joi.object().optional(),\n datasourceId: Joi.string().required(),\n transformer: OPTIONAL_STRING,\n parameters: Joi.object({}).required().unknown(true),\n queryId: OPTIONAL_STRING,\n }).unknown(true))\n}\n", "import { queryValidation } from \"../validation\"\nimport { generateQueryID } from \"../../../../db/utils\"\nimport { ImportInfo, ImportSource } from \"./sources/base\"\nimport { OpenAPI2 } from \"./sources/openapi2\"\nimport { OpenAPI3 } from \"./sources/openapi3\"\nimport { Curl } from \"./sources/curl\"\n// @ts-ignore\nimport { events, context } from \"@budibase/backend-core\"\nimport { Datasource, Query } from \"@budibase/types\"\n\ninterface ImportResult {\n errorQueries: Query[]\n queries: Query[]\n}\n\nexport class RestImporter {\n data: string\n sources: ImportSource[]\n source!: ImportSource\n\n constructor(data: string) {\n this.data = data\n this.sources = [new OpenAPI2(), new OpenAPI3(), new Curl()]\n }\n\n init = async () => {\n for (let source of this.sources) {\n if (await source.isSupported(this.data)) {\n this.source = source\n break\n }\n }\n }\n\n getInfo = async (): Promise<ImportInfo> => {\n return this.source.getInfo()\n }\n\n importQueries = async (datasourceId: string): Promise<ImportResult> => {\n // construct the queries\n let queries = await this.source.getQueries(datasourceId)\n\n // validate queries\n const errorQueries: Query[] = []\n const schema = queryValidation()\n queries = queries\n .filter(query => {\n const validation = schema.validate(query)\n if (validation.error) {\n errorQueries.push(query)\n return false\n }\n return true\n })\n .map(query => {\n query._id = generateQueryID(query.datasourceId)\n return query\n })\n\n // persist queries\n const db = context.getAppDB()\n const response = await db.bulkDocs(queries)\n\n // create index to seperate queries and errors\n const queryIndex = queries.reduce((acc, query) => {\n if (query._id) {\n acc[query._id] = query\n }\n return acc\n }, {} as { [key: string]: Query })\n\n // check for failed writes\n response.forEach((query: any) => {\n if (!query.ok) {\n errorQueries.push(queryIndex[query.id])\n delete queryIndex[query.id]\n }\n })\n\n const successQueries = Object.values(queryIndex)\n\n // events\n const count = successQueries.length\n const importSource = this.source.getImportSource()\n const datasource: Datasource = await db.get(datasourceId)\n await events.query.imported(datasource, importSource, count)\n for (let query of successQueries) {\n await events.query.created(datasource, query)\n }\n\n return {\n errorQueries,\n queries: successQueries,\n }\n }\n}\n", "import { ImportInfo } from \"./base\"\nimport { Query, QueryParameter } from \"@budibase/types\"\nimport { OpenAPIV2 } from \"openapi-types\"\nimport { OpenAPISource } from \"./base/openapi\"\nimport { URL } from \"url\"\n\nconst parameterNotRef = (\n param: OpenAPIV2.Parameter | OpenAPIV2.ReferenceObject\n): param is OpenAPIV2.Parameter => {\n // all refs are deferenced by parser library\n return true\n}\n\nconst isOpenAPI2 = (document: any): document is OpenAPIV2.Document => {\n if (document.swagger === \"2.0\") {\n return true\n } else {\n return false\n }\n}\n\nconst methods: string[] = Object.values(OpenAPIV2.HttpMethods)\n\nconst isOperation = (\n key: string,\n pathItem: any\n): pathItem is OpenAPIV2.OperationObject => {\n return methods.includes(key)\n}\n\nconst isParameter = (\n key: string,\n pathItem: any\n): pathItem is OpenAPIV2.Parameter => {\n return !isOperation(key, pathItem)\n}\n\n/**\n * OpenAPI Version 2.0 - aka \"Swagger\"\n * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md\n */\nexport class OpenAPI2 extends OpenAPISource {\n document!: OpenAPIV2.Document\n\n isSupported = async (data: string): Promise<boolean> => {\n try {\n const document: any = await this.parseData(data)\n if (isOpenAPI2(document)) {\n this.document = document\n return true\n } else {\n return false\n }\n } catch (err) {\n return false\n }\n }\n\n getUrl = (): URL => {\n const scheme = this.document.schemes?.includes(\"https\") ? \"https\" : \"http\"\n const basePath = this.document.basePath || \"\"\n const host = this.document.host || \"<host>\"\n return new URL(`${scheme}://${host}${basePath}`)\n }\n\n getInfo = async (): Promise<ImportInfo> => {\n const name = this.document.info.title || \"Swagger Import\"\n return {\n name,\n }\n }\n\n getImportSource(): string {\n return \"openapi2.0\"\n }\n\n getQueries = async (datasourceId: string): Promise<Query[]> => {\n const url = this.getUrl()\n const queries = []\n\n for (let [path, pathItem] of Object.entries(this.document.paths)) {\n // parameters that apply to every operation in the path\n let pathParams: OpenAPIV2.Parameter[] = []\n\n for (let [key, opOrParams] of Object.entries(pathItem)) {\n if (isParameter(key, opOrParams)) {\n const pathParameters = opOrParams as OpenAPIV2.Parameter[]\n pathParams.push(...pathParameters)\n continue\n }\n // can not be a parameter, must be an operation\n const operation = opOrParams as OpenAPIV2.OperationObject\n\n const methodName = key\n const name = operation.operationId || path\n let queryString = \"\"\n const headers: any = {}\n let requestBody = undefined\n const parameters: QueryParameter[] = []\n\n if (operation.consumes) {\n headers[\"Content-Type\"] = operation.consumes[0]\n }\n\n // combine the path parameters with the operation parameters\n const operationParams = operation.parameters || []\n const allParams = [...pathParams, ...operationParams]\n\n for (let param of allParams) {\n if (parameterNotRef(param)) {\n switch (param.in) {\n case \"query\":\n let prefix = \"\"\n if (queryString) {\n prefix = \"&\"\n }\n queryString = `${queryString}${prefix}${param.name}={{${param.name}}}`\n break\n case \"header\":\n headers[param.name] = `{{${param.name}}}`\n break\n case \"path\":\n // do nothing: param is already in the path\n break\n case \"formData\":\n // future enhancement\n break\n case \"body\":\n // set the request body to the example provided\n // future enhancement: generate an example from the schema\n let bodyParam: OpenAPIV2.InBodyParameterObject =\n param as OpenAPIV2.InBodyParameterObject\n if (param.schema.example) {\n const schema = bodyParam.schema as OpenAPIV2.SchemaObject\n requestBody = schema.example\n }\n break\n }\n\n // add the parameter if it can be bound in our config\n if ([\"query\", \"header\", \"path\"].includes(param.in)) {\n parameters.push({\n name: param.name,\n default: param.default || \"\",\n })\n }\n }\n }\n\n const query = this.constructQuery(\n datasourceId,\n name,\n methodName,\n path,\n url,\n queryString,\n headers,\n parameters,\n requestBody\n )\n queries.push(query)\n }\n }\n\n return queries\n }\n}\n", "import { ImportSource } from \".\"\nimport SwaggerParser from \"@apidevtools/swagger-parser\"\nimport { OpenAPI } from \"openapi-types\"\nconst yaml = require(\"js-yaml\")\n\nexport abstract class OpenAPISource extends ImportSource {\n parseData = async (data: string): Promise<OpenAPI.Document> => {\n let json: OpenAPI.Document\n try {\n json = JSON.parse(data)\n } catch (jsonErr) {\n // couldn't parse json\n // try to convert yaml -> json\n try {\n json = yaml.load(data)\n } catch (yamlErr) {\n // couldn't parse yaml\n throw new Error(\"Could not parse JSON or YAML\")\n }\n }\n\n return SwaggerParser.validate(json, {})\n }\n}\n", "import { ImportInfo } from \"./base\"\nimport { Query, QueryParameter } from \"@budibase/types\"\nimport { OpenAPIV3 } from \"openapi-types\"\nimport { OpenAPISource } from \"./base/openapi\"\nimport { URL } from \"url\"\n\nconst parameterNotRef = (\n param: OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject\n): param is OpenAPIV3.ParameterObject => {\n // all refs are deferenced by parser library\n return true\n}\n\nconst requestBodyNotRef = (\n param: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject | undefined\n): param is OpenAPIV3.RequestBodyObject => {\n // all refs are deferenced by parser library\n return param !== undefined\n}\n\nconst schemaNotRef = (\n param: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined\n): param is OpenAPIV3.SchemaObject => {\n // all refs are deferenced by parser library\n return param !== undefined\n}\n\nconst isOpenAPI3 = (document: any): document is OpenAPIV3.Document => {\n return document.openapi.includes(\"3.0\")\n}\n\nconst methods: string[] = Object.values(OpenAPIV3.HttpMethods)\n\nconst isOperation = (\n key: string,\n pathItem: any\n): pathItem is OpenAPIV3.OperationObject => {\n return methods.includes(key)\n}\n\nconst isParameter = (\n key: string,\n pathItem: any\n): pathItem is OpenAPIV3.ParameterObject => {\n return !isOperation(key, pathItem)\n}\n\nconst getRequestBody = (operation: OpenAPIV3.OperationObject) => {\n if (requestBodyNotRef(operation.requestBody)) {\n const request: OpenAPIV3.RequestBodyObject = operation.requestBody\n const supportedMimeTypes = getMimeTypes(operation)\n if (supportedMimeTypes.length > 0) {\n const mimeType = supportedMimeTypes[0]\n\n // try get example from request\n const content = request.content[mimeType]\n if (content.example) {\n return content.example\n }\n\n // try get example from schema\n if (schemaNotRef(content.schema)) {\n const schema = content.schema\n if (schema.example) {\n return schema.example\n }\n }\n }\n }\n return undefined\n}\n\nconst getMimeTypes = (operation: OpenAPIV3.OperationObject): string[] => {\n if (requestBodyNotRef(operation.requestBody)) {\n const request: OpenAPIV3.RequestBodyObject = operation.requestBody\n return Object.keys(request.content)\n }\n return []\n}\n\n/**\n * OpenAPI Version 3.0\n * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md\n */\nexport class OpenAPI3 extends OpenAPISource {\n document!: OpenAPIV3.Document\n\n isSupported = async (data: string): Promise<boolean> => {\n try {\n const document: any = await this.parseData(data)\n if (isOpenAPI3(document)) {\n this.document = document\n return true\n } else {\n return false\n }\n } catch (err) {\n return false\n }\n }\n\n getInfo = async (): Promise<ImportInfo> => {\n const name = this.document.info.title || \"OpenAPI Import\"\n return {\n name,\n }\n }\n\n getImportSource(): string {\n return \"openapi3.0\"\n }\n\n getQueries = async (datasourceId: string): Promise<Query[]> => {\n let url: string | URL | undefined\n if (this.document.servers?.length) {\n url = this.document.servers[0].url\n try {\n url = new URL(url)\n } catch (err) {\n // unable to construct url, e.g. with variables\n // proceed with string form of url\n }\n }\n\n const queries: Query[] = []\n\n for (let [path, pathItemObject] of Object.entries(this.document.paths)) {\n // parameters that apply to every operation in the path\n let pathParams: OpenAPIV3.ParameterObject[] = []\n\n // pathItemObject can be undefined\n if (!pathItemObject) {\n continue\n }\n\n for (let [key, opOrParams] of Object.entries(pathItemObject)) {\n if (isParameter(key, opOrParams)) {\n const pathParameters = opOrParams as OpenAPIV3.ParameterObject[]\n pathParams.push(...pathParameters)\n continue\n }\n // can not be a parameter, must be an operation\n const operation = opOrParams as OpenAPIV3.OperationObject\n\n const methodName = key\n const name = operation.operationId || path\n let queryString = \"\"\n const headers: any = {}\n let requestBody = getRequestBody(operation)\n const parameters: QueryParameter[] = []\n const mimeTypes = getMimeTypes(operation)\n\n if (mimeTypes.length > 0) {\n headers[\"Content-Type\"] = mimeTypes[0]\n }\n\n // combine the path parameters with the operation parameters\n const operationParams = operation.parameters || []\n const allParams = [...pathParams, ...operationParams]\n\n for (let param of allParams) {\n if (parameterNotRef(param)) {\n switch (param.in) {\n case \"query\":\n let prefix = \"\"\n if (queryString) {\n prefix = \"&\"\n }\n queryString = `${queryString}${prefix}${param.name}={{${param.name}}}`\n break\n case \"header\":\n headers[param.name] = `{{${param.name}}}`\n break\n case \"path\":\n // do nothing: param is already in the path\n break\n case \"formData\":\n // future enhancement\n break\n }\n\n // add the parameter if it can be bound in our config\n if ([\"query\", \"header\", \"path\"].includes(param.in)) {\n parameters.push({\n name: param.name,\n default: \"\",\n })\n }\n }\n }\n\n const query = this.constructQuery(\n datasourceId,\n name,\n methodName,\n path,\n url,\n queryString,\n headers,\n parameters,\n requestBody\n )\n queries.push(query)\n }\n }\n\n return queries\n }\n}\n", "import { ImportSource, ImportInfo } from \"./base\"\nimport { Query } from \"../../../../../definitions/common\"\nimport { URL } from \"url\"\nconst curlconverter = require(\"curlconverter\")\n\nconst parseCurl = (data: string): any => {\n const curlJson = curlconverter.toJsonString(data)\n return JSON.parse(curlJson)\n}\n\n/**\n * The curl converter parses the request body into the key field of an object\n * e.g. --d '{\"key\":\"val\"}' produces an object { \"{\"key\":\"val\"}\" : \"\" }\n * This is not what we want, so we need to parse out the key from the object\n */\nconst parseBody = (curl: any) => {\n if (curl.data) {\n const keys = Object.keys(curl.data)\n if (keys.length) {\n let key = keys[0]\n try {\n // filter out the dollar syntax used by curl for shell support\n if (key.startsWith(\"$\")) {\n key = key.substring(1)\n }\n return JSON.parse(key)\n } catch (e) {\n // do nothing\n }\n }\n }\n return undefined\n}\n\nconst parseCookie = (curl: any) => {\n if (curl.cookies) {\n return Object.entries(curl.cookies).reduce((acc, entry) => {\n const [key, value] = entry\n return acc + `${key}=${value}; `\n }, \"\")\n }\n\n return null\n}\n\n/**\n * Curl\n * https://curl.se/docs/manpage.html\n */\nexport class Curl extends ImportSource {\n curl: any\n\n isSupported = async (data: string): Promise<boolean> => {\n try {\n const curl = parseCurl(data)\n this.curl = curl\n } catch (err) {\n return false\n }\n return true\n }\n\n getUrl = (): URL => {\n return new URL(this.curl.raw_url)\n }\n\n getInfo = async (): Promise<ImportInfo> => {\n const url = this.getUrl()\n return {\n name: url.hostname,\n }\n }\n\n getImportSource(): string {\n return \"curl\"\n }\n\n getQueries = async (datasourceId: string): Promise<Query[]> => {\n const url = this.getUrl()\n const name = url.pathname\n const path = url.origin + url.pathname\n const method = this.curl.method\n const queryString = url.search\n const headers = this.curl.headers\n const requestBody = parseBody(this.curl)\n\n const cookieHeader = parseCookie(this.curl)\n if (cookieHeader) {\n headers[\"Cookie\"] = cookieHeader\n }\n\n const query = this.constructQuery(\n datasourceId,\n name,\n method,\n path,\n undefined,\n queryString,\n headers,\n [],\n requestBody\n )\n\n return [query]\n }\n}\n", "import * as queryController from \"../../api/controllers/query\"\nimport { buildCtx } from \"./utils\"\nimport * as automationUtils from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"External Data Connector\",\n tagline: \"Execute Data Connector\",\n icon: \"Data\",\n description: \"Execute a query in an external data connector\",\n type: AutomationStepType.ACTION,\n stepId: AutomationActionStepId.EXECUTE_QUERY,\n internal: true,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n query: {\n type: AutomationIOType.OBJECT,\n properties: {\n queryId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.QUERY,\n },\n },\n customType: AutomationCustomIOType.QUERY_PARAMS,\n title: \"Parameters\",\n required: [\"queryId\"],\n },\n },\n required: [\"query\"],\n },\n outputs: {\n properties: {\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The response from the datasource execution\",\n },\n info: {\n type: AutomationIOType.OBJECT,\n description:\n \"Some query types may return extra data, like headers from a REST query\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n },\n required: [\"response\", \"success\"],\n },\n },\n}\n\nexport async function run({ inputs, appId, emitter }: AutomationStepInput) {\n if (inputs.query == null) {\n return {\n success: false,\n response: {\n message: \"Invalid inputs\",\n },\n }\n }\n\n const { queryId, ...rest } = inputs.query\n\n const ctx: any = buildCtx(appId, emitter, {\n body: {\n parameters: rest,\n },\n params: {\n queryId,\n },\n })\n\n try {\n await queryController.executeV2(ctx, { isAutomation: true })\n const { data, ...rest } = ctx.body\n\n return {\n response: data,\n info: rest,\n success: true,\n }\n } catch (err) {\n return {\n success: false,\n info: {},\n response: automationUtils.getError(err),\n }\n }\n}\n", "import fetch from \"node-fetch\"\nimport { getFetchResponse } from \"./utils\"\nimport * as automationUtils from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nenum RequestType {\n POST = \"POST\",\n GET = \"GET\",\n PUT = \"PUT\",\n DELETE = \"DELETE\",\n PATCH = \"PATCH\",\n}\n\nconst BODY_REQUESTS = [RequestType.POST, RequestType.PUT, RequestType.PATCH]\n\n/**\n * NOTE: this functionality is deprecated - it no longer should be used.\n */\n\nexport const definition: AutomationStepSchema = {\n deprecated: true,\n name: \"Outgoing webhook\",\n tagline: \"Send a {{inputs.requestMethod}} request\",\n icon: \"Send\",\n description: \"Send a request of specified method to a URL\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.OUTGOING_WEBHOOK,\n inputs: {\n requestMethod: \"POST\",\n url: \"http://\",\n requestBody: \"{}\",\n headers: \"{}\",\n },\n schema: {\n inputs: {\n properties: {\n requestMethod: {\n type: AutomationIOType.STRING,\n enum: Object.values(RequestType),\n title: \"Request method\",\n },\n url: {\n type: AutomationIOType.STRING,\n title: \"URL\",\n },\n requestBody: {\n type: AutomationIOType.STRING,\n title: \"JSON Body\",\n customType: AutomationCustomIOType.WIDE,\n },\n headers: {\n type: AutomationIOType.STRING,\n title: \"Headers\",\n customType: AutomationCustomIOType.WIDE,\n },\n },\n required: [\"requestMethod\", \"url\"],\n },\n outputs: {\n properties: {\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The response from the webhook\",\n },\n httpStatus: {\n type: AutomationIOType.NUMBER,\n description: \"The HTTP status code returned\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n },\n required: [\"response\", \"success\"],\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n let { requestMethod, url, requestBody, headers } = inputs\n if (!url.startsWith(\"http\")) {\n url = `http://${url}`\n }\n const request: any = {\n method: requestMethod,\n }\n if (headers) {\n try {\n const customHeaders =\n typeof headers === \"string\" ? JSON.parse(headers) : headers\n request.headers = { ...request.headers, ...customHeaders }\n } catch (err) {\n return {\n success: false,\n response: \"Unable to process headers, must be a JSON object.\",\n }\n }\n }\n if (\n requestBody &&\n requestBody.length !== 0 &&\n BODY_REQUESTS.indexOf(requestMethod) !== -1\n ) {\n request.body =\n typeof requestBody === \"string\"\n ? requestBody\n : JSON.stringify(requestBody)\n request.headers = {\n ...request.headers,\n \"Content-Type\": \"application/json\",\n }\n }\n\n try {\n // do a quick JSON parse if there is a body, to generate an error if its invalid\n if (request.body) {\n JSON.parse(request.body)\n }\n const response = await fetch(url, request)\n const { status, message } = await getFetchResponse(response)\n return {\n httpStatus: status,\n response: message,\n success: status >= 200 && status <= 206,\n }\n } catch (err) {\n /* istanbul ignore next */\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\n/**\n * Note, there is some functionality in this that is not currently exposed as it\n * is complex and maybe better to be opinionated here.\n * GET/DELETE requests cannot handle body elements so they will not be sent if configured.\n */\n\nexport const definition: AutomationStepSchema = {\n name: \"Backend log\",\n tagline: \"Console log a value in the backend\",\n icon: \"Monitoring\",\n description: \"Logs the given text to the server (using console.log)\",\n type: AutomationStepType.ACTION,\n internal: true,\n stepId: AutomationActionStepId.SERVER_LOG,\n inputs: {\n text: \"\",\n },\n schema: {\n inputs: {\n properties: {\n text: {\n type: AutomationIOType.STRING,\n title: \"Log\",\n },\n },\n required: [\"text\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n message: {\n type: AutomationIOType.STRING,\n description: \"What was output\",\n },\n },\n required: [\"success\", \"message\"],\n },\n },\n}\n\nexport async function run({ inputs, appId }: AutomationStepInput) {\n const message = `App ${appId} - ${inputs.text}`\n console.log(message)\n return {\n success: true,\n message,\n }\n}\n", "import fetch from \"node-fetch\"\nimport { getFetchResponse } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nconst DEFAULT_USERNAME = \"Budibase Automate\"\nconst DEFAULT_AVATAR_URL = \"https://i.imgur.com/a1cmTKM.png\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Discord Message\",\n tagline: \"Send a message to a Discord server\",\n description: \"Send a message to a Discord server\",\n icon: \"ri-discord-line\",\n stepId: AutomationActionStepId.discord,\n type: AutomationStepType.ACTION,\n internal: false,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n url: {\n type: AutomationIOType.STRING,\n title: \"Discord Webhook URL\",\n },\n username: {\n type: AutomationIOType.STRING,\n title: \"Bot Name\",\n },\n avatar_url: {\n type: AutomationIOType.STRING,\n title: \"Bot Avatar URL\",\n },\n content: {\n type: AutomationIOType.STRING,\n title: \"Message\",\n },\n },\n required: [\"url\", \"content\"],\n },\n outputs: {\n properties: {\n httpStatus: {\n type: AutomationIOType.NUMBER,\n description: \"The HTTP status code of the request\",\n },\n response: {\n type: AutomationIOType.STRING,\n description: \"The response from the Discord Webhook\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the message sent successfully\",\n },\n },\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n let { url, username, avatar_url, content } = inputs\n if (!username) {\n username = DEFAULT_USERNAME\n }\n if (!avatar_url) {\n avatar_url = DEFAULT_AVATAR_URL\n }\n if (!url?.trim()?.length) {\n return {\n httpStatus: 400,\n response: \"Missing Webhook URL\",\n success: false,\n }\n }\n let response\n try {\n response = await fetch(url, {\n method: \"post\",\n body: JSON.stringify({\n username,\n avatar_url,\n content,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n } catch (err: any) {\n return {\n httpStatus: 400,\n response: err.message,\n success: false,\n }\n }\n\n const { status, message } = await getFetchResponse(response)\n return {\n httpStatus: status,\n success: status === 200 || status === 204,\n response: message,\n }\n}\n", "import fetch from \"node-fetch\"\nimport { getFetchResponse } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Slack Message\",\n tagline: \"Send a message to Slack\",\n description: \"Send a message to Slack\",\n icon: \"ri-slack-line\",\n stepId: AutomationActionStepId.slack,\n type: AutomationStepType.ACTION,\n internal: false,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n url: {\n type: AutomationIOType.STRING,\n title: \"Incoming Webhook URL\",\n },\n text: {\n type: AutomationIOType.STRING,\n title: \"Message\",\n },\n },\n required: [\"url\", \"text\"],\n },\n outputs: {\n properties: {\n httpStatus: {\n type: AutomationIOType.NUMBER,\n description: \"The HTTP status code of the request\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the message sent successfully\",\n },\n response: {\n type: AutomationIOType.STRING,\n description: \"The response from the Slack Webhook\",\n },\n },\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n let { url, text } = inputs\n if (!url?.trim()?.length) {\n return {\n httpStatus: 400,\n response: \"Missing Webhook URL\",\n success: false,\n }\n }\n let response\n try {\n response = await fetch(url, {\n method: \"post\",\n body: JSON.stringify({\n text,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n } catch (err: any) {\n return {\n httpStatus: 400,\n response: err.message,\n success: false,\n }\n }\n\n const { status, message } = await getFetchResponse(response)\n return {\n httpStatus: status,\n response: message,\n success: status === 200,\n }\n}\n", "import fetch from \"node-fetch\"\nimport { getFetchResponse } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Zapier Webhook\",\n stepId: AutomationActionStepId.zapier,\n type: AutomationStepType.ACTION,\n internal: false,\n description: \"Trigger a Zapier Zap via webhooks\",\n tagline: \"Trigger a Zapier Zap\",\n icon: \"ri-flashlight-line\",\n inputs: {},\n schema: {\n inputs: {\n properties: {\n url: {\n type: AutomationIOType.STRING,\n title: \"Webhook URL\",\n },\n body: {\n type: AutomationIOType.JSON,\n title: \"Payload\",\n },\n value1: {\n type: AutomationIOType.STRING,\n title: \"Payload Value 1\",\n },\n value2: {\n type: AutomationIOType.STRING,\n title: \"Payload Value 2\",\n },\n value3: {\n type: AutomationIOType.STRING,\n title: \"Payload Value 3\",\n },\n value4: {\n type: AutomationIOType.STRING,\n title: \"Payload Value 4\",\n },\n value5: {\n type: AutomationIOType.STRING,\n title: \"Payload Value 5\",\n },\n },\n required: [\"url\"],\n },\n outputs: {\n properties: {\n httpStatus: {\n type: AutomationIOType.NUMBER,\n description: \"The HTTP status code of the request\",\n },\n response: {\n type: AutomationIOType.STRING,\n description: \"The response from Zapier\",\n },\n },\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n //TODO - Remove deprecated values 1,2,3,4,5 after November 2023\n const { url, value1, value2, value3, value4, value5, body } = inputs\n\n let payload = {}\n try {\n payload = body?.value ? JSON.parse(body?.value) : {}\n } catch (err) {\n return {\n httpStatus: 400,\n response: \"Invalid payload JSON\",\n success: false,\n }\n }\n\n if (!url?.trim()?.length) {\n return {\n httpStatus: 400,\n response: \"Missing Webhook URL\",\n success: false,\n }\n }\n // send the platform to make sure zaps always work, even\n // if no values supplied\n let response\n try {\n response = await fetch(url, {\n method: \"post\",\n body: JSON.stringify({\n platform: \"budibase\",\n value1,\n value2,\n value3,\n value4,\n value5,\n ...payload,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n } catch (err: any) {\n return {\n httpStatus: 400,\n response: err.message,\n success: false,\n }\n }\n\n const { status, message } = await getFetchResponse(response)\n\n return {\n success: status === 200,\n httpStatus: status,\n response: message,\n }\n}\n", "import fetch from \"node-fetch\"\nimport { getFetchResponse } from \"./utils\"\nimport {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Make Integration\",\n stepTitle: \"Make\",\n tagline: \"Trigger a Make scenario\",\n description:\n \"Performs a webhook call to Make and gets the response (if configured)\",\n icon: \"ri-shut-down-line\",\n stepId: AutomationActionStepId.integromat,\n type: AutomationStepType.ACTION,\n internal: false,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n url: {\n type: AutomationIOType.STRING,\n title: \"Webhook URL\",\n },\n body: {\n type: AutomationIOType.JSON,\n title: \"Payload\",\n },\n value1: {\n type: AutomationIOType.STRING,\n title: \"Input Value 1\",\n },\n value2: {\n type: AutomationIOType.STRING,\n title: \"Input Value 2\",\n },\n value3: {\n type: AutomationIOType.STRING,\n title: \"Input Value 3\",\n },\n value4: {\n type: AutomationIOType.STRING,\n title: \"Input Value 4\",\n },\n value5: {\n type: AutomationIOType.STRING,\n title: \"Input Value 5\",\n },\n },\n required: [\"url\", \"value1\", \"value2\", \"value3\", \"value4\", \"value5\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether call was successful\",\n },\n httpStatus: {\n type: AutomationIOType.NUMBER,\n description: \"The HTTP status code returned\",\n },\n response: {\n type: AutomationIOType.OBJECT,\n description: \"The webhook response - this can have properties\",\n },\n },\n required: [\"success\", \"response\"],\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n //TODO - Remove deprecated values 1,2,3,4,5 after November 2023\n const { url, value1, value2, value3, value4, value5, body } = inputs\n\n let payload = {}\n try {\n payload = body?.value ? JSON.parse(body?.value) : {}\n } catch (err) {\n return {\n httpStatus: 400,\n response: \"Invalid payload JSON\",\n success: false,\n }\n }\n\n if (!url?.trim()?.length) {\n return {\n httpStatus: 400,\n response: \"Missing Webhook URL\",\n success: false,\n }\n }\n let response\n try {\n response = await fetch(url, {\n method: \"post\",\n body: JSON.stringify({\n value1,\n value2,\n value3,\n value4,\n value5,\n ...payload,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n })\n } catch (err: any) {\n return {\n httpStatus: 400,\n response: err.message,\n success: false,\n }\n }\n\n const { status, message } = await getFetchResponse(response)\n return {\n httpStatus: status,\n success: status === 200,\n response: message,\n }\n}\n", "import {\n AutomationActionStepId,\n AutomationStepSchema,\n AutomationStepInput,\n AutomationStepType,\n AutomationIOType,\n} from \"@budibase/types\"\n\nexport const FilterConditions = {\n EQUAL: \"EQUAL\",\n NOT_EQUAL: \"NOT_EQUAL\",\n GREATER_THAN: \"GREATER_THAN\",\n LESS_THAN: \"LESS_THAN\",\n}\n\nexport const PrettyFilterConditions = {\n [FilterConditions.EQUAL]: \"Equals\",\n [FilterConditions.NOT_EQUAL]: \"Not equals\",\n [FilterConditions.GREATER_THAN]: \"Greater than\",\n [FilterConditions.LESS_THAN]: \"Less than\",\n}\n\nexport const definition: AutomationStepSchema = {\n name: \"Condition\",\n tagline: \"{{inputs.field}} {{inputs.condition}} {{inputs.value}}\",\n icon: \"Branch2\",\n description:\n \"Conditionally halt automations which do not meet certain conditions\",\n type: AutomationStepType.LOGIC,\n internal: true,\n stepId: AutomationActionStepId.FILTER,\n inputs: {\n condition: FilterConditions.EQUAL,\n },\n schema: {\n inputs: {\n properties: {\n field: {\n type: AutomationIOType.STRING,\n title: \"Reference Value\",\n },\n condition: {\n type: AutomationIOType.STRING,\n title: \"Condition\",\n enum: Object.values(FilterConditions),\n pretty: Object.values(PrettyFilterConditions),\n },\n value: {\n type: AutomationIOType.STRING,\n title: \"Comparison Value\",\n },\n },\n required: [\"field\", \"condition\", \"value\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the action was successful\",\n },\n result: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the logic block passed\",\n },\n },\n required: [\"success\", \"result\"],\n },\n },\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n try {\n let { field, condition, value } = inputs\n // coerce types so that we can use them\n if (!isNaN(value) && !isNaN(field)) {\n value = parseFloat(value)\n field = parseFloat(field)\n } else if (!isNaN(Date.parse(value)) && !isNaN(Date.parse(field))) {\n value = Date.parse(value)\n field = Date.parse(field)\n }\n let result = false\n if (typeof field !== \"object\" && typeof value !== \"object\") {\n switch (condition) {\n case FilterConditions.EQUAL:\n result = field === value\n break\n case FilterConditions.NOT_EQUAL:\n result = field !== value\n break\n case FilterConditions.GREATER_THAN:\n result = field > value\n break\n case FilterConditions.LESS_THAN:\n result = field < value\n break\n }\n } else {\n result = false\n }\n return { success: true, result }\n } catch (err) {\n return { success: false, result: false }\n }\n}\n", "import { wait } from \"../../utilities\"\nimport {\n AutomationActionStepId,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Delay\",\n icon: \"Clock\",\n tagline: \"Delay for {{inputs.time}} milliseconds\",\n description: \"Delay the automation until an amount of time has passed\",\n stepId: AutomationActionStepId.DELAY,\n internal: true,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n time: {\n type: AutomationIOType.NUMBER,\n title: \"Delay in milliseconds\",\n },\n },\n required: [\"time\"],\n },\n outputs: {\n properties: {\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the delay was successful\",\n },\n },\n required: [\"success\"],\n },\n },\n type: AutomationStepType.LOGIC,\n}\n\nexport async function run({ inputs }: AutomationStepInput) {\n await wait(inputs.time)\n return {\n success: true,\n }\n}\n", "import {\n buildExternalTableId,\n breakExternalTableId,\n} from \"../../../integrations/utils\"\nimport {\n generateForeignKey,\n generateJunctionTableName,\n foreignKeyStructure,\n hasTypeChanged,\n setStaticSchemas,\n} from \"./utils\"\nimport { FieldTypes } from \"../../../constants\"\nimport { makeExternalQuery } from \"../../../integrations/base/query\"\nimport { handleRequest } from \"../row/external\"\nimport { events, context } from \"@budibase/backend-core\"\nimport { parse, isRows, isSchema } from \"../../../utilities/schema\"\nimport {\n Datasource,\n Table,\n QueryJson,\n Operation,\n RenameColumn,\n FieldSchema,\n UserCtx,\n TableRequest,\n RelationshipTypes,\n} from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\nconst { cloneDeep } = require(\"lodash/fp\")\n\nasync function makeTableRequest(\n datasource: Datasource,\n operation: Operation,\n table: Table,\n tables: Record<string, Table>,\n oldTable?: Table,\n renamed?: RenameColumn\n) {\n const json: QueryJson = {\n endpoint: {\n datasourceId: datasource._id!,\n entityId: table._id!,\n operation,\n },\n meta: {\n tables,\n },\n table,\n }\n if (oldTable) {\n json.meta!.table = oldTable\n }\n if (renamed) {\n json.meta!.renamed = renamed\n }\n return makeExternalQuery(datasource, json)\n}\n\nfunction cleanupRelationships(\n table: Table,\n tables: Record<string, Table>,\n oldTable?: Table\n) {\n const tableToIterate = oldTable ? oldTable : table\n // clean up relationships in couch table schemas\n for (let [key, schema] of Object.entries(tableToIterate.schema)) {\n if (\n schema.type === FieldTypes.LINK &&\n (!oldTable || table.schema[key] == null)\n ) {\n const relatedTable = Object.values(tables).find(\n table => table._id === schema.tableId\n )\n const foreignKey = schema.foreignKey\n if (!relatedTable || !foreignKey) {\n continue\n }\n for (let [relatedKey, relatedSchema] of Object.entries(\n relatedTable.schema\n )) {\n if (\n relatedSchema.type === FieldTypes.LINK &&\n relatedSchema.fieldName === foreignKey\n ) {\n delete relatedTable.schema[relatedKey]\n }\n }\n }\n }\n}\n\nfunction getDatasourceId(table: Table) {\n if (!table) {\n throw \"No table supplied\"\n }\n if (table.sourceId) {\n return table.sourceId\n }\n return breakExternalTableId(table._id).datasourceId\n}\n\nfunction otherRelationshipType(type?: string) {\n if (type === RelationshipTypes.MANY_TO_MANY) {\n return RelationshipTypes.MANY_TO_MANY\n }\n return type === RelationshipTypes.ONE_TO_MANY\n ? RelationshipTypes.MANY_TO_ONE\n : RelationshipTypes.ONE_TO_MANY\n}\n\nfunction generateManyLinkSchema(\n datasource: Datasource,\n column: FieldSchema,\n table: Table,\n relatedTable: Table\n): Table {\n if (!table.primary || !relatedTable.primary) {\n throw new Error(\"Unable to generate many link schema, no primary keys\")\n }\n const primary = table.name + table.primary[0]\n const relatedPrimary = relatedTable.name + relatedTable.primary[0]\n const jcTblName = generateJunctionTableName(column, table, relatedTable)\n // first create the new table\n const junctionTable = {\n _id: buildExternalTableId(datasource._id!, jcTblName),\n name: jcTblName,\n primary: [primary, relatedPrimary],\n constrained: [primary, relatedPrimary],\n schema: {\n [primary]: foreignKeyStructure(primary, {\n toTable: table.name,\n toKey: table.primary[0],\n }),\n [relatedPrimary]: foreignKeyStructure(relatedPrimary, {\n toTable: relatedTable.name,\n toKey: relatedTable.primary[0],\n }),\n },\n }\n column.through = junctionTable._id\n column.throughFrom = relatedPrimary\n column.throughTo = primary\n column.fieldName = relatedPrimary\n return junctionTable\n}\n\nfunction generateLinkSchema(\n column: FieldSchema,\n table: Table,\n relatedTable: Table,\n type: RelationshipTypes\n) {\n if (!table.primary || !relatedTable.primary) {\n throw new Error(\"Unable to generate link schema, no primary keys\")\n }\n const isOneSide = type === RelationshipTypes.ONE_TO_MANY\n const primary = isOneSide ? relatedTable.primary[0] : table.primary[0]\n // generate a foreign key\n const foreignKey = generateForeignKey(column, relatedTable)\n column.relationshipType = type\n column.foreignKey = isOneSide ? foreignKey : primary\n column.fieldName = isOneSide ? primary : foreignKey\n return foreignKey\n}\n\nfunction generateRelatedSchema(\n linkColumn: FieldSchema,\n table: Table,\n relatedTable: Table,\n columnName: string\n) {\n // generate column for other table\n const relatedSchema = cloneDeep(linkColumn)\n // swap them from the main link\n if (linkColumn.foreignKey) {\n relatedSchema.fieldName = linkColumn.foreignKey\n relatedSchema.foreignKey = linkColumn.fieldName\n }\n // is many to many\n else {\n // don't need to copy through, already got it\n relatedSchema.fieldName = linkColumn.throughTo\n relatedSchema.throughTo = linkColumn.throughFrom\n relatedSchema.throughFrom = linkColumn.throughTo\n }\n relatedSchema.relationshipType = otherRelationshipType(\n linkColumn.relationshipType\n )\n relatedSchema.tableId = relatedTable._id\n relatedSchema.name = columnName\n table.schema[columnName] = relatedSchema\n}\n\nfunction isRelationshipSetup(column: FieldSchema) {\n return column.foreignKey || column.through\n}\n\nexport async function save(ctx: UserCtx) {\n const inputs: TableRequest = ctx.request.body\n const renamed = inputs?._rename\n // can't do this right now\n delete inputs.rows\n const datasourceId = getDatasourceId(ctx.request.body)!\n // table doesn't exist already, note that it is created\n if (!inputs._id) {\n inputs.created = true\n }\n let tableToSave: TableRequest = {\n type: \"table\",\n _id: buildExternalTableId(datasourceId, inputs.name),\n ...inputs,\n }\n\n let oldTable\n if (ctx.request.body && ctx.request.body._id) {\n oldTable = await sdk.tables.getTable(ctx.request.body._id)\n }\n\n if (hasTypeChanged(tableToSave, oldTable)) {\n ctx.throw(400, \"A column type has changed.\")\n }\n\n const db = context.getAppDB()\n const datasource = await sdk.datasources.get(datasourceId)\n if (!datasource.entities) {\n datasource.entities = {}\n }\n\n // GSheets is a specific case - only ever has a static primary key\n tableToSave = setStaticSchemas(datasource, tableToSave)\n\n const oldTables = cloneDeep(datasource.entities)\n const tables: Record<string, Table> = datasource.entities\n\n const extraTablesToUpdate = []\n\n // check if relations need setup\n for (let schema of Object.values(tableToSave.schema)) {\n if (schema.type !== FieldTypes.LINK || isRelationshipSetup(schema)) {\n continue\n }\n const relatedTable = Object.values(tables).find(\n table => table._id === schema.tableId\n )\n if (!relatedTable) {\n continue\n }\n const relatedColumnName = schema.fieldName!\n const relationType = schema.relationshipType!\n if (relationType === RelationshipTypes.MANY_TO_MANY) {\n const junctionTable = generateManyLinkSchema(\n datasource,\n schema,\n tableToSave,\n relatedTable\n )\n if (tables[junctionTable.name]) {\n throw \"Junction table already exists, cannot create another relationship.\"\n }\n tables[junctionTable.name] = junctionTable\n extraTablesToUpdate.push(junctionTable)\n } else {\n const fkTable =\n relationType === RelationshipTypes.ONE_TO_MANY\n ? tableToSave\n : relatedTable\n const foreignKey = generateLinkSchema(\n schema,\n tableToSave,\n relatedTable,\n relationType\n )\n fkTable.schema[foreignKey] = foreignKeyStructure(foreignKey)\n if (fkTable.constrained == null) {\n fkTable.constrained = []\n }\n if (fkTable.constrained.indexOf(foreignKey) === -1) {\n fkTable.constrained.push(foreignKey)\n }\n // foreign key is in other table, need to save it to external\n if (fkTable._id !== tableToSave._id) {\n extraTablesToUpdate.push(fkTable)\n }\n }\n generateRelatedSchema(schema, relatedTable, tableToSave, relatedColumnName)\n schema.main = true\n }\n\n cleanupRelationships(tableToSave, tables, oldTable)\n\n const operation = oldTable ? Operation.UPDATE_TABLE : Operation.CREATE_TABLE\n await makeTableRequest(\n datasource,\n operation,\n tableToSave,\n tables,\n oldTable,\n renamed\n )\n // update any extra tables (like foreign keys in other tables)\n for (let extraTable of extraTablesToUpdate) {\n const oldExtraTable = oldTables[extraTable.name]\n let op = oldExtraTable ? Operation.UPDATE_TABLE : Operation.CREATE_TABLE\n await makeTableRequest(datasource, op, extraTable, tables, oldExtraTable)\n }\n\n // make sure the constrained list, all still exist\n if (Array.isArray(tableToSave.constrained)) {\n tableToSave.constrained = tableToSave.constrained.filter(constraint =>\n Object.keys(tableToSave.schema).includes(constraint)\n )\n }\n\n // remove the rename prop\n delete tableToSave._rename\n // store it into couch now for budibase reference\n datasource.entities[tableToSave.name] = tableToSave\n await db.put(datasource)\n\n return tableToSave\n}\n\nexport async function destroy(ctx: UserCtx) {\n const tableToDelete: TableRequest = await sdk.tables.getTable(\n ctx.params.tableId\n )\n if (!tableToDelete || !tableToDelete.created) {\n ctx.throw(400, \"Cannot delete tables which weren't created in Budibase.\")\n }\n const datasourceId = getDatasourceId(tableToDelete)\n\n const db = context.getAppDB()\n const datasource = await sdk.datasources.get(datasourceId!)\n const tables = datasource.entities\n\n const operation = Operation.DELETE_TABLE\n if (tables) {\n await makeTableRequest(datasource, operation, tableToDelete, tables)\n cleanupRelationships(tableToDelete, tables)\n delete tables[tableToDelete.name]\n datasource.entities = tables\n }\n\n await db.put(datasource)\n\n return tableToDelete\n}\n\nexport async function bulkImport(ctx: UserCtx) {\n const table = await sdk.tables.getTable(ctx.params.tableId)\n const { rows }: { rows: unknown } = ctx.request.body\n const schema: unknown = table.schema\n\n if (!rows || !isRows(rows) || !isSchema(schema)) {\n ctx.throw(400, \"Provided data import information is invalid.\")\n }\n\n const parsedRows = parse(rows, schema)\n await handleRequest(Operation.BULK_CREATE, table._id!, {\n rows: parsedRows,\n })\n await events.rows.imported(table, parsedRows.length)\n return table\n}\n", "import * as internal from \"./internal\"\nimport * as external from \"./external\"\nimport {\n validate as validateSchema,\n isSchema,\n isRows,\n} from \"../../../utilities/schema\"\nimport { isExternalTable, isSQL } from \"../../../integrations/utils\"\nimport { getDatasourceParams } from \"../../../db/utils\"\nimport { context, events } from \"@budibase/backend-core\"\nimport { Table, UserCtx } from \"@budibase/types\"\nimport sdk from \"../../../sdk\"\nimport { jsonFromCsvString } from \"../../../utilities/csv\"\n\nfunction pickApi({ tableId, table }: { tableId?: string; table?: Table }) {\n if (table && !tableId) {\n tableId = table._id\n }\n if (table && table.type === \"external\") {\n return external\n } else if (tableId && isExternalTable(tableId)) {\n return external\n }\n return internal\n}\n\n// covers both internal and external\nexport async function fetch(ctx: UserCtx) {\n const db = context.getAppDB()\n\n const internal = await sdk.tables.getAllInternalTables()\n\n const externalTables = await db.allDocs(\n getDatasourceParams(\"plus\", {\n include_docs: true,\n })\n )\n\n const external = externalTables.rows.flatMap(tableDoc => {\n let entities = tableDoc.doc.entities\n if (entities) {\n return Object.values(entities).map((entity: any) => ({\n ...entity,\n type: \"external\",\n sourceId: tableDoc.doc._id,\n sql: isSQL(tableDoc.doc),\n }))\n } else {\n return []\n }\n })\n\n ctx.body = [...internal, ...external]\n}\n\nexport async function find(ctx: UserCtx) {\n const tableId = ctx.params.tableId\n ctx.body = await sdk.tables.getTable(tableId)\n}\n\nexport async function save(ctx: UserCtx) {\n const appId = ctx.appId\n const table = ctx.request.body\n const isImport = table.rows\n\n const savedTable = await pickApi({ table }).save(ctx)\n if (!table._id) {\n await events.table.created(savedTable)\n } else {\n await events.table.updated(savedTable)\n }\n if (isImport) {\n await events.table.imported(savedTable)\n }\n ctx.status = 200\n ctx.message = `Table ${table.name} saved successfully.`\n ctx.eventEmitter &&\n ctx.eventEmitter.emitTable(`table:save`, appId, savedTable)\n ctx.body = savedTable\n}\n\nexport async function destroy(ctx: UserCtx) {\n const appId = ctx.appId\n const tableId = ctx.params.tableId\n const deletedTable = await pickApi({ tableId }).destroy(ctx)\n await events.table.deleted(deletedTable)\n ctx.eventEmitter &&\n ctx.eventEmitter.emitTable(`table:delete`, appId, deletedTable)\n ctx.status = 200\n ctx.table = deletedTable\n ctx.body = { message: `Table ${tableId} deleted.` }\n}\n\nexport async function bulkImport(ctx: UserCtx) {\n const tableId = ctx.params.tableId\n await pickApi({ tableId }).bulkImport(ctx)\n // right now we don't trigger anything for bulk import because it\n // can only be done in the builder, but in the future we may need to\n // think about events for bulk items\n\n ctx.status = 200\n ctx.body = { message: `Bulk rows created.` }\n}\n\nexport async function csvToJson(ctx: UserCtx) {\n const { csvString } = ctx.request.body\n\n const result = await jsonFromCsvString(csvString)\n\n ctx.status = 200\n ctx.body = result\n}\n\nexport async function validateNewTableImport(ctx: UserCtx) {\n const { rows, schema }: { rows: unknown; schema: unknown } = ctx.request.body\n\n if (isRows(rows) && isSchema(schema)) {\n ctx.status = 200\n ctx.body = validateSchema(rows, schema)\n } else {\n ctx.status = 422\n }\n}\n\nexport async function validateExistingTableImport(ctx: UserCtx) {\n const { rows, tableId }: { rows: unknown; tableId: unknown } =\n ctx.request.body\n\n let schema = null\n if (tableId) {\n const table = await sdk.tables.getTable(tableId)\n schema = table.schema\n } else {\n ctx.status = 422\n return\n }\n\n if (tableId && isRows(rows) && isSchema(schema)) {\n ctx.status = 200\n ctx.body = validateSchema(rows, schema)\n } else {\n ctx.status = 422\n }\n}\n", "import csv from \"csvtojson\"\n\nexport async function jsonFromCsvString(csvString: string) {\n const castedWithEmptyValues = await csv({ ignoreEmpty: true }).fromString(\n csvString\n )\n\n // By default the csvtojson library casts empty values as empty strings. This is causing issues on conversion.\n // ignoreEmpty will remove the key completly if empty, so creating this empty object will ensure we return the values with the keys but empty values\n const result = await csv({ ignoreEmpty: false }).fromString(csvString)\n result.forEach((r, i) => {\n for (const [key] of Object.entries(r).filter(\n ([key, value]) => value === \"\"\n )) {\n if (castedWithEmptyValues[i][key] === undefined) {\n r[key] = null\n }\n }\n })\n\n return result\n}\n", "import * as rowController from \"../../api/controllers/row\"\nimport * as tableController from \"../../api/controllers/table\"\nimport { FieldTypes } from \"../../constants\"\nimport { buildCtx } from \"./utils\"\nimport * as automationUtils from \"../automationUtils\"\nimport {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepInput,\n AutomationStepSchema,\n AutomationStepType,\n SearchFilters,\n Table,\n} from \"@budibase/types\"\n\nenum SortOrder {\n ASCENDING = \"ascending\",\n DESCENDING = \"descending\",\n}\n\nconst SortOrderPretty = {\n [SortOrder.ASCENDING]: \"Ascending\",\n [SortOrder.DESCENDING]: \"Descending\",\n}\n\nenum EmptyFilterOption {\n RETURN_ALL = \"all\",\n RETURN_NONE = \"none\",\n}\n\nconst EmptyFilterOptionPretty = {\n [EmptyFilterOption.RETURN_ALL]: \"Return all table rows\",\n [EmptyFilterOption.RETURN_NONE]: \"Return no rows\",\n}\n\nexport const definition: AutomationStepSchema = {\n description: \"Query rows from the database\",\n icon: \"Search\",\n name: \"Query rows\",\n tagline: \"Query rows from {{inputs.enriched.table.name}} table\",\n type: AutomationStepType.ACTION,\n stepId: AutomationActionStepId.QUERY_ROWS,\n internal: true,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n tableId: {\n type: AutomationIOType.STRING,\n customType: AutomationCustomIOType.TABLE,\n title: \"Table\",\n },\n filters: {\n type: AutomationIOType.OBJECT,\n customType: AutomationCustomIOType.FILTERS,\n title: \"Filtering\",\n },\n sortColumn: {\n type: AutomationIOType.STRING,\n title: \"Sort Column\",\n customType: AutomationCustomIOType.COLUMN,\n },\n sortOrder: {\n type: AutomationIOType.STRING,\n title: \"Sort Order\",\n enum: Object.values(SortOrder),\n pretty: Object.values(SortOrderPretty),\n },\n limit: {\n type: AutomationIOType.NUMBER,\n title: \"Limit\",\n customType: AutomationCustomIOType.QUERY_LIMIT,\n },\n onEmptyFilter: {\n pretty: Object.values(EmptyFilterOptionPretty),\n enum: Object.values(EmptyFilterOption),\n type: AutomationIOType.STRING,\n title: \"When Filter Empty\",\n },\n },\n required: [\"tableId\"],\n },\n outputs: {\n properties: {\n rows: {\n type: AutomationIOType.ARRAY,\n customType: AutomationCustomIOType.ROWS,\n description: \"The rows that were found\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the query was successful\",\n },\n },\n required: [\"rows\", \"success\"],\n },\n },\n}\n\nasync function getTable(appId: string, tableId: string) {\n const ctx: any = buildCtx(appId, null, {\n params: {\n tableId,\n },\n })\n await tableController.find(ctx)\n return ctx.body\n}\n\nfunction typeCoercion(filters: SearchFilters, table: Table) {\n if (!filters || !table) {\n return filters\n }\n for (let key of Object.keys(filters)) {\n // @ts-ignore\n const searchParam = filters[key]\n if (typeof searchParam === \"object\") {\n for (let [property, value] of Object.entries(searchParam)) {\n const column = table.schema[property]\n // convert string inputs\n if (!column || typeof value !== \"string\") {\n continue\n }\n if (column.type === FieldTypes.NUMBER) {\n searchParam[property] = parseFloat(value)\n }\n }\n }\n }\n return filters\n}\n\nfunction hasNullFilters(filters: any[]) {\n return (\n filters.length === 0 ||\n filters.some(filter => filter.value === null || filter.value === \"\")\n )\n}\n\nexport async function run({ inputs, appId }: AutomationStepInput) {\n const { tableId, filters, sortColumn, sortOrder, limit } = inputs\n if (!tableId) {\n return {\n success: false,\n response: {\n message: \"You must select a table to query.\",\n },\n }\n }\n const table = await getTable(appId, tableId)\n let sortType = FieldTypes.STRING\n if (table && table.schema && table.schema[sortColumn] && sortColumn) {\n const fieldType = table.schema[sortColumn].type\n sortType =\n fieldType === FieldTypes.NUMBER ? FieldTypes.NUMBER : FieldTypes.STRING\n }\n const ctx: any = buildCtx(appId, null, {\n params: {\n tableId,\n },\n body: {\n sortType,\n limit,\n sort: sortColumn,\n query: typeCoercion(filters || {}, table),\n // default to ascending, like data tab\n sortOrder: sortOrder || SortOrder.ASCENDING,\n },\n version: \"1\",\n })\n try {\n let rows\n\n if (\n inputs.onEmptyFilter === EmptyFilterOption.RETURN_NONE &&\n inputs[\"filters-def\"] &&\n hasNullFilters(inputs[\"filters-def\"])\n ) {\n rows = []\n } else {\n await rowController.search(ctx)\n rows = ctx.body ? ctx.body.rows : []\n }\n\n return {\n rows,\n success: ctx.status === 200,\n }\n } catch (err) {\n return {\n success: false,\n response: automationUtils.getError(err),\n }\n }\n}\n", "import {\n AutomationActionStepId,\n AutomationCustomIOType,\n AutomationIOType,\n AutomationStepSchema,\n AutomationStepType,\n} from \"@budibase/types\"\n\nexport const definition: AutomationStepSchema = {\n name: \"Looping\",\n icon: \"Reuse\",\n tagline: \"Loop the block\",\n description: \"Loop\",\n stepId: AutomationActionStepId.LOOP,\n internal: true,\n inputs: {},\n schema: {\n inputs: {\n properties: {\n option: {\n customType: AutomationCustomIOType.LOOP_OPTION,\n title: \"Input type\",\n },\n binding: {\n type: AutomationIOType.STRING,\n title: \"Binding / Value\",\n },\n iterations: {\n type: AutomationIOType.NUMBER,\n title: \"Max loop iterations\",\n },\n failure: {\n type: AutomationIOType.STRING,\n title: \"Failure Condition\",\n },\n },\n required: [\"type\", \"value\", \"iterations\", \"failure\"],\n },\n outputs: {\n properties: {\n items: {\n customType: AutomationCustomIOType.ITEM,\n description: \"The item currently being executed\",\n },\n success: {\n type: AutomationIOType.BOOLEAN,\n description: \"Whether the message loop was successfully\",\n },\n iterations: {\n type: AutomationIOType.NUMBER,\n description: \"The amount of times the block ran\",\n },\n },\n required: [\"success\", \"items\", \"iterations\"],\n },\n },\n type: AutomationStepType.LOGIC,\n}\n", "import * as sendSmtpEmail from \"./steps/sendSmtpEmail\"\nimport * as createRow from \"./steps/createRow\"\nimport * as updateRow from \"./steps/updateRow\"\nimport * as deleteRow from \"./steps/deleteRow\"\nimport * as executeScript from \"./steps/executeScript\"\nimport * as executeQuery from \"./steps/executeQuery\"\nimport * as outgoingWebhook from \"./steps/outgoingWebhook\"\nimport * as serverLog from \"./steps/serverLog\"\nimport * as discord from \"./steps/discord\"\nimport * as slack from \"./steps/slack\"\nimport * as zapier from \"./steps/zapier\"\nimport * as make from \"./steps/make\"\nimport * as filter from \"./steps/filter\"\nimport * as delay from \"./steps/delay\"\nimport * as queryRow from \"./steps/queryRows\"\nimport * as loop from \"./steps/loop\"\nimport env from \"../environment\"\nimport {\n AutomationStepSchema,\n AutomationStepInput,\n PluginType,\n AutomationStep,\n} from \"@budibase/types\"\nimport sdk from \"../sdk\"\nimport { getAutomationPlugin } from \"../utilities/fileSystem\"\n\nconst ACTION_IMPLS: Record<\n string,\n (opts: AutomationStepInput) => Promise<any>\n> = {\n SEND_EMAIL_SMTP: sendSmtpEmail.run,\n CREATE_ROW: createRow.run,\n UPDATE_ROW: updateRow.run,\n DELETE_ROW: deleteRow.run,\n OUTGOING_WEBHOOK: outgoingWebhook.run,\n EXECUTE_SCRIPT: executeScript.run,\n EXECUTE_QUERY: executeQuery.run,\n SERVER_LOG: serverLog.run,\n DELAY: delay.run,\n FILTER: filter.run,\n QUERY_ROWS: queryRow.run,\n // these used to be lowercase step IDs, maintain for backwards compat\n discord: discord.run,\n slack: slack.run,\n zapier: zapier.run,\n integromat: make.run,\n}\nexport const BUILTIN_ACTION_DEFINITIONS: Record<string, AutomationStepSchema> =\n {\n SEND_EMAIL_SMTP: sendSmtpEmail.definition,\n CREATE_ROW: createRow.definition,\n UPDATE_ROW: updateRow.definition,\n DELETE_ROW: deleteRow.definition,\n OUTGOING_WEBHOOK: outgoingWebhook.definition,\n EXECUTE_SCRIPT: executeScript.definition,\n EXECUTE_QUERY: executeQuery.definition,\n SERVER_LOG: serverLog.definition,\n DELAY: delay.definition,\n FILTER: filter.definition,\n QUERY_ROWS: queryRow.definition,\n LOOP: loop.definition,\n // these used to be lowercase step IDs, maintain for backwards compat\n discord: discord.definition,\n slack: slack.definition,\n zapier: zapier.definition,\n integromat: make.definition,\n }\n\n// don't add the bash script/definitions unless in self host\n// the fact this isn't included in any definitions means it cannot be\n// ran at all\nif (env.SELF_HOSTED) {\n const bash = require(\"./steps/bash\")\n const openai = require(\"./steps/openai\")\n\n // @ts-ignore\n ACTION_IMPLS[\"EXECUTE_BASH\"] = bash.run\n // @ts-ignore\n BUILTIN_ACTION_DEFINITIONS[\"EXECUTE_BASH\"] = bash.definition\n\n ACTION_IMPLS.OPENAI = openai.run\n BUILTIN_ACTION_DEFINITIONS.OPENAI = openai.definition\n}\n\nexport async function getActionDefinitions() {\n const actionDefinitions = BUILTIN_ACTION_DEFINITIONS\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.AUTOMATION)\n for (let plugin of plugins) {\n const schema = plugin.schema.schema as AutomationStep\n actionDefinitions[schema.stepId] = {\n ...schema,\n custom: true,\n }\n }\n }\n return actionDefinitions\n}\n\n/* istanbul ignore next */\nexport async function getAction(stepId: string) {\n if (ACTION_IMPLS[stepId] != null) {\n return ACTION_IMPLS[stepId]\n }\n // must be a plugin\n if (env.SELF_HOSTED) {\n const plugins = await sdk.plugins.fetch(PluginType.AUTOMATION)\n const found = plugins.find(plugin => plugin.schema.schema.stepId === stepId)\n if (!found) {\n throw new Error(`Unable to find action implementation for \"${stepId}\"`)\n }\n return (await getAutomationPlugin(found)).action\n }\n}\n", "import { Table, Row } from \"@budibase/types\"\nimport BudibaseEmitter from \"./BudibaseEmitter\"\n\ntype BBEventOpts = {\n emitter: BudibaseEmitter\n eventName: string\n appId: string\n table?: Table\n row?: Row\n metadata?: any\n}\n\ninterface BBEventTable extends Table {\n tableId?: string\n}\n\ntype BBEvent = {\n appId: string\n tableId?: string\n row?: Row\n table?: BBEventTable\n id?: string\n revision?: string\n metadata?: any\n}\n\nexport function rowEmission({\n emitter,\n eventName,\n appId,\n row,\n table,\n metadata,\n}: BBEventOpts) {\n let event: BBEvent = {\n row,\n appId,\n tableId: row?.tableId,\n }\n if (table) {\n event.table = table\n }\n event.id = row?._id\n if (row?._rev) {\n event.revision = row._rev\n }\n if (metadata) {\n event.metadata = metadata\n }\n emitter.emit(eventName, event)\n}\n\nexport function tableEmission({\n emitter,\n eventName,\n appId,\n table,\n metadata,\n}: BBEventOpts) {\n const tableId = table?._id\n const inputTable: BBEventTable | undefined = table\n if (inputTable) {\n inputTable.tableId = tableId\n }\n let event: BBEvent = {\n table: inputTable,\n appId,\n tableId: tableId,\n }\n event.id = tableId\n if (table?._rev) {\n event.revision = table._rev\n }\n if (metadata) {\n event.metadata = metadata\n }\n emitter.emit(eventName, event)\n}\n", "import { EventEmitter } from \"events\"\nimport { rowEmission, tableEmission } from \"./utils\"\nimport { Table, Row } from \"@budibase/types\"\n\n/**\n * keeping event emitter in one central location as it might be used for things other than\n * automations (what it was for originally) - having a central emitter will be useful in the\n * future.\n */\n\n/**\n * Extending the standard emitter to some syntactic sugar and standardisation to the emitted event.\n * This is specifically quite important for template strings used in automations.\n */\nclass BudibaseEmitter extends EventEmitter {\n emitRow(eventName: string, appId: string, row: Row, table?: Table) {\n rowEmission({ emitter: this, eventName, appId, row, table })\n }\n\n emitTable(eventName: string, appId: string, table?: Table) {\n tableEmission({ emitter: this, eventName, appId, table })\n }\n\n emitPort(portNumber?: number | string) {\n this.emit(\"internal:port\", portNumber)\n }\n}\n\nexport default BudibaseEmitter\n", "import { constants, logging } from \"@budibase/backend-core\"\nimport { sdk as proSdk } from \"@budibase/pro\"\nimport { DocUpdateEvent, UserGroupSyncEvents } from \"@budibase/types\"\nimport { syncUsersToAllApps } from \"../../sdk/app/applications/sync\"\nimport { UpdateCallback } from \"./processors\"\n\nexport default function process(updateCb?: UpdateCallback) {\n const processor = async (update: DocUpdateEvent) => {\n try {\n const docId = update.id\n const isGroup = docId.startsWith(constants.DocumentType.GROUP)\n let userIds: string[]\n if (isGroup) {\n const group = await proSdk.groups.get(docId)\n userIds = group.users?.map(user => user._id) || []\n } else {\n userIds = [docId]\n }\n if (userIds.length > 0) {\n await syncUsersToAllApps(userIds)\n }\n if (updateCb) {\n updateCb(docId)\n }\n } catch (err: any) {\n // if something not found - no changes to perform\n if (err?.status === 404) {\n return\n } else {\n logging.logAlert(\"Failed to perform user/group app sync\", err)\n }\n }\n }\n return { events: UserGroupSyncEvents, processor }\n}\n", "import userGroupProcessor from \"./syncUsers\"\nimport { docUpdates } from \"@budibase/backend-core\"\n\nexport type UpdateCallback = (docId: string) => void\nlet started = false\n\nexport function init(updateCb?: UpdateCallback) {\n if (started) {\n return\n }\n const processors = [userGroupProcessor(updateCb)]\n docUpdates.init(processors)\n started = true\n}\n", "import BudibaseEmitter from \"./BudibaseEmitter\"\n\nconst emitter = new BudibaseEmitter()\n\nexport { init } from \"./docUpdates\"\nexport default emitter\n", "import { rowEmission, tableEmission } from \"./utils\"\nimport mainEmitter from \"./index\"\nimport env from \"../environment\"\nimport { Table, Row } from \"@budibase/types\"\n\n// max number of automations that can chain on top of each other\n// TODO: in future make this configurable at the automation level\nconst MAX_AUTOMATION_CHAIN = env.SELF_HOSTED ? 5 : 0\n\n/**\n * Special emitter which takes the count of automation runs which have occurred and blocks an\n * automation from running if it has reached the maximum number of chained automations runs.\n * This essentially \"fakes\" the normal emitter to add some functionality in-between to stop automations\n * from getting stuck endlessly chaining.\n */\nclass AutomationEmitter {\n chainCount: number\n metadata: { automationChainCount: number }\n\n constructor(chainCount: number) {\n this.chainCount = chainCount\n this.metadata = {\n automationChainCount: chainCount,\n }\n }\n\n emitRow(eventName: string, appId: string, row: Row, table?: Table) {\n // don't emit even if we've reached max automation chain\n if (this.chainCount >= MAX_AUTOMATION_CHAIN) {\n return\n }\n rowEmission({\n emitter: mainEmitter,\n eventName,\n appId,\n row,\n table,\n metadata: this.metadata,\n })\n }\n\n emitTable(eventName: string, appId: string, table?: Table) {\n // don't emit even if we've reached max automation chain\n if (this.chainCount > MAX_AUTOMATION_CHAIN) {\n return\n }\n\n tableEmission({\n emitter: mainEmitter,\n eventName,\n appId,\n table,\n metadata: this.metadata,\n })\n }\n}\n\nexport default AutomationEmitter\n", "import env from \"../../environment\"\nimport { AutomationResults, Automation, App } from \"@budibase/types\"\nimport { automations } from \"@budibase/pro\"\nimport { db as dbUtils } from \"@budibase/backend-core\"\n\nexport async function storeLog(\n automation: Automation,\n results: AutomationResults\n) {\n // can disable this if un-needed in self-host, also only do this for prod apps\n if (env.DISABLE_AUTOMATION_LOGS) {\n return\n }\n await automations.logs.storeLog(automation, results)\n}\n\nexport async function checkAppMetadata(apps: App[]) {\n const maxStartDate = await automations.logs.oldestLogDate()\n for (let metadata of apps) {\n if (!metadata.automationErrors) {\n continue\n }\n for (let [key, errors] of Object.entries(metadata.automationErrors)) {\n const updated = []\n for (let error of errors) {\n if (!error) {\n continue\n }\n const startDate = error.split(dbUtils.SEPARATOR)[2]\n if (startDate > maxStartDate) {\n updated.push(error)\n }\n }\n metadata.automationErrors[key] = updated\n }\n }\n return apps\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Event", "init_license", "init_license", "QueryType", "DatasourceFieldType", "SourceName", "init_auth", "TenantResolutionStrategy", "init_user", "init_auth", "init_user", "init_account", "init_user", "init_account", "init_user", "init_app", "init_automation", "AutomationIOType", "AutomationCustomIOType", "AutomationTriggerStepId", "AutomationActionStepId", "init_datasource", "init_layout", "init_query", "init_role", "init_table", "init_screen", "init_view", "init_user", "init_backup", "AppBackupType", "AppBackupTrigger", "init_app", "init_automation", "init_datasource", "init_layout", "init_query", "init_role", "init_table", "init_screen", "init_view", "init_user", "init_backup", "init_user", "init_userGroup", "init_plugin", "PluginType", "ScheduleType", "ScheduleRepeatPeriod", "init_environmentVariables", "init_auditLogs", "init_user", "init_userGroup", "init_plugin", "init_environmentVariables", "init_auditLogs", "init_account", "init_app", "init_accounts", "init_user", "init_license", "init_account", "init_accounts", "init_user", "init_license", "init_auth", "init_user", "init_schedule", "init_environment", "init_environment", "init_backup", "init_datasource", "init_app", "init_backup", "init_datasource", "init_environmentVariables", "init_auditLogs", "init_events", "init_users", "init_users", "init_global", "init_environmentVariables", "init_auditLogs", "init_events", "init_auth", "init_user", "init_schedule", "init_app", "init_global", "init_account", "init_db", "AutomationViewMode", "ViewName", "InternalTable", "DocumentType", "UserStatus", "Cookie", "Header", "GlobalRole", "Config", "init_constants", "init_db", "doInIdentityContext", "getIdentity", "init_context", "isTest", "isCypress", "isJest", "isDev", "LOADED", "environment", "environment_default", "init_environment", "init_constants", "init_environment", "environment_default", "path", "body", "params", "fetch", "response", "db", "options", "environment_default", "init_environment", "url", "opts", "PouchDB", "find", "Nano", "response", "db", "params", "view", "stream", "db", "environment_default", "json", "init_db", "init_environment", "environment_default", "params", "init_environment", "init_db", "init_constants", "init_context", "init_constants", "SEPARATOR", "environment_default", "db", "init_utils", "init_environment", "Databases", "SelectableDatabase", "init_timers", "timeout", "init", "client", "environment_default", "resolve", "stream", "keys", "init_environment", "init_utils", "init_timers", "db", "SEPARATOR", "response", "init", "init_utils", "init_context", "client", "BaseCache", "CacheKey", "TTL", "init_db", "init_context", "init_tenancy", "init_context", "init_constants", "_a", "params", "init_tenancy", "init_db", "init_constants", "init_db", "environment_default", "db", "keys", "init_users", "init_constants", "init_environment", "init_context", "init_environment", "environment_default", "options", "client", "Redlock", "init_tenants", "init_constants", "init_platform", "init_users", "init_tenants", "init_constants", "init_correlation", "init_environment", "init_context", "init_correlation", "environment_default", "getLogParams", "getIdentity", "getTenantId", "getAppId", "getAutomationId", "data", "pino", "db", "import_node_fetch", "init_api", "options", "json", "fetch", "init_accounts", "init_api", "init_environment", "init_constants", "environment_default", "response", "json", "init_accounts", "db", "environment_default", "client", "init_user", "init_tenancy", "init_context", "init_platform", "init_environment", "init_accounts", "init_constants", "tenancy", "init_constants", "json", "environment_default", "response", "apps", "db", "data", "init_utils", "init_environment", "init_constants", "init_context", "init_db", "db", "view", "params", "response", "environment_default", "init_constants", "init_context", "init_db", "init_environment", "rows", "CreateFuncByName", "init_constants", "resolve", "body", "response", "fetch", "json", "index", "params", "rows", "search", "import_node_fetch", "builder", "db", "fn", "init_context", "init_searchIndexes", "init_db", "init_utils", "init_context", "init_searchIndexes", "populateFromDB", "db", "client", "EXPIRY_SECONDS", "init_db", "client", "db", "cache", "response", "get", "init_user", "db", "environment_default", "init_configs", "init_constants", "init_context", "init_environment", "init_configs", "init_analytics", "init_configs", "init_context", "init_environment", "init_context", "PostHog", "environment_default", "group", "init_environment", "init_analytics", "environment_default", "group", "init_environment", "environment_default", "group", "data", "init_environment", "environment_default", "APP_PREFIX", "environment_default", "apps", "options", "resolve", "init_utils", "init_db", "init_constants", "init_environment", "init_tenancy", "init_context", "utils_exports", "init_utils", "import_events", "init_utils", "events", "init_constants", "JobQueue", "_a", "init_constants", "init_context", "environment_default", "BullQueue", "shutdown", "init_environment", "init_utils", "init_timers", "shutdown", "init_queue", "init_constants", "init_context", "init_queue", "init_utils", "init_environment", "fn", "environment_default", "group", "processors", "init", "environment_default", "init_utils", "init_events", "init_db", "init_context", "init_environment", "semver", "init_identification", "init_context", "init_environment", "init_utils", "init_configs", "getIdentity", "environment", "environment_default", "group", "builder", "verified", "db", "recordEvent", "init_backfill", "init_context", "events", "eventKey", "keys", "init", "init_queue", "init", "init_queue", "init_queue", "init_events", "init_identification", "init_backfill", "recordEvent", "init_account", "init_events", "deleted", "created", "init_app", "init_events", "init_auth", "init_events", "created", "deleted", "init_automation", "init_events", "datasource", "created", "updated", "deleted", "init_datasource", "init_events", "init_email", "init_events", "init_license", "init_events", "created", "deleted", "init_layout", "init_events", "init_events", "created", "updated", "deleted", "run", "init_query", "init_events", "datasource", "created", "updated", "deleted", "init_role", "init_events", "created", "deleted", "init_screen", "init_events", "created", "imported", "init_rows", "init_events", "created", "updated", "deleted", "exported", "imported", "init_table", "init_events", "init_serve", "init_events", "created", "updated", "deleted", "init_user", "init_events", "init_context", "created", "view", "updated", "deleted", "exported", "init_view", "init_events", "init_installation", "init_events", "init_backfill", "init_events", "init_environment", "environment_default", "created", "group", "updated", "deleted", "init_events", "init_context", "init", "imported", "deleted", "init_plugin", "init_events", "init_backup", "init_events", "created", "deleted", "init_environmentVariable", "init_events", "search", "init_auditLog", "init_events", "init_account", "init_app", "init_auth", "init_automation", "init_datasource", "init_email", "init_license", "init_layout", "init_query", "init_role", "init_screen", "init_rows", "init_table", "init_serve", "init_user", "init_view", "init_installation", "init_backfill", "init_plugin", "init_backup", "init_environmentVariable", "init_auditLog", "shutdown", "init_events", "init_analytics", "init_identification", "init_backfill", "init_migrations", "init_constants", "init_db", "init_environment", "init_platform", "init_context", "init_migrations", "users_exports", "users", "db", "response", "init_users", "init_db", "init_context", "params", "Role", "cloneDeep", "role", "db", "body", "init_db", "init_context", "environment_default", "init_environment", "init_context", "TenantFeatureFlag", "client", "environment_default", "logWarn", "EXPIRY_SECONDS", "init_environment", "init_utils", "init_context", "init_configs", "init_constants", "init_utils", "init_users", "authenticate", "response", "fetch", "import_node_fetch", "init_sso", "init_db", "init_utils", "init_users", "init_context", "authenticate", "init_utils", "init_sso", "buildVerifyFn", "getCallbackUrl", "strategyFactory", "params", "authenticate", "response", "fetch", "body", "import_node_fetch", "init_sso", "init_utils", "google_exports", "passport", "GoogleStrategy", "db", "datasource", "err", "init_google", "init_constants", "init_utils", "init_db", "init_configs", "init_sso", "init_matchers", "matches", "pattern", "options", "environment_default", "crypto", "SEPARATOR", "init_environment", "SecretOption", "init_errors", "init_errors", "db", "init_constants", "init_utils", "init_user", "init_matchers", "init_db", "init_context", "init_environment", "init_errors", "environment_default", "auditLog_default", "init_auditLog", "init_tenancy", "init_context", "init_matchers", "init_constants", "init_constants", "init_utils", "init_constants", "init_matchers", "correlator", "environment_default", "pino", "init_middleware", "init_environment", "import_uuid", "correlator", "middleware_default", "init_middleware", "init_constants", "uuid", "status", "body", "init_errors", "json", "params", "Joi", "auditLog_default", "middleware_default", "init_middleware", "init_google", "init_utils", "init_auditLog", "init_tenancy", "google_exports", "resolve", "refreshToken", "params", "db", "jwt", "init_auth", "init_context", "init_constants", "init_middleware", "init_user", "init_events", "init_configs", "init_utils", "init_sso", "auditLog_default", "jwt", "init_auth", "joi", "validate", "import_joi", "init_utils", "validate", "init_plugin", "init_utils", "import_path", "import_fs", "init_utils", "init_environment", "environment_default", "fs", "import_node_fetch", "import_path", "import_fs", "import_uuid", "init_environment", "init_utils", "init_db", "stream", "environment_default", "AWS", "client", "path", "fs", "params", "response", "data", "fetch", "zlib", "tar", "environment_default", "getPresignedUrl", "init_environment", "init_app", "init_environment", "environment_default", "getPresignedUrl", "init_global", "init_environment", "init_context", "environment_default", "getPresignedUrl", "init_environment", "init_context", "plugins", "environment_default", "getPresignedUrl", "init_app", "init_global", "objectStore_exports", "init_objectStore", "init_utils", "init_redis", "init_utils", "net", "environment_default", "import_util", "init_environment", "dns", "init_blacklist", "init_context", "init", "init_src", "init_configs", "init_events", "init_migrations", "init_users", "init_accounts", "init_platform", "init_auth", "init_constants", "init_middleware", "init_plugin", "init_queue", "init_db", "init_context", "init_objectStore", "init_redis", "init_utils", "init_errors", "init_timers", "init_environment", "init_blacklist", "init_tenancy", "init_api", "init_license", "init_license", "init_documents", "init_license", "init_init", "init_api", "init_license", "init_documents", "init_init", "client", "init", "shutdown", "getClient", "init_redis", "init_src", "import_node_fetch", "API", "init_api", "init_src", "options", "json", "fetch", "init_api", "utils_exports", "init_utils", "init_src", "Writethrough", "getDB", "bustCache", "init_quotas", "init_src", "init_utils", "db", "response", "bustCache", "utils_exports", "init_quotas", "init_utils", "destroy", "get", "save", "init_src", "db", "response", "db", "fn", "init_src", "db", "createView", "ViewName", "SEPARATOR", "DocumentType", "init_groups", "init_src", "init_views", "init_groups", "destroy", "fetch", "get", "save", "start", "params", "utils_exports", "db", "users", "group", "users_exports", "init_groups", "init_src", "init_views", "pagination", "response", "data", "init_pagination", "db", "SEPARATOR", "AutomationViewMode", "createView", "ViewName", "DocumentType", "init_views", "init_src", "quotas_exports", "init_quotas", "UNLIMITED", "init_quotas", "import_fs", "import_path", "init_version", "init_src", "environment_default", "path", "objectStore_exports", "fs", "utils_exports", "init_misc", "init_constants", "init_quotas", "init_version", "init_misc", "init_sdk", "init_constants", "APP_BACKUP_PREFIX", "db", "params", "pagination", "users", "users_exports", "data", "init_src", "init_pagination", "init_views", "init_constants", "get", "db", "init_environmentVariables", "init_src", "LRU", "init_db", "init_quotas", "init_groups", "init_environmentVariables", "api", "init_src", "init_db", "init_constants", "environment_default", "response", "json", "fn", "users_exports", "body", "fs", "jwt", "import_fs", "import_path", "import_os", "init_src", "environment_default", "activateLicenseKey", "getLicense", "init_licenses", "init_db", "init_cache", "init_constants", "init_src", "refresh", "environment_default", "init_licenses", "EXPIRY_SECONDS", "refresh", "init_cache", "init_redis", "init_licenses", "init_src", "init_constants", "client", "getClient", "getLicense", "environment_default", "cache_exports", "refresh", "init_cache", "activateLicenseKey", "cache_exports", "getLicense", "init_licensing", "init_cache", "init_licenses", "cache_exports", "environment_default", "init_src", "init_licensing", "init_features", "init_features", "init_branding", "set", "triggerQuota", "init_quotas", "init_constants", "init_licensing", "init_db", "init_src", "request", "index", "quotas_exports", "cache_exports", "init_quotas", "init_src", "apps", "init_quotas", "init_rows", "init_quotas", "init_automations", "init_quotas", "utils_exports", "db", "environment_default", "users_exports", "init_quotas", "init_src", "init_groups", "init_quotas", "init_plugins", "init_quotas", "set", "init_users", "init_quotas", "init_src", "users_exports", "init_helpers", "init_rows", "init_automations", "init_groups", "init_plugins", "init_users", "quotas_exports", "bustCache", "set", "utils_exports", "init_quotas", "init_helpers", "api", "init_api", "init_db", "init_src", "environment_default", "data", "response", "options", "init_api", "createActivity", "init_users", "init_api", "data", "users_exports", "createActivity", "init_users", "fn", "response", "init_src", "status", "SEPARATOR", "AutomationViewMode", "DocumentType", "UNICODE_MAX", "db", "params", "response", "pagination", "getQueryIndex", "ViewName", "init_automations", "init_views", "init_src", "init_pagination", "init_constants", "logging_exports", "oldestLogDate", "status", "response", "options", "init_logging", "init_src", "init_automations", "logging_exports", "init_automations", "init_logging", "init_errors", "init_src", "group", "getBulk", "fetch", "get", "save", "remove", "addUsers", "users", "users_exports", "removeUsers", "init_groups", "init_src", "init_db", "init_quotas", "init_errors", "groups_exports", "addUsers", "fetch", "get", "getBulk", "remove", "removeUsers", "save", "init_groups", "fs", "import_fs", "import_path", "db", "hash", "objectStore_exports", "write", "response", "init_plugins", "init_src", "init_quotas", "environment_default", "fetch", "environment", "update", "remove", "init_environmentVariables", "init_src", "init_db", "init_sdk", "environmentVariables_exports", "fetch", "remove", "update", "init_environmentVariables", "utils_exports", "save", "db", "response", "search", "params", "stream", "json", "data", "init_auditLogs", "init_src", "init_views", "init_constants", "exports", "module", "fn", "exports", "module", "dayjs", "options", "exports", "module", "exports", "module", "exports", "module", "start", "matches", "exports", "module", "exports", "module", "cloneDeep", "matches", "path", "data", "exports", "module", "exports", "module", "fn", "exports", "module", "fn", "exports", "module", "process", "processors", "matches", "exports", "module", "exports", "module", "start", "end", "index", "exports", "module", "processors", "process", "matches", "invalidCase", "validCase", "handlebars", "require_src", "exports", "module", "VM", "params", "MAX_DATE", "filter", "search", "deleted", "init_utils", "init_sdk", "init_src", "utils_exports", "users_exports", "save", "user", "app", "deleted", "fetch", "params", "filter", "response", "definitions", "events", "init_auditLogs", "init_src", "init_utils", "auditLogs_exports", "definitions", "fetch", "init_auditLogs", "init", "init_queue", "init_src", "storeAppBackupMetadata", "status", "objectStore_exports", "fetchAppBackups", "path", "backup_default", "init_backup", "init_src", "init_db", "init_queue", "init_features", "init", "data", "updateMetadata", "status", "backup_default", "objectStore_exports", "fs", "path", "import_fs", "init_src", "init_backup", "init_queue", "init", "init_backups", "init_backup", "init_queue", "backup_default", "init_apps", "init_src", "utils_exports", "init_utils", "init_apps", "users_exports", "create", "get", "init", "remove", "update", "init_users", "init_src", "params", "db", "builder", "init", "init_init", "init_backups", "init_users", "init_scim", "init_users", "auditLogs_exports", "environmentVariables_exports", "groups_exports", "init", "quotas_exports", "users_exports", "utils_exports", "init_sdk", "init_branding", "init_licensing", "init_quotas", "init_users", "init_automations", "init_features", "init_groups", "init_plugins", "init_environmentVariables", "init_auditLogs", "init_backups", "init_utils", "init_init", "init_scim", "init_licensing", "init_src", "init_sdk", "init_feature", "init_features", "doInScimContext", "init_src", "init_features", "init_middleware", "init_licensing", "init_feature", "groups_exports", "destroy", "fetch", "find", "save", "updateGroupApps", "init_groups", "group", "get", "response", "addUsers", "removeUsers", "remove", "params", "users", "environmentVariables_exports", "fetch", "create", "update", "destroy", "init_environmentVariables", "init_sdk", "init_src", "init_global", "init_groups", "init_environmentVariables", "Joi", "import_joi", "init_groups", "init_global", "init_middleware", "init_src", "Router", "groups_exports", "Joi", "import_router", "import_joi", "router", "init_environmentVariables", "init_src", "Router", "fetch", "create", "update", "destroy", "search", "auditLogs_exports", "download", "stream", "definitions", "init_auditLogs", "init_sdk", "init_src", "Joi", "import_router", "import_joi", "router", "init_auditLogs", "init_src", "Router", "search", "download", "definitions", "utils_exports", "body", "response", "path", "fs", "import_fs", "init_backups", "init_sdk", "init_src", "Joi", "import_router", "import_joi", "router", "init_backups", "init_src", "Router", "body", "Joi", "import_router", "import_joi", "router", "init_schedules", "init_middleware", "init_src", "Router", "request", "get", "find", "create", "update", "remove", "init_users", "init_src", "init_sdk", "users_exports", "init_constants", "init_helpers", "init_helpers", "removeKeyNumbering", "init_constants", "init_helpers", "datasource", "filter", "parse", "utils_exports", "init_utils", "init_src", "init_constants", "init_helpers", "init_utils", "group", "import_scim_patch", "get", "create", "find", "remove", "update", "init_groups", "init_src", "groups_exports", "response", "_", "users_exports", "utils_exports", "import_router", "router", "init_scim", "init_middleware", "init_users", "init_groups", "Router", "doInScimContext", "get", "find", "create", "update", "remove", "init_api", "init_groups", "init_environmentVariables", "init_auditLogs", "init_backups", "init_schedules", "init_scim", "users_exports", "utils_exports", "import_scim2_parse_filter", "init_users", "init_src", "response", "unreachable", "filter", "parseFilters", "groups_exports", "init_groups", "group", "groups_exports", "users_exports", "init_users", "init_groups", "init_src", "init_sdk", "init_constants", "init_middleware", "init_api", "v4", "init_newid", "getDocParams", "DocumentType", "SEPARATOR", "rows", "StaticDatabases", "APP_PREFIX", "APP_DEV_PREFIX", "isDevAppID", "isProdAppID", "ViewName", "UNICODE_MAX", "generateAppID", "generateRoleID", "getRoleParams", "getQueryIndex", "getRowParams", "generateRowID", "getUserMetadataParams", "generateUserMetadataID", "getGlobalIDFromUserMetadataID", "init_utils", "init_newid", "init_src", "resolve", "checkSlashesInUrl", "import_stream", "isDev", "init_utilities", "init_src", "init_utils", "stream", "NoEmptyFilterStrings", "ObjectStoreBuckets", "init_constants", "init_src", "InvalidColumns", "objectStore_exports", "budibaseTempDir", "init_src", "objectStore_exports", "import_fs", "import_path", "uuid", "path", "budibaseTempDir", "fs", "tar", "init_constants", "init_src", "import_path", "init_app", "init_constants", "init_src", "path", "hash", "fs", "objectStore_exports", "import_fs", "import_path", "init_plugin", "init_src", "budibaseTempDir", "pkg", "init_constants", "init_src", "objectStore_exports", "ObjectStoreBuckets", "init_fileSystem", "init_app", "init_plugin", "init_constants", "budibaseTempDir", "uuid", "tar", "db", "path", "fs", "MemoryStream", "objectStore_exports", "ObjectStoreBuckets", "import_fs", "import_path", "init_exports", "init_src", "init_fileSystem", "init_constants", "init_utils", "db", "rows", "automations", "fs", "budibaseTempDir", "uuid", "tar", "path", "objectStore_exports", "ObjectStoreBuckets", "import_path", "import_fs", "init_src", "init_utils", "init_constants", "init_fileSystem", "init_sdk", "db", "init_src", "init_utils", "backups_default", "init_backups", "init_exports", "DocumentType", "datasource", "init_utils", "init_constants", "SEPARATOR", "getEnvironmentVariables", "environmentVariables_exports", "init_utils", "init_src", "schema", "knex", "init_utils", "init_constants", "client", "json", "client", "start", "end", "parse", "body", "json", "knex", "import_knex", "init_src", "init_utils", "fn", "relationships", "builder", "response", "init_utils", "init_utilities", "response", "resolve", "client", "matches", "json", "init", "AWS", "import_lodash", "import_aws_sdk", "SCHEMA", "AWS", "response", "params", "SCHEMA", "options", "response", "json", "params", "db", "SCHEMA", "index", "json", "SCHEMA", "init_src", "response", "SCHEMA", "init_utils", "response", "client", "request", "definition", "schema", "json", "import_aws_sdk", "SCHEMA", "AWS", "response", "params", "stream", "resolve", "csv", "SCHEMA", "Airtable", "json", "matches", "dayjs", "SCHEMA", "init_utils", "init_utilities", "response", "mysql", "json", "SCHEMA", "response", "import_lodash", "import_node_fetch", "SCHEMA", "init_utilities", "init_src", "response", "pagination", "data", "keys", "path", "params", "qs", "body", "FormData", "fetch", "import_node_fetch", "SCHEMA", "init_utils", "init_src", "init_constants", "response", "fetch", "json", "rows", "filtered", "SCHEMA", "SCHEMA", "redis_default", "init_redis", "Redis", "response", "SCHEMA", "SCHEMA", "init_utils", "init_constants", "response", "options", "json", "definition", "DEFINITIONS", "plugins", "import_lodash", "init_integrations", "init_redis", "init_fileSystem", "init_sdk", "redis_default", "enrich", "get", "datasource", "getEnvironmentVariables", "definition", "response", "definitions", "update", "old", "_", "import_lodash", "init_datasources", "init_src", "init_utils", "init_integrations", "init_datasources", "db", "datasource", "init_src", "init_utils", "init_datasources", "webhook_exports", "destroy", "save", "db", "response", "init_webhook", "init_src", "init_utils", "init_automations", "init_webhook", "webhook_exports", "groups_exports", "db", "getGlobalIDFromUserMetadataID", "users", "globalUser", "init_global", "init_utils", "init_src", "users", "db", "generateUserMetadataID", "user", "init_src", "init_sdk", "init_global", "init_utils", "utils_exports", "init_utils", "init_utils", "utils_exports", "getEnvironmentVariables", "import_string_templates", "init_queries", "init_utils", "init_queries", "params", "DocumentType", "SEPARATOR", "db", "rows", "init_src", "init_utils", "init_constants", "db", "response", "getRowParams", "init_rows", "init_src", "init_utils", "rows_default", "init_rows", "utils_exports", "generateUserMetadataID", "newDoc", "db", "getUserMetadataParams", "users", "data", "getGlobalIDFromUserMetadataID", "import_lodash", "init_utils", "init_global", "init_src", "init_users", "init_utils", "utils_exports", "path", "init_fileSystem", "init_redis", "init_src", "init_utils", "init_utils", "init_redis", "init_src", "init_utils", "init_src", "init_utils", "init_src", "init_utils", "init_global", "init_src", "init_src", "init_client", "init_src", "init_client", "plugins_exports", "fetch", "db", "response", "plugins", "objectStore_exports", "init_plugins", "init_src", "init_plugins", "plugins_exports", "init_sdk", "init_backups", "init_automations", "init_datasources", "init_queries", "init_rows", "init_users", "init_plugins", "backups_default", "rows_default", "init_automations", "import_string_templates", "init_sdk", "init_automations", "db", "init_users", "init_utils", "init_global", "init_src", "users", "generateUserMetadataID", "db", "init_user", "init_utils", "init_global", "init_users", "init_src", "init_sdk", "datasource", "json", "Integration", "init_query", "init_integrations", "init_sdk", "csv", "rows", "Format", "utils_exports", "validate", "json", "datasource", "db", "cloneDeep", "rows", "init_utils", "init_user", "init_constants", "init_src", "init_query", "init_sdk", "definition", "run", "import_string_templates", "definition", "run", "response", "Model", "execute", "init_src", "init", "init_src", "getClient", "init", "cache", "response", "workerFarm", "timeout", "resolve", "response", "definition", "definition", "definition", "definition", "definition", "definition", "init_src", "init_src", "import_api", "init_newid", "init_utilities", "init_constants", "init_src", "init_utils", "import_fp", "init_sdk", "import_node_fetch", "init_utilities", "init_src", "init_global", "request", "environment_default", "response", "fetch", "checkSlashesInUrl", "definition", "run", "response", "init_src", "destroy", "fetch", "find", "save", "search", "init_utils", "init_constants", "init_src", "init_utils", "DocumentType", "SEPARATOR", "db", "view", "ViewName", "init_src", "db", "params", "getQueryIndex", "ViewName", "init_utils", "init_constants", "init_src", "init_utils", "init_constants", "users", "getUserMetadataParams", "response", "Sentry", "import_lodash", "init_constants", "init_utils", "init_global", "init_constants", "init_constants", "import_string_templates", "rows", "init_constants", "init_src", "init_utils", "init_constants", "init_src", "cloneDeep", "rows", "objectStore_exports", "row", "ObjectStoreBuckets", "init_src", "rows", "db", "users", "link", "row", "init_utils", "init_user", "init_constants", "init_utils", "init_src", "paginatedSearch", "params", "fullSearch", "init_global", "init_newid", "init_src", "Pouch", "emit", "init_utils", "init_src", "filter", "calculation", "db", "view", "import_fp", "init_src", "init_utils", "init_constants", "init_src", "isEqual", "cloneDeep", "db", "db", "cloneDeep", "isEqual", "response", "init_fileSystem", "init_utils", "db", "rows", "response", "getRowParams", "dbTable", "validate", "save", "generateRowID", "DocumentType", "fetch", "calculation", "group", "data", "find", "destroy", "search", "params", "paginatedSearch", "fullSearch", "exportRows", "csv", "row", "tableId", "index", "bulkDestroy", "destroy", "exportRows", "fetch", "fetchEnrichedRow", "fetchView", "find", "patch", "save", "search", "init_constants", "init_utils", "init_utils", "init_constants", "import_string_templates", "import_fp", "init_src", "init_sdk", "field", "filter", "datasource", "rows", "definition", "tableId", "response", "row", "linkPrimary", "linkSecondary", "body", "table", "json", "init_fileSystem", "init_sdk", "init_utils", "cleanExportRows", "NoEmptyFilterStrings", "patch", "validate", "save", "fetchView", "fetch", "find", "response", "destroy", "bulkDestroy", "rows", "search", "params", "exportRows", "datasource", "fetchEnrichedRow", "init_utils", "patch", "body", "save", "quotas_exports", "destroy", "response", "rows", "quotas_exports", "row", "search", "status", "emitter", "definition", "run", "emitter", "save", "definition", "run", "emitter", "patch", "definition", "run", "emitter", "destroy", "import_node_fetch", "fetch", "definition", "run", "emitter", "init_utils", "init_constants", "init_utils", "init_utils", "init_constants", "init_constants", "init_utils", "import_lodash", "init_constants", "init_constants", "import_fp", "init_src", "init_src", "init_constants", "import_string_templates", "import_fp", "import_lodash", "init_src", "init_sdk", "init_src", "import_lodash", "import_fp", "init_sdk", "init_constants", "init_integrations", "init_utils", "init_src", "init_sdk", "init_src", "import_joi", "Joi", "init_utils", "import_openapi_types", "methods", "init_src", "init_src", "init_sdk", "Runner", "utils_exports", "execute", "db", "datasource", "Runner", "rows", "pagination", "quotas_exports", "execute", "definition", "run", "emitter", "data", "rest", "import_node_fetch", "RequestType", "definition", "run", "request", "response", "fetch", "status", "definition", "run", "import_node_fetch", "definition", "run", "response", "fetch", "status", "import_node_fetch", "definition", "run", "response", "fetch", "status", "import_node_fetch", "definition", "run", "body", "response", "fetch", "status", "import_node_fetch", "definition", "run", "body", "response", "fetch", "status", "definition", "run", "init_utilities", "definition", "run", "init_utils", "init_constants", "init_query", "init_src", "init_sdk", "cloneDeep", "init_utils", "init_src", "init_sdk", "import_csvtojson", "find", "init_constants", "SortOrder", "EmptyFilterOption", "definition", "getTable", "find", "filter", "run", "rows", "search", "definition", "init_sdk", "init_fileSystem", "run", "definition", "plugins", "emitter", "import_events", "init_src", "init_src", "init_utils", "init_constants", "init_src", "storeLog", "init_src", "import_string_templates", "import_fp", "init_utils", "CRON_STEP_ID", "db", "storeLog", "getEnvironmentVariables", "isProdAppID", "index", "innerValue", "execute", "response"]
|
|
7
|
+
}
|