@budibase/server 2.1.43-alpha.1 → 2.1.43

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 (798) hide show
  1. package/__mocks__/aws-sdk.ts +0 -14
  2. package/__mocks__/node-fetch.ts +1 -5
  3. package/builder/assets/index.534f6c29.css +6 -0
  4. package/builder/assets/index.fb99ddaf.js +1021 -0
  5. package/builder/index.html +2 -2
  6. package/coverage/clover.xml +3875 -10924
  7. package/coverage/coverage-final.json +118 -267
  8. package/coverage/lcov-report/{src/api/controllers/apikeys.ts.html → api/controllers/apikeys.js.html} +30 -30
  9. package/coverage/lcov-report/{src/api/controllers/automation.ts.html → api/controllers/automation.js.html} +99 -99
  10. package/coverage/lcov-report/{src/api/controllers/cloud.ts.html → api/controllers/cloud.js.html} +58 -58
  11. package/coverage/lcov-report/{src/api/controllers/datasource.ts.html → api/controllers/datasource.js.html} +107 -287
  12. package/coverage/lcov-report/{src/api/controllers/dev.ts.html → api/controllers/dev.js.html} +87 -69
  13. package/coverage/lcov-report/api/controllers/index.html +326 -0
  14. package/coverage/lcov-report/{src/middleware/selfhost.ts.html → api/controllers/integration.js.html} +28 -22
  15. package/coverage/lcov-report/{src/api/controllers/layout.ts.html → api/controllers/layout.js.html} +31 -31
  16. package/coverage/lcov-report/{src/api/controllers/metadata.ts.html → api/controllers/metadata.js.html} +30 -33
  17. package/coverage/lcov-report/{src/api/controllers/migrations.ts.html → api/controllers/migrations.js.html} +17 -20
  18. package/coverage/lcov-report/{src/api/controllers/permission.ts.html → api/controllers/permission.js.html} +79 -88
  19. package/coverage/lcov-report/{src/utilities/routing → api/controllers/query}/index.html +8 -8
  20. package/coverage/lcov-report/{src/api/controllers/query/validation.ts.html → api/controllers/query/validation.js.html} +25 -25
  21. package/coverage/lcov-report/{src/api/controllers/role.ts.html → api/controllers/role.js.html} +60 -48
  22. package/coverage/lcov-report/{src/api/controllers/routing.ts.html → api/controllers/routing.js.html} +58 -67
  23. package/coverage/lcov-report/{src/api/controllers/row/external.ts.html → api/controllers/row/external.js.html} +111 -162
  24. package/coverage/lcov-report/{src/api → api}/controllers/row/index.html +52 -82
  25. package/coverage/lcov-report/{src/api/controllers/row/internal.ts.html → api/controllers/row/internal.js.html} +121 -163
  26. package/coverage/lcov-report/{src/api/controllers/row/internalSearch.ts.html → api/controllers/row/internalSearch.js.html} +117 -189
  27. package/coverage/lcov-report/{src/api/controllers/row/staticFormula.ts.html → api/controllers/row/staticFormula.js.html} +58 -73
  28. package/coverage/lcov-report/{src/api/controllers/row/utils.ts.html → api/controllers/row/utils.js.html} +58 -88
  29. package/coverage/lcov-report/{src/api/controllers/script.ts.html → api/controllers/script.js.html} +16 -19
  30. package/coverage/lcov-report/{src/api/controllers/table/bulkFormula.ts.html → api/controllers/table/bulkFormula.js.html} +62 -104
  31. package/coverage/lcov-report/{src/api/controllers/table/external.ts.html → api/controllers/table/external.js.html} +111 -204
  32. package/coverage/lcov-report/{src/utilities/fileSystem → api/controllers/table}/index.html +44 -44
  33. package/coverage/lcov-report/{src/api/controllers/table/index.ts.html → api/controllers/table/index.js.html} +49 -58
  34. package/coverage/lcov-report/{src/api/controllers/templates.ts.html → api/controllers/templates.js.html} +29 -38
  35. package/coverage/lcov-report/{src/api/controllers/user.ts.html → api/controllers/user.js.html} +99 -93
  36. package/coverage/lcov-report/{src/api/controllers/view/exporters.ts.html → api/controllers/view/exporters.js.html} +16 -22
  37. package/coverage/lcov-report/{src/api → api}/controllers/view/index.html +36 -36
  38. package/coverage/lcov-report/{src/api/controllers/view/index.ts.html → api/controllers/view/index.js.html} +64 -91
  39. package/coverage/lcov-report/{src/api/controllers/view/utils.ts.html → api/controllers/view/utils.js.html} +54 -72
  40. package/coverage/lcov-report/{src/api/controllers/view/viewBuilder.ts.html → api/controllers/view/viewBuilder.js.html} +36 -78
  41. package/coverage/lcov-report/{src/api → api}/index.html +23 -23
  42. package/coverage/lcov-report/{src/api/index.ts.html → api/index.js.html} +76 -55
  43. package/coverage/lcov-report/{src/middleware/utils.ts.html → api/routes/analytics.js.html} +19 -19
  44. package/coverage/lcov-report/api/routes/apikeys.js.html +121 -0
  45. package/coverage/lcov-report/{src/api/routes/automation.ts.html → api/routes/automation.js.html} +47 -53
  46. package/coverage/lcov-report/{src/api/routes/backup.ts.html → api/routes/cloud.js.html} +28 -28
  47. package/coverage/lcov-report/{src/api/routes/component.ts.html → api/routes/component.js.html} +24 -24
  48. package/coverage/lcov-report/{src/definitions/datasource.ts.html → api/routes/datasource.js.html} +64 -61
  49. package/coverage/lcov-report/{src/api/routes/cloud.ts.html → api/routes/deploy.js.html} +28 -31
  50. package/coverage/lcov-report/{src/automations/index.ts.html → api/routes/dev.js.html} +46 -46
  51. package/coverage/lcov-report/{src/api → api}/routes/index.html +47 -167
  52. package/coverage/lcov-report/api/routes/integration.js.html +121 -0
  53. package/coverage/lcov-report/{src/db/index.ts.html → api/routes/layout.js.html} +28 -28
  54. package/coverage/lcov-report/{src/api/routes/metadata.ts.html → api/routes/metadata.js.html} +31 -31
  55. package/coverage/lcov-report/{src/sdk/index.ts.html → api/routes/migrations.js.html} +21 -24
  56. package/coverage/lcov-report/{src/api/routes/permission.ts.html → api/routes/permission.js.html} +31 -55
  57. package/coverage/lcov-report/{src/api/routes/query.ts.html → api/routes/query.js.html} +50 -41
  58. package/coverage/lcov-report/api/routes/role.js.html +130 -0
  59. package/coverage/lcov-report/{src/api/routes/routing.ts.html → api/routes/routing.js.html} +24 -24
  60. package/coverage/lcov-report/api/routes/screen.js.html +139 -0
  61. package/coverage/lcov-report/{src/api/routes/script.ts.html → api/routes/script.js.html} +17 -17
  62. package/coverage/lcov-report/{src/api/routes/table.ts.html → api/routes/table.js.html} +41 -32
  63. package/coverage/lcov-report/{src/api/routes/templates.ts.html → api/routes/templates.js.html} +25 -25
  64. package/coverage/lcov-report/{src/api/routes/user.ts.html → api/routes/user.js.html} +41 -35
  65. package/coverage/lcov-report/{src/api → api}/routes/utils/index.html +15 -15
  66. package/coverage/lcov-report/{src/api/routes/utils/validators.ts.html → api/routes/utils/validators.js.html} +98 -86
  67. package/coverage/lcov-report/{src/api/routes/view.ts.html → api/routes/view.js.html} +36 -45
  68. package/coverage/lcov-report/{src/automations/actions.ts.html → automations/actions.js.html} +60 -69
  69. package/coverage/lcov-report/{src/automations/automationUtils.ts.html → automations/automationUtils.js.html} +33 -36
  70. package/coverage/lcov-report/{src/automations/bullboard.ts.html → automations/bullboard.js.html} +42 -39
  71. package/coverage/lcov-report/{src/automations → automations}/index.html +48 -63
  72. package/coverage/lcov-report/{src/websocket.ts.html → automations/index.js.html} +50 -41
  73. package/coverage/lcov-report/{src/automations/steps/bash.ts.html → automations/steps/bash.js.html} +30 -45
  74. package/coverage/lcov-report/{src/automations/steps/delay.ts.html → automations/steps/delay.js.html} +19 -34
  75. package/coverage/lcov-report/{src/automations/steps/discord.ts.html → automations/steps/discord.js.html} +28 -43
  76. package/coverage/lcov-report/{src/automations/steps/executeQuery.ts.html → automations/steps/executeQuery.js.html} +30 -45
  77. package/coverage/lcov-report/{src/automations/steps/executeScript.ts.html → automations/steps/executeScript.js.html} +28 -58
  78. package/coverage/lcov-report/{src/automations/steps/filter.ts.html → automations/steps/filter.js.html} +30 -39
  79. package/coverage/lcov-report/automations/steps/index.html +341 -0
  80. package/coverage/lcov-report/{src/automations/steps/integromat.ts.html → automations/steps/integromat.js.html} +23 -38
  81. package/coverage/lcov-report/{src/automations/steps/loop.ts.html → automations/steps/loop.js.html} +15 -21
  82. package/coverage/lcov-report/{src/automations/steps/outgoingWebhook.ts.html → automations/steps/outgoingWebhook.js.html} +39 -54
  83. package/coverage/lcov-report/{src/automations/steps/queryRows.ts.html → automations/steps/queryRows.js.html} +66 -102
  84. package/coverage/lcov-report/{src/automations/steps/sendSmtpEmail.ts.html → automations/steps/sendSmtpEmail.js.html} +25 -40
  85. package/coverage/lcov-report/{src/automations/steps/serverLog.ts.html → automations/steps/serverLog.js.html} +22 -40
  86. package/coverage/lcov-report/{src/automations/steps/slack.ts.html → automations/steps/slack.js.html} +23 -38
  87. package/coverage/lcov-report/{src/automations/steps/updateRow.ts.html → automations/steps/updateRow.js.html} +25 -40
  88. package/coverage/lcov-report/{src/automations/steps/utils.ts.html → automations/steps/utils.js.html} +27 -45
  89. package/coverage/lcov-report/{src/automations/steps/zapier.ts.html → automations/steps/zapier.js.html} +23 -41
  90. package/coverage/lcov-report/{src/definitions/automations.ts.html → automations/triggerInfo/app.js.html} +42 -42
  91. package/coverage/lcov-report/{src/automations/triggerInfo/cron.ts.html → automations/triggerInfo/cron.js.html} +15 -30
  92. package/coverage/lcov-report/{src/automations → automations}/triggerInfo/index.html +31 -31
  93. package/coverage/lcov-report/{src/api/routes/layout.ts.html → automations/triggerInfo/index.js.html} +26 -29
  94. package/coverage/lcov-report/{src/automations/triggerInfo/rowDeleted.ts.html → automations/triggerInfo/rowDeleted.js.html} +15 -30
  95. package/coverage/lcov-report/{src/automations/triggerInfo/rowSaved.ts.html → automations/triggerInfo/rowSaved.js.html} +15 -30
  96. package/coverage/lcov-report/{src/automations/triggerInfo/rowUpdated.ts.html → automations/triggerInfo/rowUpdated.js.html} +15 -30
  97. package/coverage/lcov-report/{src/automations/triggerInfo/webhook.ts.html → automations/triggerInfo/webhook.js.html} +15 -30
  98. package/coverage/lcov-report/{src/automations/triggers.ts.html → automations/triggers.js.html} +66 -78
  99. package/coverage/lcov-report/{src/constants → constants}/index.html +26 -26
  100. package/coverage/lcov-report/{src/integrations/dynamodb.ts.html → constants/index.js.html} +227 -263
  101. package/coverage/lcov-report/{src/constants/layouts.ts.html → constants/layouts.js.html} +36 -18
  102. package/coverage/lcov-report/{src/constants/screens.ts.html → constants/screens.js.html} +58 -64
  103. package/coverage/lcov-report/{src/db/inMemoryView.ts.html → db/inMemoryView.js.html} +29 -47
  104. package/coverage/lcov-report/{src/db → db}/index.html +33 -48
  105. package/coverage/lcov-report/{src/api/routes/integration.ts.html → db/index.js.html} +33 -33
  106. package/coverage/lcov-report/{src/db/linkedRows/LinkController.ts.html → db/linkedRows/LinkController.js.html} +160 -97
  107. package/coverage/lcov-report/db/linkedRows/index.html +146 -0
  108. package/coverage/lcov-report/{src/db/linkedRows/index.ts.html → db/linkedRows/index.js.html} +78 -93
  109. package/coverage/lcov-report/{src/db/linkedRows/linkUtils.ts.html → db/linkedRows/linkUtils.js.html} +56 -83
  110. package/coverage/lcov-report/{src/db/newid.ts.html → db/newid.js.html} +14 -14
  111. package/coverage/lcov-report/{src/db/utils.ts.html → db/utils.js.html} +211 -163
  112. package/coverage/lcov-report/{src/events/AutomationEmitter.ts.html → events/AutomationEmitter.js.html} +25 -40
  113. package/coverage/lcov-report/{src/events → events}/index.html +33 -48
  114. package/coverage/lcov-report/{src/events/BudibaseEmitter.ts.html → events/index.js.html} +29 -26
  115. package/coverage/lcov-report/{src/api/routes/dev.ts.html → events/utils.js.html} +69 -69
  116. package/coverage/lcov-report/index.html +184 -679
  117. package/coverage/lcov-report/{src/integrations → integrations}/tests/TestConfiguration.js.html +10 -10
  118. package/coverage/lcov-report/{src/integrations → integrations}/tests/index.html +10 -10
  119. package/coverage/lcov-report/{src/middleware/appInfo.ts.html → middleware/appInfo.js.html} +30 -33
  120. package/coverage/lcov-report/{src/middleware/builder.ts.html → middleware/builder.js.html} +40 -46
  121. package/coverage/lcov-report/{src/middleware/currentapp.ts.html → middleware/currentapp.js.html} +72 -81
  122. package/coverage/lcov-report/{src/middleware → middleware}/index.html +63 -78
  123. package/coverage/lcov-report/{src/middleware/joi-validator.ts.html → middleware/joi-validator.js.html} +22 -25
  124. package/coverage/lcov-report/{src/middleware/publicApi.ts.html → middleware/publicApi.js.html} +27 -27
  125. package/coverage/lcov-report/{src/middleware/resourceId.ts.html → middleware/resourceId.js.html} +45 -60
  126. package/coverage/lcov-report/{src/tests/utilities/index.ts.html → middleware/selfhost.js.html} +30 -33
  127. package/coverage/lcov-report/{src/events/index.ts.html → middleware/utils.js.html} +24 -18
  128. package/coverage/lcov-report/{src/utilities/budibaseDir.ts.html → utilities/budibaseDir.js.html} +14 -14
  129. package/coverage/lcov-report/{src/utilities/centralPath.ts.html → utilities/centralPath.js.html} +16 -16
  130. package/coverage/lcov-report/{src/utilities/csvParser.ts.html → utilities/csvParser.js.html} +59 -107
  131. package/coverage/lcov-report/{src/utilities/global.ts.html → utilities/global.js.html} +82 -115
  132. package/coverage/lcov-report/{src/utilities → utilities}/index.html +77 -92
  133. package/coverage/lcov-report/{src/utilities/index.ts.html → utilities/index.js.html} +74 -98
  134. package/coverage/lcov-report/{src/utilities/plugins.ts.html → utilities/plugins.js.html} +22 -25
  135. package/coverage/lcov-report/{src/integrations/airtable.ts.html → utilities/queue/inMemoryQueue.js.html} +135 -213
  136. package/coverage/lcov-report/{src/migrations → utilities/queue}/index.html +23 -23
  137. package/coverage/lcov-report/{src/sdk → utilities/routing}/index.html +10 -10
  138. package/coverage/lcov-report/{src/api/controllers/public/mapping/tables.ts.html → utilities/routing/index.js.html} +43 -46
  139. package/coverage/lcov-report/{src/definitions → utilities/rowProcessor}/index.html +34 -34
  140. package/coverage/lcov-report/{src/utilities/rowProcessor/index.ts.html → utilities/rowProcessor/index.js.html} +359 -128
  141. package/coverage/lcov-report/{src/utilities/rowProcessor/utils.ts.html → utilities/rowProcessor/utils.js.html} +42 -54
  142. package/coverage/lcov-report/{src/utilities/scriptRunner.ts.html → utilities/scriptRunner.js.html} +19 -31
  143. package/coverage/lcov-report/{src/utilities/security.ts.html → utilities/security.js.html} +78 -60
  144. package/coverage/lcov-report/{src/utilities/statusCodes.ts.html → utilities/statusCodes.js.html} +11 -11
  145. package/coverage/lcov-report/{src/utilities → utilities}/usageQuota/index.html +28 -28
  146. package/coverage/lcov-report/{src/utilities/usageQuota/rows.ts.html → utilities/usageQuota/rows.js.html} +48 -36
  147. package/coverage/lcov-report/{src/utilities/usageQuota/usageQuoteReset.ts.html → utilities/usageQuota/usageQuoteReset.js.html} +13 -13
  148. package/coverage/lcov-report/{src/utilities/users.ts.html → utilities/users.js.html} +40 -34
  149. package/coverage/lcov-report/{src/utilities/workerRequests.ts.html → utilities/workerRequests.js.html} +112 -127
  150. package/coverage/lcov.info +7069 -19741
  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/migrations/index.js +0 -5
  299. package/dist/package.json +45 -11
  300. package/dist/sdk/app/backups/exports.js +2 -1
  301. package/dist/sdk/app/backups/imports.js +3 -2
  302. package/dist/sdk/app/tables/index.js +5 -5
  303. package/dist/startup.js +10 -10
  304. package/dist/tests/utilities/TestConfiguration.js +87 -111
  305. package/dist/tests/utilities/controllers.js +15 -38
  306. package/dist/tests/utilities/structures.js +53 -72
  307. package/dist/threads/automation.js +27 -49
  308. package/dist/threads/query.js +19 -17
  309. package/dist/threads/utils.js +8 -33
  310. package/dist/tsconfig.build.tsbuildinfo +1 -1
  311. package/dist/utilities/budibaseDir.js +2 -4
  312. package/dist/utilities/centralPath.js +7 -14
  313. package/dist/utilities/csvParser.js +21 -27
  314. package/dist/utilities/fileSystem/clientLibrary.js +73 -87
  315. package/dist/utilities/fileSystem/index.js +175 -203
  316. package/dist/utilities/fileSystem/processor.js +3 -8
  317. package/dist/utilities/fileSystem/utilities.js +22 -0
  318. package/dist/utilities/global.js +66 -87
  319. package/dist/utilities/index.js +75 -102
  320. package/dist/utilities/plugins.js +9 -15
  321. package/dist/utilities/queue/inMemoryQueue.js +126 -0
  322. package/dist/utilities/redis.js +65 -100
  323. package/dist/utilities/routing/index.js +23 -27
  324. package/dist/utilities/rowProcessor/index.js +191 -133
  325. package/dist/utilities/rowProcessor/utils.js +26 -35
  326. package/dist/utilities/scriptRunner.js +5 -8
  327. package/dist/utilities/security.js +35 -39
  328. package/dist/utilities/usageQuota/rows.js +49 -56
  329. package/dist/utilities/users.js +28 -31
  330. package/dist/utilities/workerRequests.js +82 -115
  331. package/dist/watch.js +2 -1
  332. package/package.json +46 -12
  333. package/scripts/exportAppTemplate.js +2 -2
  334. package/{src/tests/jestSetup.ts → scripts/jestSetup.js} +2 -11
  335. package/scripts/localdomain.js +6 -34
  336. package/src/api/controllers/{apikeys.ts → apikeys.js} +10 -10
  337. package/src/api/controllers/application.ts +42 -56
  338. package/src/api/controllers/auth.ts +3 -4
  339. package/src/api/controllers/{automation.ts → automation.js} +48 -48
  340. package/src/api/controllers/{cloud.ts → cloud.js} +24 -24
  341. package/src/api/controllers/component.ts +1 -2
  342. package/src/api/controllers/{datasource.ts → datasource.js} +49 -109
  343. package/src/api/controllers/deploy/{Deployment.ts → Deployment.js} +10 -13
  344. package/src/api/controllers/deploy/index.ts +25 -13
  345. package/src/api/controllers/{dev.ts → dev.js} +37 -31
  346. package/src/api/controllers/integration.js +14 -0
  347. package/src/api/controllers/{layout.ts → layout.js} +8 -8
  348. package/src/api/controllers/{metadata.ts → metadata.js} +10 -11
  349. package/src/api/controllers/migrations.js +13 -0
  350. package/src/api/controllers/{permission.ts → permission.js} +46 -49
  351. package/src/api/controllers/plugin/index.ts +5 -4
  352. package/src/api/controllers/plugin/utils.ts +5 -3
  353. package/src/api/controllers/public/applications.ts +9 -15
  354. package/src/api/controllers/public/rows.ts +1 -1
  355. package/src/api/controllers/public/tables.ts +2 -2
  356. package/src/api/controllers/public/utils.ts +2 -2
  357. package/src/api/controllers/query/import/index.ts +3 -2
  358. package/src/api/controllers/query/index.ts +14 -11
  359. package/src/api/controllers/query/{validation.ts → validation.js} +7 -7
  360. package/src/api/controllers/{role.ts → role.js} +25 -21
  361. package/src/api/controllers/{routing.ts → routing.js} +34 -37
  362. package/src/api/controllers/row/ExternalRequest.ts +624 -602
  363. package/src/api/controllers/row/{external.ts → external.js} +62 -79
  364. package/src/api/controllers/row/index.ts +11 -19
  365. package/src/api/controllers/row/{internal.ts → internal.js} +73 -87
  366. package/src/api/controllers/row/{internalSearch.ts → internalSearch.js} +68 -92
  367. package/src/api/controllers/row/{staticFormula.ts → staticFormula.js} +25 -30
  368. package/src/api/controllers/row/{utils.ts → utils.js} +22 -32
  369. package/src/api/controllers/screen.ts +6 -10
  370. package/src/api/controllers/script.js +11 -0
  371. package/src/api/controllers/static/index.ts +16 -14
  372. package/src/api/controllers/table/{bulkFormula.ts → bulkFormula.js} +25 -39
  373. package/src/api/controllers/table/{external.ts → external.js} +55 -86
  374. package/src/api/controllers/table/{index.ts → index.js} +18 -21
  375. package/src/api/controllers/table/internal.ts +6 -5
  376. package/src/api/controllers/table/utils.ts +21 -26
  377. package/src/api/controllers/{templates.ts → templates.js} +7 -10
  378. package/src/api/controllers/{user.ts → user.js} +49 -47
  379. package/src/api/controllers/view/{exporters.ts → exporters.js} +3 -5
  380. package/src/api/controllers/view/{index.ts → index.js} +27 -36
  381. package/src/api/controllers/view/{utils.ts → utils.js} +20 -26
  382. package/src/api/controllers/view/{viewBuilder.ts → viewBuilder.js} +11 -25
  383. package/src/api/controllers/webhook.ts +1 -1
  384. package/src/api/{index.ts → index.js} +22 -15
  385. package/src/api/routes/analytics.js +9 -0
  386. package/src/api/routes/apikeys.js +12 -0
  387. package/src/api/routes/application.ts +9 -17
  388. package/src/api/routes/auth.ts +2 -2
  389. package/src/api/routes/automation.js +85 -0
  390. package/src/api/routes/backup.ts +4 -8
  391. package/src/api/routes/cloud.js +14 -0
  392. package/src/api/routes/component.js +14 -0
  393. package/src/api/routes/datasource.js +51 -0
  394. package/src/api/routes/deploy.js +17 -0
  395. package/src/api/routes/dev.js +26 -0
  396. package/src/api/routes/integration.js +12 -0
  397. package/src/api/routes/layout.js +16 -0
  398. package/src/api/routes/{metadata.ts → metadata.js} +13 -13
  399. package/src/api/routes/migrations.js +14 -0
  400. package/src/api/routes/permission.js +33 -0
  401. package/src/api/routes/plugin.ts +6 -14
  402. package/src/api/routes/public/index.ts +14 -11
  403. package/src/api/routes/public/tests/compare.spec.js +1 -1
  404. package/src/api/routes/{query.ts → query.js} +22 -19
  405. package/src/api/routes/role.js +15 -0
  406. package/src/api/routes/routing.js +14 -0
  407. package/src/api/routes/row.ts +15 -13
  408. package/src/api/routes/screen.js +18 -0
  409. package/src/api/routes/script.js +10 -0
  410. package/src/api/routes/static.ts +10 -7
  411. package/src/api/routes/{table.ts → table.js} +13 -10
  412. package/src/api/routes/templates.js +16 -0
  413. package/src/api/routes/tests/analytics.spec.js +1 -1
  414. package/src/api/routes/tests/backup.spec.js +1 -9
  415. package/src/api/routes/tests/deployment.spec.ts +1 -1
  416. package/src/api/routes/tests/permissions.spec.js +1 -2
  417. package/src/api/routes/tests/query.spec.js +10 -15
  418. package/src/api/routes/tests/role.spec.js +9 -7
  419. package/src/api/routes/tests/routing.spec.js +1 -2
  420. package/src/api/routes/tests/row.spec.js +4 -3
  421. package/src/api/routes/tests/static.spec.js +2 -2
  422. package/src/api/routes/tests/table.spec.js +36 -40
  423. package/src/api/routes/tests/user.spec.js +1 -2
  424. package/src/api/routes/tests/utilities/TestFunctions.ts +8 -6
  425. package/src/api/routes/tests/utilities/{index.ts → index.js} +12 -12
  426. package/src/api/routes/tests/view.spec.js +3 -3
  427. package/src/api/routes/user.js +53 -0
  428. package/src/api/routes/utils/{validators.ts → validators.js} +37 -33
  429. package/src/api/routes/view.js +31 -0
  430. package/src/api/routes/webhook.ts +2 -2
  431. package/src/app.ts +14 -15
  432. package/src/automations/{actions.ts → actions.js} +23 -26
  433. package/src/automations/{automationUtils.ts → automationUtils.js} +12 -13
  434. package/src/automations/bullboard.js +39 -0
  435. package/src/automations/index.js +29 -0
  436. package/src/automations/steps/{bash.ts → bash.js} +8 -13
  437. package/src/automations/steps/createRow.ts +3 -8
  438. package/src/automations/steps/{delay.ts → delay.js} +4 -9
  439. package/src/automations/steps/deleteRow.ts +3 -8
  440. package/src/automations/steps/{discord.ts → discord.js} +5 -10
  441. package/src/automations/steps/{executeQuery.ts → executeQuery.js} +7 -12
  442. package/src/automations/steps/{executeScript.ts → executeScript.js} +7 -17
  443. package/src/automations/steps/{filter.ts → filter.js} +9 -12
  444. package/src/automations/steps/{integromat.ts → integromat.js} +5 -10
  445. package/src/automations/steps/{loop.ts → loop.js} +2 -4
  446. package/src/automations/steps/{outgoingWebhook.ts → outgoingWebhook.js} +13 -18
  447. package/src/automations/steps/{queryRows.ts → queryRows.js} +36 -48
  448. package/src/automations/steps/{sendSmtpEmail.ts → sendSmtpEmail.js} +5 -10
  449. package/src/automations/steps/{serverLog.ts → serverLog.js} +3 -9
  450. package/src/automations/steps/{slack.ts → slack.js} +5 -10
  451. package/src/automations/steps/{updateRow.ts → updateRow.js} +7 -12
  452. package/src/automations/steps/{utils.ts → utils.js} +4 -10
  453. package/src/automations/steps/{zapier.ts → zapier.js} +5 -11
  454. package/src/automations/tests/updateRow.spec.js +1 -0
  455. package/src/automations/tests/utilities/index.js +51 -0
  456. package/src/automations/triggerInfo/{app.ts → app.js} +2 -7
  457. package/src/automations/triggerInfo/{cron.ts → cron.js} +2 -7
  458. package/src/automations/triggerInfo/index.js +15 -0
  459. package/src/automations/triggerInfo/{rowDeleted.ts → rowDeleted.js} +2 -7
  460. package/src/automations/triggerInfo/{rowSaved.ts → rowSaved.js} +2 -7
  461. package/src/automations/triggerInfo/{rowUpdated.ts → rowUpdated.js} +2 -7
  462. package/src/automations/triggerInfo/{webhook.ts → webhook.js} +2 -7
  463. package/src/automations/{triggers.ts → triggers.js} +26 -30
  464. package/src/automations/utils.ts +12 -9
  465. package/src/constants/index.js +208 -0
  466. package/src/constants/{layouts.ts → layouts.js} +9 -3
  467. package/src/constants/screens.js +46 -0
  468. package/src/db/{dynamoClient.ts → dynamoClient.js} +19 -39
  469. package/src/db/{inMemoryView.ts → inMemoryView.js} +9 -15
  470. package/src/db/index.js +16 -0
  471. package/src/db/linkedRows/{LinkController.ts → LinkController.js} +85 -64
  472. package/src/db/linkedRows/{index.ts → index.js} +38 -43
  473. package/src/db/linkedRows/{linkUtils.ts → linkUtils.js} +24 -33
  474. package/src/db/{newid.ts → newid.js} +1 -1
  475. package/src/db/tests/linkController.spec.js +57 -73
  476. package/src/db/tests/linkTests.spec.js +14 -17
  477. package/src/db/{utils.ts → utils.js} +93 -77
  478. package/src/db/views/{staticViews.ts → staticViews.js} +13 -20
  479. package/src/{environment.ts → environment.js} +7 -11
  480. package/src/events/{AutomationEmitter.ts → AutomationEmitter.js} +7 -12
  481. package/src/events/{BudibaseEmitter.ts → index.js} +8 -7
  482. package/src/events/utils.js +38 -0
  483. package/src/integrations/base/sql.ts +1 -1
  484. package/src/integrations/base/sqlTable.ts +1 -1
  485. package/src/integrations/elasticsearch.ts +2 -32
  486. package/src/integrations/googlesheets.ts +7 -5
  487. package/src/integrations/index.ts +41 -45
  488. package/src/integrations/s3.ts +3 -179
  489. package/src/integrations/tests/s3.spec.ts +1 -85
  490. package/src/integrations/utils.ts +2 -6
  491. package/src/middleware/appInfo.js +19 -0
  492. package/src/middleware/authorized.ts +28 -21
  493. package/src/middleware/{builder.ts → builder.js} +15 -17
  494. package/src/middleware/{currentapp.ts → currentapp.js} +39 -42
  495. package/src/middleware/{joi-validator.ts → joi-validator.js} +8 -9
  496. package/src/middleware/publicApi.js +21 -0
  497. package/src/middleware/{resourceId.ts → resourceId.js} +11 -16
  498. package/src/middleware/{selfhost.ts → selfhost.js} +2 -4
  499. package/src/middleware/tests/authorized.spec.js +6 -5
  500. package/src/middleware/tests/currentapp.spec.js +63 -118
  501. package/src/middleware/{utils.ts → utils.js} +1 -3
  502. package/src/migrations/functions/appUrls.ts +2 -2
  503. package/src/migrations/functions/backfill/app/tables.ts +5 -2
  504. package/src/migrations/functions/backfill/global.ts +1 -1
  505. package/src/migrations/functions/tests/appUrls.spec.js +4 -4
  506. package/src/migrations/functions/tests/userEmailViewCasing.spec.js +9 -14
  507. package/src/migrations/functions/usageQuotas/syncApps.ts +4 -3
  508. package/src/migrations/functions/usageQuotas/syncRows.ts +5 -4
  509. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +7 -7
  510. package/src/migrations/functions/userEmailViewCasing.ts +3 -3
  511. package/src/migrations/index.ts +0 -9
  512. package/src/migrations/tests/index.spec.ts +1 -1
  513. package/src/module.d.ts +14 -0
  514. package/src/sdk/app/backups/exports.ts +3 -5
  515. package/src/sdk/app/backups/imports.ts +14 -7
  516. package/src/sdk/app/backups/statistics.ts +18 -9
  517. package/src/sdk/app/tables/index.ts +8 -7
  518. package/src/startup.ts +5 -5
  519. package/src/tests/utilities/{TestConfiguration.ts → TestConfiguration.js} +78 -111
  520. package/src/tests/utilities/controllers.js +16 -0
  521. package/src/tests/utilities/{index.ts → index.js} +2 -2
  522. package/src/tests/utilities/{structures.ts → structures.js} +36 -41
  523. package/src/threads/automation.ts +19 -18
  524. package/src/threads/query.ts +16 -11
  525. package/src/threads/utils.ts +5 -4
  526. package/src/utilities/budibaseDir.js +3 -0
  527. package/src/utilities/{centralPath.ts → centralPath.js} +3 -3
  528. package/src/utilities/{csvParser.ts → csvParser.js} +26 -42
  529. package/src/utilities/fileSystem/{clientLibrary.ts → clientLibrary.js} +20 -20
  530. package/src/utilities/fileSystem/{index.ts → index.js} +65 -61
  531. package/src/utilities/fileSystem/{processor.ts → processor.js} +5 -3
  532. package/src/utilities/fileSystem/utilities.js +36 -0
  533. package/src/utilities/global.js +127 -0
  534. package/src/utilities/{index.ts → index.js} +32 -40
  535. package/src/utilities/{plugins.ts → plugins.js} +4 -5
  536. package/src/utilities/queue/inMemoryQueue.js +122 -0
  537. package/src/utilities/{redis.ts → redis.js} +20 -21
  538. package/src/utilities/routing/index.js +25 -0
  539. package/src/utilities/rowProcessor/{index.ts → index.js} +144 -67
  540. package/src/utilities/rowProcessor/{utils.ts → utils.js} +15 -19
  541. package/src/utilities/{scriptRunner.ts → scriptRunner.js} +4 -8
  542. package/src/utilities/security.js +71 -0
  543. package/src/utilities/{statusCodes.ts → statusCodes.js} +1 -1
  544. package/src/utilities/usageQuota/{rows.ts → rows.js} +18 -14
  545. package/src/utilities/usageQuota/{usageQuoteReset.ts → usageQuoteReset.js} +1 -1
  546. package/src/utilities/{users.ts → users.js} +13 -11
  547. package/src/utilities/{workerRequests.ts → workerRequests.js} +38 -43
  548. package/src/watch.ts +3 -2
  549. package/tsconfig.build.json +2 -1
  550. package/tsconfig.json +1 -3
  551. package/builder/assets/index.0c44dac3.css +0 -6
  552. package/builder/assets/index.8935424b.js +0 -1021
  553. package/coverage/lcov-report/src/api/controllers/analytics.ts.html +0 -190
  554. package/coverage/lcov-report/src/api/controllers/application.ts.html +0 -2038
  555. package/coverage/lcov-report/src/api/controllers/auth.ts.html +0 -301
  556. package/coverage/lcov-report/src/api/controllers/backup.ts.html +0 -148
  557. package/coverage/lcov-report/src/api/controllers/component.ts.html +0 -259
  558. package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +0 -259
  559. package/coverage/lcov-report/src/api/controllers/deploy/index.html +0 -131
  560. package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +0 -730
  561. package/coverage/lcov-report/src/api/controllers/index.html +0 -431
  562. package/coverage/lcov-report/src/api/controllers/integration.ts.html +0 -124
  563. package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +0 -130
  564. package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +0 -310
  565. package/coverage/lcov-report/src/api/controllers/plugin/index.html +0 -206
  566. package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +0 -484
  567. package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +0 -253
  568. package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +0 -97
  569. package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +0 -121
  570. package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +0 -136
  571. package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +0 -334
  572. package/coverage/lcov-report/src/api/controllers/public/index.html +0 -191
  573. package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +0 -181
  574. package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +0 -191
  575. package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +0 -124
  576. package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +0 -202
  577. package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +0 -178
  578. package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +0 -181
  579. package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +0 -145
  580. package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +0 -328
  581. package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +0 -253
  582. package/coverage/lcov-report/src/api/controllers/public/users.ts.html +0 -268
  583. package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +0 -220
  584. package/coverage/lcov-report/src/api/controllers/query/import/index.html +0 -116
  585. package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +0 -373
  586. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +0 -131
  587. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +0 -379
  588. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +0 -157
  589. package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +0 -403
  590. package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +0 -146
  591. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +0 -586
  592. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +0 -712
  593. package/coverage/lcov-report/src/api/controllers/query/index.html +0 -131
  594. package/coverage/lcov-report/src/api/controllers/query/index.ts.html +0 -976
  595. package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +0 -2260
  596. package/coverage/lcov-report/src/api/controllers/row/index.ts.html +0 -541
  597. package/coverage/lcov-report/src/api/controllers/screen.ts.html +0 -463
  598. package/coverage/lcov-report/src/api/controllers/static/index.html +0 -116
  599. package/coverage/lcov-report/src/api/controllers/static/index.ts.html +0 -694
  600. package/coverage/lcov-report/src/api/controllers/table/index.html +0 -176
  601. package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +0 -661
  602. package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +0 -1255
  603. package/coverage/lcov-report/src/api/controllers/webhook.ts.html +0 -379
  604. package/coverage/lcov-report/src/api/routes/analytics.ts.html +0 -112
  605. package/coverage/lcov-report/src/api/routes/apikeys.ts.html +0 -121
  606. package/coverage/lcov-report/src/api/routes/application.ts.html +0 -223
  607. package/coverage/lcov-report/src/api/routes/auth.ts.html +0 -109
  608. package/coverage/lcov-report/src/api/routes/datasource.ts.html +0 -265
  609. package/coverage/lcov-report/src/api/routes/deploy.ts.html +0 -148
  610. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -289
  611. package/coverage/lcov-report/src/api/routes/migrations.ts.html +0 -127
  612. package/coverage/lcov-report/src/api/routes/plugin.ts.html +0 -151
  613. package/coverage/lcov-report/src/api/routes/public/applications.ts.html +0 -541
  614. package/coverage/lcov-report/src/api/routes/public/index.html +0 -191
  615. package/coverage/lcov-report/src/api/routes/public/index.ts.html +0 -493
  616. package/coverage/lcov-report/src/api/routes/public/middleware/index.html +0 -116
  617. package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +0 -328
  618. package/coverage/lcov-report/src/api/routes/public/queries.ts.html +0 -313
  619. package/coverage/lcov-report/src/api/routes/public/rows.ts.html +0 -598
  620. package/coverage/lcov-report/src/api/routes/public/tables.ts.html +0 -586
  621. package/coverage/lcov-report/src/api/routes/public/users.ts.html +0 -511
  622. package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +0 -238
  623. package/coverage/lcov-report/src/api/routes/public/utils/index.html +0 -116
  624. package/coverage/lcov-report/src/api/routes/role.ts.html +0 -157
  625. package/coverage/lcov-report/src/api/routes/row.ts.html +0 -883
  626. package/coverage/lcov-report/src/api/routes/screen.ts.html +0 -154
  627. package/coverage/lcov-report/src/api/routes/static.ts.html +0 -280
  628. package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +0 -550
  629. package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +0 -131
  630. package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +0 -367
  631. package/coverage/lcov-report/src/api/routes/webhook.ts.html +0 -166
  632. package/coverage/lcov-report/src/app.ts.html +0 -406
  633. package/coverage/lcov-report/src/automations/logging/index.html +0 -116
  634. package/coverage/lcov-report/src/automations/logging/index.ts.html +0 -199
  635. package/coverage/lcov-report/src/automations/steps/createRow.ts.html +0 -382
  636. package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +0 -349
  637. package/coverage/lcov-report/src/automations/steps/index.html +0 -371
  638. package/coverage/lcov-report/src/automations/tests/utilities/index.html +0 -116
  639. package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +0 -265
  640. package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +0 -196
  641. package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +0 -130
  642. package/coverage/lcov-report/src/automations/utils.ts.html +0 -886
  643. package/coverage/lcov-report/src/constants/index.ts.html +0 -697
  644. package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +0 -2059
  645. package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +0 -541
  646. package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +0 -427
  647. package/coverage/lcov-report/src/db/defaultData/index.html +0 -176
  648. package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +0 -403
  649. package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +0 -559
  650. package/coverage/lcov-report/src/db/dynamoClient.ts.html +0 -526
  651. package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +0 -265
  652. package/coverage/lcov-report/src/db/linkedRows/index.html +0 -161
  653. package/coverage/lcov-report/src/environment.ts.html +0 -457
  654. package/coverage/lcov-report/src/events/utils.ts.html +0 -319
  655. package/coverage/lcov-report/src/index.html +0 -191
  656. package/coverage/lcov-report/src/index.ts.html +0 -133
  657. package/coverage/lcov-report/src/integrations/arangodb.ts.html +0 -415
  658. package/coverage/lcov-report/src/integrations/base/index.html +0 -161
  659. package/coverage/lcov-report/src/integrations/base/query.ts.html +0 -133
  660. package/coverage/lcov-report/src/integrations/base/sql.ts.html +0 -1951
  661. package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +0 -691
  662. package/coverage/lcov-report/src/integrations/base/utils.ts.html +0 -121
  663. package/coverage/lcov-report/src/integrations/couchdb.ts.html +0 -406
  664. package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +0 -634
  665. package/coverage/lcov-report/src/integrations/firebase.ts.html +0 -646
  666. package/coverage/lcov-report/src/integrations/googlesheets.ts.html +0 -1315
  667. package/coverage/lcov-report/src/integrations/index.html +0 -371
  668. package/coverage/lcov-report/src/integrations/index.ts.html +0 -445
  669. package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +0 -1006
  670. package/coverage/lcov-report/src/integrations/mongodb.ts.html +0 -1867
  671. package/coverage/lcov-report/src/integrations/mysql.ts.html +0 -964
  672. package/coverage/lcov-report/src/integrations/oracle.ts.html +0 -1474
  673. package/coverage/lcov-report/src/integrations/postgres.ts.html +0 -1069
  674. package/coverage/lcov-report/src/integrations/queries/index.html +0 -116
  675. package/coverage/lcov-report/src/integrations/queries/sql.ts.html +0 -463
  676. package/coverage/lcov-report/src/integrations/redis.ts.html +0 -550
  677. package/coverage/lcov-report/src/integrations/rest.ts.html +0 -1381
  678. package/coverage/lcov-report/src/integrations/s3.ts.html +0 -862
  679. package/coverage/lcov-report/src/integrations/snowflake.ts.html +0 -376
  680. package/coverage/lcov-report/src/integrations/utils.ts.html +0 -1018
  681. package/coverage/lcov-report/src/middleware/authorized.ts.html +0 -460
  682. package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +0 -187
  683. package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +0 -163
  684. package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +0 -151
  685. package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +0 -206
  686. package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +0 -172
  687. package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +0 -226
  688. package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +0 -151
  689. package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +0 -151
  690. package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +0 -166
  691. package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +0 -532
  692. package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +0 -283
  693. package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +0 -146
  694. package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +0 -265
  695. package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +0 -232
  696. package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +0 -724
  697. package/coverage/lcov-report/src/migrations/functions/backfill/index.html +0 -161
  698. package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +0 -106
  699. package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +0 -235
  700. package/coverage/lcov-report/src/migrations/functions/index.html +0 -161
  701. package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +0 -130
  702. package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +0 -520
  703. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +0 -161
  704. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +0 -94
  705. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +0 -127
  706. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +0 -115
  707. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +0 -169
  708. package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +0 -124
  709. package/coverage/lcov-report/src/migrations/index.ts.html +0 -430
  710. package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +0 -205
  711. package/coverage/lcov-report/src/migrations/tests/index.html +0 -131
  712. package/coverage/lcov-report/src/migrations/tests/structures.ts.html +0 -283
  713. package/coverage/lcov-report/src/sdk/app/automations/index.html +0 -131
  714. package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +0 -100
  715. package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +0 -214
  716. package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +0 -91
  717. package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +0 -604
  718. package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +0 -682
  719. package/coverage/lcov-report/src/sdk/app/backups/index.html +0 -176
  720. package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +0 -112
  721. package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +0 -292
  722. package/coverage/lcov-report/src/sdk/app/tables/index.html +0 -116
  723. package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +0 -265
  724. package/coverage/lcov-report/src/startup.ts.html +0 -499
  725. package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +0 -1966
  726. package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +0 -127
  727. package/coverage/lcov-report/src/tests/utilities/index.html +0 -161
  728. package/coverage/lcov-report/src/tests/utilities/structures.ts.html +0 -667
  729. package/coverage/lcov-report/src/threads/automation.ts.html +0 -1594
  730. package/coverage/lcov-report/src/threads/index.html +0 -161
  731. package/coverage/lcov-report/src/threads/index.ts.html +0 -418
  732. package/coverage/lcov-report/src/threads/query.ts.html +0 -961
  733. package/coverage/lcov-report/src/threads/utils.ts.html +0 -373
  734. package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +0 -547
  735. package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +0 -1129
  736. package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +0 -142
  737. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -343
  738. package/coverage/lcov-report/src/utilities/routing/index.ts.html +0 -181
  739. package/coverage/lcov-report/src/utilities/rowProcessor/index.html +0 -146
  740. package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +0 -373
  741. package/coverage/lcov-report/src/watch.ts.html +0 -196
  742. package/dist/db/defaultData/datasource_bb_default.js +0 -573
  743. package/dist/db/defaultData/employeeImport.js +0 -155
  744. package/dist/db/defaultData/expensesImport.js +0 -117
  745. package/dist/db/defaultData/inventoryImport.js +0 -109
  746. package/dist/db/defaultData/jobsImport.js +0 -152
  747. package/dist/db/linkedRows/LinkDocument.js +0 -32
  748. package/dist/events/BudibaseEmitter.js +0 -24
  749. package/dist/migrations/functions/tableSettings.js +0 -130
  750. package/dist/utilities/rowProcessor/map.js +0 -99
  751. package/jest.config.ts +0 -33
  752. package/src/api/controllers/integration.ts +0 -13
  753. package/src/api/controllers/migrations.ts +0 -14
  754. package/src/api/controllers/script.ts +0 -12
  755. package/src/api/routes/analytics.ts +0 -9
  756. package/src/api/routes/apikeys.ts +0 -12
  757. package/src/api/routes/automation.ts +0 -87
  758. package/src/api/routes/cloud.ts +0 -18
  759. package/src/api/routes/component.ts +0 -14
  760. package/src/api/routes/datasource.ts +0 -60
  761. package/src/api/routes/deploy.ts +0 -21
  762. package/src/api/routes/dev.ts +0 -38
  763. package/src/api/routes/integration.ts +0 -16
  764. package/src/api/routes/layout.ts +0 -16
  765. package/src/api/routes/migrations.ts +0 -14
  766. package/src/api/routes/permission.ts +0 -41
  767. package/src/api/routes/role.ts +0 -24
  768. package/src/api/routes/routing.ts +0 -14
  769. package/src/api/routes/screen.ts +0 -23
  770. package/src/api/routes/script.ts +0 -10
  771. package/src/api/routes/templates.ts +0 -16
  772. package/src/api/routes/user.ts +0 -51
  773. package/src/api/routes/view.ts +0 -34
  774. package/src/automations/bullboard.ts +0 -38
  775. package/src/automations/index.ts +0 -26
  776. package/src/automations/tests/utilities/index.ts +0 -60
  777. package/src/automations/triggerInfo/index.ts +0 -15
  778. package/src/constants/index.ts +0 -204
  779. package/src/constants/screens.ts +0 -48
  780. package/src/db/defaultData/datasource_bb_default.ts +0 -658
  781. package/src/db/defaultData/employeeImport.ts +0 -152
  782. package/src/db/defaultData/expensesImport.ts +0 -114
  783. package/src/db/defaultData/inventoryImport.ts +0 -106
  784. package/src/db/defaultData/jobsImport.ts +0 -158
  785. package/src/db/index.ts +0 -16
  786. package/src/db/linkedRows/LinkDocument.ts +0 -60
  787. package/src/events/index.ts +0 -5
  788. package/src/events/utils.ts +0 -78
  789. package/src/middleware/appInfo.ts +0 -20
  790. package/src/middleware/publicApi.ts +0 -21
  791. package/src/migrations/functions/tableSettings.ts +0 -145
  792. package/src/migrations/functions/tests/tableSettings.spec.ts +0 -144
  793. package/src/tests/utilities/controllers.ts +0 -14
  794. package/src/utilities/budibaseDir.ts +0 -3
  795. package/src/utilities/global.ts +0 -138
  796. package/src/utilities/routing/index.ts +0 -32
  797. package/src/utilities/rowProcessor/map.ts +0 -96
  798. 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
  }