@budibase/server 0.9.188 → 0.9.190-alpha.10
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.2bd3b345.js +1316 -0
- package/builder/assets/index.4fb3f887.css +1 -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 +1608 -1191
- package/coverage/coverage-final.json +97 -93
- 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 +113 -80
- 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 +245 -41
- 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 +98 -98
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
- package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
- package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
- package/coverage/lcov-report/api/controllers/query.js.html +79 -229
- package/coverage/lcov-report/api/controllers/role.js.html +9 -9
- package/coverage/lcov-report/api/controllers/routing.js.html +29 -29
- 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 +3 -3
- 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 +533 -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 +5 -5
- 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 +536 -2
- 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 +464 -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 +46 -16
- 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 +2 -2
- 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 +4 -4
- package/coverage/lcov-report/db/utils.js.html +75 -75
- 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 +19 -16
- package/coverage/lcov-report/middleware/builder.js.html +22 -13
- package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
- 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 +2 -2
- 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 +38 -23
- package/coverage/lcov-report/utilities/index.html +48 -48
- package/coverage/lcov-report/utilities/index.js.html +49 -16
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +31 -10
- 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 +2 -2
- 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 +2687 -1942
- package/dist/api/controllers/application.js +16 -6
- 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 +32 -62
- package/dist/api/controllers/row/ExternalRequest.js +83 -36
- 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 +146 -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/row.js +178 -0
- package/dist/api/routes/table.js +150 -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 +17 -1
- 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 +350 -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 +367 -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 +18 -9
- 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 +19 -10
- package/scripts/dev/manage.js +1 -0
- package/scripts/docs/README.md +31 -0
- package/scripts/docs/generate.js +74 -0
- package/scripts/docs/toSwagger.js +320 -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 -7
- 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 +35 -85
- package/src/api/controllers/row/ExternalRequest.ts +99 -38
- 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 +151 -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/row.js +178 -0
- package/src/api/routes/table.js +154 -0
- package/src/api/routes/tests/application.spec.js +0 -2
- 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 +38 -9
- package/src/api/routes/tests/screen.spec.js +1 -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 +21 -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 +375 -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 +464 -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
|
@@ -8,23 +8,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
-
var t = {};
|
|
13
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
-
t[p] = s[p];
|
|
15
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
-
t[p[i]] = s[p[i]];
|
|
19
|
-
}
|
|
20
|
-
return t;
|
|
21
|
-
};
|
|
22
11
|
const CouchDB = require("../../../db");
|
|
23
|
-
const
|
|
12
|
+
const internal = require("./internal");
|
|
13
|
+
const external = require("./external");
|
|
24
14
|
const csvParser = require("../../../utilities/csvParser");
|
|
25
|
-
const {
|
|
26
|
-
const {
|
|
27
|
-
const {
|
|
15
|
+
const { isExternalTable } = require("../../../integrations/utils");
|
|
16
|
+
const { getTableParams, getDatasourceParams, BudibaseInternalDB, } = require("../../../db/utils");
|
|
17
|
+
const { getTable } = require("./utils");
|
|
18
|
+
function pickApi({ tableId, table }) {
|
|
19
|
+
if (table && !tableId) {
|
|
20
|
+
tableId = table._id;
|
|
21
|
+
}
|
|
22
|
+
if (table && table.type === "external") {
|
|
23
|
+
return external;
|
|
24
|
+
}
|
|
25
|
+
else if (tableId && isExternalTable(tableId)) {
|
|
26
|
+
return external;
|
|
27
|
+
}
|
|
28
|
+
return internal;
|
|
29
|
+
}
|
|
30
|
+
// covers both internal and external
|
|
28
31
|
exports.fetch = function (ctx) {
|
|
29
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
33
|
const db = new CouchDB(ctx.appId);
|
|
@@ -50,126 +53,49 @@ exports.find = function (ctx) {
|
|
|
50
53
|
exports.save = function (ctx) {
|
|
51
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
55
|
const appId = ctx.appId;
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
let tableToSave = Object.assign({ type: "table", _id: generateTableID(), views: {} }, rest);
|
|
56
|
-
// if the table obj had an _id then it will have been retrieved
|
|
57
|
-
let oldTable;
|
|
58
|
-
if (ctx.request.body && ctx.request.body._id) {
|
|
59
|
-
oldTable = yield db.get(ctx.request.body._id);
|
|
60
|
-
}
|
|
61
|
-
// saving a table is a complex operation, involving many different steps, this
|
|
62
|
-
// has been broken out into a utility to make it more obvious/easier to manipulate
|
|
63
|
-
const tableSaveFunctions = new TableSaveFunctions({
|
|
64
|
-
db,
|
|
65
|
-
ctx,
|
|
66
|
-
oldTable,
|
|
67
|
-
dataImport,
|
|
68
|
-
});
|
|
69
|
-
tableToSave = yield tableSaveFunctions.before(tableToSave);
|
|
70
|
-
// make sure that types don't change of a column, have to remove
|
|
71
|
-
// the column if you want to change the type
|
|
72
|
-
if (oldTable && oldTable.schema) {
|
|
73
|
-
for (let propKey of Object.keys(tableToSave.schema)) {
|
|
74
|
-
let column = tableToSave.schema[propKey];
|
|
75
|
-
let oldColumn = oldTable.schema[propKey];
|
|
76
|
-
if (oldColumn && oldColumn.type === "internal") {
|
|
77
|
-
oldColumn.type = "auto";
|
|
78
|
-
}
|
|
79
|
-
if (oldColumn && oldColumn.type !== column.type) {
|
|
80
|
-
ctx.throw(400, "Cannot change the type of a column");
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// Don't rename if the name is the same
|
|
85
|
-
let { _rename } = tableToSave;
|
|
86
|
-
/* istanbul ignore next */
|
|
87
|
-
if (_rename && _rename.old === _rename.updated) {
|
|
88
|
-
_rename = null;
|
|
89
|
-
delete tableToSave._rename;
|
|
90
|
-
}
|
|
91
|
-
// rename row fields when table column is renamed
|
|
92
|
-
/* istanbul ignore next */
|
|
93
|
-
if (_rename && tableToSave.schema[_rename.updated].type === FieldTypes.LINK) {
|
|
94
|
-
ctx.throw(400, "Cannot rename a linked column.");
|
|
95
|
-
}
|
|
96
|
-
tableToSave = yield tableSaveFunctions.mid(tableToSave);
|
|
97
|
-
// update schema of non-statistics views when new columns are added
|
|
98
|
-
for (let view in tableToSave.views) {
|
|
99
|
-
const tableView = tableToSave.views[view];
|
|
100
|
-
if (!tableView)
|
|
101
|
-
continue;
|
|
102
|
-
if (tableView.schema.group || tableView.schema.field)
|
|
103
|
-
continue;
|
|
104
|
-
tableView.schema = tableToSave.schema;
|
|
105
|
-
}
|
|
106
|
-
// update linked rows
|
|
107
|
-
try {
|
|
108
|
-
const linkResp = yield linkRows.updateLinks({
|
|
109
|
-
appId,
|
|
110
|
-
eventType: oldTable
|
|
111
|
-
? linkRows.EventType.TABLE_UPDATED
|
|
112
|
-
: linkRows.EventType.TABLE_SAVE,
|
|
113
|
-
table: tableToSave,
|
|
114
|
-
oldTable: oldTable,
|
|
115
|
-
});
|
|
116
|
-
if (linkResp != null && linkResp._rev) {
|
|
117
|
-
tableToSave._rev = linkResp._rev;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
catch (err) {
|
|
121
|
-
ctx.throw(400, err);
|
|
122
|
-
}
|
|
123
|
-
// don't perform any updates until relationships have been
|
|
124
|
-
// checked by the updateLinks function
|
|
125
|
-
const updatedRows = tableSaveFunctions.getUpdatedRows();
|
|
126
|
-
if (updatedRows && updatedRows.length !== 0) {
|
|
127
|
-
yield db.bulkDocs(updatedRows);
|
|
128
|
-
}
|
|
129
|
-
const result = yield db.put(tableToSave);
|
|
130
|
-
tableToSave._rev = result.rev;
|
|
131
|
-
tableToSave = yield tableSaveFunctions.after(tableToSave);
|
|
132
|
-
ctx.eventEmitter &&
|
|
133
|
-
ctx.eventEmitter.emitTable(`table:save`, appId, tableToSave);
|
|
56
|
+
const table = ctx.request.body;
|
|
57
|
+
const savedTable = yield pickApi({ table }).save(ctx);
|
|
134
58
|
ctx.status = 200;
|
|
135
|
-
ctx.message = `Table ${
|
|
136
|
-
ctx.
|
|
59
|
+
ctx.message = `Table ${table.name} saved successfully.`;
|
|
60
|
+
ctx.eventEmitter &&
|
|
61
|
+
ctx.eventEmitter.emitTable(`table:save`, appId, savedTable);
|
|
62
|
+
ctx.body = savedTable;
|
|
137
63
|
});
|
|
138
64
|
};
|
|
139
65
|
exports.destroy = function (ctx) {
|
|
140
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
67
|
const appId = ctx.appId;
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
// Delete all rows for that table
|
|
145
|
-
const rows = yield db.allDocs(getRowParams(ctx.params.tableId, null, {
|
|
146
|
-
include_docs: true,
|
|
147
|
-
}));
|
|
148
|
-
yield db.bulkDocs(rows.rows.map(row => (Object.assign(Object.assign({}, row.doc), { _deleted: true }))));
|
|
149
|
-
// update linked rows
|
|
150
|
-
yield linkRows.updateLinks({
|
|
151
|
-
appId,
|
|
152
|
-
eventType: linkRows.EventType.TABLE_DELETE,
|
|
153
|
-
table: tableToDelete,
|
|
154
|
-
});
|
|
155
|
-
// don't remove the table itself until very end
|
|
156
|
-
yield db.remove(tableToDelete);
|
|
157
|
-
// remove table search index
|
|
158
|
-
const currentIndexes = yield db.getIndexes();
|
|
159
|
-
const existingIndex = currentIndexes.indexes.find(existing => existing.name === `search:${ctx.params.tableId}`);
|
|
160
|
-
if (existingIndex) {
|
|
161
|
-
yield db.deleteIndex(existingIndex);
|
|
162
|
-
}
|
|
68
|
+
const tableId = ctx.params.tableId;
|
|
69
|
+
const deletedTable = yield pickApi({ tableId }).destroy(ctx);
|
|
163
70
|
ctx.eventEmitter &&
|
|
164
|
-
ctx.eventEmitter.emitTable(`table:delete`, appId,
|
|
71
|
+
ctx.eventEmitter.emitTable(`table:delete`, appId, deletedTable);
|
|
165
72
|
ctx.status = 200;
|
|
166
|
-
ctx.body = { message: `Table ${
|
|
73
|
+
ctx.body = { message: `Table ${tableId} deleted.` };
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
exports.bulkImport = function (ctx) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const tableId = ctx.params.tableId;
|
|
79
|
+
yield pickApi({ tableId }).bulkImport(ctx);
|
|
80
|
+
// right now we don't trigger anything for bulk import because it
|
|
81
|
+
// can only be done in the builder, but in the future we may need to
|
|
82
|
+
// think about events for bulk items
|
|
83
|
+
ctx.status = 200;
|
|
84
|
+
ctx.body = { message: `Bulk rows created.` };
|
|
167
85
|
});
|
|
168
86
|
};
|
|
169
87
|
exports.validateCSVSchema = function (ctx) {
|
|
170
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
|
|
172
|
-
const
|
|
89
|
+
// tableId being specified means its an import to an existing table
|
|
90
|
+
const { csvString, schema = {}, tableId } = ctx.request.body;
|
|
91
|
+
let existingTable;
|
|
92
|
+
if (tableId) {
|
|
93
|
+
existingTable = yield getTable(ctx.appId, tableId);
|
|
94
|
+
}
|
|
95
|
+
let result = yield csvParser.parse(csvString, schema);
|
|
96
|
+
if (existingTable) {
|
|
97
|
+
result = csvParser.updateSchema({ schema: result, existingTable });
|
|
98
|
+
}
|
|
173
99
|
ctx.body = { schema: result };
|
|
174
100
|
});
|
|
175
101
|
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
const CouchDB = require("../../../db");
|
|
23
|
+
const linkRows = require("../../../db/linkedRows");
|
|
24
|
+
const { getRowParams, generateTableID } = require("../../../db/utils");
|
|
25
|
+
const { FieldTypes } = require("../../../constants");
|
|
26
|
+
const { TableSaveFunctions, hasTypeChanged, getTable, handleDataImport, } = require("./utils");
|
|
27
|
+
exports.save = function (ctx) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
const appId = ctx.appId;
|
|
30
|
+
const db = new CouchDB(appId);
|
|
31
|
+
const _a = ctx.request.body, { dataImport } = _a, rest = __rest(_a, ["dataImport"]);
|
|
32
|
+
let tableToSave = Object.assign({ type: "table", _id: generateTableID(), views: {} }, rest);
|
|
33
|
+
// if the table obj had an _id then it will have been retrieved
|
|
34
|
+
let oldTable;
|
|
35
|
+
if (ctx.request.body && ctx.request.body._id) {
|
|
36
|
+
oldTable = yield db.get(ctx.request.body._id);
|
|
37
|
+
}
|
|
38
|
+
if (hasTypeChanged(tableToSave, oldTable)) {
|
|
39
|
+
ctx.throw(400, "A column type has changed.");
|
|
40
|
+
}
|
|
41
|
+
// saving a table is a complex operation, involving many different steps, this
|
|
42
|
+
// has been broken out into a utility to make it more obvious/easier to manipulate
|
|
43
|
+
const tableSaveFunctions = new TableSaveFunctions({
|
|
44
|
+
db,
|
|
45
|
+
ctx,
|
|
46
|
+
oldTable,
|
|
47
|
+
dataImport,
|
|
48
|
+
});
|
|
49
|
+
tableToSave = yield tableSaveFunctions.before(tableToSave);
|
|
50
|
+
// make sure that types don't change of a column, have to remove
|
|
51
|
+
// the column if you want to change the type
|
|
52
|
+
if (oldTable && oldTable.schema) {
|
|
53
|
+
for (let propKey of Object.keys(tableToSave.schema)) {
|
|
54
|
+
let oldColumn = oldTable.schema[propKey];
|
|
55
|
+
if (oldColumn && oldColumn.type === "internal") {
|
|
56
|
+
oldColumn.type = "auto";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Don't rename if the name is the same
|
|
61
|
+
let { _rename } = tableToSave;
|
|
62
|
+
/* istanbul ignore next */
|
|
63
|
+
if (_rename && _rename.old === _rename.updated) {
|
|
64
|
+
_rename = null;
|
|
65
|
+
delete tableToSave._rename;
|
|
66
|
+
}
|
|
67
|
+
// rename row fields when table column is renamed
|
|
68
|
+
/* istanbul ignore next */
|
|
69
|
+
if (_rename && tableToSave.schema[_rename.updated].type === FieldTypes.LINK) {
|
|
70
|
+
ctx.throw(400, "Cannot rename a linked column.");
|
|
71
|
+
}
|
|
72
|
+
tableToSave = yield tableSaveFunctions.mid(tableToSave);
|
|
73
|
+
// update schema of non-statistics views when new columns are added
|
|
74
|
+
for (let view in tableToSave.views) {
|
|
75
|
+
const tableView = tableToSave.views[view];
|
|
76
|
+
if (!tableView)
|
|
77
|
+
continue;
|
|
78
|
+
if (tableView.schema.group || tableView.schema.field)
|
|
79
|
+
continue;
|
|
80
|
+
tableView.schema = tableToSave.schema;
|
|
81
|
+
}
|
|
82
|
+
// update linked rows
|
|
83
|
+
try {
|
|
84
|
+
const linkResp = yield linkRows.updateLinks({
|
|
85
|
+
appId,
|
|
86
|
+
eventType: oldTable
|
|
87
|
+
? linkRows.EventType.TABLE_UPDATED
|
|
88
|
+
: linkRows.EventType.TABLE_SAVE,
|
|
89
|
+
table: tableToSave,
|
|
90
|
+
oldTable: oldTable,
|
|
91
|
+
});
|
|
92
|
+
if (linkResp != null && linkResp._rev) {
|
|
93
|
+
tableToSave._rev = linkResp._rev;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
ctx.throw(400, err);
|
|
98
|
+
}
|
|
99
|
+
// don't perform any updates until relationships have been
|
|
100
|
+
// checked by the updateLinks function
|
|
101
|
+
const updatedRows = tableSaveFunctions.getUpdatedRows();
|
|
102
|
+
if (updatedRows && updatedRows.length !== 0) {
|
|
103
|
+
yield db.bulkDocs(updatedRows);
|
|
104
|
+
}
|
|
105
|
+
const result = yield db.put(tableToSave);
|
|
106
|
+
tableToSave._rev = result.rev;
|
|
107
|
+
tableToSave = yield tableSaveFunctions.after(tableToSave);
|
|
108
|
+
return tableToSave;
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
exports.destroy = function (ctx) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
const appId = ctx.appId;
|
|
114
|
+
const db = new CouchDB(appId);
|
|
115
|
+
const tableToDelete = yield db.get(ctx.params.tableId);
|
|
116
|
+
// Delete all rows for that table
|
|
117
|
+
const rows = yield db.allDocs(getRowParams(ctx.params.tableId, null, {
|
|
118
|
+
include_docs: true,
|
|
119
|
+
}));
|
|
120
|
+
yield db.bulkDocs(rows.rows.map(row => (Object.assign(Object.assign({}, row.doc), { _deleted: true }))));
|
|
121
|
+
// update linked rows
|
|
122
|
+
yield linkRows.updateLinks({
|
|
123
|
+
appId,
|
|
124
|
+
eventType: linkRows.EventType.TABLE_DELETE,
|
|
125
|
+
table: tableToDelete,
|
|
126
|
+
});
|
|
127
|
+
// don't remove the table itself until very end
|
|
128
|
+
yield db.remove(tableToDelete);
|
|
129
|
+
// remove table search index
|
|
130
|
+
const currentIndexes = yield db.getIndexes();
|
|
131
|
+
const existingIndex = currentIndexes.indexes.find(existing => existing.name === `search:${ctx.params.tableId}`);
|
|
132
|
+
if (existingIndex) {
|
|
133
|
+
yield db.deleteIndex(existingIndex);
|
|
134
|
+
}
|
|
135
|
+
return tableToDelete;
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
exports.bulkImport = function (ctx) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const appId = ctx.appId;
|
|
141
|
+
const table = yield getTable(appId, ctx.params.tableId);
|
|
142
|
+
const { dataImport } = ctx.request.body;
|
|
143
|
+
yield handleDataImport(appId, ctx.user, table, dataImport);
|
|
144
|
+
return table;
|
|
145
|
+
});
|
|
146
|
+
};
|
|
@@ -14,7 +14,7 @@ const { getRowParams, generateRowID, InternalTables, } = require("../../../db/ut
|
|
|
14
14
|
const { isEqual } = require("lodash/fp");
|
|
15
15
|
const { AutoFieldSubTypes, FieldTypes } = require("../../../constants");
|
|
16
16
|
const { inputProcessing } = require("../../../utilities/rowProcessor");
|
|
17
|
-
const { USERS_TABLE_SCHEMA } = require("../../../constants");
|
|
17
|
+
const { USERS_TABLE_SCHEMA, SwitchableTypes } = require("../../../constants");
|
|
18
18
|
const { isExternalTable, breakExternalTableId, } = require("../../../integrations/utils");
|
|
19
19
|
const { getViews, saveView } = require("../view/utils");
|
|
20
20
|
const viewTemplate = require("../view/viewBuilder");
|
|
@@ -66,37 +66,38 @@ exports.makeSureTableUpToDate = (table, tableToSave) => {
|
|
|
66
66
|
return tableToSave;
|
|
67
67
|
};
|
|
68
68
|
exports.handleDataImport = (appId, user, table, dataImport) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
if (!dataImport || !dataImport.csvString) {
|
|
70
|
+
return table;
|
|
71
|
+
}
|
|
69
72
|
const db = new CouchDB(appId);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
schema.constraints.inclusion
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
];
|
|
92
|
-
}
|
|
73
|
+
// Populate the table with rows imported from CSV in a bulk update
|
|
74
|
+
const data = yield csvParser.transform(Object.assign(Object.assign({}, dataImport), { existingTable: table }));
|
|
75
|
+
let finalData = [];
|
|
76
|
+
for (let i = 0; i < data.length; i++) {
|
|
77
|
+
let row = data[i];
|
|
78
|
+
row._id = generateRowID(table._id);
|
|
79
|
+
row.tableId = table._id;
|
|
80
|
+
const processed = inputProcessing(user, table, row, {
|
|
81
|
+
noAutoRelationships: true,
|
|
82
|
+
});
|
|
83
|
+
table = processed.table;
|
|
84
|
+
row = processed.row;
|
|
85
|
+
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
|
86
|
+
// check whether the options need to be updated for inclusion as part of the data import
|
|
87
|
+
if (schema.type === FieldTypes.OPTIONS &&
|
|
88
|
+
(!schema.constraints.inclusion ||
|
|
89
|
+
schema.constraints.inclusion.indexOf(row[fieldName]) === -1)) {
|
|
90
|
+
schema.constraints.inclusion = [
|
|
91
|
+
...schema.constraints.inclusion,
|
|
92
|
+
row[fieldName],
|
|
93
|
+
];
|
|
93
94
|
}
|
|
94
|
-
finalData.push(row);
|
|
95
95
|
}
|
|
96
|
-
|
|
97
|
-
let response = yield db.put(table);
|
|
98
|
-
table._rev = response._rev;
|
|
96
|
+
finalData.push(row);
|
|
99
97
|
}
|
|
98
|
+
yield db.bulkDocs(finalData);
|
|
99
|
+
let response = yield db.put(table);
|
|
100
|
+
table._rev = response._rev;
|
|
100
101
|
return table;
|
|
101
102
|
});
|
|
102
103
|
exports.handleSearchIndexes = (appId, table) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -277,4 +278,37 @@ exports.checkForViewUpdates = (db, table, rename, deletedColumns) => __awaiter(v
|
|
|
277
278
|
}
|
|
278
279
|
}
|
|
279
280
|
});
|
|
281
|
+
exports.generateForeignKey = (column, relatedTable) => {
|
|
282
|
+
return `fk_${relatedTable.name}_${column.fieldName}`;
|
|
283
|
+
};
|
|
284
|
+
exports.generateJunctionTableName = (column, table, relatedTable) => {
|
|
285
|
+
return `jt_${table.name}_${relatedTable.name}_${column.name}_${column.fieldName}`;
|
|
286
|
+
};
|
|
287
|
+
exports.foreignKeyStructure = (keyName, meta = null) => {
|
|
288
|
+
const structure = {
|
|
289
|
+
type: FieldTypes.NUMBER,
|
|
290
|
+
constraints: {},
|
|
291
|
+
name: keyName,
|
|
292
|
+
};
|
|
293
|
+
if (meta) {
|
|
294
|
+
structure.meta = meta;
|
|
295
|
+
}
|
|
296
|
+
return structure;
|
|
297
|
+
};
|
|
298
|
+
exports.hasTypeChanged = (table, oldTable) => {
|
|
299
|
+
if (!oldTable) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
for (let [key, field] of Object.entries(oldTable.schema)) {
|
|
303
|
+
const oldType = field.type;
|
|
304
|
+
if (!table.schema[key]) {
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
const newType = table.schema[key].type;
|
|
308
|
+
if (oldType !== newType && SwitchableTypes.indexOf(oldType) === -1) {
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return false;
|
|
313
|
+
};
|
|
280
314
|
exports.TableSaveFunctions = TableSaveFunctions;
|
|
@@ -11,22 +11,132 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
const CouchDB = require("../../db");
|
|
12
12
|
const { generateUserMetadataID, getUserMetadataParams, } = require("../../db/utils");
|
|
13
13
|
const { InternalTables } = require("../../db/utils");
|
|
14
|
-
const { getGlobalUsers } = require("../../utilities/global");
|
|
14
|
+
const { getGlobalUsers, getRawGlobalUser } = require("../../utilities/global");
|
|
15
15
|
const { getFullUser } = require("../../utilities/users");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const { isEqual } = require("lodash");
|
|
17
|
+
const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles");
|
|
18
|
+
const { getDevelopmentAppID, getDeployedAppIDs } = require("@budibase/auth/db");
|
|
19
|
+
const { doesDatabaseExist } = require("../../utilities");
|
|
20
|
+
const { UserStatus } = require("@budibase/auth/constants");
|
|
21
|
+
function rawMetadata(db) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
return (yield db.allDocs(getUserMetadataParams(null, {
|
|
24
|
+
include_docs: true,
|
|
25
|
+
}))).rows.map(row => row.doc);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function combineMetadataAndUser(user, metadata) {
|
|
29
|
+
// skip users with no access
|
|
30
|
+
if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
delete user._rev;
|
|
34
|
+
const metadataId = generateUserMetadataID(user._id);
|
|
35
|
+
const newDoc = Object.assign(Object.assign({}, user), { _id: metadataId, tableId: InternalTables.USER_METADATA });
|
|
36
|
+
const found = Array.isArray(metadata)
|
|
37
|
+
? metadata.find(doc => doc._id === metadataId)
|
|
38
|
+
: metadata;
|
|
39
|
+
// copy rev over for the purposes of equality check
|
|
40
|
+
if (found) {
|
|
41
|
+
newDoc._rev = found._rev;
|
|
42
|
+
}
|
|
43
|
+
if (found == null || !isEqual(newDoc, found)) {
|
|
44
|
+
return Object.assign(Object.assign({}, found), newDoc);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
22
47
|
}
|
|
48
|
+
exports.syncGlobalUsers = (appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
// sync user metadata
|
|
50
|
+
const db = new CouchDB(appId);
|
|
51
|
+
const [users, metadata] = yield Promise.all([
|
|
52
|
+
getGlobalUsers(appId),
|
|
53
|
+
rawMetadata(db),
|
|
54
|
+
]);
|
|
55
|
+
const toWrite = [];
|
|
56
|
+
for (let user of users) {
|
|
57
|
+
const combined = yield combineMetadataAndUser(user, metadata);
|
|
58
|
+
if (combined) {
|
|
59
|
+
toWrite.push(combined);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
yield db.bulkDocs(toWrite);
|
|
63
|
+
});
|
|
64
|
+
exports.syncUser = function (ctx) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
let deleting = false, user;
|
|
67
|
+
const userId = ctx.params.id;
|
|
68
|
+
try {
|
|
69
|
+
user = yield getRawGlobalUser(userId);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err && err.status === 404) {
|
|
73
|
+
user = {};
|
|
74
|
+
deleting = true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const roles = user.roles;
|
|
81
|
+
// remove props which aren't useful to metadata
|
|
82
|
+
delete user.password;
|
|
83
|
+
delete user.forceResetPassword;
|
|
84
|
+
delete user.roles;
|
|
85
|
+
// run through all production appIDs in the users roles
|
|
86
|
+
let prodAppIds;
|
|
87
|
+
// if they are a builder then get all production app IDs
|
|
88
|
+
if ((user.builder && user.builder.global) || deleting) {
|
|
89
|
+
prodAppIds = yield getDeployedAppIDs(CouchDB);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
prodAppIds = Object.entries(roles)
|
|
93
|
+
.filter(entry => entry[1] !== BUILTIN_ROLE_IDS.PUBLIC)
|
|
94
|
+
.map(([appId]) => appId);
|
|
95
|
+
}
|
|
96
|
+
for (let prodAppId of prodAppIds) {
|
|
97
|
+
const roleId = roles[prodAppId];
|
|
98
|
+
const devAppId = getDevelopmentAppID(prodAppId);
|
|
99
|
+
for (let appId of [prodAppId, devAppId]) {
|
|
100
|
+
if (!(yield doesDatabaseExist(appId))) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const db = new CouchDB(appId);
|
|
104
|
+
const metadataId = generateUserMetadataID(userId);
|
|
105
|
+
let metadata;
|
|
106
|
+
try {
|
|
107
|
+
metadata = yield db.get(metadataId);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (deleting) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
metadata = {
|
|
114
|
+
tableId: InternalTables.USER_METADATA,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// assign the roleId for the metadata doc
|
|
118
|
+
if (roleId) {
|
|
119
|
+
metadata.roleId = roleId;
|
|
120
|
+
}
|
|
121
|
+
let combined = !deleting
|
|
122
|
+
? combineMetadataAndUser(user, metadata)
|
|
123
|
+
: Object.assign(Object.assign({}, metadata), { status: UserStatus.INACTIVE, metadata: BUILTIN_ROLE_IDS.PUBLIC });
|
|
124
|
+
// if its null then there was no updates required
|
|
125
|
+
if (combined) {
|
|
126
|
+
yield db.put(combined);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
ctx.body = {
|
|
131
|
+
message: "User synced.",
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
};
|
|
23
135
|
exports.fetchMetadata = function (ctx) {
|
|
24
136
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
137
|
const database = new CouchDB(ctx.appId);
|
|
26
138
|
const global = yield getGlobalUsers(ctx.appId);
|
|
27
|
-
const metadata =
|
|
28
|
-
include_docs: true,
|
|
29
|
-
}))).rows.map(row => row.doc);
|
|
139
|
+
const metadata = yield rawMetadata(database);
|
|
30
140
|
const users = [];
|
|
31
141
|
for (let user of global) {
|
|
32
142
|
// find the metadata that matches up to the global ID
|
|
@@ -52,7 +162,9 @@ exports.updateMetadata = function (ctx) {
|
|
|
52
162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
163
|
const appId = ctx.appId;
|
|
54
164
|
const db = new CouchDB(appId);
|
|
55
|
-
const user =
|
|
165
|
+
const user = ctx.request.body;
|
|
166
|
+
// this isn't applicable to the user
|
|
167
|
+
delete user.roles;
|
|
56
168
|
const metadata = Object.assign({ tableId: InternalTables.USER_METADATA }, user);
|
|
57
169
|
ctx.body = yield db.put(metadata);
|
|
58
170
|
});
|
|
@@ -25,6 +25,7 @@ const { apiFileReturn } = require("../../../utilities/fileSystem");
|
|
|
25
25
|
const exporters = require("./exporters");
|
|
26
26
|
const { saveView, getView, getViews, deleteView } = require("./utils");
|
|
27
27
|
const { fetchView } = require("../row");
|
|
28
|
+
const { getTable } = require("../table/utils");
|
|
28
29
|
exports.fetch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
30
|
const db = new CouchDB(ctx.appId);
|
|
30
31
|
ctx.body = yield getViews(db);
|
|
@@ -65,7 +66,7 @@ exports.exportView = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
65
66
|
const viewName = decodeURI(ctx.query.view);
|
|
66
67
|
const view = yield getView(db, viewName);
|
|
67
68
|
const format = ctx.query.format;
|
|
68
|
-
if (!format) {
|
|
69
|
+
if (!format || !Object.values(exporters.ExportFormats).includes(format)) {
|
|
69
70
|
ctx.throw(400, "Format must be specified, either csv or json");
|
|
70
71
|
}
|
|
71
72
|
if (view) {
|
|
@@ -87,9 +88,20 @@ exports.exportView = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
87
88
|
let schema = view && view.meta && view.meta.schema;
|
|
88
89
|
if (!schema) {
|
|
89
90
|
const tableId = ctx.params.tableId || view.meta.tableId;
|
|
90
|
-
const table = yield
|
|
91
|
+
const table = yield getTable(ctx.appId, tableId);
|
|
91
92
|
schema = table.schema;
|
|
92
93
|
}
|
|
94
|
+
// make sure no "undefined" entries appear in the CSV
|
|
95
|
+
if (format === exporters.ExportFormats.CSV) {
|
|
96
|
+
const schemaKeys = Object.keys(schema);
|
|
97
|
+
for (let key of schemaKeys) {
|
|
98
|
+
for (let row of ctx.body) {
|
|
99
|
+
if (row[key] == null) {
|
|
100
|
+
row[key] = "";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
93
105
|
// Export part
|
|
94
106
|
let headers = Object.keys(schema);
|
|
95
107
|
const exporter = exporters[format];
|
package/dist/api/routes/query.js
CHANGED
|
@@ -41,7 +41,7 @@ router
|
|
|
41
41
|
.get("/api/queries", authorized(BUILDER), queryController.fetch)
|
|
42
42
|
.post("/api/queries", bodySubResource("datasourceId", "_id"), authorized(BUILDER), generateQueryValidation(), queryController.save)
|
|
43
43
|
.post("/api/queries/preview", bodyResource("datasourceId"), authorized(BUILDER), generateQueryPreviewValidation(), queryController.preview)
|
|
44
|
-
.get("/api/queries/:queryId", authorized(PermissionTypes.QUERY, PermissionLevels.READ), queryController.find)
|
|
44
|
+
.get("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.READ), queryController.find)
|
|
45
45
|
.post("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.WRITE), queryController.execute)
|
|
46
46
|
.delete("/api/queries/:queryId/:revId", paramResource("queryId"), authorized(BUILDER), queryController.destroy);
|
|
47
47
|
module.exports = router;
|