@budibase/server 2.0.29 → 2.0.30-alpha.0

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 (200) hide show
  1. package/builder/assets/{index.530ce8a0.js → index.ae93bd4f.js} +261 -261
  2. package/builder/assets/{index.dfa4073c.css → index.e56da48a.css} +2 -2
  3. package/builder/index.html +2 -2
  4. package/coverage/clover.xml +344 -341
  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 +2 -2
  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 +10 -16
  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/plugins.js.html +1 -1
  137. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +13 -13
  138. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  139. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  140. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  141. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  142. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +38 -38
  143. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +10 -10
  144. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  145. package/coverage/lcov-report/utilities/security.js.html +1 -1
  146. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  147. package/coverage/lcov-report/utilities/usageQuota/index.html +14 -14
  148. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +23 -11
  149. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  150. package/coverage/lcov-report/utilities/users.js.html +1 -1
  151. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  152. package/coverage/lcov.info +619 -614
  153. package/dist/api/controllers/application.js +2 -2
  154. package/dist/api/controllers/dev.js +1 -1
  155. package/dist/api/controllers/query/index.js +6 -2
  156. package/dist/api/controllers/row/index.js +30 -10
  157. package/dist/api/controllers/static/templates/preview.hbs +10 -0
  158. package/dist/api/controllers/table/internal.js +8 -2
  159. package/dist/api/controllers/table/utils.js +3 -1
  160. package/dist/automations/steps/updateRow.js +2 -2
  161. package/dist/automations/utils.js +5 -3
  162. package/dist/db/utils.js +1 -1
  163. package/dist/index.js +1 -0
  164. package/dist/integrations/rest.js +39 -2
  165. package/dist/migrations/functions/{quotas1.js → syncQuotas.js} +3 -7
  166. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -1
  167. package/dist/migrations/functions/{pluginCount.js → usageQuotas/syncPlugins.js} +1 -3
  168. package/dist/migrations/functions/usageQuotas/syncRows.js +9 -5
  169. package/dist/migrations/index.js +3 -9
  170. package/dist/package.json +7 -7
  171. package/dist/tsconfig.build.tsbuildinfo +1 -1
  172. package/dist/utilities/usageQuota/rows.js +6 -4
  173. package/package.json +8 -8
  174. package/src/api/controllers/application.ts +2 -2
  175. package/src/api/controllers/dev.js +1 -1
  176. package/src/api/controllers/query/index.ts +7 -2
  177. package/src/api/controllers/row/index.ts +36 -13
  178. package/src/api/controllers/static/templates/preview.hbs +10 -0
  179. package/src/api/controllers/table/internal.ts +5 -2
  180. package/src/api/controllers/table/utils.ts +3 -1
  181. package/src/api/routes/tests/row.spec.js +22 -27
  182. package/src/automations/steps/updateRow.js +2 -2
  183. package/src/automations/tests/automation.spec.js +1 -6
  184. package/src/automations/utils.ts +6 -4
  185. package/src/db/utils.js +0 -2
  186. package/src/definitions/datasource.ts +1 -0
  187. package/src/index.ts +1 -0
  188. package/src/integrations/rest.ts +18 -2
  189. package/src/integrations/tests/rest.spec.ts +9 -9
  190. package/src/migrations/functions/backfill/global.ts +1 -1
  191. package/src/migrations/functions/{quotas1.ts → syncQuotas.ts} +3 -8
  192. package/src/migrations/functions/tests/{quotas1.spec.js → syncQuotas.spec.js} +5 -2
  193. package/src/migrations/functions/usageQuotas/syncApps.ts +0 -1
  194. package/src/migrations/functions/usageQuotas/syncPlugins.ts +10 -0
  195. package/src/migrations/functions/usageQuotas/syncRows.ts +15 -6
  196. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +9 -1
  197. package/src/migrations/index.ts +3 -15
  198. package/src/migrations/tests/index.spec.ts +0 -1
  199. package/src/utilities/usageQuota/rows.js +7 -3
  200. package/src/migrations/functions/pluginCount.ts +0 -12
@@ -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, doWithDB, } = require("@budibase/backend-core/db");
12
+ const { isDevAppID, getDevelopmentAppID, getProdAppID, 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 = [];
56
+ let uniqueRows = [], rowsByApp = {};
57
57
  const pairs = getAppPairs(appIds);
58
58
  for (let pair of Object.values(pairs)) {
59
59
  let appRows = [];
@@ -73,7 +73,9 @@ 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
- uniqueRows = uniqueRows.concat([...new Set(appRows)]);
76
+ const prodId = getProdAppID(pair.devId || pair.prodId);
77
+ rowsByApp[prodId] = [...new Set(appRows)];
78
+ uniqueRows = uniqueRows.concat(rowsByApp[prodId]);
77
79
  }
78
- return uniqueRows;
80
+ return { rows: uniqueRows, appRows: rowsByApp };
79
81
  });
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.29",
4
+ "version": "2.0.30-alpha.0",
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.29",
81
- "@budibase/client": "^2.0.29",
82
- "@budibase/pro": "2.0.28",
83
- "@budibase/string-templates": "^2.0.29",
84
- "@budibase/types": "^2.0.29",
80
+ "@budibase/backend-core": "2.0.30-alpha.0",
81
+ "@budibase/client": "2.0.30-alpha.0",
82
+ "@budibase/pro": "2.0.29",
83
+ "@budibase/string-templates": "2.0.30-alpha.0",
84
+ "@budibase/types": "2.0.30-alpha.0",
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.6",
149
+ "vm2": "3.9.11",
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": "855990ae0050c1f43ceb6fca36fd5aeaba8d6740"
202
+ "gitHead": "d0200a093e9d0030f1194c2b0084f775c76a7121"
203
203
  }
@@ -359,7 +359,7 @@ const appPostCreate = async (ctx: any, app: App) => {
359
359
  await creationEvents(ctx.request, app)
360
360
  // app import & template creation
361
361
  if (ctx.request.body.useTemplate === "true") {
362
- const rows = await getUniqueRows([app.appId])
362
+ const { rows } = await getUniqueRows([app.appId])
363
363
  const rowCount = rows ? rows.length : 0
364
364
  if (rowCount) {
365
365
  try {
@@ -493,7 +493,7 @@ const destroyApp = async (ctx: any) => {
493
493
  }
494
494
 
495
495
  const preDestroyApp = async (ctx: any) => {
496
- const rows = await getUniqueRows([ctx.params.appId])
496
+ const { rows } = await getUniqueRows([ctx.params.appId])
497
497
  ctx.rowCount = rows.length
498
498
  }
499
499
 
@@ -103,7 +103,7 @@ exports.revert = async ctx => {
103
103
  target: appId,
104
104
  })
105
105
  try {
106
- if (!env.isTest()) {
106
+ if (env.COUCH_DB_URL) {
107
107
  // in-memory db stalls on rollback
108
108
  await replication.rollback()
109
109
  }
@@ -153,7 +153,10 @@ export async function preview(ctx: any) {
153
153
  auth: { ...authConfigCtx },
154
154
  },
155
155
  })
156
- const { rows, keys, info, extra } = await quotas.addQuery(runFn)
156
+
157
+ const { rows, keys, info, extra } = await quotas.addQuery(runFn, {
158
+ datasourceId: datasource._id,
159
+ })
157
160
  const schemaFields: any = {}
158
161
  if (rows?.length > 0) {
159
162
  for (let key of [...new Set(keys)] as string[]) {
@@ -234,7 +237,9 @@ async function execute(
234
237
  },
235
238
  })
236
239
 
237
- const { rows, pagination, extra } = await quotas.addQuery(runFn)
240
+ const { rows, pagination, extra } = await quotas.addQuery(runFn, {
241
+ datasourceId: datasource._id,
242
+ })
238
243
  // remove the raw from execution incase transformer being used to hide data
239
244
  if (extra?.raw) {
240
245
  delete extra.raw
@@ -31,8 +31,11 @@ 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)
34
+ const { row, table } = await quotas.addQuery(
35
+ () => pickApi(tableId).patch(ctx),
36
+ {
37
+ datasourceId: tableId,
38
+ }
36
39
  )
37
40
  ctx.status = 200
38
41
  ctx.eventEmitter &&
@@ -54,7 +57,9 @@ export const save = async (ctx: any) => {
54
57
  }
55
58
  try {
56
59
  const { row, table } = await quotas.addRow(() =>
57
- quotas.addQuery(() => pickApi(tableId).save(ctx))
60
+ quotas.addQuery(() => pickApi(tableId).save(ctx), {
61
+ datasourceId: tableId,
62
+ })
58
63
  )
59
64
  ctx.status = 200
60
65
  ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
@@ -68,7 +73,9 @@ export const save = async (ctx: any) => {
68
73
  export async function fetchView(ctx: any) {
69
74
  const tableId = getTableId(ctx)
70
75
  try {
71
- ctx.body = await quotas.addQuery(() => pickApi(tableId).fetchView(ctx))
76
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).fetchView(ctx), {
77
+ datasourceId: tableId,
78
+ })
72
79
  } catch (err) {
73
80
  ctx.throw(400, err)
74
81
  }
@@ -77,7 +84,9 @@ export async function fetchView(ctx: any) {
77
84
  export async function fetch(ctx: any) {
78
85
  const tableId = getTableId(ctx)
79
86
  try {
80
- ctx.body = await quotas.addQuery(() => pickApi(tableId).fetch(ctx))
87
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).fetch(ctx), {
88
+ datasourceId: tableId,
89
+ })
81
90
  } catch (err) {
82
91
  ctx.throw(400, err)
83
92
  }
@@ -86,7 +95,9 @@ export async function fetch(ctx: any) {
86
95
  export async function find(ctx: any) {
87
96
  const tableId = getTableId(ctx)
88
97
  try {
89
- ctx.body = await quotas.addQuery(() => pickApi(tableId).find(ctx))
98
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).find(ctx), {
99
+ datasourceId: tableId,
100
+ })
90
101
  } catch (err) {
91
102
  ctx.throw(400, err)
92
103
  }
@@ -98,8 +109,11 @@ export async function destroy(ctx: any) {
98
109
  const tableId = getTableId(ctx)
99
110
  let response, row
100
111
  if (inputs.rows) {
101
- let { rows } = await quotas.addQuery(() =>
102
- pickApi(tableId).bulkDestroy(ctx)
112
+ let { rows } = await quotas.addQuery(
113
+ () => pickApi(tableId).bulkDestroy(ctx),
114
+ {
115
+ datasourceId: tableId,
116
+ }
103
117
  )
104
118
  await quotas.removeRows(rows.length)
105
119
  response = rows
@@ -107,7 +121,9 @@ export async function destroy(ctx: any) {
107
121
  ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
108
122
  }
109
123
  } else {
110
- let resp = await quotas.addQuery(() => pickApi(tableId).destroy(ctx))
124
+ let resp = await quotas.addQuery(() => pickApi(tableId).destroy(ctx), {
125
+ datasourceId: tableId,
126
+ })
111
127
  await quotas.removeRow()
112
128
  response = resp.response
113
129
  row = resp.row
@@ -123,7 +139,9 @@ export async function search(ctx: any) {
123
139
  const tableId = getTableId(ctx)
124
140
  try {
125
141
  ctx.status = 200
126
- ctx.body = await quotas.addQuery(() => pickApi(tableId).search(ctx))
142
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).search(ctx), {
143
+ datasourceId: tableId,
144
+ })
127
145
  } catch (err) {
128
146
  ctx.throw(400, err)
129
147
  }
@@ -141,8 +159,11 @@ export async function validate(ctx: any) {
141
159
  export async function fetchEnrichedRow(ctx: any) {
142
160
  const tableId = getTableId(ctx)
143
161
  try {
144
- ctx.body = await quotas.addQuery(() =>
145
- pickApi(tableId).fetchEnrichedRow(ctx)
162
+ ctx.body = await quotas.addQuery(
163
+ () => pickApi(tableId).fetchEnrichedRow(ctx),
164
+ {
165
+ datasourceId: tableId,
166
+ }
146
167
  )
147
168
  } catch (err) {
148
169
  ctx.throw(400, err)
@@ -152,7 +173,9 @@ export async function fetchEnrichedRow(ctx: any) {
152
173
  export const exportRows = async (ctx: any) => {
153
174
  const tableId = getTableId(ctx)
154
175
  try {
155
- ctx.body = await quotas.addQuery(() => pickApi(tableId).exportRows(ctx))
176
+ ctx.body = await quotas.addQuery(() => pickApi(tableId).exportRows(ctx), {
177
+ datasourceId: tableId,
178
+ })
156
179
  } catch (err) {
157
180
  ctx.throw(400, err)
158
181
  }
@@ -56,6 +56,16 @@
56
56
  return
57
57
  }
58
58
 
59
+ // If this is a custom event, try and handle it
60
+ if (parsed.runtimeEvent) {
61
+ const { name, payload } = parsed
62
+ if (window.handleBuilderRuntimeEvent) {
63
+ window.handleBuilderRuntimeEvent(name, payload)
64
+ }
65
+ return
66
+ }
67
+
68
+ // Otherwise this is a full reload message
59
69
  // Extract data from message
60
70
  const {
61
71
  selectedComponentId,
@@ -18,6 +18,7 @@ import { Table } from "@budibase/types"
18
18
  import { quotas } from "@budibase/pro"
19
19
  import { isEqual } from "lodash"
20
20
  import { cloneDeep } from "lodash/fp"
21
+ import env from "../../../environment"
21
22
 
22
23
  function checkAutoColumns(table: Table, oldTable: Table) {
23
24
  if (!table.schema) {
@@ -153,7 +154,9 @@ export async function destroy(ctx: any) {
153
154
  await db.bulkDocs(
154
155
  rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
155
156
  )
156
- await quotas.removeRows(rows.rows.length)
157
+ await quotas.removeRows(rows.rows.length, {
158
+ tableId: ctx.params.tableId,
159
+ })
157
160
 
158
161
  // update linked rows
159
162
  await updateLinks({
@@ -165,7 +168,7 @@ export async function destroy(ctx: any) {
165
168
  await db.remove(tableToDelete)
166
169
 
167
170
  // remove table search index
168
- if (!isTest()) {
171
+ if (!isTest() || env.COUCH_DB_URL) {
169
172
  const currentIndexes = await db.getIndexes()
170
173
  const existingIndex = currentIndexes.indexes.find(
171
174
  (existing: any) => existing.name === `search:${ctx.params.tableId}`
@@ -148,7 +148,9 @@ 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))
151
+ await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {
152
+ tableId: table._id,
153
+ })
152
154
  await events.rows.imported(table, "csv", finalData.length)
153
155
  return table
154
156
  }
@@ -34,18 +34,13 @@ describe("/rows", () => {
34
34
  .expect(status)
35
35
 
36
36
  const getRowUsage = async () => {
37
- return config.doInContext(null, () =>
38
- quotas.getCurrentUsageValue(QuotaUsageType.STATIC, StaticQuotaName.ROWS)
39
- )
37
+ const { total } = await config.doInContext(null, () => quotas.getCurrentUsageValues(QuotaUsageType.STATIC, StaticQuotaName.ROWS))
38
+ return total
40
39
  }
41
40
 
42
41
  const getQueryUsage = async () => {
43
- return config.doInContext(null, () =>
44
- quotas.getCurrentUsageValue(
45
- QuotaUsageType.MONTHLY,
46
- MonthlyQuotaName.QUERIES
47
- )
48
- )
42
+ const { total } = await config.doInContext(null, () => quotas.getCurrentUsageValues(QuotaUsageType.MONTHLY, MonthlyQuotaName.QUERIES))
43
+ return total
49
44
  }
50
45
 
51
46
  const assertRowUsage = async expected => {
@@ -60,26 +55,26 @@ describe("/rows", () => {
60
55
 
61
56
  describe("save, load, update", () => {
62
57
  it("returns a success message when the row is created", async () => {
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)
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)
77
72
  })
78
73
 
79
74
  it("updates a row successfully", async () => {
80
75
  const existing = await config.createRow()
81
- // const rowUsage = await getRowUsage()
82
- // const queryUsage = await getQueryUsage()
76
+ const rowUsage = await getRowUsage()
77
+ const queryUsage = await getQueryUsage()
83
78
 
84
79
  const res = await request
85
80
  .post(`/api/${table._id}/rows`)
@@ -97,8 +92,8 @@ describe("/rows", () => {
97
92
  `${table.name} updated successfully.`
98
93
  )
99
94
  expect(res.body.name).toEqual("Updated Name")
100
- // await assertRowUsage(rowUsage)
101
- // await assertQueryUsage(queryUsage + 1)
95
+ await assertRowUsage(rowUsage)
96
+ await assertQueryUsage(queryUsage + 1)
102
97
  })
103
98
 
104
99
  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 falsy properties so that they aren't updated
69
+ // clear any undefined, null or empty string properties so that they aren't updated
70
70
  for (let propKey of Object.keys(inputs.row)) {
71
- if (!inputs.row[propKey] || inputs.row[propKey] === "") {
71
+ if (inputs.row[propKey] == null || inputs.row[propKey] === "") {
72
72
  delete inputs.row[propKey]
73
73
  }
74
74
  }
@@ -29,16 +29,11 @@ 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 })
32
+ await triggers.externalTrigger(basicAutomation(), { a: 1, appId: "app_123" })
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
-
42
37
  it("should check coercion", async () => {
43
38
  const table = await config.createTable()
44
39
  const automation = basicAutomation()
@@ -13,7 +13,7 @@ import {
13
13
  getAppId,
14
14
  getProdAppDB,
15
15
  } from "@budibase/backend-core/context"
16
- import { tenancy } from "@budibase/backend-core"
16
+ import { context } from "@budibase/backend-core"
17
17
  import { quotas } from "@budibase/pro"
18
18
  import { Automation } from "@budibase/types"
19
19
 
@@ -28,12 +28,14 @@ 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
31
32
  console.log(jobMessage(job, "running"))
32
33
  // need to actually await these so that an error can be captured properly
33
- const tenantId = tenancy.getTenantIDFromAppID(job.data.event.appId)
34
- return await tenancy.doInTenant(tenantId, async () => {
34
+ return await context.doInContext(job.data.event.appId, async () => {
35
35
  const runFn = () => Runner.run(job)
36
- return quotas.addAutomation(runFn)
36
+ return quotas.addAutomation(runFn, {
37
+ automationId,
38
+ })
37
39
  })
38
40
  } catch (err) {
39
41
  const errJson = JSON.stringify(err)
package/src/db/utils.js CHANGED
@@ -34,8 +34,6 @@ const DocumentType = {
34
34
  INSTANCE: "inst",
35
35
  LAYOUT: "layout",
36
36
  SCREEN: "screen",
37
- DATASOURCE: "datasource",
38
- DATASOURCE_PLUS: "datasource_plus",
39
37
  QUERY: "query",
40
38
  DEPLOYMENTS: "deployments",
41
39
  METADATA: "metadata",
@@ -31,6 +31,7 @@ export interface BearerAuthConfig {
31
31
 
32
32
  export interface RestConfig {
33
33
  url: string
34
+ rejectUnauthorized: boolean
34
35
  defaultHeaders: {
35
36
  [key: string]: any
36
37
  }
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ function runServer() {
8
8
  checkDevelopmentEnvironment()
9
9
  fixPath()
10
10
  // this will setup http and https proxies form env variables
11
+ process.env.GLOBAL_AGENT_FORCE_GLOBAL_AGENT = "false"
11
12
  bootstrap()
12
13
  require("./app")
13
14
  }
@@ -14,6 +14,7 @@ import {
14
14
  BearerAuthConfig,
15
15
  } from "../definitions/datasource"
16
16
  import { get } from "lodash"
17
+ import * as https from "https"
17
18
  import qs from "querystring"
18
19
  const fetch = require("node-fetch")
19
20
  const { formatBytes } = require("../utilities")
@@ -76,6 +77,11 @@ const SCHEMA: Integration = {
76
77
  required: false,
77
78
  default: {},
78
79
  },
80
+ rejectUnauthorized: {
81
+ type: DatasourceFieldType.BOOLEAN,
82
+ default: true,
83
+ required: false,
84
+ },
79
85
  legacyHttpParser: {
80
86
  display: "Legacy HTTP Support",
81
87
  type: DatasourceFieldType.BOOLEAN,
@@ -218,8 +224,12 @@ class RestIntegration implements IntegrationBase {
218
224
  }
219
225
  }
220
226
 
221
- // make sure the query string is fully encoded
222
- const main = `${path}?${qs.encode(qs.decode(queryString))}`
227
+ if (queryString) {
228
+ // make sure the query string is fully encoded
229
+ queryString = "?" + qs.encode(qs.decode(queryString))
230
+ }
231
+ const main = `${path}${queryString}`
232
+
223
233
  let complete = main
224
234
  if (this.config.url && !main.startsWith("http")) {
225
235
  complete = !this.config.url ? main : `${this.config.url}/${main}`
@@ -381,6 +391,12 @@ class RestIntegration implements IntegrationBase {
381
391
  paginationValues
382
392
  )
383
393
 
394
+ if (this.config.rejectUnauthorized == false) {
395
+ input.agent = new https.Agent({
396
+ rejectUnauthorized: false,
397
+ })
398
+ }
399
+
384
400
  if (this.config.legacyHttpParser) {
385
401
  // https://github.com/nodejs/node/issues/43798
386
402
  input.extraHttpOptions = { insecureHTTPParser: true }
@@ -256,7 +256,7 @@ describe("REST Integration", () => {
256
256
  authConfigId: "c59c14bd1898a43baa08da68959b24686",
257
257
  }
258
258
  await config.integration.read(query)
259
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
259
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/`, {
260
260
  method: "GET",
261
261
  headers: {
262
262
  Authorization: "Basic dXNlcjpwYXNzd29yZA==",
@@ -269,7 +269,7 @@ describe("REST Integration", () => {
269
269
  authConfigId: "0d91d732f34e4befabeff50b392a8ff3",
270
270
  }
271
271
  await config.integration.read(query)
272
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
272
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/`, {
273
273
  method: "GET",
274
274
  headers: {
275
275
  Authorization: "Bearer mytoken",
@@ -327,7 +327,7 @@ describe("REST Integration", () => {
327
327
  },
328
328
  }
329
329
  await config.integration.create(query)
330
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
330
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
331
331
  body: JSON.stringify({
332
332
  [pageParam]: pageValue,
333
333
  [sizeParam]: sizeValue,
@@ -359,7 +359,7 @@ describe("REST Integration", () => {
359
359
  },
360
360
  }
361
361
  await config.integration.create(query)
362
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
362
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
363
363
  body: expect.any(FormData),
364
364
  headers: {},
365
365
  method: "POST",
@@ -390,7 +390,7 @@ describe("REST Integration", () => {
390
390
  },
391
391
  }
392
392
  await config.integration.create(query)
393
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
393
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
394
394
  body: expect.any(URLSearchParams),
395
395
  headers: {},
396
396
  method: "POST",
@@ -456,7 +456,7 @@ describe("REST Integration", () => {
456
456
  },
457
457
  }
458
458
  const res = await config.integration.create(query)
459
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
459
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
460
460
  body: JSON.stringify({
461
461
  [pageParam]: pageValue,
462
462
  [sizeParam]: sizeValue,
@@ -490,7 +490,7 @@ describe("REST Integration", () => {
490
490
  },
491
491
  }
492
492
  const res = await config.integration.create(query)
493
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
493
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
494
494
  body: expect.any(FormData),
495
495
  headers: {},
496
496
  method: "POST",
@@ -523,7 +523,7 @@ describe("REST Integration", () => {
523
523
  },
524
524
  }
525
525
  const res = await config.integration.create(query)
526
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
526
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api`, {
527
527
  body: expect.any(URLSearchParams),
528
528
  headers: {},
529
529
  method: "POST",
@@ -563,7 +563,7 @@ describe("REST Integration", () => {
563
563
  legacyHttpParser: true,
564
564
  })
565
565
  await config.integration.read({})
566
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
566
+ expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/`, {
567
567
  method: "GET",
568
568
  headers: {},
569
569
  extraHttpOptions: {
@@ -8,7 +8,7 @@ import {
8
8
  accounts,
9
9
  db as dbUtils,
10
10
  } from "@budibase/backend-core"
11
- import { QuotaUsage } from "@budibase/pro"
11
+ import { QuotaUsage } from "@budibase/types"
12
12
  import {
13
13
  CloudAccount,
14
14
  App,
@@ -1,20 +1,15 @@
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"
4
5
 
5
6
  /**
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.
7
+ * Synchronise quotas to the state of the db.
13
8
  */
14
-
15
9
  export const run = async () => {
16
10
  await runQuotaMigration(async () => {
17
11
  await syncApps.run()
18
12
  await syncRows.run()
13
+ await syncPlugins.run()
19
14
  })
20
15
  }
@@ -2,11 +2,13 @@ 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()
5
6
 
6
7
  jest.mock("../usageQuotas/syncApps", () => ({ run: syncApps }) )
7
8
  jest.mock("../usageQuotas/syncRows", () => ({ run: syncRows }) )
9
+ jest.mock("../usageQuotas/syncPlugins", () => ({ run: syncPlugins }) )
8
10
 
9
- const migration = require("../quotas1")
11
+ const migration = require("../syncQuotas")
10
12
 
11
13
  describe("run", () => {
12
14
  let config = new TestConfig(false)
@@ -17,9 +19,10 @@ describe("run", () => {
17
19
 
18
20
  afterAll(config.end)
19
21
 
20
- it("runs ", async () => {
22
+ it("run", async () => {
21
23
  await migration.run()
22
24
  expect(syncApps).toHaveBeenCalledTimes(1)
23
25
  expect(syncRows).toHaveBeenCalledTimes(1)
26
+ expect(syncPlugins).toHaveBeenCalledTimes(1)
24
27
  })
25
28
  })
@@ -5,7 +5,6 @@ import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
5
5
 
6
6
  export const run = async () => {
7
7
  // get app count
8
- // @ts-ignore
9
8
  const devApps = await getAllApps({ dev: true })
10
9
  const appCount = devApps ? devApps.length : 0
11
10