@budibase/server 2.1.40-alpha.5 → 2.1.41

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 (787) hide show
  1. package/__mocks__/aws-sdk.ts +0 -14
  2. package/__mocks__/node-fetch.ts +1 -5
  3. package/builder/assets/{index.8170ae19.js → index.2467ba90.js} +327 -327
  4. package/builder/assets/{index.144dddb2.css → index.534f6c29.css} +2 -2
  5. package/builder/index.html +2 -2
  6. package/coverage/clover.xml +3740 -10734
  7. package/coverage/coverage-final.json +118 -266
  8. package/coverage/lcov-report/{src/api/controllers/apikeys.ts.html → api/controllers/apikeys.js.html} +26 -26
  9. package/coverage/lcov-report/{src/api/controllers/automation.ts.html → api/controllers/automation.js.html} +75 -75
  10. package/coverage/lcov-report/{src/api/controllers/cloud.ts.html → api/controllers/cloud.js.html} +47 -47
  11. package/coverage/lcov-report/{src/api/controllers/datasource.ts.html → api/controllers/datasource.js.html} +88 -268
  12. package/coverage/lcov-report/{src/api/controllers/dev.ts.html → api/controllers/dev.js.html} +71 -53
  13. package/coverage/lcov-report/api/controllers/index.html +326 -0
  14. package/coverage/lcov-report/{src/api/controllers/integration.ts.html → api/controllers/integration.js.html} +22 -19
  15. package/coverage/lcov-report/{src/api/controllers/layout.ts.html → api/controllers/layout.js.html} +26 -26
  16. package/coverage/lcov-report/{src/api/controllers/metadata.ts.html → api/controllers/metadata.js.html} +23 -26
  17. package/coverage/lcov-report/{src/api/controllers/migrations.ts.html → api/controllers/migrations.js.html} +15 -18
  18. package/coverage/lcov-report/{src/api/controllers/permission.ts.html → api/controllers/permission.js.html} +71 -80
  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} +17 -17
  21. package/coverage/lcov-report/{src/api/controllers/role.ts.html → api/controllers/role.js.html} +56 -44
  22. package/coverage/lcov-report/{src/api/controllers/routing.ts.html → api/controllers/routing.js.html} +56 -65
  23. package/coverage/lcov-report/{src/api/controllers/row/external.ts.html → api/controllers/row/external.js.html} +94 -145
  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} +95 -137
  26. package/coverage/lcov-report/{src/api/controllers/row/internalSearch.ts.html → api/controllers/row/internalSearch.js.html} +110 -182
  27. package/coverage/lcov-report/{src/api/controllers/row/staticFormula.ts.html → api/controllers/row/staticFormula.js.html} +51 -66
  28. package/coverage/lcov-report/{src/api/controllers/row/utils.ts.html → api/controllers/row/utils.js.html} +47 -77
  29. package/coverage/lcov-report/{src/api/controllers/script.ts.html → api/controllers/script.js.html} +14 -17
  30. package/coverage/lcov-report/{src/api/controllers/table/bulkFormula.ts.html → api/controllers/table/bulkFormula.js.html} +54 -96
  31. package/coverage/lcov-report/{src/api/controllers/table/external.ts.html → api/controllers/table/external.js.html} +103 -196
  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} +37 -46
  34. package/coverage/lcov-report/{src/api/controllers/templates.ts.html → api/controllers/templates.js.html} +25 -34
  35. package/coverage/lcov-report/{src/api/controllers/user.ts.html → api/controllers/user.js.html} +85 -79
  36. package/coverage/lcov-report/{src/api/controllers/view/exporters.ts.html → api/controllers/view/exporters.js.html} +14 -20
  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} +48 -75
  39. package/coverage/lcov-report/{src/api/controllers/view/utils.ts.html → api/controllers/view/utils.js.html} +43 -61
  40. package/coverage/lcov-report/{src/api/controllers/view/viewBuilder.ts.html → api/controllers/view/viewBuilder.js.html} +32 -74
  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} +56 -35
  43. package/coverage/lcov-report/{src/api/routes/analytics.ts.html → api/routes/analytics.js.html} +14 -14
  44. package/coverage/lcov-report/{src/middleware/selfhost.ts.html → api/routes/apikeys.js.html} +27 -27
  45. package/coverage/lcov-report/{src/api/routes/automation.ts.html → api/routes/automation.js.html} +42 -48
  46. package/coverage/lcov-report/{src/api/routes/backup.ts.html → api/routes/cloud.js.html} +21 -21
  47. package/coverage/lcov-report/{src/api/routes/component.ts.html → api/routes/component.js.html} +17 -17
  48. package/coverage/lcov-report/{src/constants/screens.ts.html → api/routes/datasource.js.html} +65 -56
  49. package/coverage/lcov-report/{src/api/routes/cloud.ts.html → api/routes/deploy.js.html} +22 -25
  50. package/coverage/lcov-report/{src/automations/index.ts.html → api/routes/dev.js.html} +42 -42
  51. package/coverage/lcov-report/{src/api → api}/routes/index.html +47 -167
  52. package/coverage/lcov-report/{src/api/routes/apikeys.ts.html → api/routes/integration.js.html} +18 -18
  53. package/coverage/lcov-report/{src/api/routes/layout.ts.html → api/routes/layout.js.html} +18 -18
  54. package/coverage/lcov-report/{src/api/routes/metadata.ts.html → api/routes/metadata.js.html} +24 -24
  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} +24 -48
  57. package/coverage/lcov-report/{src/api/routes/query.ts.html → api/routes/query.js.html} +42 -33
  58. package/coverage/lcov-report/{src/db/index.ts.html → api/routes/role.js.html} +25 -28
  59. package/coverage/lcov-report/{src/api/routes/routing.ts.html → api/routes/routing.js.html} +17 -17
  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} +33 -24
  63. package/coverage/lcov-report/{src/api/routes/templates.ts.html → api/routes/templates.js.html} +18 -18
  64. package/coverage/lcov-report/{src/api/routes/user.ts.html → api/routes/user.js.html} +35 -29
  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} +58 -46
  67. package/coverage/lcov-report/{src/api/routes/view.ts.html → api/routes/view.js.html} +31 -40
  68. package/coverage/lcov-report/{src/automations/actions.ts.html → automations/actions.js.html} +41 -50
  69. package/coverage/lcov-report/{src/automations/automationUtils.ts.html → automations/automationUtils.js.html} +27 -30
  70. package/coverage/lcov-report/{src/automations/bullboard.ts.html → automations/bullboard.js.html} +33 -30
  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} +25 -40
  74. package/coverage/lcov-report/{src/automations/steps/delay.ts.html → automations/steps/delay.js.html} +17 -32
  75. package/coverage/lcov-report/{src/automations/steps/discord.ts.html → automations/steps/discord.js.html} +23 -38
  76. package/coverage/lcov-report/{src/automations/steps/executeQuery.ts.html → automations/steps/executeQuery.js.html} +26 -41
  77. package/coverage/lcov-report/{src/automations/steps/executeScript.ts.html → automations/steps/executeScript.js.html} +24 -54
  78. package/coverage/lcov-report/{src/automations/steps/filter.ts.html → automations/steps/filter.js.html} +27 -36
  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} +20 -35
  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} +33 -48
  83. package/coverage/lcov-report/{src/automations/steps/queryRows.ts.html → automations/steps/queryRows.js.html} +58 -94
  84. package/coverage/lcov-report/{src/automations/steps/sendSmtpEmail.ts.html → automations/steps/sendSmtpEmail.js.html} +22 -37
  85. package/coverage/lcov-report/{src/automations/steps/serverLog.ts.html → automations/steps/serverLog.js.html} +20 -38
  86. package/coverage/lcov-report/{src/automations/steps/slack.ts.html → automations/steps/slack.js.html} +20 -35
  87. package/coverage/lcov-report/{src/automations/steps/updateRow.ts.html → automations/steps/updateRow.js.html} +21 -36
  88. package/coverage/lcov-report/{src/automations/steps/utils.ts.html → automations/steps/utils.js.html} +26 -44
  89. package/coverage/lcov-report/{src/automations/steps/zapier.ts.html → automations/steps/zapier.js.html} +20 -38
  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/automations/triggerInfo/index.ts.html → automations/triggerInfo/index.js.html} +17 -17
  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} +47 -59
  99. package/coverage/lcov-report/{src/constants → constants}/index.html +26 -26
  100. package/coverage/lcov-report/{src/constants/index.ts.html → constants/index.js.html} +185 -173
  101. package/coverage/lcov-report/{src/constants/layouts.ts.html → constants/layouts.js.html} +34 -16
  102. package/coverage/lcov-report/{src/definitions/datasource.ts.html → constants/screens.js.html} +60 -72
  103. package/coverage/lcov-report/{src/db/inMemoryView.ts.html → db/inMemoryView.js.html} +26 -44
  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} +36 -36
  106. package/coverage/lcov-report/{src/db/linkedRows/LinkController.ts.html → db/linkedRows/LinkController.js.html} +155 -92
  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} +68 -83
  109. package/coverage/lcov-report/{src/db/linkedRows/linkUtils.ts.html → db/linkedRows/linkUtils.js.html} +46 -73
  110. package/coverage/lcov-report/{src/db/newid.ts.html → db/newid.js.html} +11 -11
  111. package/coverage/lcov-report/{src/db/utils.ts.html → db/utils.js.html} +153 -105
  112. package/coverage/lcov-report/{src/events/AutomationEmitter.ts.html → events/AutomationEmitter.js.html} +21 -36
  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} +26 -23
  115. package/coverage/lcov-report/{src/automations/triggerInfo/app.ts.html → events/utils.js.html} +72 -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} +28 -31
  120. package/coverage/lcov-report/{src/middleware/builder.ts.html → middleware/builder.js.html} +37 -43
  121. package/coverage/lcov-report/{src/middleware/currentapp.ts.html → middleware/currentapp.js.html} +68 -77
  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} +24 -24
  125. package/coverage/lcov-report/{src/middleware/resourceId.ts.html → middleware/resourceId.js.html} +25 -40
  126. package/coverage/lcov-report/{src/tests/utilities/index.ts.html → middleware/selfhost.js.html} +30 -33
  127. package/coverage/lcov-report/{src/middleware/utils.ts.html → middleware/utils.js.html} +13 -19
  128. package/coverage/lcov-report/{src/utilities/budibaseDir.ts.html → utilities/budibaseDir.js.html} +12 -12
  129. package/coverage/lcov-report/{src/utilities/centralPath.ts.html → utilities/centralPath.js.html} +13 -13
  130. package/coverage/lcov-report/{src/utilities/csvParser.ts.html → utilities/csvParser.js.html} +56 -104
  131. package/coverage/lcov-report/{src/utilities/global.ts.html → utilities/global.js.html} +74 -107
  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} +54 -78
  134. package/coverage/lcov-report/{src/utilities/plugins.ts.html → utilities/plugins.js.html} +19 -22
  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/routes/role.ts.html → utilities/routing/index.js.html} +42 -39
  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} +346 -115
  141. package/coverage/lcov-report/{src/utilities/rowProcessor/utils.ts.html → utilities/rowProcessor/utils.js.html} +38 -50
  142. package/coverage/lcov-report/{src/utilities/scriptRunner.ts.html → utilities/scriptRunner.js.html} +16 -28
  143. package/coverage/lcov-report/{src/utilities/security.ts.html → utilities/security.js.html} +74 -56
  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} +46 -34
  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} +35 -29
  149. package/coverage/lcov-report/{src/utilities/workerRequests.ts.html → utilities/workerRequests.js.html} +114 -129
  150. package/coverage/lcov.info +6967 -19532
  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 -538
  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/s3.js +1 -157
  283. package/dist/integrations/tests/TestConfiguration.js +1 -0
  284. package/dist/middleware/appInfo.js +9 -14
  285. package/dist/middleware/authorized.js +21 -22
  286. package/dist/middleware/builder.js +40 -41
  287. package/dist/middleware/currentapp.js +37 -39
  288. package/dist/middleware/joi-validator.js +10 -17
  289. package/dist/middleware/publicApi.js +6 -5
  290. package/dist/middleware/resourceId.js +9 -16
  291. package/dist/middleware/selfhost.js +4 -5
  292. package/dist/middleware/utils.js +2 -5
  293. package/dist/migrations/functions/appUrls.js +2 -2
  294. package/dist/migrations/functions/backfill/global.js +1 -1
  295. package/dist/migrations/functions/usageQuotas/syncApps.js +4 -3
  296. package/dist/migrations/functions/usageQuotas/syncRows.js +4 -3
  297. package/dist/migrations/functions/userEmailViewCasing.js +3 -3
  298. package/dist/package.json +45 -11
  299. package/dist/sdk/app/backups/exports.js +2 -1
  300. package/dist/sdk/app/backups/imports.js +3 -2
  301. package/dist/sdk/app/tables/index.js +5 -5
  302. package/dist/startup.js +10 -10
  303. package/dist/tests/utilities/TestConfiguration.js +87 -111
  304. package/dist/tests/utilities/controllers.js +15 -38
  305. package/dist/tests/utilities/structures.js +53 -72
  306. package/dist/threads/automation.js +27 -49
  307. package/dist/threads/query.js +19 -17
  308. package/dist/threads/utils.js +8 -33
  309. package/dist/tsconfig.build.tsbuildinfo +1 -1
  310. package/dist/utilities/budibaseDir.js +2 -4
  311. package/dist/utilities/centralPath.js +7 -14
  312. package/dist/utilities/csvParser.js +21 -27
  313. package/dist/utilities/fileSystem/clientLibrary.js +73 -87
  314. package/dist/utilities/fileSystem/index.js +175 -203
  315. package/dist/utilities/fileSystem/processor.js +3 -8
  316. package/dist/utilities/fileSystem/utilities.js +22 -0
  317. package/dist/utilities/global.js +66 -87
  318. package/dist/utilities/index.js +75 -102
  319. package/dist/utilities/plugins.js +9 -15
  320. package/dist/utilities/queue/inMemoryQueue.js +126 -0
  321. package/dist/utilities/redis.js +65 -100
  322. package/dist/utilities/routing/index.js +23 -27
  323. package/dist/utilities/rowProcessor/index.js +191 -133
  324. package/dist/utilities/rowProcessor/utils.js +26 -35
  325. package/dist/utilities/scriptRunner.js +5 -8
  326. package/dist/utilities/security.js +35 -39
  327. package/dist/utilities/usageQuota/rows.js +49 -56
  328. package/dist/utilities/users.js +28 -31
  329. package/dist/utilities/workerRequests.js +82 -115
  330. package/dist/watch.js +2 -1
  331. package/package.json +46 -12
  332. package/scripts/exportAppTemplate.js +2 -2
  333. package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +2 -11
  334. package/scripts/localdomain.js +6 -34
  335. package/src/api/controllers/{apikeys.ts → apikeys.js} +10 -10
  336. package/src/api/controllers/application.ts +42 -56
  337. package/src/api/controllers/auth.ts +3 -4
  338. package/src/api/controllers/{automation.ts → automation.js} +48 -48
  339. package/src/api/controllers/{cloud.ts → cloud.js} +24 -24
  340. package/src/api/controllers/component.ts +1 -2
  341. package/src/api/controllers/{datasource.ts → datasource.js} +49 -109
  342. package/src/api/controllers/deploy/{Deployment.ts → Deployment.js} +10 -13
  343. package/src/api/controllers/deploy/index.ts +25 -13
  344. package/src/api/controllers/{dev.ts → dev.js} +37 -31
  345. package/src/api/controllers/integration.js +14 -0
  346. package/src/api/controllers/{layout.ts → layout.js} +8 -8
  347. package/src/api/controllers/{metadata.ts → metadata.js} +10 -11
  348. package/src/api/controllers/migrations.js +13 -0
  349. package/src/api/controllers/{permission.ts → permission.js} +46 -49
  350. package/src/api/controllers/plugin/index.ts +5 -4
  351. package/src/api/controllers/plugin/utils.ts +5 -3
  352. package/src/api/controllers/public/applications.ts +9 -15
  353. package/src/api/controllers/public/rows.ts +1 -1
  354. package/src/api/controllers/public/tables.ts +2 -2
  355. package/src/api/controllers/public/utils.ts +2 -2
  356. package/src/api/controllers/query/import/index.ts +3 -2
  357. package/src/api/controllers/query/index.ts +14 -11
  358. package/src/api/controllers/query/{validation.ts → validation.js} +7 -7
  359. package/src/api/controllers/{role.ts → role.js} +25 -21
  360. package/src/api/controllers/{routing.ts → routing.js} +34 -37
  361. package/src/api/controllers/row/ExternalRequest.ts +624 -602
  362. package/src/api/controllers/row/{external.ts → external.js} +62 -79
  363. package/src/api/controllers/row/index.ts +11 -19
  364. package/src/api/controllers/row/{internal.ts → internal.js} +73 -87
  365. package/src/api/controllers/row/{internalSearch.ts → internalSearch.js} +68 -92
  366. package/src/api/controllers/row/{staticFormula.ts → staticFormula.js} +25 -30
  367. package/src/api/controllers/row/{utils.ts → utils.js} +22 -32
  368. package/src/api/controllers/screen.ts +6 -10
  369. package/src/api/controllers/script.js +11 -0
  370. package/src/api/controllers/static/index.ts +16 -14
  371. package/src/api/controllers/table/{bulkFormula.ts → bulkFormula.js} +25 -39
  372. package/src/api/controllers/table/{external.ts → external.js} +55 -86
  373. package/src/api/controllers/table/{index.ts → index.js} +18 -21
  374. package/src/api/controllers/table/internal.ts +6 -5
  375. package/src/api/controllers/table/utils.ts +21 -26
  376. package/src/api/controllers/{templates.ts → templates.js} +7 -10
  377. package/src/api/controllers/{user.ts → user.js} +49 -47
  378. package/src/api/controllers/view/{exporters.ts → exporters.js} +3 -5
  379. package/src/api/controllers/view/{index.ts → index.js} +27 -36
  380. package/src/api/controllers/view/{utils.ts → utils.js} +20 -26
  381. package/src/api/controllers/view/{viewBuilder.ts → viewBuilder.js} +11 -25
  382. package/src/api/controllers/webhook.ts +1 -1
  383. package/src/api/{index.ts → index.js} +22 -15
  384. package/src/api/routes/analytics.js +9 -0
  385. package/src/api/routes/apikeys.js +12 -0
  386. package/src/api/routes/application.ts +9 -17
  387. package/src/api/routes/auth.ts +2 -2
  388. package/src/api/routes/automation.js +85 -0
  389. package/src/api/routes/backup.ts +4 -8
  390. package/src/api/routes/cloud.js +14 -0
  391. package/src/api/routes/component.js +14 -0
  392. package/src/api/routes/datasource.js +51 -0
  393. package/src/api/routes/deploy.js +17 -0
  394. package/src/api/routes/dev.js +26 -0
  395. package/src/api/routes/integration.js +12 -0
  396. package/src/api/routes/layout.js +16 -0
  397. package/src/api/routes/{metadata.ts → metadata.js} +13 -13
  398. package/src/api/routes/migrations.js +14 -0
  399. package/src/api/routes/permission.js +33 -0
  400. package/src/api/routes/plugin.ts +6 -14
  401. package/src/api/routes/public/index.ts +14 -11
  402. package/src/api/routes/public/tests/compare.spec.js +1 -1
  403. package/src/api/routes/{query.ts → query.js} +22 -19
  404. package/src/api/routes/role.js +15 -0
  405. package/src/api/routes/routing.js +14 -0
  406. package/src/api/routes/row.ts +15 -13
  407. package/src/api/routes/screen.js +18 -0
  408. package/src/api/routes/script.js +10 -0
  409. package/src/api/routes/static.ts +10 -7
  410. package/src/api/routes/{table.ts → table.js} +13 -10
  411. package/src/api/routes/templates.js +16 -0
  412. package/src/api/routes/tests/analytics.spec.js +1 -1
  413. package/src/api/routes/tests/backup.spec.js +1 -9
  414. package/src/api/routes/tests/deployment.spec.ts +1 -1
  415. package/src/api/routes/tests/permissions.spec.js +1 -2
  416. package/src/api/routes/tests/query.spec.js +10 -15
  417. package/src/api/routes/tests/role.spec.js +9 -7
  418. package/src/api/routes/tests/routing.spec.js +1 -2
  419. package/src/api/routes/tests/row.spec.js +4 -3
  420. package/src/api/routes/tests/static.spec.js +2 -2
  421. package/src/api/routes/tests/table.spec.js +36 -40
  422. package/src/api/routes/tests/user.spec.js +1 -2
  423. package/src/api/routes/tests/utilities/TestFunctions.ts +8 -6
  424. package/src/api/routes/tests/utilities/{index.ts → index.js} +12 -12
  425. package/src/api/routes/tests/view.spec.js +3 -3
  426. package/src/api/routes/user.js +53 -0
  427. package/src/api/routes/utils/{validators.ts → validators.js} +37 -33
  428. package/src/api/routes/view.js +31 -0
  429. package/src/api/routes/webhook.ts +2 -2
  430. package/src/app.ts +14 -15
  431. package/src/automations/{actions.ts → actions.js} +23 -26
  432. package/src/automations/{automationUtils.ts → automationUtils.js} +12 -13
  433. package/src/automations/bullboard.js +39 -0
  434. package/src/automations/index.js +29 -0
  435. package/src/automations/steps/{bash.ts → bash.js} +8 -13
  436. package/src/automations/steps/createRow.ts +3 -8
  437. package/src/automations/steps/{delay.ts → delay.js} +4 -9
  438. package/src/automations/steps/deleteRow.ts +3 -8
  439. package/src/automations/steps/{discord.ts → discord.js} +5 -10
  440. package/src/automations/steps/{executeQuery.ts → executeQuery.js} +7 -12
  441. package/src/automations/steps/{executeScript.ts → executeScript.js} +7 -17
  442. package/src/automations/steps/{filter.ts → filter.js} +9 -12
  443. package/src/automations/steps/{integromat.ts → integromat.js} +5 -10
  444. package/src/automations/steps/{loop.ts → loop.js} +2 -4
  445. package/src/automations/steps/{outgoingWebhook.ts → outgoingWebhook.js} +13 -18
  446. package/src/automations/steps/{queryRows.ts → queryRows.js} +36 -48
  447. package/src/automations/steps/{sendSmtpEmail.ts → sendSmtpEmail.js} +5 -10
  448. package/src/automations/steps/{serverLog.ts → serverLog.js} +3 -9
  449. package/src/automations/steps/{slack.ts → slack.js} +5 -10
  450. package/src/automations/steps/{updateRow.ts → updateRow.js} +7 -12
  451. package/src/automations/steps/{utils.ts → utils.js} +4 -10
  452. package/src/automations/steps/{zapier.ts → zapier.js} +5 -11
  453. package/src/automations/tests/updateRow.spec.js +1 -0
  454. package/src/automations/tests/utilities/index.js +51 -0
  455. package/src/automations/triggerInfo/{app.ts → app.js} +2 -7
  456. package/src/automations/triggerInfo/{cron.ts → cron.js} +2 -7
  457. package/src/automations/triggerInfo/index.js +15 -0
  458. package/src/automations/triggerInfo/{rowDeleted.ts → rowDeleted.js} +2 -7
  459. package/src/automations/triggerInfo/{rowSaved.ts → rowSaved.js} +2 -7
  460. package/src/automations/triggerInfo/{rowUpdated.ts → rowUpdated.js} +2 -7
  461. package/src/automations/triggerInfo/{webhook.ts → webhook.js} +2 -7
  462. package/src/automations/{triggers.ts → triggers.js} +26 -30
  463. package/src/automations/utils.ts +12 -9
  464. package/src/constants/index.js +208 -0
  465. package/src/constants/{layouts.ts → layouts.js} +9 -3
  466. package/src/constants/screens.js +46 -0
  467. package/src/db/{dynamoClient.ts → dynamoClient.js} +19 -39
  468. package/src/db/{inMemoryView.ts → inMemoryView.js} +9 -15
  469. package/src/db/index.js +16 -0
  470. package/src/db/linkedRows/{LinkController.ts → LinkController.js} +85 -64
  471. package/src/db/linkedRows/{index.ts → index.js} +38 -43
  472. package/src/db/linkedRows/{linkUtils.ts → linkUtils.js} +24 -33
  473. package/src/db/{newid.ts → newid.js} +1 -1
  474. package/src/db/tests/linkController.spec.js +57 -73
  475. package/src/db/tests/linkTests.spec.js +14 -17
  476. package/src/db/{utils.ts → utils.js} +93 -77
  477. package/src/db/views/{staticViews.ts → staticViews.js} +13 -20
  478. package/src/{environment.ts → environment.js} +7 -11
  479. package/src/events/{AutomationEmitter.ts → AutomationEmitter.js} +7 -12
  480. package/src/events/{BudibaseEmitter.ts → index.js} +8 -7
  481. package/src/events/utils.js +38 -0
  482. package/src/integrations/base/sql.ts +1 -1
  483. package/src/integrations/base/sqlTable.ts +1 -1
  484. package/src/integrations/elasticsearch.ts +2 -32
  485. package/src/integrations/googlesheets.ts +7 -5
  486. package/src/integrations/index.ts +41 -45
  487. package/src/integrations/s3.ts +3 -179
  488. package/src/integrations/tests/s3.spec.ts +1 -85
  489. package/src/integrations/utils.ts +2 -6
  490. package/src/middleware/appInfo.js +19 -0
  491. package/src/middleware/authorized.ts +28 -21
  492. package/src/middleware/{builder.ts → builder.js} +15 -17
  493. package/src/middleware/{currentapp.ts → currentapp.js} +39 -42
  494. package/src/middleware/{joi-validator.ts → joi-validator.js} +8 -9
  495. package/src/middleware/publicApi.js +21 -0
  496. package/src/middleware/{resourceId.ts → resourceId.js} +11 -16
  497. package/src/middleware/{selfhost.ts → selfhost.js} +2 -4
  498. package/src/middleware/tests/authorized.spec.js +6 -5
  499. package/src/middleware/tests/currentapp.spec.js +63 -118
  500. package/src/middleware/{utils.ts → utils.js} +1 -3
  501. package/src/migrations/functions/appUrls.ts +2 -2
  502. package/src/migrations/functions/backfill/app/tables.ts +5 -2
  503. package/src/migrations/functions/backfill/global.ts +1 -1
  504. package/src/migrations/functions/tests/appUrls.spec.js +4 -4
  505. package/src/migrations/functions/tests/userEmailViewCasing.spec.js +9 -14
  506. package/src/migrations/functions/usageQuotas/syncApps.ts +4 -3
  507. package/src/migrations/functions/usageQuotas/syncRows.ts +5 -4
  508. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +7 -7
  509. package/src/migrations/functions/userEmailViewCasing.ts +3 -3
  510. package/src/migrations/tests/index.spec.ts +1 -1
  511. package/src/module.d.ts +14 -0
  512. package/src/sdk/app/backups/exports.ts +3 -5
  513. package/src/sdk/app/backups/imports.ts +14 -7
  514. package/src/sdk/app/backups/statistics.ts +18 -9
  515. package/src/sdk/app/tables/index.ts +8 -7
  516. package/src/startup.ts +5 -5
  517. package/src/tests/utilities/{TestConfiguration.ts → TestConfiguration.js} +78 -111
  518. package/src/tests/utilities/controllers.js +16 -0
  519. package/src/tests/utilities/{index.ts → index.js} +2 -2
  520. package/src/tests/utilities/{structures.ts → structures.js} +36 -41
  521. package/src/threads/automation.ts +19 -18
  522. package/src/threads/query.ts +16 -11
  523. package/src/threads/utils.ts +5 -4
  524. package/src/utilities/budibaseDir.js +3 -0
  525. package/src/utilities/{centralPath.ts → centralPath.js} +3 -3
  526. package/src/utilities/{csvParser.ts → csvParser.js} +26 -42
  527. package/src/utilities/fileSystem/{clientLibrary.ts → clientLibrary.js} +20 -20
  528. package/src/utilities/fileSystem/{index.ts → index.js} +65 -61
  529. package/src/utilities/fileSystem/{processor.ts → processor.js} +5 -3
  530. package/src/utilities/fileSystem/utilities.js +36 -0
  531. package/src/utilities/global.js +127 -0
  532. package/src/utilities/{index.ts → index.js} +32 -40
  533. package/src/utilities/{plugins.ts → plugins.js} +4 -5
  534. package/src/utilities/queue/inMemoryQueue.js +122 -0
  535. package/src/utilities/{redis.ts → redis.js} +20 -21
  536. package/src/utilities/routing/index.js +25 -0
  537. package/src/utilities/rowProcessor/{index.ts → index.js} +144 -67
  538. package/src/utilities/rowProcessor/{utils.ts → utils.js} +15 -19
  539. package/src/utilities/{scriptRunner.ts → scriptRunner.js} +4 -8
  540. package/src/utilities/security.js +71 -0
  541. package/src/utilities/{statusCodes.ts → statusCodes.js} +1 -1
  542. package/src/utilities/usageQuota/{rows.ts → rows.js} +18 -14
  543. package/src/utilities/usageQuota/{usageQuoteReset.ts → usageQuoteReset.js} +1 -1
  544. package/src/utilities/{users.ts → users.js} +13 -11
  545. package/src/utilities/{workerRequests.ts → workerRequests.js} +38 -43
  546. package/src/watch.ts +3 -2
  547. package/tsconfig.build.json +2 -1
  548. package/tsconfig.json +1 -3
  549. package/coverage/lcov-report/src/api/controllers/analytics.ts.html +0 -190
  550. package/coverage/lcov-report/src/api/controllers/application.ts.html +0 -2038
  551. package/coverage/lcov-report/src/api/controllers/auth.ts.html +0 -301
  552. package/coverage/lcov-report/src/api/controllers/backup.ts.html +0 -148
  553. package/coverage/lcov-report/src/api/controllers/component.ts.html +0 -259
  554. package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +0 -259
  555. package/coverage/lcov-report/src/api/controllers/deploy/index.html +0 -131
  556. package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +0 -730
  557. package/coverage/lcov-report/src/api/controllers/index.html +0 -431
  558. package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +0 -130
  559. package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +0 -310
  560. package/coverage/lcov-report/src/api/controllers/plugin/index.html +0 -206
  561. package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +0 -484
  562. package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +0 -253
  563. package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +0 -97
  564. package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +0 -121
  565. package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +0 -136
  566. package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +0 -334
  567. package/coverage/lcov-report/src/api/controllers/public/index.html +0 -191
  568. package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +0 -181
  569. package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +0 -191
  570. package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +0 -124
  571. package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +0 -202
  572. package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +0 -178
  573. package/coverage/lcov-report/src/api/controllers/public/mapping/tables.ts.html +0 -163
  574. package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +0 -181
  575. package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +0 -145
  576. package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +0 -328
  577. package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +0 -253
  578. package/coverage/lcov-report/src/api/controllers/public/users.ts.html +0 -268
  579. package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +0 -220
  580. package/coverage/lcov-report/src/api/controllers/query/import/index.html +0 -116
  581. package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +0 -373
  582. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +0 -131
  583. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +0 -379
  584. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +0 -157
  585. package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +0 -403
  586. package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +0 -146
  587. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +0 -586
  588. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +0 -712
  589. package/coverage/lcov-report/src/api/controllers/query/index.html +0 -131
  590. package/coverage/lcov-report/src/api/controllers/query/index.ts.html +0 -976
  591. package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +0 -2260
  592. package/coverage/lcov-report/src/api/controllers/row/index.ts.html +0 -541
  593. package/coverage/lcov-report/src/api/controllers/screen.ts.html +0 -463
  594. package/coverage/lcov-report/src/api/controllers/static/index.html +0 -116
  595. package/coverage/lcov-report/src/api/controllers/static/index.ts.html +0 -694
  596. package/coverage/lcov-report/src/api/controllers/table/index.html +0 -176
  597. package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +0 -661
  598. package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +0 -1255
  599. package/coverage/lcov-report/src/api/controllers/webhook.ts.html +0 -379
  600. package/coverage/lcov-report/src/api/routes/application.ts.html +0 -223
  601. package/coverage/lcov-report/src/api/routes/auth.ts.html +0 -109
  602. package/coverage/lcov-report/src/api/routes/datasource.ts.html +0 -265
  603. package/coverage/lcov-report/src/api/routes/deploy.ts.html +0 -148
  604. package/coverage/lcov-report/src/api/routes/dev.ts.html +0 -199
  605. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -289
  606. package/coverage/lcov-report/src/api/routes/migrations.ts.html +0 -127
  607. package/coverage/lcov-report/src/api/routes/plugin.ts.html +0 -151
  608. package/coverage/lcov-report/src/api/routes/public/applications.ts.html +0 -541
  609. package/coverage/lcov-report/src/api/routes/public/index.html +0 -191
  610. package/coverage/lcov-report/src/api/routes/public/index.ts.html +0 -493
  611. package/coverage/lcov-report/src/api/routes/public/middleware/index.html +0 -116
  612. package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +0 -328
  613. package/coverage/lcov-report/src/api/routes/public/queries.ts.html +0 -313
  614. package/coverage/lcov-report/src/api/routes/public/rows.ts.html +0 -598
  615. package/coverage/lcov-report/src/api/routes/public/tables.ts.html +0 -586
  616. package/coverage/lcov-report/src/api/routes/public/users.ts.html +0 -511
  617. package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +0 -238
  618. package/coverage/lcov-report/src/api/routes/public/utils/index.html +0 -116
  619. package/coverage/lcov-report/src/api/routes/row.ts.html +0 -883
  620. package/coverage/lcov-report/src/api/routes/screen.ts.html +0 -154
  621. package/coverage/lcov-report/src/api/routes/static.ts.html +0 -280
  622. package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +0 -550
  623. package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +0 -131
  624. package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +0 -367
  625. package/coverage/lcov-report/src/api/routes/webhook.ts.html +0 -166
  626. package/coverage/lcov-report/src/app.ts.html +0 -406
  627. package/coverage/lcov-report/src/automations/logging/index.html +0 -116
  628. package/coverage/lcov-report/src/automations/logging/index.ts.html +0 -199
  629. package/coverage/lcov-report/src/automations/steps/createRow.ts.html +0 -382
  630. package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +0 -349
  631. package/coverage/lcov-report/src/automations/steps/index.html +0 -371
  632. package/coverage/lcov-report/src/automations/tests/utilities/index.html +0 -116
  633. package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +0 -265
  634. package/coverage/lcov-report/src/automations/utils.ts.html +0 -886
  635. package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +0 -2059
  636. package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +0 -541
  637. package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +0 -427
  638. package/coverage/lcov-report/src/db/defaultData/index.html +0 -176
  639. package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +0 -403
  640. package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +0 -559
  641. package/coverage/lcov-report/src/db/dynamoClient.ts.html +0 -526
  642. package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +0 -265
  643. package/coverage/lcov-report/src/db/linkedRows/index.html +0 -161
  644. package/coverage/lcov-report/src/environment.ts.html +0 -457
  645. package/coverage/lcov-report/src/events/index.ts.html +0 -100
  646. package/coverage/lcov-report/src/events/utils.ts.html +0 -319
  647. package/coverage/lcov-report/src/index.html +0 -191
  648. package/coverage/lcov-report/src/index.ts.html +0 -133
  649. package/coverage/lcov-report/src/integrations/arangodb.ts.html +0 -415
  650. package/coverage/lcov-report/src/integrations/base/index.html +0 -161
  651. package/coverage/lcov-report/src/integrations/base/query.ts.html +0 -133
  652. package/coverage/lcov-report/src/integrations/base/sql.ts.html +0 -1951
  653. package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +0 -691
  654. package/coverage/lcov-report/src/integrations/base/utils.ts.html +0 -121
  655. package/coverage/lcov-report/src/integrations/couchdb.ts.html +0 -406
  656. package/coverage/lcov-report/src/integrations/dynamodb.ts.html +0 -745
  657. package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +0 -634
  658. package/coverage/lcov-report/src/integrations/firebase.ts.html +0 -646
  659. package/coverage/lcov-report/src/integrations/googlesheets.ts.html +0 -1315
  660. package/coverage/lcov-report/src/integrations/index.html +0 -371
  661. package/coverage/lcov-report/src/integrations/index.ts.html +0 -445
  662. package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +0 -1006
  663. package/coverage/lcov-report/src/integrations/mongodb.ts.html +0 -1867
  664. package/coverage/lcov-report/src/integrations/mysql.ts.html +0 -964
  665. package/coverage/lcov-report/src/integrations/oracle.ts.html +0 -1474
  666. package/coverage/lcov-report/src/integrations/postgres.ts.html +0 -1069
  667. package/coverage/lcov-report/src/integrations/queries/index.html +0 -116
  668. package/coverage/lcov-report/src/integrations/queries/sql.ts.html +0 -463
  669. package/coverage/lcov-report/src/integrations/redis.ts.html +0 -550
  670. package/coverage/lcov-report/src/integrations/rest.ts.html +0 -1381
  671. package/coverage/lcov-report/src/integrations/s3.ts.html +0 -862
  672. package/coverage/lcov-report/src/integrations/snowflake.ts.html +0 -376
  673. package/coverage/lcov-report/src/integrations/utils.ts.html +0 -1018
  674. package/coverage/lcov-report/src/middleware/authorized.ts.html +0 -460
  675. package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +0 -187
  676. package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +0 -163
  677. package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +0 -151
  678. package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +0 -206
  679. package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +0 -172
  680. package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +0 -226
  681. package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +0 -151
  682. package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +0 -151
  683. package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +0 -166
  684. package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +0 -532
  685. package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +0 -283
  686. package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +0 -146
  687. package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +0 -265
  688. package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +0 -232
  689. package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +0 -724
  690. package/coverage/lcov-report/src/migrations/functions/backfill/index.html +0 -161
  691. package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +0 -106
  692. package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +0 -235
  693. package/coverage/lcov-report/src/migrations/functions/index.html +0 -146
  694. package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +0 -130
  695. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +0 -161
  696. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +0 -94
  697. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +0 -127
  698. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +0 -115
  699. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +0 -169
  700. package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +0 -124
  701. package/coverage/lcov-report/src/migrations/index.ts.html +0 -403
  702. package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +0 -205
  703. package/coverage/lcov-report/src/migrations/tests/index.html +0 -131
  704. package/coverage/lcov-report/src/migrations/tests/structures.ts.html +0 -283
  705. package/coverage/lcov-report/src/sdk/app/automations/index.html +0 -131
  706. package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +0 -100
  707. package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +0 -214
  708. package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +0 -91
  709. package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +0 -604
  710. package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +0 -682
  711. package/coverage/lcov-report/src/sdk/app/backups/index.html +0 -176
  712. package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +0 -112
  713. package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +0 -292
  714. package/coverage/lcov-report/src/sdk/app/tables/index.html +0 -116
  715. package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +0 -265
  716. package/coverage/lcov-report/src/startup.ts.html +0 -499
  717. package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +0 -1966
  718. package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +0 -127
  719. package/coverage/lcov-report/src/tests/utilities/index.html +0 -161
  720. package/coverage/lcov-report/src/tests/utilities/structures.ts.html +0 -667
  721. package/coverage/lcov-report/src/threads/automation.ts.html +0 -1594
  722. package/coverage/lcov-report/src/threads/index.html +0 -161
  723. package/coverage/lcov-report/src/threads/index.ts.html +0 -418
  724. package/coverage/lcov-report/src/threads/query.ts.html +0 -961
  725. package/coverage/lcov-report/src/threads/utils.ts.html +0 -373
  726. package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +0 -547
  727. package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +0 -1129
  728. package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +0 -142
  729. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -343
  730. package/coverage/lcov-report/src/utilities/routing/index.ts.html +0 -181
  731. package/coverage/lcov-report/src/utilities/rowProcessor/index.html +0 -146
  732. package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +0 -373
  733. package/coverage/lcov-report/src/watch.ts.html +0 -196
  734. package/dist/db/defaultData/datasource_bb_default.js +0 -573
  735. package/dist/db/defaultData/employeeImport.js +0 -155
  736. package/dist/db/defaultData/expensesImport.js +0 -117
  737. package/dist/db/defaultData/inventoryImport.js +0 -109
  738. package/dist/db/defaultData/jobsImport.js +0 -152
  739. package/dist/db/linkedRows/LinkDocument.js +0 -32
  740. package/dist/events/BudibaseEmitter.js +0 -24
  741. package/dist/utilities/rowProcessor/map.js +0 -99
  742. package/jest.config.ts +0 -33
  743. package/src/api/controllers/integration.ts +0 -13
  744. package/src/api/controllers/migrations.ts +0 -14
  745. package/src/api/controllers/script.ts +0 -12
  746. package/src/api/routes/analytics.ts +0 -9
  747. package/src/api/routes/apikeys.ts +0 -12
  748. package/src/api/routes/automation.ts +0 -87
  749. package/src/api/routes/cloud.ts +0 -18
  750. package/src/api/routes/component.ts +0 -14
  751. package/src/api/routes/datasource.ts +0 -60
  752. package/src/api/routes/deploy.ts +0 -21
  753. package/src/api/routes/dev.ts +0 -38
  754. package/src/api/routes/integration.ts +0 -16
  755. package/src/api/routes/layout.ts +0 -16
  756. package/src/api/routes/migrations.ts +0 -14
  757. package/src/api/routes/permission.ts +0 -41
  758. package/src/api/routes/role.ts +0 -24
  759. package/src/api/routes/routing.ts +0 -14
  760. package/src/api/routes/screen.ts +0 -23
  761. package/src/api/routes/script.ts +0 -10
  762. package/src/api/routes/templates.ts +0 -16
  763. package/src/api/routes/user.ts +0 -51
  764. package/src/api/routes/view.ts +0 -34
  765. package/src/automations/bullboard.ts +0 -38
  766. package/src/automations/index.ts +0 -26
  767. package/src/automations/tests/utilities/index.ts +0 -60
  768. package/src/automations/triggerInfo/index.ts +0 -15
  769. package/src/constants/index.ts +0 -204
  770. package/src/constants/screens.ts +0 -48
  771. package/src/db/defaultData/datasource_bb_default.ts +0 -658
  772. package/src/db/defaultData/employeeImport.ts +0 -152
  773. package/src/db/defaultData/expensesImport.ts +0 -114
  774. package/src/db/defaultData/inventoryImport.ts +0 -106
  775. package/src/db/defaultData/jobsImport.ts +0 -158
  776. package/src/db/index.ts +0 -16
  777. package/src/db/linkedRows/LinkDocument.ts +0 -60
  778. package/src/events/index.ts +0 -5
  779. package/src/events/utils.ts +0 -78
  780. package/src/middleware/appInfo.ts +0 -20
  781. package/src/middleware/publicApi.ts +0 -21
  782. package/src/tests/utilities/controllers.ts +0 -14
  783. package/src/utilities/budibaseDir.ts +0 -3
  784. package/src/utilities/global.ts +0 -138
  785. package/src/utilities/routing/index.ts +0 -32
  786. package/src/utilities/rowProcessor/map.ts +0 -96
  787. 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,692 +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
- }
421
- const thisRow = fixArrayTypes(basicProcessing(row, table), table)
422
- if (thisRow._id == null) {
423
- throw "Unable to generate row ID for SQL rows"
424
440
  }
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 (!table || (table.primary && table.primary.indexOf(colName) !== -1)) {
592
- continue
593
- }
594
- for (let row of rows) {
595
- const filters = buildFilters(generateIdForRow(row, table), {}, table)
596
- // safety check, if there are no filters on deletion bad things happen
597
- if (Object.keys(filters).length !== 0) {
598
- const op = isMany ? Operation.DELETE : Operation.UPDATE
599
- const body = isMany ? null : { [colName]: null }
579
+ const operation = isUpdate
580
+ ? DataSourceOperation.UPDATE
581
+ : DataSourceOperation.CREATE
582
+ if (!found) {
600
583
  promises.push(
601
584
  getDatasourceAndQuery({
602
- endpoint: getEndpoint(tableId, op),
585
+ endpoint: getEndpoint(tableId, operation),
586
+ // if we're doing many relationships then we're writing, only one response
603
587
  body,
604
- filters,
588
+ filters: buildFilters(id, {}, linkTable),
605
589
  })
606
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
+ }
607
624
  }
608
625
  }
626
+ await Promise.all(promises)
609
627
  }
610
- await Promise.all(promises)
611
- }
612
628
 
613
- /**
614
- * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which
615
- * you have column overlap in relationships, e.g. we join a few different tables and they all have the
616
- * concept of an ID, but for some of them it will be null (if they say don't have a relationship).
617
- * Creating the specific list of fields that we desire, and excluding the ones that are no use to us
618
- * is more performant and has the added benefit of protecting against this scenario.
619
- */
620
- buildFields(
621
- table: Table,
622
- includeRelations: IncludeRelationship = IncludeRelationship.INCLUDE
623
- ) {
624
- function extractRealFields(table: Table, existing: string[] = []) {
625
- return Object.entries(table.schema)
626
- .filter(
627
- column =>
628
- column[1].type !== FieldTypes.LINK &&
629
- column[1].type !== FieldTypes.FORMULA &&
630
- !existing.find((field: string) => field === column[0])
631
- )
632
- .map(column => `${table.name}.${column[0]}`)
633
- }
634
- let fields = extractRealFields(table)
635
- for (let field of Object.values(table.schema)) {
636
- if (field.type !== FieldTypes.LINK || !includeRelations) {
637
- 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]}`)
638
649
  }
639
- const { tableName: linkTableName } = breakExternalTableId(field.tableId)
640
- if (linkTableName) {
641
- const linkTable = this.tables[linkTableName]
642
- if (linkTable) {
643
- const linkedFields = extractRealFields(linkTable, fields)
644
- 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
+ }
645
662
  }
646
663
  }
664
+ return fields
647
665
  }
648
- return fields
649
- }
650
666
 
651
- async run(config: RunConfig) {
652
- const { operation, tableId } = this
653
- let { datasourceId, tableName } = breakExternalTableId(tableId)
654
- if (!tableName) {
655
- throw "Unable to run without a table name"
656
- }
657
- if (!this.datasource) {
658
- const db = context.getAppDB()
659
- this.datasource = await db.get(datasourceId)
660
- if (!this.datasource || !this.datasource.entities) {
661
- 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
662
680
  }
663
- this.tables = this.datasource.entities
664
- }
665
- const table = this.tables[tableName]
666
- let isSql = isSQL(this.datasource)
667
- if (!table) {
668
- throw `Unable to process query, table "${tableName}" not defined.`
669
- }
670
- // look for specific components of config which may not be considered acceptable
671
- let { id, row, filters, sort, paginate, rows } = cleanupConfig(
672
- config,
673
- table
674
- )
675
- filters = buildFilters(id, filters || {}, table)
676
- const relationships = this.buildRelationships(table)
677
- // clean up row on ingress using schema
678
- const processed = this.inputProcessing(row, table)
679
- row = processed.row
680
- if (
681
- operation === Operation.DELETE &&
682
- (filters == null || Object.keys(filters).length === 0)
683
- ) {
684
- throw "Deletion must be filtered"
685
- }
686
- let json = {
687
- endpoint: {
688
- datasourceId,
689
- entityId: tableName,
690
- operation,
691
- },
692
- resource: {
693
- // have to specify the fields to avoid column overlap (for SQL)
694
- fields: isSql ? this.buildFields(table) : [],
695
- },
696
- filters,
697
- sort,
698
- paginate,
699
- relationships,
700
- body: row || rows,
701
- // pass an id filter into extra, purely for mysql/returning
702
- extra: {
703
- idFilter: buildFilters(id || generateIdForRow(row, table), {}, table),
704
- },
705
- meta: {
706
- table,
707
- },
708
- }
709
- // can't really use response right now
710
- const response = await getDatasourceAndQuery(json)
711
- // handle many to many relationships now if we know the ID (could be auto increment)
712
- if (operation !== Operation.READ && processed.manyRelationships) {
713
- await this.handleManyRelationships(
714
- table._id || "",
715
- response[0],
716
- 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
717
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 }
718
743
  }
719
- const output = this.outputProcessing(response, table, relationships)
720
- // if reading it'll just be an array of rows, return whole thing
721
- return operation === Operation.READ && Array.isArray(response)
722
- ? output
723
- : { row: output[0], table }
724
744
  }
745
+
746
+ module.exports = ExternalRequest
725
747
  }