@budibase/server 2.0.33 → 2.0.34-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 (277) hide show
  1. package/__mocks__/mongodb.ts +1 -1
  2. package/builder/assets/backups-default.8c011f1b.png +0 -0
  3. package/builder/assets/{index.dfa4073c.css → index.b15ffe95.css} +2 -2
  4. package/builder/assets/{index.ce49a649.js → index.d09d1931.js} +340 -332
  5. package/builder/index.html +2 -2
  6. package/coverage/clover.xml +634 -689
  7. package/coverage/coverage-final.json +34 -36
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/cloud.js.html +74 -62
  11. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/dev.js.html +2 -2
  13. package/coverage/lcov-report/api/controllers/index.html +17 -32
  14. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  20. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/internal.js.html +12 -12
  26. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +15 -15
  28. package/coverage/lcov-report/api/controllers/row/utils.js.html +13 -13
  29. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +12 -9
  31. package/coverage/lcov-report/api/controllers/table/external.js.html +10 -10
  32. package/coverage/lcov-report/api/controllers/table/index.html +16 -16
  33. package/coverage/lcov-report/api/controllers/table/index.js.html +5 -5
  34. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  38. package/coverage/lcov-report/api/controllers/view/index.js.html +3 -3
  39. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  42. package/coverage/lcov-report/api/index.html +1 -1
  43. package/coverage/lcov-report/api/index.js.html +7 -7
  44. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  45. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  46. package/coverage/lcov-report/api/routes/automation.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 +5 -20
  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 +6 -6
  72. package/coverage/lcov-report/automations/bullboard.js.html +17 -92
  73. package/coverage/lcov-report/automations/index.html +18 -18
  74. package/coverage/lcov-report/automations/index.js.html +9 -9
  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 +26 -26
  101. package/coverage/lcov-report/constants/index.html +5 -5
  102. package/coverage/lcov-report/constants/index.js.html +10 -16
  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 +19 -19
  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 +37 -316
  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 +77 -77
  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 +11 -8
  133. package/coverage/lcov-report/utilities/global.js.html +16 -16
  134. package/coverage/lcov-report/utilities/index.html +15 -15
  135. package/coverage/lcov-report/utilities/index.js.html +7 -7
  136. package/coverage/lcov-report/utilities/plugins.js.html +1 -1
  137. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +52 -52
  138. package/coverage/lcov-report/utilities/queue/index.html +21 -21
  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 +54 -39
  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 +2 -2
  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 +1141 -1246
  153. package/dist/api/controllers/application.js +4 -7
  154. package/dist/api/controllers/backup.js +19 -13
  155. package/dist/api/controllers/cloud.js +38 -35
  156. package/dist/api/controllers/deploy/index.js +11 -2
  157. package/dist/api/controllers/dev.js +1 -1
  158. package/dist/api/controllers/query/index.js +7 -2
  159. package/dist/api/controllers/row/index.js +30 -10
  160. package/dist/api/controllers/static/index.js +2 -2
  161. package/dist/api/controllers/static/templates/preview.hbs +10 -0
  162. package/dist/api/controllers/table/bulkFormula.js +4 -3
  163. package/dist/api/controllers/table/external.js +5 -4
  164. package/dist/api/controllers/table/index.js +4 -4
  165. package/dist/api/controllers/table/internal.js +10 -3
  166. package/dist/api/controllers/table/utils.js +7 -49
  167. package/dist/api/controllers/view/index.js +2 -2
  168. package/dist/api/routes/backup.js +34 -7
  169. package/dist/api/routes/index.js +9 -4
  170. package/dist/app.js +14 -0
  171. package/dist/automations/automationUtils.js +2 -2
  172. package/dist/automations/bullboard.js +5 -33
  173. package/dist/automations/index.js +4 -4
  174. package/dist/automations/steps/updateRow.js +2 -2
  175. package/dist/automations/triggers.js +4 -4
  176. package/dist/automations/utils.js +18 -12
  177. package/dist/constants/index.js +4 -5
  178. package/dist/db/utils.js +10 -75
  179. package/dist/index.js +1 -0
  180. package/dist/integrations/arangodb.js +2 -0
  181. package/dist/integrations/base/sqlTable.js +1 -0
  182. package/dist/integrations/mongodb.js +300 -11
  183. package/dist/integrations/rest.js +38 -5
  184. package/dist/migrations/functions/backfill/app/tables.js +5 -8
  185. package/dist/migrations/functions/{quotas1.js → syncQuotas.js} +3 -7
  186. package/dist/migrations/functions/usageQuotas/syncApps.js +0 -1
  187. package/dist/migrations/functions/{pluginCount.js → usageQuotas/syncPlugins.js} +1 -3
  188. package/dist/migrations/functions/usageQuotas/syncRows.js +9 -5
  189. package/dist/migrations/index.js +9 -38
  190. package/dist/package.json +14 -14
  191. package/dist/sdk/app/backups/constants.js +5 -0
  192. package/dist/sdk/app/backups/exports.js +172 -0
  193. package/dist/sdk/app/backups/imports.js +162 -0
  194. package/dist/sdk/app/backups/index.js +29 -0
  195. package/dist/sdk/app/backups/statistics.js +73 -0
  196. package/dist/sdk/app/tables/index.js +61 -0
  197. package/dist/sdk/index.js +15 -0
  198. package/dist/tests/utilities/TestConfiguration.js +4 -2
  199. package/dist/threads/automation.js +12 -17
  200. package/dist/tsconfig.build.tsbuildinfo +1 -1
  201. package/dist/utilities/csvParser.js +1 -0
  202. package/dist/utilities/fileSystem/index.js +3 -95
  203. package/dist/utilities/fileSystem/utilities.js +2 -1
  204. package/dist/utilities/rowProcessor/index.js +5 -0
  205. package/dist/utilities/usageQuota/rows.js +6 -4
  206. package/package.json +15 -15
  207. package/specs/openapi.json +3 -0
  208. package/specs/openapi.yaml +3 -0
  209. package/src/api/controllers/application.ts +5 -12
  210. package/src/api/controllers/{backup.js → backup.ts} +7 -7
  211. package/src/api/controllers/cloud.js +44 -40
  212. package/src/api/controllers/deploy/index.ts +20 -8
  213. package/src/api/controllers/dev.js +1 -1
  214. package/src/api/controllers/query/index.ts +8 -2
  215. package/src/api/controllers/row/index.ts +36 -13
  216. package/src/api/controllers/static/index.ts +2 -2
  217. package/src/api/controllers/static/templates/preview.hbs +10 -0
  218. package/src/api/controllers/table/bulkFormula.js +4 -3
  219. package/src/api/controllers/table/external.js +4 -4
  220. package/src/api/controllers/table/index.js +4 -4
  221. package/src/api/controllers/table/internal.ts +8 -9
  222. package/src/api/controllers/table/utils.ts +4 -53
  223. package/src/api/controllers/view/index.js +2 -2
  224. package/src/api/routes/backup.ts +10 -0
  225. package/src/api/routes/index.ts +11 -5
  226. package/src/api/routes/tests/backup.spec.js +1 -1
  227. package/src/api/routes/tests/{deployment.spec.js → deployment.spec.ts} +4 -4
  228. package/src/api/routes/tests/row.spec.js +22 -27
  229. package/src/app.ts +15 -0
  230. package/src/automations/automationUtils.js +2 -2
  231. package/src/automations/bullboard.js +8 -33
  232. package/src/automations/index.js +4 -4
  233. package/src/automations/steps/updateRow.js +2 -2
  234. package/src/automations/tests/automation.spec.js +1 -6
  235. package/src/automations/triggers.js +4 -4
  236. package/src/automations/utils.ts +18 -12
  237. package/src/constants/index.js +4 -6
  238. package/src/db/utils.js +17 -110
  239. package/src/definitions/automations.ts +0 -12
  240. package/src/definitions/datasource.ts +1 -0
  241. package/src/index.ts +1 -0
  242. package/src/integrations/arangodb.ts +2 -0
  243. package/src/integrations/base/sqlTable.ts +1 -0
  244. package/src/integrations/mongodb.ts +290 -27
  245. package/src/integrations/rest.ts +17 -5
  246. package/src/integrations/tests/mongo.spec.ts +19 -19
  247. package/src/integrations/tests/rest.spec.ts +38 -22
  248. package/src/migrations/functions/backfill/app/tables.ts +7 -13
  249. package/src/migrations/functions/backfill/global.ts +1 -1
  250. package/src/migrations/functions/{quotas1.ts → syncQuotas.ts} +3 -8
  251. package/src/migrations/functions/tests/{quotas1.spec.js → syncQuotas.spec.js} +5 -2
  252. package/src/migrations/functions/usageQuotas/syncApps.ts +0 -1
  253. package/src/migrations/functions/usageQuotas/syncPlugins.ts +10 -0
  254. package/src/migrations/functions/usageQuotas/syncRows.ts +15 -6
  255. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +9 -1
  256. package/src/migrations/index.ts +20 -45
  257. package/src/migrations/tests/index.spec.ts +0 -1
  258. package/src/sdk/app/backups/constants.ts +2 -0
  259. package/src/sdk/app/backups/exports.ts +171 -0
  260. package/src/sdk/app/backups/imports.ts +169 -0
  261. package/src/sdk/app/backups/index.ts +9 -0
  262. package/src/sdk/app/backups/statistics.ts +78 -0
  263. package/src/sdk/app/tables/index.ts +61 -0
  264. package/src/sdk/index.ts +13 -0
  265. package/src/tests/utilities/TestConfiguration.js +5 -2
  266. package/src/threads/automation.ts +20 -27
  267. package/src/utilities/csvParser.js +1 -0
  268. package/src/utilities/fileSystem/index.js +2 -119
  269. package/src/utilities/fileSystem/utilities.js +2 -0
  270. package/src/utilities/rowProcessor/index.js +5 -0
  271. package/src/utilities/usageQuota/rows.js +7 -3
  272. package/coverage/lcov-report/api/controllers/backup.js.html +0 -142
  273. package/coverage/lcov-report/api/routes/backup.js.html +0 -115
  274. package/dist/automations/listeners.js +0 -102
  275. package/src/api/routes/backup.js +0 -10
  276. package/src/automations/listeners.ts +0 -78
  277. package/src/migrations/functions/pluginCount.ts +0 -12
@@ -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
  }
@@ -5,7 +5,7 @@ require("svelte/register")
5
5
  const send = require("koa-send")
6
6
  const { resolve, join } = require("../../../utilities/centralPath")
7
7
  const uuid = require("uuid")
8
- const { ObjectStoreBuckets } = require("../../../constants")
8
+ const { ObjectStoreBuckets, ATTACHMENT_DIR } = require("../../../constants")
9
9
  const { processString } = require("@budibase/string-templates")
10
10
  const {
11
11
  loadHandlebarsFile,
@@ -90,7 +90,7 @@ export const uploadFile = async function (ctx: any) {
90
90
 
91
91
  return prepareUpload({
92
92
  file,
93
- s3Key: `${ctx.appId}/attachments/${processedFileName}`,
93
+ s3Key: `${ctx.appId}/${ATTACHMENT_DIR}/${processedFileName}`,
94
94
  bucket: ObjectStoreBuckets.APPS,
95
95
  })
96
96
  })
@@ -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,
@@ -1,10 +1,11 @@
1
1
  const { FieldTypes, FormulaTypes } = require("../../../constants")
2
- const { getAllInternalTables, clearColumns } = require("./utils")
2
+ const { clearColumns } = require("./utils")
3
3
  const { doesContainStrings } = require("@budibase/string-templates")
4
4
  const { cloneDeep } = require("lodash/fp")
5
5
  const { isEqual, uniq } = require("lodash")
6
6
  const { updateAllFormulasInTable } = require("../row/staticFormula")
7
7
  const { getAppDB } = require("@budibase/backend-core/context")
8
+ const sdk = require("../../../sdk")
8
9
 
9
10
  function isStaticFormula(column) {
10
11
  return (
@@ -39,7 +40,7 @@ function getFormulaThatUseColumn(table, columnNames) {
39
40
  */
40
41
  async function checkIfFormulaNeedsCleared(table, { oldTable, deletion }) {
41
42
  // start by retrieving all tables, remove the current table from the list
42
- const tables = (await getAllInternalTables()).filter(
43
+ const tables = (await sdk.tables.getAllInternalTables()).filter(
43
44
  tbl => tbl._id !== table._id
44
45
  )
45
46
  const schemaToUse = oldTable ? oldTable.schema : table.schema
@@ -99,7 +100,7 @@ async function updateRelatedFormulaLinksOnTables(
99
100
  ) {
100
101
  const db = getAppDB()
101
102
  // start by retrieving all tables, remove the current table from the list
102
- const tables = (await getAllInternalTables()).filter(
103
+ const tables = (await sdk.tables.getAllInternalTables()).filter(
103
104
  tbl => tbl._id !== table._id
104
105
  )
105
106
  // clone the tables, so we can compare at end
@@ -3,7 +3,6 @@ const {
3
3
  breakExternalTableId,
4
4
  } = require("../../../integrations/utils")
5
5
  const {
6
- getTable,
7
6
  generateForeignKey,
8
7
  generateJunctionTableName,
9
8
  foreignKeyStructure,
@@ -20,6 +19,7 @@ const csvParser = require("../../../utilities/csvParser")
20
19
  const { handleRequest } = require("../row/external")
21
20
  const { getAppDB } = require("@budibase/backend-core/context")
22
21
  const { events } = require("@budibase/backend-core")
22
+ const sdk = require("../../../sdk")
23
23
 
24
24
  async function makeTableRequest(
25
25
  datasource,
@@ -181,7 +181,7 @@ exports.save = async function (ctx) {
181
181
 
182
182
  let oldTable
183
183
  if (ctx.request.body && ctx.request.body._id) {
184
- oldTable = await getTable(ctx.request.body._id)
184
+ oldTable = await sdk.tables.getTable(ctx.request.body._id)
185
185
  }
186
186
 
187
187
  if (hasTypeChanged(tableToSave, oldTable)) {
@@ -281,7 +281,7 @@ exports.save = async function (ctx) {
281
281
  }
282
282
 
283
283
  exports.destroy = async function (ctx) {
284
- const tableToDelete = await getTable(ctx.params.tableId)
284
+ const tableToDelete = await sdk.tables.getTable(ctx.params.tableId)
285
285
  if (!tableToDelete || !tableToDelete.created) {
286
286
  ctx.throw(400, "Cannot delete tables which weren't created in Budibase.")
287
287
  }
@@ -303,7 +303,7 @@ exports.destroy = async function (ctx) {
303
303
  }
304
304
 
305
305
  exports.bulkImport = async function (ctx) {
306
- const table = await getTable(ctx.params.tableId)
306
+ const table = await sdk.tables.getTable(ctx.params.tableId)
307
307
  const { dataImport } = ctx.request.body
308
308
  if (!dataImport || !dataImport.schema || !dataImport.csvString) {
309
309
  ctx.throw(400, "Provided data import information is invalid.")
@@ -4,8 +4,8 @@ const csvParser = require("../../../utilities/csvParser")
4
4
  const { isExternalTable, isSQL } = require("../../../integrations/utils")
5
5
  const { getDatasourceParams } = require("../../../db/utils")
6
6
  const { getAppDB } = require("@budibase/backend-core/context")
7
- const { getTable, getAllInternalTables } = require("./utils")
8
7
  const { events } = require("@budibase/backend-core")
8
+ const sdk = require("../../../sdk")
9
9
 
10
10
  function pickApi({ tableId, table }) {
11
11
  if (table && !tableId) {
@@ -23,7 +23,7 @@ function pickApi({ tableId, table }) {
23
23
  exports.fetch = async function (ctx) {
24
24
  const db = getAppDB()
25
25
 
26
- const internal = await getAllInternalTables()
26
+ const internal = await sdk.tables.getAllInternalTables()
27
27
 
28
28
  const externalTables = await db.allDocs(
29
29
  getDatasourceParams("plus", {
@@ -50,7 +50,7 @@ exports.fetch = async function (ctx) {
50
50
 
51
51
  exports.find = async function (ctx) {
52
52
  const tableId = ctx.params.tableId
53
- ctx.body = await getTable(tableId)
53
+ ctx.body = await sdk.tables.getTable(tableId)
54
54
  }
55
55
 
56
56
  exports.save = async function (ctx) {
@@ -101,7 +101,7 @@ exports.validateCSVSchema = async function (ctx) {
101
101
  const { csvString, schema = {}, tableId } = ctx.request.body
102
102
  let existingTable
103
103
  if (tableId) {
104
- existingTable = await getTable(tableId)
104
+ existingTable = await sdk.tables.getTable(tableId)
105
105
  }
106
106
  let result = await csvParser.parse(csvString, schema)
107
107
  if (existingTable) {
@@ -1,12 +1,7 @@
1
1
  import { updateLinks, EventType } from "../../../db/linkedRows"
2
2
  import { getRowParams, generateTableID } from "../../../db/utils"
3
3
  import { FieldTypes } from "../../../constants"
4
- import {
5
- TableSaveFunctions,
6
- hasTypeChanged,
7
- getTable,
8
- handleDataImport,
9
- } from "./utils"
4
+ import { TableSaveFunctions, hasTypeChanged, handleDataImport } from "./utils"
10
5
  const { getAppDB } = require("@budibase/backend-core/context")
11
6
  import { isTest } from "../../../environment"
12
7
  import {
@@ -18,6 +13,8 @@ import { Table } from "@budibase/types"
18
13
  import { quotas } from "@budibase/pro"
19
14
  import { isEqual } from "lodash"
20
15
  import { cloneDeep } from "lodash/fp"
16
+ import env from "../../../environment"
17
+ import sdk from "../../../sdk"
21
18
 
22
19
  function checkAutoColumns(table: Table, oldTable: Table) {
23
20
  if (!table.schema) {
@@ -153,7 +150,9 @@ export async function destroy(ctx: any) {
153
150
  await db.bulkDocs(
154
151
  rows.rows.map((row: any) => ({ ...row.doc, _deleted: true }))
155
152
  )
156
- await quotas.removeRows(rows.rows.length)
153
+ await quotas.removeRows(rows.rows.length, {
154
+ tableId: ctx.params.tableId,
155
+ })
157
156
 
158
157
  // update linked rows
159
158
  await updateLinks({
@@ -165,7 +164,7 @@ export async function destroy(ctx: any) {
165
164
  await db.remove(tableToDelete)
166
165
 
167
166
  // remove table search index
168
- if (!isTest()) {
167
+ if (!isTest() || env.COUCH_DB_URL) {
169
168
  const currentIndexes = await db.getIndexes()
170
169
  const existingIndex = currentIndexes.indexes.find(
171
170
  (existing: any) => existing.name === `search:${ctx.params.tableId}`
@@ -185,7 +184,7 @@ export async function destroy(ctx: any) {
185
184
  }
186
185
 
187
186
  export async function bulkImport(ctx: any) {
188
- const table = await getTable(ctx.params.tableId)
187
+ const table = await sdk.tables.getTable(ctx.params.tableId)
189
188
  const { dataImport } = ctx.request.body
190
189
  await handleDataImport(ctx.user, table, dataImport)
191
190
  return table
@@ -1,11 +1,5 @@
1
1
  import { transform } from "../../../utilities/csvParser"
2
- import {
3
- getRowParams,
4
- generateRowID,
5
- InternalTables,
6
- getTableParams,
7
- BudibaseInternalDB,
8
- } from "../../../db/utils"
2
+ import { getRowParams, generateRowID, InternalTables } from "../../../db/utils"
9
3
  import { isEqual } from "lodash"
10
4
  import { AutoFieldSubTypes, FieldTypes } from "../../../constants"
11
5
  import {
@@ -17,11 +11,6 @@ import {
17
11
  SwitchableTypes,
18
12
  CanSwitchTypes,
19
13
  } from "../../../constants"
20
- import {
21
- isExternalTable,
22
- breakExternalTableId,
23
- isSQL,
24
- } from "../../../integrations/utils"
25
14
  import { getViews, saveView } from "../view/utils"
26
15
  import viewTemplate from "../view/viewBuilder"
27
16
  const { getAppDB } = require("@budibase/backend-core/context")
@@ -148,7 +137,9 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
148
137
  finalData.push(row)
149
138
  }
150
139
 
151
- await quotas.addRows(finalData.length, () => db.bulkDocs(finalData))
140
+ await quotas.addRows(finalData.length, () => db.bulkDocs(finalData), {
141
+ tableId: table._id,
142
+ })
152
143
  await events.rows.imported(table, "csv", finalData.length)
153
144
  return table
154
145
  }
@@ -254,46 +245,6 @@ class TableSaveFunctions {
254
245
  }
255
246
  }
256
247
 
257
- export async function getAllInternalTables() {
258
- const db = getAppDB()
259
- const internalTables = await db.allDocs(
260
- getTableParams(null, {
261
- include_docs: true,
262
- })
263
- )
264
- return internalTables.rows.map((tableDoc: any) => ({
265
- ...tableDoc.doc,
266
- type: "internal",
267
- sourceId: BudibaseInternalDB._id,
268
- }))
269
- }
270
-
271
- export async function getAllExternalTables(datasourceId: any) {
272
- const db = getAppDB()
273
- const datasource = await db.get(datasourceId)
274
- if (!datasource || !datasource.entities) {
275
- throw "Datasource is not configured fully."
276
- }
277
- return datasource.entities
278
- }
279
-
280
- export async function getExternalTable(datasourceId: any, tableName: any) {
281
- const entities = await getAllExternalTables(datasourceId)
282
- return entities[tableName]
283
- }
284
-
285
- export async function getTable(tableId: any) {
286
- const db = getAppDB()
287
- if (isExternalTable(tableId)) {
288
- let { datasourceId, tableName } = breakExternalTableId(tableId)
289
- const datasource = await db.get(datasourceId)
290
- const table = await getExternalTable(datasourceId, tableName)
291
- return { ...table, sql: isSQL(datasource) }
292
- } else {
293
- return db.get(tableId)
294
- }
295
- }
296
-
297
248
  export async function checkForViewUpdates(
298
249
  table: any,
299
250
  rename: any,
@@ -3,12 +3,12 @@ const { apiFileReturn } = require("../../../utilities/fileSystem")
3
3
  const exporters = require("./exporters")
4
4
  const { saveView, getView, getViews, deleteView } = require("./utils")
5
5
  const { fetchView } = require("../row")
6
- const { getTable } = require("../table/utils")
7
6
  const { FieldTypes } = require("../../../constants")
8
7
  const { getAppDB } = require("@budibase/backend-core/context")
9
8
  const { events } = require("@budibase/backend-core")
10
9
  const { DocumentType } = require("../../../db/utils")
11
10
  const { cloneDeep, isEqual } = require("lodash")
11
+ const sdk = require("../../../sdk")
12
12
 
13
13
  exports.fetch = async ctx => {
14
14
  ctx.body = await getViews()
@@ -144,7 +144,7 @@ exports.exportView = async ctx => {
144
144
 
145
145
  let schema = view && view.meta && view.meta.schema
146
146
  const tableId = ctx.params.tableId || view.meta.tableId
147
- const table = await getTable(tableId)
147
+ const table = await sdk.tables.getTable(tableId)
148
148
  if (!schema) {
149
149
  schema = table.schema
150
150
  }
@@ -0,0 +1,10 @@
1
+ import Router from "@koa/router"
2
+ import * as controller from "../controllers/backup"
3
+ import authorized from "../../middleware/authorized"
4
+ import { BUILDER } from "@budibase/backend-core/permissions"
5
+
6
+ const router = new Router()
7
+
8
+ router.get("/api/backups/export", authorized(BUILDER), controller.exportAppDump)
9
+
10
+ export default router
@@ -25,11 +25,17 @@ import devRoutes from "./dev"
25
25
  import cloudRoutes from "./cloud"
26
26
  import migrationRoutes from "./migrations"
27
27
  import pluginRoutes from "./plugin"
28
+ import Router from "@koa/router"
29
+ import { api } from "@budibase/pro"
28
30
 
29
31
  export { default as staticRoutes } from "./static"
30
32
  export { default as publicRoutes } from "./public"
31
33
 
32
- export const mainRoutes = [
34
+ const appBackupRoutes = api.appBackups
35
+ const scheduleRoutes = api.schedules
36
+ export const mainRoutes: Router[] = [
37
+ appBackupRoutes,
38
+ backupRoutes,
33
39
  authRoutes,
34
40
  deployRoutes,
35
41
  layoutRoutes,
@@ -49,14 +55,14 @@ export const mainRoutes = [
49
55
  permissionRoutes,
50
56
  datasourceRoutes,
51
57
  queryRoutes,
52
- backupRoutes,
53
58
  metadataRoutes,
54
59
  devRoutes,
55
60
  cloudRoutes,
56
- // these need to be handled last as they still use /api/:tableId
57
- // this could be breaking as koa may recognise other routes as this
58
- tableRoutes,
59
61
  rowRoutes,
60
62
  migrationRoutes,
61
63
  pluginRoutes,
64
+ scheduleRoutes,
65
+ // these need to be handled last as they still use /api/:tableId
66
+ // this could be breaking as koa may recognise other routes as this
67
+ tableRoutes,
62
68
  ]
@@ -21,7 +21,7 @@ describe("/backups", () => {
21
21
  .set(config.defaultHeaders())
22
22
  .expect(200)
23
23
  expect(res.text).toBeDefined()
24
- expect(res.text.includes(`"db_name":"${config.getAppId()}"`)).toEqual(true)
24
+ expect(res.headers["content-type"]).toEqual("application/gzip")
25
25
  expect(events.app.exported.mock.calls.length).toBe(1)
26
26
  })
27
27
 
@@ -1,5 +1,5 @@
1
- const setup = require("./utilities")
2
- const { events } = require("@budibase/backend-core")
1
+ import setup from "./utilities"
2
+ import { events } from "@budibase/backend-core"
3
3
 
4
4
  describe("/deployments", () => {
5
5
  let request = setup.getRequest()
@@ -19,7 +19,7 @@ describe("/deployments", () => {
19
19
  .set(config.defaultHeaders())
20
20
  .expect("Content-Type", /json/)
21
21
  .expect(200)
22
- expect(events.app.published.mock.calls.length).toBe(1)
22
+ expect((events.app.published as jest.Mock).mock.calls.length).toBe(1)
23
23
  })
24
24
  })
25
- })
25
+ })
@@ -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 () => {
package/src/app.ts CHANGED
@@ -37,6 +37,8 @@ import {
37
37
  } from "./utilities/workerRequests"
38
38
  import { watch } from "./watch"
39
39
  import { initialise as initialiseWebsockets } from "./websocket"
40
+ import sdk from "./sdk"
41
+ import * as pro from "@budibase/pro"
40
42
 
41
43
  const app = new Koa()
42
44
 
@@ -102,12 +104,25 @@ server.on("close", async () => {
102
104
  }
103
105
  })
104
106
 
107
+ const initPro = async () => {
108
+ await pro.init({
109
+ backups: {
110
+ processing: {
111
+ exportAppFn: sdk.backups.exportApp,
112
+ importAppFn: sdk.backups.importApp,
113
+ statsFn: sdk.backups.calculateBackupStats,
114
+ },
115
+ },
116
+ })
117
+ }
118
+
105
119
  module.exports = server.listen(env.PORT || 0, async () => {
106
120
  console.log(`Budibase running on ${JSON.stringify(server.address())}`)
107
121
  env._set("PORT", server.address().port)
108
122
  eventEmitter.emitPort(env.PORT)
109
123
  fileSystem.init()
110
124
  await redis.init()
125
+ await initPro()
111
126
 
112
127
  // run migrations on startup if not done via http
113
128
  // not recommended in a clustered environment
@@ -1,10 +1,10 @@
1
- const { getTable } = require("../api/controllers/table/utils")
2
1
  const {
3
2
  findHBSBlocks,
4
3
  decodeJSBinding,
5
4
  isJSBinding,
6
5
  encodeJSBinding,
7
6
  } = require("@budibase/string-templates")
7
+ const sdk = require("../sdk")
8
8
 
9
9
  /**
10
10
  * When values are input to the system generally they will be of type string as this is required for template strings.
@@ -64,7 +64,7 @@ exports.cleanInputValues = (inputs, schema) => {
64
64
  * @returns {Promise<Object>} The cleaned up rows object, will should now have all the required primitive types.
65
65
  */
66
66
  exports.cleanUpRow = async (tableId, row) => {
67
- let table = await getTable(tableId)
67
+ let table = await sdk.tables.getTable(tableId)
68
68
  return exports.cleanInputValues(row, { properties: table.schema })
69
69
  }
70
70