@budibase/server 1.0.105-alpha.21 → 1.0.105-alpha.24

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 (292) hide show
  1. package/builder/assets/{index.8d922c8c.js → index.06b1c616.js} +150 -147
  2. package/builder/assets/{index.b7e0672d.css → index.e3fb1cb4.css} +2 -2
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +517 -1564
  5. package/coverage/coverage-final.json +27 -43
  6. package/coverage/lcov-report/api/controllers/analytics.js.html +8 -3
  7. package/coverage/lcov-report/api/controllers/apikeys.js.html +9 -4
  8. package/coverage/lcov-report/api/controllers/auth.js.html +8 -3
  9. package/coverage/lcov-report/api/controllers/automation.js.html +8 -3
  10. package/coverage/lcov-report/api/controllers/backup.js.html +8 -3
  11. package/coverage/lcov-report/api/controllers/cloud.js.html +8 -3
  12. package/coverage/lcov-report/api/controllers/component.js.html +8 -3
  13. package/coverage/lcov-report/api/controllers/datasource.js.html +11 -6
  14. package/coverage/lcov-report/api/controllers/dev.js.html +8 -3
  15. package/coverage/lcov-report/api/controllers/index.html +16 -26
  16. package/coverage/lcov-report/api/controllers/integration.js.html +8 -3
  17. package/coverage/lcov-report/api/controllers/layout.js.html +8 -3
  18. package/coverage/lcov-report/api/controllers/metadata.js.html +8 -3
  19. package/coverage/lcov-report/api/controllers/migrations.js.html +8 -3
  20. package/coverage/lcov-report/api/controllers/permission.js.html +8 -3
  21. package/coverage/lcov-report/api/controllers/query/index.html +16 -26
  22. package/coverage/lcov-report/api/controllers/query/validation.js.html +8 -3
  23. package/coverage/lcov-report/api/controllers/role.js.html +10 -5
  24. package/coverage/lcov-report/api/controllers/routing.js.html +9 -4
  25. package/coverage/lcov-report/api/controllers/row/external.js.html +8 -3
  26. package/coverage/lcov-report/api/controllers/row/index.html +23 -33
  27. package/coverage/lcov-report/api/controllers/row/internal.js.html +32 -24
  28. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +21 -16
  29. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +24 -19
  30. package/coverage/lcov-report/api/controllers/row/utils.js.html +20 -15
  31. package/coverage/lcov-report/api/controllers/screen.js.html +9 -4
  32. package/coverage/lcov-report/api/controllers/script.js.html +8 -3
  33. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +52 -47
  34. package/coverage/lcov-report/api/controllers/table/external.js.html +8 -3
  35. package/coverage/lcov-report/api/controllers/table/index.html +17 -42
  36. package/coverage/lcov-report/api/controllers/table/index.js.html +20 -15
  37. package/coverage/lcov-report/api/controllers/templates.js.html +8 -3
  38. package/coverage/lcov-report/api/controllers/user.js.html +8 -3
  39. package/coverage/lcov-report/api/controllers/view/exporters.js.html +8 -3
  40. package/coverage/lcov-report/api/controllers/view/index.html +8 -3
  41. package/coverage/lcov-report/api/controllers/view/index.js.html +10 -5
  42. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -3
  43. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +8 -3
  44. package/coverage/lcov-report/api/controllers/webhook.js.html +10 -5
  45. package/coverage/lcov-report/api/index.html +18 -13
  46. package/coverage/lcov-report/api/index.js.html +28 -8
  47. package/coverage/lcov-report/api/routes/analytics.js.html +8 -3
  48. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -3
  49. package/coverage/lcov-report/api/routes/auth.js.html +8 -3
  50. package/coverage/lcov-report/api/routes/automation.js.html +8 -3
  51. package/coverage/lcov-report/api/routes/backup.js.html +8 -3
  52. package/coverage/lcov-report/api/routes/cloud.js.html +8 -3
  53. package/coverage/lcov-report/api/routes/component.js.html +8 -3
  54. package/coverage/lcov-report/api/routes/datasource.js.html +8 -3
  55. package/coverage/lcov-report/api/routes/deploy.js.html +8 -3
  56. package/coverage/lcov-report/api/routes/dev.js.html +9 -4
  57. package/coverage/lcov-report/api/routes/index.html +13 -68
  58. package/coverage/lcov-report/api/routes/integration.js.html +8 -3
  59. package/coverage/lcov-report/api/routes/layout.js.html +8 -3
  60. package/coverage/lcov-report/api/routes/metadata.js.html +8 -3
  61. package/coverage/lcov-report/api/routes/migrations.js.html +8 -3
  62. package/coverage/lcov-report/api/routes/permission.js.html +8 -3
  63. package/coverage/lcov-report/api/routes/query.js.html +8 -3
  64. package/coverage/lcov-report/api/routes/role.js.html +8 -3
  65. package/coverage/lcov-report/api/routes/routing.js.html +8 -3
  66. package/coverage/lcov-report/api/routes/screen.js.html +8 -3
  67. package/coverage/lcov-report/api/routes/script.js.html +8 -3
  68. package/coverage/lcov-report/api/routes/table.js.html +8 -3
  69. package/coverage/lcov-report/api/routes/templates.js.html +8 -3
  70. package/coverage/lcov-report/api/routes/user.js.html +8 -3
  71. package/coverage/lcov-report/api/routes/utils/index.html +8 -3
  72. package/coverage/lcov-report/api/routes/utils/validators.js.html +8 -3
  73. package/coverage/lcov-report/api/routes/view.js.html +8 -3
  74. package/coverage/lcov-report/api/routes/webhook.js.html +8 -3
  75. package/coverage/lcov-report/automations/actions.js.html +9 -4
  76. package/coverage/lcov-report/automations/automationUtils.js.html +20 -15
  77. package/coverage/lcov-report/automations/bullboard.js.html +8 -3
  78. package/coverage/lcov-report/automations/index.html +16 -26
  79. package/coverage/lcov-report/automations/index.js.html +8 -3
  80. package/coverage/lcov-report/automations/steps/bash.js.html +8 -3
  81. package/coverage/lcov-report/automations/steps/delay.js.html +8 -3
  82. package/coverage/lcov-report/automations/steps/discord.js.html +8 -3
  83. package/coverage/lcov-report/automations/steps/executeQuery.js.html +8 -3
  84. package/coverage/lcov-report/automations/steps/executeScript.js.html +8 -3
  85. package/coverage/lcov-report/automations/steps/filter.js.html +8 -3
  86. package/coverage/lcov-report/automations/steps/index.html +16 -41
  87. package/coverage/lcov-report/automations/steps/integromat.js.html +8 -3
  88. package/coverage/lcov-report/automations/steps/loop.js.html +8 -3
  89. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +9 -4
  90. package/coverage/lcov-report/automations/steps/queryRows.js.html +9 -4
  91. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +8 -3
  92. package/coverage/lcov-report/automations/steps/serverLog.js.html +8 -3
  93. package/coverage/lcov-report/automations/steps/slack.js.html +8 -3
  94. package/coverage/lcov-report/automations/steps/updateRow.js.html +8 -3
  95. package/coverage/lcov-report/automations/steps/utils.js.html +14 -9
  96. package/coverage/lcov-report/automations/steps/zapier.js.html +8 -3
  97. package/coverage/lcov-report/automations/triggerInfo/app.js.html +8 -3
  98. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +8 -3
  99. package/coverage/lcov-report/automations/triggerInfo/index.html +8 -3
  100. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -3
  101. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +8 -3
  102. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +8 -3
  103. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +8 -3
  104. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +8 -3
  105. package/coverage/lcov-report/automations/triggers.js.html +16 -11
  106. package/coverage/lcov-report/block-navigation.js +8 -0
  107. package/coverage/lcov-report/constants/index.html +8 -3
  108. package/coverage/lcov-report/constants/index.js.html +35 -30
  109. package/coverage/lcov-report/constants/layouts.js.html +8 -3
  110. package/coverage/lcov-report/constants/screens.js.html +8 -3
  111. package/coverage/lcov-report/db/client.js.html +26 -21
  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 +10 -5
  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 +83 -78
  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 +122 -117
  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 +11 -6
  131. package/coverage/lcov-report/middleware/index.html +16 -41
  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 +55 -50
  139. package/coverage/lcov-report/threads/index.html +16 -26
  140. package/coverage/lcov-report/threads/query.js.html +10 -5
  141. package/coverage/lcov-report/threads/utils.js.html +11 -6
  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 +46 -41
  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 +45 -40
  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 +759 -2599
  165. package/dist/api/controllers/application.js +138 -70
  166. package/dist/api/controllers/deploy/index.js +64 -35
  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/table/internal.js +40 -34
  179. package/dist/api/controllers/table/utils.js +271 -229
  180. package/dist/api/index.js +5 -0
  181. package/dist/api/routes/application.js +39 -13
  182. package/dist/api/routes/index.js +61 -56
  183. package/dist/api/routes/public/index.js +6 -9
  184. package/dist/api/routes/public/queries.js +1 -1
  185. package/dist/api/routes/public/rows.js +1 -1
  186. package/dist/api/routes/public/tables.js +3 -3
  187. package/dist/api/routes/public/users.js +1 -1
  188. package/dist/api/routes/row.js +43 -17
  189. package/dist/api/routes/static.js +40 -13
  190. package/dist/api/routes/tests/utilities/TestFunctions.js +62 -26
  191. package/dist/app.js +11 -4
  192. package/dist/automations/steps/createRow.js +12 -12
  193. package/dist/automations/steps/deleteRow.js +13 -16
  194. package/dist/automations/tests/utilities/index.js +0 -2
  195. package/dist/automations/utils.js +187 -132
  196. package/dist/environment.js +0 -2
  197. package/dist/integrations/base/sql.js +2 -2
  198. package/dist/integrations/base/sqlTable.js +2 -2
  199. package/dist/integrations/googlesheets.js +1 -1
  200. package/dist/integrations/microsoftSqlServer.js +8 -8
  201. package/dist/integrations/mysql.js +9 -9
  202. package/dist/integrations/oracle.js +7 -7
  203. package/dist/integrations/postgres.js +7 -7
  204. package/dist/integrations/rest.js +1 -1
  205. package/dist/middleware/authorized.js +51 -51
  206. package/dist/migrations/functions/appUrls.js +1 -1
  207. package/dist/migrations/functions/developerQuota.js +49 -0
  208. package/dist/migrations/functions/publishedAppsQuota.js +47 -0
  209. package/dist/migrations/functions/quotas1.js +6 -2
  210. package/dist/migrations/functions/usageQuotas/index.js +0 -4
  211. package/dist/migrations/functions/usageQuotas/syncApps.js +4 -7
  212. package/dist/migrations/functions/usageQuotas/syncDevelopers.js +24 -0
  213. package/dist/migrations/functions/usageQuotas/syncPublishedApps.js +26 -0
  214. package/dist/migrations/functions/usageQuotas/syncRows.js +5 -8
  215. package/dist/migrations/index.js +17 -1
  216. package/dist/package.json +10 -8
  217. package/dist/threads/index.js +35 -8
  218. package/dist/tsconfig.build.tsbuildinfo +1 -0
  219. package/dist/utilities/queue/inMemoryQueue.js +6 -1
  220. package/nodemon.json +1 -1
  221. package/package.json +11 -9
  222. package/scripts/dev/manage.js +2 -0
  223. package/src/api/controllers/{application.js → application.ts} +103 -44
  224. package/src/api/controllers/deploy/{index.js → index.ts} +45 -28
  225. package/src/api/controllers/public/applications.ts +2 -2
  226. package/src/api/controllers/public/queries.ts +1 -1
  227. package/src/api/controllers/public/rows.ts +1 -1
  228. package/src/api/controllers/query/{index.js → index.ts} +51 -48
  229. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  230. package/src/api/controllers/row/{index.js → index.ts} +24 -17
  231. package/src/api/controllers/row/internal.js +2 -1
  232. package/src/api/controllers/table/{internal.js → internal.ts} +27 -24
  233. package/src/api/controllers/table/{utils.js → utils.ts} +86 -69
  234. package/src/api/index.js +5 -0
  235. package/src/api/routes/{application.js → application.ts} +8 -14
  236. package/src/api/routes/index.ts +60 -0
  237. package/src/api/routes/public/index.ts +1 -4
  238. package/src/api/routes/{row.js → row.ts} +7 -15
  239. package/src/api/routes/{static.js → static.ts} +11 -11
  240. package/src/api/routes/tests/utilities/{TestFunctions.js → TestFunctions.ts} +42 -25
  241. package/src/app.ts +1 -2
  242. package/src/automations/steps/{createRow.js → createRow.ts} +9 -15
  243. package/src/automations/steps/{deleteRow.js → deleteRow.ts} +10 -16
  244. package/src/automations/tests/automation.spec.js +0 -1
  245. package/src/automations/tests/{createRow.spec.js → createRow.spec.ts} +4 -15
  246. package/src/automations/tests/{deleteRow.spec.js → deleteRow.spec.ts} +3 -5
  247. package/src/automations/tests/utilities/index.js +0 -2
  248. package/src/automations/{utils.js → utils.ts} +39 -27
  249. package/src/environment.js +0 -2
  250. package/src/middleware/{authorized.js → authorized.ts} +20 -14
  251. package/src/migrations/functions/developerQuota.ts +15 -0
  252. package/src/migrations/functions/publishedAppsQuota.ts +13 -0
  253. package/src/migrations/functions/tests/quotas1.spec.js +0 -2
  254. package/src/migrations/functions/usageQuotas/index.ts +0 -5
  255. package/src/migrations/functions/usageQuotas/syncApps.ts +3 -6
  256. package/src/migrations/functions/usageQuotas/syncDevelopers.ts +19 -0
  257. package/src/migrations/functions/usageQuotas/syncPublishedApps.ts +21 -0
  258. package/src/migrations/functions/usageQuotas/syncRows.ts +3 -6
  259. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts +32 -0
  260. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +38 -0
  261. package/src/migrations/index.ts +13 -1
  262. package/src/module.d.ts +4 -0
  263. package/src/threads/{index.js → index.ts} +14 -12
  264. package/src/utilities/queue/inMemoryQueue.js +7 -1
  265. package/tsconfig.build.json +10 -0
  266. package/tsconfig.json +2 -2
  267. package/coverage/lcov-report/api/controllers/application.js.html +0 -1430
  268. package/coverage/lcov-report/api/controllers/query/index.js.html +0 -713
  269. package/coverage/lcov-report/api/controllers/row/index.js.html +0 -524
  270. package/coverage/lcov-report/api/controllers/table/internal.js.html +0 -548
  271. package/coverage/lcov-report/api/controllers/table/utils.js.html +0 -1331
  272. package/coverage/lcov-report/api/routes/application.js.html +0 -179
  273. package/coverage/lcov-report/api/routes/index.js.html +0 -266
  274. package/coverage/lcov-report/api/routes/row.js.html +0 -908
  275. package/coverage/lcov-report/api/routes/static.js.html +0 -245
  276. package/coverage/lcov-report/automations/steps/createRow.js.html +0 -380
  277. package/coverage/lcov-report/automations/steps/deleteRow.js.html +0 -347
  278. package/coverage/lcov-report/automations/utils.js.html +0 -662
  279. package/coverage/lcov-report/middleware/authorized.js.html +0 -458
  280. package/coverage/lcov-report/middleware/usageQuota.js.html +0 -572
  281. package/coverage/lcov-report/threads/index.js.html +0 -278
  282. package/coverage/lcov-report/utilities/usageQuota/index.js.html +0 -359
  283. package/dist/middleware/usageQuota.js +0 -154
  284. package/dist/tsconfig.tsbuildinfo +0 -1
  285. package/dist/utilities/usageQuota/index.js +0 -86
  286. package/src/api/routes/index.js +0 -62
  287. package/src/middleware/tests/usageQuota.spec.js +0 -134
  288. package/src/middleware/usageQuota.js +0 -164
  289. package/src/migrations/functions/usageQuotas/tests/syncApps.spec.js +0 -37
  290. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.js +0 -43
  291. package/src/utilities/tests/usageQuota/usageQuota.spec.js +0 -72
  292. package/src/utilities/usageQuota/index.js +0 -93
@@ -1,31 +1,38 @@
1
- const rowController = require("../../../controllers/row")
2
- const appController = require("../../../controllers/application")
3
- const { AppStatus } = require("../../../../db/utils")
4
- const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
5
- const { TENANT_ID } = require("../../../../tests/utilities/structures")
6
- const { getAppDB, doInAppContext } = require("@budibase/backend-core/context")
7
- const env = require("../../../../environment")
8
-
9
- function Request(appId, params) {
10
- this.appId = appId
11
- this.params = params
12
- this.request = {}
1
+ import * as rowController from "../../../controllers/row"
2
+ import * as appController from "../../../controllers/application"
3
+ import { AppStatus } from "../../../../db/utils"
4
+ import { BUILTIN_ROLE_IDS } from "@budibase/backend-core/roles"
5
+ import { TENANT_ID } from "../../../../tests/utilities/structures"
6
+ import { getAppDB, doInAppContext } from "@budibase/backend-core/context"
7
+ import * as env from "../../../../environment"
8
+
9
+ class Request {
10
+ appId: any
11
+ params: any
12
+ request: any
13
+ body: any
14
+
15
+ constructor(appId: any, params: any) {
16
+ this.appId = appId
17
+ this.params = params
18
+ this.request = {}
19
+ }
13
20
  }
14
21
 
15
- function runRequest(appId, controlFunc, request) {
22
+ function runRequest(appId: any, controlFunc: any, request?: any) {
16
23
  return doInAppContext(appId, async () => {
17
24
  return controlFunc(request)
18
25
  })
19
26
  }
20
27
 
21
- exports.getAllTableRows = async config => {
28
+ export const getAllTableRows = async (config: any) => {
22
29
  const req = new Request(config.appId, { tableId: config.table._id })
23
30
  await runRequest(config.appId, rowController.fetch, req)
24
31
  return req.body
25
32
  }
26
33
 
27
- exports.clearAllApps = async (tenantId = TENANT_ID) => {
28
- const req = { query: { status: AppStatus.DEV }, user: { tenantId } }
34
+ export const clearAllApps = async (tenantId = TENANT_ID) => {
35
+ const req: any = { query: { status: AppStatus.DEV }, user: { tenantId } }
29
36
  await appController.fetch(req)
30
37
  const apps = req.body
31
38
  if (!apps || apps.length <= 0) {
@@ -34,11 +41,11 @@ exports.clearAllApps = async (tenantId = TENANT_ID) => {
34
41
  for (let app of apps) {
35
42
  const { appId } = app
36
43
  const req = new Request(null, { appId })
37
- await runRequest(appId, appController.delete, req)
44
+ await runRequest(appId, appController.destroy, req)
38
45
  }
39
46
  }
40
47
 
41
- exports.clearAllAutomations = async config => {
48
+ export const clearAllAutomations = async (config: any) => {
42
49
  const automations = await config.getAllAutomations()
43
50
  for (let auto of automations) {
44
51
  await doInAppContext(config.appId, async () => {
@@ -47,7 +54,12 @@ exports.clearAllAutomations = async config => {
47
54
  }
48
55
  }
49
56
 
50
- exports.createRequest = (request, method, url, body) => {
57
+ export const createRequest = (
58
+ request: any,
59
+ method: any,
60
+ url: any,
61
+ body: any
62
+ ) => {
51
63
  let req
52
64
 
53
65
  if (method === "POST") req = request.post(url).send(body)
@@ -59,7 +71,12 @@ exports.createRequest = (request, method, url, body) => {
59
71
  return req
60
72
  }
61
73
 
62
- exports.checkBuilderEndpoint = async ({ config, method, url, body }) => {
74
+ export const checkBuilderEndpoint = async ({
75
+ config,
76
+ method,
77
+ url,
78
+ body,
79
+ }: any) => {
63
80
  const headers = await config.login({
64
81
  userId: "us_fail",
65
82
  builder: false,
@@ -71,14 +88,14 @@ exports.checkBuilderEndpoint = async ({ config, method, url, body }) => {
71
88
  .expect(403)
72
89
  }
73
90
 
74
- exports.checkPermissionsEndpoint = async ({
91
+ export const checkPermissionsEndpoint = async ({
75
92
  config,
76
93
  method,
77
94
  url,
78
95
  body,
79
96
  passRole,
80
97
  failRole,
81
- }) => {
98
+ }: any) => {
82
99
  const passHeader = await config.login({
83
100
  roleId: passRole,
84
101
  prodApp: true,
@@ -106,11 +123,11 @@ exports.checkPermissionsEndpoint = async ({
106
123
  .expect(403)
107
124
  }
108
125
 
109
- exports.getDB = () => {
126
+ export const getDB = () => {
110
127
  return getAppDB()
111
128
  }
112
129
 
113
- exports.testAutomation = async (config, automation) => {
130
+ export const testAutomation = async (config: any, automation: any) => {
114
131
  return runRequest(automation.appId, async () => {
115
132
  return await config.request
116
133
  .post(`/api/automations/${automation._id}/test`)
@@ -126,7 +143,7 @@ exports.testAutomation = async (config, automation) => {
126
143
  })
127
144
  }
128
145
 
129
- exports.runInProd = async func => {
146
+ export const runInProd = async (func: any) => {
130
147
  const nodeEnv = env.NODE_ENV
131
148
  const workerId = env.JEST_WORKER_ID
132
149
  env._set("NODE_ENV", "PRODUCTION")
package/src/app.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  // need to load environment first
2
2
  import { ExtendableContext } from "koa"
3
-
4
3
  import * as env from "./environment"
5
4
  const CouchDB = require("./db")
6
5
  require("@budibase/backend-core").init(CouchDB)
@@ -15,7 +14,7 @@ const automations = require("./automations/index")
15
14
  const Sentry = require("@sentry/node")
16
15
  const fileSystem = require("./utilities/fileSystem")
17
16
  const bullboard = require("./automations/bullboard")
18
- const redis = require("./utilities/redis")
17
+ import redis from "./utilities/redis"
19
18
  import * as migrations from "./migrations"
20
19
 
21
20
  const app = new Koa()
@@ -1,9 +1,8 @@
1
- const rowController = require("../../api/controllers/row")
2
- const automationUtils = require("../automationUtils")
3
- const usage = require("../../utilities/usageQuota")
4
- const { buildCtx } = require("./utils")
1
+ import { save } from "../../api/controllers/row"
2
+ import { cleanUpRow, getError } from "../automationUtils"
3
+ import { buildCtx } from "./utils"
5
4
 
6
- exports.definition = {
5
+ export const definition = {
7
6
  name: "Create Row",
8
7
  tagline: "Create a {{inputs.enriched.table.name}} row",
9
8
  icon: "TableRowAddBottom",
@@ -59,7 +58,7 @@ exports.definition = {
59
58
  },
60
59
  }
61
60
 
62
- exports.run = async function ({ inputs, appId, emitter }) {
61
+ export async function run({ inputs, appId, emitter }: any) {
63
62
  if (inputs.row == null || inputs.row.tableId == null) {
64
63
  return {
65
64
  success: false,
@@ -69,7 +68,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
69
68
  }
70
69
  }
71
70
  // have to clean up the row, remove the table from it
72
- const ctx = buildCtx(appId, emitter, {
71
+ const ctx: any = buildCtx(appId, emitter, {
73
72
  body: inputs.row,
74
73
  params: {
75
74
  tableId: inputs.row.tableId,
@@ -77,13 +76,8 @@ exports.run = async function ({ inputs, appId, emitter }) {
77
76
  })
78
77
 
79
78
  try {
80
- inputs.row = await automationUtils.cleanUpRow(
81
- inputs.row.tableId,
82
- inputs.row
83
- )
84
- await usage.update(usage.Properties.ROW, 1, { dryRun: true })
85
- await rowController.save(ctx)
86
- await usage.update(usage.Properties.ROW, 1)
79
+ inputs.row = await cleanUpRow(inputs.row.tableId, inputs.row)
80
+ await save(ctx)
87
81
  return {
88
82
  row: inputs.row,
89
83
  response: ctx.body,
@@ -94,7 +88,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
94
88
  } catch (err) {
95
89
  return {
96
90
  success: false,
97
- response: automationUtils.getError(err),
91
+ response: getError(err),
98
92
  }
99
93
  }
100
94
  }
@@ -1,9 +1,8 @@
1
- const rowController = require("../../api/controllers/row")
2
- const usage = require("../../utilities/usageQuota")
3
- const { buildCtx } = require("./utils")
4
- const automationUtils = require("../automationUtils")
1
+ import { destroy } from "../../api/controllers/row"
2
+ import { buildCtx } from "./utils"
3
+ import { getError } from "../automationUtils"
5
4
 
6
- exports.definition = {
5
+ export const definition = {
7
6
  description: "Delete a row from your database",
8
7
  icon: "TableRowRemoveCenter",
9
8
  name: "Delete Row",
@@ -24,12 +23,8 @@ exports.definition = {
24
23
  type: "string",
25
24
  title: "Row ID",
26
25
  },
27
- revision: {
28
- type: "string",
29
- title: "Row Revision",
30
- },
31
26
  },
32
- required: ["tableId", "id", "revision"],
27
+ required: ["tableId", "id"],
33
28
  },
34
29
  outputs: {
35
30
  properties: {
@@ -52,8 +47,8 @@ exports.definition = {
52
47
  },
53
48
  }
54
49
 
55
- exports.run = async function ({ inputs, appId, emitter }) {
56
- if (inputs.id == null || inputs.revision == null) {
50
+ export async function run({ inputs, appId, emitter }: any) {
51
+ if (inputs.id == null) {
57
52
  return {
58
53
  success: false,
59
54
  response: {
@@ -62,7 +57,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
62
57
  }
63
58
  }
64
59
 
65
- let ctx = buildCtx(appId, emitter, {
60
+ let ctx: any = buildCtx(appId, emitter, {
66
61
  body: {
67
62
  _id: inputs.id,
68
63
  _rev: inputs.revision,
@@ -73,8 +68,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
73
68
  })
74
69
 
75
70
  try {
76
- await usage.update(usage.Properties.ROW, -1)
77
- await rowController.destroy(ctx)
71
+ await destroy(ctx)
78
72
  return {
79
73
  response: ctx.body,
80
74
  row: ctx.row,
@@ -83,7 +77,7 @@ exports.run = async function ({ inputs, appId, emitter }) {
83
77
  } catch (err) {
84
78
  return {
85
79
  success: false,
86
- response: automationUtils.getError(err),
80
+ response: getError(err),
87
81
  }
88
82
  }
89
83
  }
@@ -1,4 +1,3 @@
1
- jest.mock("../../utilities/usageQuota")
2
1
  jest.mock("../../threads/automation")
3
2
  jest.mock("../../utilities/redis", () => ({
4
3
  init: jest.fn(),
@@ -1,10 +1,8 @@
1
- jest.mock("../../utilities/usageQuota")
2
-
3
- const usageQuota = require("../../utilities/usageQuota")
4
- const setup = require("./utilities")
1
+ import * as setup from "./utilities"
5
2
 
6
3
  describe("test the create row action", () => {
7
- let table, row
4
+ let table: any
5
+ let row: any
8
6
  let config = setup.getConfig()
9
7
 
10
8
  beforeEach(async () => {
@@ -36,20 +34,11 @@ describe("test the create row action", () => {
36
34
  row: {
37
35
  tableId: "invalid",
38
36
  invalid: "invalid",
39
- }
37
+ },
40
38
  })
41
39
  expect(res.success).toEqual(false)
42
40
  })
43
41
 
44
- it("check usage quota attempts", async () => {
45
- await setup.runInProd(async () => {
46
- await setup.runStep(setup.actions.CREATE_ROW.stepId, {
47
- row
48
- })
49
- expect(usageQuota.update).toHaveBeenCalledWith("rows", 1)
50
- })
51
- })
52
-
53
42
  it("should check invalid inputs return an error", async () => {
54
43
  const res = await setup.runStep(setup.actions.CREATE_ROW.stepId, {})
55
44
  expect(res.success).toEqual(false)
@@ -1,10 +1,9 @@
1
- jest.mock("../../utilities/usageQuota")
2
-
3
- const usageQuota = require("../../utilities/usageQuota")
4
1
  const setup = require("./utilities")
5
2
 
6
3
  describe("test the delete row action", () => {
7
- let table, row, inputs
4
+ let table: any
5
+ let row: any
6
+ let inputs: any
8
7
  let config = setup.getConfig()
9
8
 
10
9
  beforeEach(async () => {
@@ -37,7 +36,6 @@ describe("test the delete row action", () => {
37
36
  it("check usage quota attempts", async () => {
38
37
  await setup.runInProd(async () => {
39
38
  await setup.runStep(setup.actions.DELETE_ROW.stepId, inputs)
40
- expect(usageQuota.update).toHaveBeenCalledWith("rows", -1)
41
39
  })
42
40
  })
43
41
 
@@ -18,7 +18,6 @@ exports.afterAll = () => {
18
18
 
19
19
  exports.runInProd = async fn => {
20
20
  env._set("NODE_ENV", "production")
21
- env._set("USE_QUOTAS", 1)
22
21
  let error
23
22
  try {
24
23
  await fn()
@@ -26,7 +25,6 @@ exports.runInProd = async fn => {
26
25
  error = err
27
26
  }
28
27
  env._set("NODE_ENV", "jest")
29
- env._set("USE_QUOTAS", null)
30
28
  if (error) {
31
29
  throw error
32
30
  }
@@ -1,26 +1,32 @@
1
- const { Thread, ThreadType } = require("../threads")
2
- const { definitions } = require("./triggerInfo")
3
- const webhooks = require("../api/controllers/webhook")
4
- const CouchDB = require("../db")
5
- const { queue } = require("./bullboard")
6
- const newid = require("../db/newid")
7
- const { updateEntityMetadata } = require("../utilities")
8
- const { MetadataTypes, WebhookType } = require("../constants")
9
- const { getProdAppID } = require("@budibase/backend-core/db")
10
- const { cloneDeep } = require("lodash/fp")
11
- const { getAppDB, getAppId } = require("@budibase/backend-core/context")
1
+ import { Thread, ThreadType } from "../threads"
2
+ import { definitions } from "./triggerInfo"
3
+ import * as webhooks from "../api/controllers/webhook"
4
+ import CouchDB from "../db"
5
+ import { queue } from "./bullboard"
6
+ import newid from "../db/newid"
7
+ import { updateEntityMetadata } from "../utilities"
8
+ import { MetadataTypes, WebhookType } from "../constants"
9
+ import { getProdAppID } from "@budibase/backend-core/db"
10
+ import { cloneDeep } from "lodash/fp"
11
+ import { getAppDB, getAppId } from "@budibase/backend-core/context"
12
+ import { tenancy } from "@budibase/backend-core"
13
+ import { quotas } from "@budibase/pro"
12
14
 
13
15
  const WH_STEP_ID = definitions.WEBHOOK.stepId
14
16
  const CRON_STEP_ID = definitions.CRON.stepId
15
17
  const Runner = new Thread(ThreadType.AUTOMATION)
16
18
 
17
- exports.processEvent = async job => {
19
+ export async function processEvent(job: any) {
18
20
  try {
19
- // need to actually await these so that an error can be captured properly
20
21
  console.log(
21
22
  `${job.data.automation.appId} automation ${job.data.automation._id} running`
22
23
  )
23
- return await Runner.run(job)
24
+ // need to actually await these so that an error can be captured properly
25
+ const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
26
+ return await tenancy.doInTenant(tenantId, async () => {
27
+ const runFn = () => Runner.run(job)
28
+ return quotas.addAutomation(runFn)
29
+ })
24
30
  } catch (err) {
25
31
  const errJson = JSON.stringify(err)
26
32
  console.error(
@@ -31,11 +37,15 @@ exports.processEvent = async job => {
31
37
  }
32
38
  }
33
39
 
34
- exports.updateTestHistory = async (appId, automation, history) => {
40
+ export async function updateTestHistory(
41
+ appId: any,
42
+ automation: any,
43
+ history: any
44
+ ) {
35
45
  return updateEntityMetadata(
36
46
  MetadataTypes.AUTOMATION_TEST_HISTORY,
37
47
  automation._id,
38
- metadata => {
48
+ (metadata: any) => {
39
49
  if (metadata && Array.isArray(metadata.history)) {
40
50
  metadata.history.push(history)
41
51
  } else {
@@ -48,7 +58,7 @@ exports.updateTestHistory = async (appId, automation, history) => {
48
58
  )
49
59
  }
50
60
 
51
- exports.removeDeprecated = definitions => {
61
+ export function removeDeprecated(definitions: any) {
52
62
  const base = cloneDeep(definitions)
53
63
  for (let key of Object.keys(base)) {
54
64
  if (base[key].deprecated) {
@@ -59,13 +69,15 @@ exports.removeDeprecated = definitions => {
59
69
  }
60
70
 
61
71
  // end the repetition and the job itself
62
- exports.disableAllCrons = async appId => {
72
+ export async function disableAllCrons(appId: any) {
63
73
  const promises = []
64
74
  const jobs = await queue.getRepeatableJobs()
65
75
  for (let job of jobs) {
66
76
  if (job.key.includes(`${appId}_cron`)) {
67
77
  promises.push(queue.removeRepeatableByKey(job.key))
68
- promises.push(queue.removeJobs(job.id))
78
+ if (job.id) {
79
+ promises.push(queue.removeJobs(job.id))
80
+ }
69
81
  }
70
82
  }
71
83
  return Promise.all(promises)
@@ -76,9 +88,9 @@ exports.disableAllCrons = async appId => {
76
88
  * @param {string} appId The ID of the app in which we are checking for webhooks
77
89
  * @param {object|undefined} automation The automation object to be updated.
78
90
  */
79
- exports.enableCronTrigger = async (appId, automation) => {
91
+ export async function enableCronTrigger(appId: any, automation: any) {
80
92
  const trigger = automation ? automation.definition.trigger : null
81
- function isCronTrigger(auto) {
93
+ function isCronTrigger(auto: any) {
82
94
  return (
83
95
  auto &&
84
96
  auto.definition.trigger &&
@@ -89,7 +101,7 @@ exports.enableCronTrigger = async (appId, automation) => {
89
101
  if (isCronTrigger(automation)) {
90
102
  // make a job id rather than letting Bull decide, makes it easier to handle on way out
91
103
  const jobId = `${appId}_cron_${newid()}`
92
- const job = await queue.add(
104
+ const job: any = await queue.add(
93
105
  {
94
106
  automation,
95
107
  event: { appId, timestamp: Date.now() },
@@ -117,13 +129,13 @@ exports.enableCronTrigger = async (appId, automation) => {
117
129
  * @returns {Promise<object|undefined>} After this is complete the new automation object may have been updated and should be
118
130
  * written to DB (this does not write to DB as it would be wasteful to repeat).
119
131
  */
120
- exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
132
+ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
121
133
  const appId = getAppId()
122
134
  const oldTrigger = oldAuto ? oldAuto.definition.trigger : null
123
135
  const newTrigger = newAuto ? newAuto.definition.trigger : null
124
136
  const triggerChanged =
125
137
  oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id
126
- function isWebhookTrigger(auto) {
138
+ function isWebhookTrigger(auto: any) {
127
139
  return (
128
140
  auto &&
129
141
  auto.definition.trigger &&
@@ -159,7 +171,7 @@ exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
159
171
  (!isWebhookTrigger(oldAuto) || triggerChanged) &&
160
172
  isWebhookTrigger(newAuto)
161
173
  ) {
162
- const ctx = {
174
+ const ctx: any = {
163
175
  appId,
164
176
  request: {
165
177
  body: new webhooks.Webhook(
@@ -189,6 +201,6 @@ exports.checkForWebhooks = async ({ oldAuto, newAuto }) => {
189
201
  * @param appId {string} the app that is being removed.
190
202
  * @return {Promise<void>} clean is complete if this succeeds.
191
203
  */
192
- exports.cleanupAutomations = async appId => {
193
- await exports.disableAllCrons(appId)
204
+ export async function cleanupAutomations(appId: any) {
205
+ await disableAllCrons(appId)
194
206
  }
@@ -38,8 +38,6 @@ module.exports = {
38
38
  ENABLE_ANALYTICS: process.env.ENABLE_ANALYTICS,
39
39
  MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
40
40
  MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
41
- USE_QUOTAS: process.env.USE_QUOTAS,
42
- EXCLUDE_QUOTAS_TENANTS: process.env.EXCLUDE_QUOTAS_TENANTS,
43
41
  REDIS_URL: process.env.REDIS_URL,
44
42
  REDIS_PASSWORD: process.env.REDIS_PASSWORD,
45
43
  INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
@@ -1,8 +1,8 @@
1
- const {
1
+ import {
2
2
  getUserRoleHierarchy,
3
3
  getRequiredResourceRole,
4
4
  BUILTIN_ROLE_IDS,
5
- } = require("@budibase/backend-core/roles")
5
+ } from "@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) {
16
+ function hasResource(ctx: any) {
17
17
  return ctx.resourceId != null
18
18
  }
19
19
 
@@ -25,7 +25,12 @@ 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 (ctx, resourceRoles, permType, permLevel) => {
28
+ const checkAuthorized = async (
29
+ ctx: any,
30
+ resourceRoles: any,
31
+ permType: any,
32
+ permLevel: any
33
+ ) => {
29
34
  // check if this is a builder api and the user is not a builder
30
35
  const isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
31
36
  const isBuilderApi = permType === PermissionTypes.BUILDER
@@ -40,10 +45,10 @@ const checkAuthorized = async (ctx, resourceRoles, permType, permLevel) => {
40
45
  }
41
46
 
42
47
  const checkAuthorizedResource = async (
43
- ctx,
44
- resourceRoles,
45
- permType,
46
- permLevel
48
+ ctx: any,
49
+ resourceRoles: any,
50
+ permType: any,
51
+ permLevel: any
47
52
  ) => {
48
53
  // get the user's roles
49
54
  const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC
@@ -54,7 +59,9 @@ const checkAuthorizedResource = async (
54
59
  // check if the user has the required role
55
60
  if (resourceRoles.length > 0) {
56
61
  // deny access if the user doesn't have the required resource role
57
- const found = userRoles.find(role => resourceRoles.indexOf(role._id) !== -1)
62
+ const found = userRoles.find(
63
+ (role: any) => resourceRoles.indexOf(role._id) !== -1
64
+ )
58
65
  if (!found) {
59
66
  ctx.throw(403, permError)
60
67
  }
@@ -64,9 +71,8 @@ const checkAuthorizedResource = async (
64
71
  }
65
72
  }
66
73
 
67
- module.exports =
68
- (permType, permLevel = null, opts = { schema: false }) =>
69
- async (ctx, next) => {
74
+ export = (permType: any, permLevel: any = null, opts = { schema: false }) =>
75
+ async (ctx: any, next: any) => {
70
76
  // webhooks don't need authentication, each webhook unique
71
77
  // also internal requests (between services) don't need authorized
72
78
  if (isWebhookEndpoint(ctx) || ctx.internal) {
@@ -82,8 +88,8 @@ module.exports =
82
88
  await builderMiddleware(ctx, permType)
83
89
 
84
90
  // get the resource roles
85
- let resourceRoles = [],
86
- otherLevelRoles
91
+ let resourceRoles: any = []
92
+ let otherLevelRoles: any = []
87
93
  const otherLevel =
88
94
  permLevel === PermissionLevels.READ
89
95
  ? PermissionLevels.WRITE
@@ -0,0 +1,15 @@
1
+ const { createUserBuildersView } = require("@budibase/backend-core/db")
2
+ import * as syncDevelopers from "./usageQuotas/syncDevelopers"
3
+
4
+ /**
5
+ * Date:
6
+ * March 2022
7
+ *
8
+ * Description:
9
+ * Create the builder users view and sync the developer count
10
+ */
11
+
12
+ export const run = async (db: any) => {
13
+ await createUserBuildersView(db)
14
+ await syncDevelopers.run()
15
+ }
@@ -0,0 +1,13 @@
1
+ import * as syncPublishedApps from "./usageQuotas/syncPublishedApps"
2
+
3
+ /**
4
+ * Date:
5
+ * March 2022
6
+ *
7
+ * Description:
8
+ * Sync the published apps count
9
+ */
10
+
11
+ export const run = async (db: any) => {
12
+ await syncPublishedApps.run()
13
+ }
@@ -1,4 +1,3 @@
1
- const env = require("../../../environment")
2
1
  const TestConfig = require("../../../tests/utilities/TestConfiguration")
3
2
 
4
3
  const syncApps = jest.fn()
@@ -14,7 +13,6 @@ describe("run", () => {
14
13
 
15
14
  beforeEach(async () => {
16
15
  await config.init()
17
- env._set("USE_QUOTAS", 1)
18
16
  })
19
17
 
20
18
  afterAll(config.end)
@@ -1,8 +1,3 @@
1
- const { useQuotas } = require("../../../utilities/usageQuota")
2
-
3
1
  export const runQuotaMigration = async (migration: Function) => {
4
- if (!useQuotas()) {
5
- return
6
- }
7
2
  await migration()
8
3
  }
@@ -1,9 +1,8 @@
1
- import { getGlobalDB, getTenantId } from "@budibase/backend-core/tenancy"
1
+ import { getTenantId } from "@budibase/backend-core/tenancy"
2
2
  import { getAllApps } from "@budibase/backend-core/db"
3
- import { getUsageQuotaDoc } from "../../../utilities/usageQuota"
3
+ import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
4
4
 
5
5
  export const run = async () => {
6
- const db = getGlobalDB()
7
6
  // get app count
8
7
  // @ts-ignore
9
8
  const devApps = await getAllApps({ dev: true })
@@ -12,7 +11,5 @@ export const run = async () => {
12
11
  // sync app count
13
12
  const tenantId = getTenantId()
14
13
  console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`)
15
- const usageDoc = await getUsageQuotaDoc(db)
16
- usageDoc.usageQuota.apps = appCount
17
- await db.put(usageDoc)
14
+ await quotas.setUsage(appCount, StaticQuotaName.APPS, QuotaUsageType.STATIC)
18
15
  }