@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.
Files changed (290) hide show
  1. package/Dockerfile +1 -1
  2. package/__mocks__/mssql.ts +1 -1
  3. package/__mocks__/pg.ts +3 -0
  4. package/builder/assets/bb-space-man.5be51a45.svg +290 -0
  5. package/builder/assets/index.053c6f7a.js +1321 -0
  6. package/builder/assets/index.4a7c5636.css +1 -0
  7. package/builder/assets/vendor.470042a4.js +152 -0
  8. package/builder/assets/vendor.5e1fe644.css +1 -0
  9. package/builder/index.html +4 -4
  10. package/coverage/clover.xml +1357 -959
  11. package/coverage/coverage-final.json +91 -87
  12. package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
  13. package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
  14. package/coverage/lcov-report/api/controllers/application.js.html +65 -14
  15. package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
  16. package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
  17. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  20. package/coverage/lcov-report/api/controllers/datasource.js.html +147 -27
  21. package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
  22. package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
  23. package/coverage/lcov-report/api/controllers/index.html +90 -90
  24. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
  26. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
  27. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  28. package/coverage/lcov-report/api/controllers/query.js.html +53 -209
  29. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  30. package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
  31. package/coverage/lcov-report/api/controllers/row/external.js.html +12 -6
  32. package/coverage/lcov-report/api/controllers/row/index.html +26 -26
  33. package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
  35. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  36. package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
  37. package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
  38. package/coverage/lcov-report/api/controllers/script.js.html +3 -3
  39. package/coverage/lcov-report/api/controllers/table/external.js.html +980 -0
  40. package/coverage/lcov-report/api/controllers/table/index.html +56 -26
  41. package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
  42. package/coverage/lcov-report/api/controllers/table/internal.js.html +545 -0
  43. package/coverage/lcov-report/api/controllers/table/utils.js.html +172 -49
  44. package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
  45. package/coverage/lcov-report/api/controllers/user.js.html +390 -33
  46. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.html +9 -9
  48. package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
  49. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  50. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
  51. package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
  52. package/coverage/lcov-report/api/index.html +1 -1
  53. package/coverage/lcov-report/api/index.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  65. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/index.html +4 -4
  67. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/query.js.html +5 -2
  73. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  79. package/coverage/lcov-report/api/routes/table.js.html +35 -2
  80. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/user.js.html +17 -2
  82. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  83. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  84. package/coverage/lcov-report/automations/actions.js.html +2 -2
  85. package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
  86. package/coverage/lcov-report/automations/bullboard.js.html +71 -20
  87. package/coverage/lcov-report/automations/index.html +33 -48
  88. package/coverage/lcov-report/automations/index.js.html +2 -2
  89. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
  94. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
  96. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/index.html +14 -14
  98. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
  100. package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
  101. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
  106. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  108. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  109. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  111. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  113. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  114. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggers.js.html +22 -10
  116. package/coverage/lcov-report/automations/utils.js.html +42 -12
  117. package/coverage/lcov-report/constants/index.html +5 -5
  118. package/coverage/lcov-report/constants/index.js.html +49 -4
  119. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  120. package/coverage/lcov-report/constants/screens.js.html +1 -1
  121. package/coverage/lcov-report/db/client.js.html +2 -2
  122. package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
  123. package/coverage/lcov-report/db/index.html +2 -2
  124. package/coverage/lcov-report/db/index.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
  126. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  127. package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
  128. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
  129. package/coverage/lcov-report/db/newid.js.html +1 -1
  130. package/coverage/lcov-report/db/utils.js.html +1 -1
  131. package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
  132. package/coverage/lcov-report/events/index.html +6 -6
  133. package/coverage/lcov-report/events/index.js.html +1 -1
  134. package/coverage/lcov-report/events/utils.js.html +5 -5
  135. package/coverage/lcov-report/index.html +98 -83
  136. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  137. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  138. package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
  139. package/coverage/lcov-report/middleware/authorized.js.html +11 -8
  140. package/coverage/lcov-report/middleware/builder.js.html +16 -7
  141. package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
  142. package/coverage/lcov-report/middleware/index.html +23 -23
  143. package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
  144. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  145. package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
  146. package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
  147. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  148. package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +83 -32
  149. package/coverage/lcov-report/threads/index.html +141 -0
  150. package/coverage/lcov-report/threads/index.js.html +260 -0
  151. package/coverage/lcov-report/threads/query.js.html +269 -0
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  154. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  155. package/coverage/lcov-report/utilities/csvParser.js.html +144 -15
  156. package/coverage/lcov-report/utilities/global.js.html +26 -11
  157. package/coverage/lcov-report/utilities/index.html +49 -49
  158. package/coverage/lcov-report/utilities/index.js.html +65 -17
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
  160. package/coverage/lcov-report/utilities/queue/index.html +14 -14
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
  167. package/coverage/lcov-report/utilities/security.js.html +3 -3
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/users.js.html +1 -1
  170. package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
  171. package/coverage/lcov.info +2301 -1599
  172. package/dist/api/controllers/application.js +16 -2
  173. package/dist/api/controllers/auth.js +3 -3
  174. package/dist/api/controllers/datasource.js +47 -16
  175. package/dist/api/controllers/deploy/index.js +2 -0
  176. package/dist/api/controllers/dev.js +4 -1
  177. package/dist/api/controllers/query.js +30 -58
  178. package/dist/api/controllers/row/ExternalRequest.js +37 -14
  179. package/dist/api/controllers/row/external.js +1 -0
  180. package/dist/api/controllers/row/utils.js +6 -12
  181. package/dist/api/controllers/static/index.js +1 -1
  182. package/dist/api/controllers/table/external.js +242 -0
  183. package/dist/api/controllers/table/index.js +49 -123
  184. package/dist/api/controllers/table/internal.js +150 -0
  185. package/dist/api/controllers/table/utils.js +62 -28
  186. package/dist/api/controllers/user.js +123 -11
  187. package/dist/api/routes/query.js +1 -1
  188. package/dist/api/routes/table.js +7 -1
  189. package/dist/api/routes/user.js +2 -1
  190. package/dist/app.js +2 -11
  191. package/dist/automations/bullboard.js +37 -10
  192. package/dist/automations/triggers.js +7 -3
  193. package/dist/automations/utils.js +11 -2
  194. package/dist/constants/index.js +13 -0
  195. package/dist/definitions/datasource.js +4 -0
  196. package/dist/integrations/base/IntegrationBase.js +2 -0
  197. package/dist/integrations/base/datasourcePlus.js +2 -0
  198. package/dist/integrations/base/sql.js +334 -180
  199. package/dist/integrations/base/sqlTable.js +143 -0
  200. package/dist/integrations/base/utils.js +30 -0
  201. package/dist/integrations/microsoftSqlServer.js +117 -9
  202. package/dist/integrations/mysql.js +14 -84
  203. package/dist/integrations/postgres.js +35 -28
  204. package/dist/integrations/utils.js +56 -9
  205. package/dist/middleware/authorized.js +2 -1
  206. package/dist/middleware/builder.js +4 -1
  207. package/dist/package.json +7 -6
  208. package/dist/tests/utilities/TestConfiguration.js +2 -1
  209. package/dist/{automations/thread.js → threads/automation.js} +23 -7
  210. package/dist/threads/index.js +58 -0
  211. package/dist/threads/query.js +61 -0
  212. package/dist/tsconfig.tsbuildinfo +1 -1
  213. package/dist/utilities/csvParser.js +46 -5
  214. package/dist/utilities/global.js +6 -2
  215. package/dist/utilities/index.js +18 -2
  216. package/dist/utilities/queue/inMemoryQueue.js +8 -0
  217. package/dist/utilities/scriptRunner.js +4 -1
  218. package/package.json +8 -7
  219. package/scripts/integrations/mssql/data/Dockerfile +9 -0
  220. package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
  221. package/scripts/integrations/mssql/data/setup.sql +54 -0
  222. package/scripts/integrations/mssql/docker-compose.yaml +12 -0
  223. package/scripts/integrations/mssql/reset.sh +3 -0
  224. package/scripts/likeCypress.ts +33 -0
  225. package/src/api/controllers/application.js +19 -2
  226. package/src/api/controllers/auth.js +3 -0
  227. package/src/api/controllers/datasource.js +56 -16
  228. package/src/api/controllers/deploy/index.js +2 -0
  229. package/src/api/controllers/dev.js +4 -1
  230. package/src/api/controllers/query.js +29 -81
  231. package/src/api/controllers/row/ExternalRequest.ts +47 -16
  232. package/src/api/controllers/row/external.js +2 -0
  233. package/src/api/controllers/row/utils.js +8 -11
  234. package/src/api/controllers/static/index.js +1 -1
  235. package/src/api/controllers/table/external.js +300 -0
  236. package/src/api/controllers/table/index.js +47 -137
  237. package/src/api/controllers/table/internal.js +155 -0
  238. package/src/api/controllers/table/utils.js +74 -33
  239. package/src/api/controllers/user.js +132 -13
  240. package/src/api/routes/query.js +1 -0
  241. package/src/api/routes/table.js +11 -0
  242. package/src/api/routes/tests/datasource.spec.js +2 -2
  243. package/src/api/routes/tests/misc.spec.js +5 -1
  244. package/src/api/routes/tests/query.spec.js +0 -1
  245. package/src/api/routes/user.js +5 -0
  246. package/src/app.ts +2 -10
  247. package/src/automations/bullboard.js +28 -11
  248. package/src/automations/tests/automation.spec.js +3 -4
  249. package/src/automations/triggers.js +7 -3
  250. package/src/automations/utils.js +12 -2
  251. package/src/constants/index.js +15 -0
  252. package/src/definitions/common.ts +7 -1
  253. package/src/definitions/datasource.ts +9 -3
  254. package/src/integrations/airtable.ts +2 -1
  255. package/src/integrations/arangodb.ts +2 -1
  256. package/src/integrations/base/IntegrationBase.ts +6 -0
  257. package/src/integrations/base/datasourcePlus.ts +9 -0
  258. package/src/integrations/base/sql.ts +359 -222
  259. package/src/integrations/base/sqlTable.ts +180 -0
  260. package/src/integrations/base/utils.ts +22 -0
  261. package/src/integrations/couchdb.ts +2 -1
  262. package/src/integrations/dynamodb.ts +2 -1
  263. package/src/integrations/elasticsearch.ts +2 -1
  264. package/src/integrations/microsoftSqlServer.ts +145 -13
  265. package/src/integrations/mongodb.ts +2 -1
  266. package/src/integrations/mysql.ts +20 -94
  267. package/src/integrations/postgres.ts +45 -35
  268. package/src/integrations/rest.ts +2 -1
  269. package/src/integrations/s3.ts +2 -1
  270. package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
  271. package/src/integrations/tests/postgres.spec.js +4 -0
  272. package/src/integrations/utils.ts +60 -8
  273. package/src/middleware/authorized.js +2 -1
  274. package/src/middleware/builder.js +4 -1
  275. package/src/tests/utilities/TestConfiguration.js +2 -1
  276. package/src/{automations/thread.js → threads/automation.js} +24 -7
  277. package/src/threads/index.js +60 -0
  278. package/src/threads/query.js +63 -0
  279. package/src/utilities/csvParser.js +48 -5
  280. package/src/utilities/global.js +7 -2
  281. package/src/utilities/index.js +18 -2
  282. package/src/utilities/queue/inMemoryQueue.js +7 -0
  283. package/src/utilities/scriptRunner.js +4 -1
  284. package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
  285. package/src/utilities/tests/csvParser.spec.js +3 -0
  286. package/tsconfig.json +1 -1
  287. package/builder/assets/index.34964222.js +0 -201
  288. package/builder/assets/index.7469e1e4.css +0 -29
  289. package/builder/assets/vendor.278a305c.js +0 -9
  290. package/builder/assets/vendor.d75d5eb7.css +0 -1
@@ -14,7 +14,7 @@ const { getRowParams, generateRowID, InternalTables, } = require("../../../db/ut
14
14
  const { isEqual } = require("lodash/fp");
15
15
  const { AutoFieldSubTypes, FieldTypes } = require("../../../constants");
16
16
  const { inputProcessing } = require("../../../utilities/rowProcessor");
17
- const { USERS_TABLE_SCHEMA } = require("../../../constants");
17
+ const { USERS_TABLE_SCHEMA, SwitchableTypes } = require("../../../constants");
18
18
  const { isExternalTable, breakExternalTableId, } = require("../../../integrations/utils");
19
19
  const { getViews, saveView } = require("../view/utils");
20
20
  const viewTemplate = require("../view/viewBuilder");
@@ -66,37 +66,38 @@ exports.makeSureTableUpToDate = (table, tableToSave) => {
66
66
  return tableToSave;
67
67
  };
68
68
  exports.handleDataImport = (appId, user, table, dataImport) => __awaiter(void 0, void 0, void 0, function* () {
69
+ if (!dataImport || !dataImport.csvString) {
70
+ return table;
71
+ }
69
72
  const db = new CouchDB(appId);
70
- if (dataImport && dataImport.csvString) {
71
- // Populate the table with rows imported from CSV in a bulk update
72
- const data = yield csvParser.transform(dataImport);
73
- let finalData = [];
74
- for (let i = 0; i < data.length; i++) {
75
- let row = data[i];
76
- row._id = generateRowID(table._id);
77
- row.tableId = table._id;
78
- const processed = inputProcessing(user, table, row, {
79
- noAutoRelationships: true,
80
- });
81
- table = processed.table;
82
- row = processed.row;
83
- for (let [fieldName, schema] of Object.entries(table.schema)) {
84
- // check whether the options need to be updated for inclusion as part of the data import
85
- if (schema.type === FieldTypes.OPTIONS &&
86
- (!schema.constraints.inclusion ||
87
- schema.constraints.inclusion.indexOf(row[fieldName]) === -1)) {
88
- schema.constraints.inclusion = [
89
- ...schema.constraints.inclusion,
90
- row[fieldName],
91
- ];
92
- }
73
+ // Populate the table with rows imported from CSV in a bulk update
74
+ const data = yield csvParser.transform(Object.assign(Object.assign({}, dataImport), { existingTable: table }));
75
+ let finalData = [];
76
+ for (let i = 0; i < data.length; i++) {
77
+ let row = data[i];
78
+ row._id = generateRowID(table._id);
79
+ row.tableId = table._id;
80
+ const processed = inputProcessing(user, table, row, {
81
+ noAutoRelationships: true,
82
+ });
83
+ table = processed.table;
84
+ row = processed.row;
85
+ for (let [fieldName, schema] of Object.entries(table.schema)) {
86
+ // check whether the options need to be updated for inclusion as part of the data import
87
+ if (schema.type === FieldTypes.OPTIONS &&
88
+ (!schema.constraints.inclusion ||
89
+ schema.constraints.inclusion.indexOf(row[fieldName]) === -1)) {
90
+ schema.constraints.inclusion = [
91
+ ...schema.constraints.inclusion,
92
+ row[fieldName],
93
+ ];
93
94
  }
94
- finalData.push(row);
95
95
  }
96
- yield db.bulkDocs(finalData);
97
- let response = yield db.put(table);
98
- table._rev = response._rev;
96
+ finalData.push(row);
99
97
  }
98
+ yield db.bulkDocs(finalData);
99
+ let response = yield db.put(table);
100
+ table._rev = response._rev;
100
101
  return table;
101
102
  });
102
103
  exports.handleSearchIndexes = (appId, table) => __awaiter(void 0, void 0, void 0, function* () {
@@ -277,4 +278,37 @@ exports.checkForViewUpdates = (db, table, rename, deletedColumns) => __awaiter(v
277
278
  }
278
279
  }
279
280
  });
281
+ exports.generateForeignKey = (column, relatedTable) => {
282
+ return `fk_${relatedTable.name}_${column.fieldName}`;
283
+ };
284
+ exports.generateJunctionTableName = (column, table, relatedTable) => {
285
+ return `jt_${table.name}_${relatedTable.name}_${column.name}_${column.fieldName}`;
286
+ };
287
+ exports.foreignKeyStructure = (keyName, meta = null) => {
288
+ const structure = {
289
+ type: FieldTypes.NUMBER,
290
+ constraints: {},
291
+ name: keyName,
292
+ };
293
+ if (meta) {
294
+ structure.meta = meta;
295
+ }
296
+ return structure;
297
+ };
298
+ exports.hasTypeChanged = (table, oldTable) => {
299
+ if (!oldTable) {
300
+ return false;
301
+ }
302
+ for (let [key, field] of Object.entries(oldTable.schema)) {
303
+ const oldType = field.type;
304
+ if (!table.schema[key]) {
305
+ continue;
306
+ }
307
+ const newType = table.schema[key].type;
308
+ if (oldType !== newType && SwitchableTypes.indexOf(oldType) === -1) {
309
+ return true;
310
+ }
311
+ }
312
+ return false;
313
+ };
280
314
  exports.TableSaveFunctions = TableSaveFunctions;
@@ -11,22 +11,132 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  const CouchDB = require("../../db");
12
12
  const { generateUserMetadataID, getUserMetadataParams, } = require("../../db/utils");
13
13
  const { InternalTables } = require("../../db/utils");
14
- const { getGlobalUsers } = require("../../utilities/global");
14
+ const { getGlobalUsers, getRawGlobalUser } = require("../../utilities/global");
15
15
  const { getFullUser } = require("../../utilities/users");
16
- function removeGlobalProps(user) {
17
- // make sure to always remove some of the global user props
18
- delete user.password;
19
- delete user.roles;
20
- delete user.builder;
21
- return user;
16
+ const { isEqual } = require("lodash");
17
+ const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles");
18
+ const { getDevelopmentAppID, getDeployedAppIDs } = require("@budibase/auth/db");
19
+ const { doesDatabaseExist } = require("../../utilities");
20
+ const { UserStatus } = require("@budibase/auth/constants");
21
+ function rawMetadata(db) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ return (yield db.allDocs(getUserMetadataParams(null, {
24
+ include_docs: true,
25
+ }))).rows.map(row => row.doc);
26
+ });
27
+ }
28
+ function combineMetadataAndUser(user, metadata) {
29
+ // skip users with no access
30
+ if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) {
31
+ return null;
32
+ }
33
+ delete user._rev;
34
+ const metadataId = generateUserMetadataID(user._id);
35
+ const newDoc = Object.assign(Object.assign({}, user), { _id: metadataId, tableId: InternalTables.USER_METADATA });
36
+ const found = Array.isArray(metadata)
37
+ ? metadata.find(doc => doc._id === metadataId)
38
+ : metadata;
39
+ // copy rev over for the purposes of equality check
40
+ if (found) {
41
+ newDoc._rev = found._rev;
42
+ }
43
+ if (found == null || !isEqual(newDoc, found)) {
44
+ return Object.assign(Object.assign({}, found), newDoc);
45
+ }
46
+ return null;
22
47
  }
48
+ exports.syncGlobalUsers = (appId) => __awaiter(void 0, void 0, void 0, function* () {
49
+ // sync user metadata
50
+ const db = new CouchDB(appId);
51
+ const [users, metadata] = yield Promise.all([
52
+ getGlobalUsers(appId),
53
+ rawMetadata(db),
54
+ ]);
55
+ const toWrite = [];
56
+ for (let user of users) {
57
+ const combined = yield combineMetadataAndUser(user, metadata);
58
+ if (combined) {
59
+ toWrite.push(combined);
60
+ }
61
+ }
62
+ yield db.bulkDocs(toWrite);
63
+ });
64
+ exports.syncUser = function (ctx) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ let deleting = false, user;
67
+ const userId = ctx.params.id;
68
+ try {
69
+ user = yield getRawGlobalUser(userId);
70
+ }
71
+ catch (err) {
72
+ if (err && err.status === 404) {
73
+ user = {};
74
+ deleting = true;
75
+ }
76
+ else {
77
+ throw err;
78
+ }
79
+ }
80
+ const roles = user.roles;
81
+ // remove props which aren't useful to metadata
82
+ delete user.password;
83
+ delete user.forceResetPassword;
84
+ delete user.roles;
85
+ // run through all production appIDs in the users roles
86
+ let prodAppIds;
87
+ // if they are a builder then get all production app IDs
88
+ if ((user.builder && user.builder.global) || deleting) {
89
+ prodAppIds = yield getDeployedAppIDs(CouchDB);
90
+ }
91
+ else {
92
+ prodAppIds = Object.entries(roles)
93
+ .filter(entry => entry[1] !== BUILTIN_ROLE_IDS.PUBLIC)
94
+ .map(([appId]) => appId);
95
+ }
96
+ for (let prodAppId of prodAppIds) {
97
+ const roleId = roles[prodAppId];
98
+ const devAppId = getDevelopmentAppID(prodAppId);
99
+ for (let appId of [prodAppId, devAppId]) {
100
+ if (!(yield doesDatabaseExist(appId))) {
101
+ continue;
102
+ }
103
+ const db = new CouchDB(appId);
104
+ const metadataId = generateUserMetadataID(userId);
105
+ let metadata;
106
+ try {
107
+ metadata = yield db.get(metadataId);
108
+ }
109
+ catch (err) {
110
+ if (deleting) {
111
+ continue;
112
+ }
113
+ metadata = {
114
+ tableId: InternalTables.USER_METADATA,
115
+ };
116
+ }
117
+ // assign the roleId for the metadata doc
118
+ if (roleId) {
119
+ metadata.roleId = roleId;
120
+ }
121
+ let combined = !deleting
122
+ ? combineMetadataAndUser(user, metadata)
123
+ : Object.assign(Object.assign({}, metadata), { status: UserStatus.INACTIVE, metadata: BUILTIN_ROLE_IDS.PUBLIC });
124
+ // if its null then there was no updates required
125
+ if (combined) {
126
+ yield db.put(combined);
127
+ }
128
+ }
129
+ }
130
+ ctx.body = {
131
+ message: "User synced.",
132
+ };
133
+ });
134
+ };
23
135
  exports.fetchMetadata = function (ctx) {
24
136
  return __awaiter(this, void 0, void 0, function* () {
25
137
  const database = new CouchDB(ctx.appId);
26
138
  const global = yield getGlobalUsers(ctx.appId);
27
- const metadata = (yield database.allDocs(getUserMetadataParams(null, {
28
- include_docs: true,
29
- }))).rows.map(row => row.doc);
139
+ const metadata = yield rawMetadata(database);
30
140
  const users = [];
31
141
  for (let user of global) {
32
142
  // find the metadata that matches up to the global ID
@@ -52,7 +162,9 @@ exports.updateMetadata = function (ctx) {
52
162
  return __awaiter(this, void 0, void 0, function* () {
53
163
  const appId = ctx.appId;
54
164
  const db = new CouchDB(appId);
55
- const user = removeGlobalProps(ctx.request.body);
165
+ const user = ctx.request.body;
166
+ // this isn't applicable to the user
167
+ delete user.roles;
56
168
  const metadata = Object.assign({ tableId: InternalTables.USER_METADATA }, user);
57
169
  ctx.body = yield db.put(metadata);
58
170
  });
@@ -41,7 +41,7 @@ router
41
41
  .get("/api/queries", authorized(BUILDER), queryController.fetch)
42
42
  .post("/api/queries", bodySubResource("datasourceId", "_id"), authorized(BUILDER), generateQueryValidation(), queryController.save)
43
43
  .post("/api/queries/preview", bodyResource("datasourceId"), authorized(BUILDER), generateQueryPreviewValidation(), queryController.preview)
44
- .get("/api/queries/:queryId", authorized(PermissionTypes.QUERY, PermissionLevels.READ), queryController.find)
44
+ .get("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.READ), queryController.find)
45
45
  .post("/api/queries/:queryId", paramResource("queryId"), authorized(PermissionTypes.QUERY, PermissionLevels.WRITE), queryController.execute)
46
46
  .delete("/api/queries/:queryId/:revId", paramResource("queryId"), authorized(BUILDER), queryController.destroy);
47
47
  module.exports = router;
@@ -27,5 +27,11 @@ router
27
27
  // allows control over updating a table
28
28
  bodyResource("_id"), authorized(BUILDER), generateSaveValidator(), tableController.save)
29
29
  .post("/api/tables/csv/validate", authorized(BUILDER), tableController.validateCSVSchema)
30
- .delete("/api/tables/:tableId/:revId", paramResource("tableId"), authorized(BUILDER), tableController.destroy);
30
+ .delete("/api/tables/:tableId/:revId", paramResource("tableId"), authorized(BUILDER), tableController.destroy)
31
+ // this is currently builder only, but in the future
32
+ // it could be carried out by an end user in app,
33
+ // however some thought will need to be had about
34
+ // implications for automations (triggers)
35
+ // new trigger type, bulk rows created
36
+ .post("/api/tables/:tableId/import", paramResource("tableId"), authorized(BUILDER), tableController.bulkImport);
31
37
  module.exports = router;
@@ -9,5 +9,6 @@ router
9
9
  .get("/api/users/metadata/:id", authorized(PermissionTypes.USER, PermissionLevels.READ), controller.findMetadata)
10
10
  .put("/api/users/metadata", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.updateMetadata)
11
11
  .post("/api/users/metadata/self", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.updateSelfMetadata)
12
- .delete("/api/users/metadata/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.destroyMetadata);
12
+ .delete("/api/users/metadata/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.destroyMetadata)
13
+ .post("/api/users/metadata/sync/:id", authorized(PermissionTypes.USER, PermissionLevels.WRITE), controller.syncUser);
13
14
  module.exports = router;
package/dist/app.js CHANGED
@@ -41,17 +41,8 @@ app.use(pino({
41
41
  level: env.LOG_LEVEL || "error",
42
42
  }));
43
43
  if (!env.isTest()) {
44
- const bullApp = bullboard.init();
45
- app.use((ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
46
- if (ctx.path.startsWith(bullboard.pathPrefix)) {
47
- ctx.status = 200;
48
- ctx.respond = false;
49
- bullApp(ctx.req, ctx.res);
50
- }
51
- else {
52
- yield next();
53
- }
54
- }));
44
+ const plugin = bullboard.init();
45
+ app.use(plugin);
55
46
  }
56
47
  app.context.eventEmitter = eventEmitter;
57
48
  app.context.auth = {};
@@ -1,7 +1,16 @@
1
1
  "use strict";
2
- const { createBullBoard } = require("bull-board");
3
- const { BullAdapter } = require("bull-board/bullAdapter");
4
- const express = require("express");
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ const { createBullBoard } = require("@bull-board/api");
12
+ const { BullAdapter } = require("@bull-board/api/bullAdapter");
13
+ const { KoaAdapter } = require("@bull-board/koa");
5
14
  const env = require("../environment");
6
15
  const Queue = env.isTest()
7
16
  ? require("../utilities/queue/inMemoryQueue")
@@ -9,19 +18,37 @@ const Queue = env.isTest()
9
18
  const { JobQueues } = require("../constants");
10
19
  const { utils } = require("@budibase/auth/redis");
11
20
  const { opts, redisProtocolUrl } = utils.getRedisOptions();
12
- const redisConfig = redisProtocolUrl || { redis: opts };
13
- let automationQueue = new Queue(JobQueues.AUTOMATIONS, redisConfig);
14
- exports.pathPrefix = "/bulladmin";
21
+ const CLEANUP_PERIOD_MS = 60 * 1000;
22
+ const queueConfig = redisProtocolUrl || { redis: opts };
23
+ let cleanupInternal = null;
24
+ let automationQueue = new Queue(JobQueues.AUTOMATIONS, queueConfig);
25
+ function cleanup() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ yield automationQueue.clean(CLEANUP_PERIOD_MS, "completed");
28
+ });
29
+ }
30
+ const PATH_PREFIX = "/bulladmin";
15
31
  exports.init = () => {
16
- const expressApp = express();
32
+ // cleanup the events every 5 minutes
33
+ if (!cleanupInternal) {
34
+ cleanupInternal = setInterval(cleanup, CLEANUP_PERIOD_MS);
35
+ // fire off an initial cleanup
36
+ cleanup().catch(err => {
37
+ console.error(`Unable to cleanup automation queue initially - ${err}`);
38
+ });
39
+ }
17
40
  // Set up queues for bull board admin
18
41
  const queues = [automationQueue];
19
42
  const adapters = [];
43
+ const serverAdapter = new KoaAdapter();
20
44
  for (let queue of queues) {
21
45
  adapters.push(new BullAdapter(queue));
22
46
  }
23
- const { router } = createBullBoard(adapters);
24
- expressApp.use(exports.pathPrefix, router);
25
- return expressApp;
47
+ createBullBoard({
48
+ queues: adapters,
49
+ serverAdapter,
50
+ });
51
+ serverAdapter.setBasePath(PATH_PREFIX);
52
+ return serverAdapter.registerPlugin();
26
53
  };
27
54
  exports.queue = automationQueue;
@@ -20,6 +20,10 @@ const { checkTestFlag } = require("../utilities/redis");
20
20
  const utils = require("./utils");
21
21
  const env = require("../environment");
22
22
  const TRIGGER_DEFINITIONS = definitions;
23
+ const JOB_OPTS = {
24
+ removeOnComplete: true,
25
+ removeOnFail: true,
26
+ };
23
27
  function queueRelevantRowAutomations(event, eventType) {
24
28
  return __awaiter(this, void 0, void 0, function* () {
25
29
  if (event.appId == null) {
@@ -47,7 +51,7 @@ function queueRelevantRowAutomations(event, eventType) {
47
51
  }
48
52
  if (automationTrigger.inputs &&
49
53
  automationTrigger.inputs.tableId === event.row.tableId) {
50
- yield queue.add({ automation, event });
54
+ yield queue.add({ automation, event }, JOB_OPTS);
51
55
  }
52
56
  }
53
57
  });
@@ -85,7 +89,7 @@ exports.externalTrigger = function (automation, params, { getResponses } = {}) {
85
89
  automation.definition.trigger != null &&
86
90
  automation.definition.trigger.stepId === definitions.APP.stepId &&
87
91
  automation.definition.trigger.stepId === "APP" &&
88
- !checkTestFlag(automation._id)) {
92
+ !(yield checkTestFlag(automation._id))) {
89
93
  // values are likely to be submitted as strings, so we shall convert to correct type
90
94
  const coercedFields = {};
91
95
  const fields = automation.definition.trigger.inputs.fields;
@@ -99,7 +103,7 @@ exports.externalTrigger = function (automation, params, { getResponses } = {}) {
99
103
  return utils.processEvent({ data });
100
104
  }
101
105
  else {
102
- return queue.add(data);
106
+ return queue.add(data, JOB_OPTS);
103
107
  }
104
108
  });
105
109
  };
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- const runner = require("./thread");
11
+ const { Thread, ThreadType } = require("../threads");
12
12
  const { definitions } = require("./triggerInfo");
13
13
  const webhooks = require("../api/controllers/webhook");
14
14
  const CouchDB = require("../db");
@@ -19,10 +19,11 @@ const { MetadataTypes } = require("../constants");
19
19
  const { getDeployedAppID } = require("@budibase/auth/db");
20
20
  const WH_STEP_ID = definitions.WEBHOOK.stepId;
21
21
  const CRON_STEP_ID = definitions.CRON.stepId;
22
+ const Runner = new Thread(ThreadType.AUTOMATION);
22
23
  exports.processEvent = (job) => __awaiter(void 0, void 0, void 0, function* () {
23
24
  try {
24
25
  // need to actually await these so that an error can be captured properly
25
- return yield runner(job);
26
+ return yield Runner.run(job);
26
27
  }
27
28
  catch (err) {
28
29
  console.error(`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`);
@@ -146,3 +147,11 @@ exports.checkForWebhooks = ({ appId, oldAuto, newAuto }) => __awaiter(void 0, vo
146
147
  }
147
148
  return newAuto;
148
149
  });
150
+ /**
151
+ * When removing an app/unpublishing it need to make sure automations are cleaned up (cron).
152
+ * @param appId {string} the app that is being removed.
153
+ * @return {Promise<void>} clean is complete if this succeeds.
154
+ */
155
+ exports.cleanupAutomations = (appId) => __awaiter(void 0, void 0, void 0, function* () {
156
+ yield exports.disableAllCrons(appId);
157
+ });
@@ -41,6 +41,12 @@ exports.FieldTypes = {
41
41
  JSON: "json",
42
42
  INTERNAL: "internal",
43
43
  };
44
+ exports.SwitchableTypes = [
45
+ exports.FieldTypes.STRING,
46
+ exports.FieldTypes.OPTIONS,
47
+ exports.FieldTypes.NUMBER,
48
+ exports.FieldTypes.BOOLEAN,
49
+ ];
44
50
  exports.RelationshipTypes = {
45
51
  ONE_TO_MANY: "one-to-many",
46
52
  MANY_TO_ONE: "many-to-one",
@@ -56,6 +62,10 @@ exports.DataSourceOperation = {
56
62
  READ: "READ",
57
63
  UPDATE: "UPDATE",
58
64
  DELETE: "DELETE",
65
+ BULK_CREATE: "BULK_CREATE",
66
+ CREATE_TABLE: "CREATE_TABLE",
67
+ UPDATE_TABLE: "UPDATE_TABLE",
68
+ DELETE_TABLE: "DELETE_TABLE",
59
69
  };
60
70
  exports.SortDirection = {
61
71
  ASCENDING: "ASCENDING",
@@ -140,5 +150,8 @@ exports.MetadataTypes = {
140
150
  AUTOMATION_TEST_INPUT: "automationTestInput",
141
151
  AUTOMATION_TEST_HISTORY: "automationTestHistory",
142
152
  };
153
+ exports.BuildSchemaErrors = {
154
+ NO_KEY: "no_key",
155
+ };
143
156
  // pass through the list from the auth/core lib
144
157
  exports.ObjectStoreBuckets = ObjectStoreBuckets;
@@ -7,6 +7,10 @@ var Operation;
7
7
  Operation["READ"] = "READ";
8
8
  Operation["UPDATE"] = "UPDATE";
9
9
  Operation["DELETE"] = "DELETE";
10
+ Operation["BULK_CREATE"] = "BULK_CREATE";
11
+ Operation["CREATE_TABLE"] = "CREATE_TABLE";
12
+ Operation["UPDATE_TABLE"] = "UPDATE_TABLE";
13
+ Operation["DELETE_TABLE"] = "DELETE_TABLE";
10
14
  })(Operation = exports.Operation || (exports.Operation = {}));
11
15
  var SortDirection;
12
16
  (function (SortDirection) {
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });