@budibase/server 1.0.123-alpha.0 → 1.0.123

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 (330) hide show
  1. package/builder/assets/index.68a7f4e3.css +6 -0
  2. package/builder/assets/index.8d4a5b33.js +1291 -0
  3. package/builder/assets/{vendor.5240f480.js → vendor.8e34a169.js} +1 -1
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +1763 -758
  6. package/coverage/coverage-final.json +43 -28
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +3 -8
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +4 -9
  9. package/coverage/lcov-report/api/controllers/application.js.html +1436 -0
  10. package/coverage/lcov-report/api/controllers/auth.js.html +3 -8
  11. package/coverage/lcov-report/api/controllers/automation.js.html +3 -8
  12. package/coverage/lcov-report/api/controllers/backup.js.html +3 -8
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +3 -8
  14. package/coverage/lcov-report/api/controllers/component.js.html +3 -8
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +6 -11
  16. package/coverage/lcov-report/api/controllers/dev.js.html +3 -8
  17. package/coverage/lcov-report/api/controllers/index.html +26 -16
  18. package/coverage/lcov-report/api/controllers/integration.js.html +3 -8
  19. package/coverage/lcov-report/api/controllers/layout.js.html +3 -8
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -8
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +3 -8
  22. package/coverage/lcov-report/api/controllers/permission.js.html +3 -8
  23. package/coverage/lcov-report/api/controllers/query/index.html +26 -16
  24. package/coverage/lcov-report/api/controllers/query/index.js.html +713 -0
  25. package/coverage/lcov-report/api/controllers/query/validation.js.html +3 -8
  26. package/coverage/lcov-report/api/controllers/role.js.html +5 -10
  27. package/coverage/lcov-report/api/controllers/routing.js.html +4 -9
  28. package/coverage/lcov-report/api/controllers/row/external.js.html +3 -8
  29. package/coverage/lcov-report/api/controllers/row/index.html +35 -25
  30. package/coverage/lcov-report/api/controllers/row/index.js.html +524 -0
  31. package/coverage/lcov-report/api/controllers/row/internal.js.html +24 -32
  32. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +16 -21
  33. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +19 -24
  34. package/coverage/lcov-report/api/controllers/row/utils.js.html +19 -33
  35. package/coverage/lcov-report/api/controllers/screen.js.html +4 -9
  36. package/coverage/lcov-report/api/controllers/script.js.html +3 -8
  37. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +50 -55
  38. package/coverage/lcov-report/api/controllers/table/external.js.html +3 -8
  39. package/coverage/lcov-report/api/controllers/table/index.html +44 -19
  40. package/coverage/lcov-report/api/controllers/table/index.js.html +15 -20
  41. package/coverage/lcov-report/api/controllers/table/internal.js.html +620 -0
  42. package/coverage/lcov-report/api/controllers/table/utils.js.html +1331 -0
  43. package/coverage/lcov-report/api/controllers/templates.js.html +3 -8
  44. package/coverage/lcov-report/api/controllers/user.js.html +3 -8
  45. package/coverage/lcov-report/api/controllers/view/exporters.js.html +3 -8
  46. package/coverage/lcov-report/api/controllers/view/index.html +3 -8
  47. package/coverage/lcov-report/api/controllers/view/index.js.html +5 -10
  48. package/coverage/lcov-report/api/controllers/view/utils.js.html +3 -8
  49. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -8
  50. package/coverage/lcov-report/api/controllers/webhook.js.html +5 -10
  51. package/coverage/lcov-report/api/index.html +13 -18
  52. package/coverage/lcov-report/api/index.js.html +8 -28
  53. package/coverage/lcov-report/api/routes/analytics.js.html +3 -8
  54. package/coverage/lcov-report/api/routes/apikeys.js.html +3 -8
  55. package/coverage/lcov-report/api/routes/application.js.html +179 -0
  56. package/coverage/lcov-report/api/routes/auth.js.html +3 -8
  57. package/coverage/lcov-report/api/routes/automation.js.html +3 -8
  58. package/coverage/lcov-report/api/routes/backup.js.html +3 -8
  59. package/coverage/lcov-report/api/routes/cloud.js.html +3 -8
  60. package/coverage/lcov-report/api/routes/component.js.html +3 -8
  61. package/coverage/lcov-report/api/routes/datasource.js.html +3 -8
  62. package/coverage/lcov-report/api/routes/deploy.js.html +3 -8
  63. package/coverage/lcov-report/api/routes/dev.js.html +4 -9
  64. package/coverage/lcov-report/api/routes/index.html +68 -13
  65. package/coverage/lcov-report/api/routes/index.js.html +266 -0
  66. package/coverage/lcov-report/api/routes/integration.js.html +3 -8
  67. package/coverage/lcov-report/api/routes/layout.js.html +3 -8
  68. package/coverage/lcov-report/api/routes/metadata.js.html +3 -8
  69. package/coverage/lcov-report/api/routes/migrations.js.html +3 -8
  70. package/coverage/lcov-report/api/routes/permission.js.html +3 -8
  71. package/coverage/lcov-report/api/routes/query.js.html +3 -8
  72. package/coverage/lcov-report/api/routes/role.js.html +3 -8
  73. package/coverage/lcov-report/api/routes/routing.js.html +3 -8
  74. package/coverage/lcov-report/api/routes/row.js.html +908 -0
  75. package/coverage/lcov-report/api/routes/screen.js.html +3 -8
  76. package/coverage/lcov-report/api/routes/script.js.html +3 -8
  77. package/coverage/lcov-report/{automations/steps/loop.js.html → api/routes/static.js.html} +80 -70
  78. package/coverage/lcov-report/api/routes/table.js.html +3 -8
  79. package/coverage/lcov-report/api/routes/templates.js.html +3 -8
  80. package/coverage/lcov-report/api/routes/user.js.html +3 -8
  81. package/coverage/lcov-report/api/routes/utils/index.html +3 -8
  82. package/coverage/lcov-report/api/routes/utils/validators.js.html +3 -8
  83. package/coverage/lcov-report/api/routes/view.js.html +3 -8
  84. package/coverage/lcov-report/api/routes/webhook.js.html +3 -8
  85. package/coverage/lcov-report/automations/actions.js.html +7 -21
  86. package/coverage/lcov-report/automations/automationUtils.js.html +23 -64
  87. package/coverage/lcov-report/automations/bullboard.js.html +3 -8
  88. package/coverage/lcov-report/automations/index.html +37 -27
  89. package/coverage/lcov-report/automations/index.js.html +3 -8
  90. package/coverage/lcov-report/automations/steps/bash.js.html +3 -8
  91. package/coverage/lcov-report/automations/steps/createRow.js.html +380 -0
  92. package/coverage/lcov-report/automations/steps/delay.js.html +3 -8
  93. package/coverage/lcov-report/automations/steps/deleteRow.js.html +347 -0
  94. package/coverage/lcov-report/automations/steps/discord.js.html +3 -8
  95. package/coverage/lcov-report/automations/steps/executeQuery.js.html +3 -8
  96. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -8
  97. package/coverage/lcov-report/automations/steps/filter.js.html +3 -8
  98. package/coverage/lcov-report/automations/steps/index.html +41 -31
  99. package/coverage/lcov-report/automations/steps/integromat.js.html +3 -8
  100. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +4 -9
  101. package/coverage/lcov-report/automations/steps/queryRows.js.html +4 -9
  102. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +3 -8
  103. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -8
  104. package/coverage/lcov-report/automations/steps/slack.js.html +3 -8
  105. package/coverage/lcov-report/automations/steps/updateRow.js.html +3 -8
  106. package/coverage/lcov-report/automations/steps/utils.js.html +9 -14
  107. package/coverage/lcov-report/automations/steps/zapier.js.html +3 -8
  108. package/coverage/lcov-report/automations/triggerInfo/app.js.html +3 -8
  109. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +3 -8
  110. package/coverage/lcov-report/automations/triggerInfo/index.html +3 -8
  111. package/coverage/lcov-report/automations/triggerInfo/index.js.html +3 -8
  112. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +3 -8
  113. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +3 -8
  114. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +3 -8
  115. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +3 -8
  116. package/coverage/lcov-report/automations/triggers.js.html +11 -16
  117. package/coverage/lcov-report/automations/utils.js.html +665 -0
  118. package/coverage/lcov-report/block-navigation.js +0 -8
  119. package/coverage/lcov-report/constants/index.html +3 -8
  120. package/coverage/lcov-report/constants/index.js.html +42 -41
  121. package/coverage/lcov-report/constants/layouts.js.html +3 -8
  122. package/coverage/lcov-report/constants/screens.js.html +3 -8
  123. package/coverage/lcov-report/db/inMemoryView.js.html +3 -8
  124. package/coverage/lcov-report/db/index.html +3 -8
  125. package/coverage/lcov-report/db/index.js.html +4 -9
  126. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +23 -25
  127. package/coverage/lcov-report/db/linkedRows/index.html +12 -17
  128. package/coverage/lcov-report/db/linkedRows/index.js.html +17 -22
  129. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +7 -12
  130. package/coverage/lcov-report/db/newid.js.html +6 -11
  131. package/coverage/lcov-report/db/utils.js.html +79 -84
  132. package/coverage/lcov-report/events/AutomationEmitter.js.html +9 -14
  133. package/coverage/lcov-report/events/index.html +3 -8
  134. package/coverage/lcov-report/events/index.js.html +4 -9
  135. package/coverage/lcov-report/events/utils.js.html +13 -18
  136. package/coverage/lcov-report/index.html +132 -137
  137. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +3 -8
  138. package/coverage/lcov-report/integrations/tests/index.html +3 -8
  139. package/coverage/lcov-report/middleware/appInfo.js.html +3 -8
  140. package/coverage/lcov-report/middleware/authorized.js.html +458 -0
  141. package/coverage/lcov-report/middleware/builder.js.html +3 -8
  142. package/coverage/lcov-report/middleware/currentapp.js.html +15 -65
  143. package/coverage/lcov-report/middleware/index.html +50 -25
  144. package/coverage/lcov-report/middleware/joi-validator.js.html +4 -9
  145. package/coverage/lcov-report/middleware/publicApi.js.html +3 -8
  146. package/coverage/lcov-report/middleware/resourceId.js.html +3 -8
  147. package/coverage/lcov-report/middleware/selfhost.js.html +4 -9
  148. package/coverage/lcov-report/middleware/usageQuota.js.html +572 -0
  149. package/coverage/lcov-report/middleware/utils.js.html +3 -8
  150. package/coverage/lcov-report/sorter.js +0 -26
  151. package/coverage/lcov-report/threads/automation.js.html +90 -581
  152. package/coverage/lcov-report/threads/index.html +40 -30
  153. package/coverage/lcov-report/threads/index.js.html +296 -0
  154. package/coverage/lcov-report/threads/query.js.html +4 -9
  155. package/coverage/lcov-report/threads/utils.js.html +9 -17
  156. package/coverage/lcov-report/utilities/bcrypt.js.html +3 -8
  157. package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -8
  158. package/coverage/lcov-report/utilities/centralPath.js.html +3 -8
  159. package/coverage/lcov-report/utilities/csvParser.js.html +5 -10
  160. package/coverage/lcov-report/utilities/global.js.html +4 -9
  161. package/coverage/lcov-report/utilities/index.html +3 -8
  162. package/coverage/lcov-report/utilities/index.js.html +6 -11
  163. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +9 -32
  164. package/coverage/lcov-report/utilities/queue/index.html +7 -12
  165. package/coverage/lcov-report/utilities/routing/index.html +3 -8
  166. package/coverage/lcov-report/utilities/routing/index.js.html +3 -8
  167. package/coverage/lcov-report/utilities/rowProcessor/index.html +27 -32
  168. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +71 -67
  169. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +106 -27
  170. package/coverage/lcov-report/utilities/scriptRunner.js.html +3 -8
  171. package/coverage/lcov-report/utilities/security.js.html +4 -9
  172. package/coverage/lcov-report/utilities/statusCodes.js.html +3 -8
  173. package/coverage/lcov-report/utilities/usageQuota/index.html +34 -24
  174. package/coverage/lcov-report/utilities/usageQuota/index.js.html +359 -0
  175. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +39 -44
  176. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +3 -8
  177. package/coverage/lcov-report/utilities/users.js.html +3 -8
  178. package/coverage/lcov-report/utilities/workerRequests.js.html +4 -9
  179. package/coverage/lcov.info +3061 -1290
  180. package/dist/api/controllers/application.js +73 -145
  181. package/dist/api/controllers/deploy/index.js +36 -68
  182. package/dist/api/controllers/public/applications.js +9 -29
  183. package/dist/api/controllers/public/queries.js +7 -27
  184. package/dist/api/controllers/public/rows.js +12 -32
  185. package/dist/api/controllers/public/tables.js +2 -2
  186. package/dist/api/controllers/public/users.js +8 -8
  187. package/dist/api/controllers/public/utils.js +1 -1
  188. package/dist/api/controllers/query/import/index.js +3 -3
  189. package/dist/api/controllers/query/index.js +44 -57
  190. package/dist/api/controllers/row/ExternalRequest.js +27 -27
  191. package/dist/api/controllers/row/index.js +60 -83
  192. package/dist/api/controllers/row/internal.js +1 -2
  193. package/dist/api/controllers/row/utils.js +1 -2
  194. package/dist/api/controllers/static/templates/BudibaseApp.svelte +0 -3
  195. package/dist/api/controllers/table/bulkFormula.js +1 -2
  196. package/dist/api/controllers/table/internal.js +55 -40
  197. package/dist/api/controllers/table/utils.js +229 -271
  198. package/dist/api/index.js +0 -5
  199. package/dist/api/routes/application.js +13 -39
  200. package/dist/api/routes/index.js +56 -61
  201. package/dist/api/routes/public/index.js +9 -6
  202. package/dist/api/routes/public/queries.js +1 -1
  203. package/dist/api/routes/public/rows.js +1 -1
  204. package/dist/api/routes/public/tables.js +3 -3
  205. package/dist/api/routes/public/users.js +1 -1
  206. package/dist/api/routes/row.js +17 -43
  207. package/dist/api/routes/static.js +13 -40
  208. package/dist/api/routes/tests/utilities/TestFunctions.js +33 -75
  209. package/dist/app.js +4 -8
  210. package/dist/automations/actions.js +0 -3
  211. package/dist/automations/automationUtils.js +0 -10
  212. package/dist/automations/steps/createRow.js +12 -12
  213. package/dist/automations/steps/deleteRow.js +16 -13
  214. package/dist/automations/tests/utilities/index.js +11 -13
  215. package/dist/automations/utils.js +133 -187
  216. package/dist/constants/index.js +7 -5
  217. package/dist/db/linkedRows/LinkController.js +1 -0
  218. package/dist/definitions/datasource.js +0 -1
  219. package/dist/environment.js +3 -2
  220. package/dist/index.js +0 -4
  221. package/dist/integrations/base/sql.js +2 -2
  222. package/dist/integrations/base/sqlTable.js +2 -2
  223. package/dist/integrations/googlesheets.js +1 -1
  224. package/dist/integrations/index.js +0 -4
  225. package/dist/integrations/microsoftSqlServer.js +8 -8
  226. package/dist/integrations/mysql.js +9 -9
  227. package/dist/integrations/oracle.js +7 -7
  228. package/dist/integrations/postgres.js +7 -7
  229. package/dist/integrations/queries/sql.js +2 -2
  230. package/dist/integrations/rest.js +1 -1
  231. package/dist/middleware/authorized.js +51 -51
  232. package/dist/middleware/currentapp.js +1 -15
  233. package/dist/middleware/usageQuota.js +154 -0
  234. package/dist/migrations/functions/appUrls.js +1 -1
  235. package/dist/migrations/functions/quotas1.js +2 -6
  236. package/dist/migrations/functions/usageQuotas/index.js +4 -0
  237. package/dist/migrations/functions/usageQuotas/syncApps.js +7 -4
  238. package/dist/migrations/functions/usageQuotas/syncRows.js +8 -5
  239. package/dist/migrations/index.js +1 -17
  240. package/dist/package.json +4 -10
  241. package/dist/threads/automation.js +27 -149
  242. package/dist/threads/index.js +10 -36
  243. package/dist/threads/utils.js +0 -1
  244. package/dist/tsconfig.tsbuildinfo +1 -0
  245. package/dist/utilities/queue/inMemoryQueue.js +1 -6
  246. package/dist/utilities/rowProcessor/index.js +11 -6
  247. package/dist/utilities/rowProcessor/utils.js +27 -1
  248. package/dist/utilities/usageQuota/index.js +86 -0
  249. package/nodemon.json +1 -1
  250. package/package.json +9 -15
  251. package/scripts/dev/manage.js +0 -2
  252. package/src/api/controllers/{application.ts → application.js} +51 -118
  253. package/src/api/controllers/deploy/{index.ts → index.js} +29 -53
  254. package/src/api/controllers/public/applications.ts +2 -2
  255. package/src/api/controllers/public/queries.ts +1 -1
  256. package/src/api/controllers/public/rows.ts +1 -1
  257. package/src/api/controllers/query/{index.ts → index.js} +48 -51
  258. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  259. package/src/api/controllers/row/{index.ts → index.js} +17 -24
  260. package/src/api/controllers/row/internal.js +1 -2
  261. package/src/api/controllers/row/utils.js +1 -4
  262. package/src/api/controllers/static/templates/BudibaseApp.svelte +0 -3
  263. package/src/api/controllers/table/bulkFormula.js +1 -1
  264. package/src/api/controllers/table/{internal.ts → internal.js} +48 -27
  265. package/src/api/controllers/table/{utils.ts → utils.js} +69 -86
  266. package/src/api/index.js +0 -5
  267. package/src/api/routes/{application.ts → application.js} +14 -8
  268. package/src/api/routes/index.js +62 -0
  269. package/src/api/routes/public/index.ts +4 -1
  270. package/src/api/routes/{row.ts → row.js} +15 -7
  271. package/src/api/routes/{static.ts → static.js} +11 -11
  272. package/src/api/routes/tests/misc.spec.js +37 -39
  273. package/src/api/routes/tests/routing.spec.js +0 -1
  274. package/src/api/routes/tests/utilities/{TestFunctions.ts → TestFunctions.js} +33 -57
  275. package/src/app.ts +2 -1
  276. package/src/automations/actions.js +0 -3
  277. package/src/automations/automationUtils.js +0 -12
  278. package/src/automations/steps/{createRow.ts → createRow.js} +15 -9
  279. package/src/automations/steps/{deleteRow.ts → deleteRow.js} +16 -10
  280. package/src/automations/tests/automation.spec.js +1 -0
  281. package/src/automations/tests/{createRow.spec.ts → createRow.spec.js} +15 -4
  282. package/src/automations/tests/{deleteRow.spec.ts → deleteRow.spec.js} +5 -3
  283. package/src/automations/tests/utilities/index.js +10 -12
  284. package/src/automations/{utils.ts → utils.js} +28 -39
  285. package/src/constants/index.js +8 -6
  286. package/src/db/linkedRows/LinkController.js +1 -0
  287. package/src/definitions/datasource.ts +0 -1
  288. package/src/environment.js +3 -2
  289. package/src/index.ts +0 -3
  290. package/src/integrations/index.ts +0 -4
  291. package/src/middleware/{authorized.ts → authorized.js} +14 -20
  292. package/src/middleware/currentapp.js +1 -16
  293. package/src/middleware/tests/usageQuota.spec.js +120 -0
  294. package/src/middleware/usageQuota.js +164 -0
  295. package/src/migrations/functions/tests/quotas1.spec.js +2 -0
  296. package/src/migrations/functions/usageQuotas/index.ts +5 -0
  297. package/src/migrations/functions/usageQuotas/syncApps.ts +6 -3
  298. package/src/migrations/functions/usageQuotas/syncRows.ts +6 -3
  299. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +41 -0
  300. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +45 -0
  301. package/src/migrations/index.ts +1 -13
  302. package/src/threads/automation.js +34 -196
  303. package/src/threads/{index.ts → index.js} +14 -18
  304. package/src/threads/utils.js +0 -1
  305. package/src/utilities/queue/inMemoryQueue.js +1 -7
  306. package/src/utilities/rowProcessor/index.js +12 -9
  307. package/src/utilities/rowProcessor/utils.js +29 -1
  308. package/src/utilities/tests/usageQuota/usageQuota.spec.js +72 -0
  309. package/src/utilities/usageQuota/index.js +93 -0
  310. package/tsconfig.json +2 -2
  311. package/builder/assets/index.89795487.css +0 -6
  312. package/builder/assets/index.be9a1b80.js +0 -1299
  313. package/dist/automations/steps/loop.js +0 -51
  314. package/dist/integrations/redis.js +0 -158
  315. package/dist/migrations/functions/developerQuota.js +0 -49
  316. package/dist/migrations/functions/publishedAppsQuota.js +0 -47
  317. package/dist/migrations/functions/usageQuotas/syncDevelopers.js +0 -24
  318. package/dist/migrations/functions/usageQuotas/syncPublishedApps.js +0 -26
  319. package/dist/tsconfig.build.tsbuildinfo +0 -1
  320. package/src/api/routes/index.ts +0 -60
  321. package/src/automations/steps/loop.js +0 -50
  322. package/src/integrations/redis.ts +0 -152
  323. package/src/integrations/tests/redis.spec.js +0 -60
  324. package/src/migrations/functions/developerQuota.ts +0 -15
  325. package/src/migrations/functions/publishedAppsQuota.ts +0 -13
  326. package/src/migrations/functions/usageQuotas/syncDevelopers.ts +0 -19
  327. package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +0 -21
  328. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts +0 -34
  329. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +0 -40
  330. package/tsconfig.build.json +0 -10
@@ -1,31 +1,26 @@
1
- import { Thread, ThreadType } from "../threads"
2
- import { definitions } from "./triggerInfo"
3
- import * as webhooks from "../api/controllers/webhook"
4
- import { queue } from "./bullboard"
5
- import newid from "../db/newid"
6
- import { updateEntityMetadata } from "../utilities"
7
- import { MetadataTypes, WebhookType } from "../constants"
8
- import { getProdAppID, doWithDB } from "@budibase/backend-core/db"
9
- import { cloneDeep } from "lodash/fp"
10
- import { getAppDB, getAppId } from "@budibase/backend-core/context"
11
- import { tenancy } from "@budibase/backend-core"
12
- import { quotas } from "@budibase/pro"
1
+ const { Thread, ThreadType } = require("../threads")
2
+ const { definitions } = require("./triggerInfo")
3
+ const webhooks = require("../api/controllers/webhook")
4
+ const { queue } = require("./bullboard")
5
+ const newid = require("../db/newid")
6
+ const { updateEntityMetadata } = require("../utilities")
7
+ const { MetadataTypes, WebhookType } = require("../constants")
8
+ const { getProdAppID } = require("@budibase/backend-core/db")
9
+ const { cloneDeep } = require("lodash/fp")
10
+ const { doWithDB } = require("@budibase/backend-core/db")
11
+ const { getAppDB, getAppId } = require("@budibase/backend-core/context")
13
12
 
14
13
  const WH_STEP_ID = definitions.WEBHOOK.stepId
15
14
  const CRON_STEP_ID = definitions.CRON.stepId
16
15
  const Runner = new Thread(ThreadType.AUTOMATION)
17
16
 
18
- export async function processEvent(job: any) {
17
+ exports.processEvent = async job => {
19
18
  try {
19
+ // need to actually await these so that an error can be captured properly
20
20
  console.log(
21
21
  `${job.data.automation.appId} automation ${job.data.automation._id} running`
22
22
  )
23
- // need to actually await these so that an error can be captured properly
24
- const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
25
- return await tenancy.doInTenant(tenantId, async () => {
26
- const runFn = () => Runner.run(job)
27
- return quotas.addAutomation(runFn)
28
- })
23
+ return await Runner.run(job)
29
24
  } catch (err) {
30
25
  const errJson = JSON.stringify(err)
31
26
  console.error(
@@ -36,15 +31,11 @@ export async function processEvent(job: any) {
36
31
  }
37
32
  }
38
33
 
39
- export async function updateTestHistory(
40
- appId: any,
41
- automation: any,
42
- history: any
43
- ) {
34
+ exports.updateTestHistory = async (appId, automation, history) => {
44
35
  return updateEntityMetadata(
45
36
  MetadataTypes.AUTOMATION_TEST_HISTORY,
46
37
  automation._id,
47
- (metadata: any) => {
38
+ metadata => {
48
39
  if (metadata && Array.isArray(metadata.history)) {
49
40
  metadata.history.push(history)
50
41
  } else {
@@ -57,7 +48,7 @@ export async function updateTestHistory(
57
48
  )
58
49
  }
59
50
 
60
- export function removeDeprecated(definitions: any) {
51
+ exports.removeDeprecated = definitions => {
61
52
  const base = cloneDeep(definitions)
62
53
  for (let key of Object.keys(base)) {
63
54
  if (base[key].deprecated) {
@@ -68,15 +59,13 @@ export function removeDeprecated(definitions: any) {
68
59
  }
69
60
 
70
61
  // end the repetition and the job itself
71
- export async function disableAllCrons(appId: any) {
62
+ exports.disableAllCrons = async appId => {
72
63
  const promises = []
73
64
  const jobs = await queue.getRepeatableJobs()
74
65
  for (let job of jobs) {
75
66
  if (job.key.includes(`${appId}_cron`)) {
76
67
  promises.push(queue.removeRepeatableByKey(job.key))
77
- if (job.id) {
78
- promises.push(queue.removeJobs(job.id))
79
- }
68
+ promises.push(queue.removeJobs(job.id))
80
69
  }
81
70
  }
82
71
  return Promise.all(promises)
@@ -87,9 +76,9 @@ export async function disableAllCrons(appId: any) {
87
76
  * @param {string} appId The ID of the app in which we are checking for webhooks
88
77
  * @param {object|undefined} automation The automation object to be updated.
89
78
  */
90
- export async function enableCronTrigger(appId: any, automation: any) {
79
+ exports.enableCronTrigger = async (appId, automation) => {
91
80
  const trigger = automation ? automation.definition.trigger : null
92
- function isCronTrigger(auto: any) {
81
+ function isCronTrigger(auto) {
93
82
  return (
94
83
  auto &&
95
84
  auto.definition.trigger &&
@@ -100,7 +89,7 @@ export async function enableCronTrigger(appId: any, automation: any) {
100
89
  if (isCronTrigger(automation)) {
101
90
  // make a job id rather than letting Bull decide, makes it easier to handle on way out
102
91
  const jobId = `${appId}_cron_${newid()}`
103
- const job: any = await queue.add(
92
+ const job = await queue.add(
104
93
  {
105
94
  automation,
106
95
  event: { appId, timestamp: Date.now() },
@@ -112,7 +101,7 @@ export async function enableCronTrigger(appId: any, automation: any) {
112
101
  // can't use getAppDB here as this is likely to be called from dev app,
113
102
  // but this call could be for dev app or prod app, need to just use what
114
103
  // was passed in
115
- await doWithDB(appId, async (db: any) => {
104
+ await doWithDB(appId, async db => {
116
105
  const response = await db.put(automation)
117
106
  automation._id = response.id
118
107
  automation._rev = response.rev
@@ -129,13 +118,13 @@ export async function enableCronTrigger(appId: any, automation: any) {
129
118
  * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
130
119
  * written to DB (this does not write to DB as it would be wasteful to repeat).
131
120
  */
132
- export async function checkForWebhooks({ oldAuto, newAuto }: any) {
121
+ exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
133
122
  const appId = getAppId()
134
123
  const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
135
124
  const newTrigger = newAuto ? newAuto.definition.trigger : null
136
125
  const triggerChanged =
137
126
  oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id
138
- function isWebhookTrigger(auto: any) {
127
+ function isWebhookTrigger(auto) {
139
128
  return (
140
129
  auto &&
141
130
  auto.definition.trigger &&
@@ -171,7 +160,7 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
171
160
  (!isWebhookTrigger(oldAuto) || triggerChanged) &&
172
161
  isWebhookTrigger(newAuto)
173
162
  ) {
174
- const ctx: any = {
163
+ const ctx = {
175
164
  appId,
176
165
  request: {
177
166
  body: new webhooks.Webhook(
@@ -201,6 +190,6 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
201
190
  * @param appId {string} the app that is being removed.
202
191
  * @return {Promise<void>} clean is complete if this succeeds.
203
192
  */
204
- export async function cleanupAutomations(appId: any) {
205
- await disableAllCrons(appId)
193
+ exports.cleanupAutomations = async appId => {
194
+ await exports.disableAllCrons(appId)
206
195
  }
@@ -162,6 +162,14 @@ exports.AutoFieldSubTypes = {
162
162
  AUTO_ID: "autoID",
163
163
  }
164
164
 
165
+ exports.AutoFieldDefaultNames = {
166
+ CREATED_BY: "Created By",
167
+ CREATED_AT: "Created At",
168
+ UPDATED_BY: "Updated By",
169
+ UPDATED_AT: "Updated At",
170
+ AUTO_ID: "Auto ID",
171
+ }
172
+
165
173
  exports.OBJ_STORE_DIRECTORY = "/prod-budi-app-assets"
166
174
  exports.BaseQueryVerbs = {
167
175
  CREATE: "create",
@@ -190,11 +198,5 @@ exports.WebhookType = {
190
198
  AUTOMATION: "automation",
191
199
  }
192
200
 
193
- exports.AutomationErrors = {
194
- INCORRECT_TYPE: "INCORRECT_TYPE",
195
- MAX_ITERATIONS: "MAX_ITERATIONS_REACHED",
196
- FAILURE_CONDITION: "FAILURE_CONDITION_MET",
197
- }
198
-
199
201
  // pass through the list from the auth/core lib
200
202
  exports.ObjectStoreBuckets = ObjectStoreBuckets
@@ -376,6 +376,7 @@ class LinkController {
376
376
 
377
377
  if (field.autocolumn) {
378
378
  linkedField.autocolumn = field.autocolumn
379
+ linkedField.subtype = field.subtype
379
380
  }
380
381
 
381
382
  // check the linked table to make sure we aren't overwriting an existing column
@@ -49,7 +49,6 @@ export enum SourceNames {
49
49
  ORACLE = "ORACLE",
50
50
  GOOGLE_SHEETS = "GOOGLE_SHEETS",
51
51
  FIREBASE = "FIREBASE",
52
- REDIS = "REDIS",
53
52
  }
54
53
 
55
54
  export enum IncludeRelationships {
@@ -34,7 +34,7 @@ let inThread = false
34
34
 
35
35
  module.exports = {
36
36
  // important
37
- PORT: process.env.PORT || process.env.APP_PORT,
37
+ PORT: process.env.PORT,
38
38
  JWT_SECRET: process.env.JWT_SECRET,
39
39
  COUCH_DB_URL: process.env.COUCH_DB_URL,
40
40
  MINIO_URL: process.env.MINIO_URL,
@@ -44,6 +44,8 @@ module.exports = {
44
44
  ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
45
45
  MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
46
46
  MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
47
+ USE_QUOTAS: process.env.USE_QUOTAS,
48
+ EXCLUDE_QUOTAS_TENANTS: process.env.EXCLUDE_QUOTAS_TENANTS,
47
49
  REDIS_URL: process.env.REDIS_URL,
48
50
  REDIS_PASSWORD: process.env.REDIS_PASSWORD,
49
51
  INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
@@ -63,7 +65,6 @@ module.exports = {
63
65
  LOG_LEVEL: process.env.LOG_LEVEL,
64
66
  AUTOMATION_DIRECTORY: process.env.AUTOMATION_DIRECTORY,
65
67
  AUTOMATION_BUCKET: process.env.AUTOMATION_BUCKET,
66
- AUTOMATION_MAX_ITERATIONS: process.env.AUTOMATION_MAX_ITERATIONS,
67
68
  SENDGRID_API_KEY: process.env.SENDGRID_API_KEY,
68
69
  DYNAMO_ENDPOINT: process.env.DYNAMO_ENDPOINT,
69
70
  POSTHOG_TOKEN: process.env.POSTHOG_TOKEN,
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { bootstrap } from "global-agent"
2
1
  const fixPath = require("fix-path")
3
2
  const { checkDevelopmentEnvironment } = require("./utilities/fileSystem")
4
3
 
@@ -7,8 +6,6 @@ function runServer() {
7
6
  // will print an error explaining what to do
8
7
  checkDevelopmentEnvironment()
9
8
  fixPath()
10
- // this will setup http and https proxies form env variables
11
- bootstrap()
12
9
  require("./app")
13
10
  }
14
11
 
@@ -11,7 +11,6 @@ const arangodb = require("./arangodb")
11
11
  const rest = require("./rest")
12
12
  const googlesheets = require("./googlesheets")
13
13
  const firebase = require("./firebase")
14
- const redis = require("./redis")
15
14
  const { SourceNames } = require("../definitions/datasource")
16
15
  const environment = require("../environment")
17
16
 
@@ -27,8 +26,6 @@ const DEFINITIONS = {
27
26
  [SourceNames.MYSQL]: mysql.schema,
28
27
  [SourceNames.ARANGODB]: arangodb.schema,
29
28
  [SourceNames.REST]: rest.schema,
30
- [SourceNames.FIREBASE]: firebase.schema,
31
- [SourceNames.REDIS]: redis.schema,
32
29
  }
33
30
 
34
31
  const INTEGRATIONS = {
@@ -45,7 +42,6 @@ const INTEGRATIONS = {
45
42
  [SourceNames.REST]: rest.integration,
46
43
  [SourceNames.FIREBASE]: firebase.integration,
47
44
  [SourceNames.GOOGLE_SHEETS]: googlesheets.integration,
48
- [SourceNames.REDIS]: redis.integration,
49
45
  }
50
46
 
51
47
  // optionally add oracle integration if the oracle binary can be installed
@@ -1,8 +1,8 @@
1
- import {
1
+ const {
2
2
  getUserRoleHierarchy,
3
3
  getRequiredResourceRole,
4
4
  BUILTIN_ROLE_IDS,
5
- } from "@budibase/backend-core/roles"
5
+ } = require("@budibase/backend-core/roles")
6
6
  const {
7
7
  PermissionTypes,
8
8
  PermissionLevels,
@@ -13,7 +13,7 @@ const { isWebhookEndpoint } = require("./utils")
13
13
  const { buildCsrfMiddleware } = require("@budibase/backend-core/auth")
14
14
  const { getAppId } = require("@budibase/backend-core/context")
15
15
 
16
- function hasResource(ctx: any) {
16
+ function hasResource(ctx) {
17
17
  return ctx.resourceId != null
18
18
  }
19
19
 
@@ -25,12 +25,7 @@ const csrf = buildCsrfMiddleware()
25
25
  * - Builders can access all resources.
26
26
  * - Otherwise the user must have the required role.
27
27
  */
28
- const checkAuthorized = async (
29
- ctx: any,
30
- resourceRoles: any,
31
- permType: any,
32
- permLevel: any
33
- ) => {
28
+ const checkAuthorized = async (ctx, resourceRoles, permType, permLevel) => {
34
29
  // check if this is a builder api and the user is not a builder
35
30
  const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
36
31
  const isBuilderApi = permType === PermissionTypes.BUILDER
@@ -45,10 +40,10 @@ const checkAuthorized = async (
45
40
  }
46
41
 
47
42
  const checkAuthorizedResource = async (
48
- ctx: any,
49
- resourceRoles: any,
50
- permType: any,
51
- permLevel: any
43
+ ctx,
44
+ resourceRoles,
45
+ permType,
46
+ permLevel
52
47
  ) => {
53
48
  // get the user's roles
54
49
  const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
@@ -59,9 +54,7 @@ const checkAuthorizedResource = async (
59
54
  // check if the user has the required role
60
55
  if (resourceRoles.length > 0) {
61
56
  // deny access if the user doesn't have the required resource role
62
- const found = userRoles.find(
63
- (role: any) => resourceRoles.indexOf(role._id) !== -1
64
- )
57
+ const found = userRoles.find(role => resourceRoles.indexOf(role._id) !== -1)
65
58
  if (!found) {
66
59
  ctx.throw(403, permError)
67
60
  }
@@ -71,8 +64,9 @@ const checkAuthorizedResource = async (
71
64
  }
72
65
  }
73
66
 
74
- export = (permType: any, permLevel: any = null, opts = { schema: false }) =>
75
- async (ctx: any, next: any) => {
67
+ module.exports =
68
+ (permType, permLevel = null, opts = { schema: false }) =>
69
+ async (ctx, next) => {
76
70
  // webhooks don't need authentication, each webhook unique
77
71
  // also internal requests (between services) don't need authorized
78
72
  if (isWebhookEndpoint(ctx) || ctx.internal) {
@@ -88,8 +82,8 @@ export = (permType: any, permLevel: any = null, opts = { schema: false }) =>
88
82
  await builderMiddleware(ctx, permType)
89
83
 
90
84
  // get the resource roles
91
- let resourceRoles: any = []
92
- let otherLevelRoles: any = []
85
+ let resourceRoles = [],
86
+ otherLevelRoles
93
87
  const otherLevel =
94
88
  permLevel === PermissionLevels.READ
95
89
  ? PermissionLevels.WRITE
@@ -4,7 +4,7 @@ const {
4
4
  getCookie,
5
5
  clearCookie,
6
6
  } = require("@budibase/backend-core/utils")
7
- const { Cookies, Headers } = require("@budibase/backend-core/constants")
7
+ const { Cookies } = require("@budibase/backend-core/constants")
8
8
  const { getRole } = require("@budibase/backend-core/roles")
9
9
  const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
10
10
  const { generateUserMetadataID, isDevAppID } = require("../db/utils")
@@ -63,21 +63,6 @@ module.exports = async (ctx, next) => {
63
63
  appId = requestAppId
64
64
  // retrieving global user gets the right role
65
65
  roleId = globalUser.roleId || roleId
66
-
67
- // Allow builders to specify their role via a header
68
- const isBuilder =
69
- globalUser && globalUser.builder && globalUser.builder.global
70
- const isDevApp = appId && isDevAppID(appId)
71
- const roleHeader = ctx.request && ctx.request.headers[Headers.PREVIEW_ROLE]
72
- if (isBuilder && isDevApp && roleHeader) {
73
- // Ensure the role is valid by ensuring a definition exists
74
- try {
75
- await getRole(roleHeader)
76
- roleId = roleHeader
77
- } catch (error) {
78
- // Swallow error and do nothing
79
- }
80
- }
81
66
  }
82
67
 
83
68
  // nothing more to do
@@ -0,0 +1,120 @@
1
+ jest.mock("../../db")
2
+ jest.mock("../../utilities/usageQuota")
3
+ jest.mock("@budibase/backend-core/tenancy", () => ({
4
+ getTenantId: () => "testing123"
5
+ }))
6
+
7
+ const usageQuotaMiddleware = require("../usageQuota")
8
+ const usageQuota = require("../../utilities/usageQuota")
9
+
10
+ jest.mock("@budibase/backend-core/db")
11
+ const { dangerousGetDB } = require("@budibase/backend-core/db")
12
+
13
+ const env = require("../../environment")
14
+
15
+ class TestConfiguration {
16
+ constructor() {
17
+ this.throw = jest.fn()
18
+ this.next = jest.fn()
19
+ this.middleware = usageQuotaMiddleware
20
+ this.ctx = {
21
+ throw: this.throw,
22
+ next: this.next,
23
+ appId: "test",
24
+ request: {
25
+ body: {}
26
+ },
27
+ req: {
28
+ method: "POST",
29
+ url: "/applications"
30
+ }
31
+ }
32
+ usageQuota.useQuotas = () => true
33
+ }
34
+
35
+ executeMiddleware() {
36
+ return this.middleware(this.ctx, this.next)
37
+ }
38
+
39
+ setProd(bool) {
40
+ if (bool) {
41
+ env.isDev = () => false
42
+ env.isProd = () => true
43
+ this.ctx.user = { tenantId: "test" }
44
+ } else {
45
+ env.isDev = () => true
46
+ env.isProd = () => false
47
+ }
48
+ }
49
+
50
+ setMethod(method) {
51
+ this.ctx.req.method = method
52
+ }
53
+
54
+ setUrl(url) {
55
+ this.ctx.req.url = url
56
+ }
57
+
58
+ setBody(body) {
59
+ this.ctx.request.body = body
60
+ }
61
+
62
+ setFiles(files) {
63
+ this.ctx.request.files = { file: files }
64
+ }
65
+ }
66
+
67
+ describe("usageQuota middleware", () => {
68
+ let config
69
+
70
+ beforeEach(() => {
71
+ config = new TestConfiguration()
72
+ })
73
+
74
+ it("skips the middleware if there is no usage property or method", async () => {
75
+ await config.executeMiddleware()
76
+ expect(config.next).toHaveBeenCalled()
77
+ })
78
+
79
+ it("passes through to next middleware if document already exists", async () => {
80
+ config.setProd(true)
81
+ config.setBody({
82
+ _id: "test",
83
+ _rev: "test",
84
+ })
85
+
86
+ dangerousGetDB.mockImplementationOnce(() => ({
87
+ get: async () => true
88
+ }))
89
+
90
+ await config.executeMiddleware()
91
+
92
+ expect(config.next).toHaveBeenCalled()
93
+ })
94
+
95
+ it("throws if request has _id, but the document no longer exists", async () => {
96
+ config.setBody({
97
+ _id: "123",
98
+ _rev: "test",
99
+ })
100
+ config.setProd(true)
101
+
102
+ dangerousGetDB.mockImplementationOnce(() => ({
103
+ get: async () => {
104
+ throw new Error()
105
+ }
106
+ }))
107
+
108
+ await config.executeMiddleware()
109
+ expect(config.throw).toHaveBeenCalledWith(404, `${config.ctx.request.body._id} does not exist`)
110
+ })
111
+
112
+ it("calculates and persists the correct usage quota for the relevant action", async () => {
113
+ config.setUrl("/rows")
114
+
115
+ await config.executeMiddleware()
116
+
117
+ expect(usageQuota.update).toHaveBeenCalledWith("rows", 1)
118
+ expect(config.next).toHaveBeenCalled()
119
+ })
120
+ })
@@ -0,0 +1,164 @@
1
+ const usageQuota = require("../utilities/usageQuota")
2
+ const { getUniqueRows } = require("../utilities/usageQuota/rows")
3
+ const {
4
+ isExternalTable,
5
+ isRowId: isExternalRowId,
6
+ } = require("../integrations/utils")
7
+ const { getAppDB } = require("@budibase/backend-core/context")
8
+
9
+ // currently only counting new writes and deletes
10
+ const METHOD_MAP = {
11
+ POST: 1,
12
+ DELETE: -1,
13
+ }
14
+
15
+ const DOMAIN_MAP = {
16
+ rows: usageQuota.Properties.ROW,
17
+ // upload: usageQuota.Properties.UPLOAD, // doesn't work yet
18
+ // views: usageQuota.Properties.VIEW, // doesn't work yet
19
+ // users: usageQuota.Properties.USER, // doesn't work yet
20
+ applications: usageQuota.Properties.APPS,
21
+ // this will not be updated by endpoint calls
22
+ // instead it will be updated by triggerInfo
23
+ // automationRuns: usageQuota.Properties.AUTOMATION, // doesn't work yet
24
+ }
25
+
26
+ function getProperty(url) {
27
+ for (let domain of Object.keys(DOMAIN_MAP)) {
28
+ if (url.indexOf(domain) !== -1) {
29
+ return DOMAIN_MAP[domain]
30
+ }
31
+ }
32
+ }
33
+
34
+ module.exports = async (ctx, next) => {
35
+ if (!usageQuota.useQuotas()) {
36
+ return next()
37
+ }
38
+
39
+ let usage = METHOD_MAP[ctx.req.method]
40
+ const property = getProperty(ctx.req.url)
41
+ if (usage == null || property == null) {
42
+ return next()
43
+ }
44
+ // post request could be a save of a pre-existing entry
45
+ if (ctx.request.body && ctx.request.body._id && ctx.request.body._rev) {
46
+ const usageId = ctx.request.body._id
47
+ try {
48
+ if (ctx.appId) {
49
+ const db = getAppDB()
50
+ await db.get(usageId)
51
+ }
52
+ return next()
53
+ } catch (err) {
54
+ if (
55
+ isExternalTable(usageId) ||
56
+ (ctx.request.body.tableId &&
57
+ isExternalTable(ctx.request.body.tableId)) ||
58
+ isExternalRowId(usageId)
59
+ ) {
60
+ return next()
61
+ } else {
62
+ ctx.throw(404, `${usageId} does not exist`)
63
+ }
64
+ }
65
+ }
66
+
67
+ // update usage for uploads to be the total size
68
+ if (property === usageQuota.Properties.UPLOAD) {
69
+ const files =
70
+ ctx.request.files.file.length > 1
71
+ ? Array.from(ctx.request.files.file)
72
+ : [ctx.request.files.file]
73
+ usage = files.map(file => file.size).reduce((total, size) => total + size)
74
+ }
75
+ try {
76
+ await performRequest(ctx, next, property, usage)
77
+ } catch (err) {
78
+ ctx.throw(400, err)
79
+ }
80
+ }
81
+
82
+ const performRequest = async (ctx, next, property, usage) => {
83
+ const usageContext = {
84
+ skipNext: false,
85
+ skipUsage: false,
86
+ [usageQuota.Properties.APPS]: {},
87
+ }
88
+
89
+ if (usage === -1) {
90
+ if (PRE_DELETE[property]) {
91
+ await PRE_DELETE[property](ctx, usageContext)
92
+ }
93
+ } else {
94
+ if (PRE_CREATE[property]) {
95
+ await PRE_CREATE[property](ctx, usageContext)
96
+ }
97
+ }
98
+
99
+ // run the request
100
+ if (!usageContext.skipNext) {
101
+ await usageQuota.update(property, usage, { dryRun: true })
102
+ await next()
103
+ }
104
+
105
+ if (usage === -1) {
106
+ if (POST_DELETE[property]) {
107
+ await POST_DELETE[property](ctx, usageContext)
108
+ }
109
+ } else {
110
+ if (POST_CREATE[property]) {
111
+ await POST_CREATE[property](ctx, usageContext)
112
+ }
113
+ }
114
+
115
+ // update the usage
116
+ if (!usageContext.skipUsage) {
117
+ await usageQuota.update(property, usage)
118
+ }
119
+ }
120
+
121
+ const appPreDelete = async (ctx, usageContext) => {
122
+ if (ctx.query.unpublish) {
123
+ // don't run usage decrement for unpublish
124
+ usageContext.skipUsage = true
125
+ return
126
+ }
127
+
128
+ // store the row count to delete
129
+ const rows = await getUniqueRows([ctx.appId])
130
+ if (rows.length) {
131
+ usageContext[usageQuota.Properties.APPS] = { rowCount: rows.length }
132
+ }
133
+ }
134
+
135
+ const appPostDelete = async (ctx, usageContext) => {
136
+ // delete the app rows from usage
137
+ const rowCount = usageContext[usageQuota.Properties.APPS].rowCount
138
+ if (rowCount) {
139
+ await usageQuota.update(usageQuota.Properties.ROW, -rowCount)
140
+ }
141
+ }
142
+
143
+ const appPostCreate = async ctx => {
144
+ // app import & template creation
145
+ if (ctx.request.body.useTemplate === "true") {
146
+ const rows = await getUniqueRows([ctx.response.body.appId])
147
+ const rowCount = rows ? rows.length : 0
148
+ await usageQuota.update(usageQuota.Properties.ROW, rowCount)
149
+ }
150
+ }
151
+
152
+ const PRE_DELETE = {
153
+ [usageQuota.Properties.APPS]: appPreDelete,
154
+ }
155
+
156
+ const POST_DELETE = {
157
+ [usageQuota.Properties.APPS]: appPostDelete,
158
+ }
159
+
160
+ const PRE_CREATE = {}
161
+
162
+ const POST_CREATE = {
163
+ [usageQuota.Properties.APPS]: appPostCreate,
164
+ }
@@ -1,3 +1,4 @@
1
+ const env = require("../../../environment")
1
2
  const TestConfig = require("../../../tests/utilities/TestConfiguration")
2
3
 
3
4
  const syncApps = jest.fn()
@@ -13,6 +14,7 @@ describe("run", () => {
13
14
 
14
15
  beforeEach(async () => {
15
16
  await config.init()
17
+ env._set("USE_QUOTAS", 1)
16
18
  })
17
19
 
18
20
  afterAll(config.end)
@@ -1,3 +1,8 @@
1
+ const { useQuotas } = require("../../../utilities/usageQuota")
2
+
1
3
  export const runQuotaMigration = async (migration: Function) => {
4
+ if (!useQuotas()) {
5
+ return
6
+ }
2
7
  await migration()
3
8
  }