@budibase/server 0.9.172 → 0.9.173-alpha.3
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__/{mysql.ts → mysql2.ts} +0 -0
- package/builder/assets/{index.dbc6728e.css → index.7469e1e4.css} +2 -2
- package/builder/assets/{index.9ab01cd4.js → index.b38aa4d6.js} +34 -34
- package/builder/assets/{vendor.54435e8f.js → vendor.278a305c.js} +1 -1
- package/builder/index.html +3 -3
- package/coverage/clover.xml +973 -849
- package/coverage/coverage-final.json +47 -46
- package/coverage/lcov-report/api/controllers/analytics.js.html +21 -9
- package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
- package/coverage/lcov-report/api/controllers/application.js.html +186 -84
- package/coverage/lcov-report/api/controllers/auth.js.html +37 -10
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/backup.js.html +6 -9
- package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
- package/coverage/lcov-report/api/controllers/component.js.html +1 -1
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +41 -17
- package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
- package/coverage/lcov-report/api/controllers/index.html +71 -71
- 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 +7 -4
- package/coverage/lcov-report/api/controllers/query.js.html +129 -24
- 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 +5 -5
- package/coverage/lcov-report/api/controllers/row/index.js.html +15 -15
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/screen.js.html +9 -9
- package/coverage/lcov-report/api/controllers/script.js.html +12 -57
- package/coverage/lcov-report/api/controllers/table/index.html +28 -28
- package/coverage/lcov-report/api/controllers/table/index.js.html +16 -37
- package/coverage/lcov-report/api/controllers/table/utils.js.html +279 -33
- package/coverage/lcov-report/api/controllers/templates.js.html +49 -13
- package/coverage/lcov-report/api/controllers/user.js.html +3 -3
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +19 -19
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -8
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +54 -15
- package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +3 -3
- 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 +5 -2
- 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 +26 -11
- 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 +9 -3
- 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 +1 -1
- 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 +31 -10
- package/coverage/lcov-report/automations/automationUtils.js.html +14 -86
- package/coverage/lcov-report/automations/bullboard.js.html +1 -1
- package/coverage/lcov-report/automations/index.html +37 -37
- package/coverage/lcov-report/automations/index.js.html +1 -1
- package/coverage/lcov-report/automations/steps/bash.js.html +10 -7
- package/coverage/lcov-report/automations/steps/createRow.js.html +2 -2
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/deleteRow.js.html +8 -5
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +10 -7
- package/coverage/lcov-report/automations/steps/executeScript.js.html +10 -7
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +57 -57
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +10 -7
- package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -7
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +10 -7
- 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 +14 -14
- package/coverage/lcov-report/automations/steps/utils.js.html +10 -10
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/thread.js.html +54 -12
- 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 +28 -28
- package/coverage/lcov-report/constants/index.html +1 -1
- package/coverage/lcov-report/constants/index.js.html +5 -2
- 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 +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +12 -12
- package/coverage/lcov-report/db/linkedRows/index.html +18 -18
- package/coverage/lcov-report/db/linkedRows/index.js.html +47 -26
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +2 -2
- package/coverage/lcov-report/db/utils.js.html +17 -17
- 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 +107 -107
- 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 +2 -2
- package/coverage/lcov-report/middleware/builder.js.html +1 -1
- package/coverage/lcov-report/middleware/currentapp.js.html +52 -25
- package/coverage/lcov-report/middleware/index.html +15 -15
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
- 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 +27 -27
- package/coverage/lcov-report/utilities/index.html +32 -17
- package/coverage/lcov-report/utilities/index.js.html +4 -4
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +29 -8
- package/coverage/lcov-report/utilities/queue/index.html +15 -15
- 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 +14 -14
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +38 -8
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +143 -0
- package/coverage/lcov-report/utilities/security.js.html +1 -1
- 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 +1692 -1452
- package/dist/api/controllers/analytics.js +4 -0
- package/dist/api/controllers/application.js +185 -171
- package/dist/api/controllers/auth.js +12 -2
- package/dist/api/controllers/backup.js +4 -4
- package/dist/api/controllers/deploy/index.js +3 -16
- package/dist/api/controllers/dev.js +17 -11
- package/dist/api/controllers/permission.js +1 -0
- package/dist/api/controllers/query.js +26 -8
- package/dist/api/controllers/row/ExternalRequest.js +46 -5
- package/dist/api/controllers/script.js +4 -16
- package/dist/api/controllers/table/index.js +5 -10
- package/dist/api/controllers/table/utils.js +83 -10
- package/dist/api/controllers/templates.js +18 -3
- package/dist/api/controllers/view/viewBuilder.js +15 -1
- package/dist/api/routes/application.js +1 -0
- package/dist/api/routes/dev.js +8 -4
- package/dist/api/routes/query.js +3 -1
- package/dist/api/routes/tests/utilities/TestFunctions.js +7 -9
- package/dist/automations/actions.js +9 -3
- package/dist/automations/automationUtils.js +8 -29
- package/dist/automations/steps/bash.js +2 -1
- package/dist/automations/steps/createRow.js +1 -1
- package/dist/automations/steps/deleteRow.js +2 -1
- package/dist/automations/steps/executeQuery.js +2 -1
- package/dist/automations/steps/executeScript.js +2 -1
- package/dist/automations/steps/outgoingWebhook.js +2 -1
- package/dist/automations/steps/queryRows.js +2 -1
- package/dist/automations/steps/sendSmtpEmail.js +2 -1
- package/dist/automations/steps/updateRow.js +6 -2
- package/dist/automations/thread.js +14 -3
- package/dist/constants/index.js +1 -0
- package/dist/db/linkedRows/index.js +9 -6
- package/dist/integrations/base/sql.js +4 -4
- package/dist/integrations/mysql.js +1 -1
- package/dist/integrations/utils.js +17 -1
- package/dist/middleware/currentapp.js +8 -2
- package/dist/package.json +7 -6
- package/dist/tests/utilities/TestConfiguration.js +34 -19
- package/dist/tests/utilities/controllers.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/index.js +49 -33
- package/dist/utilities/global.js +1 -1
- package/dist/utilities/queue/inMemoryQueue.js +6 -0
- package/dist/utilities/rowProcessor/index.js +8 -0
- package/dist/utilities/scriptRunner.js +19 -0
- package/package.json +8 -7
- package/scripts/jestSetup.js +2 -0
- package/src/api/controllers/analytics.js +4 -0
- package/src/api/controllers/application.js +43 -9
- package/src/api/controllers/auth.js +12 -3
- package/src/api/controllers/backup.js +4 -5
- package/src/api/controllers/deploy/index.js +3 -18
- package/src/api/controllers/dev.js +16 -8
- package/src/api/controllers/permission.js +1 -0
- package/src/api/controllers/query.js +46 -11
- package/src/api/controllers/row/ExternalRequest.ts +53 -4
- package/src/api/controllers/script.js +4 -19
- package/src/api/controllers/table/index.js +5 -12
- package/src/api/controllers/table/utils.js +94 -12
- package/src/api/controllers/templates.js +17 -5
- package/src/api/controllers/view/tests/__snapshots__/viewBuilder.spec.js.snap +1 -1
- package/src/api/controllers/view/viewBuilder.js +14 -1
- package/src/api/routes/application.js +1 -0
- package/src/api/routes/dev.js +9 -4
- package/src/api/routes/query.js +3 -1
- package/src/api/routes/tests/auth.spec.js +1 -2
- package/src/api/routes/tests/permissions.spec.js +3 -0
- package/src/api/routes/tests/query.spec.js +2 -2
- package/src/api/routes/tests/routing.spec.js +24 -8
- package/src/api/routes/tests/user.spec.js +1 -1
- package/src/api/routes/tests/utilities/TestFunctions.js +7 -9
- package/src/api/routes/tests/webhook.spec.js +4 -1
- package/src/automations/actions.js +10 -3
- package/src/automations/automationUtils.js +7 -31
- package/src/automations/steps/bash.js +2 -1
- package/src/automations/steps/createRow.js +1 -1
- package/src/automations/steps/deleteRow.js +2 -1
- package/src/automations/steps/executeQuery.js +2 -1
- package/src/automations/steps/executeScript.js +2 -1
- package/src/automations/steps/outgoingWebhook.js +2 -1
- package/src/automations/steps/queryRows.js +2 -1
- package/src/automations/steps/sendSmtpEmail.js +2 -1
- package/src/automations/steps/updateRow.js +6 -6
- package/src/automations/thread.js +17 -3
- package/src/constants/index.js +1 -0
- package/src/db/linkedRows/index.js +14 -7
- package/src/integrations/base/sql.ts +11 -3
- package/src/integrations/mysql.ts +1 -1
- package/src/integrations/tests/mongo.spec.js +10 -6
- package/src/integrations/tests/mysql.spec.js +1 -1
- package/src/integrations/utils.ts +18 -0
- package/src/middleware/currentapp.js +11 -2
- package/src/middleware/tests/currentapp.spec.js +3 -3
- package/src/tests/utilities/TestConfiguration.js +47 -19
- package/src/tests/utilities/controllers.js +1 -0
- package/src/utilities/fileSystem/index.js +65 -43
- package/src/utilities/global.js +1 -1
- package/src/utilities/queue/inMemoryQueue.js +7 -0
- package/src/utilities/rowProcessor/index.js +10 -0
- package/src/utilities/scriptRunner.js +21 -0
|
@@ -98,53 +98,69 @@ exports.apiFileReturn = contents => {
|
|
|
98
98
|
fs.writeFileSync(path, contents);
|
|
99
99
|
return fs.createReadStream(path);
|
|
100
100
|
};
|
|
101
|
+
/**
|
|
102
|
+
* Local utility to back up the database state for an app, excluding global user
|
|
103
|
+
* data or user relationships.
|
|
104
|
+
* @param {string} appId The app to backup
|
|
105
|
+
* @param {object} config Config to send to export DB
|
|
106
|
+
* @returns {*} either a string or a stream of the backup
|
|
107
|
+
*/
|
|
108
|
+
const backupAppData = (appId, config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
+
return yield exports.exportDB(appId, Object.assign(Object.assign({}, config), { filter: doc => !(doc._id.includes(USER_METDATA_PREFIX) ||
|
|
110
|
+
doc._id.includes(LINK_USER_METADATA_PREFIX)) }));
|
|
111
|
+
});
|
|
101
112
|
/**
|
|
102
113
|
* Takes a copy of the database state for an app to the object store.
|
|
103
114
|
* @param {string} appId The ID of the app which is to be backed up.
|
|
104
115
|
* @param {string} backupName The name of the backup located in the object store.
|
|
105
|
-
* @return
|
|
106
|
-
* to the temporary backup file (to return via API if required).
|
|
116
|
+
* @return {*} a readable stream to the completed backup file
|
|
107
117
|
*/
|
|
108
118
|
exports.performBackup = (appId, backupName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
-
return
|
|
110
|
-
exportName: backupName,
|
|
111
|
-
filter: doc => !(doc._id.includes(USER_METDATA_PREFIX) ||
|
|
112
|
-
doc.includes(LINK_USER_METADATA_PREFIX)),
|
|
113
|
-
});
|
|
119
|
+
return yield backupAppData(appId, { exportName: backupName });
|
|
114
120
|
});
|
|
115
121
|
/**
|
|
116
|
-
*
|
|
122
|
+
* Streams a backup of the database state for an app
|
|
123
|
+
* @param {string} appId The ID of the app which is to be backed up.
|
|
124
|
+
* @returns {*} a readable stream of the backup which is written in real time
|
|
125
|
+
*/
|
|
126
|
+
exports.streamBackup = (appId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
+
return yield backupAppData(appId, { stream: true });
|
|
128
|
+
});
|
|
129
|
+
/**
|
|
130
|
+
* Exports a DB to either file or a variable (memory).
|
|
117
131
|
* @param {string} dbName the DB which is to be exported.
|
|
118
|
-
* @param {string} exportName optional -
|
|
132
|
+
* @param {string} exportName optional - provide a filename to write the backup to a file
|
|
133
|
+
* @param {boolean} stream optional - whether to perform a full backup
|
|
119
134
|
* @param {function} filter optional - a filter function to clear out any un-wanted docs.
|
|
120
|
-
* @return
|
|
135
|
+
* @return {*} either a readable stream or a string
|
|
121
136
|
*/
|
|
122
|
-
exports.exportDB = (dbName, {
|
|
123
|
-
let stream, appString = "", path = null;
|
|
124
|
-
if (exportName) {
|
|
125
|
-
path = join(budibaseTempDir(), exportName);
|
|
126
|
-
stream = fs.createWriteStream(path);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
stream = new MemoryStream();
|
|
130
|
-
stream.on("data", chunk => {
|
|
131
|
-
appString += chunk.toString();
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
// perform couch dump
|
|
137
|
+
exports.exportDB = (dbName, { stream, filter, exportName } = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
138
|
const instanceDb = new CouchDB(dbName);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return appString;
|
|
139
|
+
// Stream the dump if required
|
|
140
|
+
if (stream) {
|
|
141
|
+
const memStream = new MemoryStream();
|
|
142
|
+
instanceDb.dump(memStream, { filter });
|
|
143
|
+
return memStream;
|
|
142
144
|
}
|
|
143
|
-
//
|
|
144
|
-
if (
|
|
145
|
-
|
|
145
|
+
// Write the dump to file if required
|
|
146
|
+
if (exportName) {
|
|
147
|
+
const path = join(budibaseTempDir(), exportName);
|
|
148
|
+
const writeStream = fs.createWriteStream(path);
|
|
149
|
+
yield instanceDb.dump(writeStream, { filter });
|
|
150
|
+
// Upload the dump to the object store if self hosted
|
|
151
|
+
if (env.SELF_HOSTED) {
|
|
152
|
+
yield streamUpload(ObjectStoreBuckets.BACKUPS, join(dbName, exportName), fs.createReadStream(path));
|
|
153
|
+
}
|
|
154
|
+
return fs.createReadStream(path);
|
|
146
155
|
}
|
|
147
|
-
|
|
156
|
+
// Stringify the dump in memory if required
|
|
157
|
+
const memStream = new MemoryStream();
|
|
158
|
+
let appString = "";
|
|
159
|
+
memStream.on("data", chunk => {
|
|
160
|
+
appString += chunk.toString();
|
|
161
|
+
});
|
|
162
|
+
yield instanceDb.dump(memStream, { filter });
|
|
163
|
+
return appString;
|
|
148
164
|
});
|
|
149
165
|
/**
|
|
150
166
|
* Writes the provided contents to a temporary file, which can be used briefly.
|
package/dist/utilities/global.js
CHANGED
|
@@ -149,6 +149,10 @@ exports.processAutoColumn = processAutoColumn;
|
|
|
149
149
|
* @returns {object} The coerced value
|
|
150
150
|
*/
|
|
151
151
|
exports.coerce = (row, type) => {
|
|
152
|
+
// no coercion specified for type, skip it
|
|
153
|
+
if (!TYPE_TRANSFORM_MAP[type]) {
|
|
154
|
+
return row;
|
|
155
|
+
}
|
|
152
156
|
// eslint-disable-next-line no-prototype-builtins
|
|
153
157
|
if (TYPE_TRANSFORM_MAP[type].hasOwnProperty(row)) {
|
|
154
158
|
return TYPE_TRANSFORM_MAP[type][row];
|
|
@@ -190,6 +194,10 @@ exports.inputProcessing = (user = {}, table, row, opts = { noAutoRelationships:
|
|
|
190
194
|
clonedRow[key] = exports.coerce(value, field.type);
|
|
191
195
|
}
|
|
192
196
|
}
|
|
197
|
+
if (!clonedRow._id || !clonedRow._rev) {
|
|
198
|
+
clonedRow._id = row._id;
|
|
199
|
+
clonedRow._rev = row._rev;
|
|
200
|
+
}
|
|
193
201
|
// handle auto columns - this returns an object like {table, row}
|
|
194
202
|
return processAutoColumn(user, copiedTable, clonedRow, opts);
|
|
195
203
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const fetch = require("node-fetch");
|
|
3
|
+
const { VM, VMScript } = require("vm2");
|
|
4
|
+
class ScriptRunner {
|
|
5
|
+
constructor(script, context) {
|
|
6
|
+
const code = `let fn = () => {\n${script}\n}; results.out = fn();`;
|
|
7
|
+
this.vm = new VM();
|
|
8
|
+
this.results = { out: "" };
|
|
9
|
+
this.vm.setGlobals(context);
|
|
10
|
+
this.vm.setGlobal("fetch", fetch);
|
|
11
|
+
this.vm.setGlobal("results", this.results);
|
|
12
|
+
this.script = new VMScript(code);
|
|
13
|
+
}
|
|
14
|
+
execute() {
|
|
15
|
+
this.vm.run(this.script);
|
|
16
|
+
return this.results.out;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
module.exports = ScriptRunner;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.173-alpha.3",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
"author": "Budibase",
|
|
69
69
|
"license": "AGPL-3.0-or-later",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@budibase/auth": "^0.9.
|
|
72
|
-
"@budibase/client": "^0.9.
|
|
73
|
-
"@budibase/string-templates": "^0.9.
|
|
71
|
+
"@budibase/auth": "^0.9.173-alpha.3",
|
|
72
|
+
"@budibase/client": "^0.9.173-alpha.3",
|
|
73
|
+
"@budibase/string-templates": "^0.9.173-alpha.3",
|
|
74
74
|
"@elastic/elasticsearch": "7.10.0",
|
|
75
75
|
"@koa/router": "8.0.0",
|
|
76
76
|
"@sendgrid/mail": "7.1.1",
|
|
77
|
-
"@sentry/node": "
|
|
77
|
+
"@sentry/node": "^6.0.0",
|
|
78
78
|
"airtable": "0.10.1",
|
|
79
79
|
"arangojs": "7.2.0",
|
|
80
80
|
"aws-sdk": "^2.767.0",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"memorystream": "^0.3.1",
|
|
104
104
|
"mongodb": "3.6.3",
|
|
105
105
|
"mssql": "6.2.3",
|
|
106
|
-
"
|
|
106
|
+
"mysql2": "^2.3.1",
|
|
107
107
|
"node-fetch": "2.6.0",
|
|
108
108
|
"open": "7.3.0",
|
|
109
109
|
"pg": "8.5.1",
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
"to-json-schema": "0.2.5",
|
|
120
120
|
"uuid": "3.3.2",
|
|
121
121
|
"validate.js": "0.13.1",
|
|
122
|
+
"vm2": "^3.9.3",
|
|
122
123
|
"yargs": "13.2.4",
|
|
123
124
|
"zlib": "1.0.5"
|
|
124
125
|
},
|
|
@@ -148,5 +149,5 @@
|
|
|
148
149
|
"typescript": "^4.3.5",
|
|
149
150
|
"update-dotenv": "^1.1.1"
|
|
150
151
|
},
|
|
151
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "7bbd460f86bae19117a7a7ed48dc984aa6eb7826"
|
|
152
153
|
}
|
package/scripts/jestSetup.js
CHANGED
|
@@ -25,7 +25,12 @@ const { BASE_LAYOUTS } = require("../../constants/layouts")
|
|
|
25
25
|
const { createHomeScreen } = require("../../constants/screens")
|
|
26
26
|
const { cloneDeep } = require("lodash/fp")
|
|
27
27
|
const { processObject } = require("@budibase/string-templates")
|
|
28
|
-
const {
|
|
28
|
+
const {
|
|
29
|
+
getAllApps,
|
|
30
|
+
isDevAppID,
|
|
31
|
+
getDeployedAppID,
|
|
32
|
+
Replication,
|
|
33
|
+
} = require("@budibase/auth/db")
|
|
29
34
|
const { USERS_TABLE_SCHEMA } = require("../../constants")
|
|
30
35
|
const {
|
|
31
36
|
getDeployedApps,
|
|
@@ -134,7 +139,7 @@ async function createInstance(template) {
|
|
|
134
139
|
return { _id: appId }
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
exports.fetch = async
|
|
142
|
+
exports.fetch = async ctx => {
|
|
138
143
|
const dev = ctx.query && ctx.query.status === AppStatus.DEV
|
|
139
144
|
const all = ctx.query && ctx.query.status === AppStatus.ALL
|
|
140
145
|
const apps = await getAllApps(CouchDB, { dev, all })
|
|
@@ -159,7 +164,7 @@ exports.fetch = async function (ctx) {
|
|
|
159
164
|
ctx.body = apps
|
|
160
165
|
}
|
|
161
166
|
|
|
162
|
-
exports.fetchAppDefinition = async
|
|
167
|
+
exports.fetchAppDefinition = async ctx => {
|
|
163
168
|
const db = new CouchDB(ctx.params.appId)
|
|
164
169
|
const layouts = await getLayouts(db)
|
|
165
170
|
const userRoleId = getUserRoleId(ctx)
|
|
@@ -175,7 +180,7 @@ exports.fetchAppDefinition = async function (ctx) {
|
|
|
175
180
|
}
|
|
176
181
|
}
|
|
177
182
|
|
|
178
|
-
exports.fetchAppPackage = async
|
|
183
|
+
exports.fetchAppPackage = async ctx => {
|
|
179
184
|
const db = new CouchDB(ctx.params.appId)
|
|
180
185
|
const application = await db.get(DocumentTypes.APP_METADATA)
|
|
181
186
|
const layouts = await getLayouts(db)
|
|
@@ -196,7 +201,7 @@ exports.fetchAppPackage = async function (ctx) {
|
|
|
196
201
|
}
|
|
197
202
|
}
|
|
198
203
|
|
|
199
|
-
exports.create = async
|
|
204
|
+
exports.create = async ctx => {
|
|
200
205
|
const { useTemplate, templateKey, templateString } = ctx.request.body
|
|
201
206
|
const instanceConfig = {
|
|
202
207
|
useTemplate,
|
|
@@ -252,13 +257,13 @@ exports.create = async function (ctx) {
|
|
|
252
257
|
ctx.body = newApplication
|
|
253
258
|
}
|
|
254
259
|
|
|
255
|
-
exports.update = async
|
|
260
|
+
exports.update = async ctx => {
|
|
256
261
|
const data = await updateAppPackage(ctx, ctx.request.body, ctx.params.appId)
|
|
257
262
|
ctx.status = 200
|
|
258
263
|
ctx.body = data
|
|
259
264
|
}
|
|
260
265
|
|
|
261
|
-
exports.updateClient = async
|
|
266
|
+
exports.updateClient = async ctx => {
|
|
262
267
|
// Get current app version
|
|
263
268
|
const db = new CouchDB(ctx.params.appId)
|
|
264
269
|
const application = await db.get(DocumentTypes.APP_METADATA)
|
|
@@ -280,7 +285,7 @@ exports.updateClient = async function (ctx) {
|
|
|
280
285
|
ctx.body = data
|
|
281
286
|
}
|
|
282
287
|
|
|
283
|
-
exports.revertClient = async
|
|
288
|
+
exports.revertClient = async ctx => {
|
|
284
289
|
// Check app can be reverted
|
|
285
290
|
const db = new CouchDB(ctx.params.appId)
|
|
286
291
|
const application = await db.get(DocumentTypes.APP_METADATA)
|
|
@@ -303,7 +308,7 @@ exports.revertClient = async function (ctx) {
|
|
|
303
308
|
ctx.body = data
|
|
304
309
|
}
|
|
305
310
|
|
|
306
|
-
exports.delete = async
|
|
311
|
+
exports.delete = async ctx => {
|
|
307
312
|
const db = new CouchDB(ctx.params.appId)
|
|
308
313
|
|
|
309
314
|
const result = await db.destroy()
|
|
@@ -318,6 +323,35 @@ exports.delete = async function (ctx) {
|
|
|
318
323
|
ctx.body = result
|
|
319
324
|
}
|
|
320
325
|
|
|
326
|
+
exports.sync = async ctx => {
|
|
327
|
+
const appId = ctx.params.appId
|
|
328
|
+
if (!isDevAppID(appId)) {
|
|
329
|
+
ctx.throw(400, "This action cannot be performed for production apps")
|
|
330
|
+
}
|
|
331
|
+
const prodAppId = getDeployedAppID(appId)
|
|
332
|
+
const replication = new Replication({
|
|
333
|
+
source: prodAppId,
|
|
334
|
+
target: appId,
|
|
335
|
+
})
|
|
336
|
+
let error
|
|
337
|
+
try {
|
|
338
|
+
await replication.replicate({
|
|
339
|
+
filter: function (doc) {
|
|
340
|
+
return doc._id !== DocumentTypes.APP_METADATA
|
|
341
|
+
},
|
|
342
|
+
})
|
|
343
|
+
} catch (err) {
|
|
344
|
+
error = err
|
|
345
|
+
}
|
|
346
|
+
if (error) {
|
|
347
|
+
ctx.throw(400, error)
|
|
348
|
+
} else {
|
|
349
|
+
ctx.body = {
|
|
350
|
+
message: "App sync completed successfully.",
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
321
355
|
const updateAppPackage = async (ctx, appPackage, appId) => {
|
|
322
356
|
const url = await getAppUrlIfNotInUse(ctx)
|
|
323
357
|
const db = new CouchDB(appId)
|
|
@@ -28,14 +28,23 @@ exports.fetchSelf = async ctx => {
|
|
|
28
28
|
...metadata,
|
|
29
29
|
})
|
|
30
30
|
} catch (err) {
|
|
31
|
+
let response
|
|
31
32
|
// user didn't exist in app, don't pretend they do
|
|
32
33
|
if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) {
|
|
33
|
-
|
|
34
|
+
response = {}
|
|
34
35
|
}
|
|
35
36
|
// user has a role of some sort, return them
|
|
36
|
-
else {
|
|
37
|
-
|
|
37
|
+
else if (err.status === 404) {
|
|
38
|
+
const metadata = {
|
|
39
|
+
_id: userId,
|
|
40
|
+
}
|
|
41
|
+
const dbResp = await db.put(metadata)
|
|
42
|
+
user._rev = dbResp.rev
|
|
43
|
+
response = user
|
|
44
|
+
} else {
|
|
45
|
+
response = user
|
|
38
46
|
}
|
|
47
|
+
ctx.body = response
|
|
39
48
|
}
|
|
40
49
|
} else {
|
|
41
50
|
ctx.body = user
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { streamBackup } = require("../../utilities/fileSystem")
|
|
2
2
|
|
|
3
3
|
exports.exportAppDump = async function (ctx) {
|
|
4
4
|
const { appId } = ctx.query
|
|
5
|
-
const
|
|
6
|
-
const backupIdentifier = `${
|
|
7
|
-
|
|
5
|
+
const appName = decodeURI(ctx.query.appname)
|
|
6
|
+
const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt`
|
|
8
7
|
ctx.attachment(backupIdentifier)
|
|
9
|
-
ctx.body = await
|
|
8
|
+
ctx.body = await streamBackup(appId)
|
|
10
9
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const CouchDB = require("../../../db")
|
|
2
2
|
const Deployment = require("./Deployment")
|
|
3
|
-
const { Replication } = require("@budibase/auth/db")
|
|
3
|
+
const { Replication, getDeployedAppID } = require("@budibase/auth/db")
|
|
4
4
|
const { DocumentTypes, getAutomationParams } = require("../../../db/utils")
|
|
5
5
|
const {
|
|
6
6
|
disableAllCrons,
|
|
@@ -87,7 +87,7 @@ async function initDeployedApp(prodAppId) {
|
|
|
87
87
|
|
|
88
88
|
async function deployApp(deployment) {
|
|
89
89
|
try {
|
|
90
|
-
const productionAppId = deployment.appId
|
|
90
|
+
const productionAppId = getDeployedAppID(deployment.appId)
|
|
91
91
|
|
|
92
92
|
const replication = new Replication({
|
|
93
93
|
source: deployment.appId,
|
|
@@ -104,23 +104,8 @@ async function deployApp(deployment) {
|
|
|
104
104
|
appDoc.instance._id = productionAppId
|
|
105
105
|
await db.put(appDoc)
|
|
106
106
|
console.log("New app doc written successfully.")
|
|
107
|
-
|
|
108
|
-
console.log("Setting up live repl between dev and prod")
|
|
109
|
-
// Set up live sync between the live and dev instances
|
|
110
|
-
const liveReplication = new Replication({
|
|
111
|
-
source: productionAppId,
|
|
112
|
-
target: deployment.appId,
|
|
113
|
-
})
|
|
114
|
-
liveReplication.subscribe({
|
|
115
|
-
filter: function (doc) {
|
|
116
|
-
return doc._id !== DocumentTypes.APP_METADATA
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
console.log("Set up live repl between dev and prod")
|
|
120
|
-
|
|
121
|
-
console.log("Initialising deployed app")
|
|
122
107
|
await initDeployedApp(productionAppId)
|
|
123
|
-
console.log("
|
|
108
|
+
console.log("Deployed app initialised, setting deployment to successful")
|
|
124
109
|
deployment.setStatus(DeploymentStatus.SUCCESS)
|
|
125
110
|
await storeDeploymentHistory(deployment)
|
|
126
111
|
} catch (err) {
|
|
@@ -7,11 +7,13 @@ const { clearLock } = require("../../utilities/redis")
|
|
|
7
7
|
const { Replication } = require("@budibase/auth").db
|
|
8
8
|
const { DocumentTypes } = require("../../db/utils")
|
|
9
9
|
|
|
10
|
-
async function redirect(ctx, method) {
|
|
10
|
+
async function redirect(ctx, method, path = "global") {
|
|
11
11
|
const { devPath } = ctx.params
|
|
12
12
|
const queryString = ctx.originalUrl.split("?")[1] || ""
|
|
13
13
|
const response = await fetch(
|
|
14
|
-
checkSlashesInUrl(
|
|
14
|
+
checkSlashesInUrl(
|
|
15
|
+
`${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`
|
|
16
|
+
),
|
|
15
17
|
request(
|
|
16
18
|
ctx,
|
|
17
19
|
{
|
|
@@ -41,16 +43,22 @@ async function redirect(ctx, method) {
|
|
|
41
43
|
ctx.cookies
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
exports.
|
|
45
|
-
|
|
46
|
+
exports.buildRedirectGet = path => {
|
|
47
|
+
return async ctx => {
|
|
48
|
+
await redirect(ctx, "GET", path)
|
|
49
|
+
}
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
exports.
|
|
49
|
-
|
|
52
|
+
exports.buildRedirectPost = path => {
|
|
53
|
+
return async ctx => {
|
|
54
|
+
await redirect(ctx, "POST", path)
|
|
55
|
+
}
|
|
50
56
|
}
|
|
51
57
|
|
|
52
|
-
exports.
|
|
53
|
-
|
|
58
|
+
exports.buildRedirectDelete = path => {
|
|
59
|
+
return async ctx => {
|
|
60
|
+
await redirect(ctx, "DELETE", path)
|
|
61
|
+
}
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
exports.clearLock = async ctx => {
|
|
@@ -4,6 +4,7 @@ const { generateQueryID, getQueryParams } = require("../../db/utils")
|
|
|
4
4
|
const { integrations } = require("../../integrations")
|
|
5
5
|
const { BaseQueryVerbs } = require("../../constants")
|
|
6
6
|
const env = require("../../environment")
|
|
7
|
+
const ScriptRunner = require("../../utilities/scriptRunner")
|
|
7
8
|
|
|
8
9
|
// simple function to append "readable" to all read queries
|
|
9
10
|
function enrichQueries(input) {
|
|
@@ -28,12 +29,39 @@ function formatResponse(resp) {
|
|
|
28
29
|
resp = { response: resp }
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
if (!Array.isArray(resp)) {
|
|
32
|
-
resp = [resp]
|
|
33
|
-
}
|
|
34
32
|
return resp
|
|
35
33
|
}
|
|
36
34
|
|
|
35
|
+
async function runAndTransform(
|
|
36
|
+
integration,
|
|
37
|
+
queryVerb,
|
|
38
|
+
enrichedQuery,
|
|
39
|
+
transformer
|
|
40
|
+
) {
|
|
41
|
+
let rows = formatResponse(await integration[queryVerb](enrichedQuery))
|
|
42
|
+
|
|
43
|
+
// transform as required
|
|
44
|
+
if (transformer) {
|
|
45
|
+
const runner = new ScriptRunner(transformer, { data: rows })
|
|
46
|
+
rows = runner.execute()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// needs to an array for next step
|
|
50
|
+
if (!Array.isArray(rows)) {
|
|
51
|
+
rows = [rows]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// map into JSON if just raw primitive here
|
|
55
|
+
if (rows.find(row => typeof row !== "object")) {
|
|
56
|
+
rows = rows.map(value => ({ value }))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// get all the potential fields in the schema
|
|
60
|
+
let keys = rows.flatMap(Object.keys)
|
|
61
|
+
|
|
62
|
+
return { rows, keys }
|
|
63
|
+
}
|
|
64
|
+
|
|
37
65
|
exports.fetch = async function (ctx) {
|
|
38
66
|
const db = new CouchDB(ctx.appId)
|
|
39
67
|
|
|
@@ -122,15 +150,16 @@ exports.preview = async function (ctx) {
|
|
|
122
150
|
ctx.throw(400, "Integration type does not exist.")
|
|
123
151
|
}
|
|
124
152
|
|
|
125
|
-
const { fields, parameters, queryVerb } = ctx.request.body
|
|
126
|
-
|
|
153
|
+
const { fields, parameters, queryVerb, transformer } = ctx.request.body
|
|
127
154
|
const enrichedQuery = await enrichQueryFields(fields, parameters)
|
|
128
|
-
|
|
129
155
|
const integration = new Integration(datasource.config)
|
|
130
|
-
const rows = formatResponse(await integration[queryVerb](enrichedQuery))
|
|
131
156
|
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
const { rows, keys } = await runAndTransform(
|
|
158
|
+
integration,
|
|
159
|
+
queryVerb,
|
|
160
|
+
enrichedQuery,
|
|
161
|
+
transformer
|
|
162
|
+
)
|
|
134
163
|
|
|
135
164
|
ctx.body = {
|
|
136
165
|
rows,
|
|
@@ -158,10 +187,16 @@ exports.execute = async function (ctx) {
|
|
|
158
187
|
query.fields,
|
|
159
188
|
ctx.request.body.parameters
|
|
160
189
|
)
|
|
161
|
-
|
|
162
190
|
const integration = new Integration(datasource.config)
|
|
191
|
+
|
|
163
192
|
// call the relevant CRUD method on the integration class
|
|
164
|
-
|
|
193
|
+
const { rows } = await runAndTransform(
|
|
194
|
+
integration,
|
|
195
|
+
query.queryVerb,
|
|
196
|
+
enrichedQuery,
|
|
197
|
+
query.transformer
|
|
198
|
+
)
|
|
199
|
+
ctx.body = rows
|
|
165
200
|
// cleanup
|
|
166
201
|
if (integration.end) {
|
|
167
202
|
integration.end()
|