@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
package/nodemon.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "watch": ["src", "../backend-core", "../../../budibase-pro/packages/pro"],
3
3
  "ext": "js,ts,json",
4
- "ignore": ["src/**/*.spec.ts", "src/**/*.spec.js"],
4
+ "ignore": ["src/**/*.spec.ts", "src/**/*.spec.js", "../backend-core/dist/**/*"],
5
5
  "exec": "ts-node src/index.ts"
6
6
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.0.199",
4
+ "version": "1.0.200-alpha.2",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -9,7 +9,9 @@
9
9
  "url": "https://github.com/Budibase/budibase.git"
10
10
  },
11
11
  "scripts": {
12
- "build": "rimraf dist/ && tsc -p tsconfig.build.json && mv dist/src/* dist/ && rimraf dist/src/ && yarn postbuild",
12
+ "prebuild": "rimraf dist/",
13
+ "build": "tsc -p tsconfig.build.json && mv dist/src/* dist/ && rimraf dist/src/",
14
+ "build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
13
15
  "debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
14
16
  "postbuild": "copyfiles -u 1 src/**/*.svelte dist/ && copyfiles -u 1 src/**/*.hbs dist/ && copyfiles -u 1 src/**/*.json dist/",
15
17
  "test": "jest --coverage --maxWorkers=2",
@@ -37,6 +39,11 @@
37
39
  "jest": {
38
40
  "preset": "ts-jest",
39
41
  "testEnvironment": "node",
42
+ "moduleNameMapper": {
43
+ "@budibase/backend-core/(.*)": "<rootDir>/../backend-core/$1",
44
+ "@budibase/backend-core": "<rootDir>/../backend-core/src",
45
+ "@budibase/types": "<rootDir>/../types/src"
46
+ },
40
47
  "setupFiles": [
41
48
  "./scripts/jestSetup.js"
42
49
  ],
@@ -69,120 +76,123 @@
69
76
  "author": "Budibase",
70
77
  "license": "GPL-3.0",
71
78
  "dependencies": {
72
- "@apidevtools/swagger-parser": "^10.0.3",
73
- "@budibase/backend-core": "^1.0.199",
74
- "@budibase/client": "^1.0.199",
75
- "@budibase/pro": "1.0.198",
76
- "@budibase/string-templates": "^1.0.199",
77
- "@bull-board/api": "^3.7.0",
78
- "@bull-board/koa": "^3.7.0",
79
+ "@apidevtools/swagger-parser": "10.0.3",
80
+ "@budibase/backend-core": "^1.0.200-alpha.2",
81
+ "@budibase/client": "^1.0.200-alpha.2",
82
+ "@budibase/pro": "1.0.200-alpha.1",
83
+ "@budibase/string-templates": "^1.0.200-alpha.2",
84
+ "@bull-board/api": "3.7.0",
85
+ "@bull-board/koa": "3.9.4",
79
86
  "@elastic/elasticsearch": "7.10.0",
80
- "@google-cloud/firestore": "^5.0.2",
87
+ "@google-cloud/firestore": "5.0.2",
81
88
  "@koa/router": "8.0.0",
82
89
  "@sendgrid/mail": "7.1.1",
83
90
  "@sentry/node": "6.17.7",
84
- "@types/global-agent": "^2.1.1",
85
- "@types/koa__router": "^8.0.11",
86
91
  "airtable": "0.10.1",
87
92
  "arangojs": "7.2.0",
88
- "aws-sdk": "^2.767.0",
93
+ "aws-sdk": "2.1030.0",
89
94
  "bcryptjs": "2.4.3",
90
- "bull": "^3.22.4",
95
+ "bull": "3.29.3",
91
96
  "chmodr": "1.2.0",
92
97
  "csvtojson": "2.0.10",
93
- "curlconverter": "^3.21.0",
98
+ "curlconverter": "3.21.0",
94
99
  "dotenv": "8.2.0",
95
100
  "download": "8.0.0",
96
101
  "fix-path": "3.0.0",
97
- "form-data": "^4.0.0",
102
+ "form-data": "4.0.0",
98
103
  "fs-extra": "8.1.0",
99
- "global-agent": "^3.0.0",
100
- "google-auth-library": "^7.11.0",
101
- "google-spreadsheet": "^3.2.0",
104
+ "global-agent": "3.0.0",
105
+ "google-auth-library": "7.12.0",
106
+ "google-spreadsheet": "3.2.0",
102
107
  "jimp": "0.16.1",
103
108
  "joi": "17.2.1",
104
- "js-yaml": "^4.1.0",
109
+ "js-yaml": "4.1.0",
105
110
  "jsonschema": "1.4.0",
106
- "knex": "^0.95.6",
111
+ "knex": "0.95.15",
107
112
  "koa": "2.7.0",
108
113
  "koa-body": "4.2.0",
109
114
  "koa-compress": "4.0.1",
110
- "koa-connect": "^2.1.0",
115
+ "koa-connect": "2.1.0",
111
116
  "koa-pino-logger": "3.0.0",
112
117
  "koa-send": "5.0.0",
113
118
  "koa-session": "5.12.0",
114
119
  "koa-static": "5.0.0",
115
- "koa2-ratelimit": "^1.1.0",
120
+ "koa2-ratelimit": "1.1.0",
116
121
  "lodash": "4.17.21",
117
- "memorystream": "^0.3.1",
122
+ "memorystream": "0.3.1",
118
123
  "mongodb": "3.6.3",
119
124
  "mssql": "6.2.3",
120
- "mysql2": "^2.3.1",
125
+ "mysql2": "2.3.3",
121
126
  "node-fetch": "2.6.7",
122
- "open": "^8.4.0",
127
+ "open": "8.4.0",
123
128
  "pg": "8.5.1",
124
129
  "pino-pretty": "4.0.0",
125
- "posthog-node": "^1.1.4",
130
+ "posthog-node": "1.3.0",
126
131
  "pouchdb": "7.3.0",
127
- "pouchdb-adapter-memory": "^7.2.1",
132
+ "pouchdb-adapter-memory": "7.2.2",
128
133
  "pouchdb-all-dbs": "1.0.2",
129
- "pouchdb-find": "^7.2.2",
134
+ "pouchdb-find": "7.2.2",
130
135
  "pouchdb-replication-stream": "1.2.9",
131
136
  "redis": "4",
132
137
  "server-destroy": "1.0.1",
133
- "svelte": "^3.38.2",
134
- "swagger-parser": "^10.0.3",
138
+ "svelte": "3.44.1",
139
+ "swagger-parser": "10.0.3",
135
140
  "to-json-schema": "0.2.5",
136
141
  "uuid": "3.3.2",
137
142
  "validate.js": "0.13.1",
138
- "vm2": "^3.9.3",
139
- "worker-farm": "^1.7.0",
140
- "xml2js": "^0.4.23",
143
+ "vm2": "3.9.6",
144
+ "worker-farm": "1.7.0",
145
+ "xml2js": "0.4.23",
141
146
  "yargs": "13.2.4",
142
147
  "zlib": "1.0.5"
143
148
  },
144
149
  "devDependencies": {
145
- "@babel/core": "^7.14.3",
146
- "@babel/preset-env": "^7.14.4",
150
+ "@babel/core": "7.17.4",
151
+ "@babel/preset-env": "7.16.11",
147
152
  "@budibase/standard-components": "^0.9.139",
148
- "@jest/test-sequencer": "^24.8.0",
149
- "@types/apidoc": "^0.50.0",
150
- "@types/bson": "^4.2.0",
151
- "@types/bull": "^3.15.1",
152
- "@types/google-spreadsheet": "^3.1.5",
153
- "@types/jest": "^27.4.1",
154
- "@types/koa": "^2.13.3",
155
- "@types/koa-router": "^7.4.2",
153
+ "@budibase/types": "^1.0.200-alpha.2",
154
+ "@jest/test-sequencer": "24.9.0",
155
+ "@types/apidoc": "0.50.0",
156
+ "@types/bson": "4.2.0",
157
+ "@types/bull": "3.15.8",
158
+ "@types/global-agent": "2.1.1",
159
+ "@types/google-spreadsheet": "3.1.5",
160
+ "@types/jest": "27.5.1",
161
+ "@types/koa": "2.13.4",
162
+ "@types/koa__router": "8.0.0",
156
163
  "@types/lodash": "4.14.180",
157
164
  "@types/mongodb": "3.6.3",
158
- "@types/node": "^15.12.4",
159
- "@types/oracledb": "^5.2.1",
160
- "@types/redis": "^4.0.11",
165
+ "@types/node": "14.18.20",
166
+ "@types/node-fetch": "2.6.1",
167
+ "@types/oracledb": "5.2.2",
168
+ "@types/redis": "4.0.11",
161
169
  "@typescript-eslint/parser": "5.12.0",
162
- "apidoc": "^0.50.2",
163
- "babel-jest": "^27.0.2",
164
- "copyfiles": "^2.4.1",
165
- "docker-compose": "^0.23.6",
166
- "eslint": "^6.8.0",
167
- "ioredis-mock": "^7.2.0",
168
- "is-wsl": "^2.2.0",
169
- "jest": "^27.0.5",
170
- "jest-openapi": "^0.14.2",
171
- "nodemon": "^2.0.4",
172
- "openapi-types": "^9.3.1",
173
- "openapi-typescript": "^5.2.0",
174
- "path-to-regexp": "^6.2.0",
175
- "prettier": "^2.3.1",
176
- "rimraf": "^3.0.2",
177
- "supertest": "^4.0.2",
178
- "swagger-jsdoc": "^6.1.0",
179
- "ts-jest": "^27.0.3",
180
- "ts-node": "^10.0.0",
181
- "typescript": "^4.5.5",
182
- "update-dotenv": "^1.1.1"
170
+ "apidoc": "0.50.4",
171
+ "babel-jest": "27.5.1",
172
+ "copyfiles": "2.4.1",
173
+ "docker-compose": "0.23.17",
174
+ "eslint": "6.8.0",
175
+ "ioredis-mock": "7.2.0",
176
+ "is-wsl": "2.2.0",
177
+ "jest": "27.5.1",
178
+ "jest-openapi": "0.14.2",
179
+ "nodemon": "2.0.15",
180
+ "openapi-types": "9.3.1",
181
+ "openapi-typescript": "5.2.0",
182
+ "path-to-regexp": "6.2.0",
183
+ "prettier": "2.5.1",
184
+ "rimraf": "3.0.2",
185
+ "supertest": "4.0.2",
186
+ "swagger-jsdoc": "6.1.0",
187
+ "timekeeper": "2.2.0",
188
+ "ts-jest": "27.1.3",
189
+ "ts-node": "10.5.0",
190
+ "tsconfig-paths": "4.0.0",
191
+ "typescript": "4.6.2",
192
+ "update-dotenv": "1.1.1"
183
193
  },
184
194
  "optionalDependencies": {
185
- "oracledb": "^5.3.0"
195
+ "oracledb": "5.3.0"
186
196
  },
187
- "gitHead": "2c737c1a615123b11482a239e7044356b27a268a"
197
+ "gitHead": "a35a4d60c0136d5996d8a1d4c65a76c51d318b99"
188
198
  }
@@ -54,6 +54,8 @@ async function init() {
54
54
  DISABLE_ACCOUNT_PORTAL: "",
55
55
  MULTI_TENANCY: "",
56
56
  DISABLE_THREADING: 1,
57
+ SERVICE: "app-service",
58
+ DEPLOYMENT_ENVIRONMENT: "development",
57
59
  }
58
60
  let envFile = ""
59
61
  Object.keys(envFileJson).forEach(key => {
@@ -9,4 +9,11 @@ env._set("BUDIBASE_DIR", tmpdir("budibase-unittests"))
9
9
  env._set("LOG_LEVEL", "silent")
10
10
  env._set("PORT", 0)
11
11
 
12
+ const { mocks } = require("@budibase/backend-core/tests")
13
+
14
+ // mock all dates to 2020-01-01T00:00:00.000Z
15
+ // use tk.reset() to use real dates in individual tests
16
+ const tk = require("timekeeper")
17
+ tk.freeze(mocks.date.MOCK_DATE)
18
+
12
19
  global.console.log = jest.fn() // console.log are ignored in tests
@@ -10,7 +10,7 @@ const WORKER_PORT = "4200"
10
10
 
11
11
  // @ts-ignore
12
12
  process.env.NODE_ENV = "cypress"
13
- process.env.ENABLE_ANALYTICS = "false"
13
+ process.env.ENABLE_ANALYTICS = "0"
14
14
  process.env.JWT_SECRET = "budibase"
15
15
  process.env.COUCH_URL = `leveldb://${tmpdir}/.data/`
16
16
  process.env.SELF_HOSTED = "1"
@@ -0,0 +1,8 @@
1
+ import { events } from "@budibase/backend-core"
2
+
3
+ export const isEnabled = async (ctx: any) => {
4
+ const enabled = await events.analytics.enabled()
5
+ ctx.body = {
6
+ enabled,
7
+ }
8
+ }
@@ -52,7 +52,8 @@ const {
52
52
  } = require("@budibase/backend-core/context")
53
53
  import { getUniqueRows } from "../../utilities/usageQuota/rows"
54
54
  import { quotas } from "@budibase/pro"
55
- import { errors } from "@budibase/backend-core"
55
+ import { errors, events, migrations } from "@budibase/backend-core"
56
+ import { App, MigrationType } from "@budibase/types"
56
57
 
57
58
  const URL_REGEX_SLASH = /\/|\\/g
58
59
 
@@ -234,7 +235,7 @@ const performAppCreate = async (ctx: any) => {
234
235
  const apps = await getAllApps({ dev: true })
235
236
  const name = ctx.request.body.name
236
237
  checkAppName(ctx, apps, name)
237
- const url = exports.getAppUrl(ctx)
238
+ const url = getAppUrl(ctx)
238
239
  checkAppUrl(ctx, apps, url)
239
240
 
240
241
  const { useTemplate, templateKey, templateString } = ctx.request.body
@@ -258,7 +259,7 @@ const performAppCreate = async (ctx: any) => {
258
259
  } catch (err) {
259
260
  // nothing to do
260
261
  }
261
- const newApplication = {
262
+ const newApplication: App = {
262
263
  _id: DocumentTypes.APP_METADATA,
263
264
  _rev,
264
265
  appId: instance._id,
@@ -292,10 +293,42 @@ const performAppCreate = async (ctx: any) => {
292
293
  return newApplication
293
294
  }
294
295
 
295
- const appPostCreate = async (ctx: any, appId: string) => {
296
+ const creationEvents = async (request: any, app: App) => {
297
+ let creationFns: ((app: App) => Promise<void>)[] = []
298
+
299
+ const body = request.body
300
+ if (body.useTemplate === "true") {
301
+ // from template
302
+ if (body.templateKey && body.templateKey !== "undefined") {
303
+ creationFns.push(a => events.app.templateImported(a, body.templateKey))
304
+ }
305
+ // from file
306
+ else if (request.files?.templateFile) {
307
+ creationFns.push(a => events.app.fileImported(a))
308
+ }
309
+ // unknown
310
+ else {
311
+ console.error("Could not determine template creation event")
312
+ }
313
+ }
314
+ creationFns.push(a => events.app.created(a))
315
+
316
+ for (let fn of creationFns) {
317
+ await fn(app)
318
+ }
319
+ }
320
+
321
+ const appPostCreate = async (ctx: any, app: App) => {
322
+ const tenantId = getTenantId()
323
+ await migrations.backPopulateMigrations({
324
+ type: MigrationType.APP,
325
+ tenantId,
326
+ appId: app.appId,
327
+ })
328
+ await creationEvents(ctx.request, app)
296
329
  // app import & template creation
297
330
  if (ctx.request.body.useTemplate === "true") {
298
- const rows = await getUniqueRows([appId])
331
+ const rows = await getUniqueRows([app.appId])
299
332
  const rowCount = rows ? rows.length : 0
300
333
  if (rowCount) {
301
334
  try {
@@ -305,7 +338,7 @@ const appPostCreate = async (ctx: any, appId: string) => {
305
338
  // this import resulted in row usage exceeding the quota
306
339
  // delete the app
307
340
  // skip pre and post steps as no rows have been added to quotas yet
308
- ctx.params.appId = appId
341
+ ctx.params.appId = app.appId
309
342
  await destroyApp(ctx)
310
343
  }
311
344
  throw err
@@ -316,7 +349,7 @@ const appPostCreate = async (ctx: any, appId: string) => {
316
349
 
317
350
  export const create = async (ctx: any) => {
318
351
  const newApplication = await quotas.addApp(() => performAppCreate(ctx))
319
- await appPostCreate(ctx, newApplication.appId)
352
+ await appPostCreate(ctx, newApplication)
320
353
  await bustCache(CacheKeys.CHECKLIST)
321
354
  ctx.body = newApplication
322
355
  ctx.status = 200
@@ -331,15 +364,16 @@ export const update = async (ctx: any) => {
331
364
  if (name) {
332
365
  checkAppName(ctx, apps, name, ctx.params.appId)
333
366
  }
334
- const url = await exports.getAppUrl(ctx)
367
+ const url = getAppUrl(ctx)
335
368
  if (url) {
336
369
  checkAppUrl(ctx, apps, url, ctx.params.appId)
337
370
  ctx.request.body.url = url
338
371
  }
339
372
 
340
- const data = await updateAppPackage(ctx.request.body, ctx.params.appId)
373
+ const app = await updateAppPackage(ctx.request.body, ctx.params.appId)
374
+ await events.app.updated(app)
341
375
  ctx.status = 200
342
- ctx.body = data
376
+ ctx.body = app
343
377
  }
344
378
 
345
379
  export const updateClient = async (ctx: any) => {
@@ -355,13 +389,15 @@ export const updateClient = async (ctx: any) => {
355
389
  }
356
390
 
357
391
  // Update versions in app package
392
+ const updatedToVersion = packageJson.version
358
393
  const appPackageUpdates = {
359
- version: packageJson.version,
394
+ version: updatedToVersion,
360
395
  revertableVersion: currentVersion,
361
396
  }
362
- const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
397
+ const app = await updateAppPackage(appPackageUpdates, ctx.params.appId)
398
+ await events.app.versionUpdated(app, currentVersion, updatedToVersion)
363
399
  ctx.status = 200
364
- ctx.body = data
400
+ ctx.body = app
365
401
  }
366
402
 
367
403
  export const revertClient = async (ctx: any) => {
@@ -378,13 +414,16 @@ export const revertClient = async (ctx: any) => {
378
414
  }
379
415
 
380
416
  // Update versions in app package
417
+ const currentVersion = application.version
418
+ const revertedToVersion = application.revertableVersion
381
419
  const appPackageUpdates = {
382
- version: application.revertableVersion,
420
+ version: revertedToVersion,
383
421
  revertableVersion: null,
384
422
  }
385
- const data = await updateAppPackage(appPackageUpdates, ctx.params.appId)
423
+ const app = await updateAppPackage(appPackageUpdates, ctx.params.appId)
424
+ await events.app.versionReverted(app, currentVersion, revertedToVersion)
386
425
  ctx.status = 200
387
- ctx.body = data
426
+ ctx.body = app
388
427
  }
389
428
 
390
429
  const destroyApp = async (ctx: any) => {
@@ -396,12 +435,15 @@ const destroyApp = async (ctx: any) => {
396
435
  }
397
436
 
398
437
  const db = isUnpublish ? getProdAppDB() : getAppDB()
438
+ const app = await db.get(DocumentTypes.APP_METADATA)
399
439
  const result = await db.destroy()
400
440
 
401
441
  if (isUnpublish) {
402
442
  await quotas.removePublishedApp()
443
+ await events.app.unpublished(app)
403
444
  } else {
404
445
  await quotas.removeApp()
446
+ await events.app.deleted(app)
405
447
  }
406
448
 
407
449
  /* istanbul ignore next */
@@ -514,10 +556,10 @@ const updateAppPackage = async (appPackage: any, appId: any) => {
514
556
  // Redis, shouldn't ever store it
515
557
  delete newAppPackage.lockedBy
516
558
 
517
- const response = await db.put(newAppPackage)
559
+ await db.put(newAppPackage)
518
560
  // remove any cached metadata, so that it will be updated
519
561
  await appCache.invalidateAppMetadata(appId)
520
- return response
562
+ return newAppPackage
521
563
  }
522
564
 
523
565
  const createEmptyAppPackage = async (ctx: any, app: any) => {
@@ -10,6 +10,7 @@ const { deleteEntityMetadata } = require("../../utilities")
10
10
  const { MetadataTypes } = require("../../constants")
11
11
  const { setTestFlag, clearTestFlag } = require("../../utilities/redis")
12
12
  const { getAppDB } = require("@budibase/backend-core/context")
13
+ const { events } = require("@budibase/backend-core")
13
14
 
14
15
  const ACTION_DEFS = removeDeprecated(actions.ACTION_DEFINITIONS)
15
16
  const TRIGGER_DEFS = removeDeprecated(triggers.TRIGGER_DEFINITIONS)
@@ -70,6 +71,10 @@ exports.create = async function (ctx) {
70
71
  newAuto: automation,
71
72
  })
72
73
  const response = await db.put(automation)
74
+ await events.automation.created(automation)
75
+ for (let step of automation.definition.steps) {
76
+ await events.automation.stepCreated(automation, step)
77
+ }
73
78
  automation._rev = response.rev
74
79
 
75
80
  ctx.status = 200
@@ -82,6 +87,30 @@ exports.create = async function (ctx) {
82
87
  }
83
88
  }
84
89
 
90
+ const getNewSteps = (oldAutomation, automation) => {
91
+ const oldStepIds = oldAutomation.definition.steps.map(s => s.id)
92
+ return automation.definition.steps.filter(s => !oldStepIds.includes(s.id))
93
+ }
94
+
95
+ const getDeletedSteps = (oldAutomation, automation) => {
96
+ const stepIds = automation.definition.steps.map(s => s.id)
97
+ return oldAutomation.definition.steps.filter(s => !stepIds.includes(s.id))
98
+ }
99
+
100
+ const handleStepEvents = async (oldAutomation, automation) => {
101
+ // new steps
102
+ const newSteps = getNewSteps(oldAutomation, automation)
103
+ for (let step of newSteps) {
104
+ await events.automation.stepCreated(automation, step)
105
+ }
106
+
107
+ // old steps
108
+ const deletedSteps = getDeletedSteps(oldAutomation, automation)
109
+ for (let step of deletedSteps) {
110
+ await events.automation.stepDeleted(automation, step)
111
+ }
112
+ }
113
+
85
114
  exports.update = async function (ctx) {
86
115
  const db = getAppDB()
87
116
  let automation = ctx.request.body
@@ -98,13 +127,14 @@ exports.update = async function (ctx) {
98
127
  const oldAutoTrigger =
99
128
  oldAutomation && oldAutomation.definition.trigger
100
129
  ? oldAutomation.definition.trigger
101
- : {}
130
+ : undefined
102
131
  const newAutoTrigger =
103
132
  automation && automation.definition.trigger
104
133
  ? automation.definition.trigger
105
134
  : {}
106
135
  // trigger has been updated, remove the test inputs
107
- if (oldAutoTrigger.id !== newAutoTrigger.id) {
136
+ if (oldAutoTrigger && oldAutoTrigger.id !== newAutoTrigger.id) {
137
+ await events.automation.triggerUpdated(automation)
108
138
  await deleteEntityMetadata(
109
139
  ctx.appId,
110
140
  MetadataTypes.AUTOMATION_TEST_INPUT,
@@ -112,6 +142,8 @@ exports.update = async function (ctx) {
112
142
  )
113
143
  }
114
144
 
145
+ await handleStepEvents(oldAutomation, automation)
146
+
115
147
  ctx.status = 200
116
148
  ctx.body = {
117
149
  message: `Automation ${automation._id} updated successfully.`,
@@ -148,6 +180,7 @@ exports.destroy = async function (ctx) {
148
180
  // delete metadata first
149
181
  await cleanupAutomationMetadata(automationId)
150
182
  ctx.body = await db.remove(automationId, ctx.params.rev)
183
+ await events.automation.deleted(oldAutomation)
151
184
  }
152
185
 
153
186
  exports.getActionList = async function (ctx) {
@@ -215,4 +248,5 @@ exports.test = async function (ctx) {
215
248
  })
216
249
  await clearTestFlag(automation._id)
217
250
  ctx.body = response
251
+ await events.automation.tested(automation)
218
252
  }
@@ -1,4 +1,6 @@
1
1
  const { streamBackup } = require("../../utilities/fileSystem")
2
+ const { events, context } = require("@budibase/backend-core")
3
+ const { DocumentTypes } = require("../../db/utils")
2
4
 
3
5
  exports.exportAppDump = async function (ctx) {
4
6
  const { appId } = ctx.query
@@ -6,4 +8,10 @@ exports.exportAppDump = async function (ctx) {
6
8
  const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt`
7
9
  ctx.attachment(backupIdentifier)
8
10
  ctx.body = await streamBackup(appId)
11
+
12
+ await context.doInAppContext(appId, async () => {
13
+ const appDb = context.getAppDB()
14
+ const app = await appDb.get(DocumentTypes.APP_METADATA)
15
+ await events.app.exported(app)
16
+ })
9
17
  }
@@ -11,6 +11,7 @@ const { integrations } = require("../../integrations")
11
11
  const { getDatasourceAndQuery } = require("./row/utils")
12
12
  const { invalidateDynamicVariables } = require("../../threads/utils")
13
13
  const { getAppDB } = require("@budibase/backend-core/context")
14
+ const { events } = require("@budibase/backend-core")
14
15
 
15
16
  exports.fetch = async function (ctx) {
16
17
  // Get internal tables
@@ -108,6 +109,7 @@ exports.update = async function (ctx) {
108
109
  }
109
110
 
110
111
  const response = await db.put(datasource)
112
+ await events.datasource.updated(datasource)
111
113
  datasource._rev = response.rev
112
114
 
113
115
  // Drain connection pools when configuration is changed
@@ -142,6 +144,7 @@ exports.save = async function (ctx) {
142
144
  }
143
145
 
144
146
  const dbResp = await db.put(datasource)
147
+ await events.datasource.created(datasource)
145
148
  datasource._rev = dbResp.rev
146
149
 
147
150
  // Drain connection pools when configuration is changed
@@ -161,11 +164,11 @@ exports.save = async function (ctx) {
161
164
 
162
165
  exports.destroy = async function (ctx) {
163
166
  const db = getAppDB()
167
+ const datasourceId = ctx.params.datasourceId
164
168
 
169
+ const datasource = await db.get(datasourceId)
165
170
  // Delete all queries for the datasource
166
- const queries = await db.allDocs(
167
- getQueryParams(ctx.params.datasourceId, null)
168
- )
171
+ const queries = await db.allDocs(getQueryParams(datasourceId, null))
169
172
  await db.bulkDocs(
170
173
  queries.rows.map(row => ({
171
174
  _id: row.id,
@@ -175,7 +178,8 @@ exports.destroy = async function (ctx) {
175
178
  )
176
179
 
177
180
  // delete the datasource
178
- await db.remove(ctx.params.datasourceId, ctx.params.revId)
181
+ await db.remove(datasourceId, ctx.params.revId)
182
+ await events.datasource.deleted(datasource)
179
183
 
180
184
  ctx.message = `Datasource deleted.`
181
185
  ctx.status = 200
@@ -13,6 +13,7 @@ import {
13
13
  getProdAppDB,
14
14
  } from "@budibase/backend-core/context"
15
15
  import { quotas } from "@budibase/pro"
16
+ import { events } from "@budibase/backend-core"
16
17
 
17
18
  // the max time we can wait for an invalidation to complete before considering it failed
18
19
  const MAX_PENDING_TIME_MS = 30 * 60000
@@ -122,6 +123,7 @@ async function deployApp(deployment: any) {
122
123
  console.log("Deployed app initialised, setting deployment to successful")
123
124
  deployment.setStatus(DeploymentStatus.SUCCESS)
124
125
  await storeDeploymentHistory(deployment)
126
+ return appDoc
125
127
  } catch (err: any) {
126
128
  deployment.setStatus(DeploymentStatus.FAILURE, err.message)
127
129
  await storeDeploymentHistory(deployment)
@@ -186,12 +188,14 @@ const _deployApp = async function (ctx: any) {
186
188
 
187
189
  console.log("Deploying app...")
188
190
 
191
+ let app
189
192
  if (await isFirstDeploy()) {
190
- await quotas.addPublishedApp(() => deployApp(deployment))
193
+ app = await quotas.addPublishedApp(() => deployApp(deployment))
191
194
  } else {
192
- await deployApp(deployment)
195
+ app = await deployApp(deployment)
193
196
  }
194
197
 
198
+ await events.app.published(app)
195
199
  ctx.body = deployment
196
200
  }
197
201