@budibase/server 0.9.184 → 0.9.185-alpha.11
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 +1 -1
- package/__mocks__/mssql.ts +1 -1
- package/__mocks__/pg.ts +3 -0
- package/builder/assets/bb-space-man.5be51a45.svg +290 -0
- package/builder/assets/index.053c6f7a.js +1321 -0
- package/builder/assets/index.4a7c5636.css +1 -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 +1357 -959
- package/coverage/coverage-final.json +91 -87
- 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 +65 -14
- 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 +147 -27
- 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 +90 -90
- 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 +12 -6
- 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 +980 -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 +172 -49
- 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 +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +9 -9
- package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
- 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 +3 -3
- package/coverage/lcov-report/automations/bullboard.js.html +71 -20
- package/coverage/lcov-report/automations/index.html +33 -48
- 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 +49 -4
- 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 +1 -1
- package/coverage/lcov-report/db/utils.js.html +1 -1
- 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 +98 -83
- 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} +83 -32
- package/coverage/lcov-report/threads/index.html +141 -0
- package/coverage/lcov-report/threads/index.js.html +260 -0
- package/coverage/lcov-report/threads/query.js.html +269 -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 +49 -49
- package/coverage/lcov-report/utilities/index.js.html +65 -17
- 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 +2301 -1599
- package/dist/api/controllers/application.js +16 -2
- package/dist/api/controllers/auth.js +3 -3
- package/dist/api/controllers/datasource.js +47 -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 +37 -14
- package/dist/api/controllers/row/external.js +1 -0
- package/dist/api/controllers/row/utils.js +6 -12
- package/dist/api/controllers/static/index.js +1 -1
- package/dist/api/controllers/table/external.js +242 -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/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 +13 -0
- package/dist/definitions/datasource.js +4 -0
- package/dist/integrations/base/IntegrationBase.js +2 -0
- package/dist/integrations/base/datasourcePlus.js +2 -0
- package/dist/integrations/base/sql.js +334 -180
- package/dist/integrations/base/sqlTable.js +143 -0
- package/dist/integrations/base/utils.js +30 -0
- package/dist/integrations/microsoftSqlServer.js +117 -9
- package/dist/integrations/mysql.js +14 -84
- package/dist/integrations/postgres.js +35 -28
- package/dist/integrations/utils.js +56 -9
- package/dist/middleware/authorized.js +2 -1
- package/dist/middleware/builder.js +4 -1
- package/dist/package.json +7 -6
- package/dist/tests/utilities/TestConfiguration.js +2 -1
- package/dist/{automations/thread.js → threads/automation.js} +23 -7
- package/dist/threads/index.js +58 -0
- package/dist/threads/query.js +61 -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 +18 -2
- package/dist/utilities/queue/inMemoryQueue.js +8 -0
- package/dist/utilities/scriptRunner.js +4 -1
- package/package.json +8 -7
- 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/likeCypress.ts +33 -0
- package/src/api/controllers/application.js +19 -2
- package/src/api/controllers/auth.js +3 -0
- package/src/api/controllers/datasource.js +56 -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 +47 -16
- package/src/api/controllers/row/external.js +2 -0
- package/src/api/controllers/row/utils.js +8 -11
- package/src/api/controllers/static/index.js +1 -1
- package/src/api/controllers/table/external.js +300 -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/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 +15 -0
- package/src/definitions/common.ts +7 -1
- package/src/definitions/datasource.ts +9 -3
- 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 +359 -222
- 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/microsoftSqlServer.ts +145 -13
- package/src/integrations/mongodb.ts +2 -1
- package/src/integrations/mysql.ts +20 -94
- 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/postgres.spec.js +4 -0
- package/src/integrations/utils.ts +60 -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} +24 -7
- package/src/threads/index.js +60 -0
- package/src/threads/query.js +63 -0
- package/src/utilities/csvParser.js +48 -5
- package/src/utilities/global.js +7 -2
- package/src/utilities/index.js +18 -2
- 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.34964222.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
|
@@ -26,6 +26,9 @@ const { clientLibraryPath, stringToReadStream } = require("../../utilities");
|
|
|
26
26
|
const { getAllLocks } = require("../../utilities/redis");
|
|
27
27
|
const { updateClientLibrary, backupClientLibrary, revertClientLibrary, } = require("../../utilities/fileSystem/clientLibrary");
|
|
28
28
|
const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy");
|
|
29
|
+
const { syncGlobalUsers } = require("./user");
|
|
30
|
+
const { app: appCache } = require("@budibase/auth/cache");
|
|
31
|
+
const { cleanupAutomations } = require("../../automations/utils");
|
|
29
32
|
const URL_REGEX_SLASH = /\/|\\/g;
|
|
30
33
|
// utility function, need to do away with this
|
|
31
34
|
function getLayouts(db) {
|
|
@@ -161,7 +164,7 @@ exports.fetchAppPackage = (ctx) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
161
164
|
application,
|
|
162
165
|
screens,
|
|
163
166
|
layouts,
|
|
164
|
-
clientLibPath: clientLibraryPath(ctx.params.appId),
|
|
167
|
+
clientLibPath: clientLibraryPath(ctx.params.appId, application.version),
|
|
165
168
|
};
|
|
166
169
|
});
|
|
167
170
|
exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -213,6 +216,7 @@ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
213
216
|
if (!env.isTest()) {
|
|
214
217
|
yield createApp(appId);
|
|
215
218
|
}
|
|
219
|
+
yield appCache.invalidateAppMetadata(appId, newApplication);
|
|
216
220
|
ctx.status = 200;
|
|
217
221
|
ctx.body = newApplication;
|
|
218
222
|
});
|
|
@@ -267,8 +271,12 @@ exports.delete = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
267
271
|
if (!env.isTest() && !ctx.query.unpublish) {
|
|
268
272
|
yield deleteApp(ctx.params.appId);
|
|
269
273
|
}
|
|
274
|
+
if (ctx.query && ctx.query.unpublish) {
|
|
275
|
+
yield cleanupAutomations(ctx.params.appId);
|
|
276
|
+
}
|
|
270
277
|
// make sure the app/role doesn't stick around after the app has been deleted
|
|
271
278
|
yield removeAppFromUserRoles(ctx, ctx.params.appId);
|
|
279
|
+
yield appCache.invalidateAppMetadata(ctx.params.appId);
|
|
272
280
|
ctx.status = 200;
|
|
273
281
|
ctx.body = result;
|
|
274
282
|
});
|
|
@@ -277,6 +285,7 @@ exports.sync = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
277
285
|
if (!isDevAppID(appId)) {
|
|
278
286
|
ctx.throw(400, "This action cannot be performed for production apps");
|
|
279
287
|
}
|
|
288
|
+
// replicate prod to dev
|
|
280
289
|
const prodAppId = getDeployedAppID(appId);
|
|
281
290
|
try {
|
|
282
291
|
const prodDb = new CouchDB(prodAppId, { skip_setup: true });
|
|
@@ -307,6 +316,8 @@ exports.sync = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
307
316
|
catch (err) {
|
|
308
317
|
error = err;
|
|
309
318
|
}
|
|
319
|
+
// sync the users
|
|
320
|
+
yield syncGlobalUsers(appId);
|
|
310
321
|
if (error) {
|
|
311
322
|
ctx.throw(400, error);
|
|
312
323
|
}
|
|
@@ -327,7 +338,10 @@ const updateAppPackage = (ctx, appPackage, appId) => __awaiter(void 0, void 0, v
|
|
|
327
338
|
// the locked by property is attached by server but generated from
|
|
328
339
|
// Redis, shouldn't ever store it
|
|
329
340
|
delete newAppPackage.lockedBy;
|
|
330
|
-
|
|
341
|
+
const response = yield db.put(newAppPackage);
|
|
342
|
+
// remove any cached metadata, so that it will be updated
|
|
343
|
+
yield appCache.invalidateAppMetadata(appId);
|
|
344
|
+
return response;
|
|
331
345
|
});
|
|
332
346
|
const createEmptyAppPackage = (ctx, app) => __awaiter(void 0, void 0, void 0, function* () {
|
|
333
347
|
const db = new CouchDB(app.appId);
|
|
@@ -22,6 +22,8 @@ exports.fetchSelf = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
const user = yield getFullUser(ctx, userId);
|
|
25
|
+
// this shouldn't be returned by the app self
|
|
26
|
+
delete user.roles;
|
|
25
27
|
if (appId) {
|
|
26
28
|
const db = new CouchDB(appId);
|
|
27
29
|
// remove the full roles structure
|
|
@@ -40,9 +42,7 @@ exports.fetchSelf = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
40
42
|
}
|
|
41
43
|
// user has a role of some sort, return them
|
|
42
44
|
else if (err.status === 404) {
|
|
43
|
-
const metadata = {
|
|
44
|
-
_id: userId,
|
|
45
|
-
};
|
|
45
|
+
const metadata = Object.assign(Object.assign({}, user), { _id: userId });
|
|
46
46
|
const dbResp = yield db.put(metadata);
|
|
47
47
|
user._rev = dbResp.rev;
|
|
48
48
|
response = user;
|
|
@@ -10,8 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
const CouchDB = require("../../db");
|
|
12
12
|
const { generateDatasourceID, getDatasourceParams, getQueryParams, DocumentTypes, BudibaseInternalDB, getTableParams, } = require("../../db/utils");
|
|
13
|
+
const { BuildSchemaErrors } = require("../../constants");
|
|
13
14
|
const { integrations } = require("../../integrations");
|
|
14
|
-
const {
|
|
15
|
+
const { getDatasourceAndQuery } = require("./row/utils");
|
|
15
16
|
exports.fetch = function (ctx) {
|
|
16
17
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17
18
|
const database = new CouchDB(ctx.appId);
|
|
@@ -33,11 +34,15 @@ exports.buildSchemaFromDb = function (ctx) {
|
|
|
33
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
35
|
const db = new CouchDB(ctx.appId);
|
|
35
36
|
const datasource = yield db.get(ctx.params.datasourceId);
|
|
36
|
-
const tables = yield buildSchemaHelper(datasource);
|
|
37
|
+
const { tables, error } = yield buildSchemaHelper(datasource);
|
|
37
38
|
datasource.entities = tables;
|
|
38
|
-
const
|
|
39
|
-
datasource._rev =
|
|
40
|
-
|
|
39
|
+
const dbResp = yield db.put(datasource);
|
|
40
|
+
datasource._rev = dbResp.rev;
|
|
41
|
+
const response = { datasource };
|
|
42
|
+
if (error) {
|
|
43
|
+
response.error = error;
|
|
44
|
+
}
|
|
45
|
+
ctx.body = response;
|
|
41
46
|
});
|
|
42
47
|
};
|
|
43
48
|
exports.update = function (ctx) {
|
|
@@ -57,7 +62,7 @@ exports.update = function (ctx) {
|
|
|
57
62
|
}
|
|
58
63
|
ctx.status = 200;
|
|
59
64
|
ctx.message = "Datasource saved successfully.";
|
|
60
|
-
ctx.body = datasource;
|
|
65
|
+
ctx.body = { datasource };
|
|
61
66
|
});
|
|
62
67
|
};
|
|
63
68
|
exports.save = function (ctx) {
|
|
@@ -66,12 +71,14 @@ exports.save = function (ctx) {
|
|
|
66
71
|
const plus = ctx.request.body.datasource.plus;
|
|
67
72
|
const fetchSchema = ctx.request.body.fetchSchema;
|
|
68
73
|
const datasource = Object.assign({ _id: generateDatasourceID({ plus }), type: plus ? DocumentTypes.DATASOURCE_PLUS : DocumentTypes.DATASOURCE }, ctx.request.body.datasource);
|
|
74
|
+
let schemaError = null;
|
|
69
75
|
if (fetchSchema) {
|
|
70
|
-
|
|
76
|
+
const { tables, error } = yield buildSchemaHelper(datasource);
|
|
77
|
+
schemaError = error;
|
|
71
78
|
datasource.entities = tables;
|
|
72
79
|
}
|
|
73
|
-
const
|
|
74
|
-
datasource._rev =
|
|
80
|
+
const dbResp = yield db.put(datasource);
|
|
81
|
+
datasource._rev = dbResp.rev;
|
|
75
82
|
// Drain connection pools when configuration is changed
|
|
76
83
|
if (datasource.source) {
|
|
77
84
|
const source = integrations[datasource.source];
|
|
@@ -79,17 +86,23 @@ exports.save = function (ctx) {
|
|
|
79
86
|
yield source.pool.end();
|
|
80
87
|
}
|
|
81
88
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
const response = { datasource };
|
|
90
|
+
if (schemaError) {
|
|
91
|
+
response.error = schemaError;
|
|
92
|
+
}
|
|
93
|
+
ctx.body = response;
|
|
85
94
|
});
|
|
86
95
|
};
|
|
87
96
|
exports.destroy = function (ctx) {
|
|
88
97
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
98
|
const db = new CouchDB(ctx.appId);
|
|
90
99
|
// Delete all queries for the datasource
|
|
91
|
-
const
|
|
92
|
-
yield db.bulkDocs(
|
|
100
|
+
const queries = yield db.allDocs(getQueryParams(ctx.params.datasourceId, null));
|
|
101
|
+
yield db.bulkDocs(queries.rows.map(row => ({
|
|
102
|
+
_id: row.id,
|
|
103
|
+
_rev: row.value.rev,
|
|
104
|
+
_deleted: true,
|
|
105
|
+
})));
|
|
93
106
|
// delete the datasource
|
|
94
107
|
yield db.remove(ctx.params.datasourceId, ctx.params.revId);
|
|
95
108
|
ctx.message = `Datasource deleted.`;
|
|
@@ -107,7 +120,7 @@ exports.query = function (ctx) {
|
|
|
107
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
108
121
|
const queryJson = ctx.request.body;
|
|
109
122
|
try {
|
|
110
|
-
ctx.body = yield
|
|
123
|
+
ctx.body = yield getDatasourceAndQuery(ctx.appId, queryJson);
|
|
111
124
|
}
|
|
112
125
|
catch (err) {
|
|
113
126
|
ctx.throw(400, err);
|
|
@@ -120,5 +133,23 @@ const buildSchemaHelper = (datasource) => __awaiter(void 0, void 0, void 0, func
|
|
|
120
133
|
const connector = new Connector(datasource.config);
|
|
121
134
|
yield connector.buildSchema(datasource._id, datasource.entities);
|
|
122
135
|
datasource.entities = connector.tables;
|
|
123
|
-
|
|
136
|
+
// make sure they all have a display name selected
|
|
137
|
+
for (let entity of Object.values(datasource.entities)) {
|
|
138
|
+
if (entity.primaryDisplay) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const notAutoColumn = Object.values(entity.schema).find(schema => !schema.autocolumn);
|
|
142
|
+
if (notAutoColumn) {
|
|
143
|
+
entity.primaryDisplay = notAutoColumn.name;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const errors = connector.schemaErrors;
|
|
147
|
+
let error = null;
|
|
148
|
+
if (errors && Object.keys(errors).length > 0) {
|
|
149
|
+
const noKeyTables = Object.entries(errors)
|
|
150
|
+
.filter(entry => entry[1] === BuildSchemaErrors.NO_KEY)
|
|
151
|
+
.map(([name]) => name);
|
|
152
|
+
error = `No primary key constraint found for the following: ${noKeyTables.join(", ")}`;
|
|
153
|
+
}
|
|
154
|
+
return { tables: connector.tables, error };
|
|
124
155
|
});
|
|
@@ -13,6 +13,7 @@ const Deployment = require("./Deployment");
|
|
|
13
13
|
const { Replication, getDeployedAppID } = require("@budibase/auth/db");
|
|
14
14
|
const { DocumentTypes, getAutomationParams } = require("../../../db/utils");
|
|
15
15
|
const { disableAllCrons, enableCronTrigger, } = require("../../../automations/utils");
|
|
16
|
+
const { app: appCache } = require("@budibase/auth/cache");
|
|
16
17
|
// the max time we can wait for an invalidation to complete before considering it failed
|
|
17
18
|
const MAX_PENDING_TIME_MS = 30 * 60000;
|
|
18
19
|
const DeploymentStatus = {
|
|
@@ -95,6 +96,7 @@ function deployApp(deployment) {
|
|
|
95
96
|
appDoc.appId = productionAppId;
|
|
96
97
|
appDoc.instance._id = productionAppId;
|
|
97
98
|
yield db.put(appDoc);
|
|
99
|
+
yield appCache.invalidateAppMetadata(productionAppId);
|
|
98
100
|
console.log("New app doc written successfully.");
|
|
99
101
|
yield initDeployedApp(productionAppId);
|
|
100
102
|
console.log("Deployed app initialised, setting deployment to successful");
|
|
@@ -16,6 +16,7 @@ const { request } = require("../../utilities/workerRequests");
|
|
|
16
16
|
const { clearLock } = require("../../utilities/redis");
|
|
17
17
|
const { Replication } = require("@budibase/auth").db;
|
|
18
18
|
const { DocumentTypes } = require("../../db/utils");
|
|
19
|
+
const { app: appCache } = require("@budibase/auth/cache");
|
|
19
20
|
function redirect(ctx, method, path = "global") {
|
|
20
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
22
|
const { devPath } = ctx.params;
|
|
@@ -25,7 +26,8 @@ function redirect(ctx, method, path = "global") {
|
|
|
25
26
|
body: ctx.request.body,
|
|
26
27
|
}, true));
|
|
27
28
|
if (response.status !== 200) {
|
|
28
|
-
|
|
29
|
+
const err = yield response.text();
|
|
30
|
+
ctx.throw(400, err);
|
|
29
31
|
}
|
|
30
32
|
const cookie = response.headers.get("set-cookie");
|
|
31
33
|
if (cookie) {
|
|
@@ -102,6 +104,7 @@ exports.revert = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
102
104
|
appDoc.appId = appId;
|
|
103
105
|
appDoc.instance._id = appId;
|
|
104
106
|
yield db.put(appDoc);
|
|
107
|
+
yield appCache.invalidateAppMetadata(appId);
|
|
105
108
|
ctx.body = {
|
|
106
109
|
message: "Reverted changes successfully.",
|
|
107
110
|
};
|
|
@@ -11,10 +11,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
const { processString } = require("@budibase/string-templates");
|
|
12
12
|
const CouchDB = require("../../db");
|
|
13
13
|
const { generateQueryID, getQueryParams } = require("../../db/utils");
|
|
14
|
-
const { integrations } = require("../../integrations");
|
|
15
14
|
const { BaseQueryVerbs } = require("../../constants");
|
|
16
15
|
const env = require("../../environment");
|
|
17
|
-
const
|
|
16
|
+
const { Thread, ThreadType } = require("../../threads");
|
|
17
|
+
const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 });
|
|
18
18
|
// simple function to append "readable" to all read queries
|
|
19
19
|
function enrichQueries(input) {
|
|
20
20
|
const wasArray = Array.isArray(input);
|
|
@@ -26,38 +26,6 @@ function enrichQueries(input) {
|
|
|
26
26
|
}
|
|
27
27
|
return wasArray ? queries : queries[0];
|
|
28
28
|
}
|
|
29
|
-
function formatResponse(resp) {
|
|
30
|
-
if (typeof resp === "string") {
|
|
31
|
-
try {
|
|
32
|
-
resp = JSON.parse(resp);
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
resp = { response: resp };
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return resp;
|
|
39
|
-
}
|
|
40
|
-
function runAndTransform(integration, queryVerb, enrichedQuery, transformer) {
|
|
41
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
let rows = formatResponse(yield integration[queryVerb](enrichedQuery));
|
|
43
|
-
// transform as required
|
|
44
|
-
if (transformer) {
|
|
45
|
-
const runner = new ScriptRunner(transformer, { data: rows });
|
|
46
|
-
rows = runner.execute();
|
|
47
|
-
}
|
|
48
|
-
// needs to an array for next step
|
|
49
|
-
if (!Array.isArray(rows)) {
|
|
50
|
-
rows = [rows];
|
|
51
|
-
}
|
|
52
|
-
// map into JSON if just raw primitive here
|
|
53
|
-
if (rows.find(row => typeof row !== "object")) {
|
|
54
|
-
rows = rows.map(value => ({ value }));
|
|
55
|
-
}
|
|
56
|
-
// get all the potential fields in the schema
|
|
57
|
-
let keys = rows.flatMap(Object.keys);
|
|
58
|
-
return { rows, keys };
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
29
|
exports.fetch = function (ctx) {
|
|
62
30
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
31
|
const db = new CouchDB(ctx.appId);
|
|
@@ -94,7 +62,9 @@ function enrichQueryFields(fields, parameters = {}) {
|
|
|
94
62
|
}
|
|
95
63
|
else if (typeof fields[key] === "string") {
|
|
96
64
|
// enrich string value as normal
|
|
97
|
-
enrichedQuery[key] = yield processString(fields[key], parameters
|
|
65
|
+
enrichedQuery[key] = yield processString(fields[key], parameters, {
|
|
66
|
+
noHelpers: true,
|
|
67
|
+
});
|
|
98
68
|
}
|
|
99
69
|
else {
|
|
100
70
|
enrichedQuery[key] = fields[key];
|
|
@@ -133,21 +103,22 @@ exports.preview = function (ctx) {
|
|
|
133
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
134
104
|
const db = new CouchDB(ctx.appId);
|
|
135
105
|
const datasource = yield db.get(ctx.request.body.datasourceId);
|
|
136
|
-
const Integration = integrations[datasource.source];
|
|
137
|
-
if (!Integration) {
|
|
138
|
-
ctx.throw(400, "Integration type does not exist.");
|
|
139
|
-
}
|
|
140
106
|
const { fields, parameters, queryVerb, transformer } = ctx.request.body;
|
|
141
107
|
const enrichedQuery = yield enrichQueryFields(fields, parameters);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
108
|
+
try {
|
|
109
|
+
const { rows, keys } = yield Runner.run({
|
|
110
|
+
datasource,
|
|
111
|
+
queryVerb,
|
|
112
|
+
query: enrichedQuery,
|
|
113
|
+
transformer,
|
|
114
|
+
});
|
|
115
|
+
ctx.body = {
|
|
116
|
+
rows,
|
|
117
|
+
schemaFields: [...new Set(keys)],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
ctx.throw(400, err);
|
|
151
122
|
}
|
|
152
123
|
});
|
|
153
124
|
};
|
|
@@ -156,18 +127,19 @@ exports.execute = function (ctx) {
|
|
|
156
127
|
const db = new CouchDB(ctx.appId);
|
|
157
128
|
const query = yield db.get(ctx.params.queryId);
|
|
158
129
|
const datasource = yield db.get(query.datasourceId);
|
|
159
|
-
const Integration = integrations[datasource.source];
|
|
160
|
-
if (!Integration) {
|
|
161
|
-
ctx.throw(400, "Integration type does not exist.");
|
|
162
|
-
}
|
|
163
130
|
const enrichedQuery = yield enrichQueryFields(query.fields, ctx.request.body.parameters);
|
|
164
|
-
const integration = new Integration(datasource.config);
|
|
165
131
|
// call the relevant CRUD method on the integration class
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
132
|
+
try {
|
|
133
|
+
const { rows } = yield Runner.run({
|
|
134
|
+
datasource,
|
|
135
|
+
queryVerb: query.queryVerb,
|
|
136
|
+
query: enrichedQuery,
|
|
137
|
+
transformer: query.transformer,
|
|
138
|
+
});
|
|
139
|
+
ctx.body = rows;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
ctx.throw(400, err);
|
|
171
143
|
}
|
|
172
144
|
});
|
|
173
145
|
};
|
|
@@ -24,12 +24,13 @@ const datasource_1 = require("../../../definitions/datasource");
|
|
|
24
24
|
const utils_1 = require("../../../integrations/utils");
|
|
25
25
|
var External;
|
|
26
26
|
(function (External) {
|
|
27
|
-
const {
|
|
27
|
+
const { getDatasourceAndQuery } = require("./utils");
|
|
28
28
|
const { DataSourceOperation, FieldTypes, RelationshipTypes, } = require("../../../constants");
|
|
29
29
|
const { breakExternalTableId, isSQL } = require("../../../integrations/utils");
|
|
30
30
|
const { processObjectSync } = require("@budibase/string-templates");
|
|
31
31
|
const { cloneDeep } = require("lodash/fp");
|
|
32
32
|
const CouchDB = require("../../../db");
|
|
33
|
+
const { processFormulas } = require("../../../utilities/rowProcessor/utils");
|
|
33
34
|
function buildFilters(id, filters, table) {
|
|
34
35
|
const primary = table.primary;
|
|
35
36
|
// if passed in array need to copy for shifting etc
|
|
@@ -151,6 +152,21 @@ var External;
|
|
|
151
152
|
thisRow._rev = "rev";
|
|
152
153
|
return thisRow;
|
|
153
154
|
}
|
|
155
|
+
function fixArrayTypes(row, table) {
|
|
156
|
+
for (let [fieldName, schema] of Object.entries(table.schema)) {
|
|
157
|
+
if (schema.type === FieldTypes.ARRAY &&
|
|
158
|
+
typeof row[fieldName] === "string") {
|
|
159
|
+
try {
|
|
160
|
+
row[fieldName] = JSON.parse(row[fieldName]);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// couldn't convert back to array, ignore
|
|
164
|
+
delete row[fieldName];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return row;
|
|
169
|
+
}
|
|
154
170
|
function isMany(field) {
|
|
155
171
|
return (field.relationshipType && field.relationshipType.split("-")[0] === "many");
|
|
156
172
|
}
|
|
@@ -182,7 +198,10 @@ var External;
|
|
|
182
198
|
let newRow = {}, manyRelationships = [];
|
|
183
199
|
for (let [key, field] of Object.entries(table.schema)) {
|
|
184
200
|
// if set already, or not set just skip it
|
|
185
|
-
if (
|
|
201
|
+
if (row[key] == null ||
|
|
202
|
+
newRow[key] ||
|
|
203
|
+
field.autocolumn ||
|
|
204
|
+
field.type === FieldTypes.FORMULA) {
|
|
186
205
|
continue;
|
|
187
206
|
}
|
|
188
207
|
// if its an empty string then it means return the column to null (if possible)
|
|
@@ -278,7 +297,7 @@ var External;
|
|
|
278
297
|
return rows;
|
|
279
298
|
}
|
|
280
299
|
outputProcessing(rows = [], table, relationships) {
|
|
281
|
-
if (rows[0].read === true) {
|
|
300
|
+
if (!rows || rows.length === 0 || rows[0].read === true) {
|
|
282
301
|
return [];
|
|
283
302
|
}
|
|
284
303
|
let finalRows = {};
|
|
@@ -290,12 +309,15 @@ var External;
|
|
|
290
309
|
finalRows = this.updateRelationshipColumns(row, finalRows, relationships);
|
|
291
310
|
continue;
|
|
292
311
|
}
|
|
293
|
-
const thisRow = basicProcessing(row, table);
|
|
312
|
+
const thisRow = fixArrayTypes(basicProcessing(row, table), table);
|
|
313
|
+
if (thisRow._id == null) {
|
|
314
|
+
throw "Unable to generate row ID for SQL rows";
|
|
315
|
+
}
|
|
294
316
|
finalRows[thisRow._id] = thisRow;
|
|
295
317
|
// do this at end once its been added to the final rows
|
|
296
318
|
finalRows = this.updateRelationshipColumns(row, finalRows, relationships);
|
|
297
319
|
}
|
|
298
|
-
return Object.values(finalRows);
|
|
320
|
+
return processFormulas(table, Object.values(finalRows));
|
|
299
321
|
}
|
|
300
322
|
/**
|
|
301
323
|
* Gets the list of relationship JSON structures based on the columns in the table,
|
|
@@ -359,7 +381,7 @@ var External;
|
|
|
359
381
|
const tableId = isMany ? field.through : field.tableId;
|
|
360
382
|
const manyKey = field.throughFrom || primaryKey;
|
|
361
383
|
const fieldName = isMany ? manyKey : field.fieldName;
|
|
362
|
-
const response = yield
|
|
384
|
+
const response = yield getDatasourceAndQuery(this.appId, {
|
|
363
385
|
endpoint: getEndpoint(tableId, DataSourceOperation.READ),
|
|
364
386
|
filters: {
|
|
365
387
|
equal: {
|
|
@@ -403,7 +425,7 @@ var External;
|
|
|
403
425
|
? DataSourceOperation.UPDATE
|
|
404
426
|
: DataSourceOperation.CREATE;
|
|
405
427
|
if (!found) {
|
|
406
|
-
promises.push(
|
|
428
|
+
promises.push(getDatasourceAndQuery(appId, {
|
|
407
429
|
endpoint: getEndpoint(tableId, operation),
|
|
408
430
|
// if we're doing many relationships then we're writing, only one response
|
|
409
431
|
body,
|
|
@@ -430,7 +452,7 @@ var External;
|
|
|
430
452
|
? DataSourceOperation.DELETE
|
|
431
453
|
: DataSourceOperation.UPDATE;
|
|
432
454
|
const body = isMany ? null : { [colName]: null };
|
|
433
|
-
promises.push(
|
|
455
|
+
promises.push(getDatasourceAndQuery(this.appId, {
|
|
434
456
|
endpoint: getEndpoint(tableId, op),
|
|
435
457
|
body,
|
|
436
458
|
filters,
|
|
@@ -449,13 +471,14 @@ var External;
|
|
|
449
471
|
* is more performant and has the added benefit of protecting against this scenario.
|
|
450
472
|
*/
|
|
451
473
|
buildFields(table, includeRelations = datasource_1.IncludeRelationships.INCLUDE) {
|
|
452
|
-
function
|
|
474
|
+
function extractRealFields(table, existing = []) {
|
|
453
475
|
return Object.entries(table.schema)
|
|
454
476
|
.filter(column => column[1].type !== FieldTypes.LINK &&
|
|
477
|
+
column[1].type !== FieldTypes.FORMULA &&
|
|
455
478
|
!existing.find((field) => field === column[0]))
|
|
456
479
|
.map(column => `${table.name}.${column[0]}`);
|
|
457
480
|
}
|
|
458
|
-
let fields =
|
|
481
|
+
let fields = extractRealFields(table);
|
|
459
482
|
for (let field of Object.values(table.schema)) {
|
|
460
483
|
if (field.type !== FieldTypes.LINK || !includeRelations) {
|
|
461
484
|
continue;
|
|
@@ -463,7 +486,7 @@ var External;
|
|
|
463
486
|
const { tableName: linkTableName } = breakExternalTableId(field.tableId);
|
|
464
487
|
const linkTable = this.tables[linkTableName];
|
|
465
488
|
if (linkTable) {
|
|
466
|
-
const linkedFields =
|
|
489
|
+
const linkedFields = extractRealFields(linkTable, fields);
|
|
467
490
|
fields = fields.concat(linkedFields);
|
|
468
491
|
}
|
|
469
492
|
}
|
|
@@ -487,7 +510,7 @@ var External;
|
|
|
487
510
|
throw `Unable to process query, table "${tableName}" not defined.`;
|
|
488
511
|
}
|
|
489
512
|
// look for specific components of config which may not be considered acceptable
|
|
490
|
-
let { id, row, filters, sort, paginate } = cleanupConfig(config, table);
|
|
513
|
+
let { id, row, filters, sort, paginate, rows } = cleanupConfig(config, table);
|
|
491
514
|
filters = buildFilters(id, filters || {}, table);
|
|
492
515
|
const relationships = this.buildRelationships(table);
|
|
493
516
|
// clean up row on ingress using schema
|
|
@@ -511,7 +534,7 @@ var External;
|
|
|
511
534
|
sort,
|
|
512
535
|
paginate,
|
|
513
536
|
relationships,
|
|
514
|
-
body: row,
|
|
537
|
+
body: row || rows,
|
|
515
538
|
// pass an id filter into extra, purely for mysql/returning
|
|
516
539
|
extra: {
|
|
517
540
|
idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
|
|
@@ -521,7 +544,7 @@ var External;
|
|
|
521
544
|
},
|
|
522
545
|
};
|
|
523
546
|
// can't really use response right now
|
|
524
|
-
const response = yield
|
|
547
|
+
const response = yield getDatasourceAndQuery(appId, json);
|
|
525
548
|
// handle many to many relationships now if we know the ID (could be auto increment)
|
|
526
549
|
if (operation !== DataSourceOperation.READ &&
|
|
527
550
|
processed.manyRelationships) {
|
|
@@ -41,6 +41,7 @@ function handleRequest(appId, operation, tableId, opts = {}) {
|
|
|
41
41
|
return new ExternalRequest(appId, operation, tableId, opts.datasource).run(opts);
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
+
exports.handleRequest = handleRequest;
|
|
44
45
|
exports.patch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
46
|
const appId = ctx.appId;
|
|
46
47
|
const inputs = ctx.request.body;
|
|
@@ -14,8 +14,8 @@ const CouchDB = require("../../../db");
|
|
|
14
14
|
const { InternalTables } = require("../../../db/utils");
|
|
15
15
|
const userController = require("../user");
|
|
16
16
|
const { FieldTypes } = require("../../../constants");
|
|
17
|
-
const { integrations } = require("../../../integrations");
|
|
18
17
|
const { processStringSync } = require("@budibase/string-templates");
|
|
18
|
+
const { makeExternalQuery } = require("../../../integrations/base/utils");
|
|
19
19
|
validateJs.extend(validateJs.validators.datetime, {
|
|
20
20
|
parse: function (value) {
|
|
21
21
|
return new Date(value).getTime();
|
|
@@ -25,19 +25,11 @@ validateJs.extend(validateJs.validators.datetime, {
|
|
|
25
25
|
return new Date(value).toISOString();
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
|
-
exports.
|
|
28
|
+
exports.getDatasourceAndQuery = (appId, json) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
29
|
const datasourceId = json.endpoint.datasourceId;
|
|
30
30
|
const db = new CouchDB(appId);
|
|
31
31
|
const datasource = yield db.get(datasourceId);
|
|
32
|
-
|
|
33
|
-
// query is the opinionated function
|
|
34
|
-
if (Integration.prototype.query) {
|
|
35
|
-
const integration = new Integration(datasource.config);
|
|
36
|
-
return integration.query(json);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
throw "Datasource does not support query.";
|
|
40
|
-
}
|
|
32
|
+
return makeExternalQuery(datasource, json);
|
|
41
33
|
});
|
|
42
34
|
exports.findRow = (ctx, db, tableId, rowId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
35
|
let row;
|
|
@@ -73,7 +65,9 @@ exports.validate = ({ appId, tableId, row, table }) => __awaiter(void 0, void 0,
|
|
|
73
65
|
}
|
|
74
66
|
let res;
|
|
75
67
|
// Validate.js doesn't seem to handle array
|
|
76
|
-
if (table.schema[fieldName].type === FieldTypes.ARRAY
|
|
68
|
+
if (table.schema[fieldName].type === FieldTypes.ARRAY &&
|
|
69
|
+
row[fieldName] &&
|
|
70
|
+
row[fieldName].length) {
|
|
77
71
|
row[fieldName].map(val => {
|
|
78
72
|
if (!constraints.inclusion.includes(val)) {
|
|
79
73
|
errors[fieldName] = "Field not in list";
|
|
@@ -91,7 +91,7 @@ exports.serveApp = function (ctx) {
|
|
|
91
91
|
title: appInfo.name,
|
|
92
92
|
production: env.isProd(),
|
|
93
93
|
appId,
|
|
94
|
-
clientLibPath: clientLibraryPath(appId),
|
|
94
|
+
clientLibPath: clientLibraryPath(appId, appInfo.version),
|
|
95
95
|
});
|
|
96
96
|
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`);
|
|
97
97
|
ctx.body = yield processString(appHbs, {
|