@budibase/server 1.0.49-alpha.6 → 1.0.49

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 (376) hide show
  1. package/__mocks__/arangojs.ts +1 -1
  2. package/__mocks__/aws-sdk.ts +4 -4
  3. package/__mocks__/mongodb.ts +5 -4
  4. package/__mocks__/mssql.ts +3 -3
  5. package/__mocks__/node-fetch.ts +1 -2
  6. package/__mocks__/pg.ts +5 -3
  7. package/builder/assets/{index.1b905242.js → index.2c37968e.js} +231 -234
  8. package/builder/assets/index.39e01193.css +1 -0
  9. package/builder/assets/{vendor.d526bfe8.js → vendor.f9faf6ab.js} +12 -12
  10. package/builder/index.html +3 -3
  11. package/coverage/clover.xml +2816 -3119
  12. package/coverage/coverage-final.json +101 -106
  13. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/application.js.html +152 -257
  16. package/coverage/lcov-report/api/controllers/auth.js.html +13 -22
  17. package/coverage/lcov-report/api/controllers/automation.js.html +69 -39
  18. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/cloud.js.html +11 -8
  20. package/coverage/lcov-report/api/controllers/component.js.html +16 -13
  21. package/coverage/lcov-report/api/controllers/datasource.js.html +51 -81
  22. package/coverage/lcov-report/api/controllers/dev.js.html +6 -6
  23. package/coverage/lcov-report/{utilities/usageQuota/usageQuoteReset.js.html → api/controllers/hosting.js.html} +48 -36
  24. package/coverage/lcov-report/api/controllers/index.html +76 -76
  25. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
  27. package/coverage/lcov-report/api/controllers/metadata.js.html +21 -6
  28. package/coverage/lcov-report/api/controllers/permission.js.html +19 -19
  29. package/coverage/lcov-report/api/controllers/query/index.html +10 -10
  30. package/coverage/lcov-report/api/controllers/query/index.js.html +35 -38
  31. package/coverage/lcov-report/api/controllers/query/validation.js.html +6 -6
  32. package/coverage/lcov-report/api/controllers/role.js.html +16 -16
  33. package/coverage/lcov-report/api/controllers/routing.js.html +10 -7
  34. package/coverage/lcov-report/api/controllers/row/external.js.html +27 -21
  35. package/coverage/lcov-report/api/controllers/row/index.html +34 -49
  36. package/coverage/lcov-report/api/controllers/row/index.js.html +26 -26
  37. package/coverage/lcov-report/api/controllers/row/internal.js.html +226 -118
  38. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +34 -52
  39. package/coverage/lcov-report/api/controllers/row/utils.js.html +62 -47
  40. package/coverage/lcov-report/api/controllers/screen.js.html +21 -15
  41. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  42. package/coverage/lcov-report/api/controllers/table/external.js.html +34 -25
  43. package/coverage/lcov-report/api/controllers/table/index.html +43 -58
  44. package/coverage/lcov-report/api/controllers/table/index.js.html +82 -58
  45. package/coverage/lcov-report/api/controllers/table/internal.js.html +66 -81
  46. package/coverage/lcov-report/api/controllers/table/utils.js.html +110 -218
  47. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  48. package/coverage/lcov-report/api/controllers/user.js.html +50 -47
  49. package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
  50. package/coverage/lcov-report/api/controllers/view/index.html +16 -16
  51. package/coverage/lcov-report/api/controllers/view/index.js.html +33 -27
  52. package/coverage/lcov-report/api/controllers/view/utils.js.html +20 -35
  53. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
  54. package/coverage/lcov-report/api/controllers/webhook.js.html +28 -34
  55. package/coverage/lcov-report/api/index.html +1 -1
  56. package/coverage/lcov-report/api/index.js.html +8 -8
  57. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/{migrations.js.html → hosting.js.html} +14 -17
  69. package/coverage/lcov-report/api/routes/index.html +18 -18
  70. package/coverage/lcov-report/api/routes/index.js.html +3 -3
  71. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/static.js.html +2 -17
  82. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  83. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  84. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  85. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  86. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  87. package/coverage/lcov-report/automations/actions.js.html +24 -24
  88. package/coverage/lcov-report/automations/automationUtils.js.html +10 -7
  89. package/coverage/lcov-report/automations/bullboard.js.html +16 -16
  90. package/coverage/lcov-report/automations/index.html +18 -18
  91. package/coverage/lcov-report/automations/index.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
  93. package/coverage/lcov-report/automations/steps/createRow.js.html +22 -13
  94. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  95. package/coverage/lcov-report/automations/steps/deleteRow.js.html +20 -11
  96. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  97. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  98. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  99. package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
  100. package/coverage/lcov-report/automations/steps/index.html +13 -13
  101. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  102. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  103. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
  104. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  105. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  106. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  107. package/coverage/lcov-report/automations/steps/updateRow.js.html +7 -7
  108. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  109. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  110. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  111. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  113. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  114. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  116. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  117. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  118. package/coverage/lcov-report/automations/triggers.js.html +55 -61
  119. package/coverage/lcov-report/automations/utils.js.html +42 -54
  120. package/coverage/lcov-report/constants/index.html +5 -5
  121. package/coverage/lcov-report/constants/index.js.html +26 -53
  122. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  123. package/coverage/lcov-report/constants/screens.js.html +4 -4
  124. package/coverage/lcov-report/db/client.js.html +18 -18
  125. package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
  126. package/coverage/lcov-report/db/index.html +15 -15
  127. package/coverage/lcov-report/db/index.js.html +3 -3
  128. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +37 -25
  129. package/coverage/lcov-report/db/linkedRows/index.html +27 -27
  130. package/coverage/lcov-report/db/linkedRows/index.js.html +96 -51
  131. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +42 -42
  132. package/coverage/lcov-report/db/newid.js.html +4 -4
  133. package/coverage/lcov-report/db/utils.js.html +87 -87
  134. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  135. package/coverage/lcov-report/events/index.html +1 -1
  136. package/coverage/lcov-report/events/index.js.html +5 -5
  137. package/coverage/lcov-report/events/utils.js.html +3 -3
  138. package/coverage/lcov-report/index.html +120 -135
  139. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  140. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  141. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  142. package/coverage/lcov-report/middleware/authorized.js.html +65 -173
  143. package/coverage/lcov-report/middleware/builder.js.html +10 -10
  144. package/coverage/lcov-report/middleware/currentapp.js.html +83 -95
  145. package/coverage/lcov-report/middleware/index.html +38 -38
  146. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  147. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  148. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  149. package/coverage/lcov-report/middleware/usageQuota.js.html +53 -281
  150. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  151. package/coverage/lcov-report/threads/automation.js.html +24 -30
  152. package/coverage/lcov-report/threads/index.html +26 -26
  153. package/coverage/lcov-report/threads/index.js.html +10 -10
  154. package/coverage/lcov-report/threads/query.js.html +26 -62
  155. package/coverage/lcov-report/threads/utils.js.html +14 -14
  156. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  157. package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
  158. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  159. package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
  160. package/coverage/lcov-report/utilities/global.js.html +49 -58
  161. package/coverage/lcov-report/utilities/index.html +37 -37
  162. package/coverage/lcov-report/utilities/index.js.html +73 -43
  163. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +8 -8
  164. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  165. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  166. package/coverage/lcov-report/utilities/routing/index.js.html +7 -7
  167. package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -27
  168. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +103 -97
  169. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +27 -75
  170. package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
  171. package/coverage/lcov-report/utilities/security.js.html +8 -8
  172. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  173. package/coverage/lcov-report/utilities/users.js.html +9 -9
  174. package/coverage/lcov-report/utilities/workerRequests.js.html +112 -43
  175. package/coverage/lcov.info +4423 -5022
  176. package/dist/api/controllers/application.js +60 -90
  177. package/dist/api/controllers/auth.js +5 -8
  178. package/dist/api/controllers/automation.js +19 -14
  179. package/dist/api/controllers/cloud.js +3 -2
  180. package/dist/api/controllers/component.js +4 -3
  181. package/dist/api/controllers/datasource.js +10 -20
  182. package/dist/api/controllers/deploy/Deployment.js +6 -3
  183. package/dist/api/controllers/deploy/index.js +13 -12
  184. package/dist/api/controllers/dev.js +5 -5
  185. package/dist/api/controllers/hosting.js +30 -0
  186. package/dist/api/controllers/layout.js +3 -3
  187. package/dist/api/controllers/metadata.js +4 -4
  188. package/dist/api/controllers/permission.js +4 -4
  189. package/dist/api/controllers/query/import/index.js +6 -4
  190. package/dist/api/controllers/query/index.js +10 -11
  191. package/dist/api/controllers/role.js +5 -5
  192. package/dist/api/controllers/routing.js +6 -5
  193. package/dist/api/controllers/row/ExternalRequest.js +63 -76
  194. package/dist/api/controllers/row/external.js +4 -4
  195. package/dist/api/controllers/row/internal.js +93 -55
  196. package/dist/api/controllers/row/internalSearch.js +17 -23
  197. package/dist/api/controllers/row/utils.js +14 -13
  198. package/dist/api/controllers/screen.js +7 -5
  199. package/dist/api/controllers/static/index.js +12 -61
  200. package/dist/api/controllers/table/external.js +10 -7
  201. package/dist/api/controllers/table/index.js +13 -16
  202. package/dist/api/controllers/table/internal.js +16 -22
  203. package/dist/api/controllers/table/utils.js +35 -62
  204. package/dist/api/controllers/user.js +20 -18
  205. package/dist/api/controllers/view/index.js +10 -8
  206. package/dist/api/controllers/view/utils.js +4 -9
  207. package/dist/api/controllers/webhook.js +8 -10
  208. package/dist/api/routes/hosting.js +11 -0
  209. package/dist/api/routes/index.js +2 -2
  210. package/dist/api/routes/static.js +1 -2
  211. package/dist/api/routes/tests/utilities/TestFunctions.js +17 -37
  212. package/dist/app.js +5 -35
  213. package/dist/automations/automationUtils.js +3 -2
  214. package/dist/automations/steps/createRow.js +5 -3
  215. package/dist/automations/steps/deleteRow.js +4 -1
  216. package/dist/automations/steps/updateRow.js +1 -1
  217. package/dist/automations/triggers.js +25 -27
  218. package/dist/automations/utils.js +5 -10
  219. package/dist/constants/index.js +0 -7
  220. package/dist/db/linkedRows/LinkController.js +7 -3
  221. package/dist/db/linkedRows/index.js +27 -16
  222. package/dist/db/linkedRows/linkUtils.js +6 -6
  223. package/dist/db/views/staticViews.js +10 -9
  224. package/dist/definitions/datasource.js +0 -1
  225. package/dist/environment.js +1 -4
  226. package/dist/integrations/base/sql.js +6 -13
  227. package/dist/integrations/index.js +0 -3
  228. package/dist/integrations/utils.js +9 -60
  229. package/dist/middleware/authorized.js +30 -57
  230. package/dist/middleware/builder.js +2 -2
  231. package/dist/middleware/currentapp.js +37 -41
  232. package/dist/middleware/usageQuota.js +15 -82
  233. package/dist/package.json +5 -8
  234. package/dist/tests/utilities/TestConfiguration.js +50 -80
  235. package/dist/threads/automation.js +11 -13
  236. package/dist/threads/query.js +13 -23
  237. package/dist/tsconfig.tsbuildinfo +1 -1
  238. package/dist/utilities/fileSystem/index.js +3 -4
  239. package/dist/utilities/global.js +12 -15
  240. package/dist/utilities/index.js +17 -7
  241. package/dist/utilities/routing/index.js +5 -5
  242. package/dist/utilities/rowProcessor/index.js +17 -23
  243. package/dist/utilities/rowProcessor/utils.js +4 -14
  244. package/dist/utilities/{usageQuota/index.js → usageQuota.js} +31 -45
  245. package/dist/utilities/users.js +3 -3
  246. package/dist/utilities/workerRequests.js +24 -4
  247. package/nodemon.json +1 -1
  248. package/package.json +6 -9
  249. package/scripts/likeCypress.ts +1 -1
  250. package/src/api/controllers/application.js +50 -85
  251. package/src/api/controllers/auth.js +5 -8
  252. package/src/api/controllers/automation.js +23 -13
  253. package/src/api/controllers/cloud.js +3 -2
  254. package/src/api/controllers/component.js +4 -3
  255. package/src/api/controllers/datasource.js +11 -21
  256. package/src/api/controllers/deploy/Deployment.js +7 -3
  257. package/src/api/controllers/deploy/index.js +13 -20
  258. package/src/api/controllers/dev.js +5 -5
  259. package/src/api/controllers/hosting.js +22 -0
  260. package/src/api/controllers/layout.js +3 -3
  261. package/src/api/controllers/metadata.js +9 -4
  262. package/src/api/controllers/permission.js +4 -4
  263. package/src/api/controllers/query/import/index.ts +6 -4
  264. package/src/api/controllers/query/import/tests/index.spec.js +1 -2
  265. package/src/api/controllers/query/index.js +10 -11
  266. package/src/api/controllers/role.js +5 -5
  267. package/src/api/controllers/routing.js +6 -5
  268. package/src/api/controllers/row/ExternalRequest.ts +42 -53
  269. package/src/api/controllers/row/external.js +6 -4
  270. package/src/api/controllers/row/internal.js +90 -54
  271. package/src/api/controllers/row/internalSearch.js +17 -23
  272. package/src/api/controllers/row/utils.js +18 -13
  273. package/src/api/controllers/screen.js +7 -5
  274. package/src/api/controllers/static/index.js +12 -65
  275. package/src/api/controllers/table/external.js +10 -7
  276. package/src/api/controllers/table/index.js +28 -20
  277. package/src/api/controllers/table/internal.js +19 -24
  278. package/src/api/controllers/table/utils.js +42 -78
  279. package/src/api/controllers/user.js +20 -19
  280. package/src/api/controllers/view/index.js +10 -8
  281. package/src/api/controllers/view/utils.js +4 -9
  282. package/src/api/controllers/webhook.js +8 -10
  283. package/src/api/routes/hosting.js +13 -0
  284. package/src/api/routes/index.js +2 -2
  285. package/src/api/routes/static.js +0 -5
  286. package/src/api/routes/tests/application.spec.js +2 -2
  287. package/src/api/routes/tests/auth.spec.js +2 -1
  288. package/src/api/routes/tests/automation.spec.js +0 -1
  289. package/src/api/routes/tests/hosting.spec.js +36 -0
  290. package/src/api/routes/tests/misc.spec.js +1 -0
  291. package/src/api/routes/tests/routing.spec.js +12 -21
  292. package/src/api/routes/tests/row.spec.js +4 -7
  293. package/src/api/routes/tests/utilities/TestFunctions.js +17 -39
  294. package/src/app.ts +5 -18
  295. package/src/automations/automationUtils.js +3 -2
  296. package/src/automations/steps/createRow.js +5 -2
  297. package/src/automations/steps/deleteRow.js +4 -1
  298. package/src/automations/steps/updateRow.js +1 -1
  299. package/src/automations/triggers.js +31 -33
  300. package/src/automations/utils.js +5 -9
  301. package/src/constants/index.js +0 -9
  302. package/src/db/linkedRows/LinkController.js +7 -3
  303. package/src/db/linkedRows/index.js +31 -16
  304. package/src/db/linkedRows/linkUtils.js +6 -6
  305. package/src/db/tests/linkController.spec.js +1 -0
  306. package/src/db/tests/linkTests.spec.js +6 -5
  307. package/src/db/views/staticViews.js +10 -8
  308. package/src/definitions/common.ts +0 -3
  309. package/src/definitions/datasource.ts +0 -3
  310. package/src/environment.js +1 -4
  311. package/src/integrations/base/sql.ts +7 -14
  312. package/src/integrations/index.ts +0 -3
  313. package/src/integrations/tests/sql.spec.js +0 -16
  314. package/src/integrations/utils.ts +12 -75
  315. package/src/middleware/authorized.js +30 -66
  316. package/src/middleware/builder.js +2 -2
  317. package/src/middleware/currentapp.js +46 -50
  318. package/src/middleware/tests/authorized.spec.js +6 -13
  319. package/src/middleware/tests/currentapp.spec.js +0 -6
  320. package/src/middleware/tests/usageQuota.spec.js +24 -18
  321. package/src/middleware/usageQuota.js +17 -93
  322. package/src/tests/utilities/TestConfiguration.js +55 -82
  323. package/src/threads/automation.js +15 -17
  324. package/src/threads/query.js +14 -26
  325. package/src/utilities/fileSystem/index.js +3 -4
  326. package/src/utilities/global.js +12 -15
  327. package/src/utilities/index.js +17 -7
  328. package/src/utilities/routing/index.js +5 -5
  329. package/src/utilities/rowProcessor/index.js +27 -25
  330. package/src/utilities/rowProcessor/utils.js +7 -23
  331. package/src/utilities/usageQuota.js +73 -0
  332. package/src/utilities/users.js +3 -3
  333. package/src/utilities/workerRequests.js +27 -4
  334. package/builder/assets/index.83c0944f.css +0 -1
  335. package/coverage/lcov-report/api/controllers/migrations.js.html +0 -119
  336. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +0 -548
  337. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +0 -599
  338. package/coverage/lcov-report/utilities/usageQuota/index.html +0 -141
  339. package/coverage/lcov-report/utilities/usageQuota/index.js.html +0 -359
  340. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +0 -305
  341. package/dist/api/controllers/migrations.js +0 -21
  342. package/dist/api/controllers/row/staticFormula.js +0 -147
  343. package/dist/api/controllers/table/bulkFormula.js +0 -159
  344. package/dist/api/routes/migrations.js +0 -9
  345. package/dist/integrations/googlesheets.js +0 -340
  346. package/dist/migrations/functions/appUrls.js +0 -46
  347. package/dist/migrations/functions/quotas1.js +0 -50
  348. package/dist/migrations/functions/usageQuotas/index.js +0 -20
  349. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -30
  350. package/dist/migrations/functions/usageQuotas/syncRows.js +0 -33
  351. package/dist/migrations/functions/userEmailViewCasing.js +0 -24
  352. package/dist/migrations/index.js +0 -62
  353. package/dist/utilities/usageQuota/rows.js +0 -78
  354. package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
  355. package/src/api/controllers/migrations.js +0 -13
  356. package/src/api/controllers/row/staticFormula.js +0 -156
  357. package/src/api/controllers/table/bulkFormula.js +0 -173
  358. package/src/api/routes/migrations.js +0 -14
  359. package/src/api/routes/tests/static.spec.js +0 -98
  360. package/src/integrations/googlesheets.ts +0 -353
  361. package/src/migrations/functions/appUrls.ts +0 -34
  362. package/src/migrations/functions/quotas1.ts +0 -20
  363. package/src/migrations/functions/tests/appUrls.spec.js +0 -29
  364. package/src/migrations/functions/tests/quotas1.spec.js +0 -27
  365. package/src/migrations/functions/tests/userEmailViewCasing.spec.js +0 -25
  366. package/src/migrations/functions/usageQuotas/index.ts +0 -8
  367. package/src/migrations/functions/usageQuotas/syncApps.ts +0 -19
  368. package/src/migrations/functions/usageQuotas/syncRows.ts +0 -22
  369. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +0 -37
  370. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +0 -43
  371. package/src/migrations/functions/userEmailViewCasing.ts +0 -13
  372. package/src/migrations/index.ts +0 -56
  373. package/src/utilities/tests/usageQuota/usageQuota.spec.js +0 -72
  374. package/src/utilities/usageQuota/index.js +0 -93
  375. package/src/utilities/usageQuota/rows.js +0 -75
  376. package/src/utilities/usageQuota/usageQuoteReset.js +0 -18
@@ -1,14 +1,14 @@
1
1
  const { SearchIndexes } = require("../../../db/utils")
2
2
  const fetch = require("node-fetch")
3
3
  const { getCouchUrl } = require("@budibase/backend-core/db")
4
- const { getAppId } = require("@budibase/backend-core/context")
5
4
 
6
5
  /**
7
6
  * Class to build lucene query URLs.
8
7
  * Optionally takes a base lucene query object.
9
8
  */
10
9
  class QueryBuilder {
11
- constructor(base) {
10
+ constructor(appId, base) {
11
+ this.appId = appId
12
12
  this.query = {
13
13
  string: {},
14
14
  fuzzy: {},
@@ -37,30 +37,22 @@ class QueryBuilder {
37
37
  }
38
38
 
39
39
  setLimit(limit) {
40
- if (limit != null) {
41
- this.limit = limit
42
- }
40
+ this.limit = limit
43
41
  return this
44
42
  }
45
43
 
46
44
  setSort(sort) {
47
- if (sort != null) {
48
- this.sort = sort
49
- }
45
+ this.sort = sort
50
46
  return this
51
47
  }
52
48
 
53
49
  setSortOrder(sortOrder) {
54
- if (sortOrder != null) {
55
- this.sortOrder = sortOrder
56
- }
50
+ this.sortOrder = sortOrder
57
51
  return this
58
52
  }
59
53
 
60
54
  setSortType(sortType) {
61
- if (sortType != null) {
62
- this.sortType = sortType
63
- }
55
+ this.sortType = sortType
64
56
  return this
65
57
  }
66
58
 
@@ -241,8 +233,7 @@ class QueryBuilder {
241
233
  }
242
234
 
243
235
  async run() {
244
- const appId = getAppId()
245
- const url = `${getCouchUrl()}/${appId}/_design/database/_search/${
236
+ const url = `${getCouchUrl()}/${this.appId}/_design/database/_search/${
246
237
  SearchIndexes.ROWS
247
238
  }`
248
239
  const body = this.buildSearchBody()
@@ -279,6 +270,7 @@ const runQuery = async (url, body) => {
279
270
  * Gets round the fixed limit of 200 results from a query by fetching as many
280
271
  * pages as required and concatenating the results. This recursively operates
281
272
  * until enough results have been found.
273
+ * @param appId {string} The app ID to search
282
274
  * @param query {object} The JSON query structure
283
275
  * @param params {object} The search params including:
284
276
  * tableId {string} The table ID to search
@@ -291,7 +283,7 @@ const runQuery = async (url, body) => {
291
283
  * rows {array|null} Current results in the recursive search
292
284
  * @returns {Promise<*[]|*>}
293
285
  */
294
- const recursiveSearch = async (query, params) => {
286
+ const recursiveSearch = async (appId, query, params) => {
295
287
  const bookmark = params.bookmark
296
288
  const rows = params.rows || []
297
289
  if (rows.length >= params.limit) {
@@ -301,7 +293,7 @@ const recursiveSearch = async (query, params) => {
301
293
  if (rows.length > params.limit - 200) {
302
294
  pageSize = params.limit - rows.length
303
295
  }
304
- const page = await new QueryBuilder(query)
296
+ const page = await new QueryBuilder(appId, query)
305
297
  .setVersion(params.version)
306
298
  .setTable(params.tableId)
307
299
  .setBookmark(bookmark)
@@ -321,13 +313,14 @@ const recursiveSearch = async (query, params) => {
321
313
  bookmark: page.bookmark,
322
314
  rows: [...rows, ...page.rows],
323
315
  }
324
- return await recursiveSearch(query, newParams)
316
+ return await recursiveSearch(appId, query, newParams)
325
317
  }
326
318
 
327
319
  /**
328
320
  * Performs a paginated search. A bookmark will be returned to allow the next
329
321
  * page to be fetched. There is a max limit off 200 results per page in a
330
322
  * paginated search.
323
+ * @param appId {string} The app ID to search
331
324
  * @param query {object} The JSON query structure
332
325
  * @param params {object} The search params including:
333
326
  * tableId {string} The table ID to search
@@ -339,13 +332,13 @@ const recursiveSearch = async (query, params) => {
339
332
  * bookmark {string} The bookmark to resume from
340
333
  * @returns {Promise<{hasNextPage: boolean, rows: *[]}>}
341
334
  */
342
- exports.paginatedSearch = async (query, params) => {
335
+ exports.paginatedSearch = async (appId, query, params) => {
343
336
  let limit = params.limit
344
337
  if (limit == null || isNaN(limit) || limit < 0) {
345
338
  limit = 50
346
339
  }
347
340
  limit = Math.min(limit, 200)
348
- const search = new QueryBuilder(query)
341
+ const search = new QueryBuilder(appId, query)
349
342
  .setVersion(params.version)
350
343
  .setTable(params.tableId)
351
344
  .setSort(params.sort)
@@ -374,6 +367,7 @@ exports.paginatedSearch = async (query, params) => {
374
367
  * desired amount of results. There is a limit of 1000 results to avoid
375
368
  * heavy performance hits, and to avoid client components breaking from
376
369
  * handling too much data.
370
+ * @param appId {string} The app ID to search
377
371
  * @param query {object} The JSON query structure
378
372
  * @param params {object} The search params including:
379
373
  * tableId {string} The table ID to search
@@ -384,12 +378,12 @@ exports.paginatedSearch = async (query, params) => {
384
378
  * limit {number} The desired number of results
385
379
  * @returns {Promise<{rows: *}>}
386
380
  */
387
- exports.fullSearch = async (query, params) => {
381
+ exports.fullSearch = async (appId, query, params) => {
388
382
  let limit = params.limit
389
383
  if (limit == null || isNaN(limit) || limit < 0) {
390
384
  limit = 1000
391
385
  }
392
386
  params.limit = Math.min(limit, 1000)
393
- const rows = await recursiveSearch(query, params)
387
+ const rows = await recursiveSearch(appId, query, params)
394
388
  return { rows }
395
389
  }
@@ -1,11 +1,11 @@
1
1
  const validateJs = require("validate.js")
2
2
  const { cloneDeep } = require("lodash/fp")
3
+ const CouchDB = require("../../../db")
3
4
  const { InternalTables } = require("../../../db/utils")
4
5
  const userController = require("../user")
5
6
  const { FieldTypes } = require("../../../constants")
6
7
  const { processStringSync } = require("@budibase/string-templates")
7
8
  const { makeExternalQuery } = require("../../../integrations/base/utils")
8
- const { getAppDB } = require("@budibase/backend-core/context")
9
9
 
10
10
  validateJs.extend(validateJs.validators.datetime, {
11
11
  parse: function (value) {
@@ -17,15 +17,14 @@ validateJs.extend(validateJs.validators.datetime, {
17
17
  },
18
18
  })
19
19
 
20
- exports.getDatasourceAndQuery = async json => {
20
+ exports.getDatasourceAndQuery = async (appId, json) => {
21
21
  const datasourceId = json.endpoint.datasourceId
22
- const db = getAppDB()
22
+ const db = new CouchDB(appId)
23
23
  const datasource = await db.get(datasourceId)
24
24
  return makeExternalQuery(datasource, json)
25
25
  }
26
26
 
27
- exports.findRow = async (ctx, tableId, rowId) => {
28
- const db = getAppDB()
27
+ exports.findRow = async (ctx, db, tableId, rowId) => {
29
28
  let row
30
29
  // TODO remove special user case in future
31
30
  if (tableId === InternalTables.USER_METADATA) {
@@ -43,9 +42,9 @@ exports.findRow = async (ctx, tableId, rowId) => {
43
42
  return row
44
43
  }
45
44
 
46
- exports.validate = async ({ tableId, row, table }) => {
45
+ exports.validate = async ({ appId, tableId, row, table }) => {
47
46
  if (!table) {
48
- const db = getAppDB()
47
+ const db = new CouchDB(appId)
49
48
  table = await db.get(tableId)
50
49
  }
51
50
  const errors = {}
@@ -59,16 +58,22 @@ exports.validate = async ({ tableId, row, table }) => {
59
58
  let res
60
59
 
61
60
  // Validate.js doesn't seem to handle array
62
- if (type === FieldTypes.ARRAY && row[fieldName]) {
63
- if (row[fieldName].length) {
61
+ if (type === FieldTypes.ARRAY) {
62
+ const hasValues =
63
+ Array.isArray(row[fieldName]) && row[fieldName].length > 0
64
+
65
+ // Check values are valid if values are specified
66
+ if (hasValues) {
64
67
  row[fieldName].map(val => {
65
68
  if (!constraints.inclusion.includes(val)) {
66
- errors[fieldName] = "Field not in list"
69
+ errors[fieldName] = "Value not in list"
67
70
  }
68
71
  })
69
- } else if (constraints.presence && row[fieldName].length === 0) {
70
- // non required MultiSelect creates an empty array, which should not throw errors
71
- errors[fieldName] = [`${fieldName} is required`]
72
+ }
73
+
74
+ // Check for required constraint
75
+ if (constraints.presence === true && !hasValues) {
76
+ errors[fieldName] = "Required field"
72
77
  }
73
78
  } else if (type === FieldTypes.JSON && typeof row[fieldName] === "string") {
74
79
  // this should only happen if there is an error
@@ -1,9 +1,10 @@
1
+ const CouchDB = require("../../db")
1
2
  const { getScreenParams, generateScreenID } = require("../../db/utils")
2
3
  const { AccessController } = require("@budibase/backend-core/roles")
3
- const { getAppDB } = require("@budibase/backend-core/context")
4
4
 
5
5
  exports.fetch = async ctx => {
6
- const db = getAppDB()
6
+ const appId = ctx.appId
7
+ const db = new CouchDB(appId)
7
8
 
8
9
  const screens = (
9
10
  await db.allDocs(
@@ -13,14 +14,15 @@ exports.fetch = async ctx => {
13
14
  )
14
15
  ).rows.map(element => element.doc)
15
16
 
16
- ctx.body = await new AccessController().checkScreensAccess(
17
+ ctx.body = await new AccessController(appId).checkScreensAccess(
17
18
  screens,
18
19
  ctx.user.role._id
19
20
  )
20
21
  }
21
22
 
22
23
  exports.save = async ctx => {
23
- const db = getAppDB()
24
+ const appId = ctx.appId
25
+ const db = new CouchDB(appId)
24
26
  let screen = ctx.request.body
25
27
 
26
28
  if (!screen._id) {
@@ -37,7 +39,7 @@ exports.save = async ctx => {
37
39
  }
38
40
 
39
41
  exports.destroy = async ctx => {
40
- const db = getAppDB()
42
+ const db = new CouchDB(ctx.appId)
41
43
  await db.remove(ctx.params.screenId, ctx.params.screenRev)
42
44
  ctx.body = {
43
45
  message: "Screen deleted successfully",
@@ -5,7 +5,8 @@ const { resolve, join } = require("../../../utilities/centralPath")
5
5
  const uuid = require("uuid")
6
6
  const { ObjectStoreBuckets } = require("../../../constants")
7
7
  const { processString } = require("@budibase/string-templates")
8
- const { getAllApps } = require("@budibase/backend-core/db")
8
+ const { getDeployedApps } = require("../../../utilities/workerRequests")
9
+ const CouchDB = require("../../../db")
9
10
  const {
10
11
  loadHandlebarsFile,
11
12
  NODE_MODULES_PATH,
@@ -16,9 +17,6 @@ const { clientLibraryPath } = require("../../../utilities")
16
17
  const { upload } = require("../../../utilities/fileSystem")
17
18
  const { attachmentsRelativeURL } = require("../../../utilities")
18
19
  const { DocumentTypes } = require("../../../db/utils")
19
- const { getAppDB } = require("@budibase/backend-core/context")
20
- const AWS = require("aws-sdk")
21
- const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1"
22
20
 
23
21
  async function prepareUpload({ s3Key, bucket, metadata, file }) {
24
22
  const response = await upload({
@@ -39,18 +37,12 @@ async function prepareUpload({ s3Key, bucket, metadata, file }) {
39
37
  }
40
38
  }
41
39
 
42
- async function getAppIdFromUrl(ctx) {
43
- // the "appId" component of the URL can be the id or the custom url
40
+ async function checkForSelfHostedURL(ctx) {
41
+ // the "appId" component of the URL may actually be a specific self hosted URL
44
42
  let possibleAppUrl = `/${encodeURI(ctx.params.appId).toLowerCase()}`
45
-
46
- // search prod apps for a url that matches, exclude dev where id is always used
47
- const apps = await getAllApps({ dev: false })
48
- const app = apps.filter(
49
- a => a.url && a.url.toLowerCase() === possibleAppUrl
50
- )[0]
51
-
52
- if (app && app.appId) {
53
- return app.appId
43
+ const apps = await getDeployedApps()
44
+ if (apps[possibleAppUrl] && apps[possibleAppUrl].appId) {
45
+ return apps[possibleAppUrl].appId
54
46
  } else {
55
47
  return ctx.params.appId
56
48
  }
@@ -83,9 +75,12 @@ exports.uploadFile = async function (ctx) {
83
75
  }
84
76
 
85
77
  exports.serveApp = async function (ctx) {
86
- let appId = await getAppIdFromUrl(ctx)
78
+ let appId = ctx.params.appId
79
+ if (env.SELF_HOSTED) {
80
+ appId = await checkForSelfHostedURL(ctx)
81
+ }
87
82
  const App = require("./templates/BudibaseApp.svelte").default
88
- const db = getAppDB({ skip_setup: true })
83
+ const db = new CouchDB(appId, { skip_setup: true })
89
84
  const appInfo = await db.get(DocumentTypes.APP_METADATA)
90
85
 
91
86
  const { head, html, css } = App.render({
@@ -109,51 +104,3 @@ exports.serveClientLibrary = async function (ctx) {
109
104
  root: join(NODE_MODULES_PATH, "@budibase", "client", "dist"),
110
105
  })
111
106
  }
112
-
113
- exports.getSignedUploadURL = async function (ctx) {
114
- const database = getAppDB()
115
-
116
- // Ensure datasource is valid
117
- let datasource
118
- try {
119
- const { datasourceId } = ctx.params
120
- datasource = await database.get(datasourceId)
121
- if (!datasource) {
122
- ctx.throw(400, "The specified datasource could not be found")
123
- }
124
- } catch (error) {
125
- ctx.throw(400, "The specified datasource could not be found")
126
- }
127
-
128
- // Ensure we aren't using a custom endpoint
129
- if (datasource?.config?.endpoint) {
130
- ctx.throw(400, "S3 datasources with custom endpoints are not supported")
131
- }
132
-
133
- // Determine type of datasource and generate signed URL
134
- let signedUrl
135
- let publicUrl
136
- if (datasource.source === "S3") {
137
- const { bucket, key } = ctx.request.body || {}
138
- if (!bucket || !key) {
139
- ctx.throw(400, "bucket and key values are required")
140
- return
141
- }
142
- try {
143
- const s3 = new AWS.S3({
144
- region: AWS_REGION,
145
- accessKeyId: datasource?.config?.accessKeyId,
146
- secretAccessKey: datasource?.config?.secretAccessKey,
147
- apiVersion: "2006-03-01",
148
- signatureVersion: "v4",
149
- })
150
- const params = { Bucket: bucket, Key: key }
151
- signedUrl = s3.getSignedUrl("putObject", params)
152
- publicUrl = `https://${bucket}.s3.${AWS_REGION}.amazonaws.com/${key}`
153
- } catch (error) {
154
- ctx.throw(400, error)
155
- }
156
- }
157
-
158
- ctx.body = { signedUrl, publicUrl }
159
- }
@@ -1,3 +1,4 @@
1
+ const CouchDB = require("../../../db")
1
2
  const {
2
3
  buildExternalTableId,
3
4
  breakExternalTableId,
@@ -18,7 +19,6 @@ const { makeExternalQuery } = require("../../../integrations/base/utils")
18
19
  const { cloneDeep } = require("lodash/fp")
19
20
  const csvParser = require("../../../utilities/csvParser")
20
21
  const { handleRequest } = require("../row/external")
21
- const { getAppDB } = require("@budibase/backend-core/context")
22
22
 
23
23
  async function makeTableRequest(
24
24
  datasource,
@@ -159,6 +159,7 @@ function isRelationshipSetup(column) {
159
159
  }
160
160
 
161
161
  exports.save = async function (ctx) {
162
+ const appId = ctx.appId
162
163
  const table = ctx.request.body
163
164
  // can't do this right now
164
165
  delete table.dataImport
@@ -175,14 +176,14 @@ exports.save = async function (ctx) {
175
176
 
176
177
  let oldTable
177
178
  if (ctx.request.body && ctx.request.body._id) {
178
- oldTable = await getTable(ctx.request.body._id)
179
+ oldTable = await getTable(appId, ctx.request.body._id)
179
180
  }
180
181
 
181
182
  if (hasTypeChanged(tableToSave, oldTable)) {
182
183
  ctx.throw(400, "A column type has changed.")
183
184
  }
184
185
 
185
- const db = getAppDB()
186
+ const db = new CouchDB(appId)
186
187
  const datasource = await db.get(datasourceId)
187
188
  const oldTables = cloneDeep(datasource.entities)
188
189
  const tables = datasource.entities
@@ -266,13 +267,14 @@ exports.save = async function (ctx) {
266
267
  }
267
268
 
268
269
  exports.destroy = async function (ctx) {
269
- const tableToDelete = await getTable(ctx.params.tableId)
270
+ const appId = ctx.appId
271
+ const tableToDelete = await getTable(appId, ctx.params.tableId)
270
272
  if (!tableToDelete || !tableToDelete.created) {
271
273
  ctx.throw(400, "Cannot delete tables which weren't created in Budibase.")
272
274
  }
273
275
  const datasourceId = getDatasourceId(tableToDelete)
274
276
 
275
- const db = getAppDB()
277
+ const db = new CouchDB(appId)
276
278
  const datasource = await db.get(datasourceId)
277
279
  const tables = datasource.entities
278
280
 
@@ -288,7 +290,8 @@ exports.destroy = async function (ctx) {
288
290
  }
289
291
 
290
292
  exports.bulkImport = async function (ctx) {
291
- const table = await getTable(ctx.params.tableId)
293
+ const appId = ctx.appId
294
+ const table = await getTable(appId, ctx.params.tableId)
292
295
  const { dataImport } = ctx.request.body
293
296
  if (!dataImport || !dataImport.schema || !dataImport.csvString) {
294
297
  ctx.throw(400, "Provided data import information is invalid.")
@@ -297,7 +300,7 @@ exports.bulkImport = async function (ctx) {
297
300
  ...dataImport,
298
301
  existingTable: table,
299
302
  })
300
- await handleRequest(DataSourceOperation.BULK_CREATE, table._id, {
303
+ await handleRequest(appId, DataSourceOperation.BULK_CREATE, table._id, {
301
304
  rows,
302
305
  })
303
306
  return table
@@ -1,10 +1,14 @@
1
+ const CouchDB = require("../../../db")
1
2
  const internal = require("./internal")
2
3
  const external = require("./external")
3
4
  const csvParser = require("../../../utilities/csvParser")
4
- const { isExternalTable, isSQL } = require("../../../integrations/utils")
5
- const { getDatasourceParams } = require("../../../db/utils")
6
- const { getAppDB } = require("@budibase/backend-core/context")
7
- const { getTable, getAllInternalTables } = require("./utils")
5
+ const { isExternalTable } = require("../../../integrations/utils")
6
+ const {
7
+ getTableParams,
8
+ getDatasourceParams,
9
+ BudibaseInternalDB,
10
+ } = require("../../../db/utils")
11
+ const { getTable } = require("./utils")
8
12
 
9
13
  function pickApi({ tableId, table }) {
10
14
  if (table && !tableId) {
@@ -20,9 +24,19 @@ function pickApi({ tableId, table }) {
20
24
 
21
25
  // covers both internal and external
22
26
  exports.fetch = async function (ctx) {
23
- const db = getAppDB()
27
+ const db = new CouchDB(ctx.appId)
24
28
 
25
- const internal = await getAllInternalTables()
29
+ const internalTables = await db.allDocs(
30
+ getTableParams(null, {
31
+ include_docs: true,
32
+ })
33
+ )
34
+
35
+ const internal = internalTables.rows.map(row => ({
36
+ ...row.doc,
37
+ type: "internal",
38
+ sourceId: BudibaseInternalDB._id,
39
+ }))
26
40
 
27
41
  const externalTables = await db.allDocs(
28
42
  getDatasourceParams("plus", {
@@ -30,18 +44,12 @@ exports.fetch = async function (ctx) {
30
44
  })
31
45
  )
32
46
 
33
- const external = externalTables.rows.flatMap(tableDoc => {
34
- let entities = tableDoc.doc.entities
35
- if (entities) {
36
- return Object.values(entities).map(entity => ({
37
- ...entity,
38
- type: "external",
39
- sourceId: tableDoc.doc._id,
40
- sql: isSQL(tableDoc.doc),
41
- }))
42
- } else {
43
- return []
44
- }
47
+ const external = externalTables.rows.flatMap(row => {
48
+ return Object.values(row.doc.entities || {}).map(entity => ({
49
+ ...entity,
50
+ type: "external",
51
+ sourceId: row.doc._id,
52
+ }))
45
53
  })
46
54
 
47
55
  ctx.body = [...internal, ...external]
@@ -49,7 +57,7 @@ exports.fetch = async function (ctx) {
49
57
 
50
58
  exports.find = async function (ctx) {
51
59
  const tableId = ctx.params.id
52
- ctx.body = await getTable(tableId)
60
+ ctx.body = await getTable(ctx.appId, tableId)
53
61
  }
54
62
 
55
63
  exports.save = async function (ctx) {
@@ -88,7 +96,7 @@ exports.validateCSVSchema = async function (ctx) {
88
96
  const { csvString, schema = {}, tableId } = ctx.request.body
89
97
  let existingTable
90
98
  if (tableId) {
91
- existingTable = await getTable(tableId)
99
+ existingTable = await getTable(ctx.appId, tableId)
92
100
  }
93
101
  let result = await csvParser.parse(csvString, schema)
94
102
  if (existingTable) {
@@ -1,3 +1,4 @@
1
+ const CouchDB = require("../../../db")
1
2
  const linkRows = require("../../../db/linkedRows")
2
3
  const { getRowParams, generateTableID } = require("../../../db/utils")
3
4
  const { FieldTypes } = require("../../../constants")
@@ -7,14 +8,10 @@ const {
7
8
  getTable,
8
9
  handleDataImport,
9
10
  } = require("./utils")
10
- const usageQuota = require("../../../utilities/usageQuota")
11
- const { getAppDB } = require("@budibase/backend-core/context")
12
- const env = require("../../../environment")
13
- const { cleanupAttachments } = require("../../../utilities/rowProcessor")
14
- const { runStaticFormulaChecks } = require("./bulkFormula")
15
11
 
16
12
  exports.save = async function (ctx) {
17
- const db = getAppDB()
13
+ const appId = ctx.appId
14
+ const db = new CouchDB(appId)
18
15
  const { dataImport, ...rest } = ctx.request.body
19
16
  let tableToSave = {
20
17
  type: "table",
@@ -36,7 +33,8 @@ exports.save = async function (ctx) {
36
33
  // saving a table is a complex operation, involving many different steps, this
37
34
  // has been broken out into a utility to make it more obvious/easier to manipulate
38
35
  const tableSaveFunctions = new TableSaveFunctions({
39
- user: ctx.user,
36
+ db,
37
+ ctx,
40
38
  oldTable,
41
39
  dataImport,
42
40
  })
@@ -81,6 +79,7 @@ exports.save = async function (ctx) {
81
79
  // update linked rows
82
80
  try {
83
81
  const linkResp = await linkRows.updateLinks({
82
+ appId,
84
83
  eventType: oldTable
85
84
  ? linkRows.EventType.TABLE_UPDATED
86
85
  : linkRows.EventType.TABLE_SAVE,
@@ -104,13 +103,13 @@ exports.save = async function (ctx) {
104
103
  tableToSave._rev = result.rev
105
104
 
106
105
  tableToSave = await tableSaveFunctions.after(tableToSave)
107
- // has to run after, make sure it has _id
108
- await runStaticFormulaChecks(tableToSave, { oldTable })
106
+
109
107
  return tableToSave
110
108
  }
111
109
 
112
110
  exports.destroy = async function (ctx) {
113
- const db = getAppDB()
111
+ const appId = ctx.appId
112
+ const db = new CouchDB(appId)
114
113
  const tableToDelete = await db.get(ctx.params.tableId)
115
114
 
116
115
  // Delete all rows for that table
@@ -120,10 +119,10 @@ exports.destroy = async function (ctx) {
120
119
  })
121
120
  )
122
121
  await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
123
- await usageQuota.update(usageQuota.Properties.ROW, -rows.rows.length)
124
122
 
125
123
  // update linked rows
126
124
  await linkRows.updateLinks({
125
+ appId,
127
126
  eventType: linkRows.EventType.TABLE_DELETE,
128
127
  table: tableToDelete,
129
128
  })
@@ -132,25 +131,21 @@ exports.destroy = async function (ctx) {
132
131
  await db.remove(tableToDelete)
133
132
 
134
133
  // remove table search index
135
- if (!env.isTest()) {
136
- const currentIndexes = await db.getIndexes()
137
- const existingIndex = currentIndexes.indexes.find(
138
- existing => existing.name === `search:${ctx.params.tableId}`
139
- )
140
- if (existingIndex) {
141
- await db.deleteIndex(existingIndex)
142
- }
134
+ const currentIndexes = await db.getIndexes()
135
+ const existingIndex = currentIndexes.indexes.find(
136
+ existing => existing.name === `search:${ctx.params.tableId}`
137
+ )
138
+ if (existingIndex) {
139
+ await db.deleteIndex(existingIndex)
143
140
  }
144
141
 
145
- // has to run after, make sure it has _id
146
- await runStaticFormulaChecks(tableToDelete, { deletion: true })
147
- await cleanupAttachments(tableToDelete, { rows })
148
142
  return tableToDelete
149
143
  }
150
144
 
151
145
  exports.bulkImport = async function (ctx) {
152
- const table = await getTable(ctx.params.tableId)
146
+ const appId = ctx.appId
147
+ const table = await getTable(appId, ctx.params.tableId)
153
148
  const { dataImport } = ctx.request.body
154
- await handleDataImport(ctx.user, table, dataImport)
149
+ await handleDataImport(appId, ctx.user, table, dataImport)
155
150
  return table
156
151
  }