@budibase/server 2.0.14-alpha.2 → 2.0.15

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 (191) hide show
  1. package/builder/assets/{index.aef99fa8.css → index.dfa4073c.css} +2 -2
  2. package/builder/assets/{index.d83a34bc.js → index.e969ba05.js} +274 -274
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +341 -344
  5. package/coverage/coverage-final.json +24 -24
  6. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  7. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/index.html +1 -1
  13. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  19. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/internal.js.html +12 -12
  25. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +15 -15
  27. package/coverage/lcov-report/api/controllers/row/utils.js.html +13 -13
  28. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  32. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  41. package/coverage/lcov-report/api/index.html +1 -1
  42. package/coverage/lcov-report/api/index.js.html +5 -5
  43. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  44. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  45. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  46. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/index.html +1 -1
  53. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  67. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  70. package/coverage/lcov-report/automations/actions.js.html +1 -1
  71. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  72. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  73. package/coverage/lcov-report/automations/index.html +1 -1
  74. package/coverage/lcov-report/automations/index.js.html +5 -5
  75. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  76. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  77. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  78. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  79. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  80. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  81. package/coverage/lcov-report/automations/steps/index.html +1 -1
  82. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/updateRow.js.html +3 -3
  90. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  92. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  93. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  94. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  95. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  96. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  97. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggers.js.html +22 -22
  101. package/coverage/lcov-report/constants/index.html +1 -1
  102. package/coverage/lcov-report/constants/index.js.html +1 -1
  103. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  104. package/coverage/lcov-report/constants/screens.js.html +1 -1
  105. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  106. package/coverage/lcov-report/db/index.html +1 -1
  107. package/coverage/lcov-report/db/index.js.html +1 -1
  108. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +11 -11
  109. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  110. package/coverage/lcov-report/db/linkedRows/index.js.html +11 -11
  111. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +3 -3
  112. package/coverage/lcov-report/db/newid.js.html +2 -2
  113. package/coverage/lcov-report/db/utils.js.html +16 -10
  114. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  115. package/coverage/lcov-report/events/index.html +1 -1
  116. package/coverage/lcov-report/events/index.js.html +2 -2
  117. package/coverage/lcov-report/events/utils.js.html +9 -9
  118. package/coverage/lcov-report/index.html +15 -15
  119. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  120. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  121. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  122. package/coverage/lcov-report/middleware/builder.js.html +11 -11
  123. package/coverage/lcov-report/middleware/currentapp.js.html +34 -34
  124. package/coverage/lcov-report/middleware/index.html +1 -1
  125. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  126. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  127. package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
  128. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  129. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  130. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  131. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  132. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  133. package/coverage/lcov-report/utilities/global.js.html +16 -16
  134. package/coverage/lcov-report/utilities/index.html +1 -1
  135. package/coverage/lcov-report/utilities/index.js.html +1 -1
  136. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +13 -13
  137. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  138. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  139. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  140. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  141. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +38 -38
  142. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
  143. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  144. package/coverage/lcov-report/utilities/security.js.html +1 -1
  145. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  146. package/coverage/lcov-report/utilities/usageQuota/index.html +14 -14
  147. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +11 -23
  148. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  149. package/coverage/lcov-report/utilities/users.js.html +1 -1
  150. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  151. package/coverage/lcov.info +614 -619
  152. package/dist/api/controllers/application.js +2 -2
  153. package/dist/api/controllers/public/rows.js +4 -2
  154. package/dist/api/controllers/query/index.js +6 -6
  155. package/dist/api/controllers/row/index.js +10 -30
  156. package/dist/api/controllers/table/internal.js +1 -3
  157. package/dist/api/controllers/table/utils.js +1 -3
  158. package/dist/automations/steps/updateRow.js +2 -2
  159. package/dist/automations/utils.js +3 -5
  160. package/dist/db/utils.js +1 -1
  161. package/dist/migrations/functions/{usageQuotas/syncPlugins.js → pluginCount.js} +3 -1
  162. package/dist/migrations/functions/{syncQuotas.js → quotas1.js} +7 -3
  163. package/dist/migrations/functions/usageQuotas/syncApps.js +1 -0
  164. package/dist/migrations/functions/usageQuotas/syncRows.js +5 -9
  165. package/dist/migrations/index.js +9 -3
  166. package/dist/package.json +7 -7
  167. package/dist/tsconfig.build.tsbuildinfo +1 -1
  168. package/dist/utilities/usageQuota/rows.js +4 -6
  169. package/package.json +8 -8
  170. package/src/api/controllers/application.ts +2 -2
  171. package/src/api/controllers/public/rows.ts +7 -2
  172. package/src/api/controllers/query/index.ts +6 -7
  173. package/src/api/controllers/row/index.ts +13 -36
  174. package/src/api/controllers/table/internal.ts +1 -3
  175. package/src/api/controllers/table/utils.ts +1 -3
  176. package/src/api/routes/tests/row.spec.js +27 -22
  177. package/src/automations/steps/updateRow.js +2 -2
  178. package/src/automations/tests/automation.spec.js +6 -1
  179. package/src/automations/utils.ts +4 -6
  180. package/src/db/utils.js +2 -0
  181. package/src/migrations/functions/backfill/global.ts +1 -1
  182. package/src/migrations/functions/pluginCount.ts +12 -0
  183. package/src/migrations/functions/{syncQuotas.ts → quotas1.ts} +8 -3
  184. package/src/migrations/functions/tests/{syncQuotas.spec.js → quotas1.spec.js} +2 -5
  185. package/src/migrations/functions/usageQuotas/syncApps.ts +1 -0
  186. package/src/migrations/functions/usageQuotas/syncRows.ts +6 -15
  187. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +1 -9
  188. package/src/migrations/index.ts +15 -3
  189. package/src/migrations/tests/index.spec.ts +1 -0
  190. package/src/utilities/usageQuota/rows.js +3 -7
  191. package/src/migrations/functions/usageQuotas/syncPlugins.ts +0 -10
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  const { getRowParams, USER_METDATA_PREFIX } = require("../../db/utils");
12
- const { isDevAppID, getDevelopmentAppID, getProdAppID, doWithDB, } = require("@budibase/backend-core/db");
12
+ const { isDevAppID, getDevelopmentAppID, doWithDB, } = require("@budibase/backend-core/db");
13
13
  const ROW_EXCLUSIONS = [USER_METDATA_PREFIX];
14
14
  const getAppPairs = appIds => {
15
15
  // collect the app ids into dev / prod pairs
@@ -53,7 +53,7 @@ const getAppRows = (appId) => __awaiter(void 0, void 0, void 0, function* () {
53
53
  * Rows duplicates may exist across apps due to data import so they are not filtered out.
54
54
  */
55
55
  exports.getUniqueRows = (appIds) => __awaiter(void 0, void 0, void 0, function* () {
56
- let uniqueRows = [], rowsByApp = {};
56
+ let uniqueRows = [];
57
57
  const pairs = getAppPairs(appIds);
58
58
  for (let pair of Object.values(pairs)) {
59
59
  let appRows = [];
@@ -73,9 +73,7 @@ exports.getUniqueRows = (appIds) => __awaiter(void 0, void 0, void 0, function*
73
73
  // this can't be done on all rows because app import results in
74
74
  // duplicate row ids across apps
75
75
  // the array pre-concat is important to avoid stack overflow
76
- const prodId = getProdAppID(pair.devId || pair.prodId);
77
- rowsByApp[prodId] = [...new Set(appRows)];
78
- uniqueRows = uniqueRows.concat(rowsByApp[prodId]);
76
+ uniqueRows = uniqueRows.concat([...new Set(appRows)]);
79
77
  }
80
- return { rows: uniqueRows, appRows: rowsByApp };
78
+ return uniqueRows;
81
79
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.0.14-alpha.2",
4
+ "version": "2.0.15",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -77,11 +77,11 @@
77
77
  "license": "GPL-3.0",
78
78
  "dependencies": {
79
79
  "@apidevtools/swagger-parser": "10.0.3",
80
- "@budibase/backend-core": "2.0.14-alpha.2",
81
- "@budibase/client": "2.0.14-alpha.2",
82
- "@budibase/pro": "2.0.14-alpha.1",
83
- "@budibase/string-templates": "2.0.14-alpha.2",
84
- "@budibase/types": "2.0.14-alpha.2",
80
+ "@budibase/backend-core": "^2.0.15",
81
+ "@budibase/client": "^2.0.15",
82
+ "@budibase/pro": "2.0.14",
83
+ "@budibase/string-templates": "^2.0.15",
84
+ "@budibase/types": "^2.0.15",
85
85
  "@bull-board/api": "3.7.0",
86
86
  "@bull-board/koa": "3.9.4",
87
87
  "@elastic/elasticsearch": "7.10.0",
@@ -146,7 +146,7 @@
146
146
  "to-json-schema": "0.2.5",
147
147
  "uuid": "3.3.2",
148
148
  "validate.js": "0.13.1",
149
- "vm2": "3.9.11",
149
+ "vm2": "3.9.6",
150
150
  "worker-farm": "1.7.0",
151
151
  "xml2js": "0.4.23",
152
152
  "yargs": "13.2.4",
@@ -199,5 +199,5 @@
199
199
  "optionalDependencies": {
200
200
  "oracledb": "5.3.0"
201
201
  },
202
- "gitHead": "7f233038acf2170b851340eaaba02741d79b81c1"
202
+ "gitHead": "ca0f857dbedcad51fc2bc90cf16b9667afc08bc6"
203
203
  }
@@ -356,7 +356,7 @@ const appPostCreate = async (ctx: any, app: App) => {
356
356
  await creationEvents(ctx.request, app)
357
357
  // app import & template creation
358
358
  if (ctx.request.body.useTemplate === "true") {
359
- const { rows } = await getUniqueRows([app.appId])
359
+ const rows = await getUniqueRows([app.appId])
360
360
  const rowCount = rows ? rows.length : 0
361
361
  if (rowCount) {
362
362
  try {
@@ -490,7 +490,7 @@ const destroyApp = async (ctx: any) => {
490
490
  }
491
491
 
492
492
  const preDestroyApp = async (ctx: any) => {
493
- const { rows } = await getUniqueRows([ctx.params.appId])
493
+ const rows = await getUniqueRows([ctx.params.appId])
494
494
  ctx.rowCount = rows.length
495
495
  }
496
496
 
@@ -52,14 +52,19 @@ export async function read(ctx: any, next: any) {
52
52
  }
53
53
 
54
54
  export async function update(ctx: any, next: any) {
55
- ctx.request.body = await addRev(fixRow(ctx.request.body, ctx.params))
55
+ const { tableId } = ctx.params
56
+ ctx.request.body = await addRev(fixRow(ctx.request.body, ctx.params), tableId)
56
57
  await rowController.save(ctx)
57
58
  await next()
58
59
  }
59
60
 
60
61
  export async function destroy(ctx: any, next: any) {
62
+ const { tableId } = ctx.params
61
63
  // set the body as expected, with the _id and _rev fields
62
- ctx.request.body = await addRev(fixRow({ _id: ctx.params.rowId }, ctx.params))
64
+ ctx.request.body = await addRev(
65
+ fixRow({ _id: ctx.params.rowId }, ctx.params),
66
+ tableId
67
+ )
63
68
  await rowController.destroy(ctx)
64
69
  // destroy controller doesn't currently return the row as the body, need to adjust this
65
70
  // in the public API to be correct
@@ -153,10 +153,7 @@ export async function preview(ctx: any) {
153
153
  auth: { ...authConfigCtx },
154
154
  },
155
155
  })
156
-
157
- const { rows, keys, info, extra } = await quotas.addQuery(runFn, {
158
- datasourceId: datasource._id,
159
- })
156
+ const { rows, keys, info, extra } = await quotas.addQuery(runFn)
160
157
  const schemaFields: any = {}
161
158
  if (rows?.length > 0) {
162
159
  for (let key of [...new Set(keys)] as string[]) {
@@ -237,9 +234,11 @@ async function execute(
237
234
  },
238
235
  })
239
236
 
240
- const { rows, pagination, extra } = await quotas.addQuery(runFn, {
241
- datasourceId: datasource._id,
242
- })
237
+ const { rows, pagination, extra } = await quotas.addQuery(runFn)
238
+ // remove the raw from execution incase transformer being used to hide data
239
+ if (extra?.raw) {
240
+ delete extra.raw
241
+ }
243
242
  if (opts && opts.rowsOnly) {
244
243
  ctx.body = rows
245
244
  } else {
@@ -31,11 +31,8 @@ export async function patch(ctx: any): Promise<any> {
31
31
  return save(ctx)
32
32
  }
33
33
  try {
34
- const { row, table } = await quotas.addQuery(
35
- () => pickApi(tableId).patch(ctx),
36
- {
37
- datasourceId: tableId,
38
- }
34
+ const { row, table } = await quotas.addQuery(() =>
35
+ pickApi(tableId).patch(ctx)
39
36
  )
40
37
  ctx.status = 200
41
38
  ctx.eventEmitter &&
@@ -57,9 +54,7 @@ export const save = async (ctx: any) => {
57
54
  }
58
55
  try {
59
56
  const { row, table } = await quotas.addRow(() =>
60
- quotas.addQuery(() => pickApi(tableId).save(ctx), {
61
- datasourceId: tableId,
62
- })
57
+ quotas.addQuery(() => pickApi(tableId).save(ctx))
63
58
  )
64
59
  ctx.status = 200
65
60
  ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
@@ -73,9 +68,7 @@ export const save = async (ctx: any) => {
73
68
  export async function fetchView(ctx: any) {
74
69
  const tableId = getTableId(ctx)
75
70
  try {
76
- ctx.body = await quotas.addQuery(() => pickApi(tableId).fetchView(ctx), {
77
- datasourceId: tableId,
78
- })
71
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).fetchView(ctx))
79
72
  } catch (err) {
80
73
  ctx.throw(400, err)
81
74
  }
@@ -84,9 +77,7 @@ export async function fetchView(ctx: any) {
84
77
  export async function fetch(ctx: any) {
85
78
  const tableId = getTableId(ctx)
86
79
  try {
87
- ctx.body = await quotas.addQuery(() => pickApi(tableId).fetch(ctx), {
88
- datasourceId: tableId,
89
- })
80
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).fetch(ctx))
90
81
  } catch (err) {
91
82
  ctx.throw(400, err)
92
83
  }
@@ -95,9 +86,7 @@ export async function fetch(ctx: any) {
95
86
  export async function find(ctx: any) {
96
87
  const tableId = getTableId(ctx)
97
88
  try {
98
- ctx.body = await quotas.addQuery(() => pickApi(tableId).find(ctx), {
99
- datasourceId: tableId,
100
- })
89
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).find(ctx))
101
90
  } catch (err) {
102
91
  ctx.throw(400, err)
103
92
  }
@@ -109,11 +98,8 @@ export async function destroy(ctx: any) {
109
98
  const tableId = getTableId(ctx)
110
99
  let response, row
111
100
  if (inputs.rows) {
112
- let { rows } = await quotas.addQuery(
113
- () => pickApi(tableId).bulkDestroy(ctx),
114
- {
115
- datasourceId: tableId,
116
- }
101
+ let { rows } = await quotas.addQuery(() =>
102
+ pickApi(tableId).bulkDestroy(ctx)
117
103
  )
118
104
  await quotas.removeRows(rows.length)
119
105
  response = rows
@@ -121,9 +107,7 @@ export async function destroy(ctx: any) {
121
107
  ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
122
108
  }
123
109
  } else {
124
- let resp = await quotas.addQuery(() => pickApi(tableId).destroy(ctx), {
125
- datasourceId: tableId,
126
- })
110
+ let resp = await quotas.addQuery(() => pickApi(tableId).destroy(ctx))
127
111
  await quotas.removeRow()
128
112
  response = resp.response
129
113
  row = resp.row
@@ -139,9 +123,7 @@ export async function search(ctx: any) {
139
123
  const tableId = getTableId(ctx)
140
124
  try {
141
125
  ctx.status = 200
142
- ctx.body = await quotas.addQuery(() => pickApi(tableId).search(ctx), {
143
- datasourceId: tableId,
144
- })
126
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).search(ctx))
145
127
  } catch (err) {
146
128
  ctx.throw(400, err)
147
129
  }
@@ -159,11 +141,8 @@ export async function validate(ctx: any) {
159
141
  export async function fetchEnrichedRow(ctx: any) {
160
142
  const tableId = getTableId(ctx)
161
143
  try {
162
- ctx.body = await quotas.addQuery(
163
- () => pickApi(tableId).fetchEnrichedRow(ctx),
164
- {
165
- datasourceId: tableId,
166
- }
144
+ ctx.body = await quotas.addQuery(() =>
145
+ pickApi(tableId).fetchEnrichedRow(ctx)
167
146
  )
168
147
  } catch (err) {
169
148
  ctx.throw(400, err)
@@ -173,9 +152,7 @@ export async function fetchEnrichedRow(ctx: any) {
173
152
  export const exportRows = async (ctx: any) => {
174
153
  const tableId = getTableId(ctx)
175
154
  try {
176
- ctx.body = await quotas.addQuery(() => pickApi(tableId).exportRows(ctx), {
177
- datasourceId: tableId,
178
- })
155
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).exportRows(ctx))
179
156
  } catch (err) {
180
157
  ctx.throw(400, err)
181
158
  }
@@ -145,9 +145,7 @@ export async function destroy(ctx: any) {
145
145
  await db.bulkDocs(
146
146
  rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
147
147
  )
148
- await quotas.removeRows(rows.rows.length, {
149
- tableId: ctx.params.tableId,
150
- })
148
+ await quotas.removeRows(rows.rows.length)
151
149
 
152
150
  // update linked rows
153
151
  await updateLinks({
@@ -148,9 +148,7 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
148
148
  finalData.push(row)
149
149
  }
150
150
 
151
- await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {
152
- tableId: table._id,
153
- })
151
+ await quotas.addRows(finalData.length, () => db.bulkDocs(finalData))
154
152
  await events.rows.imported(table, "csv", finalData.length)
155
153
  return table
156
154
  }
@@ -34,13 +34,18 @@ describe("/rows", () => {
34
34
  .expect(status)
35
35
 
36
36
  const getRowUsage = async () => {
37
- const { total } = await config.doInContext(null, () => quotas.getCurrentUsageValues(QuotaUsageType.STATIC, StaticQuotaName.ROWS))
38
- return total
37
+ return config.doInContext(null, () =>
38
+ quotas.getCurrentUsageValue(QuotaUsageType.STATIC, StaticQuotaName.ROWS)
39
+ )
39
40
  }
40
41
 
41
42
  const getQueryUsage = async () => {
42
- const { total } = await config.doInContext(null, () => quotas.getCurrentUsageValues(QuotaUsageType.MONTHLY, MonthlyQuotaName.QUERIES))
43
- return total
43
+ return config.doInContext(null, () =>
44
+ quotas.getCurrentUsageValue(
45
+ QuotaUsageType.MONTHLY,
46
+ MonthlyQuotaName.QUERIES
47
+ )
48
+ )
44
49
  }
45
50
 
46
51
  const assertRowUsage = async expected => {
@@ -55,26 +60,26 @@ describe("/rows", () => {
55
60
 
56
61
  describe("save, load, update", () => {
57
62
  it("returns a success message when the row is created", async () => {
58
- const rowUsage = await getRowUsage()
59
- const queryUsage = await getQueryUsage()
60
-
61
- const res = await request
62
- .post(`/api/${row.tableId}/rows`)
63
- .send(row)
64
- .set(config.defaultHeaders())
65
- .expect('Content-Type', /json/)
66
- .expect(200)
67
- expect(res.res.statusMessage).toEqual(`${table.name} saved successfully`)
68
- expect(res.body.name).toEqual("Test Contact")
69
- expect(res.body._rev).toBeDefined()
70
- await assertRowUsage(rowUsage + 1)
71
- await assertQueryUsage(queryUsage + 1)
63
+ // const rowUsage = await getRowUsage()
64
+ // const queryUsage = await getQueryUsage()
65
+ //
66
+ // const res = await request
67
+ // .post(`/api/${row.tableId}/rows`)
68
+ // .send(row)
69
+ // .set(config.defaultHeaders())
70
+ // .expect('Content-Type', /json/)
71
+ // .expect(200)
72
+ // expect(res.res.statusMessage).toEqual(`${table.name} saved successfully`)
73
+ // expect(res.body.name).toEqual("Test Contact")
74
+ // expect(res.body._rev).toBeDefined()
75
+ // await assertRowUsage(rowUsage + 1)
76
+ // await assertQueryUsage(queryUsage + 1)
72
77
  })
73
78
 
74
79
  it("updates a row successfully", async () => {
75
80
  const existing = await config.createRow()
76
- const rowUsage = await getRowUsage()
77
- const queryUsage = await getQueryUsage()
81
+ // const rowUsage = await getRowUsage()
82
+ // const queryUsage = await getQueryUsage()
78
83
 
79
84
  const res = await request
80
85
  .post(`/api/${table._id}/rows`)
@@ -92,8 +97,8 @@ describe("/rows", () => {
92
97
  `${table.name} updated successfully.`
93
98
  )
94
99
  expect(res.body.name).toEqual("Updated Name")
95
- await assertRowUsage(rowUsage)
96
- await assertQueryUsage(queryUsage + 1)
100
+ // await assertRowUsage(rowUsage)
101
+ // await assertQueryUsage(queryUsage + 1)
97
102
  })
98
103
 
99
104
  it("should load a row", async () => {
@@ -66,9 +66,9 @@ exports.run = async function ({ inputs, appId, emitter }) {
66
66
  }
67
67
  const tableId = inputs.row.tableId
68
68
 
69
- // clear any undefined, null or empty string properties so that they aren't updated
69
+ // clear any falsy properties so that they aren't updated
70
70
  for (let propKey of Object.keys(inputs.row)) {
71
- if (inputs.row[propKey] == null || inputs.row[propKey] === "") {
71
+ if (!inputs.row[propKey] || inputs.row[propKey] === "") {
72
72
  delete inputs.row[propKey]
73
73
  }
74
74
  }
@@ -29,11 +29,16 @@ describe("Run through some parts of the automations system", () => {
29
29
  afterAll(setup.afterAll)
30
30
 
31
31
  it("should be able to init in builder", async () => {
32
- await triggers.externalTrigger(basicAutomation(), { a: 1, appId: "app_123" })
32
+ await triggers.externalTrigger(basicAutomation(), { a: 1 })
33
33
  await wait(100)
34
34
  expect(thread.execute).toHaveBeenCalled()
35
35
  })
36
36
 
37
+ it("should be able to init in prod", async () => {
38
+ await triggers.externalTrigger(basicAutomation(), { a: 1 })
39
+ await wait(100)
40
+ })
41
+
37
42
  it("should check coercion", async () => {
38
43
  const table = await config.createTable()
39
44
  const automation = basicAutomation()
@@ -13,7 +13,7 @@ import {
13
13
  getAppId,
14
14
  getProdAppDB,
15
15
  } from "@budibase/backend-core/context"
16
- import { context } from "@budibase/backend-core"
16
+ import { tenancy } from "@budibase/backend-core"
17
17
  import { quotas } from "@budibase/pro"
18
18
  import { Automation } from "@budibase/types"
19
19
 
@@ -28,14 +28,12 @@ const jobMessage = (job: any, message: string) => {
28
28
 
29
29
  export async function processEvent(job: any) {
30
30
  try {
31
- const automationId = job.data.automation._id
32
31
  console.log(jobMessage(job, "running"))
33
32
  // need to actually await these so that an error can be captured properly
34
- return await context.doInContext(job.data.event.appId, async () => {
33
+ const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
34
+ return await tenancy.doInTenant(tenantId, async () => {
35
35
  const runFn = () => Runner.run(job)
36
- return quotas.addAutomation(runFn, {
37
- automationId,
38
- })
36
+ return quotas.addAutomation(runFn)
39
37
  })
40
38
  } catch (err) {
41
39
  const errJson = JSON.stringify(err)
package/src/db/utils.js CHANGED
@@ -34,6 +34,8 @@ const DocumentType = {
34
34
  INSTANCE: "inst",
35
35
  LAYOUT: "layout",
36
36
  SCREEN: "screen",
37
+ DATASOURCE: "datasource",
38
+ DATASOURCE_PLUS: "datasource_plus",
37
39
  QUERY: "query",
38
40
  DEPLOYMENTS: "deployments",
39
41
  METADATA: "metadata",
@@ -8,7 +8,7 @@ import {
8
8
  accounts,
9
9
  db as dbUtils,
10
10
  } from "@budibase/backend-core"
11
- import { QuotaUsage } from "@budibase/types"
11
+ import { QuotaUsage } from "@budibase/pro"
12
12
  import {
13
13
  CloudAccount,
14
14
  App,
@@ -0,0 +1,12 @@
1
+ import { tenancy, logging } from "@budibase/backend-core"
2
+ import { plugins } from "@budibase/pro"
3
+
4
+ export const run = async () => {
5
+ try {
6
+ await tenancy.doInTenant(tenancy.DEFAULT_TENANT_ID, async () => {
7
+ await plugins.checkPluginQuotas()
8
+ })
9
+ } catch (err) {
10
+ logging.logAlert("Failed to update plugin quotas", err)
11
+ }
12
+ }
@@ -1,15 +1,20 @@
1
1
  import { runQuotaMigration } from "./usageQuotas"
2
2
  import * as syncApps from "./usageQuotas/syncApps"
3
3
  import * as syncRows from "./usageQuotas/syncRows"
4
- import * as syncPlugins from "./usageQuotas/syncPlugins"
5
4
 
6
5
  /**
7
- * Synchronise quotas to the state of the db.
6
+ * Date:
7
+ * January 2022
8
+ *
9
+ * Description:
10
+ * Synchronise the app and row quotas to the state of the db after it was
11
+ * discovered that the quota resets were still in place and the row quotas
12
+ * weren't being decremented correctly.
8
13
  */
14
+
9
15
  export const run = async () => {
10
16
  await runQuotaMigration(async () => {
11
17
  await syncApps.run()
12
18
  await syncRows.run()
13
- await syncPlugins.run()
14
19
  })
15
20
  }
@@ -2,13 +2,11 @@ const TestConfig = require("../../../tests/utilities/TestConfiguration")
2
2
 
3
3
  const syncApps = jest.fn()
4
4
  const syncRows = jest.fn()
5
- const syncPlugins = jest.fn()
6
5
 
7
6
  jest.mock("../usageQuotas/syncApps", () => ({ run: syncApps }) )
8
7
  jest.mock("../usageQuotas/syncRows", () => ({ run: syncRows }) )
9
- jest.mock("../usageQuotas/syncPlugins", () => ({ run: syncPlugins }) )
10
8
 
11
- const migration = require("../syncQuotas")
9
+ const migration = require("../quotas1")
12
10
 
13
11
  describe("run", () => {
14
12
  let config = new TestConfig(false)
@@ -19,10 +17,9 @@ describe("run", () => {
19
17
 
20
18
  afterAll(config.end)
21
19
 
22
- it("run", async () => {
20
+ it("runs ", async () => {
23
21
  await migration.run()
24
22
  expect(syncApps).toHaveBeenCalledTimes(1)
25
23
  expect(syncRows).toHaveBeenCalledTimes(1)
26
- expect(syncPlugins).toHaveBeenCalledTimes(1)
27
24
  })
28
25
  })
@@ -5,6 +5,7 @@ import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
5
5
 
6
6
  export const run = async () => {
7
7
  // get app count
8
+ // @ts-ignore
8
9
  const devApps = await getAllApps({ dev: true })
9
10
  const appCount = devApps ? devApps.length : 0
10
11
 
@@ -2,28 +2,19 @@ import { getTenantId } from "@budibase/backend-core/tenancy"
2
2
  import { getAllApps } from "@budibase/backend-core/db"
3
3
  import { getUniqueRows } from "../../../utilities/usageQuota/rows"
4
4
  import { quotas } from "@budibase/pro"
5
- import { StaticQuotaName, QuotaUsageType } from "@budibase/types"
5
+ import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
6
6
 
7
7
  export const run = async () => {
8
8
  // get all rows in all apps
9
+ // @ts-ignore
9
10
  const allApps = await getAllApps({ all: true })
11
+ // @ts-ignore
10
12
  const appIds = allApps ? allApps.map((app: { appId: any }) => app.appId) : []
11
- const { appRows } = await getUniqueRows(appIds)
12
-
13
- // get the counts per app
14
- const counts: { [key: string]: number } = {}
15
- let rowCount = 0
16
- Object.entries(appRows).forEach(([appId, rows]) => {
17
- counts[appId] = rows.length
18
- rowCount += rows.length
19
- })
13
+ const rows = await getUniqueRows(appIds)
14
+ const rowCount = rows ? rows.length : 0
20
15
 
21
16
  // sync row count
22
17
  const tenantId = getTenantId()
23
18
  console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`)
24
- await quotas.setUsagePerApp(
25
- counts,
26
- StaticQuotaName.ROWS,
27
- QuotaUsageType.STATIC
28
- )
19
+ await quotas.setUsage(rowCount, StaticQuotaName.ROWS, QuotaUsageType.STATIC)
29
20
  }
@@ -2,7 +2,6 @@ import TestConfig from "../../../../tests/utilities/TestConfiguration"
2
2
  import * as syncRows from "../syncRows"
3
3
  import { quotas } from "@budibase/pro"
4
4
  import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
5
- const { getProdAppID } = require("@budibase/backend-core/db")
6
5
 
7
6
  describe("syncRows", () => {
8
7
  let config = new TestConfig(false)
@@ -23,11 +22,10 @@ describe("syncRows", () => {
23
22
  expect(usageDoc.usageQuota.rows).toEqual(300)
24
23
 
25
24
  // app 1
26
- const app1 = config.app
27
25
  await config.createTable()
28
26
  await config.createRow()
29
27
  // app 2
30
- const app2 = await config.createApp("second-app")
28
+ await config.createApp("second-app")
31
29
  await config.createTable()
32
30
  await config.createRow()
33
31
  await config.createRow()
@@ -38,12 +36,6 @@ describe("syncRows", () => {
38
36
  // assert the migration worked
39
37
  usageDoc = await quotas.getQuotaUsage()
40
38
  expect(usageDoc.usageQuota.rows).toEqual(3)
41
- expect(usageDoc.apps?.[getProdAppID(app1.appId)].usageQuota.rows).toEqual(
42
- 1
43
- )
44
- expect(usageDoc.apps?.[getProdAppID(app2.appId)].usageQuota.rows).toEqual(
45
- 2
46
- )
47
39
  })
48
40
  })
49
41
  })
@@ -4,9 +4,11 @@ import env from "../environment"
4
4
 
5
5
  // migration functions
6
6
  import * as userEmailViewCasing from "./functions/userEmailViewCasing"
7
- import * as syncQuotas from "./functions/syncQuotas"
7
+ import * as quota1 from "./functions/quotas1"
8
8
  import * as appUrls from "./functions/appUrls"
9
9
  import * as backfill from "./functions/backfill"
10
+ import * as pluginCount from "./functions/pluginCount"
11
+
10
12
  /**
11
13
  * Populate the migration function and additional configuration from
12
14
  * the static migration definitions.
@@ -24,10 +26,10 @@ export const buildMigrations = () => {
24
26
  })
25
27
  break
26
28
  }
27
- case MigrationName.SYNC_QUOTAS: {
29
+ case MigrationName.QUOTAS_1: {
28
30
  serverMigrations.push({
29
31
  ...definition,
30
- fn: syncQuotas.run,
32
+ fn: quota1.run,
31
33
  })
32
34
  break
33
35
  }
@@ -67,6 +69,16 @@ export const buildMigrations = () => {
67
69
  })
68
70
  break
69
71
  }
72
+ case MigrationName.PLUGIN_COUNT: {
73
+ if (env.SELF_HOSTED) {
74
+ serverMigrations.push({
75
+ ...definition,
76
+ fn: pluginCount.run,
77
+ silent: !!env.SELF_HOSTED,
78
+ preventRetry: false,
79
+ })
80
+ }
81
+ }
70
82
  }
71
83
  }
72
84
 
@@ -4,6 +4,7 @@ import {
4
4
  tenancy,
5
5
  DocumentType,
6
6
  context,
7
+ db,
7
8
  } from "@budibase/backend-core"
8
9
  import TestConfig from "../../tests/utilities/TestConfiguration"
9
10
  import structures from "../../tests/utilities/structures"
@@ -2,7 +2,6 @@ const { getRowParams, USER_METDATA_PREFIX } = require("../../db/utils")
2
2
  const {
3
3
  isDevAppID,
4
4
  getDevelopmentAppID,
5
- getProdAppID,
6
5
  doWithDB,
7
6
  } = require("@budibase/backend-core/db")
8
7
 
@@ -53,8 +52,7 @@ const getAppRows = async appId => {
53
52
  * Rows duplicates may exist across apps due to data import so they are not filtered out.
54
53
  */
55
54
  exports.getUniqueRows = async appIds => {
56
- let uniqueRows = [],
57
- rowsByApp = {}
55
+ let uniqueRows = []
58
56
  const pairs = getAppPairs(appIds)
59
57
 
60
58
  for (let pair of Object.values(pairs)) {
@@ -75,10 +73,8 @@ exports.getUniqueRows = async appIds => {
75
73
  // this can't be done on all rows because app import results in
76
74
  // duplicate row ids across apps
77
75
  // the array pre-concat is important to avoid stack overflow
78
- const prodId = getProdAppID(pair.devId || pair.prodId)
79
- rowsByApp[prodId] = [...new Set(appRows)]
80
- uniqueRows = uniqueRows.concat(rowsByApp[prodId])
76
+ uniqueRows = uniqueRows.concat([...new Set(appRows)])
81
77
  }
82
78
 
83
- return { rows: uniqueRows, appRows: rowsByApp }
79
+ return uniqueRows
84
80
  }