@budibase/server 2.1.45 → 2.1.46-alpha.1

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