@budibase/server 0.9.169-alpha.9 → 0.9.172

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.
Files changed (227) hide show
  1. package/builder/assets/{index.aafb155b.js → index.9ab01cd4.js} +34 -34
  2. package/builder/assets/{index.0ea76a5c.css → index.dbc6728e.css} +2 -2
  3. package/builder/assets/{vendor.2053eff2.js → vendor.54435e8f.js} +2 -2
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +517 -609
  6. package/coverage/coverage-final.json +31 -32
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/application.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/backup.js.html +9 -6
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/dev.js.html +17 -41
  17. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/index.html +45 -45
  19. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +4 -7
  23. package/coverage/lcov-report/api/controllers/query.js.html +24 -129
  24. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/index.html +5 -5
  28. package/coverage/lcov-report/api/controllers/row/index.js.html +15 -15
  29. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/script.js.html +57 -12
  34. package/coverage/lcov-report/api/controllers/table/index.html +28 -28
  35. package/coverage/lcov-report/api/controllers/table/index.js.html +37 -16
  36. package/coverage/lcov-report/api/controllers/table/utils.js.html +33 -279
  37. package/coverage/lcov-report/api/controllers/templates.js.html +13 -49
  38. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -8
  43. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +6 -6
  44. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  45. package/coverage/lcov-report/api/index.html +1 -1
  46. package/coverage/lcov-report/api/index.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/dev.js.html +11 -26
  58. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/index.html +9 -9
  60. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/query.js.html +3 -9
  66. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  77. package/coverage/lcov-report/automations/actions.js.html +10 -31
  78. package/coverage/lcov-report/automations/automationUtils.js.html +86 -14
  79. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  80. package/coverage/lcov-report/automations/index.html +25 -25
  81. package/coverage/lcov-report/automations/index.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/bash.js.html +7 -10
  83. package/coverage/lcov-report/automations/steps/createRow.js.html +2 -2
  84. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/deleteRow.js.html +5 -8
  86. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/executeQuery.js.html +7 -10
  88. package/coverage/lcov-report/automations/steps/executeScript.js.html +7 -10
  89. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/index.html +57 -57
  91. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +7 -10
  93. package/coverage/lcov-report/automations/steps/queryRows.js.html +7 -10
  94. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +7 -10
  95. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/updateRow.js.html +14 -14
  98. package/coverage/lcov-report/automations/steps/utils.js.html +10 -10
  99. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  100. package/coverage/lcov-report/automations/thread.js.html +12 -54
  101. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  110. package/coverage/lcov-report/automations/utils.js.html +1 -1
  111. package/coverage/lcov-report/constants/index.html +1 -1
  112. package/coverage/lcov-report/constants/index.js.html +2 -5
  113. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  114. package/coverage/lcov-report/constants/screens.js.html +1 -1
  115. package/coverage/lcov-report/db/client.js.html +1 -1
  116. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  117. package/coverage/lcov-report/db/index.html +1 -1
  118. package/coverage/lcov-report/db/index.js.html +1 -1
  119. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +12 -12
  120. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  121. package/coverage/lcov-report/db/linkedRows/index.js.html +9 -9
  122. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  123. package/coverage/lcov-report/db/newid.js.html +1 -1
  124. package/coverage/lcov-report/db/utils.js.html +1 -1
  125. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  126. package/coverage/lcov-report/events/index.html +1 -1
  127. package/coverage/lcov-report/events/index.js.html +1 -1
  128. package/coverage/lcov-report/events/utils.js.html +1 -1
  129. package/coverage/lcov-report/index.html +69 -69
  130. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  131. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  132. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  133. package/coverage/lcov-report/middleware/authorized.js.html +1 -1
  134. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  135. package/coverage/lcov-report/middleware/currentapp.js.html +2 -2
  136. package/coverage/lcov-report/middleware/index.html +1 -1
  137. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  138. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  139. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  140. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  141. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  142. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  143. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  144. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  145. package/coverage/lcov-report/utilities/global.js.html +2 -2
  146. package/coverage/lcov-report/utilities/index.html +7 -22
  147. package/coverage/lcov-report/utilities/index.js.html +1 -1
  148. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  149. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  150. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  151. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  152. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  153. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +8 -38
  154. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  155. package/coverage/lcov-report/utilities/security.js.html +1 -1
  156. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  157. package/coverage/lcov-report/utilities/users.js.html +1 -1
  158. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  159. package/coverage/lcov.info +848 -1026
  160. package/dist/api/controllers/backup.js +4 -4
  161. package/dist/api/controllers/dev.js +11 -17
  162. package/dist/api/controllers/permission.js +0 -1
  163. package/dist/api/controllers/query.js +8 -26
  164. package/dist/api/controllers/row/ExternalRequest.js +5 -46
  165. package/dist/api/controllers/script.js +16 -4
  166. package/dist/api/controllers/table/index.js +10 -5
  167. package/dist/api/controllers/table/utils.js +10 -83
  168. package/dist/api/controllers/templates.js +3 -18
  169. package/dist/api/routes/dev.js +4 -8
  170. package/dist/api/routes/query.js +1 -3
  171. package/dist/automations/actions.js +3 -9
  172. package/dist/automations/automationUtils.js +29 -8
  173. package/dist/automations/steps/bash.js +1 -2
  174. package/dist/automations/steps/createRow.js +1 -1
  175. package/dist/automations/steps/deleteRow.js +1 -2
  176. package/dist/automations/steps/executeQuery.js +1 -2
  177. package/dist/automations/steps/executeScript.js +1 -2
  178. package/dist/automations/steps/outgoingWebhook.js +1 -2
  179. package/dist/automations/steps/queryRows.js +1 -2
  180. package/dist/automations/steps/sendSmtpEmail.js +1 -2
  181. package/dist/automations/steps/updateRow.js +2 -6
  182. package/dist/automations/thread.js +3 -14
  183. package/dist/constants/index.js +0 -1
  184. package/dist/integrations/base/sql.js +4 -4
  185. package/dist/integrations/utils.js +1 -16
  186. package/dist/middleware/currentapp.js +1 -1
  187. package/dist/package.json +5 -6
  188. package/dist/tsconfig.tsbuildinfo +1 -1
  189. package/dist/utilities/fileSystem/index.js +33 -49
  190. package/dist/utilities/global.js +1 -1
  191. package/dist/utilities/rowProcessor/index.js +0 -8
  192. package/package.json +6 -7
  193. package/src/api/controllers/backup.js +5 -4
  194. package/src/api/controllers/dev.js +8 -16
  195. package/src/api/controllers/permission.js +0 -1
  196. package/src/api/controllers/query.js +11 -46
  197. package/src/api/controllers/row/ExternalRequest.ts +4 -49
  198. package/src/api/controllers/script.js +19 -4
  199. package/src/api/controllers/table/index.js +12 -5
  200. package/src/api/controllers/table/utils.js +12 -94
  201. package/src/api/controllers/templates.js +5 -17
  202. package/src/api/routes/dev.js +4 -9
  203. package/src/api/routes/query.js +1 -3
  204. package/src/automations/actions.js +3 -10
  205. package/src/automations/automationUtils.js +31 -7
  206. package/src/automations/steps/bash.js +1 -2
  207. package/src/automations/steps/createRow.js +1 -1
  208. package/src/automations/steps/deleteRow.js +1 -2
  209. package/src/automations/steps/executeQuery.js +1 -2
  210. package/src/automations/steps/executeScript.js +1 -2
  211. package/src/automations/steps/outgoingWebhook.js +1 -2
  212. package/src/automations/steps/queryRows.js +1 -2
  213. package/src/automations/steps/sendSmtpEmail.js +1 -2
  214. package/src/automations/steps/updateRow.js +6 -6
  215. package/src/automations/thread.js +3 -17
  216. package/src/constants/index.js +0 -1
  217. package/src/integrations/base/sql.ts +3 -5
  218. package/src/integrations/tests/mongo.spec.js +6 -10
  219. package/src/integrations/utils.ts +0 -15
  220. package/src/middleware/currentapp.js +1 -1
  221. package/src/middleware/tests/currentapp.spec.js +3 -3
  222. package/src/utilities/fileSystem/index.js +43 -65
  223. package/src/utilities/global.js +1 -1
  224. package/src/utilities/rowProcessor/index.js +0 -10
  225. package/coverage/lcov-report/utilities/scriptRunner.js.html +0 -143
  226. package/dist/utilities/scriptRunner.js +0 -19
  227. package/src/utilities/scriptRunner.js +0 -21
@@ -98,69 +98,53 @@ 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
- });
112
101
  /**
113
102
  * Takes a copy of the database state for an app to the object store.
114
103
  * @param {string} appId The ID of the app which is to be backed up.
115
104
  * @param {string} backupName The name of the backup located in the object store.
116
- * @return {*} a readable stream to the completed backup file
105
+ * @return The backup has been completed when this promise completes and returns a file stream
106
+ * to the temporary backup file (to return via API if required).
117
107
  */
118
108
  exports.performBackup = (appId, backupName) => __awaiter(void 0, void 0, void 0, function* () {
119
- return yield backupAppData(appId, { exportName: backupName });
120
- });
121
- /**
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 });
109
+ return exports.exportDB(appId, {
110
+ exportName: backupName,
111
+ filter: doc => !(doc._id.includes(USER_METDATA_PREFIX) ||
112
+ doc.includes(LINK_USER_METADATA_PREFIX)),
113
+ });
128
114
  });
129
115
  /**
130
- * Exports a DB to either file or a variable (memory).
116
+ * exports a DB to either file or a variable (memory).
131
117
  * @param {string} dbName the DB which is to be exported.
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
118
+ * @param {string} exportName optional - the file name to export to, if not in memory.
134
119
  * @param {function} filter optional - a filter function to clear out any un-wanted docs.
135
- * @return {*} either a readable stream or a string
120
+ * @return Either the file stream or the variable (if no export name provided).
136
121
  */
137
- exports.exportDB = (dbName, { stream, filter, exportName } = {}) => __awaiter(void 0, void 0, void 0, function* () {
138
- const instanceDb = new CouchDB(dbName);
139
- // Stream the dump if required
140
- if (stream) {
141
- const memStream = new MemoryStream();
142
- instanceDb.dump(memStream, { filter });
143
- return memStream;
144
- }
145
- // Write the dump to file if required
122
+ exports.exportDB = (dbName, { exportName, filter } = { exportName: undefined, filter: undefined }) => __awaiter(void 0, void 0, void 0, function* () {
123
+ let stream, appString = "", path = null;
146
124
  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);
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
+ });
155
133
  }
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();
134
+ // perform couch dump
135
+ const instanceDb = new CouchDB(dbName);
136
+ yield instanceDb.dump(stream, {
137
+ filter,
161
138
  });
162
- yield instanceDb.dump(memStream, { filter });
163
- return appString;
139
+ // just in memory, return the final string
140
+ if (!exportName) {
141
+ return appString;
142
+ }
143
+ // write the file to the object store
144
+ if (env.SELF_HOSTED) {
145
+ yield streamUpload(ObjectStoreBuckets.BACKUPS, join(dbName, exportName), fs.createReadStream(path));
146
+ }
147
+ return fs.createReadStream(path);
164
148
  });
165
149
  /**
166
150
  * Writes the provided contents to a temporary file, which can be used briefly.
@@ -33,7 +33,7 @@ exports.updateAppRole = (appId, user) => {
33
33
  user.roleId = BUILTIN_ROLE_IDS.ADMIN;
34
34
  }
35
35
  else if (!user.roleId) {
36
- user.roleId = BUILTIN_ROLE_IDS.PUBLIC;
36
+ user.roleId = BUILTIN_ROLE_IDS.BASIC;
37
37
  }
38
38
  delete user.roles;
39
39
  return user;
@@ -149,10 +149,6 @@ 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
- }
156
152
  // eslint-disable-next-line no-prototype-builtins
157
153
  if (TYPE_TRANSFORM_MAP[type].hasOwnProperty(row)) {
158
154
  return TYPE_TRANSFORM_MAP[type][row];
@@ -194,10 +190,6 @@ exports.inputProcessing = (user = {}, table, row, opts = { noAutoRelationships:
194
190
  clonedRow[key] = exports.coerce(value, field.type);
195
191
  }
196
192
  }
197
- if (!clonedRow._id || !clonedRow._rev) {
198
- clonedRow._id = row._id;
199
- clonedRow._rev = row._rev;
200
- }
201
193
  // handle auto columns - this returns an object like {table, row}
202
194
  return processAutoColumn(user, copiedTable, clonedRow, opts);
203
195
  };
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.169-alpha.9",
4
+ "version": "0.9.172",
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.169-alpha.9",
72
- "@budibase/client": "^0.9.169-alpha.9",
73
- "@budibase/string-templates": "^0.9.169-alpha.9",
71
+ "@budibase/auth": "^0.9.172",
72
+ "@budibase/client": "^0.9.172",
73
+ "@budibase/string-templates": "^0.9.172",
74
74
  "@elastic/elasticsearch": "7.10.0",
75
75
  "@koa/router": "8.0.0",
76
76
  "@sendgrid/mail": "7.1.1",
77
- "@sentry/node": "^6.0.0",
77
+ "@sentry/node": "5.19.2",
78
78
  "airtable": "0.10.1",
79
79
  "arangojs": "7.2.0",
80
80
  "aws-sdk": "^2.767.0",
@@ -119,7 +119,6 @@
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",
123
122
  "yargs": "13.2.4",
124
123
  "zlib": "1.0.5"
125
124
  },
@@ -149,5 +148,5 @@
149
148
  "typescript": "^4.3.5",
150
149
  "update-dotenv": "^1.1.1"
151
150
  },
152
- "gitHead": "00e2f5b2201a0cf582c38213855284c37fa67863"
151
+ "gitHead": "f33cc5a9cd747ffb8491af36ac7baf0bf66de290"
153
152
  }
@@ -1,9 +1,10 @@
1
- const { streamBackup } = require("../../utilities/fileSystem")
1
+ const { performBackup } = require("../../utilities/fileSystem")
2
2
 
3
3
  exports.exportAppDump = async function (ctx) {
4
4
  const { appId } = ctx.query
5
- const appName = decodeURI(ctx.query.appname)
6
- const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt`
5
+ const appname = decodeURI(ctx.query.appname)
6
+ const backupIdentifier = `${appname}Backup${new Date().getTime()}.txt`
7
+
7
8
  ctx.attachment(backupIdentifier)
8
- ctx.body = await streamBackup(appId)
9
+ ctx.body = await performBackup(appId, backupIdentifier)
9
10
  }
@@ -7,13 +7,11 @@ 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, path = "global") {
10
+ async function redirect(ctx, method) {
11
11
  const { devPath } = ctx.params
12
12
  const queryString = ctx.originalUrl.split("?")[1] || ""
13
13
  const response = await fetch(
14
- checkSlashesInUrl(
15
- `${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`
16
- ),
14
+ checkSlashesInUrl(`${env.WORKER_URL}/api/global/${devPath}?${queryString}`),
17
15
  request(
18
16
  ctx,
19
17
  {
@@ -43,22 +41,16 @@ async function redirect(ctx, method, path = "global") {
43
41
  ctx.cookies
44
42
  }
45
43
 
46
- exports.buildRedirectGet = path => {
47
- return async ctx => {
48
- await redirect(ctx, "GET", path)
49
- }
44
+ exports.redirectGet = async ctx => {
45
+ await redirect(ctx, "GET")
50
46
  }
51
47
 
52
- exports.buildRedirectPost = path => {
53
- return async ctx => {
54
- await redirect(ctx, "POST", path)
55
- }
48
+ exports.redirectPost = async ctx => {
49
+ await redirect(ctx, "POST")
56
50
  }
57
51
 
58
- exports.buildRedirectDelete = path => {
59
- return async ctx => {
60
- await redirect(ctx, "DELETE", path)
61
- }
52
+ exports.redirectDelete = async ctx => {
53
+ await redirect(ctx, "DELETE")
62
54
  }
63
55
 
64
56
  exports.clearLock = async ctx => {
@@ -147,7 +147,6 @@ exports.getResourcePerms = async function (ctx) {
147
147
  const rolePerms = role.permissions
148
148
  if (
149
149
  rolePerms &&
150
- rolePerms[resourceId] &&
151
150
  (rolePerms[resourceId] === level ||
152
151
  rolePerms[resourceId].indexOf(level) !== -1)
153
152
  ) {
@@ -4,7 +4,6 @@ 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")
8
7
 
9
8
  // simple function to append "readable" to all read queries
10
9
  function enrichQueries(input) {
@@ -29,37 +28,10 @@ function formatResponse(resp) {
29
28
  resp = { response: resp }
30
29
  }
31
30
  }
32
- return resp
33
- }
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]
31
+ if (!Array.isArray(resp)) {
32
+ resp = [resp]
52
33
  }
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 }
34
+ return resp
63
35
  }
64
36
 
65
37
  exports.fetch = async function (ctx) {
@@ -150,16 +122,15 @@ exports.preview = async function (ctx) {
150
122
  ctx.throw(400, "Integration type does not exist.")
151
123
  }
152
124
 
153
- const { fields, parameters, queryVerb, transformer } = ctx.request.body
125
+ const { fields, parameters, queryVerb } = ctx.request.body
126
+
154
127
  const enrichedQuery = await enrichQueryFields(fields, parameters)
128
+
155
129
  const integration = new Integration(datasource.config)
130
+ const rows = formatResponse(await integration[queryVerb](enrichedQuery))
156
131
 
157
- const { rows, keys } = await runAndTransform(
158
- integration,
159
- queryVerb,
160
- enrichedQuery,
161
- transformer
162
- )
132
+ // get all the potential fields in the schema
133
+ const keys = rows.flatMap(Object.keys)
163
134
 
164
135
  ctx.body = {
165
136
  rows,
@@ -187,16 +158,10 @@ exports.execute = async function (ctx) {
187
158
  query.fields,
188
159
  ctx.request.body.parameters
189
160
  )
190
- const integration = new Integration(datasource.config)
191
161
 
162
+ const integration = new Integration(datasource.config)
192
163
  // call the relevant CRUD method on the integration class
193
- const { rows } = await runAndTransform(
194
- integration,
195
- query.queryVerb,
196
- enrichedQuery,
197
- query.transformer
198
- )
199
- ctx.body = rows
164
+ ctx.body = formatResponse(await integration[query.queryVerb](enrichedQuery))
200
165
  // cleanup
201
166
  if (integration.end) {
202
167
  integration.end()
@@ -15,9 +15,8 @@ import {
15
15
  import {
16
16
  breakRowIdField,
17
17
  generateRowIdField,
18
- isRowId,
19
- convertRowId,
20
18
  } from "../../../integrations/utils"
19
+ import { RelationshipTypes } from "../../../constants"
21
20
 
22
21
  interface ManyRelationship {
23
22
  tableId?: string
@@ -37,7 +36,7 @@ interface RunConfig {
37
36
 
38
37
  module External {
39
38
  const { makeExternalQuery } = require("./utils")
40
- const { DataSourceOperation, FieldTypes, RelationshipTypes } = require("../../../constants")
39
+ const { DataSourceOperation, FieldTypes } = require("../../../constants")
41
40
  const { breakExternalTableId, isSQL } = require("../../../integrations/utils")
42
41
  const { processObjectSync } = require("@budibase/string-templates")
43
42
  const { cloneDeep } = require("lodash/fp")
@@ -84,48 +83,6 @@ module External {
84
83
  }
85
84
  }
86
85
 
87
- /**
88
- * This function checks the incoming parameters to make sure all the inputs are
89
- * valid based on on the table schema. The main thing this is looking for is when a
90
- * user has made use of the _id field of a row for a foreign key or a search parameter.
91
- * In these cases the key will be sent up as [1], rather than 1. In these cases we will
92
- * simplify it down to the requirements. This function is quite complex as we try to be
93
- * relatively restrictive over what types of columns we will perform this action for.
94
- */
95
- function cleanupConfig(config: RunConfig, table: Table): RunConfig {
96
- const primaryOptions = [
97
- FieldTypes.STRING,
98
- FieldTypes.LONGFORM,
99
- FieldTypes.OPTIONS,
100
- FieldTypes.NUMBER,
101
- ]
102
- // filter out fields which cannot be keys
103
- const fieldNames = Object.entries(table.schema)
104
- .filter(schema => primaryOptions.find(val => val === schema[1].type))
105
- .map(([fieldName]) => fieldName)
106
- const iterateObject = (obj: { [key: string]: any }) => {
107
- for (let [field, value] of Object.entries(obj)) {
108
- if (fieldNames.find(name => name === field) && isRowId(value)) {
109
- obj[field] = convertRowId(value)
110
- }
111
- }
112
- }
113
- // check the row and filters to make sure they aren't a key of some sort
114
- if (config.filters) {
115
- for (let filter of Object.values(config.filters)) {
116
- if (typeof filter !== "object" || Object.keys(filter).length === 0) {
117
- continue
118
- }
119
- iterateObject(filter)
120
- }
121
- }
122
- if (config.row) {
123
- iterateObject(config.row)
124
- }
125
-
126
- return config
127
- }
128
-
129
86
  function generateIdForRow(row: Row | undefined, table: Table): string {
130
87
  const primary = table.primary
131
88
  if (!row || !primary) {
@@ -552,7 +509,7 @@ module External {
552
509
  return fields
553
510
  }
554
511
 
555
- async run(config: RunConfig) {
512
+ async run({ id, row, filters, sort, paginate }: RunConfig) {
556
513
  const { appId, operation, tableId } = this
557
514
  let { datasourceId, tableName } = breakExternalTableId(tableId)
558
515
  if (!this.datasource) {
@@ -568,11 +525,9 @@ module External {
568
525
  if (!table) {
569
526
  throw `Unable to process query, table "${tableName}" not defined.`
570
527
  }
571
- // look for specific components of config which may not be considered acceptable
572
- let { id, row, filters, sort, paginate } = cleanupConfig(config, table)
528
+ // clean up row on ingress using schema
573
529
  filters = buildFilters(id, filters || {}, table)
574
530
  const relationships = this.buildRelationships(table)
575
- // clean up row on ingress using schema
576
531
  const processed = this.inputProcessing(row, table)
577
532
  row = processed.row
578
533
  if (
@@ -1,9 +1,24 @@
1
- const ScriptRunner = require("../../utilities/scriptRunner")
1
+ const fetch = require("node-fetch")
2
+ const vm = require("vm")
3
+
4
+ class ScriptExecutor {
5
+ constructor(body) {
6
+ const code = `let fn = () => {\n${body.script}\n}; out = fn();`
7
+ this.script = new vm.Script(code)
8
+ this.context = vm.createContext(body.context)
9
+ this.context.fetch = fetch
10
+ }
11
+
12
+ execute() {
13
+ this.script.runInContext(this.context)
14
+ return this.context.out
15
+ }
16
+ }
2
17
 
3
18
  exports.execute = async function (ctx) {
4
- const { script, context } = ctx.request.body
5
- const runner = new ScriptRunner(script, context)
6
- ctx.body = runner.execute()
19
+ const executor = new ScriptExecutor(ctx.request.body)
20
+
21
+ ctx.body = executor.execute()
7
22
  }
8
23
 
9
24
  exports.save = async function (ctx) {
@@ -9,7 +9,11 @@ const {
9
9
  BudibaseInternalDB,
10
10
  } = require("../../../db/utils")
11
11
  const { FieldTypes } = require("../../../constants")
12
- const { TableSaveFunctions, getTable } = require("./utils")
12
+ const { TableSaveFunctions, getExternalTable } = require("./utils")
13
+ const {
14
+ isExternalTable,
15
+ breakExternalTableId,
16
+ } = require("../../../integrations/utils")
13
17
 
14
18
  exports.fetch = async function (ctx) {
15
19
  const db = new CouchDB(ctx.appId)
@@ -44,8 +48,14 @@ exports.fetch = async function (ctx) {
44
48
  }
45
49
 
46
50
  exports.find = async function (ctx) {
51
+ const db = new CouchDB(ctx.appId)
47
52
  const tableId = ctx.params.id
48
- ctx.body = await getTable(ctx.appId, tableId)
53
+ if (isExternalTable(tableId)) {
54
+ let { datasourceId, tableName } = breakExternalTableId(tableId)
55
+ ctx.body = await getExternalTable(ctx.appId, datasourceId, tableName)
56
+ } else {
57
+ ctx.body = await db.get(ctx.params.id)
58
+ }
49
59
  }
50
60
 
51
61
  exports.save = async function (ctx) {
@@ -81,9 +91,6 @@ exports.save = async function (ctx) {
81
91
  for (let propKey of Object.keys(tableToSave.schema)) {
82
92
  let column = tableToSave.schema[propKey]
83
93
  let oldColumn = oldTable.schema[propKey]
84
- if (oldColumn && oldColumn.type === "internal") {
85
- oldColumn.type = "auto"
86
- }
87
94
  if (oldColumn && oldColumn.type !== column.type) {
88
95
  ctx.throw(400, "Cannot change the type of a column")
89
96
  }
@@ -1,4 +1,5 @@
1
1
  const CouchDB = require("../../../db")
2
+ const linkRows = require("../../../db/linkedRows")
2
3
  const csvParser = require("../../../utilities/csvParser")
3
4
  const {
4
5
  getRowParams,
@@ -9,12 +10,6 @@ const { isEqual } = require("lodash/fp")
9
10
  const { AutoFieldSubTypes, FieldTypes } = require("../../../constants")
10
11
  const { inputProcessing } = require("../../../utilities/rowProcessor")
11
12
  const { USERS_TABLE_SCHEMA } = require("../../../constants")
12
- const {
13
- isExternalTable,
14
- breakExternalTableId,
15
- } = require("../../../integrations/utils")
16
- const { getViews, saveView } = require("../view/utils")
17
- const viewTemplate = require("../view/viewBuilder")
18
13
 
19
14
  exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
20
15
  let updatedRows = []
@@ -27,7 +22,6 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
27
22
  }
28
23
  // check for renaming of columns or deleted columns
29
24
  if (rename || deletedColumns.length !== 0) {
30
- // Update all rows
31
25
  const rows = await db.allDocs(
32
26
  getRowParams(updatedTable._id, null, {
33
27
  include_docs: true,
@@ -42,9 +36,6 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
42
36
  }
43
37
  return doc
44
38
  })
45
-
46
- // Update views
47
- await exports.checkForViewUpdates(db, updatedTable, rename, deletedColumns)
48
39
  delete updatedTable._rename
49
40
  }
50
41
  return { rows: updatedRows, table: updatedTable }
@@ -102,10 +93,19 @@ exports.handleDataImport = async (appId, user, table, dataImport) => {
102
93
  }
103
94
  }
104
95
 
105
- finalData.push(row)
96
+ // make sure link rows are up to date
97
+ finalData.push(
98
+ linkRows.updateLinks({
99
+ appId,
100
+ eventType: linkRows.EventType.ROW_SAVE,
101
+ row,
102
+ tableId: row.tableId,
103
+ table,
104
+ })
105
+ )
106
106
  }
107
107
 
108
- await db.bulkDocs(finalData)
108
+ await db.bulkDocs(await Promise.all(finalData))
109
109
  let response = await db.put(table)
110
110
  table._rev = response._rev
111
111
  }
@@ -233,86 +233,4 @@ exports.getExternalTable = async (appId, datasourceId, tableName) => {
233
233
  return entities[tableName]
234
234
  }
235
235
 
236
- exports.getTable = async (appId, tableId) => {
237
- const db = new CouchDB(appId)
238
- if (isExternalTable(tableId)) {
239
- let { datasourceId, tableName } = breakExternalTableId(tableId)
240
- return exports.getExternalTable(appId, datasourceId, tableName)
241
- } else {
242
- return db.get(tableId)
243
- }
244
- }
245
-
246
- exports.checkForViewUpdates = async (db, table, rename, deletedColumns) => {
247
- const views = await getViews(db)
248
- const tableViews = views.filter(view => view.meta.tableId === table._id)
249
-
250
- // Check each table view to see if impacted by this table action
251
- for (let view of tableViews) {
252
- let needsUpdated = false
253
-
254
- // First check for renames, otherwise check for deletions
255
- if (rename) {
256
- // Update calculation field if required
257
- if (view.meta.field === rename.old) {
258
- view.meta.field = rename.updated
259
- needsUpdated = true
260
- }
261
-
262
- // Update group by field if required
263
- if (view.meta.groupBy === rename.old) {
264
- view.meta.groupBy = rename.updated
265
- needsUpdated = true
266
- }
267
-
268
- // Update filters if required
269
- if (view.meta.filters) {
270
- view.meta.filters.forEach(filter => {
271
- if (filter.key === rename.old) {
272
- filter.key = rename.updated
273
- needsUpdated = true
274
- }
275
- })
276
- }
277
- } else if (deletedColumns) {
278
- deletedColumns.forEach(column => {
279
- // Remove calculation statement if required
280
- if (view.meta.field === column) {
281
- delete view.meta.field
282
- delete view.meta.calculation
283
- delete view.meta.groupBy
284
- needsUpdated = true
285
- }
286
-
287
- // Remove group by field if required
288
- if (view.meta.groupBy === column) {
289
- delete view.meta.groupBy
290
- needsUpdated = true
291
- }
292
-
293
- // Remove filters referencing deleted field if required
294
- if (view.meta.filters && view.meta.filters.length) {
295
- const initialLength = view.meta.filters.length
296
- view.meta.filters = view.meta.filters.filter(filter => {
297
- return filter.key !== column
298
- })
299
- if (initialLength !== view.meta.filters.length) {
300
- needsUpdated = true
301
- }
302
- }
303
- })
304
- }
305
-
306
- // Update view if required
307
- if (needsUpdated) {
308
- const newViewTemplate = viewTemplate(view.meta)
309
- await saveView(db, null, view.name, newViewTemplate)
310
- if (!newViewTemplate.meta.schema) {
311
- newViewTemplate.meta.schema = table.schema
312
- }
313
- table.views[view.name] = newViewTemplate.meta
314
- }
315
- }
316
- }
317
-
318
236
  exports.TableSaveFunctions = TableSaveFunctions
@@ -7,23 +7,11 @@ const DEFAULT_TEMPLATES_BUCKET =
7
7
 
8
8
  exports.fetch = async function (ctx) {
9
9
  const { type = "app" } = ctx.query
10
- let response,
11
- error = false
12
- try {
13
- response = await fetch(`https://${DEFAULT_TEMPLATES_BUCKET}/manifest.json`)
14
- if (response.status !== 200) {
15
- error = true
16
- }
17
- } catch (err) {
18
- error = true
19
- }
20
- // if there is an error, simply return no templates
21
- if (!error && response) {
22
- const json = await response.json()
23
- ctx.body = Object.values(json.templates[type])
24
- } else {
25
- ctx.body = []
26
- }
10
+ const response = await fetch(
11
+ `https://${DEFAULT_TEMPLATES_BUCKET}/manifest.json`
12
+ )
13
+ const json = await response.json()
14
+ ctx.body = Object.values(json.templates[type])
27
15
  }
28
16
 
29
17
  // can't currently test this, have to ignore from coverage