@budibase/server 1.0.199 → 1.0.200-alpha.2

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 (281) hide show
  1. package/Dockerfile +2 -0
  2. package/builder/assets/index.359da19e.js +1315 -0
  3. package/builder/index.html +1 -1
  4. package/coverage/clover.xml +2089 -2001
  5. package/coverage/coverage-final.json +121 -122
  6. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  7. package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
  8. package/coverage/lcov-report/api/controllers/automation.js.html +174 -72
  9. package/coverage/lcov-report/api/controllers/backup.js.html +30 -6
  10. package/coverage/lcov-report/api/controllers/cloud.js.html +11 -11
  11. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  12. package/coverage/lcov-report/api/controllers/datasource.js.html +53 -41
  13. package/coverage/lcov-report/api/controllers/dev.js.html +94 -70
  14. package/coverage/lcov-report/api/controllers/index.html +57 -72
  15. package/coverage/lcov-report/api/controllers/integration.js.html +8 -8
  16. package/coverage/lcov-report/api/controllers/layout.js.html +28 -19
  17. package/coverage/lcov-report/api/controllers/metadata.js.html +9 -9
  18. package/coverage/lcov-report/api/controllers/migrations.js.html +4 -4
  19. package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
  20. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query/validation.js.html +10 -10
  22. package/coverage/lcov-report/api/controllers/role.js.html +78 -48
  23. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  24. package/coverage/lcov-report/api/controllers/row/external.js.html +19 -19
  25. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/internal.js.html +54 -54
  27. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +9 -9
  28. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +24 -24
  29. package/coverage/lcov-report/api/controllers/row/utils.js.html +24 -24
  30. package/coverage/lcov-report/api/controllers/screen.js.html +56 -20
  31. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  32. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +49 -49
  33. package/coverage/lcov-report/api/controllers/table/external.js.html +23 -17
  34. package/coverage/lcov-report/api/controllers/table/index.html +26 -26
  35. package/coverage/lcov-report/api/controllers/table/index.js.html +85 -49
  36. package/coverage/lcov-report/api/controllers/templates.js.html +6 -6
  37. package/coverage/lcov-report/api/controllers/user.js.html +19 -19
  38. package/coverage/lcov-report/api/controllers/view/exporters.js.html +11 -11
  39. package/coverage/lcov-report/api/controllers/view/index.html +21 -21
  40. package/coverage/lcov-report/api/controllers/view/index.js.html +275 -65
  41. package/coverage/lcov-report/api/controllers/view/utils.js.html +23 -23
  42. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +40 -40
  43. package/coverage/lcov-report/api/controllers/webhook.js.html +17 -17
  44. package/coverage/lcov-report/api/index.html +15 -15
  45. package/coverage/lcov-report/api/index.js.html +39 -45
  46. package/coverage/lcov-report/api/routes/analytics.js.html +7 -13
  47. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  48. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  49. package/coverage/lcov-report/api/routes/automation.js.html +11 -11
  50. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  51. package/coverage/lcov-report/api/routes/cloud.js.html +8 -8
  52. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  53. package/coverage/lcov-report/api/routes/datasource.js.html +9 -9
  54. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  55. package/coverage/lcov-report/api/routes/dev.js.html +13 -13
  56. package/coverage/lcov-report/api/routes/index.html +1 -1
  57. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  58. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  59. package/coverage/lcov-report/api/routes/metadata.js.html +9 -9
  60. package/coverage/lcov-report/api/routes/migrations.js.html +7 -7
  61. package/coverage/lcov-report/api/routes/permission.js.html +9 -9
  62. package/coverage/lcov-report/api/routes/query.js.html +10 -10
  63. package/coverage/lcov-report/api/routes/role.js.html +9 -9
  64. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  65. package/coverage/lcov-report/api/routes/screen.js.html +9 -9
  66. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/table.js.html +10 -10
  68. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  69. package/coverage/lcov-report/api/routes/user.js.html +8 -8
  70. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  71. package/coverage/lcov-report/api/routes/utils/validators.js.html +36 -36
  72. package/coverage/lcov-report/api/routes/view.js.html +10 -10
  73. package/coverage/lcov-report/api/routes/webhook.js.html +9 -9
  74. package/coverage/lcov-report/automations/actions.js.html +25 -25
  75. package/coverage/lcov-report/automations/automationUtils.js.html +8 -8
  76. package/coverage/lcov-report/automations/bullboard.js.html +35 -35
  77. package/coverage/lcov-report/automations/index.html +29 -29
  78. package/coverage/lcov-report/automations/index.js.html +29 -17
  79. package/coverage/lcov-report/automations/steps/bash.js.html +7 -7
  80. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  81. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  82. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  83. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  84. package/coverage/lcov-report/automations/steps/filter.js.html +7 -7
  85. package/coverage/lcov-report/automations/steps/index.html +1 -1
  86. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  87. package/coverage/lcov-report/automations/steps/loop.js.html +2 -2
  88. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  89. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -10
  90. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  91. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  92. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  93. package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
  94. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  95. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  96. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  97. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  98. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  100. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  101. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  102. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  103. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  104. package/coverage/lcov-report/automations/triggers.js.html +18 -18
  105. package/coverage/lcov-report/constants/index.html +1 -1
  106. package/coverage/lcov-report/constants/index.js.html +30 -30
  107. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  108. package/coverage/lcov-report/constants/screens.js.html +4 -4
  109. package/coverage/lcov-report/db/inMemoryView.js.html +5 -5
  110. package/coverage/lcov-report/db/index.html +1 -1
  111. package/coverage/lcov-report/db/index.js.html +9 -9
  112. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +17 -17
  113. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/index.js.html +36 -36
  115. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +19 -19
  116. package/coverage/lcov-report/db/newid.js.html +4 -4
  117. package/coverage/lcov-report/db/utils.js.html +81 -81
  118. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  119. package/coverage/lcov-report/events/index.html +1 -1
  120. package/coverage/lcov-report/events/index.js.html +7 -7
  121. package/coverage/lcov-report/events/utils.js.html +10 -10
  122. package/coverage/lcov-report/index.html +74 -74
  123. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  124. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  125. package/coverage/lcov-report/middleware/appInfo.js.html +5 -5
  126. package/coverage/lcov-report/middleware/builder.js.html +20 -20
  127. package/coverage/lcov-report/middleware/currentapp.js.html +49 -49
  128. package/coverage/lcov-report/middleware/index.html +1 -1
  129. package/coverage/lcov-report/middleware/joi-validator.js.html +14 -14
  130. package/coverage/lcov-report/middleware/publicApi.js.html +5 -5
  131. package/coverage/lcov-report/middleware/resourceId.js.html +29 -29
  132. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  133. package/coverage/lcov-report/middleware/utils.js.html +4 -4
  134. package/coverage/lcov-report/threads/automation.js.html +1 -1
  135. package/coverage/lcov-report/threads/index.html +1 -1
  136. package/coverage/lcov-report/threads/query.js.html +1 -1
  137. package/coverage/lcov-report/threads/utils.js.html +13 -13
  138. package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
  139. package/coverage/lcov-report/utilities/centralPath.js.html +14 -14
  140. package/coverage/lcov-report/utilities/csvParser.js.html +34 -34
  141. package/coverage/lcov-report/utilities/global.js.html +28 -28
  142. package/coverage/lcov-report/utilities/index.html +25 -25
  143. package/coverage/lcov-report/utilities/index.js.html +41 -41
  144. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +18 -18
  145. package/coverage/lcov-report/utilities/queue/index.html +15 -15
  146. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  147. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  148. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +59 -59
  150. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +15 -15
  151. package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
  152. package/coverage/lcov-report/utilities/security.js.html +8 -8
  153. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  154. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  155. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +30 -30
  156. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  157. package/coverage/lcov-report/utilities/users.js.html +7 -7
  158. package/coverage/lcov-report/utilities/workerRequests.js.html +29 -29
  159. package/coverage/lcov.info +2903 -2762
  160. package/dist/api/controllers/analytics.js +7 -30
  161. package/dist/api/controllers/application.js +56 -16
  162. package/dist/api/controllers/automation.js +31 -2
  163. package/dist/api/controllers/backup.js +7 -0
  164. package/dist/api/controllers/datasource.js +8 -2
  165. package/dist/api/controllers/deploy/index.js +6 -2
  166. package/dist/api/controllers/dev.js +9 -2
  167. package/dist/api/controllers/layout.js +3 -0
  168. package/dist/api/controllers/query/import/index.js +12 -2
  169. package/dist/api/controllers/query/import/sources/curl.js +3 -0
  170. package/dist/api/controllers/query/import/sources/openapi2.js +3 -0
  171. package/dist/api/controllers/query/import/sources/openapi3.js +3 -0
  172. package/dist/api/controllers/query/index.js +16 -2
  173. package/dist/api/controllers/role.js +11 -0
  174. package/dist/api/controllers/screen.js +10 -1
  175. package/dist/api/controllers/static/index.js +29 -15
  176. package/dist/api/controllers/table/external.js +2 -0
  177. package/dist/api/controllers/table/index.js +12 -0
  178. package/dist/api/controllers/table/utils.js +3 -3
  179. package/dist/api/controllers/view/index.js +62 -6
  180. package/dist/api/index.js +2 -4
  181. package/dist/api/routes/analytics.js +1 -3
  182. package/dist/app.js +16 -8
  183. package/dist/automations/index.js +4 -0
  184. package/dist/environment.js +4 -2
  185. package/dist/migrations/functions/backfill/app/automations.js +31 -0
  186. package/dist/migrations/functions/backfill/app/datasources.js +28 -0
  187. package/dist/migrations/functions/backfill/app/layouts.js +33 -0
  188. package/dist/migrations/functions/backfill/app/queries.js +32 -0
  189. package/dist/migrations/functions/backfill/app/roles.js +28 -0
  190. package/dist/migrations/functions/backfill/app/screens.js +28 -0
  191. package/dist/migrations/functions/backfill/app/tables.js +40 -0
  192. package/dist/migrations/functions/backfill/app.js +175 -0
  193. package/dist/migrations/functions/backfill/global/configs.js +61 -0
  194. package/dist/migrations/functions/backfill/global/quotas.js +60 -0
  195. package/dist/migrations/functions/backfill/global/users.js +50 -0
  196. package/dist/migrations/functions/backfill/global.js +189 -0
  197. package/dist/migrations/functions/backfill/index.js +32 -0
  198. package/dist/migrations/functions/backfill/installation.js +81 -0
  199. package/dist/migrations/index.js +95 -31
  200. package/dist/migrations/tests/helpers.js +72 -0
  201. package/dist/migrations/tests/structures.js +37 -0
  202. package/dist/package.json +79 -69
  203. package/dist/tests/utilities/TestConfiguration.js +121 -93
  204. package/dist/tests/utilities/structures.js +45 -0
  205. package/dist/tsconfig.build.tsbuildinfo +1 -1
  206. package/nodemon.json +1 -1
  207. package/package.json +80 -70
  208. package/scripts/dev/manage.js +2 -0
  209. package/scripts/jestSetup.js +7 -0
  210. package/scripts/likeCypress.ts +1 -1
  211. package/src/api/controllers/analytics.ts +8 -0
  212. package/src/api/controllers/application.ts +60 -18
  213. package/src/api/controllers/automation.js +36 -2
  214. package/src/api/controllers/backup.js +8 -0
  215. package/src/api/controllers/datasource.js +8 -4
  216. package/src/api/controllers/deploy/index.ts +6 -2
  217. package/src/api/controllers/dev.js +10 -2
  218. package/src/api/controllers/layout.js +3 -0
  219. package/src/api/controllers/query/import/index.ts +16 -3
  220. package/src/api/controllers/query/import/sources/base/index.ts +2 -1
  221. package/src/api/controllers/query/import/sources/curl.ts +4 -0
  222. package/src/api/controllers/query/import/sources/openapi2.ts +4 -0
  223. package/src/api/controllers/query/import/sources/openapi3.ts +4 -0
  224. package/src/api/controllers/query/import/tests/index.spec.js +20 -7
  225. package/src/api/controllers/query/index.ts +16 -3
  226. package/src/api/controllers/role.js +10 -0
  227. package/src/api/controllers/screen.js +13 -1
  228. package/src/api/controllers/static/index.js +28 -15
  229. package/src/api/controllers/table/external.js +2 -0
  230. package/src/api/controllers/table/index.js +12 -0
  231. package/src/api/controllers/table/utils.ts +4 -4
  232. package/src/api/controllers/view/index.js +76 -6
  233. package/src/api/index.js +2 -4
  234. package/src/api/routes/analytics.js +1 -3
  235. package/src/api/routes/public/utils/Endpoint.ts +1 -1
  236. package/src/api/routes/tests/__snapshots__/datasource.spec.js.snap +5 -1
  237. package/src/api/routes/tests/application.spec.js +64 -4
  238. package/src/api/routes/tests/automation.spec.js +168 -60
  239. package/src/api/routes/tests/backup.spec.js +2 -0
  240. package/src/api/routes/tests/data/export.txt +1 -0
  241. package/src/api/routes/tests/datasource.spec.js +5 -0
  242. package/src/api/routes/tests/deployment.spec.js +25 -0
  243. package/src/api/routes/tests/dev.spec.js +40 -0
  244. package/src/api/routes/tests/layout.spec.js +4 -0
  245. package/src/api/routes/tests/query.spec.js +56 -13
  246. package/src/api/routes/tests/role.spec.js +40 -7
  247. package/src/api/routes/tests/row.spec.js +2 -3
  248. package/src/api/routes/tests/screen.spec.js +30 -4
  249. package/src/api/routes/tests/static.spec.js +120 -54
  250. package/src/api/routes/tests/table.spec.js +102 -38
  251. package/src/api/routes/tests/view.spec.js +222 -43
  252. package/src/app.ts +18 -9
  253. package/src/automations/index.js +4 -0
  254. package/src/automations/tests/delay.spec.js +4 -0
  255. package/src/environment.js +5 -2
  256. package/src/migrations/functions/backfill/app/automations.ts +26 -0
  257. package/src/migrations/functions/backfill/app/datasources.ts +22 -0
  258. package/src/migrations/functions/backfill/app/layouts.ts +29 -0
  259. package/src/migrations/functions/backfill/app/queries.ts +33 -0
  260. package/src/migrations/functions/backfill/app/roles.ts +22 -0
  261. package/src/migrations/functions/backfill/app/screens.ts +22 -0
  262. package/src/migrations/functions/backfill/app/tables.ts +36 -0
  263. package/src/migrations/functions/backfill/app.ts +148 -0
  264. package/src/migrations/functions/backfill/global/configs.ts +66 -0
  265. package/src/migrations/functions/backfill/global/quotas.ts +60 -0
  266. package/src/migrations/functions/backfill/global/users.ts +49 -0
  267. package/src/migrations/functions/backfill/global.ts +194 -0
  268. package/src/migrations/functions/backfill/index.ts +7 -0
  269. package/src/migrations/functions/backfill/installation.ts +51 -0
  270. package/src/migrations/index.ts +120 -51
  271. package/src/migrations/tests/helpers.ts +40 -0
  272. package/src/migrations/tests/index.spec.ts +132 -0
  273. package/src/migrations/tests/structures.ts +66 -0
  274. package/src/module.d.ts +0 -1
  275. package/src/tests/utilities/TestConfiguration.js +138 -90
  276. package/src/tests/utilities/structures.js +71 -0
  277. package/tsconfig.build.json +20 -5
  278. package/tsconfig.json +22 -17
  279. package/builder/assets/index.107ba2e5.js +0 -1315
  280. package/coverage/lcov-report/api/controllers/analytics.js.html +0 -202
  281. package/src/api/controllers/analytics.js +0 -39
@@ -7,6 +7,7 @@ const { Replication, getProdAppID } = require("@budibase/backend-core/db")
7
7
  const { DocumentTypes } = require("../../db/utils")
8
8
  const { app: appCache } = require("@budibase/backend-core/cache")
9
9
  const { getProdAppDB, getAppDB } = require("@budibase/backend-core/context")
10
+ const { events } = require("@budibase/backend-core")
10
11
 
11
12
  async function redirect(ctx, method, path = "global") {
12
13
  const { devPath } = ctx.params
@@ -102,7 +103,11 @@ exports.revert = async ctx => {
102
103
  target: appId,
103
104
  })
104
105
  try {
105
- await replication.rollback()
106
+ if (!env.isTest()) {
107
+ // in-memory db stalls on rollback
108
+ await replication.rollback()
109
+ }
110
+
106
111
  // update appID in reverted app to be dev version again
107
112
  const db = getAppDB()
108
113
  const appDoc = await db.get(DocumentTypes.APP_METADATA)
@@ -113,6 +118,7 @@ exports.revert = async ctx => {
113
118
  ctx.body = {
114
119
  message: "Reverted changes successfully.",
115
120
  }
121
+ await events.app.reverted(appDoc)
116
122
  } catch (err) {
117
123
  ctx.throw(400, `Unable to revert. ${err}`)
118
124
  } finally {
@@ -121,7 +127,9 @@ exports.revert = async ctx => {
121
127
  }
122
128
 
123
129
  exports.getBudibaseVersion = async ctx => {
130
+ const version = require("../../../package.json").version
124
131
  ctx.body = {
125
- version: require("../../../package.json").version,
132
+ version,
126
133
  }
134
+ await events.version.checked(version)
127
135
  }
@@ -4,6 +4,7 @@ const {
4
4
  } = require("../../constants/layouts")
5
5
  const { generateLayoutID, getScreenParams } = require("../../db/utils")
6
6
  const { getAppDB } = require("@budibase/backend-core/context")
7
+ const { events } = require("@budibase/backend-core")
7
8
 
8
9
  exports.save = async function (ctx) {
9
10
  const db = getAppDB()
@@ -19,6 +20,7 @@ exports.save = async function (ctx) {
19
20
 
20
21
  layout._id = layout._id || generateLayoutID()
21
22
  const response = await db.put(layout)
23
+ await events.layout.created(layout)
22
24
  layout._rev = response.rev
23
25
 
24
26
  ctx.body = layout
@@ -46,6 +48,7 @@ exports.destroy = async function (ctx) {
46
48
  }
47
49
 
48
50
  await db.remove(layoutId, layoutRev)
51
+ await events.layout.deleted(layoutId)
49
52
  ctx.body = { message: "Layout deleted successfully" }
50
53
  ctx.status = 200
51
54
  }
@@ -3,10 +3,12 @@ import { generateQueryID } from "../../../../db/utils"
3
3
  import { ImportInfo, ImportSource } from "./sources/base"
4
4
  import { OpenAPI2 } from "./sources/openapi2"
5
5
  import { OpenAPI3 } from "./sources/openapi3"
6
- import { Query } from "./../../../../definitions/common"
7
6
  import { Curl } from "./sources/curl"
8
7
  // @ts-ignore
9
8
  import { getAppDB } from "@budibase/backend-core/context"
9
+ import { events } from "@budibase/backend-core"
10
+ import { Datasource, Query } from "@budibase/types"
11
+
10
12
  interface ImportResult {
11
13
  errorQueries: Query[]
12
14
  queries: Query[]
@@ -36,7 +38,7 @@ export class RestImporter {
36
38
  }
37
39
 
38
40
  importQueries = async (datasourceId: string): Promise<ImportResult> => {
39
- // constuct the queries
41
+ // construct the queries
40
42
  let queries = await this.source.getQueries(datasourceId)
41
43
 
42
44
  // validate queries
@@ -76,9 +78,20 @@ export class RestImporter {
76
78
  }
77
79
  })
78
80
 
81
+ const successQueries = Object.values(queryIndex)
82
+
83
+ // events
84
+ const count = successQueries.length
85
+ const importSource = this.source.getImportSource()
86
+ const datasource: Datasource = await db.get(datasourceId)
87
+ await events.query.imported(datasource, importSource, count)
88
+ for (let query of successQueries) {
89
+ await events.query.created(datasource, query)
90
+ }
91
+
79
92
  return {
80
93
  errorQueries,
81
- queries: Object.values(queryIndex),
94
+ queries: successQueries,
82
95
  }
83
96
  }
84
97
  }
@@ -1,4 +1,4 @@
1
- import { Query, QueryParameter } from "../../../../../../definitions/datasource"
1
+ import { Query, QueryParameter } from "@budibase/types"
2
2
  import { URL } from "url"
3
3
 
4
4
  export interface ImportInfo {
@@ -17,6 +17,7 @@ export abstract class ImportSource {
17
17
  abstract isSupported(data: string): Promise<boolean>
18
18
  abstract getInfo(): Promise<ImportInfo>
19
19
  abstract getQueries(datasourceId: string): Promise<Query[]>
20
+ abstract getImportSource(): string
20
21
 
21
22
  constructQuery = (
22
23
  datasourceId: string,
@@ -71,6 +71,10 @@ export class Curl extends ImportSource {
71
71
  }
72
72
  }
73
73
 
74
+ getImportSource(): string {
75
+ return "curl"
76
+ }
77
+
74
78
  getQueries = async (datasourceId: string): Promise<Query[]> => {
75
79
  const url = this.getUrl()
76
80
  const name = url.pathname
@@ -70,6 +70,10 @@ export class OpenAPI2 extends OpenAPISource {
70
70
  }
71
71
  }
72
72
 
73
+ getImportSource(): string {
74
+ return "openapi2.0"
75
+ }
76
+
73
77
  getQueries = async (datasourceId: string): Promise<Query[]> => {
74
78
  const url = this.getUrl()
75
79
  const queries = []
@@ -106,6 +106,10 @@ export class OpenAPI3 extends OpenAPISource {
106
106
  }
107
107
  }
108
108
 
109
+ getImportSource(): string {
110
+ return "openapi3.0"
111
+ }
112
+
109
113
  getQueries = async (datasourceId: string): Promise<Query[]> => {
110
114
  let url: string | URL | undefined
111
115
  if (this.document.servers?.length) {
@@ -1,9 +1,8 @@
1
1
  const TestConfig = require("../../../../../tests/utilities/TestConfiguration")
2
-
3
2
  const { RestImporter } = require("../index")
4
-
5
3
  const fs = require("fs")
6
4
  const path = require('path')
5
+ const { events} = require("@budibase/backend-core")
7
6
 
8
7
  const getData = (file) => {
9
8
  return fs.readFileSync(path.join(__dirname, `../sources/tests/${file}`), "utf8")
@@ -54,9 +53,11 @@ describe("Rest Importer", () => {
54
53
  }
55
54
 
56
55
  const runTest = async (test, assertions) => {
57
- for (let [key, data] of Object.entries(datasets)) {
58
- await test(key, data, assertions)
59
- }
56
+ await config.doInContext(config.appId, async () => {
57
+ for (let [key, data] of Object.entries(datasets)) {
58
+ await test(key, data, assertions)
59
+ }
60
+ })
60
61
  }
61
62
 
62
63
  const testGetInfo = async (key, data, assertions) => {
@@ -103,9 +104,12 @@ describe("Rest Importer", () => {
103
104
 
104
105
  const testImportQueries = async (key, data, assertions) => {
105
106
  await init(data)
106
- const importResult = await restImporter.importQueries("datasourceId")
107
+ const datasource = await config.createDatasource()
108
+ const importResult = await restImporter.importQueries(datasource._id)
107
109
  expect(importResult.errorQueries.length).toBe(0)
108
110
  expect(importResult.queries.length).toBe(assertions[key].count)
111
+ expect(events.query.imported).toBeCalledTimes(1)
112
+ expect(events.query.imported).toBeCalledWith(datasource, assertions[key].source, assertions[key].count)
109
113
  jest.clearAllMocks()
110
114
  }
111
115
 
@@ -116,32 +120,41 @@ describe("Rest Importer", () => {
116
120
  // openapi2 (swagger)
117
121
  "oapi2CrudJson" : {
118
122
  count: 6,
123
+ source: "openapi2.0",
119
124
  },
120
125
  "oapi2CrudYaml" :{
121
126
  count: 6,
127
+ source: "openapi2.0"
122
128
  },
123
129
  "oapi2PetstoreJson" : {
124
130
  count: 20,
131
+ source: "openapi2.0"
125
132
  },
126
133
  "oapi2PetstoreYaml" :{
127
134
  count: 20,
135
+ source: "openapi2.0"
128
136
  },
129
137
  // openapi3
130
138
  "oapi3CrudJson" : {
131
139
  count: 6,
140
+ source: "openapi3.0"
132
141
  },
133
142
  "oapi3CrudYaml" :{
134
143
  count: 6,
144
+ source: "openapi3.0"
135
145
  },
136
146
  "oapi3PetstoreJson" : {
137
147
  count: 19,
148
+ source: "openapi3.0"
138
149
  },
139
150
  "oapi3PetstoreYaml" :{
140
151
  count: 19,
152
+ source: "openapi3.0"
141
153
  },
142
154
  // curl
143
155
  "curl": {
144
- count: 1
156
+ count: 1,
157
+ source: "curl"
145
158
  }
146
159
  }
147
160
  await runTest(testImportQueries, assertions)
@@ -7,6 +7,7 @@ import { invalidateDynamicVariables } from "../../../threads/utils"
7
7
  import { QUERY_THREAD_TIMEOUT } from "../../../environment"
8
8
  import { getAppDB } from "@budibase/backend-core/context"
9
9
  import { quotas } from "@budibase/pro"
10
+ import { events } from "@budibase/backend-core"
10
11
 
11
12
  const Runner = new Thread(ThreadType.QUERY, {
12
13
  timeoutMs: QUERY_THREAD_TIMEOUT || 10000,
@@ -80,11 +81,18 @@ export async function save(ctx: any) {
80
81
  const db = getAppDB()
81
82
  const query = ctx.request.body
82
83
 
84
+ const datasource = await db.get(query.datasourceId)
85
+
86
+ let eventFn
83
87
  if (!query._id) {
84
88
  query._id = generateQueryID(query.datasourceId)
89
+ eventFn = () => events.query.created(datasource, query)
90
+ } else {
91
+ eventFn = () => events.query.updated(datasource, query)
85
92
  }
86
93
 
87
94
  const response = await db.put(query)
95
+ await eventFn()
88
96
  query._rev = response.rev
89
97
 
90
98
  ctx.body = query
@@ -106,10 +114,10 @@ export async function preview(ctx: any) {
106
114
  const db = getAppDB()
107
115
 
108
116
  const datasource = await db.get(ctx.request.body.datasourceId)
117
+ const query = ctx.request.body
109
118
  // preview may not have a queryId as it hasn't been saved, but if it does
110
119
  // this stops dynamic variables from calling the same query
111
- const { fields, parameters, queryVerb, transformer, queryId } =
112
- ctx.request.body
120
+ const { fields, parameters, queryVerb, transformer, queryId } = query
113
121
 
114
122
  try {
115
123
  const runFn = () =>
@@ -124,6 +132,7 @@ export async function preview(ctx: any) {
124
132
  })
125
133
 
126
134
  const { rows, keys, info, extra } = await quotas.addQuery(runFn)
135
+ await events.query.previewed(datasource, query)
127
136
  ctx.body = {
128
137
  rows,
129
138
  schemaFields: [...new Set(keys)],
@@ -207,8 +216,12 @@ const removeDynamicVariables = async (queryId: any) => {
207
216
 
208
217
  export async function destroy(ctx: any) {
209
218
  const db = getAppDB()
210
- await removeDynamicVariables(ctx.params.queryId)
219
+ const queryId = ctx.params.queryId
220
+ await removeDynamicVariables(queryId)
221
+ const query = await db.get(queryId)
222
+ const datasource = await db.get(query.datasourceId)
211
223
  await db.remove(ctx.params.queryId, ctx.params.revId)
212
224
  ctx.message = `Query deleted.`
213
225
  ctx.status = 200
226
+ await events.query.deleted(datasource, query)
214
227
  }
@@ -10,6 +10,7 @@ const {
10
10
  InternalTables,
11
11
  } = require("../../db/utils")
12
12
  const { getAppDB } = require("@budibase/backend-core/context")
13
+ const { events } = require("@budibase/backend-core")
13
14
 
14
15
  const UpdateRolesOptions = {
15
16
  CREATED: "created",
@@ -50,8 +51,10 @@ exports.find = async function (ctx) {
50
51
  exports.save = async function (ctx) {
51
52
  const db = getAppDB()
52
53
  let { _id, name, inherits, permissionId } = ctx.request.body
54
+ let isCreate = false
53
55
  if (!_id) {
54
56
  _id = generateRoleID()
57
+ isCreate = true
55
58
  } else if (isBuiltin(_id)) {
56
59
  ctx.throw(400, "Cannot update builtin roles.")
57
60
  }
@@ -62,6 +65,11 @@ exports.save = async function (ctx) {
62
65
  role._rev = ctx.request.body._rev
63
66
  }
64
67
  const result = await db.put(role)
68
+ if (isCreate) {
69
+ await events.role.created(role)
70
+ } else {
71
+ await events.role.updated(role)
72
+ }
65
73
  await updateRolesOnUserTable(db, _id, UpdateRolesOptions.CREATED)
66
74
  role._rev = result.rev
67
75
  ctx.body = role
@@ -71,6 +79,7 @@ exports.save = async function (ctx) {
71
79
  exports.destroy = async function (ctx) {
72
80
  const db = getAppDB()
73
81
  const roleId = ctx.params.roleId
82
+ const role = await db.get(roleId)
74
83
  if (isBuiltin(roleId)) {
75
84
  ctx.throw(400, "Cannot delete builtin role.")
76
85
  }
@@ -88,6 +97,7 @@ exports.destroy = async function (ctx) {
88
97
  }
89
98
 
90
99
  await db.remove(roleId, ctx.params.rev)
100
+ await events.role.deleted(role)
91
101
  await updateRolesOnUserTable(
92
102
  db,
93
103
  ctx.params.roleId,
@@ -1,6 +1,7 @@
1
1
  const { getScreenParams, generateScreenID } = require("../../db/utils")
2
2
  const { AccessController } = require("@budibase/backend-core/roles")
3
3
  const { getAppDB } = require("@budibase/backend-core/context")
4
+ const { events } = require("@budibase/backend-core")
4
5
 
5
6
  exports.fetch = async ctx => {
6
7
  const db = getAppDB()
@@ -23,11 +24,17 @@ exports.save = async ctx => {
23
24
  const db = getAppDB()
24
25
  let screen = ctx.request.body
25
26
 
27
+ let eventFn
26
28
  if (!screen._id) {
27
29
  screen._id = generateScreenID()
30
+ eventFn = events.screen.created
28
31
  }
32
+
29
33
  const response = await db.put(screen)
30
34
 
35
+ if (eventFn) {
36
+ await eventFn(screen)
37
+ }
31
38
  ctx.message = `Screen ${screen.name} saved.`
32
39
  ctx.body = {
33
40
  ...screen,
@@ -38,7 +45,12 @@ exports.save = async ctx => {
38
45
 
39
46
  exports.destroy = async ctx => {
40
47
  const db = getAppDB()
41
- await db.remove(ctx.params.screenId, ctx.params.screenRev)
48
+ const id = ctx.params.screenId
49
+ const screen = await db.get(id)
50
+
51
+ await db.remove(id, ctx.params.screenRev)
52
+
53
+ await events.screen.deleted(screen)
42
54
  ctx.body = {
43
55
  message: "Screen deleted successfully",
44
56
  }
@@ -14,10 +14,11 @@ const env = require("../../../environment")
14
14
  const { clientLibraryPath } = require("../../../utilities")
15
15
  const { upload } = require("../../../utilities/fileSystem")
16
16
  const { attachmentsRelativeURL } = require("../../../utilities")
17
- const { DocumentTypes } = require("../../../db/utils")
17
+ const { DocumentTypes, isDevAppID } = require("../../../db/utils")
18
18
  const { getAppDB, getAppId } = require("@budibase/backend-core/context")
19
19
  const AWS = require("aws-sdk")
20
20
  const AWS_REGION = env.AWS_REGION ? env.AWS_REGION : "eu-west-1"
21
+ const { events } = require("@budibase/backend-core")
21
22
 
22
23
  async function prepareUpload({ s3Key, bucket, metadata, file }) {
23
24
  const response = await upload({
@@ -41,6 +42,7 @@ async function prepareUpload({ s3Key, bucket, metadata, file }) {
41
42
  exports.serveBuilder = async function (ctx) {
42
43
  let builderPath = resolve(TOP_LEVEL_PATH, "builder")
43
44
  await send(ctx, ctx.file, { root: builderPath })
45
+ await events.serve.servedBuilder()
44
46
  }
45
47
 
46
48
  exports.uploadFile = async function (ctx) {
@@ -65,25 +67,36 @@ exports.uploadFile = async function (ctx) {
65
67
  }
66
68
 
67
69
  exports.serveApp = async function (ctx) {
68
- const App = require("./templates/BudibaseApp.svelte").default
69
70
  const db = getAppDB({ skip_setup: true })
70
71
  const appInfo = await db.get(DocumentTypes.APP_METADATA)
71
72
  let appId = getAppId()
72
73
 
73
- const { head, html, css } = App.render({
74
- title: appInfo.name,
75
- production: env.isProd(),
76
- appId,
77
- clientLibPath: clientLibraryPath(appId, appInfo.version),
78
- })
74
+ if (!env.isJest()) {
75
+ const App = require("./templates/BudibaseApp.svelte").default
76
+ const { head, html, css } = App.render({
77
+ title: appInfo.name,
78
+ production: env.isProd(),
79
+ appId,
80
+ clientLibPath: clientLibraryPath(appId, appInfo.version),
81
+ })
79
82
 
80
- const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
81
- ctx.body = await processString(appHbs, {
82
- head,
83
- body: html,
84
- style: css.code,
85
- appId,
86
- })
83
+ const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
84
+ ctx.body = await processString(appHbs, {
85
+ head,
86
+ body: html,
87
+ style: css.code,
88
+ appId,
89
+ })
90
+ } else {
91
+ // just return the app info for jest to assert on
92
+ ctx.body = appInfo
93
+ }
94
+
95
+ if (isDevAppID(appInfo.appId)) {
96
+ await events.serve.servedAppPreview(appInfo)
97
+ } else {
98
+ await events.serve.servedApp(appInfo)
99
+ }
87
100
  }
88
101
 
89
102
  exports.serveClientLibrary = async function (ctx) {
@@ -19,6 +19,7 @@ const { cloneDeep } = require("lodash/fp")
19
19
  const csvParser = require("../../../utilities/csvParser")
20
20
  const { handleRequest } = require("../row/external")
21
21
  const { getAppDB } = require("@budibase/backend-core/context")
22
+ const { events } = require("@budibase/backend-core")
22
23
 
23
24
  async function makeTableRequest(
24
25
  datasource,
@@ -314,5 +315,6 @@ exports.bulkImport = async function (ctx) {
314
315
  await handleRequest(DataSourceOperation.BULK_CREATE, table._id, {
315
316
  rows,
316
317
  })
318
+ await events.rows.imported(table, "csv", rows.length)
317
319
  return table
318
320
  }
@@ -5,6 +5,7 @@ const { isExternalTable, isSQL } = require("../../../integrations/utils")
5
5
  const { getDatasourceParams } = require("../../../db/utils")
6
6
  const { getAppDB } = require("@budibase/backend-core/context")
7
7
  const { getTable, getAllInternalTables } = require("./utils")
8
+ const { events } = require("@budibase/backend-core")
8
9
 
9
10
  function pickApi({ tableId, table }) {
10
11
  if (table && !tableId) {
@@ -55,7 +56,17 @@ exports.find = async function (ctx) {
55
56
  exports.save = async function (ctx) {
56
57
  const appId = ctx.appId
57
58
  const table = ctx.request.body
59
+ const importFormat =
60
+ table.dataImport && table.dataImport.csvString ? "csv" : undefined
58
61
  const savedTable = await pickApi({ table }).save(ctx)
62
+ if (!table._id) {
63
+ await events.table.created(savedTable)
64
+ } else {
65
+ await events.table.updated(savedTable)
66
+ }
67
+ if (importFormat) {
68
+ await events.table.imported(savedTable, importFormat)
69
+ }
59
70
  ctx.status = 200
60
71
  ctx.message = `Table ${table.name} saved successfully.`
61
72
  ctx.eventEmitter &&
@@ -67,6 +78,7 @@ exports.destroy = async function (ctx) {
67
78
  const appId = ctx.appId
68
79
  const tableId = ctx.params.tableId
69
80
  const deletedTable = await pickApi({ tableId }).destroy(ctx)
81
+ await events.table.deleted(deletedTable)
70
82
  ctx.eventEmitter &&
71
83
  ctx.eventEmitter.emitTable(`table:delete`, appId, deletedTable)
72
84
  ctx.status = 200
@@ -26,7 +26,8 @@ import { getViews, saveView } from "../view/utils"
26
26
  import viewTemplate from "../view/viewBuilder"
27
27
  const { getAppDB } = require("@budibase/backend-core/context")
28
28
  import { cloneDeep } from "lodash/fp"
29
- import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
29
+ import { quotas } from "@budibase/pro"
30
+ import { events } from "@budibase/backend-core"
30
31
 
31
32
  export async function clearColumns(table: any, columnNames: any) {
32
33
  const db = getAppDB()
@@ -148,8 +149,7 @@ export async function handleDataImport(user: any, table: any, dataImport: any) {
148
149
  }
149
150
 
150
151
  await quotas.addRows(finalData.length, () => db.bulkDocs(finalData))
151
- let response = await db.put(table)
152
- table._rev = response._rev
152
+ await events.rows.imported(table, "csv", finalData.length)
153
153
  return table
154
154
  }
155
155
 
@@ -245,7 +245,7 @@ class TableSaveFunctions {
245
245
  // after saving
246
246
  async after(table: any) {
247
247
  table = await handleSearchIndexes(table)
248
- table = await handleDataImport(this.user, table, this.dataImport)
248
+ await handleDataImport(this.user, table, this.dataImport)
249
249
  return table
250
250
  }
251
251
 
@@ -6,6 +6,9 @@ const { fetchView } = require("../row")
6
6
  const { getTable } = require("../table/utils")
7
7
  const { FieldTypes } = require("../../../constants")
8
8
  const { getAppDB } = require("@budibase/backend-core/context")
9
+ const { events } = require("@budibase/backend-core")
10
+ const { DocumentTypes } = require("../../../db/utils")
11
+ const { cloneDeep, isEqual } = require("lodash")
9
12
 
10
13
  exports.fetch = async ctx => {
11
14
  ctx.body = await getViews()
@@ -15,24 +18,28 @@ exports.save = async ctx => {
15
18
  const db = getAppDB()
16
19
  const { originalName, ...viewToSave } = ctx.request.body
17
20
  const view = viewTemplate(viewToSave)
21
+ const viewName = viewToSave.name
18
22
 
19
- if (!viewToSave.name) {
23
+ if (!viewName) {
20
24
  ctx.throw(400, "Cannot create view without a name")
21
25
  }
22
26
 
23
- await saveView(originalName, viewToSave.name, view)
27
+ await saveView(originalName, viewName, view)
24
28
 
25
29
  // add views to table document
26
- const table = await db.get(ctx.request.body.tableId)
30
+ const existingTable = await db.get(ctx.request.body.tableId)
31
+ const table = cloneDeep(existingTable)
27
32
  if (!table.views) table.views = {}
28
33
  if (!view.meta.schema) {
29
34
  view.meta.schema = table.schema
30
35
  }
31
- table.views[viewToSave.name] = view.meta
36
+ table.views[viewName] = view.meta
32
37
  if (originalName) {
33
38
  delete table.views[originalName]
39
+ existingTable.views[viewName] = existingTable.views[originalName]
34
40
  }
35
41
  await db.put(table)
42
+ await handleViewEvents(existingTable.views[viewName], table.views[viewName])
36
43
 
37
44
  ctx.body = {
38
45
  ...table.views[viewToSave.name],
@@ -40,6 +47,62 @@ exports.save = async ctx => {
40
47
  }
41
48
  }
42
49
 
50
+ const calculationEvents = async (existingView, newView) => {
51
+ const existingCalculation = existingView && existingView.calculation
52
+ const newCalculation = newView && newView.calculation
53
+
54
+ if (existingCalculation && !newCalculation) {
55
+ await events.view.calculationDeleted(existingView)
56
+ }
57
+
58
+ if (!existingCalculation && newCalculation) {
59
+ await events.view.calculationCreated(newView)
60
+ }
61
+
62
+ if (
63
+ existingCalculation &&
64
+ newCalculation &&
65
+ existingCalculation !== newCalculation
66
+ ) {
67
+ await events.view.calculationUpdated(newView)
68
+ }
69
+ }
70
+
71
+ const filterEvents = async (existingView, newView) => {
72
+ const hasExistingFilters = !!(
73
+ existingView &&
74
+ existingView.filters &&
75
+ existingView.filters.length
76
+ )
77
+ const hasNewFilters = !!(newView && newView.filters && newView.filters.length)
78
+
79
+ if (hasExistingFilters && !hasNewFilters) {
80
+ await events.view.filterDeleted(newView)
81
+ }
82
+
83
+ if (!hasExistingFilters && hasNewFilters) {
84
+ await events.view.filterCreated(newView)
85
+ }
86
+
87
+ if (
88
+ hasExistingFilters &&
89
+ hasNewFilters &&
90
+ !isEqual(existingView.filters, newView.filters)
91
+ ) {
92
+ await events.view.filterUpdated(newView)
93
+ }
94
+ }
95
+
96
+ const handleViewEvents = async (existingView, newView) => {
97
+ if (!existingView) {
98
+ await events.view.created(newView)
99
+ } else {
100
+ await events.view.updated(newView)
101
+ }
102
+ await calculationEvents(existingView, newView)
103
+ await filterEvents(existingView, newView)
104
+ }
105
+
43
106
  exports.destroy = async ctx => {
44
107
  const db = getAppDB()
45
108
  const viewName = decodeURI(ctx.params.viewName)
@@ -47,6 +110,7 @@ exports.destroy = async ctx => {
47
110
  const table = await db.get(view.meta.tableId)
48
111
  delete table.views[viewName]
49
112
  await db.put(table)
113
+ await events.view.deleted(view)
50
114
 
51
115
  ctx.body = view
52
116
  }
@@ -79,9 +143,9 @@ exports.exportView = async ctx => {
79
143
  let rows = ctx.body
80
144
 
81
145
  let schema = view && view.meta && view.meta.schema
146
+ const tableId = ctx.params.tableId || view.meta.tableId
147
+ const table = await getTable(tableId)
82
148
  if (!schema) {
83
- const tableId = ctx.params.tableId || view.meta.tableId
84
- const table = await getTable(tableId)
85
149
  schema = table.schema
86
150
  }
87
151
 
@@ -116,4 +180,10 @@ exports.exportView = async ctx => {
116
180
  // send down the file
117
181
  ctx.attachment(filename)
118
182
  ctx.body = apiFileReturn(exporter(headers, rows))
183
+
184
+ if (viewName.startsWith(DocumentTypes.TABLE)) {
185
+ await events.table.exported(table, format)
186
+ } else {
187
+ await events.view.exported(table, format)
188
+ }
119
189
  }