@budibase/server 2.1.40-alpha.6 → 2.1.42

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 (797) 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.137fb5a9.js → index.843230be.js} +313 -313
  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.66c1c272.css +0 -6
  552. package/coverage/lcov-report/src/api/controllers/analytics.ts.html +0 -190
  553. package/coverage/lcov-report/src/api/controllers/application.ts.html +0 -2038
  554. package/coverage/lcov-report/src/api/controllers/auth.ts.html +0 -301
  555. package/coverage/lcov-report/src/api/controllers/backup.ts.html +0 -148
  556. package/coverage/lcov-report/src/api/controllers/component.ts.html +0 -259
  557. package/coverage/lcov-report/src/api/controllers/deploy/Deployment.ts.html +0 -259
  558. package/coverage/lcov-report/src/api/controllers/deploy/index.html +0 -131
  559. package/coverage/lcov-report/src/api/controllers/deploy/index.ts.html +0 -730
  560. package/coverage/lcov-report/src/api/controllers/index.html +0 -431
  561. package/coverage/lcov-report/src/api/controllers/integration.ts.html +0 -124
  562. package/coverage/lcov-report/src/api/controllers/plugin/file.ts.html +0 -130
  563. package/coverage/lcov-report/src/api/controllers/plugin/github.ts.html +0 -310
  564. package/coverage/lcov-report/src/api/controllers/plugin/index.html +0 -206
  565. package/coverage/lcov-report/src/api/controllers/plugin/index.ts.html +0 -484
  566. package/coverage/lcov-report/src/api/controllers/plugin/npm.ts.html +0 -253
  567. package/coverage/lcov-report/src/api/controllers/plugin/uploaders.ts.html +0 -97
  568. package/coverage/lcov-report/src/api/controllers/plugin/url.ts.html +0 -121
  569. package/coverage/lcov-report/src/api/controllers/plugin/utils.ts.html +0 -136
  570. package/coverage/lcov-report/src/api/controllers/public/applications.ts.html +0 -334
  571. package/coverage/lcov-report/src/api/controllers/public/index.html +0 -191
  572. package/coverage/lcov-report/src/api/controllers/public/mapping/applications.ts.html +0 -181
  573. package/coverage/lcov-report/src/api/controllers/public/mapping/index.html +0 -191
  574. package/coverage/lcov-report/src/api/controllers/public/mapping/index.ts.html +0 -124
  575. package/coverage/lcov-report/src/api/controllers/public/mapping/queries.ts.html +0 -202
  576. package/coverage/lcov-report/src/api/controllers/public/mapping/rows.ts.html +0 -178
  577. package/coverage/lcov-report/src/api/controllers/public/mapping/users.ts.html +0 -181
  578. package/coverage/lcov-report/src/api/controllers/public/queries.ts.html +0 -145
  579. package/coverage/lcov-report/src/api/controllers/public/rows.ts.html +0 -328
  580. package/coverage/lcov-report/src/api/controllers/public/tables.ts.html +0 -253
  581. package/coverage/lcov-report/src/api/controllers/public/users.ts.html +0 -268
  582. package/coverage/lcov-report/src/api/controllers/public/utils.ts.html +0 -220
  583. package/coverage/lcov-report/src/api/controllers/query/import/index.html +0 -116
  584. package/coverage/lcov-report/src/api/controllers/query/import/index.ts.html +0 -373
  585. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.html +0 -131
  586. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/index.ts.html +0 -379
  587. package/coverage/lcov-report/src/api/controllers/query/import/sources/base/openapi.ts.html +0 -157
  588. package/coverage/lcov-report/src/api/controllers/query/import/sources/curl.ts.html +0 -403
  589. package/coverage/lcov-report/src/api/controllers/query/import/sources/index.html +0 -146
  590. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi2.ts.html +0 -586
  591. package/coverage/lcov-report/src/api/controllers/query/import/sources/openapi3.ts.html +0 -712
  592. package/coverage/lcov-report/src/api/controllers/query/index.html +0 -131
  593. package/coverage/lcov-report/src/api/controllers/query/index.ts.html +0 -976
  594. package/coverage/lcov-report/src/api/controllers/row/ExternalRequest.ts.html +0 -2260
  595. package/coverage/lcov-report/src/api/controllers/row/index.ts.html +0 -541
  596. package/coverage/lcov-report/src/api/controllers/screen.ts.html +0 -463
  597. package/coverage/lcov-report/src/api/controllers/static/index.html +0 -116
  598. package/coverage/lcov-report/src/api/controllers/static/index.ts.html +0 -694
  599. package/coverage/lcov-report/src/api/controllers/table/index.html +0 -176
  600. package/coverage/lcov-report/src/api/controllers/table/internal.ts.html +0 -661
  601. package/coverage/lcov-report/src/api/controllers/table/utils.ts.html +0 -1255
  602. package/coverage/lcov-report/src/api/controllers/webhook.ts.html +0 -379
  603. package/coverage/lcov-report/src/api/routes/analytics.ts.html +0 -112
  604. package/coverage/lcov-report/src/api/routes/apikeys.ts.html +0 -121
  605. package/coverage/lcov-report/src/api/routes/application.ts.html +0 -223
  606. package/coverage/lcov-report/src/api/routes/auth.ts.html +0 -109
  607. package/coverage/lcov-report/src/api/routes/datasource.ts.html +0 -265
  608. package/coverage/lcov-report/src/api/routes/deploy.ts.html +0 -148
  609. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -289
  610. package/coverage/lcov-report/src/api/routes/migrations.ts.html +0 -127
  611. package/coverage/lcov-report/src/api/routes/plugin.ts.html +0 -151
  612. package/coverage/lcov-report/src/api/routes/public/applications.ts.html +0 -541
  613. package/coverage/lcov-report/src/api/routes/public/index.html +0 -191
  614. package/coverage/lcov-report/src/api/routes/public/index.ts.html +0 -493
  615. package/coverage/lcov-report/src/api/routes/public/middleware/index.html +0 -116
  616. package/coverage/lcov-report/src/api/routes/public/middleware/mapper.ts.html +0 -328
  617. package/coverage/lcov-report/src/api/routes/public/queries.ts.html +0 -313
  618. package/coverage/lcov-report/src/api/routes/public/rows.ts.html +0 -598
  619. package/coverage/lcov-report/src/api/routes/public/tables.ts.html +0 -586
  620. package/coverage/lcov-report/src/api/routes/public/users.ts.html +0 -511
  621. package/coverage/lcov-report/src/api/routes/public/utils/Endpoint.ts.html +0 -238
  622. package/coverage/lcov-report/src/api/routes/public/utils/index.html +0 -116
  623. package/coverage/lcov-report/src/api/routes/role.ts.html +0 -157
  624. package/coverage/lcov-report/src/api/routes/row.ts.html +0 -883
  625. package/coverage/lcov-report/src/api/routes/screen.ts.html +0 -154
  626. package/coverage/lcov-report/src/api/routes/static.ts.html +0 -280
  627. package/coverage/lcov-report/src/api/routes/tests/utilities/TestFunctions.ts.html +0 -550
  628. package/coverage/lcov-report/src/api/routes/tests/utilities/index.html +0 -131
  629. package/coverage/lcov-report/src/api/routes/tests/utilities/index.ts.html +0 -367
  630. package/coverage/lcov-report/src/api/routes/webhook.ts.html +0 -166
  631. package/coverage/lcov-report/src/app.ts.html +0 -406
  632. package/coverage/lcov-report/src/automations/logging/index.html +0 -116
  633. package/coverage/lcov-report/src/automations/logging/index.ts.html +0 -199
  634. package/coverage/lcov-report/src/automations/steps/createRow.ts.html +0 -382
  635. package/coverage/lcov-report/src/automations/steps/deleteRow.ts.html +0 -349
  636. package/coverage/lcov-report/src/automations/steps/index.html +0 -371
  637. package/coverage/lcov-report/src/automations/tests/utilities/index.html +0 -116
  638. package/coverage/lcov-report/src/automations/tests/utilities/index.ts.html +0 -265
  639. package/coverage/lcov-report/src/automations/triggerInfo/app.ts.html +0 -196
  640. package/coverage/lcov-report/src/automations/triggerInfo/index.ts.html +0 -130
  641. package/coverage/lcov-report/src/automations/utils.ts.html +0 -886
  642. package/coverage/lcov-report/src/constants/index.ts.html +0 -697
  643. package/coverage/lcov-report/src/db/defaultData/datasource_bb_default.ts.html +0 -2059
  644. package/coverage/lcov-report/src/db/defaultData/employeeImport.ts.html +0 -541
  645. package/coverage/lcov-report/src/db/defaultData/expensesImport.ts.html +0 -427
  646. package/coverage/lcov-report/src/db/defaultData/index.html +0 -176
  647. package/coverage/lcov-report/src/db/defaultData/inventoryImport.ts.html +0 -403
  648. package/coverage/lcov-report/src/db/defaultData/jobsImport.ts.html +0 -559
  649. package/coverage/lcov-report/src/db/dynamoClient.ts.html +0 -526
  650. package/coverage/lcov-report/src/db/linkedRows/LinkDocument.ts.html +0 -265
  651. package/coverage/lcov-report/src/db/linkedRows/index.html +0 -161
  652. package/coverage/lcov-report/src/environment.ts.html +0 -457
  653. package/coverage/lcov-report/src/events/utils.ts.html +0 -319
  654. package/coverage/lcov-report/src/index.html +0 -191
  655. package/coverage/lcov-report/src/index.ts.html +0 -133
  656. package/coverage/lcov-report/src/integrations/arangodb.ts.html +0 -415
  657. package/coverage/lcov-report/src/integrations/base/index.html +0 -161
  658. package/coverage/lcov-report/src/integrations/base/query.ts.html +0 -133
  659. package/coverage/lcov-report/src/integrations/base/sql.ts.html +0 -1951
  660. package/coverage/lcov-report/src/integrations/base/sqlTable.ts.html +0 -691
  661. package/coverage/lcov-report/src/integrations/base/utils.ts.html +0 -121
  662. package/coverage/lcov-report/src/integrations/couchdb.ts.html +0 -406
  663. package/coverage/lcov-report/src/integrations/elasticsearch.ts.html +0 -634
  664. package/coverage/lcov-report/src/integrations/firebase.ts.html +0 -646
  665. package/coverage/lcov-report/src/integrations/googlesheets.ts.html +0 -1315
  666. package/coverage/lcov-report/src/integrations/index.html +0 -371
  667. package/coverage/lcov-report/src/integrations/index.ts.html +0 -445
  668. package/coverage/lcov-report/src/integrations/microsoftSqlServer.ts.html +0 -1006
  669. package/coverage/lcov-report/src/integrations/mongodb.ts.html +0 -1867
  670. package/coverage/lcov-report/src/integrations/mysql.ts.html +0 -964
  671. package/coverage/lcov-report/src/integrations/oracle.ts.html +0 -1474
  672. package/coverage/lcov-report/src/integrations/postgres.ts.html +0 -1069
  673. package/coverage/lcov-report/src/integrations/queries/index.html +0 -116
  674. package/coverage/lcov-report/src/integrations/queries/sql.ts.html +0 -463
  675. package/coverage/lcov-report/src/integrations/redis.ts.html +0 -550
  676. package/coverage/lcov-report/src/integrations/rest.ts.html +0 -1381
  677. package/coverage/lcov-report/src/integrations/s3.ts.html +0 -862
  678. package/coverage/lcov-report/src/integrations/snowflake.ts.html +0 -376
  679. package/coverage/lcov-report/src/integrations/utils.ts.html +0 -1018
  680. package/coverage/lcov-report/src/middleware/authorized.ts.html +0 -460
  681. package/coverage/lcov-report/src/migrations/functions/appUrls.ts.html +0 -187
  682. package/coverage/lcov-report/src/migrations/functions/backfill/app/automations.ts.html +0 -163
  683. package/coverage/lcov-report/src/migrations/functions/backfill/app/datasources.ts.html +0 -151
  684. package/coverage/lcov-report/src/migrations/functions/backfill/app/index.html +0 -206
  685. package/coverage/lcov-report/src/migrations/functions/backfill/app/layouts.ts.html +0 -172
  686. package/coverage/lcov-report/src/migrations/functions/backfill/app/queries.ts.html +0 -226
  687. package/coverage/lcov-report/src/migrations/functions/backfill/app/roles.ts.html +0 -151
  688. package/coverage/lcov-report/src/migrations/functions/backfill/app/screens.ts.html +0 -151
  689. package/coverage/lcov-report/src/migrations/functions/backfill/app/tables.ts.html +0 -166
  690. package/coverage/lcov-report/src/migrations/functions/backfill/app.ts.html +0 -532
  691. package/coverage/lcov-report/src/migrations/functions/backfill/global/configs.ts.html +0 -283
  692. package/coverage/lcov-report/src/migrations/functions/backfill/global/index.html +0 -146
  693. package/coverage/lcov-report/src/migrations/functions/backfill/global/quotas.ts.html +0 -265
  694. package/coverage/lcov-report/src/migrations/functions/backfill/global/users.ts.html +0 -232
  695. package/coverage/lcov-report/src/migrations/functions/backfill/global.ts.html +0 -724
  696. package/coverage/lcov-report/src/migrations/functions/backfill/index.html +0 -161
  697. package/coverage/lcov-report/src/migrations/functions/backfill/index.ts.html +0 -106
  698. package/coverage/lcov-report/src/migrations/functions/backfill/installation.ts.html +0 -235
  699. package/coverage/lcov-report/src/migrations/functions/index.html +0 -161
  700. package/coverage/lcov-report/src/migrations/functions/syncQuotas.ts.html +0 -130
  701. package/coverage/lcov-report/src/migrations/functions/tableSettings.ts.html +0 -520
  702. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.html +0 -161
  703. package/coverage/lcov-report/src/migrations/functions/usageQuotas/index.ts.html +0 -94
  704. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncApps.ts.html +0 -127
  705. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncPlugins.ts.html +0 -115
  706. package/coverage/lcov-report/src/migrations/functions/usageQuotas/syncRows.ts.html +0 -169
  707. package/coverage/lcov-report/src/migrations/functions/userEmailViewCasing.ts.html +0 -124
  708. package/coverage/lcov-report/src/migrations/index.ts.html +0 -430
  709. package/coverage/lcov-report/src/migrations/tests/helpers.ts.html +0 -205
  710. package/coverage/lcov-report/src/migrations/tests/index.html +0 -131
  711. package/coverage/lcov-report/src/migrations/tests/structures.ts.html +0 -283
  712. package/coverage/lcov-report/src/sdk/app/automations/index.html +0 -131
  713. package/coverage/lcov-report/src/sdk/app/automations/index.ts.html +0 -100
  714. package/coverage/lcov-report/src/sdk/app/automations/webhook.ts.html +0 -214
  715. package/coverage/lcov-report/src/sdk/app/backups/constants.ts.html +0 -91
  716. package/coverage/lcov-report/src/sdk/app/backups/exports.ts.html +0 -604
  717. package/coverage/lcov-report/src/sdk/app/backups/imports.ts.html +0 -682
  718. package/coverage/lcov-report/src/sdk/app/backups/index.html +0 -176
  719. package/coverage/lcov-report/src/sdk/app/backups/index.ts.html +0 -112
  720. package/coverage/lcov-report/src/sdk/app/backups/statistics.ts.html +0 -292
  721. package/coverage/lcov-report/src/sdk/app/tables/index.html +0 -116
  722. package/coverage/lcov-report/src/sdk/app/tables/index.ts.html +0 -265
  723. package/coverage/lcov-report/src/startup.ts.html +0 -499
  724. package/coverage/lcov-report/src/tests/utilities/TestConfiguration.ts.html +0 -1966
  725. package/coverage/lcov-report/src/tests/utilities/controllers.ts.html +0 -127
  726. package/coverage/lcov-report/src/tests/utilities/index.html +0 -161
  727. package/coverage/lcov-report/src/tests/utilities/structures.ts.html +0 -667
  728. package/coverage/lcov-report/src/threads/automation.ts.html +0 -1594
  729. package/coverage/lcov-report/src/threads/index.html +0 -161
  730. package/coverage/lcov-report/src/threads/index.ts.html +0 -418
  731. package/coverage/lcov-report/src/threads/query.ts.html +0 -961
  732. package/coverage/lcov-report/src/threads/utils.ts.html +0 -373
  733. package/coverage/lcov-report/src/utilities/fileSystem/clientLibrary.ts.html +0 -547
  734. package/coverage/lcov-report/src/utilities/fileSystem/index.ts.html +0 -1129
  735. package/coverage/lcov-report/src/utilities/fileSystem/processor.ts.html +0 -142
  736. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -343
  737. package/coverage/lcov-report/src/utilities/routing/index.ts.html +0 -181
  738. package/coverage/lcov-report/src/utilities/rowProcessor/index.html +0 -146
  739. package/coverage/lcov-report/src/utilities/rowProcessor/map.ts.html +0 -373
  740. package/coverage/lcov-report/src/watch.ts.html +0 -196
  741. package/dist/db/defaultData/datasource_bb_default.js +0 -573
  742. package/dist/db/defaultData/employeeImport.js +0 -155
  743. package/dist/db/defaultData/expensesImport.js +0 -117
  744. package/dist/db/defaultData/inventoryImport.js +0 -109
  745. package/dist/db/defaultData/jobsImport.js +0 -152
  746. package/dist/db/linkedRows/LinkDocument.js +0 -32
  747. package/dist/events/BudibaseEmitter.js +0 -24
  748. package/dist/migrations/functions/tableSettings.js +0 -130
  749. package/dist/utilities/rowProcessor/map.js +0 -99
  750. package/jest.config.ts +0 -33
  751. package/src/api/controllers/integration.ts +0 -13
  752. package/src/api/controllers/migrations.ts +0 -14
  753. package/src/api/controllers/script.ts +0 -12
  754. package/src/api/routes/analytics.ts +0 -9
  755. package/src/api/routes/apikeys.ts +0 -12
  756. package/src/api/routes/automation.ts +0 -87
  757. package/src/api/routes/cloud.ts +0 -18
  758. package/src/api/routes/component.ts +0 -14
  759. package/src/api/routes/datasource.ts +0 -60
  760. package/src/api/routes/deploy.ts +0 -21
  761. package/src/api/routes/dev.ts +0 -38
  762. package/src/api/routes/integration.ts +0 -16
  763. package/src/api/routes/layout.ts +0 -16
  764. package/src/api/routes/migrations.ts +0 -14
  765. package/src/api/routes/permission.ts +0 -41
  766. package/src/api/routes/role.ts +0 -24
  767. package/src/api/routes/routing.ts +0 -14
  768. package/src/api/routes/screen.ts +0 -23
  769. package/src/api/routes/script.ts +0 -10
  770. package/src/api/routes/templates.ts +0 -16
  771. package/src/api/routes/user.ts +0 -51
  772. package/src/api/routes/view.ts +0 -34
  773. package/src/automations/bullboard.ts +0 -38
  774. package/src/automations/index.ts +0 -26
  775. package/src/automations/tests/utilities/index.ts +0 -60
  776. package/src/automations/triggerInfo/index.ts +0 -15
  777. package/src/constants/index.ts +0 -204
  778. package/src/constants/screens.ts +0 -48
  779. package/src/db/defaultData/datasource_bb_default.ts +0 -658
  780. package/src/db/defaultData/employeeImport.ts +0 -152
  781. package/src/db/defaultData/expensesImport.ts +0 -114
  782. package/src/db/defaultData/inventoryImport.ts +0 -106
  783. package/src/db/defaultData/jobsImport.ts +0 -158
  784. package/src/db/index.ts +0 -16
  785. package/src/db/linkedRows/LinkDocument.ts +0 -60
  786. package/src/events/index.ts +0 -5
  787. package/src/events/utils.ts +0 -78
  788. package/src/middleware/appInfo.ts +0 -20
  789. package/src/middleware/publicApi.ts +0 -21
  790. package/src/migrations/functions/tableSettings.ts +0 -145
  791. package/src/migrations/functions/tests/tableSettings.spec.ts +0 -144
  792. package/src/tests/utilities/controllers.ts +0 -14
  793. package/src/utilities/budibaseDir.ts +0 -3
  794. package/src/utilities/global.ts +0 -138
  795. package/src/utilities/routing/index.ts +0 -32
  796. package/src/utilities/rowProcessor/map.ts +0 -96
  797. 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
  }