@budibase/server 2.1.43-alpha.6 → 2.1.44

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 (809) hide show
  1. package/__mocks__/aws-sdk.ts +0 -14
  2. package/__mocks__/node-fetch.ts +1 -5
  3. package/builder/assets/index.2d05742a.js +1021 -0
  4. package/builder/assets/index.534f6c29.css +6 -0
  5. package/builder/index.html +2 -2
  6. package/coverage/clover.xml +3857 -10913
  7. package/coverage/coverage-final.json +118 -267
  8. package/coverage/lcov-report/{src/api/controllers/apikeys.ts.html → api/controllers/apikeys.js.html} +30 -30
  9. package/coverage/lcov-report/{src/api/controllers/automation.ts.html → api/controllers/automation.js.html} +99 -99
  10. package/coverage/lcov-report/{src/api/controllers/cloud.ts.html → api/controllers/cloud.js.html} +58 -58
  11. package/coverage/lcov-report/{src/api/controllers/datasource.ts.html → api/controllers/datasource.js.html} +107 -287
  12. package/coverage/lcov-report/{src/api/controllers/dev.ts.html → api/controllers/dev.js.html} +87 -69
  13. package/coverage/lcov-report/api/controllers/index.html +326 -0
  14. package/coverage/lcov-report/{src/middleware/selfhost.ts.html → api/controllers/integration.js.html} +28 -22
  15. package/coverage/lcov-report/{src/api/controllers/layout.ts.html → api/controllers/layout.js.html} +31 -31
  16. package/coverage/lcov-report/{src/api/controllers/metadata.ts.html → api/controllers/metadata.js.html} +30 -33
  17. package/coverage/lcov-report/{src/api/controllers/migrations.ts.html → api/controllers/migrations.js.html} +17 -20
  18. package/coverage/lcov-report/{src/api/controllers/permission.ts.html → api/controllers/permission.js.html} +79 -88
  19. package/coverage/lcov-report/{src/utilities/routing → api/controllers/query}/index.html +8 -8
  20. package/coverage/lcov-report/{src/api/controllers/query/validation.ts.html → api/controllers/query/validation.js.html} +25 -25
  21. package/coverage/lcov-report/{src/api/controllers/role.ts.html → api/controllers/role.js.html} +60 -48
  22. package/coverage/lcov-report/{src/api/controllers/routing.ts.html → api/controllers/routing.js.html} +58 -67
  23. package/coverage/lcov-report/{src/api/controllers/row/external.ts.html → api/controllers/row/external.js.html} +111 -162
  24. package/coverage/lcov-report/{src/api → api}/controllers/row/index.html +52 -82
  25. package/coverage/lcov-report/{src/api/controllers/row/internal.ts.html → api/controllers/row/internal.js.html} +121 -163
  26. package/coverage/lcov-report/{src/api/controllers/row/internalSearch.ts.html → api/controllers/row/internalSearch.js.html} +117 -189
  27. package/coverage/lcov-report/{src/api/controllers/row/staticFormula.ts.html → api/controllers/row/staticFormula.js.html} +58 -73
  28. package/coverage/lcov-report/{src/api/controllers/row/utils.ts.html → api/controllers/row/utils.js.html} +58 -88
  29. package/coverage/lcov-report/{src/api/controllers/script.ts.html → api/controllers/script.js.html} +16 -19
  30. package/coverage/lcov-report/{src/api/controllers/table/bulkFormula.ts.html → api/controllers/table/bulkFormula.js.html} +62 -104
  31. package/coverage/lcov-report/{src/api/controllers/table/external.ts.html → api/controllers/table/external.js.html} +111 -204
  32. package/coverage/lcov-report/{src/utilities/fileSystem → api/controllers/table}/index.html +44 -44
  33. package/coverage/lcov-report/{src/api/controllers/table/index.ts.html → api/controllers/table/index.js.html} +49 -58
  34. package/coverage/lcov-report/{src/api/controllers/templates.ts.html → api/controllers/templates.js.html} +29 -38
  35. package/coverage/lcov-report/{src/api/controllers/user.ts.html → api/controllers/user.js.html} +99 -93
  36. package/coverage/lcov-report/{src/api/controllers/view/exporters.ts.html → api/controllers/view/exporters.js.html} +16 -22
  37. package/coverage/lcov-report/{src/api → api}/controllers/view/index.html +36 -36
  38. package/coverage/lcov-report/{src/api/controllers/view/index.ts.html → api/controllers/view/index.js.html} +64 -91
  39. package/coverage/lcov-report/{src/api/controllers/view/utils.ts.html → api/controllers/view/utils.js.html} +54 -72
  40. package/coverage/lcov-report/{src/api/controllers/view/viewBuilder.ts.html → api/controllers/view/viewBuilder.js.html} +36 -78
  41. package/coverage/lcov-report/{src/api → api}/index.html +23 -23
  42. package/coverage/lcov-report/{src/api/index.ts.html → api/index.js.html} +76 -55
  43. package/coverage/lcov-report/{src/middleware/utils.ts.html → api/routes/analytics.js.html} +19 -19
  44. package/coverage/lcov-report/api/routes/apikeys.js.html +121 -0
  45. package/coverage/lcov-report/{src/api/routes/automation.ts.html → api/routes/automation.js.html} +47 -53
  46. package/coverage/lcov-report/{src/api/routes/backup.ts.html → api/routes/cloud.js.html} +28 -28
  47. package/coverage/lcov-report/{src/api/routes/component.ts.html → api/routes/component.js.html} +24 -24
  48. package/coverage/lcov-report/{src/definitions/datasource.ts.html → api/routes/datasource.js.html} +64 -61
  49. package/coverage/lcov-report/{src/api/routes/cloud.ts.html → api/routes/deploy.js.html} +28 -31
  50. package/coverage/lcov-report/{src/automations/index.ts.html → api/routes/dev.js.html} +46 -46
  51. package/coverage/lcov-report/{src/api → api}/routes/index.html +47 -167
  52. package/coverage/lcov-report/api/routes/integration.js.html +121 -0
  53. package/coverage/lcov-report/{src/db/index.ts.html → api/routes/layout.js.html} +28 -28
  54. package/coverage/lcov-report/{src/api/routes/metadata.ts.html → api/routes/metadata.js.html} +31 -31
  55. package/coverage/lcov-report/{src/sdk/index.ts.html → api/routes/migrations.js.html} +21 -24
  56. package/coverage/lcov-report/{src/api/routes/permission.ts.html → api/routes/permission.js.html} +31 -55
  57. package/coverage/lcov-report/{src/api/routes/query.ts.html → api/routes/query.js.html} +50 -41
  58. package/coverage/lcov-report/api/routes/role.js.html +130 -0
  59. package/coverage/lcov-report/{src/api/routes/routing.ts.html → api/routes/routing.js.html} +24 -24
  60. package/coverage/lcov-report/api/routes/screen.js.html +139 -0
  61. package/coverage/lcov-report/{src/api/routes/script.ts.html → api/routes/script.js.html} +17 -17
  62. package/coverage/lcov-report/{src/api/routes/table.ts.html → api/routes/table.js.html} +41 -32
  63. package/coverage/lcov-report/{src/api/routes/templates.ts.html → api/routes/templates.js.html} +25 -25
  64. package/coverage/lcov-report/{src/api/routes/user.ts.html → api/routes/user.js.html} +41 -35
  65. package/coverage/lcov-report/{src/api → api}/routes/utils/index.html +15 -15
  66. package/coverage/lcov-report/{src/api/routes/utils/validators.ts.html → api/routes/utils/validators.js.html} +98 -86
  67. package/coverage/lcov-report/{src/api/routes/view.ts.html → api/routes/view.js.html} +36 -45
  68. package/coverage/lcov-report/{src/automations/actions.ts.html → automations/actions.js.html} +60 -69
  69. package/coverage/lcov-report/{src/automations/automationUtils.ts.html → automations/automationUtils.js.html} +33 -36
  70. package/coverage/lcov-report/{src/automations/bullboard.ts.html → automations/bullboard.js.html} +42 -39
  71. package/coverage/lcov-report/{src/automations → automations}/index.html +48 -63
  72. package/coverage/lcov-report/{src/websocket.ts.html → automations/index.js.html} +50 -41
  73. package/coverage/lcov-report/{src/automations/steps/bash.ts.html → automations/steps/bash.js.html} +30 -45
  74. package/coverage/lcov-report/{src/automations/steps/delay.ts.html → automations/steps/delay.js.html} +19 -34
  75. package/coverage/lcov-report/{src/automations/steps/discord.ts.html → automations/steps/discord.js.html} +28 -43
  76. package/coverage/lcov-report/{src/automations/steps/executeQuery.ts.html → automations/steps/executeQuery.js.html} +30 -45
  77. package/coverage/lcov-report/{src/automations/steps/executeScript.ts.html → automations/steps/executeScript.js.html} +28 -58
  78. package/coverage/lcov-report/{src/automations/steps/filter.ts.html → automations/steps/filter.js.html} +30 -39
  79. package/coverage/lcov-report/automations/steps/index.html +341 -0
  80. package/coverage/lcov-report/{src/automations/steps/integromat.ts.html → automations/steps/integromat.js.html} +23 -38
  81. package/coverage/lcov-report/{src/automations/steps/loop.ts.html → automations/steps/loop.js.html} +15 -21
  82. package/coverage/lcov-report/{src/automations/steps/outgoingWebhook.ts.html → automations/steps/outgoingWebhook.js.html} +39 -54
  83. package/coverage/lcov-report/{src/automations/steps/queryRows.ts.html → automations/steps/queryRows.js.html} +66 -102
  84. package/coverage/lcov-report/{src/automations/steps/sendSmtpEmail.ts.html → automations/steps/sendSmtpEmail.js.html} +25 -40
  85. package/coverage/lcov-report/{src/automations/steps/serverLog.ts.html → automations/steps/serverLog.js.html} +22 -40
  86. package/coverage/lcov-report/{src/automations/steps/slack.ts.html → automations/steps/slack.js.html} +23 -38
  87. package/coverage/lcov-report/{src/automations/steps/updateRow.ts.html → automations/steps/updateRow.js.html} +25 -40
  88. package/coverage/lcov-report/{src/automations/steps/utils.ts.html → automations/steps/utils.js.html} +27 -45
  89. package/coverage/lcov-report/{src/automations/steps/zapier.ts.html → automations/steps/zapier.js.html} +23 -41
  90. package/coverage/lcov-report/{src/definitions/automations.ts.html → automations/triggerInfo/app.js.html} +42 -42
  91. package/coverage/lcov-report/{src/automations/triggerInfo/cron.ts.html → automations/triggerInfo/cron.js.html} +15 -30
  92. package/coverage/lcov-report/{src/automations → automations}/triggerInfo/index.html +31 -31
  93. package/coverage/lcov-report/{src/api/routes/layout.ts.html → automations/triggerInfo/index.js.html} +26 -29
  94. package/coverage/lcov-report/{src/automations/triggerInfo/rowDeleted.ts.html → automations/triggerInfo/rowDeleted.js.html} +15 -30
  95. package/coverage/lcov-report/{src/automations/triggerInfo/rowSaved.ts.html → automations/triggerInfo/rowSaved.js.html} +15 -30
  96. package/coverage/lcov-report/{src/automations/triggerInfo/rowUpdated.ts.html → automations/triggerInfo/rowUpdated.js.html} +15 -30
  97. package/coverage/lcov-report/{src/automations/triggerInfo/webhook.ts.html → automations/triggerInfo/webhook.js.html} +15 -30
  98. package/coverage/lcov-report/{src/automations/triggers.ts.html → automations/triggers.js.html} +66 -78
  99. package/coverage/lcov-report/{src/constants → constants}/index.html +26 -26
  100. package/coverage/lcov-report/{src/integrations/dynamodb.ts.html → constants/index.js.html} +227 -263
  101. package/coverage/lcov-report/{src/constants/layouts.ts.html → constants/layouts.js.html} +36 -18
  102. package/coverage/lcov-report/{src/constants/screens.ts.html → constants/screens.js.html} +58 -64
  103. package/coverage/lcov-report/{src/db/inMemoryView.ts.html → db/inMemoryView.js.html} +29 -47
  104. package/coverage/lcov-report/{src/db → db}/index.html +33 -48
  105. package/coverage/lcov-report/{src/api/routes/integration.ts.html → db/index.js.html} +33 -33
  106. package/coverage/lcov-report/{src/db/linkedRows/LinkController.ts.html → db/linkedRows/LinkController.js.html} +160 -97
  107. package/coverage/lcov-report/db/linkedRows/index.html +146 -0
  108. package/coverage/lcov-report/{src/db/linkedRows/index.ts.html → db/linkedRows/index.js.html} +78 -93
  109. package/coverage/lcov-report/{src/db/linkedRows/linkUtils.ts.html → db/linkedRows/linkUtils.js.html} +56 -83
  110. package/coverage/lcov-report/{src/db/newid.ts.html → db/newid.js.html} +14 -14
  111. package/coverage/lcov-report/{src/db/utils.ts.html → db/utils.js.html} +211 -163
  112. package/coverage/lcov-report/{src/events/AutomationEmitter.ts.html → events/AutomationEmitter.js.html} +25 -40
  113. package/coverage/lcov-report/{src/events → events}/index.html +33 -48
  114. package/coverage/lcov-report/{src/events/BudibaseEmitter.ts.html → events/index.js.html} +29 -26
  115. package/coverage/lcov-report/{src/api/routes/dev.ts.html → events/utils.js.html} +69 -69
  116. package/coverage/lcov-report/index.html +184 -679
  117. package/coverage/lcov-report/{src/integrations → integrations}/tests/TestConfiguration.js.html +10 -10
  118. package/coverage/lcov-report/{src/integrations → integrations}/tests/index.html +10 -10
  119. package/coverage/lcov-report/{src/middleware/appInfo.ts.html → middleware/appInfo.js.html} +30 -33
  120. package/coverage/lcov-report/{src/middleware/builder.ts.html → middleware/builder.js.html} +40 -46
  121. package/coverage/lcov-report/{src/middleware/currentapp.ts.html → middleware/currentapp.js.html} +72 -81
  122. package/coverage/lcov-report/{src/middleware → middleware}/index.html +63 -78
  123. package/coverage/lcov-report/{src/middleware/joi-validator.ts.html → middleware/joi-validator.js.html} +22 -25
  124. package/coverage/lcov-report/{src/middleware/publicApi.ts.html → middleware/publicApi.js.html} +27 -27
  125. package/coverage/lcov-report/{src/middleware/resourceId.ts.html → middleware/resourceId.js.html} +45 -60
  126. package/coverage/lcov-report/{src/tests/utilities/index.ts.html → middleware/selfhost.js.html} +30 -33
  127. package/coverage/lcov-report/{src/events/index.ts.html → middleware/utils.js.html} +24 -18
  128. package/coverage/lcov-report/{src/utilities/budibaseDir.ts.html → utilities/budibaseDir.js.html} +14 -14
  129. package/coverage/lcov-report/{src/utilities/centralPath.ts.html → utilities/centralPath.js.html} +16 -16
  130. package/coverage/lcov-report/{src/utilities/csvParser.ts.html → utilities/csvParser.js.html} +59 -107
  131. package/coverage/lcov-report/{src/utilities/global.ts.html → utilities/global.js.html} +82 -115
  132. package/coverage/lcov-report/{src/utilities → utilities}/index.html +77 -92
  133. package/coverage/lcov-report/{src/utilities/index.ts.html → utilities/index.js.html} +74 -98
  134. package/coverage/lcov-report/{src/utilities/plugins.ts.html → utilities/plugins.js.html} +22 -25
  135. package/coverage/lcov-report/{src/integrations/airtable.ts.html → utilities/queue/inMemoryQueue.js.html} +135 -213
  136. package/coverage/lcov-report/{src/migrations → utilities/queue}/index.html +23 -23
  137. package/coverage/lcov-report/{src/sdk → utilities/routing}/index.html +10 -10
  138. package/coverage/lcov-report/{src/api/controllers/public/mapping/tables.ts.html → utilities/routing/index.js.html} +43 -46
  139. package/coverage/lcov-report/{src/definitions → utilities/rowProcessor}/index.html +34 -34
  140. package/coverage/lcov-report/{src/utilities/rowProcessor/index.ts.html → utilities/rowProcessor/index.js.html} +359 -128
  141. package/coverage/lcov-report/{src/utilities/rowProcessor/utils.ts.html → utilities/rowProcessor/utils.js.html} +42 -54
  142. package/coverage/lcov-report/{src/utilities/scriptRunner.ts.html → utilities/scriptRunner.js.html} +19 -31
  143. package/coverage/lcov-report/{src/utilities/security.ts.html → utilities/security.js.html} +78 -60
  144. package/coverage/lcov-report/{src/utilities/statusCodes.ts.html → utilities/statusCodes.js.html} +11 -11
  145. package/coverage/lcov-report/{src/utilities → utilities}/usageQuota/index.html +28 -28
  146. package/coverage/lcov-report/{src/utilities/usageQuota/rows.ts.html → utilities/usageQuota/rows.js.html} +48 -36
  147. package/coverage/lcov-report/{src/utilities/usageQuota/usageQuoteReset.ts.html → utilities/usageQuota/usageQuoteReset.js.html} +13 -13
  148. package/coverage/lcov-report/{src/utilities/users.ts.html → utilities/users.js.html} +40 -34
  149. package/coverage/lcov-report/{src/utilities/workerRequests.ts.html → utilities/workerRequests.js.html} +112 -127
  150. package/coverage/lcov.info +7069 -19757
  151. package/dist/api/controllers/apikeys.js +9 -12
  152. package/dist/api/controllers/application.js +45 -48
  153. package/dist/api/controllers/automation.js +82 -122
  154. package/dist/api/controllers/cloud.js +71 -84
  155. package/dist/api/controllers/component.js +2 -4
  156. package/dist/api/controllers/datasource.js +94 -151
  157. package/dist/api/controllers/deploy/Deployment.js +6 -10
  158. package/dist/api/controllers/deploy/index.js +16 -13
  159. package/dist/api/controllers/dev.js +81 -96
  160. package/dist/api/controllers/integration.js +8 -11
  161. package/dist/api/controllers/layout.js +15 -18
  162. package/dist/api/controllers/metadata.js +37 -51
  163. package/dist/api/controllers/migrations.js +11 -19
  164. package/dist/api/controllers/permission.js +43 -52
  165. package/dist/api/controllers/plugin/index.js +7 -6
  166. package/dist/api/controllers/plugin/utils.js +1 -2
  167. package/dist/api/controllers/public/applications.js +9 -17
  168. package/dist/api/controllers/public/tables.js +9 -29
  169. package/dist/api/controllers/public/utils.js +2 -2
  170. package/dist/api/controllers/query/import/index.js +2 -1
  171. package/dist/api/controllers/query/index.js +13 -10
  172. package/dist/api/controllers/query/validation.js +33 -41
  173. package/dist/api/controllers/role.js +27 -29
  174. package/dist/api/controllers/routing.js +58 -71
  175. package/dist/api/controllers/row/ExternalRequest.js +542 -539
  176. package/dist/api/controllers/row/external.js +190 -258
  177. package/dist/api/controllers/row/index.js +14 -43
  178. package/dist/api/controllers/row/internal.js +295 -354
  179. package/dist/api/controllers/row/internalSearch.js +80 -95
  180. package/dist/api/controllers/row/staticFormula.js +112 -125
  181. package/dist/api/controllers/row/utils.js +84 -122
  182. package/dist/api/controllers/screen.js +66 -81
  183. package/dist/api/controllers/script.js +6 -13
  184. package/dist/api/controllers/static/index.js +14 -11
  185. package/dist/api/controllers/table/bulkFormula.js +35 -47
  186. package/dist/api/controllers/table/external.js +53 -89
  187. package/dist/api/controllers/table/index.js +31 -64
  188. package/dist/api/controllers/table/internal.js +6 -5
  189. package/dist/api/controllers/table/utils.js +35 -39
  190. package/dist/api/controllers/templates.js +10 -17
  191. package/dist/api/controllers/user.js +70 -82
  192. package/dist/api/controllers/view/exporters.js +4 -8
  193. package/dist/api/controllers/view/index.js +153 -201
  194. package/dist/api/controllers/view/utils.js +121 -151
  195. package/dist/api/controllers/view/viewBuilder.js +16 -4
  196. package/dist/api/controllers/webhook.js +2 -25
  197. package/dist/api/index.js +34 -38
  198. package/dist/api/routes/analytics.js +3 -29
  199. package/dist/api/routes/apikeys.js +7 -33
  200. package/dist/api/routes/application.js +9 -8
  201. package/dist/api/routes/auth.js +2 -1
  202. package/dist/api/routes/automation.js +20 -46
  203. package/dist/api/routes/backup.js +4 -3
  204. package/dist/api/routes/cloud.js +6 -32
  205. package/dist/api/routes/component.js +6 -32
  206. package/dist/api/routes/datasource.js +13 -39
  207. package/dist/api/routes/deploy.js +8 -34
  208. package/dist/api/routes/dev.js +10 -36
  209. package/dist/api/routes/integration.js +7 -33
  210. package/dist/api/routes/layout.js +7 -33
  211. package/dist/api/routes/metadata.js +10 -36
  212. package/dist/api/routes/migrations.js +6 -32
  213. package/dist/api/routes/permission.js +12 -38
  214. package/dist/api/routes/plugin.js +5 -5
  215. package/dist/api/routes/public/index.js +11 -11
  216. package/dist/api/routes/query.js +15 -42
  217. package/dist/api/routes/role.js +10 -36
  218. package/dist/api/routes/routing.js +6 -32
  219. package/dist/api/routes/row.js +11 -12
  220. package/dist/api/routes/screen.js +9 -35
  221. package/dist/api/routes/script.js +6 -32
  222. package/dist/api/routes/static.js +9 -9
  223. package/dist/api/routes/table.js +13 -40
  224. package/dist/api/routes/templates.js +7 -33
  225. package/dist/api/routes/tests/utilities/TestFunctions.js +8 -6
  226. package/dist/api/routes/tests/utilities/index.js +32 -69
  227. package/dist/api/routes/user.js +13 -40
  228. package/dist/api/routes/utils/validators.js +126 -142
  229. package/dist/api/routes/view.js +12 -38
  230. package/dist/api/routes/webhook.js +2 -1
  231. package/dist/app.js +22 -22
  232. package/dist/automations/actions.js +24 -53
  233. package/dist/automations/automationUtils.js +19 -31
  234. package/dist/automations/bullboard.js +29 -59
  235. package/dist/automations/index.js +18 -23
  236. package/dist/automations/steps/bash.js +10 -40
  237. package/dist/automations/steps/createRow.js +1 -2
  238. package/dist/automations/steps/delay.js +5 -9
  239. package/dist/automations/steps/deleteRow.js +1 -2
  240. package/dist/automations/steps/discord.js +7 -14
  241. package/dist/automations/steps/executeQuery.js +7 -34
  242. package/dist/automations/steps/executeScript.js +7 -34
  243. package/dist/automations/steps/filter.js +18 -20
  244. package/dist/automations/steps/integromat.js +7 -14
  245. package/dist/automations/steps/loop.js +1 -4
  246. package/dist/automations/steps/outgoingWebhook.js +14 -45
  247. package/dist/automations/steps/queryRows.js +38 -71
  248. package/dist/automations/steps/sendSmtpEmail.js +6 -33
  249. package/dist/automations/steps/serverLog.js +8 -12
  250. package/dist/automations/steps/slack.js +7 -14
  251. package/dist/automations/steps/updateRow.js +7 -34
  252. package/dist/automations/steps/utils.js +16 -22
  253. package/dist/automations/steps/zapier.js +7 -15
  254. package/dist/automations/tests/utilities/index.js +38 -62
  255. package/dist/automations/triggerInfo/app.js +1 -4
  256. package/dist/automations/triggerInfo/cron.js +1 -4
  257. package/dist/automations/triggerInfo/index.js +6 -31
  258. package/dist/automations/triggerInfo/rowDeleted.js +1 -4
  259. package/dist/automations/triggerInfo/rowSaved.js +1 -4
  260. package/dist/automations/triggerInfo/rowUpdated.js +1 -4
  261. package/dist/automations/triggerInfo/webhook.js +1 -4
  262. package/dist/automations/triggers.js +57 -90
  263. package/dist/automations/utils.js +8 -9
  264. package/dist/constants/index.js +104 -118
  265. package/dist/constants/layouts.js +10 -7
  266. package/dist/constants/screens.js +44 -49
  267. package/dist/db/dynamoClient.js +20 -20
  268. package/dist/db/inMemoryView.js +38 -47
  269. package/dist/db/index.js +4 -7
  270. package/dist/db/linkedRows/LinkController.js +70 -51
  271. package/dist/db/linkedRows/index.js +81 -93
  272. package/dist/db/linkedRows/linkUtils.js +32 -42
  273. package/dist/db/utils.js +119 -146
  274. package/dist/db/views/staticViews.js +74 -91
  275. package/dist/environment.js +6 -9
  276. package/dist/events/AutomationEmitter.js +10 -13
  277. package/dist/events/index.js +23 -5
  278. package/dist/events/utils.js +10 -18
  279. package/dist/integrations/elasticsearch.js +2 -26
  280. package/dist/integrations/googlesheets.js +6 -5
  281. package/dist/integrations/index.js +6 -15
  282. package/dist/integrations/microsoftSqlServer.js +3 -8
  283. package/dist/integrations/oracle.js +1 -8
  284. package/dist/integrations/postgres.js +3 -6
  285. package/dist/integrations/s3.js +1 -157
  286. package/dist/integrations/tests/TestConfiguration.js +1 -0
  287. package/dist/middleware/appInfo.js +9 -14
  288. package/dist/middleware/authorized.js +21 -22
  289. package/dist/middleware/builder.js +40 -41
  290. package/dist/middleware/currentapp.js +37 -39
  291. package/dist/middleware/joi-validator.js +10 -17
  292. package/dist/middleware/publicApi.js +6 -5
  293. package/dist/middleware/resourceId.js +9 -16
  294. package/dist/middleware/selfhost.js +4 -5
  295. package/dist/middleware/utils.js +2 -5
  296. package/dist/migrations/functions/appUrls.js +2 -2
  297. package/dist/migrations/functions/backfill/global.js +1 -1
  298. package/dist/migrations/functions/usageQuotas/syncApps.js +4 -3
  299. package/dist/migrations/functions/usageQuotas/syncRows.js +4 -3
  300. package/dist/migrations/functions/userEmailViewCasing.js +3 -3
  301. package/dist/migrations/index.js +0 -5
  302. package/dist/package.json +45 -11
  303. package/dist/sdk/app/backups/exports.js +2 -1
  304. package/dist/sdk/app/backups/imports.js +3 -2
  305. package/dist/sdk/app/tables/index.js +5 -5
  306. package/dist/startup.js +10 -10
  307. package/dist/tests/utilities/TestConfiguration.js +87 -111
  308. package/dist/tests/utilities/controllers.js +15 -38
  309. package/dist/tests/utilities/structures.js +53 -72
  310. package/dist/threads/automation.js +27 -49
  311. package/dist/threads/query.js +19 -17
  312. package/dist/threads/utils.js +8 -33
  313. package/dist/tsconfig.build.tsbuildinfo +1 -1
  314. package/dist/utilities/budibaseDir.js +2 -4
  315. package/dist/utilities/centralPath.js +7 -14
  316. package/dist/utilities/csvParser.js +21 -27
  317. package/dist/utilities/fileSystem/clientLibrary.js +73 -87
  318. package/dist/utilities/fileSystem/index.js +175 -203
  319. package/dist/utilities/fileSystem/processor.js +3 -8
  320. package/dist/utilities/fileSystem/utilities.js +22 -0
  321. package/dist/utilities/global.js +66 -87
  322. package/dist/utilities/index.js +75 -102
  323. package/dist/utilities/plugins.js +9 -15
  324. package/dist/utilities/queue/inMemoryQueue.js +126 -0
  325. package/dist/utilities/redis.js +65 -100
  326. package/dist/utilities/routing/index.js +23 -27
  327. package/dist/utilities/rowProcessor/index.js +191 -133
  328. package/dist/utilities/rowProcessor/utils.js +26 -35
  329. package/dist/utilities/scriptRunner.js +5 -8
  330. package/dist/utilities/security.js +35 -39
  331. package/dist/utilities/usageQuota/rows.js +49 -56
  332. package/dist/utilities/users.js +28 -31
  333. package/dist/utilities/workerRequests.js +82 -115
  334. package/dist/watch.js +2 -1
  335. package/package.json +46 -12
  336. package/scripts/exportAppTemplate.js +2 -2
  337. package/scripts/integrations/mssql/data/setup.sql +3 -3
  338. package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +2 -11
  339. package/scripts/localdomain.js +6 -34
  340. package/src/api/controllers/{apikeys.ts → apikeys.js} +10 -10
  341. package/src/api/controllers/application.ts +42 -56
  342. package/src/api/controllers/auth.ts +3 -4
  343. package/src/api/controllers/{automation.ts → automation.js} +48 -48
  344. package/src/api/controllers/{cloud.ts → cloud.js} +24 -24
  345. package/src/api/controllers/component.ts +1 -2
  346. package/src/api/controllers/{datasource.ts → datasource.js} +49 -109
  347. package/src/api/controllers/deploy/{Deployment.ts → Deployment.js} +10 -13
  348. package/src/api/controllers/deploy/index.ts +25 -13
  349. package/src/api/controllers/{dev.ts → dev.js} +37 -31
  350. package/src/api/controllers/integration.js +14 -0
  351. package/src/api/controllers/{layout.ts → layout.js} +8 -8
  352. package/src/api/controllers/{metadata.ts → metadata.js} +10 -11
  353. package/src/api/controllers/migrations.js +13 -0
  354. package/src/api/controllers/{permission.ts → permission.js} +46 -49
  355. package/src/api/controllers/plugin/index.ts +5 -4
  356. package/src/api/controllers/plugin/utils.ts +5 -3
  357. package/src/api/controllers/public/applications.ts +9 -15
  358. package/src/api/controllers/public/rows.ts +1 -1
  359. package/src/api/controllers/public/tables.ts +2 -2
  360. package/src/api/controllers/public/utils.ts +2 -2
  361. package/src/api/controllers/query/import/index.ts +3 -2
  362. package/src/api/controllers/query/index.ts +14 -11
  363. package/src/api/controllers/query/{validation.ts → validation.js} +7 -7
  364. package/src/api/controllers/{role.ts → role.js} +25 -21
  365. package/src/api/controllers/{routing.ts → routing.js} +34 -37
  366. package/src/api/controllers/row/ExternalRequest.ts +624 -605
  367. package/src/api/controllers/row/{external.ts → external.js} +62 -79
  368. package/src/api/controllers/row/index.ts +11 -19
  369. package/src/api/controllers/row/{internal.ts → internal.js} +73 -87
  370. package/src/api/controllers/row/{internalSearch.ts → internalSearch.js} +68 -92
  371. package/src/api/controllers/row/{staticFormula.ts → staticFormula.js} +25 -30
  372. package/src/api/controllers/row/{utils.ts → utils.js} +22 -32
  373. package/src/api/controllers/screen.ts +6 -10
  374. package/src/api/controllers/script.js +11 -0
  375. package/src/api/controllers/static/index.ts +16 -14
  376. package/src/api/controllers/table/{bulkFormula.ts → bulkFormula.js} +25 -39
  377. package/src/api/controllers/table/{external.ts → external.js} +55 -86
  378. package/src/api/controllers/table/{index.ts → index.js} +18 -21
  379. package/src/api/controllers/table/internal.ts +6 -5
  380. package/src/api/controllers/table/utils.ts +21 -26
  381. package/src/api/controllers/{templates.ts → templates.js} +7 -10
  382. package/src/api/controllers/{user.ts → user.js} +49 -47
  383. package/src/api/controllers/view/{exporters.ts → exporters.js} +3 -5
  384. package/src/api/controllers/view/{index.ts → index.js} +27 -36
  385. package/src/api/controllers/view/{utils.ts → utils.js} +20 -26
  386. package/src/api/controllers/view/{viewBuilder.ts → viewBuilder.js} +11 -25
  387. package/src/api/controllers/webhook.ts +1 -1
  388. package/src/api/{index.ts → index.js} +22 -15
  389. package/src/api/routes/analytics.js +9 -0
  390. package/src/api/routes/apikeys.js +12 -0
  391. package/src/api/routes/application.ts +9 -17
  392. package/src/api/routes/auth.ts +2 -2
  393. package/src/api/routes/automation.js +85 -0
  394. package/src/api/routes/backup.ts +4 -8
  395. package/src/api/routes/cloud.js +14 -0
  396. package/src/api/routes/component.js +14 -0
  397. package/src/api/routes/datasource.js +51 -0
  398. package/src/api/routes/deploy.js +17 -0
  399. package/src/api/routes/dev.js +26 -0
  400. package/src/api/routes/integration.js +12 -0
  401. package/src/api/routes/layout.js +16 -0
  402. package/src/api/routes/{metadata.ts → metadata.js} +13 -13
  403. package/src/api/routes/migrations.js +14 -0
  404. package/src/api/routes/permission.js +33 -0
  405. package/src/api/routes/plugin.ts +6 -14
  406. package/src/api/routes/public/index.ts +14 -11
  407. package/src/api/routes/public/tests/compare.spec.js +1 -1
  408. package/src/api/routes/{query.ts → query.js} +22 -19
  409. package/src/api/routes/role.js +15 -0
  410. package/src/api/routes/routing.js +14 -0
  411. package/src/api/routes/row.ts +15 -13
  412. package/src/api/routes/screen.js +18 -0
  413. package/src/api/routes/script.js +10 -0
  414. package/src/api/routes/static.ts +10 -7
  415. package/src/api/routes/{table.ts → table.js} +13 -10
  416. package/src/api/routes/templates.js +16 -0
  417. package/src/api/routes/tests/analytics.spec.js +1 -1
  418. package/src/api/routes/tests/backup.spec.js +1 -9
  419. package/src/api/routes/tests/deployment.spec.ts +1 -1
  420. package/src/api/routes/tests/permissions.spec.js +1 -2
  421. package/src/api/routes/tests/query.spec.js +10 -15
  422. package/src/api/routes/tests/role.spec.js +9 -7
  423. package/src/api/routes/tests/routing.spec.js +1 -2
  424. package/src/api/routes/tests/row.spec.js +4 -3
  425. package/src/api/routes/tests/static.spec.js +2 -2
  426. package/src/api/routes/tests/table.spec.js +36 -40
  427. package/src/api/routes/tests/user.spec.js +1 -2
  428. package/src/api/routes/tests/utilities/TestFunctions.ts +8 -6
  429. package/src/api/routes/tests/utilities/{index.ts → index.js} +12 -12
  430. package/src/api/routes/tests/view.spec.js +3 -3
  431. package/src/api/routes/user.js +53 -0
  432. package/src/api/routes/utils/{validators.ts → validators.js} +37 -33
  433. package/src/api/routes/view.js +31 -0
  434. package/src/api/routes/webhook.ts +2 -2
  435. package/src/app.ts +14 -15
  436. package/src/automations/{actions.ts → actions.js} +23 -26
  437. package/src/automations/{automationUtils.ts → automationUtils.js} +12 -13
  438. package/src/automations/bullboard.js +39 -0
  439. package/src/automations/index.js +29 -0
  440. package/src/automations/steps/{bash.ts → bash.js} +8 -13
  441. package/src/automations/steps/createRow.ts +3 -8
  442. package/src/automations/steps/{delay.ts → delay.js} +4 -9
  443. package/src/automations/steps/deleteRow.ts +3 -8
  444. package/src/automations/steps/{discord.ts → discord.js} +5 -10
  445. package/src/automations/steps/{executeQuery.ts → executeQuery.js} +7 -12
  446. package/src/automations/steps/{executeScript.ts → executeScript.js} +7 -17
  447. package/src/automations/steps/{filter.ts → filter.js} +9 -12
  448. package/src/automations/steps/{integromat.ts → integromat.js} +5 -10
  449. package/src/automations/steps/{loop.ts → loop.js} +2 -4
  450. package/src/automations/steps/{outgoingWebhook.ts → outgoingWebhook.js} +13 -18
  451. package/src/automations/steps/{queryRows.ts → queryRows.js} +36 -48
  452. package/src/automations/steps/{sendSmtpEmail.ts → sendSmtpEmail.js} +5 -10
  453. package/src/automations/steps/{serverLog.ts → serverLog.js} +3 -9
  454. package/src/automations/steps/{slack.ts → slack.js} +5 -10
  455. package/src/automations/steps/{updateRow.ts → updateRow.js} +7 -12
  456. package/src/automations/steps/{utils.ts → utils.js} +4 -10
  457. package/src/automations/steps/{zapier.ts → zapier.js} +5 -11
  458. package/src/automations/tests/updateRow.spec.js +1 -0
  459. package/src/automations/tests/utilities/index.js +51 -0
  460. package/src/automations/triggerInfo/{app.ts → app.js} +2 -7
  461. package/src/automations/triggerInfo/{cron.ts → cron.js} +2 -7
  462. package/src/automations/triggerInfo/index.js +15 -0
  463. package/src/automations/triggerInfo/{rowDeleted.ts → rowDeleted.js} +2 -7
  464. package/src/automations/triggerInfo/{rowSaved.ts → rowSaved.js} +2 -7
  465. package/src/automations/triggerInfo/{rowUpdated.ts → rowUpdated.js} +2 -7
  466. package/src/automations/triggerInfo/{webhook.ts → webhook.js} +2 -7
  467. package/src/automations/{triggers.ts → triggers.js} +26 -30
  468. package/src/automations/utils.ts +12 -9
  469. package/src/constants/index.js +208 -0
  470. package/src/constants/{layouts.ts → layouts.js} +9 -3
  471. package/src/constants/screens.js +46 -0
  472. package/src/db/{dynamoClient.ts → dynamoClient.js} +19 -39
  473. package/src/db/{inMemoryView.ts → inMemoryView.js} +9 -15
  474. package/src/db/index.js +16 -0
  475. package/src/db/linkedRows/{LinkController.ts → LinkController.js} +85 -64
  476. package/src/db/linkedRows/{index.ts → index.js} +38 -43
  477. package/src/db/linkedRows/{linkUtils.ts → linkUtils.js} +24 -33
  478. package/src/db/{newid.ts → newid.js} +1 -1
  479. package/src/db/tests/linkController.spec.js +57 -73
  480. package/src/db/tests/linkTests.spec.js +14 -17
  481. package/src/db/{utils.ts → utils.js} +93 -77
  482. package/src/db/views/{staticViews.ts → staticViews.js} +13 -20
  483. package/src/{environment.ts → environment.js} +7 -11
  484. package/src/events/{AutomationEmitter.ts → AutomationEmitter.js} +7 -12
  485. package/src/events/{BudibaseEmitter.ts → index.js} +8 -7
  486. package/src/events/utils.js +38 -0
  487. package/src/integrations/base/sql.ts +1 -1
  488. package/src/integrations/base/sqlTable.ts +1 -1
  489. package/src/integrations/elasticsearch.ts +2 -32
  490. package/src/integrations/googlesheets.ts +7 -5
  491. package/src/integrations/index.ts +41 -45
  492. package/src/integrations/microsoftSqlServer.ts +12 -14
  493. package/src/integrations/mysql.ts +3 -4
  494. package/src/integrations/oracle.ts +46 -17
  495. package/src/integrations/postgres.ts +2 -8
  496. package/src/integrations/s3.ts +3 -179
  497. package/src/integrations/tests/s3.spec.ts +1 -85
  498. package/src/integrations/utils.ts +2 -6
  499. package/src/middleware/appInfo.js +19 -0
  500. package/src/middleware/authorized.ts +28 -21
  501. package/src/middleware/{builder.ts → builder.js} +15 -17
  502. package/src/middleware/{currentapp.ts → currentapp.js} +39 -42
  503. package/src/middleware/{joi-validator.ts → joi-validator.js} +8 -9
  504. package/src/middleware/publicApi.js +21 -0
  505. package/src/middleware/{resourceId.ts → resourceId.js} +11 -16
  506. package/src/middleware/{selfhost.ts → selfhost.js} +2 -4
  507. package/src/middleware/tests/authorized.spec.js +6 -5
  508. package/src/middleware/tests/currentapp.spec.js +63 -118
  509. package/src/middleware/{utils.ts → utils.js} +1 -3
  510. package/src/migrations/functions/appUrls.ts +2 -2
  511. package/src/migrations/functions/backfill/app/tables.ts +5 -2
  512. package/src/migrations/functions/backfill/global.ts +1 -1
  513. package/src/migrations/functions/tests/appUrls.spec.js +4 -4
  514. package/src/migrations/functions/tests/userEmailViewCasing.spec.js +9 -14
  515. package/src/migrations/functions/usageQuotas/syncApps.ts +4 -3
  516. package/src/migrations/functions/usageQuotas/syncRows.ts +5 -4
  517. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +7 -7
  518. package/src/migrations/functions/userEmailViewCasing.ts +3 -3
  519. package/src/migrations/index.ts +0 -9
  520. package/src/migrations/tests/index.spec.ts +1 -1
  521. package/src/module.d.ts +14 -0
  522. package/src/sdk/app/backups/exports.ts +3 -5
  523. package/src/sdk/app/backups/imports.ts +14 -7
  524. package/src/sdk/app/backups/statistics.ts +18 -9
  525. package/src/sdk/app/tables/index.ts +8 -7
  526. package/src/startup.ts +5 -5
  527. package/src/tests/utilities/{TestConfiguration.ts → TestConfiguration.js} +78 -111
  528. package/src/tests/utilities/controllers.js +16 -0
  529. package/src/tests/utilities/{index.ts → index.js} +2 -2
  530. package/src/tests/utilities/{structures.ts → structures.js} +36 -41
  531. package/src/threads/automation.ts +19 -18
  532. package/src/threads/query.ts +16 -11
  533. package/src/threads/utils.ts +5 -4
  534. package/src/utilities/budibaseDir.js +3 -0
  535. package/src/utilities/{centralPath.ts → centralPath.js} +3 -3
  536. package/src/utilities/{csvParser.ts → csvParser.js} +26 -42
  537. package/src/utilities/fileSystem/{clientLibrary.ts → clientLibrary.js} +20 -20
  538. package/src/utilities/fileSystem/{index.ts → index.js} +65 -61
  539. package/src/utilities/fileSystem/{processor.ts → processor.js} +5 -3
  540. package/src/utilities/fileSystem/utilities.js +36 -0
  541. package/src/utilities/global.js +127 -0
  542. package/src/utilities/{index.ts → index.js} +32 -40
  543. package/src/utilities/{plugins.ts → plugins.js} +4 -5
  544. package/src/utilities/queue/inMemoryQueue.js +122 -0
  545. package/src/utilities/{redis.ts → redis.js} +20 -21
  546. package/src/utilities/routing/index.js +25 -0
  547. package/src/utilities/rowProcessor/{index.ts → index.js} +144 -67
  548. package/src/utilities/rowProcessor/{utils.ts → utils.js} +15 -19
  549. package/src/utilities/{scriptRunner.ts → scriptRunner.js} +4 -8
  550. package/src/utilities/security.js +71 -0
  551. package/src/utilities/{statusCodes.ts → statusCodes.js} +1 -1
  552. package/src/utilities/usageQuota/{rows.ts → rows.js} +18 -14
  553. package/src/utilities/usageQuota/{usageQuoteReset.ts → usageQuoteReset.js} +1 -1
  554. package/src/utilities/{users.ts → users.js} +13 -11
  555. package/src/utilities/{workerRequests.ts → workerRequests.js} +38 -43
  556. package/src/watch.ts +3 -2
  557. package/tsconfig.build.json +2 -1
  558. package/tsconfig.json +1 -3
  559. package/builder/assets/index.0c44dac3.css +0 -6
  560. package/builder/assets/index.e19dcc8e.js +0 -1021
  561. package/coverage/lcov-report/src/api/controllers/analytics.ts.html +0 -190
  562. package/coverage/lcov-report/src/api/controllers/application.ts.html +0 -2038
  563. package/coverage/lcov-report/src/api/controllers/auth.ts.html +0 -301
  564. package/coverage/lcov-report/src/api/controllers/backup.ts.html +0 -148
  565. package/coverage/lcov-report/src/api/controllers/component.ts.html +0 -259
  566. package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +0 -259
  567. package/coverage/lcov-report/src/api/controllers/deploy/index.html +0 -131
  568. package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +0 -730
  569. package/coverage/lcov-report/src/api/controllers/index.html +0 -431
  570. package/coverage/lcov-report/src/api/controllers/integration.ts.html +0 -124
  571. package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +0 -130
  572. package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +0 -310
  573. package/coverage/lcov-report/src/api/controllers/plugin/index.html +0 -206
  574. package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +0 -484
  575. package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +0 -253
  576. package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +0 -97
  577. package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +0 -121
  578. package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +0 -136
  579. package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +0 -334
  580. package/coverage/lcov-report/src/api/controllers/public/index.html +0 -191
  581. package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +0 -181
  582. package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +0 -191
  583. package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +0 -124
  584. package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +0 -202
  585. package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +0 -178
  586. package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +0 -181
  587. package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +0 -145
  588. package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +0 -328
  589. package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +0 -253
  590. package/coverage/lcov-report/src/api/controllers/public/users.ts.html +0 -268
  591. package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +0 -220
  592. package/coverage/lcov-report/src/api/controllers/query/import/index.html +0 -116
  593. package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +0 -373
  594. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +0 -131
  595. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +0 -379
  596. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +0 -157
  597. package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +0 -403
  598. package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +0 -146
  599. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +0 -586
  600. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +0 -712
  601. package/coverage/lcov-report/src/api/controllers/query/index.html +0 -131
  602. package/coverage/lcov-report/src/api/controllers/query/index.ts.html +0 -976
  603. package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +0 -2269
  604. package/coverage/lcov-report/src/api/controllers/row/index.ts.html +0 -541
  605. package/coverage/lcov-report/src/api/controllers/screen.ts.html +0 -463
  606. package/coverage/lcov-report/src/api/controllers/static/index.html +0 -116
  607. package/coverage/lcov-report/src/api/controllers/static/index.ts.html +0 -694
  608. package/coverage/lcov-report/src/api/controllers/table/index.html +0 -176
  609. package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +0 -661
  610. package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +0 -1255
  611. package/coverage/lcov-report/src/api/controllers/webhook.ts.html +0 -379
  612. package/coverage/lcov-report/src/api/routes/analytics.ts.html +0 -112
  613. package/coverage/lcov-report/src/api/routes/apikeys.ts.html +0 -121
  614. package/coverage/lcov-report/src/api/routes/application.ts.html +0 -223
  615. package/coverage/lcov-report/src/api/routes/auth.ts.html +0 -109
  616. package/coverage/lcov-report/src/api/routes/datasource.ts.html +0 -265
  617. package/coverage/lcov-report/src/api/routes/deploy.ts.html +0 -148
  618. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -289
  619. package/coverage/lcov-report/src/api/routes/migrations.ts.html +0 -127
  620. package/coverage/lcov-report/src/api/routes/plugin.ts.html +0 -151
  621. package/coverage/lcov-report/src/api/routes/public/applications.ts.html +0 -541
  622. package/coverage/lcov-report/src/api/routes/public/index.html +0 -191
  623. package/coverage/lcov-report/src/api/routes/public/index.ts.html +0 -493
  624. package/coverage/lcov-report/src/api/routes/public/middleware/index.html +0 -116
  625. package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +0 -328
  626. package/coverage/lcov-report/src/api/routes/public/queries.ts.html +0 -313
  627. package/coverage/lcov-report/src/api/routes/public/rows.ts.html +0 -598
  628. package/coverage/lcov-report/src/api/routes/public/tables.ts.html +0 -586
  629. package/coverage/lcov-report/src/api/routes/public/users.ts.html +0 -511
  630. package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +0 -238
  631. package/coverage/lcov-report/src/api/routes/public/utils/index.html +0 -116
  632. package/coverage/lcov-report/src/api/routes/role.ts.html +0 -157
  633. package/coverage/lcov-report/src/api/routes/row.ts.html +0 -883
  634. package/coverage/lcov-report/src/api/routes/screen.ts.html +0 -154
  635. package/coverage/lcov-report/src/api/routes/static.ts.html +0 -280
  636. package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +0 -550
  637. package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +0 -131
  638. package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +0 -367
  639. package/coverage/lcov-report/src/api/routes/webhook.ts.html +0 -166
  640. package/coverage/lcov-report/src/app.ts.html +0 -406
  641. package/coverage/lcov-report/src/automations/logging/index.html +0 -116
  642. package/coverage/lcov-report/src/automations/logging/index.ts.html +0 -199
  643. package/coverage/lcov-report/src/automations/steps/createRow.ts.html +0 -382
  644. package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +0 -349
  645. package/coverage/lcov-report/src/automations/steps/index.html +0 -371
  646. package/coverage/lcov-report/src/automations/tests/utilities/index.html +0 -116
  647. package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +0 -265
  648. package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +0 -196
  649. package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +0 -130
  650. package/coverage/lcov-report/src/automations/utils.ts.html +0 -886
  651. package/coverage/lcov-report/src/constants/index.ts.html +0 -697
  652. package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +0 -2059
  653. package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +0 -541
  654. package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +0 -427
  655. package/coverage/lcov-report/src/db/defaultData/index.html +0 -176
  656. package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +0 -403
  657. package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +0 -559
  658. package/coverage/lcov-report/src/db/dynamoClient.ts.html +0 -526
  659. package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +0 -265
  660. package/coverage/lcov-report/src/db/linkedRows/index.html +0 -161
  661. package/coverage/lcov-report/src/environment.ts.html +0 -457
  662. package/coverage/lcov-report/src/events/utils.ts.html +0 -319
  663. package/coverage/lcov-report/src/index.html +0 -191
  664. package/coverage/lcov-report/src/index.ts.html +0 -133
  665. package/coverage/lcov-report/src/integrations/arangodb.ts.html +0 -415
  666. package/coverage/lcov-report/src/integrations/base/index.html +0 -161
  667. package/coverage/lcov-report/src/integrations/base/query.ts.html +0 -133
  668. package/coverage/lcov-report/src/integrations/base/sql.ts.html +0 -1951
  669. package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +0 -691
  670. package/coverage/lcov-report/src/integrations/base/utils.ts.html +0 -121
  671. package/coverage/lcov-report/src/integrations/couchdb.ts.html +0 -406
  672. package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +0 -634
  673. package/coverage/lcov-report/src/integrations/firebase.ts.html +0 -646
  674. package/coverage/lcov-report/src/integrations/googlesheets.ts.html +0 -1315
  675. package/coverage/lcov-report/src/integrations/index.html +0 -371
  676. package/coverage/lcov-report/src/integrations/index.ts.html +0 -445
  677. package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +0 -1012
  678. package/coverage/lcov-report/src/integrations/mongodb.ts.html +0 -1867
  679. package/coverage/lcov-report/src/integrations/mysql.ts.html +0 -967
  680. package/coverage/lcov-report/src/integrations/oracle.ts.html +0 -1387
  681. package/coverage/lcov-report/src/integrations/postgres.ts.html +0 -1087
  682. package/coverage/lcov-report/src/integrations/queries/index.html +0 -116
  683. package/coverage/lcov-report/src/integrations/queries/sql.ts.html +0 -463
  684. package/coverage/lcov-report/src/integrations/redis.ts.html +0 -550
  685. package/coverage/lcov-report/src/integrations/rest.ts.html +0 -1381
  686. package/coverage/lcov-report/src/integrations/s3.ts.html +0 -862
  687. package/coverage/lcov-report/src/integrations/snowflake.ts.html +0 -376
  688. package/coverage/lcov-report/src/integrations/utils.ts.html +0 -1018
  689. package/coverage/lcov-report/src/middleware/authorized.ts.html +0 -460
  690. package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +0 -187
  691. package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +0 -163
  692. package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +0 -151
  693. package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +0 -206
  694. package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +0 -172
  695. package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +0 -226
  696. package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +0 -151
  697. package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +0 -151
  698. package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +0 -166
  699. package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +0 -532
  700. package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +0 -283
  701. package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +0 -146
  702. package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +0 -265
  703. package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +0 -232
  704. package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +0 -724
  705. package/coverage/lcov-report/src/migrations/functions/backfill/index.html +0 -161
  706. package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +0 -106
  707. package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +0 -235
  708. package/coverage/lcov-report/src/migrations/functions/index.html +0 -161
  709. package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +0 -130
  710. package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +0 -520
  711. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +0 -161
  712. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +0 -94
  713. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +0 -127
  714. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +0 -115
  715. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +0 -169
  716. package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +0 -124
  717. package/coverage/lcov-report/src/migrations/index.ts.html +0 -430
  718. package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +0 -205
  719. package/coverage/lcov-report/src/migrations/tests/index.html +0 -131
  720. package/coverage/lcov-report/src/migrations/tests/structures.ts.html +0 -283
  721. package/coverage/lcov-report/src/sdk/app/automations/index.html +0 -131
  722. package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +0 -100
  723. package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +0 -214
  724. package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +0 -91
  725. package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +0 -604
  726. package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +0 -682
  727. package/coverage/lcov-report/src/sdk/app/backups/index.html +0 -176
  728. package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +0 -112
  729. package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +0 -292
  730. package/coverage/lcov-report/src/sdk/app/tables/index.html +0 -116
  731. package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +0 -265
  732. package/coverage/lcov-report/src/startup.ts.html +0 -499
  733. package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +0 -1966
  734. package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +0 -127
  735. package/coverage/lcov-report/src/tests/utilities/index.html +0 -161
  736. package/coverage/lcov-report/src/tests/utilities/structures.ts.html +0 -667
  737. package/coverage/lcov-report/src/threads/automation.ts.html +0 -1594
  738. package/coverage/lcov-report/src/threads/index.html +0 -161
  739. package/coverage/lcov-report/src/threads/index.ts.html +0 -418
  740. package/coverage/lcov-report/src/threads/query.ts.html +0 -961
  741. package/coverage/lcov-report/src/threads/utils.ts.html +0 -373
  742. package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +0 -547
  743. package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +0 -1129
  744. package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +0 -142
  745. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -343
  746. package/coverage/lcov-report/src/utilities/routing/index.ts.html +0 -181
  747. package/coverage/lcov-report/src/utilities/rowProcessor/index.html +0 -146
  748. package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +0 -373
  749. package/coverage/lcov-report/src/watch.ts.html +0 -196
  750. package/dist/db/defaultData/datasource_bb_default.js +0 -573
  751. package/dist/db/defaultData/employeeImport.js +0 -155
  752. package/dist/db/defaultData/expensesImport.js +0 -117
  753. package/dist/db/defaultData/inventoryImport.js +0 -109
  754. package/dist/db/defaultData/jobsImport.js +0 -152
  755. package/dist/db/linkedRows/LinkDocument.js +0 -32
  756. package/dist/events/BudibaseEmitter.js +0 -24
  757. package/dist/integrations/base/types.js +0 -2
  758. package/dist/migrations/functions/tableSettings.js +0 -130
  759. package/dist/utilities/rowProcessor/map.js +0 -99
  760. package/jest.config.ts +0 -33
  761. package/scripts/integrations/postgres/emp-skill.sql +0 -46
  762. package/src/api/controllers/integration.ts +0 -13
  763. package/src/api/controllers/migrations.ts +0 -14
  764. package/src/api/controllers/script.ts +0 -12
  765. package/src/api/routes/analytics.ts +0 -9
  766. package/src/api/routes/apikeys.ts +0 -12
  767. package/src/api/routes/automation.ts +0 -87
  768. package/src/api/routes/cloud.ts +0 -18
  769. package/src/api/routes/component.ts +0 -14
  770. package/src/api/routes/datasource.ts +0 -60
  771. package/src/api/routes/deploy.ts +0 -21
  772. package/src/api/routes/dev.ts +0 -38
  773. package/src/api/routes/integration.ts +0 -16
  774. package/src/api/routes/layout.ts +0 -16
  775. package/src/api/routes/migrations.ts +0 -14
  776. package/src/api/routes/permission.ts +0 -41
  777. package/src/api/routes/role.ts +0 -24
  778. package/src/api/routes/routing.ts +0 -14
  779. package/src/api/routes/screen.ts +0 -23
  780. package/src/api/routes/script.ts +0 -10
  781. package/src/api/routes/templates.ts +0 -16
  782. package/src/api/routes/user.ts +0 -51
  783. package/src/api/routes/view.ts +0 -34
  784. package/src/automations/bullboard.ts +0 -38
  785. package/src/automations/index.ts +0 -26
  786. package/src/automations/tests/utilities/index.ts +0 -60
  787. package/src/automations/triggerInfo/index.ts +0 -15
  788. package/src/constants/index.ts +0 -204
  789. package/src/constants/screens.ts +0 -48
  790. package/src/db/defaultData/datasource_bb_default.ts +0 -658
  791. package/src/db/defaultData/employeeImport.ts +0 -152
  792. package/src/db/defaultData/expensesImport.ts +0 -114
  793. package/src/db/defaultData/inventoryImport.ts +0 -106
  794. package/src/db/defaultData/jobsImport.ts +0 -158
  795. package/src/db/index.ts +0 -16
  796. package/src/db/linkedRows/LinkDocument.ts +0 -60
  797. package/src/events/index.ts +0 -5
  798. package/src/events/utils.ts +0 -78
  799. package/src/integrations/base/types.ts +0 -134
  800. package/src/middleware/appInfo.ts +0 -20
  801. package/src/middleware/publicApi.ts +0 -21
  802. package/src/migrations/functions/tableSettings.ts +0 -145
  803. package/src/migrations/functions/tests/tableSettings.spec.ts +0 -144
  804. package/src/tests/utilities/controllers.ts +0 -14
  805. package/src/utilities/budibaseDir.ts +0 -3
  806. package/src/utilities/global.ts +0 -138
  807. package/src/utilities/routing/index.ts +0 -32
  808. package/src/utilities/rowProcessor/map.ts +0 -96
  809. package/src/utilities/security.ts +0 -65
@@ -18,15 +18,23 @@ import {
18
18
  convertRowId,
19
19
  } from "../../../integrations/utils"
20
20
  import { getDatasourceAndQuery } from "./utils"
21
- import { FieldTypes, RelationshipTypes } from "../../../constants"
21
+ import {
22
+ DataSourceOperation,
23
+ FieldTypes,
24
+ RelationshipTypes,
25
+ } from "../../../constants"
22
26
  import { breakExternalTableId, isSQL } from "../../../integrations/utils"
23
27
  import { processObjectSync } from "@budibase/string-templates"
24
28
  // @ts-ignore
25
29
  import { cloneDeep } from "lodash/fp"
26
- import { processFormulas, processDates } from "../../../utilities/rowProcessor"
27
- import { context } from "@budibase/backend-core"
30
+ import {
31
+ processFormulas,
32
+ processDates,
33
+ } from "../../../utilities/rowProcessor/utils"
34
+ // @ts-ignore
35
+ import { getAppDB } from "@budibase/backend-core/context"
28
36
 
29
- export interface ManyRelationship {
37
+ interface ManyRelationship {
30
38
  tableId?: string
31
39
  id?: string
32
40
  isUpdate?: boolean
@@ -34,695 +42,706 @@ export interface ManyRelationship {
34
42
  [key: string]: any
35
43
  }
36
44
 
37
- export interface RunConfig {
38
- id?: any[]
45
+ interface RunConfig {
46
+ id?: string
39
47
  filters?: SearchFilters
40
48
  sort?: SortJson
41
49
  paginate?: PaginationJson
42
- datasource?: Datasource
43
50
  row?: Row
44
51
  rows?: Row[]
45
- tables?: Record<string, Table>
46
52
  }
47
53
 
48
- function buildFilters(
49
- id: string | undefined | string[],
50
- filters: SearchFilters,
51
- table: Table
52
- ) {
53
- const primary = table.primary
54
- // if passed in array need to copy for shifting etc
55
- let idCopy: undefined | string | any[] = cloneDeep(id)
56
- if (filters) {
57
- // need to map over the filters and make sure the _id field isn't present
58
- for (let filter of Object.values(filters)) {
59
- if (filter._id && primary) {
60
- const parts = breakRowIdField(filter._id)
61
- for (let field of primary) {
62
- filter[field] = parts.shift()
54
+ module External {
55
+ function buildFilters(
56
+ id: string | undefined | string[],
57
+ filters: SearchFilters,
58
+ table: Table
59
+ ) {
60
+ const primary = table.primary
61
+ // if passed in array need to copy for shifting etc
62
+ let idCopy: undefined | string | any[] = cloneDeep(id)
63
+ if (filters) {
64
+ // need to map over the filters and make sure the _id field isn't present
65
+ for (let filter of Object.values(filters)) {
66
+ if (filter._id && primary) {
67
+ const parts = breakRowIdField(filter._id)
68
+ for (let field of primary) {
69
+ filter[field] = parts.shift()
70
+ }
63
71
  }
72
+ // make sure this field doesn't exist on any filter
73
+ delete filter._id
64
74
  }
65
- // make sure this field doesn't exist on any filter
66
- delete filter._id
67
75
  }
68
- }
69
- // there is no id, just use the user provided filters
70
- if (!idCopy || !table) {
71
- return filters
72
- }
73
- // if used as URL parameter it will have been joined
74
- if (!Array.isArray(idCopy)) {
75
- idCopy = breakRowIdField(idCopy)
76
- }
77
- const equal: any = {}
78
- if (primary && idCopy) {
79
- for (let field of primary) {
80
- // work through the ID and get the parts
81
- equal[field] = idCopy.shift()
76
+ // there is no id, just use the user provided filters
77
+ if (!idCopy || !table) {
78
+ return filters
79
+ }
80
+ // if used as URL parameter it will have been joined
81
+ if (!Array.isArray(idCopy)) {
82
+ idCopy = breakRowIdField(idCopy)
83
+ }
84
+ const equal: any = {}
85
+ if (primary && idCopy) {
86
+ for (let field of primary) {
87
+ // work through the ID and get the parts
88
+ equal[field] = idCopy.shift()
89
+ }
90
+ }
91
+ return {
92
+ equal,
82
93
  }
83
94
  }
84
- return {
85
- equal,
86
- }
87
- }
88
95
 
89
- /**
90
- * This function checks the incoming parameters to make sure all the inputs are
91
- * valid based on on the table schema. The main thing this is looking for is when a
92
- * user has made use of the _id field of a row for a foreign key or a search parameter.
93
- * In these cases the key will be sent up as [1], rather than 1. In these cases we will
94
- * simplify it down to the requirements. This function is quite complex as we try to be
95
- * relatively restrictive over what types of columns we will perform this action for.
96
- */
97
- function cleanupConfig(config: RunConfig, table: Table): RunConfig {
98
- const primaryOptions = [
99
- FieldTypes.STRING,
100
- FieldTypes.LONGFORM,
101
- FieldTypes.OPTIONS,
102
- FieldTypes.NUMBER,
103
- ]
104
- // filter out fields which cannot be keys
105
- const fieldNames = Object.entries(table.schema)
106
- .filter(schema => primaryOptions.find(val => val === schema[1].type))
107
- .map(([fieldName]) => fieldName)
108
- const iterateObject = (obj: { [key: string]: any }) => {
109
- for (let [field, value] of Object.entries(obj)) {
110
- if (fieldNames.find(name => name === field) && isRowId(value)) {
111
- obj[field] = convertRowId(value)
96
+ /**
97
+ * This function checks the incoming parameters to make sure all the inputs are
98
+ * valid based on on the table schema. The main thing this is looking for is when a
99
+ * user has made use of the _id field of a row for a foreign key or a search parameter.
100
+ * In these cases the key will be sent up as [1], rather than 1. In these cases we will
101
+ * simplify it down to the requirements. This function is quite complex as we try to be
102
+ * relatively restrictive over what types of columns we will perform this action for.
103
+ */
104
+ function cleanupConfig(config: RunConfig, table: Table): RunConfig {
105
+ const primaryOptions = [
106
+ FieldTypes.STRING,
107
+ FieldTypes.LONGFORM,
108
+ FieldTypes.OPTIONS,
109
+ FieldTypes.NUMBER,
110
+ ]
111
+ // filter out fields which cannot be keys
112
+ const fieldNames = Object.entries(table.schema)
113
+ .filter(schema => primaryOptions.find(val => val === schema[1].type))
114
+ .map(([fieldName]) => fieldName)
115
+ const iterateObject = (obj: { [key: string]: any }) => {
116
+ for (let [field, value] of Object.entries(obj)) {
117
+ if (fieldNames.find(name => name === field) && isRowId(value)) {
118
+ obj[field] = convertRowId(value)
119
+ }
112
120
  }
113
121
  }
114
- }
115
- // check the row and filters to make sure they aren't a key of some sort
116
- if (config.filters) {
117
- for (let [key, filter] of Object.entries(config.filters)) {
118
- // oneOf is an array, don't iterate it
119
- if (
120
- typeof filter !== "object" ||
121
- Object.keys(filter).length === 0 ||
122
- key === FilterType.ONE_OF
123
- ) {
124
- continue
122
+ // check the row and filters to make sure they aren't a key of some sort
123
+ if (config.filters) {
124
+ for (let [key, filter] of Object.entries(config.filters)) {
125
+ // oneOf is an array, don't iterate it
126
+ if (
127
+ typeof filter !== "object" ||
128
+ Object.keys(filter).length === 0 ||
129
+ key === FilterType.ONE_OF
130
+ ) {
131
+ continue
132
+ }
133
+ iterateObject(filter)
125
134
  }
126
- iterateObject(filter)
127
135
  }
128
- }
129
- if (config.row) {
130
- iterateObject(config.row)
131
- }
132
-
133
- return config
134
- }
135
-
136
- function generateIdForRow(row: Row | undefined, table: Table): string {
137
- const primary = table.primary
138
- if (!row || !primary) {
139
- return ""
140
- }
141
- // build id array
142
- let idParts = []
143
- for (let field of primary) {
144
- // need to handle table name + field or just field, depending on if relationships used
145
- const fieldValue = row[`${table.name}.${field}`] || row[field]
146
- if (fieldValue) {
147
- idParts.push(fieldValue)
136
+ if (config.row) {
137
+ iterateObject(config.row)
148
138
  }
149
- }
150
- if (idParts.length === 0) {
151
- return ""
152
- }
153
- return generateRowIdField(idParts)
154
- }
155
139
 
156
- function getEndpoint(tableId: string | undefined, operation: string) {
157
- if (!tableId) {
158
- return {}
159
- }
160
- const { datasourceId, tableName } = breakExternalTableId(tableId)
161
- return {
162
- datasourceId,
163
- entityId: tableName,
164
- operation,
140
+ return config
165
141
  }
166
- }
167
142
 
168
- function basicProcessing(row: Row, table: Table): Row {
169
- const thisRow: Row = {}
170
- // filter the row down to what is actually the row (not joined)
171
- for (let fieldName of Object.keys(table.schema)) {
172
- const pathValue = row[`${table.name}.${fieldName}`]
173
- const value = pathValue != null ? pathValue : row[fieldName]
174
- // all responses include "select col as table.col" so that overlaps are handled
175
- if (value != null) {
176
- thisRow[fieldName] = value
143
+ function generateIdForRow(row: Row | undefined, table: Table): string {
144
+ const primary = table.primary
145
+ if (!row || !primary) {
146
+ return ""
177
147
  }
178
- }
179
- thisRow._id = generateIdForRow(row, table)
180
- thisRow.tableId = table._id
181
- thisRow._rev = "rev"
182
- return processFormulas(table, thisRow)
183
- }
184
-
185
- function fixArrayTypes(row: Row, table: Table) {
186
- for (let [fieldName, schema] of Object.entries(table.schema)) {
187
- if (
188
- schema.type === FieldTypes.ARRAY &&
189
- typeof row[fieldName] === "string"
190
- ) {
191
- try {
192
- row[fieldName] = JSON.parse(row[fieldName])
193
- } catch (err) {
194
- // couldn't convert back to array, ignore
195
- delete row[fieldName]
148
+ // build id array
149
+ let idParts = []
150
+ for (let field of primary) {
151
+ // need to handle table name + field or just field, depending on if relationships used
152
+ const fieldValue = row[`${table.name}.${field}`] || row[field]
153
+ if (fieldValue) {
154
+ idParts.push(fieldValue)
196
155
  }
197
156
  }
198
- }
199
- return row
200
- }
201
-
202
- function isOneSide(field: FieldSchema) {
203
- return (
204
- field.relationshipType && field.relationshipType.split("-")[0] === "one"
205
- )
206
- }
207
-
208
- export class ExternalRequest {
209
- private operation: Operation
210
- private tableId: string
211
- private datasource?: Datasource
212
- private tables: { [key: string]: Table } = {}
213
-
214
- constructor(operation: Operation, tableId: string, datasource?: Datasource) {
215
- this.operation = operation
216
- this.tableId = tableId
217
- this.datasource = datasource
218
- if (datasource && datasource.entities) {
219
- this.tables = datasource.entities
157
+ if (idParts.length === 0) {
158
+ return ""
220
159
  }
160
+ return generateRowIdField(idParts)
221
161
  }
222
162
 
223
- getTable(tableId: string | undefined): Table | undefined {
163
+ function getEndpoint(tableId: string | undefined, operation: string) {
224
164
  if (!tableId) {
225
- throw "Table ID is unknown, cannot find table"
165
+ return {}
226
166
  }
227
- const { tableName } = breakExternalTableId(tableId)
228
- if (tableName) {
229
- return this.tables[tableName]
167
+ const { datasourceId, tableName } = breakExternalTableId(tableId)
168
+ return {
169
+ datasourceId,
170
+ entityId: tableName,
171
+ operation,
230
172
  }
231
173
  }
232
174
 
233
- inputProcessing(row: Row | undefined, table: Table) {
234
- if (!row) {
235
- return { row, manyRelationships: [] }
175
+ function basicProcessing(row: Row, table: Table): Row {
176
+ const thisRow: Row = {}
177
+ // filter the row down to what is actually the row (not joined)
178
+ for (let fieldName of Object.keys(table.schema)) {
179
+ const pathValue = row[`${table.name}.${fieldName}`]
180
+ const value = pathValue != null ? pathValue : row[fieldName]
181
+ // all responses include "select col as table.col" so that overlaps are handled
182
+ if (value != null) {
183
+ thisRow[fieldName] = value
184
+ }
236
185
  }
237
- // we don't really support composite keys for relationships, this is why [0] is used
238
- // @ts-ignore
239
- const tablePrimary: string = table.primary[0]
240
- let newRow: Row = {},
241
- manyRelationships: ManyRelationship[] = []
242
- for (let [key, field] of Object.entries(table.schema)) {
243
- // if set already, or not set just skip it
186
+ thisRow._id = generateIdForRow(row, table)
187
+ thisRow.tableId = table._id
188
+ thisRow._rev = "rev"
189
+ return processFormulas(table, thisRow)
190
+ }
191
+
192
+ function fixArrayTypes(row: Row, table: Table) {
193
+ for (let [fieldName, schema] of Object.entries(table.schema)) {
244
194
  if (
245
- row[key] == null ||
246
- newRow[key] ||
247
- field.autocolumn ||
248
- field.type === FieldTypes.FORMULA
195
+ schema.type === FieldTypes.ARRAY &&
196
+ typeof row[fieldName] === "string"
249
197
  ) {
250
- continue
198
+ try {
199
+ row[fieldName] = JSON.parse(row[fieldName])
200
+ } catch (err) {
201
+ // couldn't convert back to array, ignore
202
+ delete row[fieldName]
203
+ }
251
204
  }
252
- // if its an empty string then it means return the column to null (if possible)
253
- if (row[key] === "") {
254
- newRow[key] = null
255
- continue
205
+ }
206
+ return row
207
+ }
208
+
209
+ function isOneSide(field: FieldSchema) {
210
+ return (
211
+ field.relationshipType && field.relationshipType.split("-")[0] === "one"
212
+ )
213
+ }
214
+
215
+ class ExternalRequest {
216
+ private operation: Operation
217
+ private tableId: string
218
+ private datasource: Datasource
219
+ private tables: { [key: string]: Table } = {}
220
+
221
+ constructor(operation: Operation, tableId: string, datasource: Datasource) {
222
+ this.operation = operation
223
+ this.tableId = tableId
224
+ this.datasource = datasource
225
+ if (datasource && datasource.entities) {
226
+ this.tables = datasource.entities
256
227
  }
257
- // parse floats/numbers
258
- if (field.type === FieldTypes.NUMBER && !isNaN(parseFloat(row[key]))) {
259
- newRow[key] = parseFloat(row[key])
228
+ }
229
+
230
+ getTable(tableId: string | undefined): Table | undefined {
231
+ if (!tableId) {
232
+ throw "Table ID is unknown, cannot find table"
260
233
  }
261
- // if its not a link then just copy it over
262
- if (field.type !== FieldTypes.LINK) {
263
- newRow[key] = row[key]
264
- continue
234
+ const { tableName } = breakExternalTableId(tableId)
235
+ if (tableName) {
236
+ return this.tables[tableName]
265
237
  }
266
- const { tableName: linkTableName } = breakExternalTableId(field?.tableId)
267
- // table has to exist for many to many
268
- if (!linkTableName || !this.tables[linkTableName]) {
269
- continue
238
+ }
239
+
240
+ inputProcessing(row: Row | undefined, table: Table) {
241
+ if (!row) {
242
+ return { row, manyRelationships: [] }
270
243
  }
271
- const linkTable = this.tables[linkTableName]
244
+ // we don't really support composite keys for relationships, this is why [0] is used
272
245
  // @ts-ignore
273
- const linkTablePrimary = linkTable.primary[0]
274
- // one to many
275
- if (isOneSide(field)) {
276
- let id = row[key][0]
277
- if (typeof row[key] === "string") {
278
- id = decodeURIComponent(row[key]).match(/\[(.*?)\]/)?.[1]
279
- }
280
- newRow[field.foreignKey || linkTablePrimary] = breakRowIdField(id)[0]
281
- }
282
- // many to many
283
- else if (field.through) {
284
- // we're not inserting a doc, will be a bunch of update calls
285
- const otherKey: string = field.throughFrom || linkTablePrimary
286
- const thisKey: string = field.throughTo || tablePrimary
287
- row[key].map((relationship: any) => {
288
- manyRelationships.push({
289
- tableId: field.through || field.tableId,
290
- isUpdate: false,
291
- key: otherKey,
292
- [otherKey]: breakRowIdField(relationship)[0],
293
- // leave the ID for enrichment later
294
- [thisKey]: `{{ literal ${tablePrimary} }}`,
295
- })
296
- })
297
- }
298
- // many to one
299
- else {
300
- const thisKey: string = "id"
246
+ const tablePrimary: string = table.primary[0]
247
+ let newRow: Row = {},
248
+ manyRelationships: ManyRelationship[] = []
249
+ for (let [key, field] of Object.entries(table.schema)) {
250
+ // if set already, or not set just skip it
251
+ if (
252
+ row[key] == null ||
253
+ newRow[key] ||
254
+ field.autocolumn ||
255
+ field.type === FieldTypes.FORMULA
256
+ ) {
257
+ continue
258
+ }
259
+ // if its an empty string then it means return the column to null (if possible)
260
+ if (row[key] === "") {
261
+ newRow[key] = null
262
+ continue
263
+ }
264
+ // parse floats/numbers
265
+ if (field.type === FieldTypes.NUMBER && !isNaN(parseFloat(row[key]))) {
266
+ newRow[key] = parseFloat(row[key])
267
+ }
268
+ // if its not a link then just copy it over
269
+ if (field.type !== FieldTypes.LINK) {
270
+ newRow[key] = row[key]
271
+ continue
272
+ }
273
+ const { tableName: linkTableName } = breakExternalTableId(
274
+ field?.tableId
275
+ )
276
+ // table has to exist for many to many
277
+ if (!linkTableName || !this.tables[linkTableName]) {
278
+ continue
279
+ }
280
+ const linkTable = this.tables[linkTableName]
301
281
  // @ts-ignore
302
- const otherKey: string = field.fieldName
303
- row[key].map((relationship: any) => {
304
- manyRelationships.push({
305
- tableId: field.tableId,
306
- isUpdate: true,
307
- key: otherKey,
308
- [thisKey]: breakRowIdField(relationship)[0],
309
- // leave the ID for enrichment later
310
- [otherKey]: `{{ literal ${tablePrimary} }}`,
282
+ const linkTablePrimary = linkTable.primary[0]
283
+ // one to many
284
+ if (isOneSide(field)) {
285
+ newRow[field.foreignKey || linkTablePrimary] = breakRowIdField(
286
+ row[key][0]
287
+ )[0]
288
+ }
289
+ // many to many
290
+ else if (field.through) {
291
+ // we're not inserting a doc, will be a bunch of update calls
292
+ const otherKey: string = field.throughFrom || linkTablePrimary
293
+ const thisKey: string = field.throughTo || tablePrimary
294
+ row[key].map((relationship: any) => {
295
+ manyRelationships.push({
296
+ tableId: field.through || field.tableId,
297
+ isUpdate: false,
298
+ key: otherKey,
299
+ [otherKey]: breakRowIdField(relationship)[0],
300
+ // leave the ID for enrichment later
301
+ [thisKey]: `{{ literal ${tablePrimary} }}`,
302
+ })
311
303
  })
312
- })
304
+ }
305
+ // many to one
306
+ else {
307
+ const thisKey: string = "id"
308
+ // @ts-ignore
309
+ const otherKey: string = field.fieldName
310
+ row[key].map((relationship: any) => {
311
+ manyRelationships.push({
312
+ tableId: field.tableId,
313
+ isUpdate: true,
314
+ key: otherKey,
315
+ [thisKey]: breakRowIdField(relationship)[0],
316
+ // leave the ID for enrichment later
317
+ [otherKey]: `{{ literal ${tablePrimary} }}`,
318
+ })
319
+ })
320
+ }
313
321
  }
322
+ // we return the relationships that may need to be created in the through table
323
+ // we do this so that if the ID is generated by the DB it can be inserted
324
+ // after the fact
325
+ return { row: newRow, manyRelationships }
314
326
  }
315
- // we return the relationships that may need to be created in the through table
316
- // we do this so that if the ID is generated by the DB it can be inserted
317
- // after the fact
318
- return { row: newRow, manyRelationships }
319
- }
320
327
 
321
- squashRelationshipColumns(
322
- table: Table,
323
- row: Row,
324
- relationships: RelationshipsJson[]
325
- ): Row {
326
- for (let relationship of relationships) {
327
- const linkedTable = this.tables[relationship.tableName]
328
- if (!linkedTable || !row[relationship.column]) {
329
- continue
330
- }
331
- const display = linkedTable.primaryDisplay
332
- for (let key of Object.keys(row[relationship.column])) {
333
- const related: Row = row[relationship.column][key]
334
- row[relationship.column][key] = {
335
- primaryDisplay: display ? related[display] : undefined,
336
- _id: related._id,
328
+ squashRelationshipColumns(
329
+ table: Table,
330
+ row: Row,
331
+ relationships: RelationshipsJson[]
332
+ ): Row {
333
+ for (let relationship of relationships) {
334
+ const linkedTable = this.tables[relationship.tableName]
335
+ if (!linkedTable || !row[relationship.column]) {
336
+ continue
337
+ }
338
+ const display = linkedTable.primaryDisplay
339
+ for (let key of Object.keys(row[relationship.column])) {
340
+ const related: Row = row[relationship.column][key]
341
+ row[relationship.column][key] = {
342
+ primaryDisplay: display ? related[display] : undefined,
343
+ _id: related._id,
344
+ }
337
345
  }
338
346
  }
347
+ return row
339
348
  }
340
- return row
341
- }
342
349
 
343
- /**
344
- * This iterates through the returned rows and works out what elements of the rows
345
- * actually match up to another row (based on primary keys) - this is pretty specific
346
- * to SQL and the way that SQL relationships are returned based on joins.
347
- * This is complicated, but the idea is that when a SQL query returns all the relations
348
- * will be separate rows, with all of the data in each row. We have to decipher what comes
349
- * from where (which tables) and how to convert that into budibase columns.
350
- */
351
- updateRelationshipColumns(
352
- table: Table,
353
- row: Row,
354
- rows: { [key: string]: Row },
355
- relationships: RelationshipsJson[]
356
- ) {
357
- const columns: { [key: string]: any } = {}
358
- for (let relationship of relationships) {
359
- const linkedTable = this.tables[relationship.tableName]
360
- if (!linkedTable) {
361
- continue
362
- }
363
- const fromColumn = `${table.name}.${relationship.from}`
364
- const toColumn = `${linkedTable.name}.${relationship.to}`
365
- // this is important when working with multiple relationships
366
- // between the same tables, don't want to overlap/multiply the relations
367
- if (
368
- !relationship.through &&
369
- row[fromColumn]?.toString() !== row[toColumn]?.toString()
370
- ) {
371
- continue
372
- }
373
- let linked = basicProcessing(row, linkedTable)
374
- if (!linked._id) {
375
- continue
376
- }
377
- columns[relationship.column] = linked
378
- }
379
- for (let [column, related] of Object.entries(columns)) {
380
- if (!row._id) {
381
- continue
382
- }
383
- const rowId: string = row._id
384
- if (!Array.isArray(rows[rowId][column])) {
385
- rows[rowId][column] = []
350
+ /**
351
+ * This iterates through the returned rows and works out what elements of the rows
352
+ * actually match up to another row (based on primary keys) - this is pretty specific
353
+ * to SQL and the way that SQL relationships are returned based on joins.
354
+ * This is complicated, but the idea is that when a SQL query returns all the relations
355
+ * will be separate rows, with all of the data in each row. We have to decipher what comes
356
+ * from where (which tables) and how to convert that into budibase columns.
357
+ */
358
+ updateRelationshipColumns(
359
+ table: Table,
360
+ row: Row,
361
+ rows: { [key: string]: Row },
362
+ relationships: RelationshipsJson[]
363
+ ) {
364
+ const columns: { [key: string]: any } = {}
365
+ for (let relationship of relationships) {
366
+ const linkedTable = this.tables[relationship.tableName]
367
+ if (!linkedTable) {
368
+ continue
369
+ }
370
+ const fromColumn = `${table.name}.${relationship.from}`
371
+ const toColumn = `${linkedTable.name}.${relationship.to}`
372
+ // this is important when working with multiple relationships
373
+ // between the same tables, don't want to overlap/multiply the relations
374
+ if (
375
+ !relationship.through &&
376
+ row[fromColumn]?.toString() !== row[toColumn]?.toString()
377
+ ) {
378
+ continue
379
+ }
380
+ let linked = basicProcessing(row, linkedTable)
381
+ if (!linked._id) {
382
+ continue
383
+ }
384
+ columns[relationship.column] = linked
386
385
  }
387
- // make sure relationship hasn't been found already
388
- if (
389
- !rows[rowId][column].find(
390
- (relation: Row) => relation._id === related._id
391
- )
392
- ) {
393
- rows[rowId][column].push(related)
386
+ for (let [column, related] of Object.entries(columns)) {
387
+ if (!row._id) {
388
+ continue
389
+ }
390
+ const rowId: string = row._id
391
+ if (!Array.isArray(rows[rowId][column])) {
392
+ rows[rowId][column] = []
393
+ }
394
+ // make sure relationship hasn't been found already
395
+ if (
396
+ !rows[rowId][column].find(
397
+ (relation: Row) => relation._id === related._id
398
+ )
399
+ ) {
400
+ rows[rowId][column].push(related)
401
+ }
394
402
  }
403
+ return rows
395
404
  }
396
- return rows
397
- }
398
405
 
399
- outputProcessing(
400
- rows: Row[] = [],
401
- table: Table,
402
- relationships: RelationshipsJson[]
403
- ) {
404
- if (!rows || rows.length === 0 || rows[0].read === true) {
405
- return []
406
- }
407
- let finalRows: { [key: string]: Row } = {}
408
- for (let row of rows) {
409
- const rowId = generateIdForRow(row, table)
410
- row._id = rowId
411
- // this is a relationship of some sort
412
- if (finalRows[rowId]) {
406
+ outputProcessing(
407
+ rows: Row[] = [],
408
+ table: Table,
409
+ relationships: RelationshipsJson[]
410
+ ) {
411
+ if (!rows || rows.length === 0 || rows[0].read === true) {
412
+ return []
413
+ }
414
+ let finalRows: { [key: string]: Row } = {}
415
+ for (let row of rows) {
416
+ const rowId = generateIdForRow(row, table)
417
+ row._id = rowId
418
+ // this is a relationship of some sort
419
+ if (finalRows[rowId]) {
420
+ finalRows = this.updateRelationshipColumns(
421
+ table,
422
+ row,
423
+ finalRows,
424
+ relationships
425
+ )
426
+ continue
427
+ }
428
+ const thisRow = fixArrayTypes(basicProcessing(row, table), table)
429
+ if (thisRow._id == null) {
430
+ throw "Unable to generate row ID for SQL rows"
431
+ }
432
+ finalRows[thisRow._id] = thisRow
433
+ // do this at end once its been added to the final rows
413
434
  finalRows = this.updateRelationshipColumns(
414
435
  table,
415
436
  row,
416
437
  finalRows,
417
438
  relationships
418
439
  )
419
- continue
420
440
  }
421
- const thisRow = fixArrayTypes(basicProcessing(row, table), table)
422
- if (thisRow._id == null) {
423
- throw "Unable to generate row ID for SQL rows"
424
- }
425
- finalRows[thisRow._id] = thisRow
426
- // do this at end once its been added to the final rows
427
- finalRows = this.updateRelationshipColumns(
428
- table,
429
- row,
430
- finalRows,
431
- relationships
432
- )
433
- }
434
441
 
435
- // Process some additional data types
436
- let finalRowArray = Object.values(finalRows)
437
- finalRowArray = processDates(table, finalRowArray)
438
- finalRowArray = processFormulas(table, finalRowArray) as Row[]
442
+ // Process some additional data types
443
+ let finalRowArray = Object.values(finalRows)
444
+ finalRowArray = processDates(table, finalRowArray)
445
+ finalRowArray = processFormulas(table, finalRowArray)
439
446
 
440
- return finalRowArray.map((row: Row) =>
441
- this.squashRelationshipColumns(table, row, relationships)
442
- )
443
- }
447
+ return finalRowArray.map((row: Row) =>
448
+ this.squashRelationshipColumns(table, row, relationships)
449
+ )
450
+ }
444
451
 
445
- /**
446
- * Gets the list of relationship JSON structures based on the columns in the table,
447
- * this will be used by the underlying library to build whatever relationship mechanism
448
- * it has (e.g. SQL joins).
449
- */
450
- buildRelationships(table: Table): RelationshipsJson[] {
451
- const relationships = []
452
- for (let [fieldName, field] of Object.entries(table.schema)) {
453
- if (field.type !== FieldTypes.LINK) {
454
- continue
455
- }
456
- const { tableName: linkTableName } = breakExternalTableId(field.tableId)
457
- // no table to link to, this is not a valid relationships
458
- if (!linkTableName || !this.tables[linkTableName]) {
459
- continue
460
- }
461
- const linkTable = this.tables[linkTableName]
462
- if (!table.primary || !linkTable.primary) {
463
- continue
464
- }
465
- const definition: any = {
466
- // if no foreign key specified then use the name of the field in other table
467
- from: field.foreignKey || table.primary[0],
468
- to: field.fieldName,
469
- tableName: linkTableName,
470
- // need to specify where to put this back into
471
- column: fieldName,
472
- }
473
- if (field.through) {
474
- const { tableName: throughTableName } = breakExternalTableId(
475
- field.through
476
- )
477
- definition.through = throughTableName
478
- // don't support composite keys for relationships
479
- definition.from = field.throughTo || table.primary[0]
480
- definition.to = field.throughFrom || linkTable.primary[0]
481
- definition.fromPrimary = table.primary[0]
482
- definition.toPrimary = linkTable.primary[0]
452
+ /**
453
+ * Gets the list of relationship JSON structures based on the columns in the table,
454
+ * this will be used by the underlying library to build whatever relationship mechanism
455
+ * it has (e.g. SQL joins).
456
+ */
457
+ buildRelationships(table: Table): RelationshipsJson[] {
458
+ const relationships = []
459
+ for (let [fieldName, field] of Object.entries(table.schema)) {
460
+ if (field.type !== FieldTypes.LINK) {
461
+ continue
462
+ }
463
+ const { tableName: linkTableName } = breakExternalTableId(field.tableId)
464
+ // no table to link to, this is not a valid relationships
465
+ if (!linkTableName || !this.tables[linkTableName]) {
466
+ continue
467
+ }
468
+ const linkTable = this.tables[linkTableName]
469
+ if (!table.primary || !linkTable.primary) {
470
+ continue
471
+ }
472
+ const definition: any = {
473
+ // if no foreign key specified then use the name of the field in other table
474
+ from: field.foreignKey || table.primary[0],
475
+ to: field.fieldName,
476
+ tableName: linkTableName,
477
+ // need to specify where to put this back into
478
+ column: fieldName,
479
+ }
480
+ if (field.through) {
481
+ const { tableName: throughTableName } = breakExternalTableId(
482
+ field.through
483
+ )
484
+ definition.through = throughTableName
485
+ // don't support composite keys for relationships
486
+ definition.from = field.throughTo || table.primary[0]
487
+ definition.to = field.throughFrom || linkTable.primary[0]
488
+ definition.fromPrimary = table.primary[0]
489
+ definition.toPrimary = linkTable.primary[0]
490
+ }
491
+ relationships.push(definition)
483
492
  }
484
- relationships.push(definition)
493
+ return relationships
485
494
  }
486
- return relationships
487
- }
488
495
 
489
- /**
490
- * This is a cached lookup, of relationship records, this is mainly for creating/deleting junction
491
- * information.
492
- */
493
- async lookupRelations(tableId: string, row: Row) {
494
- const related: { [key: string]: any } = {}
495
- const { tableName } = breakExternalTableId(tableId)
496
- if (!tableName) {
497
- return related
498
- }
499
- const table = this.tables[tableName]
500
- // @ts-ignore
501
- const primaryKey = table.primary[0]
502
- // make a new request to get the row with all its relationships
503
- // we need this to work out if any relationships need removed
504
- for (let field of Object.values(table.schema)) {
505
- if (
506
- field.type !== FieldTypes.LINK ||
507
- !field.fieldName ||
508
- isOneSide(field)
509
- ) {
510
- continue
511
- }
512
- const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY
513
- const tableId = isMany ? field.through : field.tableId
514
- const { tableName: relatedTableName } = breakExternalTableId(tableId)
496
+ /**
497
+ * This is a cached lookup, of relationship records, this is mainly for creating/deleting junction
498
+ * information.
499
+ */
500
+ async lookupRelations(tableId: string, row: Row) {
501
+ const related: { [key: string]: any } = {}
502
+ const { tableName } = breakExternalTableId(tableId)
503
+ if (!tableName) {
504
+ return related
505
+ }
506
+ const table = this.tables[tableName]
515
507
  // @ts-ignore
516
- const linkPrimaryKey = this.tables[relatedTableName].primary[0]
517
- const manyKey = field.throughTo || primaryKey
518
- const lookupField = isMany ? primaryKey : field.foreignKey
519
- const fieldName = isMany ? manyKey : field.fieldName
520
- if (!lookupField || !row[lookupField]) {
521
- continue
522
- }
523
- const response = await getDatasourceAndQuery({
524
- endpoint: getEndpoint(tableId, Operation.READ),
525
- filters: {
526
- equal: {
527
- [fieldName]: row[lookupField],
508
+ const primaryKey = table.primary[0]
509
+ // make a new request to get the row with all its relationships
510
+ // we need this to work out if any relationships need removed
511
+ for (let field of Object.values(table.schema)) {
512
+ if (
513
+ field.type !== FieldTypes.LINK ||
514
+ !field.fieldName ||
515
+ isOneSide(field)
516
+ ) {
517
+ continue
518
+ }
519
+ const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY
520
+ const tableId = isMany ? field.through : field.tableId
521
+ const { tableName: relatedTableName } = breakExternalTableId(tableId)
522
+ // @ts-ignore
523
+ const linkPrimaryKey = this.tables[relatedTableName].primary[0]
524
+ const manyKey = field.throughTo || primaryKey
525
+ const lookupField = isMany ? primaryKey : field.foreignKey
526
+ const fieldName = isMany ? manyKey : field.fieldName
527
+ if (!lookupField || !row[lookupField]) {
528
+ continue
529
+ }
530
+ const response = await getDatasourceAndQuery({
531
+ endpoint: getEndpoint(tableId, DataSourceOperation.READ),
532
+ filters: {
533
+ equal: {
534
+ [fieldName]: row[lookupField],
535
+ },
528
536
  },
529
- },
530
- })
531
- // this is the response from knex if no rows found
532
- const rows = !response[0].read ? response : []
533
- const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName
534
- related[storeTo] = { rows, isMany, tableId }
537
+ })
538
+ // this is the response from knex if no rows found
539
+ const rows = !response[0].read ? response : []
540
+ const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName
541
+ related[storeTo] = { rows, isMany, tableId }
542
+ }
543
+ return related
535
544
  }
536
- return related
537
- }
538
545
 
539
- /**
540
- * Once a row has been written we may need to update a many field, e.g. updating foreign keys
541
- * in a bunch of rows in another table, or inserting/deleting rows from a junction table (many to many).
542
- * This is quite a complex process and is handled by this function, there are a few things going on here:
543
- * 1. If updating foreign keys its relatively simple, just create a filter for the row that needs updated
544
- * and write the various components.
545
- * 2. If junction table, then we lookup what exists already, write what doesn't exist, work out what
546
- * isn't supposed to exist anymore and delete those. This is better than the usual method of delete them
547
- * all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail).
548
- */
549
- async handleManyRelationships(
550
- mainTableId: string,
551
- row: Row,
552
- relationships: ManyRelationship[]
553
- ) {
554
- // if we're creating (in a through table) need to wipe the existing ones first
555
- const promises = []
556
- const related = await this.lookupRelations(mainTableId, row)
557
- for (let relationship of relationships) {
558
- const { key, tableId, isUpdate, id, ...rest } = relationship
559
- const body: { [key: string]: any } = processObjectSync(rest, row, {})
560
- const linkTable = this.getTable(tableId)
561
- // @ts-ignore
562
- const linkPrimary = linkTable?.primary[0]
563
- if (!linkTable || !linkPrimary) {
564
- return
565
- }
566
- const rows = related[key]?.rows || []
567
- const found = rows.find(
568
- (row: { [key: string]: any }) =>
569
- row[linkPrimary] === relationship.id ||
570
- row[linkPrimary] === body?.[linkPrimary]
571
- )
572
- const operation = isUpdate ? Operation.UPDATE : Operation.CREATE
573
- if (!found) {
574
- promises.push(
575
- getDatasourceAndQuery({
576
- endpoint: getEndpoint(tableId, operation),
577
- // if we're doing many relationships then we're writing, only one response
578
- body,
579
- filters: buildFilters(id, {}, linkTable),
580
- })
546
+ /**
547
+ * Once a row has been written we may need to update a many field, e.g. updating foreign keys
548
+ * in a bunch of rows in another table, or inserting/deleting rows from a junction table (many to many).
549
+ * This is quite a complex process and is handled by this function, there are a few things going on here:
550
+ * 1. If updating foreign keys its relatively simple, just create a filter for the row that needs updated
551
+ * and write the various components.
552
+ * 2. If junction table, then we lookup what exists already, write what doesn't exist, work out what
553
+ * isn't supposed to exist anymore and delete those. This is better than the usual method of delete them
554
+ * all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail).
555
+ */
556
+ async handleManyRelationships(
557
+ mainTableId: string,
558
+ row: Row,
559
+ relationships: ManyRelationship[]
560
+ ) {
561
+ // if we're creating (in a through table) need to wipe the existing ones first
562
+ const promises = []
563
+ const related = await this.lookupRelations(mainTableId, row)
564
+ for (let relationship of relationships) {
565
+ const { key, tableId, isUpdate, id, ...rest } = relationship
566
+ const body: { [key: string]: any } = processObjectSync(rest, row, {})
567
+ const linkTable = this.getTable(tableId)
568
+ // @ts-ignore
569
+ const linkPrimary = linkTable?.primary[0]
570
+ if (!linkTable || !linkPrimary) {
571
+ return
572
+ }
573
+ const rows = related[key]?.rows || []
574
+ const found = rows.find(
575
+ (row: { [key: string]: any }) =>
576
+ row[linkPrimary] === relationship.id ||
577
+ row[linkPrimary] === body?.[linkPrimary]
581
578
  )
582
- } else {
583
- // remove the relationship from cache so it isn't adjusted again
584
- rows.splice(rows.indexOf(found), 1)
585
- }
586
- }
587
- // finally cleanup anything that needs to be removed
588
- for (let [colName, { isMany, rows, tableId }] of Object.entries(related)) {
589
- const table: Table | undefined = this.getTable(tableId)
590
- // if its not the foreign key skip it, nothing to do
591
- if (
592
- !table ||
593
- (!isMany && table.primary && table.primary.indexOf(colName) !== -1)
594
- ) {
595
- continue
596
- }
597
- for (let row of rows) {
598
- const filters = buildFilters(generateIdForRow(row, table), {}, table)
599
- // safety check, if there are no filters on deletion bad things happen
600
- if (Object.keys(filters).length !== 0) {
601
- const op = isMany ? Operation.DELETE : Operation.UPDATE
602
- const body = isMany ? null : { [colName]: null }
579
+ const operation = isUpdate
580
+ ? DataSourceOperation.UPDATE
581
+ : DataSourceOperation.CREATE
582
+ if (!found) {
603
583
  promises.push(
604
584
  getDatasourceAndQuery({
605
- endpoint: getEndpoint(tableId, op),
585
+ endpoint: getEndpoint(tableId, operation),
586
+ // if we're doing many relationships then we're writing, only one response
606
587
  body,
607
- filters,
588
+ filters: buildFilters(id, {}, linkTable),
608
589
  })
609
590
  )
591
+ } else {
592
+ // remove the relationship from cache so it isn't adjusted again
593
+ rows.splice(rows.indexOf(found), 1)
594
+ }
595
+ }
596
+ // finally cleanup anything that needs to be removed
597
+ for (let [colName, { isMany, rows, tableId }] of Object.entries(
598
+ related
599
+ )) {
600
+ const table: Table | undefined = this.getTable(tableId)
601
+ // if its not the foreign key skip it, nothing to do
602
+ if (
603
+ !table ||
604
+ (table.primary && table.primary.indexOf(colName) !== -1)
605
+ ) {
606
+ continue
607
+ }
608
+ for (let row of rows) {
609
+ const filters = buildFilters(generateIdForRow(row, table), {}, table)
610
+ // safety check, if there are no filters on deletion bad things happen
611
+ if (Object.keys(filters).length !== 0) {
612
+ const op = isMany
613
+ ? DataSourceOperation.DELETE
614
+ : DataSourceOperation.UPDATE
615
+ const body = isMany ? null : { [colName]: null }
616
+ promises.push(
617
+ getDatasourceAndQuery({
618
+ endpoint: getEndpoint(tableId, op),
619
+ body,
620
+ filters,
621
+ })
622
+ )
623
+ }
610
624
  }
611
625
  }
626
+ await Promise.all(promises)
612
627
  }
613
- await Promise.all(promises)
614
- }
615
628
 
616
- /**
617
- * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which
618
- * you have column overlap in relationships, e.g. we join a few different tables and they all have the
619
- * concept of an ID, but for some of them it will be null (if they say don't have a relationship).
620
- * Creating the specific list of fields that we desire, and excluding the ones that are no use to us
621
- * is more performant and has the added benefit of protecting against this scenario.
622
- */
623
- buildFields(
624
- table: Table,
625
- includeRelations: IncludeRelationship = IncludeRelationship.INCLUDE
626
- ) {
627
- function extractRealFields(table: Table, existing: string[] = []) {
628
- return Object.entries(table.schema)
629
- .filter(
630
- column =>
631
- column[1].type !== FieldTypes.LINK &&
632
- column[1].type !== FieldTypes.FORMULA &&
633
- !existing.find((field: string) => field === column[0])
634
- )
635
- .map(column => `${table.name}.${column[0]}`)
636
- }
637
- let fields = extractRealFields(table)
638
- for (let field of Object.values(table.schema)) {
639
- if (field.type !== FieldTypes.LINK || !includeRelations) {
640
- continue
629
+ /**
630
+ * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which
631
+ * you have column overlap in relationships, e.g. we join a few different tables and they all have the
632
+ * concept of an ID, but for some of them it will be null (if they say don't have a relationship).
633
+ * Creating the specific list of fields that we desire, and excluding the ones that are no use to us
634
+ * is more performant and has the added benefit of protecting against this scenario.
635
+ */
636
+ buildFields(
637
+ table: Table,
638
+ includeRelations: IncludeRelationship = IncludeRelationship.INCLUDE
639
+ ) {
640
+ function extractRealFields(table: Table, existing: string[] = []) {
641
+ return Object.entries(table.schema)
642
+ .filter(
643
+ column =>
644
+ column[1].type !== FieldTypes.LINK &&
645
+ column[1].type !== FieldTypes.FORMULA &&
646
+ !existing.find((field: string) => field === column[0])
647
+ )
648
+ .map(column => `${table.name}.${column[0]}`)
641
649
  }
642
- const { tableName: linkTableName } = breakExternalTableId(field.tableId)
643
- if (linkTableName) {
644
- const linkTable = this.tables[linkTableName]
645
- if (linkTable) {
646
- const linkedFields = extractRealFields(linkTable, fields)
647
- fields = fields.concat(linkedFields)
650
+ let fields = extractRealFields(table)
651
+ for (let field of Object.values(table.schema)) {
652
+ if (field.type !== FieldTypes.LINK || !includeRelations) {
653
+ continue
654
+ }
655
+ const { tableName: linkTableName } = breakExternalTableId(field.tableId)
656
+ if (linkTableName) {
657
+ const linkTable = this.tables[linkTableName]
658
+ if (linkTable) {
659
+ const linkedFields = extractRealFields(linkTable, fields)
660
+ fields = fields.concat(linkedFields)
661
+ }
648
662
  }
649
663
  }
664
+ return fields
650
665
  }
651
- return fields
652
- }
653
666
 
654
- async run(config: RunConfig) {
655
- const { operation, tableId } = this
656
- let { datasourceId, tableName } = breakExternalTableId(tableId)
657
- if (!tableName) {
658
- throw "Unable to run without a table name"
659
- }
660
- if (!this.datasource) {
661
- const db = context.getAppDB()
662
- this.datasource = await db.get(datasourceId)
663
- if (!this.datasource || !this.datasource.entities) {
664
- throw "No tables found, fetch tables before query."
667
+ async run(config: RunConfig) {
668
+ const { operation, tableId } = this
669
+ let { datasourceId, tableName } = breakExternalTableId(tableId)
670
+ if (!tableName) {
671
+ throw "Unable to run without a table name"
672
+ }
673
+ if (!this.datasource) {
674
+ const db = getAppDB()
675
+ this.datasource = await db.get(datasourceId)
676
+ if (!this.datasource || !this.datasource.entities) {
677
+ throw "No tables found, fetch tables before query."
678
+ }
679
+ this.tables = this.datasource.entities
665
680
  }
666
- this.tables = this.datasource.entities
667
- }
668
- const table = this.tables[tableName]
669
- let isSql = isSQL(this.datasource)
670
- if (!table) {
671
- throw `Unable to process query, table "${tableName}" not defined.`
672
- }
673
- // look for specific components of config which may not be considered acceptable
674
- let { id, row, filters, sort, paginate, rows } = cleanupConfig(
675
- config,
676
- table
677
- )
678
- filters = buildFilters(id, filters || {}, table)
679
- const relationships = this.buildRelationships(table)
680
- // clean up row on ingress using schema
681
- const processed = this.inputProcessing(row, table)
682
- row = processed.row
683
- if (
684
- operation === Operation.DELETE &&
685
- (filters == null || Object.keys(filters).length === 0)
686
- ) {
687
- throw "Deletion must be filtered"
688
- }
689
- let json = {
690
- endpoint: {
691
- datasourceId,
692
- entityId: tableName,
693
- operation,
694
- },
695
- resource: {
696
- // have to specify the fields to avoid column overlap (for SQL)
697
- fields: isSql ? this.buildFields(table) : [],
698
- },
699
- filters,
700
- sort,
701
- paginate,
702
- relationships,
703
- body: row || rows,
704
- // pass an id filter into extra, purely for mysql/returning
705
- extra: {
706
- idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
707
- },
708
- meta: {
709
- table,
710
- },
711
- }
712
- // can't really use response right now
713
- const response = await getDatasourceAndQuery(json)
714
- // handle many to many relationships now if we know the ID (could be auto increment)
715
- if (operation !== Operation.READ && processed.manyRelationships) {
716
- await this.handleManyRelationships(
717
- table._id || "",
718
- response[0],
719
- processed.manyRelationships
681
+ const table = this.tables[tableName]
682
+ let isSql = isSQL(this.datasource)
683
+ if (!table) {
684
+ throw `Unable to process query, table "${tableName}" not defined.`
685
+ }
686
+ // look for specific components of config which may not be considered acceptable
687
+ let { id, row, filters, sort, paginate, rows } = cleanupConfig(
688
+ config,
689
+ table
720
690
  )
691
+ filters = buildFilters(id, filters || {}, table)
692
+ const relationships = this.buildRelationships(table)
693
+ // clean up row on ingress using schema
694
+ const processed = this.inputProcessing(row, table)
695
+ row = processed.row
696
+ if (
697
+ operation === DataSourceOperation.DELETE &&
698
+ (filters == null || Object.keys(filters).length === 0)
699
+ ) {
700
+ throw "Deletion must be filtered"
701
+ }
702
+ let json = {
703
+ endpoint: {
704
+ datasourceId,
705
+ entityId: tableName,
706
+ operation,
707
+ },
708
+ resource: {
709
+ // have to specify the fields to avoid column overlap (for SQL)
710
+ fields: isSql ? this.buildFields(table) : [],
711
+ },
712
+ filters,
713
+ sort,
714
+ paginate,
715
+ relationships,
716
+ body: row || rows,
717
+ // pass an id filter into extra, purely for mysql/returning
718
+ extra: {
719
+ idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
720
+ },
721
+ meta: {
722
+ table,
723
+ },
724
+ }
725
+ // can't really use response right now
726
+ const response = await getDatasourceAndQuery(json)
727
+ // handle many to many relationships now if we know the ID (could be auto increment)
728
+ if (
729
+ operation !== DataSourceOperation.READ &&
730
+ processed.manyRelationships
731
+ ) {
732
+ await this.handleManyRelationships(
733
+ table._id || "",
734
+ response[0],
735
+ processed.manyRelationships
736
+ )
737
+ }
738
+ const output = this.outputProcessing(response, table, relationships)
739
+ // if reading it'll just be an array of rows, return whole thing
740
+ return operation === DataSourceOperation.READ && Array.isArray(response)
741
+ ? output
742
+ : { row: output[0], table }
721
743
  }
722
- const output = this.outputProcessing(response, table, relationships)
723
- // if reading it'll just be an array of rows, return whole thing
724
- return operation === Operation.READ && Array.isArray(response)
725
- ? output
726
- : { row: output[0], table }
727
744
  }
745
+
746
+ module.exports = ExternalRequest
728
747
  }