@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
|
@@ -56,7 +56,7 @@ function parse(csvString, parsers) {
|
|
|
56
56
|
});
|
|
57
57
|
result.subscribe(row => {
|
|
58
58
|
// For each CSV row parse all the columns that need parsed
|
|
59
|
-
for (let key
|
|
59
|
+
for (let key of Object.keys(parsers)) {
|
|
60
60
|
if (!schema[key] || schema[key].success) {
|
|
61
61
|
// get the validator for the column type
|
|
62
62
|
const validator = VALIDATORS[parsers[key].type];
|
|
@@ -79,15 +79,55 @@ function parse(csvString, parsers) {
|
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
-
function
|
|
82
|
+
function updateSchema({ schema, existingTable }) {
|
|
83
|
+
if (!schema) {
|
|
84
|
+
return schema;
|
|
85
|
+
}
|
|
86
|
+
const finalSchema = {};
|
|
87
|
+
const schemaKeyMap = {};
|
|
88
|
+
Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key));
|
|
89
|
+
for (let [key, field] of Object.entries(existingTable.schema)) {
|
|
90
|
+
const lcKey = key.toLowerCase();
|
|
91
|
+
const foundKey = schemaKeyMap[lcKey];
|
|
92
|
+
if (foundKey) {
|
|
93
|
+
finalSchema[key] = schema[foundKey];
|
|
94
|
+
finalSchema[key].type = field.type;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return finalSchema;
|
|
98
|
+
}
|
|
99
|
+
function transform({ schema, csvString, existingTable }) {
|
|
83
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
101
|
const colParser = {};
|
|
85
|
-
|
|
102
|
+
// make sure the table has all the columns required for import
|
|
103
|
+
if (existingTable) {
|
|
104
|
+
schema = updateSchema({ schema, existingTable });
|
|
105
|
+
}
|
|
106
|
+
for (let key of Object.keys(schema)) {
|
|
86
107
|
colParser[key] = PARSERS[schema[key].type] || schema[key].type;
|
|
87
108
|
}
|
|
88
109
|
try {
|
|
89
|
-
const
|
|
90
|
-
|
|
110
|
+
const data = yield csv({ colParser }).fromString(csvString);
|
|
111
|
+
const schemaKeyMap = {};
|
|
112
|
+
Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key));
|
|
113
|
+
for (let element of data) {
|
|
114
|
+
if (!data) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
for (let key of Object.keys(element)) {
|
|
118
|
+
const mappedKey = schemaKeyMap[key.toLowerCase()];
|
|
119
|
+
// isn't a column in the table, remove it
|
|
120
|
+
if (mappedKey == null) {
|
|
121
|
+
delete element[key];
|
|
122
|
+
}
|
|
123
|
+
// casing is different, fix it in row
|
|
124
|
+
else if (key !== mappedKey) {
|
|
125
|
+
element[mappedKey] = element[key];
|
|
126
|
+
delete element[key];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return data;
|
|
91
131
|
}
|
|
92
132
|
catch (err) {
|
|
93
133
|
console.error(`Error transforming CSV to JSON for data import`, err);
|
|
@@ -98,4 +138,5 @@ function transform({ schema, csvString }) {
|
|
|
98
138
|
module.exports = {
|
|
99
139
|
parse,
|
|
100
140
|
transform,
|
|
141
|
+
updateSchema,
|
|
101
142
|
};
|
package/dist/utilities/global.js
CHANGED
|
@@ -50,9 +50,12 @@ exports.getCachedSelf = (ctx, appId) => __awaiter(void 0, void 0, void 0, functi
|
|
|
50
50
|
const user = yield userCache.getUser(ctx.user._id);
|
|
51
51
|
return processUser(appId, user);
|
|
52
52
|
});
|
|
53
|
-
exports.
|
|
53
|
+
exports.getRawGlobalUser = (userId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
54
|
const db = getGlobalDB();
|
|
55
|
-
|
|
55
|
+
return db.get(getGlobalIDFromUserMetadataID(userId));
|
|
56
|
+
});
|
|
57
|
+
exports.getGlobalUser = (appId, userId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
58
|
+
let user = yield exports.getRawGlobalUser(userId);
|
|
56
59
|
return processUser(appId, user);
|
|
57
60
|
});
|
|
58
61
|
exports.getGlobalUsers = (appId = null, users = null) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -71,6 +74,7 @@ exports.getGlobalUsers = (appId = null, users = null) => __awaiter(void 0, void
|
|
|
71
74
|
.filter(user => user != null)
|
|
72
75
|
.map(user => {
|
|
73
76
|
delete user.password;
|
|
77
|
+
delete user.forceResetPassword;
|
|
74
78
|
return user;
|
|
75
79
|
});
|
|
76
80
|
if (!appId) {
|
package/dist/utilities/index.js
CHANGED
|
@@ -52,12 +52,18 @@ exports.objectStoreUrl = () => {
|
|
|
52
52
|
* via a specific endpoint (under /api/assets/client).
|
|
53
53
|
* @param {string} appId In production we need the appId to look up the correct bucket, as the
|
|
54
54
|
* version of the client lib may differ between apps.
|
|
55
|
+
* @param {string} version The version to retrieve.
|
|
55
56
|
* @return {string} The URL to be inserted into appPackage response or server rendered
|
|
56
57
|
* app index file.
|
|
57
58
|
*/
|
|
58
|
-
exports.clientLibraryPath = appId => {
|
|
59
|
+
exports.clientLibraryPath = (appId, version) => {
|
|
59
60
|
if (env.isProd()) {
|
|
60
|
-
|
|
61
|
+
let url = `${exports.objectStoreUrl()}/${sanitizeKey(appId)}/budibase-client.js`;
|
|
62
|
+
// append app version to bust the cache
|
|
63
|
+
if (version) {
|
|
64
|
+
url += `?v=${version}`;
|
|
65
|
+
}
|
|
66
|
+
return url;
|
|
61
67
|
}
|
|
62
68
|
else {
|
|
63
69
|
return `/api/assets/client`;
|
|
@@ -126,3 +132,13 @@ exports.stringToReadStream = string => {
|
|
|
126
132
|
},
|
|
127
133
|
});
|
|
128
134
|
};
|
|
135
|
+
exports.doesDatabaseExist = (dbName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
|
+
try {
|
|
137
|
+
const db = new CouchDB(dbName, { skip_setup: true });
|
|
138
|
+
const info = yield db.info();
|
|
139
|
+
return info && !info.error;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const fetch = require("node-fetch");
|
|
3
3
|
const { VM, VMScript } = require("vm2");
|
|
4
|
+
const JS_TIMEOUT_MS = 1000;
|
|
4
5
|
class ScriptRunner {
|
|
5
6
|
constructor(script, context) {
|
|
6
7
|
const code = `let fn = () => {\n${script}\n}; results.out = fn();`;
|
|
7
|
-
this.vm = new VM(
|
|
8
|
+
this.vm = new VM({
|
|
9
|
+
timeout: JS_TIMEOUT_MS,
|
|
10
|
+
});
|
|
8
11
|
this.results = { out: "" };
|
|
9
12
|
this.vm.setGlobals(context);
|
|
10
13
|
this.vm.setGlobal("fetch", fetch);
|
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.185-alpha.11",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -68,9 +68,11 @@
|
|
|
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.185-alpha.11",
|
|
72
|
+
"@budibase/client": "^0.9.185-alpha.11",
|
|
73
|
+
"@budibase/string-templates": "^0.9.185-alpha.11",
|
|
74
|
+
"@bull-board/api": "^3.7.0",
|
|
75
|
+
"@bull-board/koa": "^3.7.0",
|
|
74
76
|
"@elastic/elasticsearch": "7.10.0",
|
|
75
77
|
"@koa/router": "8.0.0",
|
|
76
78
|
"@sendgrid/mail": "7.1.1",
|
|
@@ -80,7 +82,6 @@
|
|
|
80
82
|
"aws-sdk": "^2.767.0",
|
|
81
83
|
"bcryptjs": "2.4.3",
|
|
82
84
|
"bull": "^3.22.4",
|
|
83
|
-
"bull-board": "^2.0.1",
|
|
84
85
|
"chmodr": "1.2.0",
|
|
85
86
|
"csvtojson": "2.0.10",
|
|
86
87
|
"dotenv": "8.2.0",
|
|
@@ -120,6 +121,7 @@
|
|
|
120
121
|
"uuid": "3.3.2",
|
|
121
122
|
"validate.js": "0.13.1",
|
|
122
123
|
"vm2": "^3.9.3",
|
|
124
|
+
"worker-farm": "^1.7.0",
|
|
123
125
|
"yargs": "13.2.4",
|
|
124
126
|
"zlib": "1.0.5"
|
|
125
127
|
},
|
|
@@ -138,7 +140,6 @@
|
|
|
138
140
|
"copyfiles": "^2.4.1",
|
|
139
141
|
"docker-compose": "^0.23.6",
|
|
140
142
|
"eslint": "^6.8.0",
|
|
141
|
-
"express": "^4.17.1",
|
|
142
143
|
"jest": "^27.0.5",
|
|
143
144
|
"nodemon": "^2.0.4",
|
|
144
145
|
"prettier": "^2.3.1",
|
|
@@ -149,5 +150,5 @@
|
|
|
149
150
|
"typescript": "^4.3.5",
|
|
150
151
|
"update-dotenv": "^1.1.1"
|
|
151
152
|
},
|
|
152
|
-
"gitHead": "
|
|
153
|
+
"gitHead": "d6018c2c9cb114e5daa8e9e12f5ccc461e0f6f0b"
|
|
153
154
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
if [ "$1" = '/opt/mssql/bin/sqlservr' ]; then
|
|
5
|
+
# If this is the container's first run, initialize the application database
|
|
6
|
+
if [ ! -f /tmp/app-initialized ]; then
|
|
7
|
+
# Initialize the application database asynchronously in a background process. This allows a) the SQL Server process to be the main process in the container, which allows graceful shutdown and other goodies, and b) us to only start the SQL Server process once, as opposed to starting, stopping, then starting it again.
|
|
8
|
+
function initialize_app_database() {
|
|
9
|
+
# Wait a bit for SQL Server to start. SQL Server's process doesn't provide a clever way to check if it's up or not, and it needs to be up before we can import the application database
|
|
10
|
+
sleep 30s
|
|
11
|
+
|
|
12
|
+
echo "RUNNING BUDIBASE SETUP"
|
|
13
|
+
|
|
14
|
+
#run the setup script to create the DB and the schema in the DB
|
|
15
|
+
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -i setup.sql
|
|
16
|
+
|
|
17
|
+
# Note that the container has been initialized so future starts won't wipe changes to the data
|
|
18
|
+
touch /tmp/app-initialized
|
|
19
|
+
}
|
|
20
|
+
initialize_app_database &
|
|
21
|
+
fi
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
exec "$@"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
USE master;
|
|
2
|
+
|
|
3
|
+
IF OBJECT_ID ('dbo.products', 'U') IS NOT NULL
|
|
4
|
+
DROP TABLE products;
|
|
5
|
+
GO
|
|
6
|
+
CREATE TABLE products
|
|
7
|
+
(
|
|
8
|
+
id int IDENTITY(1,1),
|
|
9
|
+
name varchar (20),
|
|
10
|
+
description varchar(30),
|
|
11
|
+
CONSTRAINT pk_products PRIMARY KEY NONCLUSTERED (id)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
IF OBJECT_ID ('dbo.tasks', 'U') IS NOT NULL
|
|
15
|
+
DROP TABLE tasks;
|
|
16
|
+
GO
|
|
17
|
+
CREATE TABLE tasks
|
|
18
|
+
(
|
|
19
|
+
taskid int IDENTITY(1,1),
|
|
20
|
+
taskname varchar (20),
|
|
21
|
+
productid int,
|
|
22
|
+
CONSTRAINT pk_tasks PRIMARY KEY NONCLUSTERED (taskid),
|
|
23
|
+
CONSTRAINT fk_products FOREIGN KEY (productid) REFERENCES products (id),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
IF OBJECT_ID ('dbo.people', 'U') IS NOT NULL
|
|
27
|
+
DROP TABLE people;
|
|
28
|
+
GO
|
|
29
|
+
CREATE TABLE people
|
|
30
|
+
(
|
|
31
|
+
name varchar(30),
|
|
32
|
+
age varchar(20),
|
|
33
|
+
CONSTRAINT pk_people PRIMARY KEY NONCLUSTERED (name, age)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
INSERT products
|
|
37
|
+
(name, description)
|
|
38
|
+
VALUES
|
|
39
|
+
('Bananas', 'Fruit thing');
|
|
40
|
+
|
|
41
|
+
INSERT products
|
|
42
|
+
(name, description)
|
|
43
|
+
VALUES
|
|
44
|
+
('Meat', 'Animal thing');
|
|
45
|
+
|
|
46
|
+
INSERT tasks
|
|
47
|
+
(taskname, productid)
|
|
48
|
+
VALUES
|
|
49
|
+
('Processing', 1);
|
|
50
|
+
|
|
51
|
+
INSERT people
|
|
52
|
+
(name, age)
|
|
53
|
+
VALUES
|
|
54
|
+
('Bob', '30');
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/******************************************************
|
|
2
|
+
* This script just makes it easy to re-create *
|
|
3
|
+
* a cypress like environment for testing the backend *
|
|
4
|
+
******************************************************/
|
|
5
|
+
const path = require("path")
|
|
6
|
+
const tmpdir = path.join(require("os").tmpdir(), ".budibase")
|
|
7
|
+
|
|
8
|
+
const MAIN_PORT = "10001"
|
|
9
|
+
const WORKER_PORT = "10002"
|
|
10
|
+
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
process.env.PORT = MAIN_PORT
|
|
13
|
+
process.env.BUDIBASE_API_KEY = "6BE826CB-6B30-4AEC-8777-2E90464633DE"
|
|
14
|
+
process.env.NODE_ENV = "cypress"
|
|
15
|
+
process.env.ENABLE_ANALYTICS = "false"
|
|
16
|
+
process.env.JWT_SECRET = "budibase"
|
|
17
|
+
process.env.COUCH_URL = `leveldb://${tmpdir}/.data/`
|
|
18
|
+
process.env.SELF_HOSTED = "1"
|
|
19
|
+
process.env.WORKER_URL = `http://localhost:${WORKER_PORT}/`
|
|
20
|
+
process.env.MINIO_URL = `http://localhost:${MAIN_PORT}/`
|
|
21
|
+
process.env.MINIO_ACCESS_KEY = "budibase"
|
|
22
|
+
process.env.MINIO_SECRET_KEY = "budibase"
|
|
23
|
+
process.env.COUCH_DB_USER = "budibase"
|
|
24
|
+
process.env.COUCH_DB_PASSWORD = "budibase"
|
|
25
|
+
process.env.INTERNAL_API_KEY = "budibase"
|
|
26
|
+
process.env.ALLOW_DEV_AUTOMATIONS = "1"
|
|
27
|
+
|
|
28
|
+
// don't make this a variable or top level require
|
|
29
|
+
// it will cause environment module to be loaded prematurely
|
|
30
|
+
const server = require("../src/app")
|
|
31
|
+
process.env.PORT = WORKER_PORT
|
|
32
|
+
const worker = require("../../worker/src/index")
|
|
33
|
+
process.env.PORT = MAIN_PORT
|
|
@@ -44,6 +44,9 @@ const {
|
|
|
44
44
|
revertClientLibrary,
|
|
45
45
|
} = require("../../utilities/fileSystem/clientLibrary")
|
|
46
46
|
const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy")
|
|
47
|
+
const { syncGlobalUsers } = require("./user")
|
|
48
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
49
|
+
const { cleanupAutomations } = require("../../automations/utils")
|
|
47
50
|
|
|
48
51
|
const URL_REGEX_SLASH = /\/|\\/g
|
|
49
52
|
|
|
@@ -197,7 +200,7 @@ exports.fetchAppPackage = async ctx => {
|
|
|
197
200
|
application,
|
|
198
201
|
screens,
|
|
199
202
|
layouts,
|
|
200
|
-
clientLibPath: clientLibraryPath(ctx.params.appId),
|
|
203
|
+
clientLibPath: clientLibraryPath(ctx.params.appId, application.version),
|
|
201
204
|
}
|
|
202
205
|
}
|
|
203
206
|
|
|
@@ -253,6 +256,7 @@ exports.create = async ctx => {
|
|
|
253
256
|
await createApp(appId)
|
|
254
257
|
}
|
|
255
258
|
|
|
259
|
+
await appCache.invalidateAppMetadata(appId, newApplication)
|
|
256
260
|
ctx.status = 200
|
|
257
261
|
ctx.body = newApplication
|
|
258
262
|
}
|
|
@@ -316,8 +320,12 @@ exports.delete = async ctx => {
|
|
|
316
320
|
if (!env.isTest() && !ctx.query.unpublish) {
|
|
317
321
|
await deleteApp(ctx.params.appId)
|
|
318
322
|
}
|
|
323
|
+
if (ctx.query && ctx.query.unpublish) {
|
|
324
|
+
await cleanupAutomations(ctx.params.appId)
|
|
325
|
+
}
|
|
319
326
|
// make sure the app/role doesn't stick around after the app has been deleted
|
|
320
327
|
await removeAppFromUserRoles(ctx, ctx.params.appId)
|
|
328
|
+
await appCache.invalidateAppMetadata(ctx.params.appId)
|
|
321
329
|
|
|
322
330
|
ctx.status = 200
|
|
323
331
|
ctx.body = result
|
|
@@ -328,6 +336,8 @@ exports.sync = async (ctx, next) => {
|
|
|
328
336
|
if (!isDevAppID(appId)) {
|
|
329
337
|
ctx.throw(400, "This action cannot be performed for production apps")
|
|
330
338
|
}
|
|
339
|
+
|
|
340
|
+
// replicate prod to dev
|
|
331
341
|
const prodAppId = getDeployedAppID(appId)
|
|
332
342
|
|
|
333
343
|
try {
|
|
@@ -357,6 +367,10 @@ exports.sync = async (ctx, next) => {
|
|
|
357
367
|
} catch (err) {
|
|
358
368
|
error = err
|
|
359
369
|
}
|
|
370
|
+
|
|
371
|
+
// sync the users
|
|
372
|
+
await syncGlobalUsers(appId)
|
|
373
|
+
|
|
360
374
|
if (error) {
|
|
361
375
|
ctx.throw(400, error)
|
|
362
376
|
} else {
|
|
@@ -380,7 +394,10 @@ const updateAppPackage = async (ctx, appPackage, appId) => {
|
|
|
380
394
|
// Redis, shouldn't ever store it
|
|
381
395
|
delete newAppPackage.lockedBy
|
|
382
396
|
|
|
383
|
-
|
|
397
|
+
const response = await db.put(newAppPackage)
|
|
398
|
+
// remove any cached metadata, so that it will be updated
|
|
399
|
+
await appCache.invalidateAppMetadata(appId)
|
|
400
|
+
return response
|
|
384
401
|
}
|
|
385
402
|
|
|
386
403
|
const createEmptyAppPackage = async (ctx, app) => {
|
|
@@ -14,6 +14,8 @@ exports.fetchSelf = async ctx => {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const user = await getFullUser(ctx, userId)
|
|
17
|
+
// this shouldn't be returned by the app self
|
|
18
|
+
delete user.roles
|
|
17
19
|
|
|
18
20
|
if (appId) {
|
|
19
21
|
const db = new CouchDB(appId)
|
|
@@ -36,6 +38,7 @@ exports.fetchSelf = async ctx => {
|
|
|
36
38
|
// user has a role of some sort, return them
|
|
37
39
|
else if (err.status === 404) {
|
|
38
40
|
const metadata = {
|
|
41
|
+
...user,
|
|
39
42
|
_id: userId,
|
|
40
43
|
}
|
|
41
44
|
const dbResp = await db.put(metadata)
|
|
@@ -7,8 +7,9 @@ const {
|
|
|
7
7
|
BudibaseInternalDB,
|
|
8
8
|
getTableParams,
|
|
9
9
|
} = require("../../db/utils")
|
|
10
|
+
const { BuildSchemaErrors } = require("../../constants")
|
|
10
11
|
const { integrations } = require("../../integrations")
|
|
11
|
-
const {
|
|
12
|
+
const { getDatasourceAndQuery } = require("./row/utils")
|
|
12
13
|
|
|
13
14
|
exports.fetch = async function (ctx) {
|
|
14
15
|
const database = new CouchDB(ctx.appId)
|
|
@@ -43,13 +44,17 @@ exports.buildSchemaFromDb = async function (ctx) {
|
|
|
43
44
|
const db = new CouchDB(ctx.appId)
|
|
44
45
|
const datasource = await db.get(ctx.params.datasourceId)
|
|
45
46
|
|
|
46
|
-
const tables = await buildSchemaHelper(datasource)
|
|
47
|
+
const { tables, error } = await buildSchemaHelper(datasource)
|
|
47
48
|
datasource.entities = tables
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
-
datasource._rev =
|
|
50
|
+
const dbResp = await db.put(datasource)
|
|
51
|
+
datasource._rev = dbResp.rev
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
const response = { datasource }
|
|
54
|
+
if (error) {
|
|
55
|
+
response.error = error
|
|
56
|
+
}
|
|
57
|
+
ctx.body = response
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
exports.update = async function (ctx) {
|
|
@@ -71,7 +76,7 @@ exports.update = async function (ctx) {
|
|
|
71
76
|
|
|
72
77
|
ctx.status = 200
|
|
73
78
|
ctx.message = "Datasource saved successfully."
|
|
74
|
-
ctx.body = datasource
|
|
79
|
+
ctx.body = { datasource }
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
exports.save = async function (ctx) {
|
|
@@ -85,13 +90,15 @@ exports.save = async function (ctx) {
|
|
|
85
90
|
...ctx.request.body.datasource,
|
|
86
91
|
}
|
|
87
92
|
|
|
93
|
+
let schemaError = null
|
|
88
94
|
if (fetchSchema) {
|
|
89
|
-
|
|
95
|
+
const { tables, error } = await buildSchemaHelper(datasource)
|
|
96
|
+
schemaError = error
|
|
90
97
|
datasource.entities = tables
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
const
|
|
94
|
-
datasource._rev =
|
|
100
|
+
const dbResp = await db.put(datasource)
|
|
101
|
+
datasource._rev = dbResp.rev
|
|
95
102
|
|
|
96
103
|
// Drain connection pools when configuration is changed
|
|
97
104
|
if (datasource.source) {
|
|
@@ -101,17 +108,27 @@ exports.save = async function (ctx) {
|
|
|
101
108
|
}
|
|
102
109
|
}
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
const response = { datasource }
|
|
112
|
+
if (schemaError) {
|
|
113
|
+
response.error = schemaError
|
|
114
|
+
}
|
|
115
|
+
ctx.body = response
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
exports.destroy = async function (ctx) {
|
|
110
119
|
const db = new CouchDB(ctx.appId)
|
|
111
120
|
|
|
112
121
|
// Delete all queries for the datasource
|
|
113
|
-
const
|
|
114
|
-
|
|
122
|
+
const queries = await db.allDocs(
|
|
123
|
+
getQueryParams(ctx.params.datasourceId, null)
|
|
124
|
+
)
|
|
125
|
+
await db.bulkDocs(
|
|
126
|
+
queries.rows.map(row => ({
|
|
127
|
+
_id: row.id,
|
|
128
|
+
_rev: row.value.rev,
|
|
129
|
+
_deleted: true,
|
|
130
|
+
}))
|
|
131
|
+
)
|
|
115
132
|
|
|
116
133
|
// delete the datasource
|
|
117
134
|
await db.remove(ctx.params.datasourceId, ctx.params.revId)
|
|
@@ -129,7 +146,7 @@ exports.find = async function (ctx) {
|
|
|
129
146
|
exports.query = async function (ctx) {
|
|
130
147
|
const queryJson = ctx.request.body
|
|
131
148
|
try {
|
|
132
|
-
ctx.body = await
|
|
149
|
+
ctx.body = await getDatasourceAndQuery(ctx.appId, queryJson)
|
|
133
150
|
} catch (err) {
|
|
134
151
|
ctx.throw(400, err)
|
|
135
152
|
}
|
|
@@ -143,5 +160,28 @@ const buildSchemaHelper = async datasource => {
|
|
|
143
160
|
await connector.buildSchema(datasource._id, datasource.entities)
|
|
144
161
|
datasource.entities = connector.tables
|
|
145
162
|
|
|
146
|
-
|
|
163
|
+
// make sure they all have a display name selected
|
|
164
|
+
for (let entity of Object.values(datasource.entities)) {
|
|
165
|
+
if (entity.primaryDisplay) {
|
|
166
|
+
continue
|
|
167
|
+
}
|
|
168
|
+
const notAutoColumn = Object.values(entity.schema).find(
|
|
169
|
+
schema => !schema.autocolumn
|
|
170
|
+
)
|
|
171
|
+
if (notAutoColumn) {
|
|
172
|
+
entity.primaryDisplay = notAutoColumn.name
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const errors = connector.schemaErrors
|
|
177
|
+
let error = null
|
|
178
|
+
if (errors && Object.keys(errors).length > 0) {
|
|
179
|
+
const noKeyTables = Object.entries(errors)
|
|
180
|
+
.filter(entry => entry[1] === BuildSchemaErrors.NO_KEY)
|
|
181
|
+
.map(([name]) => name)
|
|
182
|
+
error = `No primary key constraint found for the following: ${noKeyTables.join(
|
|
183
|
+
", "
|
|
184
|
+
)}`
|
|
185
|
+
}
|
|
186
|
+
return { tables: connector.tables, error }
|
|
147
187
|
}
|
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
disableAllCrons,
|
|
7
7
|
enableCronTrigger,
|
|
8
8
|
} = require("../../../automations/utils")
|
|
9
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
9
10
|
|
|
10
11
|
// the max time we can wait for an invalidation to complete before considering it failed
|
|
11
12
|
const MAX_PENDING_TIME_MS = 30 * 60000
|
|
@@ -103,6 +104,7 @@ async function deployApp(deployment) {
|
|
|
103
104
|
appDoc.appId = productionAppId
|
|
104
105
|
appDoc.instance._id = productionAppId
|
|
105
106
|
await db.put(appDoc)
|
|
107
|
+
await appCache.invalidateAppMetadata(productionAppId)
|
|
106
108
|
console.log("New app doc written successfully.")
|
|
107
109
|
await initDeployedApp(productionAppId)
|
|
108
110
|
console.log("Deployed app initialised, setting deployment to successful")
|
|
@@ -6,6 +6,7 @@ const { request } = require("../../utilities/workerRequests")
|
|
|
6
6
|
const { clearLock } = require("../../utilities/redis")
|
|
7
7
|
const { Replication } = require("@budibase/auth").db
|
|
8
8
|
const { DocumentTypes } = require("../../db/utils")
|
|
9
|
+
const { app: appCache } = require("@budibase/auth/cache")
|
|
9
10
|
|
|
10
11
|
async function redirect(ctx, method, path = "global") {
|
|
11
12
|
const { devPath } = ctx.params
|
|
@@ -24,7 +25,8 @@ async function redirect(ctx, method, path = "global") {
|
|
|
24
25
|
)
|
|
25
26
|
)
|
|
26
27
|
if (response.status !== 200) {
|
|
27
|
-
|
|
28
|
+
const err = await response.text()
|
|
29
|
+
ctx.throw(400, err)
|
|
28
30
|
}
|
|
29
31
|
const cookie = response.headers.get("set-cookie")
|
|
30
32
|
if (cookie) {
|
|
@@ -106,6 +108,7 @@ exports.revert = async ctx => {
|
|
|
106
108
|
appDoc.appId = appId
|
|
107
109
|
appDoc.instance._id = appId
|
|
108
110
|
await db.put(appDoc)
|
|
111
|
+
await appCache.invalidateAppMetadata(appId)
|
|
109
112
|
ctx.body = {
|
|
110
113
|
message: "Reverted changes successfully.",
|
|
111
114
|
}
|