@budibase/server 1.0.26 → 1.0.27-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/__mocks__/node-fetch.ts +21 -0
- package/builder/assets/bb-spaceship.8f6e81e1.svg +227 -0
- package/builder/assets/{index.4fb3f887.css → index.0dce895b.css} +1 -1
- package/builder/assets/index.b98dd7ca.js +1348 -0
- package/builder/assets/{vendor.470042a4.js → vendor.f9faf6ab.js} +88 -88
- package/builder/index.html +3 -3
- package/coverage/clover.xml +1364 -1121
- package/coverage/coverage-final.json +37 -36
- package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +59 -59
- package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
- package/coverage/lcov-report/api/controllers/automation.js.html +22 -10
- 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 +170 -68
- package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
- package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +39 -54
- package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +126 -0
- package/coverage/lcov-report/api/controllers/{query.js.html → query/index.js.html} +225 -114
- package/coverage/lcov-report/api/controllers/query/validation.js.html +206 -0
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +22 -22
- package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +38 -11
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +7 -4
- package/coverage/lcov-report/api/controllers/row/utils.js.html +29 -20
- package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
- package/coverage/lcov-report/api/controllers/user.js.html +108 -9
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/controllers/webhook.js.html +18 -6
- 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 +1 -1
- package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
- package/coverage/lcov-report/api/routes/index.html +9 -9
- 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 +19 -85
- 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 +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +1 -1
- package/coverage/lcov-report/api/routes/templates.js.html +1 -1
- package/coverage/lcov-report/api/routes/user.js.html +32 -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 +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +20 -20
- package/coverage/lcov-report/automations/index.js.html +1 -1
- 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 +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +31 -7
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +11 -11
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +5 -8
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- 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 +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +1 -1
- package/coverage/lcov-report/automations/utils.js.html +48 -15
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +22 -22
- 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 +18 -18
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +15 -15
- package/coverage/lcov-report/db/index.js.html +3 -3
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +4 -4
- package/coverage/lcov-report/db/utils.js.html +107 -80
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +1 -1
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +99 -84
- 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 +1 -1
- package/coverage/lcov-report/middleware/authorized.js.html +10 -10
- package/coverage/lcov-report/middleware/builder.js.html +8 -8
- package/coverage/lcov-report/middleware/currentapp.js.html +28 -28
- package/coverage/lcov-report/middleware/index.html +1 -1
- package/coverage/lcov-report/middleware/joi-validator.js.html +11 -11
- package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +2 -2
- package/coverage/lcov-report/threads/automation.js.html +1 -1
- package/coverage/lcov-report/threads/index.html +31 -31
- package/coverage/lcov-report/threads/index.js.html +12 -12
- package/coverage/lcov-report/threads/query.js.html +396 -69
- package/coverage/lcov-report/threads/utils.js.html +358 -13
- 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 +1 -1
- package/coverage/lcov-report/utilities/global.js.html +13 -13
- package/coverage/lcov-report/utilities/index.html +19 -19
- package/coverage/lcov-report/utilities/index.js.html +69 -36
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- 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 +19 -19
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +235 -10
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +2 -2
- 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 +19 -19
- package/coverage/lcov.info +2294 -1874
- package/dist/api/controllers/automation.js +7 -5
- package/dist/api/controllers/datasource.js +29 -0
- package/dist/api/controllers/query/import/index.js +79 -0
- package/dist/api/controllers/query/import/sources/base/index.js +64 -0
- package/dist/api/controllers/query/import/sources/base/openapi.js +42 -0
- package/dist/api/controllers/query/import/sources/curl.js +96 -0
- package/dist/api/controllers/query/import/sources/openapi2.js +142 -0
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
- package/dist/api/controllers/{query.js → query/index.js} +86 -52
- package/dist/api/controllers/query/validation.js +38 -0
- package/dist/api/controllers/row/internal.js +14 -6
- package/dist/api/controllers/row/internalSearch.js +2 -1
- package/dist/api/controllers/row/utils.js +13 -6
- package/dist/api/controllers/user.js +37 -1
- package/dist/api/controllers/webhook.js +4 -0
- package/dist/api/routes/query.js +5 -33
- package/dist/api/routes/user.js +3 -1
- package/dist/automations/steps/executeQuery.js +8 -1
- package/dist/automations/steps/outgoingWebhook.js +2 -3
- package/dist/automations/utils.js +10 -0
- package/dist/db/utils.js +8 -0
- package/dist/definitions/datasource.js +6 -1
- package/dist/integrations/base/sqlTable.js +1 -1
- package/dist/integrations/rest.js +207 -117
- package/dist/package.json +11 -4
- package/dist/tests/utilities/TestConfiguration.js +47 -0
- package/dist/threads/query.js +148 -40
- package/dist/threads/utils.js +105 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/utilities.js +2 -1
- package/dist/utilities/index.js +10 -0
- package/dist/utilities/rowProcessor/index.js +76 -0
- package/package.json +12 -5
- package/src/api/controllers/automation.js +8 -4
- package/src/api/controllers/datasource.js +34 -0
- package/src/api/controllers/query/import/index.ts +85 -0
- package/src/api/controllers/query/import/sources/base/index.ts +87 -0
- package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
- package/src/api/controllers/query/import/sources/curl.ts +102 -0
- package/src/api/controllers/query/import/sources/openapi2.ts +163 -0
- package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +103 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
- package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
- package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
- package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
- package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
- package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
- package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +238 -0
- package/src/api/controllers/query/import/tests/index.spec.js +109 -0
- package/src/api/controllers/query/index.js +195 -0
- package/src/api/controllers/query/validation.js +42 -0
- package/src/api/controllers/row/internal.js +14 -5
- package/src/api/controllers/row/internalSearch.js +2 -1
- package/src/api/controllers/row/utils.js +11 -8
- package/src/api/controllers/user.js +33 -0
- package/src/api/controllers/webhook.js +4 -0
- package/src/api/routes/query.js +13 -35
- package/src/api/routes/tests/datasource.spec.js +45 -0
- package/src/api/routes/tests/query.spec.js +69 -0
- package/src/api/routes/user.js +10 -0
- package/src/automations/steps/executeQuery.js +9 -1
- package/src/automations/steps/outgoingWebhook.js +2 -3
- package/src/automations/utils.js +11 -0
- package/src/db/utils.js +9 -0
- package/src/definitions/common.ts +2 -16
- package/src/definitions/datasource.ts +83 -1
- package/src/integrations/base/IntegrationBase.ts +4 -4
- package/src/integrations/base/sqlTable.ts +1 -1
- package/src/integrations/oracle.ts +1 -1
- package/src/integrations/rest.ts +230 -137
- package/src/integrations/tests/rest.spec.js +167 -19
- package/src/tests/utilities/TestConfiguration.js +57 -0
- package/src/threads/query.js +149 -40
- package/src/threads/utils.js +115 -0
- package/src/utilities/fileSystem/utilities.js +2 -0
- package/src/utilities/index.js +11 -0
- package/src/utilities/rowProcessor/index.js +75 -0
- package/builder/assets/index.8adef83f.js +0 -1316
- package/src/api/controllers/query.js +0 -158
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const { ObjectStore, makeSureBucketExists, upload, streamUpload, retrieve, retrieveToTmp, deleteFolder, uploadDirectory, downloadTarball, } = require("@budibase/auth").objectStore;
|
|
2
|
+
const { ObjectStore, makeSureBucketExists, upload, deleteFiles, streamUpload, retrieve, retrieveToTmp, deleteFolder, uploadDirectory, downloadTarball, } = require("@budibase/auth").objectStore;
|
|
3
3
|
/***********************************
|
|
4
4
|
* NOTE *
|
|
5
5
|
* This file purely exists so that *
|
|
@@ -17,3 +17,4 @@ exports.retrieveToTmp = retrieveToTmp;
|
|
|
17
17
|
exports.deleteFolder = deleteFolder;
|
|
18
18
|
exports.uploadDirectory = uploadDirectory;
|
|
19
19
|
exports.downloadTarball = downloadTarball;
|
|
20
|
+
exports.deleteFiles = deleteFiles;
|
package/dist/utilities/index.js
CHANGED
|
@@ -142,3 +142,13 @@ exports.doesDatabaseExist = (dbName) => __awaiter(void 0, void 0, void 0, functi
|
|
|
142
142
|
return false;
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
|
+
exports.formatBytes = bytes => {
|
|
146
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
147
|
+
const byteIncrements = 1024;
|
|
148
|
+
let unit = 0;
|
|
149
|
+
let size = parseInt(bytes, 10) || 0;
|
|
150
|
+
while (size >= byteIncrements && ++unit) {
|
|
151
|
+
size /= byteIncrements;
|
|
152
|
+
}
|
|
153
|
+
return `${size.toFixed(size < 10 && unit > 0 ? 1 : 0)}${units[unit]}`;
|
|
154
|
+
};
|
|
@@ -13,6 +13,10 @@ const { cloneDeep } = require("lodash/fp");
|
|
|
13
13
|
const { FieldTypes, AutoFieldSubTypes } = require("../../constants");
|
|
14
14
|
const { attachmentsRelativeURL } = require("../index");
|
|
15
15
|
const { processFormulas } = require("./utils");
|
|
16
|
+
const { deleteFiles } = require("../../utilities/fileSystem/utilities");
|
|
17
|
+
const { ObjectStoreBuckets } = require("../../constants");
|
|
18
|
+
const { isProdAppID, getDeployedAppID, dbExists } = require("@budibase/auth/db");
|
|
19
|
+
const CouchDB = require("../../db");
|
|
16
20
|
const BASE_AUTO_ID = 1;
|
|
17
21
|
/**
|
|
18
22
|
* A map of how we convert various properties in rows to each other based on the row type.
|
|
@@ -89,7 +93,36 @@ const TYPE_TRANSFORM_MAP = {
|
|
|
89
93
|
[FieldTypes.AUTO]: {
|
|
90
94
|
parse: () => undefined,
|
|
91
95
|
},
|
|
96
|
+
[FieldTypes.JSON]: {
|
|
97
|
+
parse: input => {
|
|
98
|
+
try {
|
|
99
|
+
if (input === "") {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
return JSON.parse(input);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return input;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
},
|
|
92
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Given the old state of the row and the new one after an update, this will
|
|
112
|
+
* find the keys that have been removed in the updated row.
|
|
113
|
+
*/
|
|
114
|
+
function getRemovedAttachmentKeys(oldRow, row, attachmentKey) {
|
|
115
|
+
if (!oldRow[attachmentKey]) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
const oldKeys = oldRow[attachmentKey].map(attachment => attachment.key);
|
|
119
|
+
// no attachments in new row, all removed
|
|
120
|
+
if (!row[attachmentKey]) {
|
|
121
|
+
return oldKeys;
|
|
122
|
+
}
|
|
123
|
+
const newKeys = row[attachmentKey].map(attachment => attachment.key);
|
|
124
|
+
return oldKeys.filter(key => newKeys.indexOf(key) === -1);
|
|
125
|
+
}
|
|
93
126
|
/**
|
|
94
127
|
* This will update any auto columns that are found on the row/table with the correct information based on
|
|
95
128
|
* time now and the current logged in user making the request.
|
|
@@ -240,3 +273,46 @@ exports.outputProcessing = (ctx, table, rows, opts = { squash: true }) => __awai
|
|
|
240
273
|
}
|
|
241
274
|
return wasArray ? enriched : enriched[0];
|
|
242
275
|
});
|
|
276
|
+
/**
|
|
277
|
+
* Clean up any attachments that were attached to a row.
|
|
278
|
+
* @param {string} appId The ID of the app from which a row is being deleted.
|
|
279
|
+
* @param {object} table The table from which a row is being removed.
|
|
280
|
+
* @param {any} row optional - the row being removed.
|
|
281
|
+
* @param {any} rows optional - if multiple rows being deleted can do this in bulk.
|
|
282
|
+
* @param {any} oldRow optional - if updating a row this will determine the difference.
|
|
283
|
+
* @return {Promise<void>} When all attachments have been removed this will return.
|
|
284
|
+
*/
|
|
285
|
+
exports.cleanupAttachments = (appId, table, { row, rows, oldRow }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
286
|
+
if (!isProdAppID(appId)) {
|
|
287
|
+
const prodAppId = getDeployedAppID(appId);
|
|
288
|
+
// if prod exists, then don't allow deleting
|
|
289
|
+
const exists = yield dbExists(CouchDB, prodAppId);
|
|
290
|
+
if (exists) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
let files = [];
|
|
295
|
+
function addFiles(row, key) {
|
|
296
|
+
if (row[key]) {
|
|
297
|
+
files = files.concat(row[key].map(attachment => attachment.key));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
for (let [key, schema] of Object.entries(table.schema)) {
|
|
301
|
+
if (schema.type !== FieldTypes.ATTACHMENT) {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
// if updating, need to manage the differences
|
|
305
|
+
if (oldRow && row) {
|
|
306
|
+
files = files.concat(getRemovedAttachmentKeys(oldRow, row, key));
|
|
307
|
+
}
|
|
308
|
+
else if (row) {
|
|
309
|
+
addFiles(row, key);
|
|
310
|
+
}
|
|
311
|
+
else if (rows) {
|
|
312
|
+
rows.forEach(row => addFiles(row, key));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (files.length > 0) {
|
|
316
|
+
return deleteFiles(ObjectStoreBuckets.APPS, files);
|
|
317
|
+
}
|
|
318
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.27-alpha.11",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -69,9 +69,10 @@
|
|
|
69
69
|
"author": "Budibase",
|
|
70
70
|
"license": "GPL-3.0",
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@
|
|
73
|
-
"@budibase/
|
|
74
|
-
"@budibase/
|
|
72
|
+
"@apidevtools/swagger-parser": "^10.0.3",
|
|
73
|
+
"@budibase/auth": "^1.0.27-alpha.11",
|
|
74
|
+
"@budibase/client": "^1.0.27-alpha.11",
|
|
75
|
+
"@budibase/string-templates": "^1.0.27-alpha.11",
|
|
75
76
|
"@bull-board/api": "^3.7.0",
|
|
76
77
|
"@bull-board/koa": "^3.7.0",
|
|
77
78
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -85,12 +86,15 @@
|
|
|
85
86
|
"bull": "^3.22.4",
|
|
86
87
|
"chmodr": "1.2.0",
|
|
87
88
|
"csvtojson": "2.0.10",
|
|
89
|
+
"curlconverter": "^3.21.0",
|
|
88
90
|
"dotenv": "8.2.0",
|
|
89
91
|
"download": "8.0.0",
|
|
90
92
|
"fix-path": "3.0.0",
|
|
93
|
+
"form-data": "^4.0.0",
|
|
91
94
|
"fs-extra": "8.1.0",
|
|
92
95
|
"jimp": "0.16.1",
|
|
93
96
|
"joi": "17.2.1",
|
|
97
|
+
"js-yaml": "^4.1.0",
|
|
94
98
|
"jsonschema": "1.4.0",
|
|
95
99
|
"knex": "^0.95.6",
|
|
96
100
|
"koa": "2.7.0",
|
|
@@ -118,11 +122,13 @@
|
|
|
118
122
|
"pouchdb-replication-stream": "1.2.9",
|
|
119
123
|
"server-destroy": "1.0.1",
|
|
120
124
|
"svelte": "^3.38.2",
|
|
125
|
+
"swagger-parser": "^10.0.3",
|
|
121
126
|
"to-json-schema": "0.2.5",
|
|
122
127
|
"uuid": "3.3.2",
|
|
123
128
|
"validate.js": "0.13.1",
|
|
124
129
|
"vm2": "^3.9.3",
|
|
125
130
|
"worker-farm": "^1.7.0",
|
|
131
|
+
"xml2js": "^0.4.23",
|
|
126
132
|
"yargs": "13.2.4",
|
|
127
133
|
"zlib": "1.0.5"
|
|
128
134
|
},
|
|
@@ -146,6 +152,7 @@
|
|
|
146
152
|
"eslint": "^6.8.0",
|
|
147
153
|
"jest": "^27.0.5",
|
|
148
154
|
"nodemon": "^2.0.4",
|
|
155
|
+
"openapi-types": "^9.3.1",
|
|
149
156
|
"path-to-regexp": "^6.2.0",
|
|
150
157
|
"prettier": "^2.3.1",
|
|
151
158
|
"rimraf": "^3.0.2",
|
|
@@ -158,5 +165,5 @@
|
|
|
158
165
|
"optionalDependencies": {
|
|
159
166
|
"oracledb": "^5.3.0"
|
|
160
167
|
},
|
|
161
|
-
"gitHead": "
|
|
168
|
+
"gitHead": "45631b235ddba52942183e312b9154fbdb4ea862"
|
|
162
169
|
}
|
|
@@ -5,11 +5,15 @@ const { getAutomationParams, generateAutomationID } = require("../../db/utils")
|
|
|
5
5
|
const {
|
|
6
6
|
checkForWebhooks,
|
|
7
7
|
updateTestHistory,
|
|
8
|
+
removeDeprecated,
|
|
8
9
|
} = require("../../automations/utils")
|
|
9
10
|
const { deleteEntityMetadata } = require("../../utilities")
|
|
10
11
|
const { MetadataTypes } = require("../../constants")
|
|
11
12
|
const { setTestFlag, clearTestFlag } = require("../../utilities/redis")
|
|
12
13
|
|
|
14
|
+
const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS)
|
|
15
|
+
const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
|
|
16
|
+
|
|
13
17
|
/*************************
|
|
14
18
|
* *
|
|
15
19
|
* BUILDER FUNCTIONS *
|
|
@@ -155,17 +159,17 @@ exports.destroy = async function (ctx) {
|
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
exports.getActionList = async function (ctx) {
|
|
158
|
-
ctx.body =
|
|
162
|
+
ctx.body = ACTION_DEFS
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
exports.getTriggerList = async function (ctx) {
|
|
162
|
-
ctx.body =
|
|
166
|
+
ctx.body = TRIGGER_DEFS
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
module.exports.getDefinitionList = async function (ctx) {
|
|
166
170
|
ctx.body = {
|
|
167
|
-
trigger:
|
|
168
|
-
action:
|
|
171
|
+
trigger: TRIGGER_DEFS,
|
|
172
|
+
action: ACTION_DEFS,
|
|
169
173
|
}
|
|
170
174
|
}
|
|
171
175
|
|
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
const { BuildSchemaErrors, InvalidColumns } = require("../../constants")
|
|
11
11
|
const { integrations } = require("../../integrations")
|
|
12
12
|
const { getDatasourceAndQuery } = require("./row/utils")
|
|
13
|
+
const { invalidateDynamicVariables } = require("../../threads/utils")
|
|
13
14
|
|
|
14
15
|
exports.fetch = async function (ctx) {
|
|
15
16
|
const database = new CouchDB(ctx.appId)
|
|
@@ -57,10 +58,43 @@ exports.buildSchemaFromDb = async function (ctx) {
|
|
|
57
58
|
ctx.body = response
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Check for variables that have been updated or removed and invalidate them.
|
|
63
|
+
*/
|
|
64
|
+
const invalidateVariables = async (existingDatasource, updatedDatasource) => {
|
|
65
|
+
const existingVariables = existingDatasource.config.dynamicVariables
|
|
66
|
+
const updatedVariables = updatedDatasource.config.dynamicVariables
|
|
67
|
+
const toInvalidate = []
|
|
68
|
+
|
|
69
|
+
if (!existingVariables) {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!updatedVariables) {
|
|
74
|
+
// invalidate all
|
|
75
|
+
toInvalidate.push(...existingVariables)
|
|
76
|
+
} else {
|
|
77
|
+
// invaldate changed / removed
|
|
78
|
+
existingVariables.forEach(existing => {
|
|
79
|
+
const unchanged = updatedVariables.find(
|
|
80
|
+
updated =>
|
|
81
|
+
existing.name === updated.name &&
|
|
82
|
+
existing.queryId === updated.queryId &&
|
|
83
|
+
existing.value === updated.value
|
|
84
|
+
)
|
|
85
|
+
if (!unchanged) {
|
|
86
|
+
toInvalidate.push(existing)
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
await invalidateDynamicVariables(toInvalidate)
|
|
91
|
+
}
|
|
92
|
+
|
|
60
93
|
exports.update = async function (ctx) {
|
|
61
94
|
const db = new CouchDB(ctx.appId)
|
|
62
95
|
const datasourceId = ctx.params.datasourceId
|
|
63
96
|
let datasource = await db.get(datasourceId)
|
|
97
|
+
await invalidateVariables(datasource, ctx.request.body)
|
|
64
98
|
datasource = { ...datasource, ...ctx.request.body }
|
|
65
99
|
|
|
66
100
|
const response = await db.put(datasource)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import CouchDB from "../../../../db"
|
|
2
|
+
import { queryValidation } from "../validation"
|
|
3
|
+
import { generateQueryID } from "../../../../db/utils"
|
|
4
|
+
import { ImportInfo, ImportSource } from "./sources/base"
|
|
5
|
+
import { OpenAPI2 } from "./sources/openapi2"
|
|
6
|
+
import { Query } from "./../../../../definitions/common"
|
|
7
|
+
import { Curl } from "./sources/curl"
|
|
8
|
+
interface ImportResult {
|
|
9
|
+
errorQueries: Query[]
|
|
10
|
+
queries: Query[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class RestImporter {
|
|
14
|
+
data: string
|
|
15
|
+
sources: ImportSource[]
|
|
16
|
+
source!: ImportSource
|
|
17
|
+
|
|
18
|
+
constructor(data: string) {
|
|
19
|
+
this.data = data
|
|
20
|
+
this.sources = [new OpenAPI2(), new Curl()]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
init = async () => {
|
|
24
|
+
for (let source of this.sources) {
|
|
25
|
+
if (await source.isSupported(this.data)) {
|
|
26
|
+
this.source = source
|
|
27
|
+
break
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getInfo = async (): Promise<ImportInfo> => {
|
|
33
|
+
return this.source.getInfo()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
importQueries = async (
|
|
37
|
+
appId: string,
|
|
38
|
+
datasourceId: string
|
|
39
|
+
): Promise<ImportResult> => {
|
|
40
|
+
// constuct the queries
|
|
41
|
+
let queries = await this.source.getQueries(datasourceId)
|
|
42
|
+
|
|
43
|
+
// validate queries
|
|
44
|
+
const errorQueries: Query[] = []
|
|
45
|
+
const schema = queryValidation()
|
|
46
|
+
queries = queries
|
|
47
|
+
.filter(query => {
|
|
48
|
+
const validation = schema.validate(query)
|
|
49
|
+
if (validation.error) {
|
|
50
|
+
errorQueries.push(query)
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
return true
|
|
54
|
+
})
|
|
55
|
+
.map(query => {
|
|
56
|
+
query._id = generateQueryID(query.datasourceId)
|
|
57
|
+
return query
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// persist queries
|
|
61
|
+
const db = new CouchDB(appId)
|
|
62
|
+
const response = await db.bulkDocs(queries)
|
|
63
|
+
|
|
64
|
+
// create index to seperate queries and errors
|
|
65
|
+
const queryIndex = queries.reduce((acc, query) => {
|
|
66
|
+
if (query._id) {
|
|
67
|
+
acc[query._id] = query
|
|
68
|
+
}
|
|
69
|
+
return acc
|
|
70
|
+
}, {} as { [key: string]: Query })
|
|
71
|
+
|
|
72
|
+
// check for failed writes
|
|
73
|
+
response.forEach((query: any) => {
|
|
74
|
+
if (!query.ok) {
|
|
75
|
+
errorQueries.push(queryIndex[query.id])
|
|
76
|
+
delete queryIndex[query.id]
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
errorQueries,
|
|
82
|
+
queries: Object.values(queryIndex),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Query, QueryParameter } from "../../../../../../definitions/datasource"
|
|
2
|
+
import { URL } from "url"
|
|
3
|
+
|
|
4
|
+
export interface ImportInfo {
|
|
5
|
+
name: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
enum MethodToVerb {
|
|
9
|
+
get = "read",
|
|
10
|
+
post = "create",
|
|
11
|
+
put = "update",
|
|
12
|
+
patch = "patch",
|
|
13
|
+
delete = "delete",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export abstract class ImportSource {
|
|
17
|
+
abstract isSupported(data: string): Promise<boolean>
|
|
18
|
+
abstract getInfo(): Promise<ImportInfo>
|
|
19
|
+
abstract getQueries(datasourceId: string): Promise<Query[]>
|
|
20
|
+
|
|
21
|
+
constructQuery = (
|
|
22
|
+
datasourceId: string,
|
|
23
|
+
name: string,
|
|
24
|
+
method: string,
|
|
25
|
+
path: string,
|
|
26
|
+
url: URL,
|
|
27
|
+
queryString: string,
|
|
28
|
+
headers: object = {},
|
|
29
|
+
parameters: QueryParameter[] = [],
|
|
30
|
+
body: object | undefined = undefined
|
|
31
|
+
): Query => {
|
|
32
|
+
const readable = true
|
|
33
|
+
const queryVerb = this.verbFromMethod(method)
|
|
34
|
+
const transformer = "return data"
|
|
35
|
+
const schema = {}
|
|
36
|
+
path = this.processPath(path)
|
|
37
|
+
path = `${url.origin}/${path}`
|
|
38
|
+
queryString = this.processQuery(queryString)
|
|
39
|
+
const requestBody = JSON.stringify(body, null, 2)
|
|
40
|
+
|
|
41
|
+
const query: Query = {
|
|
42
|
+
datasourceId,
|
|
43
|
+
name,
|
|
44
|
+
parameters,
|
|
45
|
+
fields: {
|
|
46
|
+
headers,
|
|
47
|
+
queryString,
|
|
48
|
+
path,
|
|
49
|
+
requestBody,
|
|
50
|
+
},
|
|
51
|
+
transformer,
|
|
52
|
+
schema,
|
|
53
|
+
readable,
|
|
54
|
+
queryVerb,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return query
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
verbFromMethod = (method: string) => {
|
|
61
|
+
const verb = (<any>MethodToVerb)[method]
|
|
62
|
+
if (!verb) {
|
|
63
|
+
throw new Error(`Unsupported method: ${method}`)
|
|
64
|
+
}
|
|
65
|
+
return verb
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
processPath = (path: string): string => {
|
|
69
|
+
if (path?.startsWith("/")) {
|
|
70
|
+
path = path.substring(1)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// add extra braces around params for binding
|
|
74
|
+
path = path.replace(/[{]/g, "{{")
|
|
75
|
+
path = path.replace(/[}]/g, "}}")
|
|
76
|
+
|
|
77
|
+
return path
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
processQuery = (queryString: string): string => {
|
|
81
|
+
if (queryString?.startsWith("?")) {
|
|
82
|
+
return queryString.substring(1)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return queryString
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ImportSource } from "."
|
|
2
|
+
import SwaggerParser from "@apidevtools/swagger-parser"
|
|
3
|
+
import { OpenAPI } from "openapi-types"
|
|
4
|
+
const yaml = require("js-yaml")
|
|
5
|
+
|
|
6
|
+
export abstract class OpenAPISource extends ImportSource {
|
|
7
|
+
parseData = async (data: string): Promise<OpenAPI.Document> => {
|
|
8
|
+
let json: OpenAPI.Document
|
|
9
|
+
try {
|
|
10
|
+
json = JSON.parse(data)
|
|
11
|
+
} catch (jsonErr) {
|
|
12
|
+
// couldn't parse json
|
|
13
|
+
// try to convert yaml -> json
|
|
14
|
+
try {
|
|
15
|
+
json = yaml.load(data)
|
|
16
|
+
} catch (yamlErr) {
|
|
17
|
+
// couldn't parse yaml
|
|
18
|
+
throw new Error("Could not parse JSON or YAML")
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return SwaggerParser.validate(json, {})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ImportSource, ImportInfo } from "./base"
|
|
2
|
+
import { Query } from "../../../../../definitions/common"
|
|
3
|
+
import { URL } from "url"
|
|
4
|
+
const curlconverter = require("curlconverter")
|
|
5
|
+
|
|
6
|
+
const parseCurl = (data: string): any => {
|
|
7
|
+
const curlJson = curlconverter.toJsonString(data)
|
|
8
|
+
return JSON.parse(curlJson)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The curl converter parses the request body into the key field of an object
|
|
13
|
+
* e.g. --d '{"key":"val"}' produces an object { "{"key":"val"}" : "" }
|
|
14
|
+
* This is not what we want, so we need to parse out the key from the object
|
|
15
|
+
*/
|
|
16
|
+
const parseBody = (curl: any) => {
|
|
17
|
+
if (curl.data) {
|
|
18
|
+
const keys = Object.keys(curl.data)
|
|
19
|
+
if (keys.length) {
|
|
20
|
+
let key = keys[0]
|
|
21
|
+
try {
|
|
22
|
+
// filter out the dollar syntax used by curl for shell support
|
|
23
|
+
if (key.startsWith("$")) {
|
|
24
|
+
key = key.substring(1)
|
|
25
|
+
}
|
|
26
|
+
return JSON.parse(key)
|
|
27
|
+
} catch (e) {
|
|
28
|
+
// do nothing
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const parseCookie = (curl: any) => {
|
|
36
|
+
if (curl.cookies) {
|
|
37
|
+
return Object.entries(curl.cookies).reduce((acc, entry) => {
|
|
38
|
+
const [key, value] = entry
|
|
39
|
+
return acc + `${key}=${value}; `
|
|
40
|
+
}, "")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Curl
|
|
48
|
+
* https://curl.se/docs/manpage.html
|
|
49
|
+
*/
|
|
50
|
+
export class Curl extends ImportSource {
|
|
51
|
+
curl: any
|
|
52
|
+
|
|
53
|
+
isSupported = async (data: string): Promise<boolean> => {
|
|
54
|
+
try {
|
|
55
|
+
const curl = parseCurl(data)
|
|
56
|
+
this.curl = curl
|
|
57
|
+
} catch (err) {
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
return true
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getUrl = (): URL => {
|
|
64
|
+
return new URL(this.curl.raw_url)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getInfo = async (): Promise<ImportInfo> => {
|
|
68
|
+
const url = this.getUrl()
|
|
69
|
+
return {
|
|
70
|
+
name: url.hostname,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getQueries = async (datasourceId: string): Promise<Query[]> => {
|
|
75
|
+
const url = this.getUrl()
|
|
76
|
+
const name = url.pathname
|
|
77
|
+
const path = url.pathname
|
|
78
|
+
const method = this.curl.method
|
|
79
|
+
const queryString = url.search
|
|
80
|
+
const headers = this.curl.headers
|
|
81
|
+
const requestBody = parseBody(this.curl)
|
|
82
|
+
|
|
83
|
+
const cookieHeader = parseCookie(this.curl)
|
|
84
|
+
if (cookieHeader) {
|
|
85
|
+
headers["Cookie"] = cookieHeader
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const query = this.constructQuery(
|
|
89
|
+
datasourceId,
|
|
90
|
+
name,
|
|
91
|
+
method,
|
|
92
|
+
path,
|
|
93
|
+
url,
|
|
94
|
+
queryString,
|
|
95
|
+
headers,
|
|
96
|
+
[],
|
|
97
|
+
requestBody
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return [query]
|
|
101
|
+
}
|
|
102
|
+
}
|