@budibase/server 1.0.123 → 1.0.125

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 (325) hide show
  1. package/builder/assets/index.3d890df7.js +1299 -0
  2. package/builder/assets/index.89795487.css +6 -0
  3. package/builder/assets/{vendor.8e34a169.js → vendor.5240f480.js} +1 -1
  4. package/builder/index.html +3 -3
  5. package/coverage/clover.xml +695 -1678
  6. package/coverage/coverage-final.json +28 -43
  7. package/coverage/lcov-report/api/controllers/analytics.js.html +8 -3
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +9 -4
  9. package/coverage/lcov-report/api/controllers/auth.js.html +8 -3
  10. package/coverage/lcov-report/api/controllers/automation.js.html +8 -3
  11. package/coverage/lcov-report/api/controllers/backup.js.html +8 -3
  12. package/coverage/lcov-report/api/controllers/cloud.js.html +8 -3
  13. package/coverage/lcov-report/api/controllers/component.js.html +8 -3
  14. package/coverage/lcov-report/api/controllers/datasource.js.html +11 -6
  15. package/coverage/lcov-report/api/controllers/dev.js.html +8 -3
  16. package/coverage/lcov-report/api/controllers/index.html +16 -26
  17. package/coverage/lcov-report/api/controllers/integration.js.html +8 -3
  18. package/coverage/lcov-report/api/controllers/layout.js.html +8 -3
  19. package/coverage/lcov-report/api/controllers/metadata.js.html +8 -3
  20. package/coverage/lcov-report/api/controllers/migrations.js.html +8 -3
  21. package/coverage/lcov-report/api/controllers/permission.js.html +8 -3
  22. package/coverage/lcov-report/api/controllers/query/index.html +16 -26
  23. package/coverage/lcov-report/api/controllers/query/validation.js.html +8 -3
  24. package/coverage/lcov-report/api/controllers/role.js.html +10 -5
  25. package/coverage/lcov-report/api/controllers/routing.js.html +9 -4
  26. package/coverage/lcov-report/api/controllers/row/external.js.html +8 -3
  27. package/coverage/lcov-report/api/controllers/row/index.html +25 -35
  28. package/coverage/lcov-report/api/controllers/row/internal.js.html +32 -24
  29. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +21 -16
  30. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +24 -19
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +33 -19
  32. package/coverage/lcov-report/api/controllers/screen.js.html +9 -4
  33. package/coverage/lcov-report/api/controllers/script.js.html +8 -3
  34. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +55 -50
  35. package/coverage/lcov-report/api/controllers/table/external.js.html +8 -3
  36. package/coverage/lcov-report/api/controllers/table/index.html +19 -44
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +20 -15
  38. package/coverage/lcov-report/api/controllers/templates.js.html +8 -3
  39. package/coverage/lcov-report/api/controllers/user.js.html +8 -3
  40. package/coverage/lcov-report/api/controllers/view/exporters.js.html +8 -3
  41. package/coverage/lcov-report/api/controllers/view/index.html +8 -3
  42. package/coverage/lcov-report/api/controllers/view/index.js.html +10 -5
  43. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -3
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +8 -3
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +10 -5
  46. package/coverage/lcov-report/api/index.html +18 -13
  47. package/coverage/lcov-report/api/index.js.html +28 -8
  48. package/coverage/lcov-report/api/routes/analytics.js.html +8 -3
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -3
  50. package/coverage/lcov-report/api/routes/auth.js.html +8 -3
  51. package/coverage/lcov-report/api/routes/automation.js.html +8 -3
  52. package/coverage/lcov-report/api/routes/backup.js.html +8 -3
  53. package/coverage/lcov-report/api/routes/cloud.js.html +8 -3
  54. package/coverage/lcov-report/api/routes/component.js.html +8 -3
  55. package/coverage/lcov-report/api/routes/datasource.js.html +8 -3
  56. package/coverage/lcov-report/api/routes/deploy.js.html +8 -3
  57. package/coverage/lcov-report/api/routes/dev.js.html +9 -4
  58. package/coverage/lcov-report/api/routes/index.html +13 -68
  59. package/coverage/lcov-report/api/routes/integration.js.html +8 -3
  60. package/coverage/lcov-report/api/routes/layout.js.html +8 -3
  61. package/coverage/lcov-report/api/routes/metadata.js.html +8 -3
  62. package/coverage/lcov-report/api/routes/migrations.js.html +8 -3
  63. package/coverage/lcov-report/api/routes/permission.js.html +8 -3
  64. package/coverage/lcov-report/api/routes/query.js.html +8 -3
  65. package/coverage/lcov-report/api/routes/role.js.html +8 -3
  66. package/coverage/lcov-report/api/routes/routing.js.html +8 -3
  67. package/coverage/lcov-report/api/routes/screen.js.html +8 -3
  68. package/coverage/lcov-report/api/routes/script.js.html +8 -3
  69. package/coverage/lcov-report/api/routes/table.js.html +8 -3
  70. package/coverage/lcov-report/api/routes/templates.js.html +8 -3
  71. package/coverage/lcov-report/api/routes/user.js.html +8 -3
  72. package/coverage/lcov-report/api/routes/utils/index.html +8 -3
  73. package/coverage/lcov-report/api/routes/utils/validators.js.html +8 -3
  74. package/coverage/lcov-report/api/routes/view.js.html +8 -3
  75. package/coverage/lcov-report/api/routes/webhook.js.html +8 -3
  76. package/coverage/lcov-report/automations/actions.js.html +21 -7
  77. package/coverage/lcov-report/automations/automationUtils.js.html +64 -23
  78. package/coverage/lcov-report/automations/bullboard.js.html +8 -3
  79. package/coverage/lcov-report/automations/index.html +27 -37
  80. package/coverage/lcov-report/automations/index.js.html +8 -3
  81. package/coverage/lcov-report/automations/steps/bash.js.html +8 -3
  82. package/coverage/lcov-report/automations/steps/delay.js.html +8 -3
  83. package/coverage/lcov-report/automations/steps/discord.js.html +8 -3
  84. package/coverage/lcov-report/automations/steps/executeQuery.js.html +8 -3
  85. package/coverage/lcov-report/automations/steps/executeScript.js.html +8 -3
  86. package/coverage/lcov-report/automations/steps/filter.js.html +8 -3
  87. package/coverage/lcov-report/automations/steps/index.html +31 -41
  88. package/coverage/lcov-report/automations/steps/integromat.js.html +8 -3
  89. package/coverage/lcov-report/{api/routes/static.js.html → automations/steps/loop.js.html} +70 -80
  90. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +9 -4
  91. package/coverage/lcov-report/automations/steps/queryRows.js.html +9 -4
  92. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +8 -3
  93. package/coverage/lcov-report/automations/steps/serverLog.js.html +8 -3
  94. package/coverage/lcov-report/automations/steps/slack.js.html +8 -3
  95. package/coverage/lcov-report/automations/steps/updateRow.js.html +8 -3
  96. package/coverage/lcov-report/automations/steps/utils.js.html +14 -9
  97. package/coverage/lcov-report/automations/steps/zapier.js.html +8 -3
  98. package/coverage/lcov-report/automations/triggerInfo/app.js.html +8 -3
  99. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +8 -3
  100. package/coverage/lcov-report/automations/triggerInfo/index.html +8 -3
  101. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -3
  102. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +8 -3
  103. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +8 -3
  104. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +8 -3
  105. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +8 -3
  106. package/coverage/lcov-report/automations/triggers.js.html +16 -11
  107. package/coverage/lcov-report/block-navigation.js +8 -0
  108. package/coverage/lcov-report/constants/index.html +12 -7
  109. package/coverage/lcov-report/constants/index.js.html +55 -32
  110. package/coverage/lcov-report/constants/layouts.js.html +8 -3
  111. package/coverage/lcov-report/constants/screens.js.html +8 -3
  112. package/coverage/lcov-report/db/inMemoryView.js.html +8 -3
  113. package/coverage/lcov-report/db/index.html +8 -3
  114. package/coverage/lcov-report/db/index.js.html +9 -4
  115. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +20 -15
  116. package/coverage/lcov-report/db/linkedRows/index.html +8 -3
  117. package/coverage/lcov-report/db/linkedRows/index.js.html +22 -17
  118. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +12 -7
  119. package/coverage/lcov-report/db/newid.js.html +11 -6
  120. package/coverage/lcov-report/db/utils.js.html +84 -79
  121. package/coverage/lcov-report/events/AutomationEmitter.js.html +14 -9
  122. package/coverage/lcov-report/events/index.html +8 -3
  123. package/coverage/lcov-report/events/index.js.html +9 -4
  124. package/coverage/lcov-report/events/utils.js.html +18 -13
  125. package/coverage/lcov-report/index.html +125 -120
  126. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +8 -3
  127. package/coverage/lcov-report/integrations/tests/index.html +8 -3
  128. package/coverage/lcov-report/middleware/appInfo.js.html +8 -3
  129. package/coverage/lcov-report/middleware/builder.js.html +8 -3
  130. package/coverage/lcov-report/middleware/currentapp.js.html +65 -15
  131. package/coverage/lcov-report/middleware/index.html +25 -50
  132. package/coverage/lcov-report/middleware/joi-validator.js.html +9 -4
  133. package/coverage/lcov-report/middleware/publicApi.js.html +8 -3
  134. package/coverage/lcov-report/middleware/resourceId.js.html +8 -3
  135. package/coverage/lcov-report/middleware/selfhost.js.html +9 -4
  136. package/coverage/lcov-report/middleware/utils.js.html +8 -3
  137. package/coverage/lcov-report/sorter.js +26 -0
  138. package/coverage/lcov-report/threads/automation.js.html +581 -90
  139. package/coverage/lcov-report/threads/index.html +30 -40
  140. package/coverage/lcov-report/threads/query.js.html +9 -4
  141. package/coverage/lcov-report/threads/utils.js.html +17 -9
  142. package/coverage/lcov-report/utilities/bcrypt.js.html +8 -3
  143. package/coverage/lcov-report/utilities/budibaseDir.js.html +8 -3
  144. package/coverage/lcov-report/utilities/centralPath.js.html +8 -3
  145. package/coverage/lcov-report/utilities/csvParser.js.html +10 -5
  146. package/coverage/lcov-report/utilities/global.js.html +9 -4
  147. package/coverage/lcov-report/utilities/index.html +8 -3
  148. package/coverage/lcov-report/utilities/index.js.html +11 -6
  149. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +32 -9
  150. package/coverage/lcov-report/utilities/queue/index.html +12 -7
  151. package/coverage/lcov-report/utilities/routing/index.html +8 -3
  152. package/coverage/lcov-report/utilities/routing/index.js.html +8 -3
  153. package/coverage/lcov-report/utilities/rowProcessor/index.html +8 -3
  154. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +48 -43
  155. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +18 -13
  156. package/coverage/lcov-report/utilities/scriptRunner.js.html +8 -3
  157. package/coverage/lcov-report/utilities/security.js.html +9 -4
  158. package/coverage/lcov-report/utilities/statusCodes.js.html +8 -3
  159. package/coverage/lcov-report/utilities/usageQuota/index.html +24 -34
  160. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +44 -39
  161. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +8 -3
  162. package/coverage/lcov-report/utilities/users.js.html +8 -3
  163. package/coverage/lcov-report/utilities/workerRequests.js.html +9 -4
  164. package/coverage/lcov.info +1144 -2875
  165. package/dist/api/controllers/application.js +145 -73
  166. package/dist/api/controllers/deploy/index.js +68 -36
  167. package/dist/api/controllers/public/applications.js +29 -9
  168. package/dist/api/controllers/public/queries.js +27 -7
  169. package/dist/api/controllers/public/rows.js +32 -12
  170. package/dist/api/controllers/public/tables.js +2 -2
  171. package/dist/api/controllers/public/users.js +8 -8
  172. package/dist/api/controllers/public/utils.js +1 -1
  173. package/dist/api/controllers/query/import/index.js +3 -3
  174. package/dist/api/controllers/query/index.js +57 -44
  175. package/dist/api/controllers/row/ExternalRequest.js +27 -27
  176. package/dist/api/controllers/row/index.js +83 -60
  177. package/dist/api/controllers/row/internal.js +2 -1
  178. package/dist/api/controllers/row/utils.js +2 -1
  179. package/dist/api/controllers/static/templates/BudibaseApp.svelte +3 -0
  180. package/dist/api/controllers/table/bulkFormula.js +2 -1
  181. package/dist/api/controllers/table/internal.js +41 -35
  182. package/dist/api/controllers/table/utils.js +271 -229
  183. package/dist/api/index.js +5 -0
  184. package/dist/api/routes/application.js +39 -13
  185. package/dist/api/routes/index.js +61 -56
  186. package/dist/api/routes/public/index.js +6 -9
  187. package/dist/api/routes/public/queries.js +1 -1
  188. package/dist/api/routes/public/rows.js +1 -1
  189. package/dist/api/routes/public/tables.js +3 -3
  190. package/dist/api/routes/public/users.js +1 -1
  191. package/dist/api/routes/row.js +43 -17
  192. package/dist/api/routes/static.js +40 -13
  193. package/dist/api/routes/tests/utilities/TestFunctions.js +75 -33
  194. package/dist/app.js +8 -4
  195. package/dist/automations/actions.js +3 -0
  196. package/dist/automations/automationUtils.js +10 -0
  197. package/dist/automations/steps/createRow.js +12 -12
  198. package/dist/automations/steps/deleteRow.js +13 -16
  199. package/dist/automations/steps/loop.js +51 -0
  200. package/dist/automations/tests/utilities/index.js +13 -11
  201. package/dist/automations/utils.js +187 -133
  202. package/dist/constants/index.js +5 -0
  203. package/dist/definitions/datasource.js +1 -0
  204. package/dist/environment.js +2 -3
  205. package/dist/index.js +4 -0
  206. package/dist/integrations/base/sql.js +2 -2
  207. package/dist/integrations/base/sqlTable.js +2 -2
  208. package/dist/integrations/googlesheets.js +1 -1
  209. package/dist/integrations/index.js +4 -0
  210. package/dist/integrations/microsoftSqlServer.js +8 -8
  211. package/dist/integrations/mysql.js +9 -9
  212. package/dist/integrations/oracle.js +7 -7
  213. package/dist/integrations/postgres.js +7 -7
  214. package/dist/integrations/queries/sql.js +2 -2
  215. package/dist/integrations/redis.js +158 -0
  216. package/dist/integrations/rest.js +1 -1
  217. package/dist/middleware/authorized.js +51 -51
  218. package/dist/middleware/currentapp.js +15 -1
  219. package/dist/migrations/functions/appUrls.js +1 -1
  220. package/dist/migrations/functions/developerQuota.js +49 -0
  221. package/dist/migrations/functions/publishedAppsQuota.js +47 -0
  222. package/dist/migrations/functions/quotas1.js +6 -2
  223. package/dist/migrations/functions/usageQuotas/index.js +0 -4
  224. package/dist/migrations/functions/usageQuotas/syncApps.js +4 -7
  225. package/dist/migrations/functions/usageQuotas/syncDevelopers.js +24 -0
  226. package/dist/migrations/functions/usageQuotas/syncPublishedApps.js +26 -0
  227. package/dist/migrations/functions/usageQuotas/syncRows.js +5 -8
  228. package/dist/migrations/index.js +17 -1
  229. package/dist/package.json +14 -8
  230. package/dist/threads/automation.js +149 -27
  231. package/dist/threads/index.js +36 -10
  232. package/dist/threads/utils.js +1 -0
  233. package/dist/tsconfig.build.tsbuildinfo +1 -0
  234. package/dist/utilities/queue/inMemoryQueue.js +6 -1
  235. package/nodemon.json +1 -1
  236. package/package.json +15 -9
  237. package/scripts/dev/manage.js +2 -0
  238. package/src/api/controllers/{application.js → application.ts} +118 -51
  239. package/src/api/controllers/deploy/{index.js → index.ts} +53 -29
  240. package/src/api/controllers/public/applications.ts +2 -2
  241. package/src/api/controllers/public/queries.ts +1 -1
  242. package/src/api/controllers/public/rows.ts +1 -1
  243. package/src/api/controllers/query/{index.js → index.ts} +51 -48
  244. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  245. package/src/api/controllers/row/{index.js → index.ts} +24 -17
  246. package/src/api/controllers/row/internal.js +2 -1
  247. package/src/api/controllers/row/utils.js +4 -1
  248. package/src/api/controllers/static/templates/BudibaseApp.svelte +3 -0
  249. package/src/api/controllers/table/bulkFormula.js +1 -1
  250. package/src/api/controllers/table/{internal.js → internal.ts} +30 -26
  251. package/src/api/controllers/table/{utils.js → utils.ts} +86 -69
  252. package/src/api/index.js +5 -0
  253. package/src/api/routes/{application.js → application.ts} +8 -14
  254. package/src/api/routes/index.ts +60 -0
  255. package/src/api/routes/public/index.ts +1 -4
  256. package/src/api/routes/{row.js → row.ts} +7 -15
  257. package/src/api/routes/{static.js → static.ts} +11 -11
  258. package/src/api/routes/tests/misc.spec.js +39 -37
  259. package/src/api/routes/tests/utilities/{TestFunctions.js → TestFunctions.ts} +57 -33
  260. package/src/app.ts +1 -2
  261. package/src/automations/actions.js +3 -0
  262. package/src/automations/automationUtils.js +12 -0
  263. package/src/automations/steps/{createRow.js → createRow.ts} +9 -15
  264. package/src/automations/steps/{deleteRow.js → deleteRow.ts} +10 -16
  265. package/src/automations/steps/loop.js +50 -0
  266. package/src/automations/tests/automation.spec.js +0 -1
  267. package/src/automations/tests/{createRow.spec.js → createRow.spec.ts} +4 -15
  268. package/src/automations/tests/{deleteRow.spec.js → deleteRow.spec.ts} +3 -5
  269. package/src/automations/tests/utilities/index.js +12 -10
  270. package/src/automations/{utils.js → utils.ts} +39 -28
  271. package/src/constants/index.js +6 -0
  272. package/src/definitions/common.ts +1 -0
  273. package/src/definitions/datasource.ts +1 -0
  274. package/src/environment.js +2 -3
  275. package/src/index.ts +3 -0
  276. package/src/integrations/index.ts +4 -0
  277. package/src/integrations/redis.ts +152 -0
  278. package/src/integrations/tests/redis.spec.js +60 -0
  279. package/src/middleware/{authorized.js → authorized.ts} +20 -14
  280. package/src/middleware/currentapp.js +16 -1
  281. package/src/middleware/tests/currentapp.spec.js +8 -4
  282. package/src/migrations/functions/developerQuota.ts +15 -0
  283. package/src/migrations/functions/publishedAppsQuota.ts +13 -0
  284. package/src/migrations/functions/tests/quotas1.spec.js +0 -2
  285. package/src/migrations/functions/usageQuotas/index.ts +0 -5
  286. package/src/migrations/functions/usageQuotas/syncApps.ts +3 -6
  287. package/src/migrations/functions/usageQuotas/syncDevelopers.ts +19 -0
  288. package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +21 -0
  289. package/src/migrations/functions/usageQuotas/syncRows.ts +3 -6
  290. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts +34 -0
  291. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +40 -0
  292. package/src/migrations/index.ts +13 -1
  293. package/src/threads/automation.js +196 -34
  294. package/src/threads/{index.js → index.ts} +18 -14
  295. package/src/threads/utils.js +1 -0
  296. package/src/utilities/queue/inMemoryQueue.js +7 -1
  297. package/tsconfig.build.json +10 -0
  298. package/tsconfig.json +2 -2
  299. package/builder/assets/index.68a7f4e3.css +0 -6
  300. package/builder/assets/index.8d4a5b33.js +0 -1291
  301. package/coverage/lcov-report/api/controllers/application.js.html +0 -1436
  302. package/coverage/lcov-report/api/controllers/query/index.js.html +0 -713
  303. package/coverage/lcov-report/api/controllers/row/index.js.html +0 -524
  304. package/coverage/lcov-report/api/controllers/table/internal.js.html +0 -620
  305. package/coverage/lcov-report/api/controllers/table/utils.js.html +0 -1331
  306. package/coverage/lcov-report/api/routes/application.js.html +0 -179
  307. package/coverage/lcov-report/api/routes/index.js.html +0 -266
  308. package/coverage/lcov-report/api/routes/row.js.html +0 -908
  309. package/coverage/lcov-report/automations/steps/createRow.js.html +0 -380
  310. package/coverage/lcov-report/automations/steps/deleteRow.js.html +0 -347
  311. package/coverage/lcov-report/automations/utils.js.html +0 -665
  312. package/coverage/lcov-report/middleware/authorized.js.html +0 -458
  313. package/coverage/lcov-report/middleware/usageQuota.js.html +0 -572
  314. package/coverage/lcov-report/threads/index.js.html +0 -296
  315. package/coverage/lcov-report/utilities/usageQuota/index.js.html +0 -359
  316. package/dist/middleware/usageQuota.js +0 -154
  317. package/dist/tsconfig.tsbuildinfo +0 -1
  318. package/dist/utilities/usageQuota/index.js +0 -86
  319. package/src/api/routes/index.js +0 -62
  320. package/src/middleware/tests/usageQuota.spec.js +0 -120
  321. package/src/middleware/usageQuota.js +0 -164
  322. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +0 -41
  323. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +0 -45
  324. package/src/utilities/tests/usageQuota/usageQuota.spec.js +0 -72
  325. package/src/utilities/usageQuota/index.js +0 -93
@@ -1,86 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- const env = require("../../environment");
12
- const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy");
13
- const { StaticDatabases, generateNewUsageQuotaDoc, } = require("@budibase/backend-core/db");
14
- exports.useQuotas = () => {
15
- // check if quotas are enabled
16
- if (env.USE_QUOTAS) {
17
- // check if there are any tenants without limits
18
- if (env.EXCLUDE_QUOTAS_TENANTS) {
19
- const excludedTenants = env.EXCLUDE_QUOTAS_TENANTS.replace(/\s/g, "").split(",");
20
- const tenantId = getTenantId();
21
- if (excludedTenants.includes(tenantId)) {
22
- return false;
23
- }
24
- }
25
- return true;
26
- }
27
- return false;
28
- };
29
- exports.Properties = {
30
- ROW: "rows",
31
- UPLOAD: "storage",
32
- VIEW: "views",
33
- USER: "users",
34
- AUTOMATION: "automationRuns",
35
- APPS: "apps",
36
- EMAILS: "emails", // doesn't work yet
37
- };
38
- exports.getUsageQuotaDoc = (db) => __awaiter(void 0, void 0, void 0, function* () {
39
- let quota;
40
- try {
41
- quota = yield db.get(StaticDatabases.GLOBAL.docs.usageQuota);
42
- }
43
- catch (err) {
44
- // doc doesn't exist. Create it
45
- quota = generateNewUsageQuotaDoc();
46
- const response = yield db.put(quota);
47
- quota._rev = response.rev;
48
- }
49
- return quota;
50
- });
51
- /**
52
- * Given a specified tenantId this will add to the usage object for the specified property.
53
- * @param {string} property The property which is to be added to (within the nested usageQuota object).
54
- * @param {number} usage The amount (this can be negative) to adjust the number by.
55
- * @param {object} opts optional - options such as dryRun, to check what update will do.
56
- * @returns {Promise<void>} When this completes the API key will now be up to date - the quota period may have
57
- * also been reset after this call.
58
- */
59
- exports.update = (property, usage, opts = { dryRun: false }) => __awaiter(void 0, void 0, void 0, function* () {
60
- if (!exports.useQuotas()) {
61
- return;
62
- }
63
- try {
64
- const db = getGlobalDB();
65
- const quota = yield exports.getUsageQuotaDoc(db);
66
- // increment the quota
67
- quota.usageQuota[property] += usage;
68
- if (quota.usageQuota[property] > quota.usageLimits[property] &&
69
- usage > 0 // allow for decrementing usage when the quota is already exceeded
70
- ) {
71
- throw new Error(`You have exceeded your usage quota of ${quota.usageLimits[property]} ${property}.`);
72
- }
73
- if (quota.usageQuota[property] < 0) {
74
- // never go negative if the quota has previously been exceeded
75
- quota.usageQuota[property] = 0;
76
- }
77
- // update the usage quotas
78
- if (!opts.dryRun) {
79
- yield db.put(quota);
80
- }
81
- }
82
- catch (err) {
83
- console.error(`Error updating usage quotas for ${property}`, err);
84
- throw err;
85
- }
86
- });
@@ -1,62 +0,0 @@
1
- const authRoutes = require("./auth")
2
- const layoutRoutes = require("./layout")
3
- const screenRoutes = require("./screen")
4
- const userRoutes = require("./user")
5
- const applicationRoutes = require("./application")
6
- const tableRoutes = require("./table")
7
- const rowRoutes = require("./row")
8
- const viewRoutes = require("./view")
9
- const staticRoutes = require("./static")
10
- const componentRoutes = require("./component")
11
- const automationRoutes = require("./automation")
12
- const webhookRoutes = require("./webhook")
13
- const roleRoutes = require("./role")
14
- const deployRoutes = require("./deploy")
15
- const apiKeysRoutes = require("./apikeys")
16
- const templatesRoutes = require("./templates")
17
- const analyticsRoutes = require("./analytics")
18
- const routingRoutes = require("./routing")
19
- const integrationRoutes = require("./integration")
20
- const permissionRoutes = require("./permission")
21
- const datasourceRoutes = require("./datasource")
22
- const queryRoutes = require("./query")
23
- const backupRoutes = require("./backup")
24
- const metadataRoutes = require("./metadata")
25
- const devRoutes = require("./dev")
26
- const cloudRoutes = require("./cloud")
27
- const migrationRoutes = require("./migrations")
28
- const publicRoutes = require("./public")
29
-
30
- exports.mainRoutes = [
31
- authRoutes,
32
- deployRoutes,
33
- layoutRoutes,
34
- screenRoutes,
35
- userRoutes,
36
- applicationRoutes,
37
- automationRoutes,
38
- viewRoutes,
39
- componentRoutes,
40
- roleRoutes,
41
- apiKeysRoutes,
42
- templatesRoutes,
43
- analyticsRoutes,
44
- webhookRoutes,
45
- routingRoutes,
46
- integrationRoutes,
47
- permissionRoutes,
48
- datasourceRoutes,
49
- queryRoutes,
50
- backupRoutes,
51
- metadataRoutes,
52
- devRoutes,
53
- cloudRoutes,
54
- // these need to be handled last as they still use /api/:tableId
55
- // this could be breaking as koa may recognise other routes as this
56
- tableRoutes,
57
- rowRoutes,
58
- migrationRoutes,
59
- ]
60
-
61
- exports.publicRoutes = publicRoutes
62
- exports.staticRoutes = staticRoutes
@@ -1,120 +0,0 @@
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
- })
@@ -1,164 +0,0 @@
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,41 +0,0 @@
1
- const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
2
- const TestConfig = require("../../../../tests/utilities/TestConfiguration")
3
- const { TENANT_ID } = require("../../../../tests/utilities/structures")
4
- const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota")
5
- const syncApps = require("../syncApps")
6
- const env = require("../../../../environment")
7
-
8
- describe("syncApps", () => {
9
-
10
- let config = new TestConfig(false)
11
-
12
- beforeEach(async () => {
13
- await config.init()
14
- env._set("USE_QUOTAS", 1)
15
- })
16
-
17
- afterAll(config.end)
18
-
19
- it("runs successfully", async () => {
20
- await doInTenant(TENANT_ID, async () => {
21
- const db = getGlobalDB()
22
- // create the usage quota doc and mock usages
23
- await getUsageQuotaDoc(db)
24
- await update(Properties.APPS, 3)
25
-
26
- let usageDoc = await getUsageQuotaDoc(db)
27
- expect(usageDoc.usageQuota.apps).toEqual(3)
28
-
29
- // create an extra app to test the migration
30
- await config.createApp("quota-test")
31
-
32
- // migrate
33
- await syncApps.run()
34
-
35
- // assert the migration worked
36
- usageDoc = await getUsageQuotaDoc(db)
37
- expect(usageDoc.usageQuota.apps).toEqual(2)
38
- })
39
- })
40
- })
41
-
@@ -1,45 +0,0 @@
1
- const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
2
- const TestConfig = require("../../../../tests/utilities/TestConfiguration")
3
- const { TENANT_ID } = require("../../../../tests/utilities/structures")
4
- const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota")
5
- const syncRows = require("../syncRows")
6
- const env = require("../../../../environment")
7
-
8
- describe("syncRows", () => {
9
- let config = new TestConfig(false)
10
-
11
- beforeEach(async () => {
12
- await config.init()
13
- env._set("USE_QUOTAS", 1)
14
- })
15
-
16
- afterAll(config.end)
17
-
18
- it("runs successfully", async () => {
19
- await doInTenant(TENANT_ID, async () => {
20
- const db = getGlobalDB()
21
- await getUsageQuotaDoc(db)
22
- await update(Properties.ROW, 300)
23
-
24
- let usageDoc = await getUsageQuotaDoc(db)
25
- expect(usageDoc.usageQuota.rows).toEqual(300)
26
-
27
- // app 1
28
- await config.createTable()
29
- await config.createRow()
30
- // app 2
31
- await config.createApp("second-app")
32
- await config.createTable()
33
- await config.createRow()
34
- await config.createRow()
35
-
36
- // migrate
37
- await syncRows.run()
38
-
39
- // assert the migration worked
40
- usageDoc = await getUsageQuotaDoc(db)
41
- expect(usageDoc.usageQuota.rows).toEqual(3)
42
- })
43
- })
44
- })
45
-
@@ -1,72 +0,0 @@
1
- const getTenantId = jest.fn()
2
- jest.mock("@budibase/backend-core/tenancy", () => ({
3
- getTenantId
4
- }))
5
- const usageQuota = require("../../usageQuota")
6
- const env = require("../../../environment")
7
-
8
- class TestConfiguration {
9
- constructor() {
10
- this.enableQuotas()
11
- }
12
-
13
- enableQuotas = () => {
14
- env.USE_QUOTAS = 1
15
- }
16
-
17
- disableQuotas = () => {
18
- env.USE_QUOTAS = null
19
- }
20
-
21
- setTenantId = (tenantId) => {
22
- getTenantId.mockReturnValue(tenantId)
23
- }
24
-
25
- setExcludedTenants = (tenants) => {
26
- env.EXCLUDE_QUOTAS_TENANTS = tenants
27
- }
28
-
29
- reset = () => {
30
- this.disableQuotas()
31
- this.setExcludedTenants(null)
32
- }
33
- }
34
-
35
- describe("usageQuota", () => {
36
- let config
37
-
38
- beforeEach(() => {
39
- config = new TestConfiguration()
40
- })
41
-
42
- afterEach(() => {
43
- config.reset()
44
- })
45
-
46
- describe("useQuotas", () => {
47
- it("works when no settings have been provided", () => {
48
- config.reset()
49
- expect(usageQuota.useQuotas()).toBe(false)
50
- })
51
- it("honours USE_QUOTAS setting", () => {
52
- config.disableQuotas()
53
- expect(usageQuota.useQuotas()).toBe(false)
54
-
55
- config.enableQuotas()
56
- expect(usageQuota.useQuotas()).toBe(true)
57
- })
58
- it("honours EXCLUDE_QUOTAS_TENANTS setting", () => {
59
- config.setTenantId("test")
60
-
61
- // tenantId is in the list
62
- config.setExcludedTenants("test, test2, test2")
63
- expect(usageQuota.useQuotas()).toBe(false)
64
- config.setExcludedTenants("test,test2,test2")
65
- expect(usageQuota.useQuotas()).toBe(false)
66
-
67
- // tenantId is not in the list
68
- config.setTenantId("other")
69
- expect(usageQuota.useQuotas()).toBe(true)
70
- })
71
- })
72
- })
@@ -1,93 +0,0 @@
1
- const env = require("../../environment")
2
- const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
3
- const {
4
- StaticDatabases,
5
- generateNewUsageQuotaDoc,
6
- } = require("@budibase/backend-core/db")
7
-
8
- exports.useQuotas = () => {
9
- // check if quotas are enabled
10
- if (env.USE_QUOTAS) {
11
- // check if there are any tenants without limits
12
- if (env.EXCLUDE_QUOTAS_TENANTS) {
13
- const excludedTenants = env.EXCLUDE_QUOTAS_TENANTS.replace(
14
- /\s/g,
15
- ""
16
- ).split(",")
17
- const tenantId = getTenantId()
18
- if (excludedTenants.includes(tenantId)) {
19
- return false
20
- }
21
- }
22
- return true
23
- }
24
- return false
25
- }
26
-
27
- exports.Properties = {
28
- ROW: "rows",
29
- UPLOAD: "storage", // doesn't work yet
30
- VIEW: "views", // doesn't work yet
31
- USER: "users", // doesn't work yet
32
- AUTOMATION: "automationRuns", // doesn't work yet
33
- APPS: "apps",
34
- EMAILS: "emails", // doesn't work yet
35
- }
36
-
37
- exports.getUsageQuotaDoc = async db => {
38
- let quota
39
- try {
40
- quota = await db.get(StaticDatabases.GLOBAL.docs.usageQuota)
41
- } catch (err) {
42
- // doc doesn't exist. Create it
43
- quota = generateNewUsageQuotaDoc()
44
- const response = await db.put(quota)
45
- quota._rev = response.rev
46
- }
47
-
48
- return quota
49
- }
50
-
51
- /**
52
- * Given a specified tenantId this will add to the usage object for the specified property.
53
- * @param {string} property The property which is to be added to (within the nested usageQuota object).
54
- * @param {number} usage The amount (this can be negative) to adjust the number by.
55
- * @param {object} opts optional - options such as dryRun, to check what update will do.
56
- * @returns {Promise<void>} When this completes the API key will now be up to date - the quota period may have
57
- * also been reset after this call.
58
- */
59
- exports.update = async (property, usage, opts = { dryRun: false }) => {
60
- if (!exports.useQuotas()) {
61
- return
62
- }
63
-
64
- try {
65
- const db = getGlobalDB()
66
- const quota = await exports.getUsageQuotaDoc(db)
67
-
68
- // increment the quota
69
- quota.usageQuota[property] += usage
70
-
71
- if (
72
- quota.usageQuota[property] > quota.usageLimits[property] &&
73
- usage > 0 // allow for decrementing usage when the quota is already exceeded
74
- ) {
75
- throw new Error(
76
- `You have exceeded your usage quota of ${quota.usageLimits[property]} ${property}.`
77
- )
78
- }
79
-
80
- if (quota.usageQuota[property] < 0) {
81
- // never go negative if the quota has previously been exceeded
82
- quota.usageQuota[property] = 0
83
- }
84
-
85
- // update the usage quotas
86
- if (!opts.dryRun) {
87
- await db.put(quota)
88
- }
89
- } catch (err) {
90
- console.error(`Error updating usage quotas for ${property}`, err)
91
- throw err
92
- }
93
- }