@budibase/server 0.9.188 → 0.9.190-alpha.2
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/Dockerfile +7 -1
- package/__mocks__/mssql.ts +1 -1
- package/__mocks__/oracledb.ts +31 -0
- package/__mocks__/pg.ts +3 -0
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.7d405e74.css +1 -0
- package/builder/assets/index.edea4fa5.js +1316 -0
- package/builder/assets/oracle.66592424.png +0 -0
- package/builder/assets/vendor.470042a4.js +152 -0
- package/builder/assets/vendor.5e1fe644.css +1 -0
- package/builder/index.html +4 -4
- package/coverage/clover.xml +1507 -1081
- package/coverage/coverage-final.json +93 -89
- package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
- package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
- package/coverage/lcov-report/api/controllers/application.js.html +64 -13
- package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
- package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
- package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +4 -4
- package/coverage/lcov-report/api/controllers/datasource.js.html +232 -28
- package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
- package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
- package/coverage/lcov-report/api/controllers/index.html +91 -91
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
- package/coverage/lcov-report/api/controllers/query.js.html +53 -209
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
- package/coverage/lcov-report/api/controllers/row/external.js.html +17 -8
- package/coverage/lcov-report/api/controllers/row/index.html +26 -26
- package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
- package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
- package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
- package/coverage/lcov-report/api/controllers/script.js.html +3 -3
- package/coverage/lcov-report/api/controllers/table/external.js.html +1001 -0
- package/coverage/lcov-report/api/controllers/table/index.html +56 -26
- package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
- package/coverage/lcov-report/api/controllers/table/internal.js.html +545 -0
- package/coverage/lcov-report/api/controllers/table/utils.js.html +175 -52
- package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
- package/coverage/lcov-report/api/controllers/user.js.html +390 -33
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +19 -4
- package/coverage/lcov-report/api/controllers/view/index.html +22 -22
- package/coverage/lcov-report/api/controllers/view/index.js.html +52 -13
- package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
- package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
- package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/routes/application.js.html +1 -1
- package/coverage/lcov-report/api/routes/auth.js.html +1 -1
- package/coverage/lcov-report/api/routes/automation.js.html +1 -1
- package/coverage/lcov-report/api/routes/backup.js.html +1 -1
- package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
- package/coverage/lcov-report/api/routes/component.js.html +1 -1
- package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
- package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
- package/coverage/lcov-report/api/routes/dev.js.html +2 -2
- package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +4 -4
- package/coverage/lcov-report/api/routes/index.js.html +1 -1
- package/coverage/lcov-report/api/routes/integration.js.html +1 -1
- package/coverage/lcov-report/api/routes/layout.js.html +1 -1
- package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
- package/coverage/lcov-report/api/routes/permission.js.html +1 -1
- package/coverage/lcov-report/api/routes/query.js.html +5 -2
- package/coverage/lcov-report/api/routes/role.js.html +1 -1
- package/coverage/lcov-report/api/routes/routing.js.html +1 -1
- package/coverage/lcov-report/api/routes/row.js.html +1 -1
- package/coverage/lcov-report/api/routes/screen.js.html +1 -1
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/static.js.html +2 -2
- package/coverage/lcov-report/api/routes/table.js.html +35 -2
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +17 -2
- package/coverage/lcov-report/api/routes/view.js.html +1 -1
- package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/actions.js.html +2 -2
- package/coverage/lcov-report/automations/automationUtils.js.html +4 -4
- package/coverage/lcov-report/automations/bullboard.js.html +71 -20
- package/coverage/lcov-report/automations/index.html +35 -50
- package/coverage/lcov-report/automations/index.js.html +2 -2
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +14 -14
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
- package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
- package/coverage/lcov-report/automations/triggers.js.html +22 -10
- package/coverage/lcov-report/automations/utils.js.html +42 -12
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +87 -21
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/client.js.html +2 -2
- package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
- package/coverage/lcov-report/db/index.html +2 -2
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
- package/coverage/lcov-report/db/linkedRows/index.html +10 -10
- package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
- package/coverage/lcov-report/db/newid.js.html +3 -3
- package/coverage/lcov-report/db/utils.js.html +57 -57
- package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
- package/coverage/lcov-report/events/index.html +6 -6
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +5 -5
- package/coverage/lcov-report/index.html +106 -91
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
- package/coverage/lcov-report/middleware/authorized.js.html +11 -8
- package/coverage/lcov-report/middleware/builder.js.html +16 -7
- package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
- package/coverage/lcov-report/middleware/index.html +23 -23
- package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
- package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
- package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
- package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
- package/coverage/lcov-report/middleware/utils.js.html +1 -1
- package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +90 -33
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +278 -0
- package/coverage/lcov-report/threads/query.js.html +278 -0
- package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +144 -15
- package/coverage/lcov-report/utilities/global.js.html +26 -11
- package/coverage/lcov-report/utilities/index.html +48 -48
- package/coverage/lcov-report/utilities/index.js.html +47 -14
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
- package/coverage/lcov-report/utilities/queue/index.html +14 -14
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
- package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
- package/coverage/lcov-report/utilities/security.js.html +3 -3
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
- package/coverage/lcov.info +2495 -1737
- package/dist/api/controllers/application.js +15 -1
- package/dist/api/controllers/auth.js +3 -3
- package/dist/api/controllers/datasource.js +67 -16
- package/dist/api/controllers/deploy/index.js +2 -0
- package/dist/api/controllers/dev.js +4 -1
- package/dist/api/controllers/query.js +30 -58
- package/dist/api/controllers/row/ExternalRequest.js +78 -34
- package/dist/api/controllers/row/external.js +3 -1
- package/dist/api/controllers/row/utils.js +6 -12
- package/dist/api/controllers/table/external.js +249 -0
- package/dist/api/controllers/table/index.js +49 -123
- package/dist/api/controllers/table/internal.js +150 -0
- package/dist/api/controllers/table/utils.js +62 -28
- package/dist/api/controllers/user.js +123 -11
- package/dist/api/controllers/view/exporters.js +4 -0
- package/dist/api/controllers/view/index.js +14 -2
- package/dist/api/routes/query.js +1 -1
- package/dist/api/routes/table.js +7 -1
- package/dist/api/routes/user.js +2 -1
- package/dist/app.js +2 -11
- package/dist/automations/bullboard.js +37 -10
- package/dist/automations/triggers.js +7 -3
- package/dist/automations/utils.js +11 -2
- package/dist/constants/index.js +19 -0
- package/dist/definitions/datasource.js +5 -0
- package/dist/environment.js +13 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/datasourcePlus.js +2 -0
- package/dist/integrations/base/sql.js +353 -177
- package/dist/integrations/base/sqlTable.js +143 -0
- package/dist/integrations/base/utils.js +30 -0
- package/dist/integrations/index.js +6 -0
- package/dist/integrations/microsoftSqlServer.js +117 -9
- package/dist/integrations/mysql.js +16 -85
- package/dist/integrations/oracle.js +347 -0
- package/dist/integrations/postgres.js +35 -28
- package/dist/integrations/utils.js +71 -9
- package/dist/middleware/authorized.js +2 -1
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +12 -7
- package/dist/tests/utilities/TestConfiguration.js +2 -1
- package/dist/{automations/thread.js → threads/automation.js} +26 -8
- package/dist/threads/index.js +64 -0
- package/dist/threads/query.js +64 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/csvParser.js +46 -5
- package/dist/utilities/global.js +6 -2
- package/dist/utilities/index.js +11 -0
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +13 -8
- package/scripts/dev/manage.js +1 -0
- package/scripts/integrations/mssql/data/Dockerfile +9 -0
- package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
- package/scripts/integrations/mssql/data/setup.sql +54 -0
- package/scripts/integrations/mssql/docker-compose.yaml +12 -0
- package/scripts/integrations/mssql/reset.sh +3 -0
- package/scripts/integrations/oracle/docker-compose.yml +19 -0
- package/scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip +0 -0
- package/scripts/integrations/oracle/instantclient/linux/x86-64/install.sh +23 -0
- package/scripts/integrations/oracle/oracle.md +90 -0
- package/scripts/integrations/postgres/docker-compose.yml +3 -3
- package/scripts/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +18 -1
- package/src/api/controllers/auth.js +3 -0
- package/src/api/controllers/datasource.js +84 -16
- package/src/api/controllers/deploy/index.js +2 -0
- package/src/api/controllers/dev.js +4 -1
- package/src/api/controllers/query.js +29 -81
- package/src/api/controllers/row/ExternalRequest.ts +91 -36
- package/src/api/controllers/row/external.js +4 -1
- package/src/api/controllers/row/utils.js +8 -11
- package/src/api/controllers/table/external.js +307 -0
- package/src/api/controllers/table/index.js +47 -137
- package/src/api/controllers/table/internal.js +155 -0
- package/src/api/controllers/table/utils.js +74 -33
- package/src/api/controllers/user.js +132 -13
- package/src/api/controllers/view/exporters.js +5 -0
- package/src/api/controllers/view/index.js +15 -2
- package/src/api/routes/query.js +1 -0
- package/src/api/routes/table.js +11 -0
- package/src/api/routes/tests/datasource.spec.js +2 -2
- package/src/api/routes/tests/misc.spec.js +5 -1
- package/src/api/routes/tests/query.spec.js +0 -1
- package/src/api/routes/user.js +5 -0
- package/src/app.ts +2 -10
- package/src/automations/bullboard.js +28 -11
- package/src/automations/tests/automation.spec.js +3 -4
- package/src/automations/triggers.js +7 -3
- package/src/automations/utils.js +12 -2
- package/src/constants/index.js +22 -0
- package/src/definitions/common.ts +7 -1
- package/src/definitions/datasource.ts +10 -3
- package/src/environment.js +15 -0
- package/src/integrations/airtable.ts +2 -1
- package/src/integrations/arangodb.ts +2 -1
- package/src/integrations/base/IntegrationBase.ts +6 -0
- package/src/integrations/base/datasourcePlus.ts +9 -0
- package/src/integrations/base/sql.ts +377 -218
- package/src/integrations/base/sqlTable.ts +180 -0
- package/src/integrations/base/utils.ts +22 -0
- package/src/integrations/couchdb.ts +2 -1
- package/src/integrations/dynamodb.ts +2 -1
- package/src/integrations/elasticsearch.ts +2 -1
- package/src/integrations/index.ts +7 -0
- package/src/integrations/microsoftSqlServer.ts +145 -13
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +23 -95
- package/src/integrations/oracle.ts +458 -0
- package/src/integrations/postgres.ts +45 -35
- package/src/integrations/rest.ts +2 -1
- package/src/integrations/s3.ts +2 -1
- package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
- package/src/integrations/tests/oracle.spec.js +94 -0
- package/src/integrations/tests/postgres.spec.js +4 -0
- package/src/integrations/utils.ts +78 -8
- package/src/middleware/authorized.js +2 -1
- package/src/middleware/builder.js +4 -1
- package/src/tests/utilities/TestConfiguration.js +2 -1
- package/src/{automations/thread.js → threads/automation.js} +27 -8
- package/src/threads/index.js +66 -0
- package/src/threads/query.js +66 -0
- package/src/utilities/csvParser.js +48 -5
- package/src/utilities/global.js +7 -2
- package/src/utilities/index.js +11 -0
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/scriptRunner.js +4 -1
- package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
- package/src/utilities/tests/csvParser.spec.js +3 -0
- package/tsconfig.json +1 -1
- package/builder/assets/index.550fdba7.js +0 -201
- package/builder/assets/index.7469e1e4.css +0 -29
- package/builder/assets/vendor.278a305c.js +0 -9
- package/builder/assets/vendor.d75d5eb7.css +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const oracledb = require("oracledb")
|
|
2
|
+
const OracleIntegration = require("../oracle")
|
|
3
|
+
jest.mock("oracledb")
|
|
4
|
+
|
|
5
|
+
class TestConfiguration {
|
|
6
|
+
constructor(config = {}) {
|
|
7
|
+
this.integration = new OracleIntegration.integration(config)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const options = { autoCommit: true }
|
|
12
|
+
|
|
13
|
+
describe("Oracle Integration", () => {
|
|
14
|
+
let config
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
jest.clearAllMocks()
|
|
18
|
+
config = new TestConfiguration()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
expect(oracledb.closeMock).toHaveBeenCalled()
|
|
23
|
+
expect(oracledb.closeMock).toHaveBeenCalledTimes(1)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("calls the create method with the correct params", async () => {
|
|
27
|
+
const sql = "insert into users (name, age) values ('Joe', 123);"
|
|
28
|
+
await config.integration.create({
|
|
29
|
+
sql
|
|
30
|
+
})
|
|
31
|
+
expect(oracledb.executeMock).toHaveBeenCalledWith(sql, [], options)
|
|
32
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("calls the read method with the correct params", async () => {
|
|
36
|
+
const sql = "select * from users;"
|
|
37
|
+
await config.integration.read({
|
|
38
|
+
sql
|
|
39
|
+
})
|
|
40
|
+
expect(oracledb.executeMock).toHaveBeenCalledWith(sql, [], options)
|
|
41
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it("calls the update method with the correct params", async () => {
|
|
45
|
+
const sql = "update table users set name = 'test';"
|
|
46
|
+
const response = await config.integration.update({
|
|
47
|
+
sql
|
|
48
|
+
})
|
|
49
|
+
expect(oracledb.executeMock).toHaveBeenCalledWith(sql, [], options)
|
|
50
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("calls the delete method with the correct params", async () => {
|
|
54
|
+
const sql = "delete from users where name = 'todelete';"
|
|
55
|
+
await config.integration.delete({
|
|
56
|
+
sql
|
|
57
|
+
})
|
|
58
|
+
expect(oracledb.executeMock).toHaveBeenCalledWith(sql, [], options)
|
|
59
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe("no rows returned", () => {
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
oracledb.executeMock.mockImplementation(() => ({ rows: [] }))
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it("returns the correct response when the create response has no rows", async () => {
|
|
68
|
+
const sql = "insert into users (name, age) values ('Joe', 123);"
|
|
69
|
+
const response = await config.integration.create({
|
|
70
|
+
sql
|
|
71
|
+
})
|
|
72
|
+
expect(response).toEqual([{ created: true }])
|
|
73
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it("returns the correct response when the update response has no rows", async () => {
|
|
77
|
+
const sql = "update table users set name = 'test';"
|
|
78
|
+
const response = await config.integration.update({
|
|
79
|
+
sql
|
|
80
|
+
})
|
|
81
|
+
expect(response).toEqual([{ updated: true }])
|
|
82
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it("returns the correct response when the delete response has no rows", async () => {
|
|
86
|
+
const sql = "delete from users where name = 'todelete';"
|
|
87
|
+
const response = await config.integration.delete({
|
|
88
|
+
sql
|
|
89
|
+
})
|
|
90
|
+
expect(response).toEqual([{ deleted: true }])
|
|
91
|
+
expect(oracledb.executeMock).toHaveBeenCalledTimes(1)
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
})
|
|
@@ -15,6 +15,10 @@ describe("Postgres Integration", () => {
|
|
|
15
15
|
config = new TestConfiguration()
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
+
it("calls the connection callback", async () => {
|
|
19
|
+
expect(pg.on).toHaveBeenCalledWith('connect', expect.anything())
|
|
20
|
+
})
|
|
21
|
+
|
|
18
22
|
it("calls the create method with the correct params", async () => {
|
|
19
23
|
const sql = "insert into users (name, age) values ('Joe', 123);"
|
|
20
24
|
await config.integration.create({
|
|
@@ -1,12 +1,54 @@
|
|
|
1
1
|
import { SqlQuery } from "../definitions/datasource"
|
|
2
|
-
import { Datasource } from "../definitions/common"
|
|
2
|
+
import { Datasource, Table } from "../definitions/common"
|
|
3
3
|
import { SourceNames } from "../definitions/datasource"
|
|
4
4
|
const { DocumentTypes, SEPARATOR } = require("../db/utils")
|
|
5
|
-
const {
|
|
5
|
+
const {
|
|
6
|
+
FieldTypes,
|
|
7
|
+
BuildSchemaErrors,
|
|
8
|
+
InvalidColumns,
|
|
9
|
+
} = require("../constants")
|
|
6
10
|
|
|
7
11
|
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
|
|
8
12
|
const ROW_ID_REGEX = /^\[.*]$/g
|
|
9
13
|
|
|
14
|
+
const SQL_TYPE_MAP = {
|
|
15
|
+
text: FieldTypes.LONGFORM,
|
|
16
|
+
varchar: FieldTypes.STRING,
|
|
17
|
+
integer: FieldTypes.NUMBER,
|
|
18
|
+
bigint: FieldTypes.NUMBER,
|
|
19
|
+
decimal: FieldTypes.NUMBER,
|
|
20
|
+
smallint: FieldTypes.NUMBER,
|
|
21
|
+
real: FieldTypes.NUMBER,
|
|
22
|
+
"double precision": FieldTypes.NUMBER,
|
|
23
|
+
timestamp: FieldTypes.DATETIME,
|
|
24
|
+
time: FieldTypes.DATETIME,
|
|
25
|
+
boolean: FieldTypes.BOOLEAN,
|
|
26
|
+
json: FieldTypes.JSON,
|
|
27
|
+
date: FieldTypes.DATETIME,
|
|
28
|
+
blob: FieldTypes.LONGFORM,
|
|
29
|
+
enum: FieldTypes.STRING,
|
|
30
|
+
float: FieldTypes.NUMBER,
|
|
31
|
+
int: FieldTypes.NUMBER,
|
|
32
|
+
numeric: FieldTypes.NUMBER,
|
|
33
|
+
mediumint: FieldTypes.NUMBER,
|
|
34
|
+
dec: FieldTypes.NUMBER,
|
|
35
|
+
double: FieldTypes.NUMBER,
|
|
36
|
+
fixed: FieldTypes.NUMBER,
|
|
37
|
+
datetime: FieldTypes.DATETIME,
|
|
38
|
+
tinyint: FieldTypes.BOOLEAN,
|
|
39
|
+
long: FieldTypes.LONGFORM,
|
|
40
|
+
number: FieldTypes.NUMBER,
|
|
41
|
+
binary_float: FieldTypes.NUMBER,
|
|
42
|
+
binary_double: FieldTypes.NUMBER,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export enum SqlClients {
|
|
46
|
+
MS_SQL = "mssql",
|
|
47
|
+
POSTGRES = "pg",
|
|
48
|
+
MY_SQL = "mysql",
|
|
49
|
+
ORACLE = "oracledb",
|
|
50
|
+
}
|
|
51
|
+
|
|
10
52
|
export function isExternalTable(tableId: string) {
|
|
11
53
|
return tableId.includes(DocumentTypes.DATASOURCE)
|
|
12
54
|
}
|
|
@@ -68,8 +110,8 @@ export function breakRowIdField(_id: string | { _id: string }): any[] {
|
|
|
68
110
|
}
|
|
69
111
|
}
|
|
70
112
|
|
|
71
|
-
export function
|
|
72
|
-
for (let [external, internal] of Object.entries(
|
|
113
|
+
export function convertSqlType(type: string) {
|
|
114
|
+
for (let [external, internal] of Object.entries(SQL_TYPE_MAP)) {
|
|
73
115
|
if (type.toLowerCase().includes(external)) {
|
|
74
116
|
return internal
|
|
75
117
|
}
|
|
@@ -102,14 +144,14 @@ export function isIsoDateString(str: string) {
|
|
|
102
144
|
}
|
|
103
145
|
|
|
104
146
|
// add the existing relationships from the entities if they exist, to prevent them from being overridden
|
|
105
|
-
|
|
147
|
+
function copyExistingPropsOver(
|
|
106
148
|
tableName: string,
|
|
107
|
-
|
|
149
|
+
table: Table,
|
|
108
150
|
entities: { [key: string]: any }
|
|
109
151
|
) {
|
|
110
152
|
if (entities && entities[tableName]) {
|
|
111
153
|
if (entities[tableName].primaryDisplay) {
|
|
112
|
-
|
|
154
|
+
table.primaryDisplay = entities[tableName].primaryDisplay
|
|
113
155
|
}
|
|
114
156
|
const existingTableSchema = entities[tableName].schema
|
|
115
157
|
for (let key in existingTableSchema) {
|
|
@@ -117,8 +159,36 @@ export function copyExistingPropsOver(
|
|
|
117
159
|
continue
|
|
118
160
|
}
|
|
119
161
|
if (existingTableSchema[key].type === "link") {
|
|
120
|
-
|
|
162
|
+
table.schema[key] = existingTableSchema[key]
|
|
121
163
|
}
|
|
122
164
|
}
|
|
123
165
|
}
|
|
166
|
+
return table
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function finaliseExternalTables(
|
|
170
|
+
tables: { [key: string]: any },
|
|
171
|
+
entities: { [key: string]: any }
|
|
172
|
+
) {
|
|
173
|
+
const invalidColumns = Object.values(InvalidColumns)
|
|
174
|
+
let finalTables: { [key: string]: any } = {}
|
|
175
|
+
const errors: { [key: string]: string } = {}
|
|
176
|
+
for (let [name, table] of Object.entries(tables)) {
|
|
177
|
+
const schemaFields = Object.keys(table.schema)
|
|
178
|
+
// make sure every table has a key
|
|
179
|
+
if (table.primary == null || table.primary.length === 0) {
|
|
180
|
+
errors[name] = BuildSchemaErrors.NO_KEY
|
|
181
|
+
continue
|
|
182
|
+
} else if (schemaFields.find(field => invalidColumns.includes(field))) {
|
|
183
|
+
errors[name] = BuildSchemaErrors.INVALID_COLUMN
|
|
184
|
+
continue
|
|
185
|
+
}
|
|
186
|
+
// make sure all previous props have been added back
|
|
187
|
+
finalTables[name] = copyExistingPropsOver(name, table, entities)
|
|
188
|
+
}
|
|
189
|
+
// sort the tables by name
|
|
190
|
+
finalTables = Object.entries(finalTables)
|
|
191
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
192
|
+
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {})
|
|
193
|
+
return { tables: finalTables, errors }
|
|
124
194
|
}
|
|
@@ -18,7 +18,8 @@ module.exports =
|
|
|
18
18
|
(permType, permLevel = null) =>
|
|
19
19
|
async (ctx, next) => {
|
|
20
20
|
// webhooks don't need authentication, each webhook unique
|
|
21
|
-
|
|
21
|
+
// also internal requests (between services) don't need authorized
|
|
22
|
+
if (isWebhookEndpoint(ctx) || ctx.internal) {
|
|
22
23
|
return next()
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
const CouchDB = require("../db")
|
|
9
9
|
const { DocumentTypes } = require("../db/utils")
|
|
10
10
|
const { PermissionTypes } = require("@budibase/auth/permissions")
|
|
11
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
11
12
|
|
|
12
13
|
const DEBOUNCE_TIME_SEC = 30
|
|
13
14
|
|
|
@@ -50,7 +51,9 @@ async function updateAppUpdatedAt(ctx) {
|
|
|
50
51
|
const db = new CouchDB(appId)
|
|
51
52
|
const metadata = await db.get(DocumentTypes.APP_METADATA)
|
|
52
53
|
metadata.updatedAt = new Date().toISOString()
|
|
53
|
-
await db.put(metadata)
|
|
54
|
+
const response = await db.put(metadata)
|
|
55
|
+
metadata._rev = response.rev
|
|
56
|
+
await appCache.invalidateAppMetadata(appId, metadata)
|
|
54
57
|
// set a new debounce record with a short TTL
|
|
55
58
|
await setDebounce(appId, DEBOUNCE_TIME_SEC)
|
|
56
59
|
}
|
|
@@ -311,7 +311,8 @@ class TestConfiguration {
|
|
|
311
311
|
|
|
312
312
|
async createDatasource(config = null) {
|
|
313
313
|
config = config || basicDatasource()
|
|
314
|
-
|
|
314
|
+
const response = await this._req(config, null, controllers.datasource.save)
|
|
315
|
+
this.datasource = response.datasource
|
|
315
316
|
return this.datasource
|
|
316
317
|
}
|
|
317
318
|
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
// when thread starts, make sure it is recorded
|
|
2
|
+
const env = require("../environment")
|
|
3
|
+
env.setInThread()
|
|
4
|
+
const actions = require("../automations/actions")
|
|
5
|
+
const automationUtils = require("../automations/automationUtils")
|
|
3
6
|
const AutomationEmitter = require("../events/AutomationEmitter")
|
|
4
7
|
const { processObject } = require("@budibase/string-templates")
|
|
5
8
|
const { DEFAULT_TENANT_ID } = require("@budibase/auth").constants
|
|
6
9
|
const CouchDB = require("../db")
|
|
7
10
|
const { DocumentTypes, isDevAppID } = require("../db/utils")
|
|
8
11
|
const { doInTenant } = require("@budibase/auth/tenancy")
|
|
9
|
-
const env = require("../environment")
|
|
10
12
|
const usage = require("../utilities/usageQuota")
|
|
13
|
+
const { definitions: triggerDefs } = require("../automations/triggerInfo")
|
|
11
14
|
|
|
12
15
|
const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
|
|
16
|
+
const CRON_STEP_ID = triggerDefs.CRON.stepId
|
|
13
17
|
const STOPPED_STATUS = { success: false, status: "STOPPED" }
|
|
14
18
|
|
|
15
19
|
/**
|
|
@@ -23,6 +27,8 @@ class Orchestrator {
|
|
|
23
27
|
this._chainCount = this._metadata ? this._metadata.automationChainCount : 0
|
|
24
28
|
this._appId = triggerOutput.appId
|
|
25
29
|
this._app = null
|
|
30
|
+
const triggerStepId = automation.definition.trigger.stepId
|
|
31
|
+
triggerOutput = this.cleanupTriggerOutputs(triggerStepId, triggerOutput)
|
|
26
32
|
// remove from context
|
|
27
33
|
delete triggerOutput.appId
|
|
28
34
|
delete triggerOutput.metadata
|
|
@@ -34,11 +40,17 @@ class Orchestrator {
|
|
|
34
40
|
this._emitter = new AutomationEmitter(this._chainCount + 1)
|
|
35
41
|
this.executionOutput = { trigger: {}, steps: [] }
|
|
36
42
|
// setup the execution output
|
|
37
|
-
const triggerStepId = automation.definition.trigger.stepId
|
|
38
43
|
const triggerId = automation.definition.trigger.id
|
|
39
44
|
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)
|
|
40
45
|
}
|
|
41
46
|
|
|
47
|
+
cleanupTriggerOutputs(stepId, triggerOutput) {
|
|
48
|
+
if (stepId === CRON_STEP_ID) {
|
|
49
|
+
triggerOutput.timestamp = Date.now()
|
|
50
|
+
}
|
|
51
|
+
return triggerOutput
|
|
52
|
+
}
|
|
53
|
+
|
|
42
54
|
async getStepFunctionality(stepId) {
|
|
43
55
|
let step = await actions.getAction(stepId)
|
|
44
56
|
if (step == null) {
|
|
@@ -119,10 +131,17 @@ class Orchestrator {
|
|
|
119
131
|
}
|
|
120
132
|
}
|
|
121
133
|
|
|
122
|
-
module.exports =
|
|
134
|
+
module.exports = (input, callback) => {
|
|
123
135
|
const automationOrchestrator = new Orchestrator(
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
input.data.automation,
|
|
137
|
+
input.data.event
|
|
126
138
|
)
|
|
127
|
-
|
|
139
|
+
automationOrchestrator
|
|
140
|
+
.execute()
|
|
141
|
+
.then(response => {
|
|
142
|
+
callback(null, response)
|
|
143
|
+
})
|
|
144
|
+
.catch(err => {
|
|
145
|
+
callback(err)
|
|
146
|
+
})
|
|
128
147
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const workerFarm = require("worker-farm")
|
|
2
|
+
const env = require("../environment")
|
|
3
|
+
|
|
4
|
+
const ThreadType = {
|
|
5
|
+
QUERY: "query",
|
|
6
|
+
AUTOMATION: "automation",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function typeToFile(type) {
|
|
10
|
+
let filename = null
|
|
11
|
+
switch (type) {
|
|
12
|
+
case ThreadType.QUERY:
|
|
13
|
+
filename = "./query"
|
|
14
|
+
break
|
|
15
|
+
case ThreadType.AUTOMATION:
|
|
16
|
+
filename = "./automation"
|
|
17
|
+
break
|
|
18
|
+
default:
|
|
19
|
+
throw "Unknown thread type"
|
|
20
|
+
}
|
|
21
|
+
return require.resolve(filename)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class Thread {
|
|
25
|
+
constructor(type, opts = { timeoutMs: null, count: 1 }) {
|
|
26
|
+
this.type = type
|
|
27
|
+
this.count = opts.count ? opts.count : 1
|
|
28
|
+
this.disableThreading =
|
|
29
|
+
env.isTest() ||
|
|
30
|
+
env.DISABLE_THREADING ||
|
|
31
|
+
this.count === 0 ||
|
|
32
|
+
env.isInThread()
|
|
33
|
+
if (!this.disableThreading) {
|
|
34
|
+
const workerOpts = {
|
|
35
|
+
autoStart: true,
|
|
36
|
+
maxConcurrentWorkers: this.count,
|
|
37
|
+
}
|
|
38
|
+
if (opts.timeoutMs) {
|
|
39
|
+
workerOpts.maxCallTime = opts.timeoutMs
|
|
40
|
+
}
|
|
41
|
+
this.workers = workerFarm(workerOpts, typeToFile(type))
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
run(data) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
let fncToCall
|
|
48
|
+
// if in test then don't use threading
|
|
49
|
+
if (this.disableThreading) {
|
|
50
|
+
fncToCall = require(typeToFile(this.type))
|
|
51
|
+
} else {
|
|
52
|
+
fncToCall = this.workers
|
|
53
|
+
}
|
|
54
|
+
fncToCall(data, (err, response) => {
|
|
55
|
+
if (err) {
|
|
56
|
+
reject(err)
|
|
57
|
+
} else {
|
|
58
|
+
resolve(response)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports.Thread = Thread
|
|
66
|
+
module.exports.ThreadType = ThreadType
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// when thread starts, make sure it is recorded
|
|
2
|
+
const env = require("../environment")
|
|
3
|
+
env.setInThread()
|
|
4
|
+
const ScriptRunner = require("../utilities/scriptRunner")
|
|
5
|
+
const { integrations } = require("../integrations")
|
|
6
|
+
|
|
7
|
+
function formatResponse(resp) {
|
|
8
|
+
if (typeof resp === "string") {
|
|
9
|
+
try {
|
|
10
|
+
resp = JSON.parse(resp)
|
|
11
|
+
} catch (err) {
|
|
12
|
+
resp = { response: resp }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return resp
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function runAndTransform(datasource, queryVerb, query, transformer) {
|
|
19
|
+
const Integration = integrations[datasource.source]
|
|
20
|
+
if (!Integration) {
|
|
21
|
+
throw "Integration type does not exist."
|
|
22
|
+
}
|
|
23
|
+
const integration = new Integration(datasource.config)
|
|
24
|
+
|
|
25
|
+
let rows = formatResponse(await integration[queryVerb](query))
|
|
26
|
+
|
|
27
|
+
// transform as required
|
|
28
|
+
if (transformer) {
|
|
29
|
+
const runner = new ScriptRunner(transformer, { data: rows })
|
|
30
|
+
rows = runner.execute()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// needs to an array for next step
|
|
34
|
+
if (!Array.isArray(rows)) {
|
|
35
|
+
rows = [rows]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// map into JSON if just raw primitive here
|
|
39
|
+
if (rows.find(row => typeof row !== "object")) {
|
|
40
|
+
rows = rows.map(value => ({ value }))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// get all the potential fields in the schema
|
|
44
|
+
let keys = rows.flatMap(Object.keys)
|
|
45
|
+
|
|
46
|
+
if (integration.end) {
|
|
47
|
+
integration.end()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return { rows, keys }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = (input, callback) => {
|
|
54
|
+
runAndTransform(
|
|
55
|
+
input.datasource,
|
|
56
|
+
input.queryVerb,
|
|
57
|
+
input.query,
|
|
58
|
+
input.transformer
|
|
59
|
+
)
|
|
60
|
+
.then(response => {
|
|
61
|
+
callback(null, response)
|
|
62
|
+
})
|
|
63
|
+
.catch(err => {
|
|
64
|
+
callback(err)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
@@ -51,7 +51,7 @@ function parse(csvString, parsers) {
|
|
|
51
51
|
})
|
|
52
52
|
result.subscribe(row => {
|
|
53
53
|
// For each CSV row parse all the columns that need parsed
|
|
54
|
-
for (let key
|
|
54
|
+
for (let key of Object.keys(parsers)) {
|
|
55
55
|
if (!schema[key] || schema[key].success) {
|
|
56
56
|
// get the validator for the column type
|
|
57
57
|
const validator = VALIDATORS[parsers[key].type]
|
|
@@ -76,16 +76,58 @@ function parse(csvString, parsers) {
|
|
|
76
76
|
})
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
function updateSchema({ schema, existingTable }) {
|
|
80
|
+
if (!schema) {
|
|
81
|
+
return schema
|
|
82
|
+
}
|
|
83
|
+
const finalSchema = {}
|
|
84
|
+
const schemaKeyMap = {}
|
|
85
|
+
Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key))
|
|
86
|
+
for (let [key, field] of Object.entries(existingTable.schema)) {
|
|
87
|
+
const lcKey = key.toLowerCase()
|
|
88
|
+
const foundKey = schemaKeyMap[lcKey]
|
|
89
|
+
if (foundKey) {
|
|
90
|
+
finalSchema[key] = schema[foundKey]
|
|
91
|
+
finalSchema[key].type = field.type
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return finalSchema
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function transform({ schema, csvString, existingTable }) {
|
|
80
98
|
const colParser = {}
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
// make sure the table has all the columns required for import
|
|
101
|
+
if (existingTable) {
|
|
102
|
+
schema = updateSchema({ schema, existingTable })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (let key of Object.keys(schema)) {
|
|
83
106
|
colParser[key] = PARSERS[schema[key].type] || schema[key].type
|
|
84
107
|
}
|
|
85
108
|
|
|
86
109
|
try {
|
|
87
|
-
const
|
|
88
|
-
|
|
110
|
+
const data = await csv({ colParser }).fromString(csvString)
|
|
111
|
+
const schemaKeyMap = {}
|
|
112
|
+
Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key))
|
|
113
|
+
for (let element of data) {
|
|
114
|
+
if (!data) {
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
for (let key of Object.keys(element)) {
|
|
118
|
+
const mappedKey = schemaKeyMap[key.toLowerCase()]
|
|
119
|
+
// isn't a column in the table, remove it
|
|
120
|
+
if (mappedKey == null) {
|
|
121
|
+
delete element[key]
|
|
122
|
+
}
|
|
123
|
+
// casing is different, fix it in row
|
|
124
|
+
else if (key !== mappedKey) {
|
|
125
|
+
element[mappedKey] = element[key]
|
|
126
|
+
delete element[key]
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return data
|
|
89
131
|
} catch (err) {
|
|
90
132
|
console.error(`Error transforming CSV to JSON for data import`, err)
|
|
91
133
|
throw err
|
|
@@ -95,4 +137,5 @@ async function transform({ schema, csvString }) {
|
|
|
95
137
|
module.exports = {
|
|
96
138
|
parse,
|
|
97
139
|
transform,
|
|
140
|
+
updateSchema,
|
|
98
141
|
}
|
package/src/utilities/global.js
CHANGED
|
@@ -46,9 +46,13 @@ exports.getCachedSelf = async (ctx, appId) => {
|
|
|
46
46
|
return processUser(appId, user)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
exports.
|
|
49
|
+
exports.getRawGlobalUser = async userId => {
|
|
50
50
|
const db = getGlobalDB()
|
|
51
|
-
|
|
51
|
+
return db.get(getGlobalIDFromUserMetadataID(userId))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports.getGlobalUser = async (appId, userId) => {
|
|
55
|
+
let user = await exports.getRawGlobalUser(userId)
|
|
52
56
|
return processUser(appId, user)
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -73,6 +77,7 @@ exports.getGlobalUsers = async (appId = null, users = null) => {
|
|
|
73
77
|
.filter(user => user != null)
|
|
74
78
|
.map(user => {
|
|
75
79
|
delete user.password
|
|
80
|
+
delete user.forceResetPassword
|
|
76
81
|
return user
|
|
77
82
|
})
|
|
78
83
|
if (!appId) {
|
package/src/utilities/index.js
CHANGED
|
@@ -48,6 +48,7 @@ exports.objectStoreUrl = () => {
|
|
|
48
48
|
* via a specific endpoint (under /api/assets/client).
|
|
49
49
|
* @param {string} appId In production we need the appId to look up the correct bucket, as the
|
|
50
50
|
* version of the client lib may differ between apps.
|
|
51
|
+
* @param {string} version The version to retrieve.
|
|
51
52
|
* @return {string} The URL to be inserted into appPackage response or server rendered
|
|
52
53
|
* app index file.
|
|
53
54
|
*/
|
|
@@ -139,3 +140,13 @@ exports.stringToReadStream = string => {
|
|
|
139
140
|
},
|
|
140
141
|
})
|
|
141
142
|
}
|
|
143
|
+
|
|
144
|
+
exports.doesDatabaseExist = async dbName => {
|
|
145
|
+
try {
|
|
146
|
+
const db = new CouchDB(dbName, { skip_setup: true })
|
|
147
|
+
const info = await db.info()
|
|
148
|
+
return info && !info.error
|
|
149
|
+
} catch (err) {
|
|
150
|
+
return false
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
const fetch = require("node-fetch")
|
|
2
2
|
const { VM, VMScript } = require("vm2")
|
|
3
|
+
const JS_TIMEOUT_MS = 1000
|
|
3
4
|
|
|
4
5
|
class ScriptRunner {
|
|
5
6
|
constructor(script, context) {
|
|
6
7
|
const code = `let fn = () => {\n${script}\n}; results.out = fn();`
|
|
7
|
-
this.vm = new VM(
|
|
8
|
+
this.vm = new VM({
|
|
9
|
+
timeout: JS_TIMEOUT_MS,
|
|
10
|
+
})
|
|
8
11
|
this.results = { out: "" }
|
|
9
12
|
this.vm.setGlobals(context)
|
|
10
13
|
this.vm.setGlobal("fetch", fetch)
|
|
@@ -3,19 +3,13 @@
|
|
|
3
3
|
exports[`CSV Parser transformation transforms a CSV file into JSON 1`] = `
|
|
4
4
|
Array [
|
|
5
5
|
Object {
|
|
6
|
-
"Address": "5 Sesame Street",
|
|
7
6
|
"Age": 4324,
|
|
8
|
-
"Name": "Bertå",
|
|
9
7
|
},
|
|
10
8
|
Object {
|
|
11
|
-
"Address": "1 World Trade Center",
|
|
12
9
|
"Age": 34,
|
|
13
|
-
"Name": "Ernie",
|
|
14
10
|
},
|
|
15
11
|
Object {
|
|
16
|
-
"Address": "44 Second Avenue",
|
|
17
12
|
"Age": 23423,
|
|
18
|
-
"Name": "Big Bird",
|
|
19
13
|
},
|
|
20
14
|
]
|
|
21
15
|
`;
|