@budibase/server 0.9.171 → 0.9.173-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 (261) hide show
  1. package/__mocks__/{mysql.ts → mysql2.ts} +0 -0
  2. package/builder/assets/{index.dbc6728e.css → index.7469e1e4.css} +2 -2
  3. package/builder/assets/{index.cf0febb9.js → index.8a8f7849.js} +34 -34
  4. package/builder/assets/{vendor.54435e8f.js → vendor.278a305c.js} +1 -1
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +973 -849
  7. package/coverage/coverage-final.json +47 -46
  8. package/coverage/lcov-report/api/controllers/analytics.js.html +21 -9
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/application.js.html +186 -84
  11. package/coverage/lcov-report/api/controllers/auth.js.html +37 -10
  12. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/backup.js.html +6 -9
  14. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/dev.js.html +41 -17
  18. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/index.html +71 -71
  20. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/permission.js.html +7 -4
  24. package/coverage/lcov-report/api/controllers/query.js.html +129 -24
  25. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/index.html +5 -5
  29. package/coverage/lcov-report/api/controllers/row/index.js.html +15 -15
  30. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/screen.js.html +9 -9
  34. package/coverage/lcov-report/api/controllers/script.js.html +12 -57
  35. package/coverage/lcov-report/api/controllers/table/index.html +28 -28
  36. package/coverage/lcov-report/api/controllers/table/index.js.html +16 -37
  37. package/coverage/lcov-report/api/controllers/table/utils.js.html +279 -33
  38. package/coverage/lcov-report/api/controllers/templates.js.html +49 -13
  39. package/coverage/lcov-report/api/controllers/user.js.html +3 -3
  40. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.html +19 -19
  42. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/utils.js.html +8 -8
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +54 -15
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  46. package/coverage/lcov-report/api/index.html +1 -1
  47. package/coverage/lcov-report/api/index.js.html +3 -3
  48. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/application.js.html +5 -2
  51. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/dev.js.html +26 -11
  59. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/index.html +9 -9
  61. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/query.js.html +9 -3
  67. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  78. package/coverage/lcov-report/automations/actions.js.html +31 -10
  79. package/coverage/lcov-report/automations/automationUtils.js.html +14 -86
  80. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  81. package/coverage/lcov-report/automations/index.html +37 -37
  82. package/coverage/lcov-report/automations/index.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/bash.js.html +10 -7
  84. package/coverage/lcov-report/automations/steps/createRow.js.html +2 -2
  85. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/deleteRow.js.html +8 -5
  87. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/executeQuery.js.html +10 -7
  89. package/coverage/lcov-report/automations/steps/executeScript.js.html +10 -7
  90. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/index.html +57 -57
  92. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +10 -7
  94. package/coverage/lcov-report/automations/steps/queryRows.js.html +10 -7
  95. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +10 -7
  96. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/updateRow.js.html +14 -14
  99. package/coverage/lcov-report/automations/steps/utils.js.html +10 -10
  100. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  101. package/coverage/lcov-report/automations/thread.js.html +54 -12
  102. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  111. package/coverage/lcov-report/automations/utils.js.html +28 -28
  112. package/coverage/lcov-report/constants/index.html +1 -1
  113. package/coverage/lcov-report/constants/index.js.html +5 -2
  114. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  115. package/coverage/lcov-report/constants/screens.js.html +2 -2
  116. package/coverage/lcov-report/db/client.js.html +1 -1
  117. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  118. package/coverage/lcov-report/db/index.html +1 -1
  119. package/coverage/lcov-report/db/index.js.html +1 -1
  120. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +12 -12
  121. package/coverage/lcov-report/db/linkedRows/index.html +18 -18
  122. package/coverage/lcov-report/db/linkedRows/index.js.html +47 -26
  123. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  124. package/coverage/lcov-report/db/newid.js.html +2 -2
  125. package/coverage/lcov-report/db/utils.js.html +17 -17
  126. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  127. package/coverage/lcov-report/events/index.html +1 -1
  128. package/coverage/lcov-report/events/index.js.html +1 -1
  129. package/coverage/lcov-report/events/utils.js.html +1 -1
  130. package/coverage/lcov-report/index.html +107 -107
  131. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  132. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  133. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  134. package/coverage/lcov-report/middleware/authorized.js.html +2 -2
  135. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  136. package/coverage/lcov-report/middleware/currentapp.js.html +52 -25
  137. package/coverage/lcov-report/middleware/index.html +15 -15
  138. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  139. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  140. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  141. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  142. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  143. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  144. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  145. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  146. package/coverage/lcov-report/utilities/global.js.html +27 -27
  147. package/coverage/lcov-report/utilities/index.html +32 -17
  148. package/coverage/lcov-report/utilities/index.js.html +4 -4
  149. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +29 -8
  150. package/coverage/lcov-report/utilities/queue/index.html +15 -15
  151. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  152. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  153. package/coverage/lcov-report/utilities/rowProcessor/index.html +14 -14
  154. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +38 -8
  155. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  156. package/coverage/lcov-report/utilities/scriptRunner.js.html +143 -0
  157. package/coverage/lcov-report/utilities/security.js.html +1 -1
  158. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  159. package/coverage/lcov-report/utilities/users.js.html +1 -1
  160. package/coverage/lcov-report/utilities/workerRequests.js.html +19 -19
  161. package/coverage/lcov.info +1692 -1452
  162. package/dist/api/controllers/analytics.js +4 -0
  163. package/dist/api/controllers/application.js +185 -171
  164. package/dist/api/controllers/auth.js +12 -2
  165. package/dist/api/controllers/backup.js +4 -4
  166. package/dist/api/controllers/deploy/index.js +3 -16
  167. package/dist/api/controllers/dev.js +17 -11
  168. package/dist/api/controllers/permission.js +1 -0
  169. package/dist/api/controllers/query.js +26 -8
  170. package/dist/api/controllers/row/ExternalRequest.js +46 -5
  171. package/dist/api/controllers/script.js +4 -16
  172. package/dist/api/controllers/table/index.js +5 -10
  173. package/dist/api/controllers/table/utils.js +83 -10
  174. package/dist/api/controllers/templates.js +18 -3
  175. package/dist/api/controllers/view/viewBuilder.js +15 -1
  176. package/dist/api/routes/application.js +1 -0
  177. package/dist/api/routes/dev.js +8 -4
  178. package/dist/api/routes/query.js +3 -1
  179. package/dist/api/routes/tests/utilities/TestFunctions.js +7 -9
  180. package/dist/automations/actions.js +9 -3
  181. package/dist/automations/automationUtils.js +8 -29
  182. package/dist/automations/steps/bash.js +2 -1
  183. package/dist/automations/steps/createRow.js +1 -1
  184. package/dist/automations/steps/deleteRow.js +2 -1
  185. package/dist/automations/steps/executeQuery.js +2 -1
  186. package/dist/automations/steps/executeScript.js +2 -1
  187. package/dist/automations/steps/outgoingWebhook.js +2 -1
  188. package/dist/automations/steps/queryRows.js +2 -1
  189. package/dist/automations/steps/sendSmtpEmail.js +2 -1
  190. package/dist/automations/steps/updateRow.js +6 -2
  191. package/dist/automations/thread.js +14 -3
  192. package/dist/constants/index.js +1 -0
  193. package/dist/db/linkedRows/index.js +9 -6
  194. package/dist/integrations/base/sql.js +4 -4
  195. package/dist/integrations/mysql.js +1 -1
  196. package/dist/integrations/utils.js +17 -1
  197. package/dist/middleware/currentapp.js +8 -2
  198. package/dist/package.json +7 -6
  199. package/dist/tests/utilities/TestConfiguration.js +34 -19
  200. package/dist/tests/utilities/controllers.js +1 -0
  201. package/dist/tsconfig.tsbuildinfo +1 -1
  202. package/dist/utilities/fileSystem/index.js +49 -33
  203. package/dist/utilities/global.js +1 -1
  204. package/dist/utilities/queue/inMemoryQueue.js +6 -0
  205. package/dist/utilities/rowProcessor/index.js +8 -0
  206. package/dist/utilities/scriptRunner.js +19 -0
  207. package/package.json +8 -7
  208. package/scripts/jestSetup.js +2 -0
  209. package/src/api/controllers/analytics.js +4 -0
  210. package/src/api/controllers/application.js +43 -9
  211. package/src/api/controllers/auth.js +12 -3
  212. package/src/api/controllers/backup.js +4 -5
  213. package/src/api/controllers/deploy/index.js +3 -18
  214. package/src/api/controllers/dev.js +16 -8
  215. package/src/api/controllers/permission.js +1 -0
  216. package/src/api/controllers/query.js +46 -11
  217. package/src/api/controllers/row/ExternalRequest.ts +53 -4
  218. package/src/api/controllers/script.js +4 -19
  219. package/src/api/controllers/table/index.js +5 -12
  220. package/src/api/controllers/table/utils.js +94 -12
  221. package/src/api/controllers/templates.js +17 -5
  222. package/src/api/controllers/view/tests/__snapshots__/viewBuilder.spec.js.snap +1 -1
  223. package/src/api/controllers/view/viewBuilder.js +14 -1
  224. package/src/api/routes/application.js +1 -0
  225. package/src/api/routes/dev.js +9 -4
  226. package/src/api/routes/query.js +3 -1
  227. package/src/api/routes/tests/auth.spec.js +1 -2
  228. package/src/api/routes/tests/permissions.spec.js +3 -0
  229. package/src/api/routes/tests/query.spec.js +2 -2
  230. package/src/api/routes/tests/routing.spec.js +24 -8
  231. package/src/api/routes/tests/user.spec.js +1 -1
  232. package/src/api/routes/tests/utilities/TestFunctions.js +7 -9
  233. package/src/api/routes/tests/webhook.spec.js +4 -1
  234. package/src/automations/actions.js +10 -3
  235. package/src/automations/automationUtils.js +7 -31
  236. package/src/automations/steps/bash.js +2 -1
  237. package/src/automations/steps/createRow.js +1 -1
  238. package/src/automations/steps/deleteRow.js +2 -1
  239. package/src/automations/steps/executeQuery.js +2 -1
  240. package/src/automations/steps/executeScript.js +2 -1
  241. package/src/automations/steps/outgoingWebhook.js +2 -1
  242. package/src/automations/steps/queryRows.js +2 -1
  243. package/src/automations/steps/sendSmtpEmail.js +2 -1
  244. package/src/automations/steps/updateRow.js +6 -6
  245. package/src/automations/thread.js +17 -3
  246. package/src/constants/index.js +1 -0
  247. package/src/db/linkedRows/index.js +14 -7
  248. package/src/integrations/base/sql.ts +11 -3
  249. package/src/integrations/mysql.ts +1 -1
  250. package/src/integrations/tests/mongo.spec.js +10 -6
  251. package/src/integrations/tests/mysql.spec.js +1 -1
  252. package/src/integrations/utils.ts +18 -0
  253. package/src/middleware/currentapp.js +11 -2
  254. package/src/middleware/tests/currentapp.spec.js +3 -3
  255. package/src/tests/utilities/TestConfiguration.js +47 -19
  256. package/src/tests/utilities/controllers.js +1 -0
  257. package/src/utilities/fileSystem/index.js +65 -43
  258. package/src/utilities/global.js +1 -1
  259. package/src/utilities/queue/inMemoryQueue.js +7 -0
  260. package/src/utilities/rowProcessor/index.js +10 -0
  261. package/src/utilities/scriptRunner.js +21 -0
@@ -26,6 +26,10 @@ exports.endUserPing = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
26
26
  };
27
27
  return;
28
28
  }
29
+ posthogClient.identify({
30
+ distinctId: ctx.user && ctx.user._id,
31
+ properties: {},
32
+ });
29
33
  posthogClient.capture({
30
34
  event: "budibase:end_user_ping",
31
35
  distinctId: ctx.user && ctx.user._id,
@@ -19,7 +19,7 @@ const { BASE_LAYOUTS } = require("../../constants/layouts");
19
19
  const { createHomeScreen } = require("../../constants/screens");
20
20
  const { cloneDeep } = require("lodash/fp");
21
21
  const { processObject } = require("@budibase/string-templates");
22
- const { getAllApps } = require("@budibase/auth/db");
22
+ const { getAllApps, isDevAppID, getDeployedAppID, Replication, } = require("@budibase/auth/db");
23
23
  const { USERS_TABLE_SCHEMA } = require("../../constants");
24
24
  const { getDeployedApps, removeAppFromUserRoles, } = require("../../utilities/workerRequests");
25
25
  const { clientLibraryPath, stringToReadStream } = require("../../utilities");
@@ -111,183 +111,197 @@ function createInstance(template) {
111
111
  return { _id: appId };
112
112
  });
113
113
  }
114
- exports.fetch = function (ctx) {
115
- return __awaiter(this, void 0, void 0, function* () {
116
- const dev = ctx.query && ctx.query.status === AppStatus.DEV;
117
- const all = ctx.query && ctx.query.status === AppStatus.ALL;
118
- const apps = yield getAllApps(CouchDB, { dev, all });
119
- // get the locks for all the dev apps
120
- if (dev || all) {
121
- const locks = yield getAllLocks();
122
- for (let app of apps) {
123
- if (app.status !== "development") {
124
- continue;
125
- }
126
- const lock = locks.find(lock => lock.appId === app.appId);
127
- if (lock) {
128
- app.lockedBy = lock.user;
129
- }
130
- else {
131
- // make sure its definitely not present
132
- delete app.lockedBy;
133
- }
114
+ exports.fetch = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
115
+ const dev = ctx.query && ctx.query.status === AppStatus.DEV;
116
+ const all = ctx.query && ctx.query.status === AppStatus.ALL;
117
+ const apps = yield getAllApps(CouchDB, { dev, all });
118
+ // get the locks for all the dev apps
119
+ if (dev || all) {
120
+ const locks = yield getAllLocks();
121
+ for (let app of apps) {
122
+ if (app.status !== "development") {
123
+ continue;
124
+ }
125
+ const lock = locks.find(lock => lock.appId === app.appId);
126
+ if (lock) {
127
+ app.lockedBy = lock.user;
128
+ }
129
+ else {
130
+ // make sure its definitely not present
131
+ delete app.lockedBy;
134
132
  }
135
133
  }
136
- ctx.body = apps;
137
- });
138
- };
139
- exports.fetchAppDefinition = function (ctx) {
140
- return __awaiter(this, void 0, void 0, function* () {
141
- const db = new CouchDB(ctx.params.appId);
142
- const layouts = yield getLayouts(db);
134
+ }
135
+ ctx.body = apps;
136
+ });
137
+ exports.fetchAppDefinition = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
138
+ const db = new CouchDB(ctx.params.appId);
139
+ const layouts = yield getLayouts(db);
140
+ const userRoleId = getUserRoleId(ctx);
141
+ const accessController = new AccessController(ctx.params.appId);
142
+ const screens = yield accessController.checkScreensAccess(yield getScreens(db), userRoleId);
143
+ ctx.body = {
144
+ layouts,
145
+ screens,
146
+ libraries: ["@budibase/standard-components"],
147
+ };
148
+ });
149
+ exports.fetchAppPackage = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
150
+ const db = new CouchDB(ctx.params.appId);
151
+ const application = yield db.get(DocumentTypes.APP_METADATA);
152
+ const layouts = yield getLayouts(db);
153
+ let screens = yield getScreens(db);
154
+ // Only filter screens if the user is not a builder
155
+ if (!(ctx.user.builder && ctx.user.builder.global)) {
143
156
  const userRoleId = getUserRoleId(ctx);
144
157
  const accessController = new AccessController(ctx.params.appId);
145
- const screens = yield accessController.checkScreensAccess(yield getScreens(db), userRoleId);
146
- ctx.body = {
147
- layouts,
148
- screens,
149
- libraries: ["@budibase/standard-components"],
150
- };
158
+ screens = yield accessController.checkScreensAccess(screens, userRoleId);
159
+ }
160
+ ctx.body = {
161
+ application,
162
+ screens,
163
+ layouts,
164
+ clientLibPath: clientLibraryPath(ctx.params.appId),
165
+ };
166
+ });
167
+ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
168
+ const { useTemplate, templateKey, templateString } = ctx.request.body;
169
+ const instanceConfig = {
170
+ useTemplate,
171
+ key: templateKey,
172
+ templateString,
173
+ };
174
+ if (ctx.request.files && ctx.request.files.templateFile) {
175
+ instanceConfig.file = ctx.request.files.templateFile;
176
+ }
177
+ const instance = yield createInstance(instanceConfig);
178
+ const appId = instance._id;
179
+ const url = yield getAppUrlIfNotInUse(ctx);
180
+ const db = new CouchDB(appId);
181
+ let _rev;
182
+ try {
183
+ // if template there will be an existing doc
184
+ const existing = yield db.get(DocumentTypes.APP_METADATA);
185
+ _rev = existing._rev;
186
+ }
187
+ catch (err) {
188
+ // nothing to do
189
+ }
190
+ const newApplication = {
191
+ _id: DocumentTypes.APP_METADATA,
192
+ _rev,
193
+ appId: instance._id,
194
+ type: "app",
195
+ version: packageJson.version,
196
+ componentLibraries: ["@budibase/standard-components"],
197
+ name: ctx.request.body.name,
198
+ url: url,
199
+ template: ctx.request.body.template,
200
+ instance: instance,
201
+ tenantId: getTenantId(),
202
+ updatedAt: new Date().toISOString(),
203
+ createdAt: new Date().toISOString(),
204
+ };
205
+ const response = yield db.put(newApplication, { force: true });
206
+ newApplication._rev = response.rev;
207
+ // Only create the default home screens and layout if we aren't importing
208
+ // an app
209
+ if (useTemplate !== "true") {
210
+ yield createEmptyAppPackage(ctx, newApplication);
211
+ }
212
+ /* istanbul ignore next */
213
+ if (!env.isTest()) {
214
+ yield createApp(appId);
215
+ }
216
+ ctx.status = 200;
217
+ ctx.body = newApplication;
218
+ });
219
+ exports.update = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
220
+ const data = yield updateAppPackage(ctx, ctx.request.body, ctx.params.appId);
221
+ ctx.status = 200;
222
+ ctx.body = data;
223
+ });
224
+ exports.updateClient = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
225
+ // Get current app version
226
+ const db = new CouchDB(ctx.params.appId);
227
+ const application = yield db.get(DocumentTypes.APP_METADATA);
228
+ const currentVersion = application.version;
229
+ // Update client library and manifest
230
+ if (!env.isTest()) {
231
+ yield backupClientLibrary(ctx.params.appId);
232
+ yield updateClientLibrary(ctx.params.appId);
233
+ }
234
+ // Update versions in app package
235
+ const appPackageUpdates = {
236
+ version: packageJson.version,
237
+ revertableVersion: currentVersion,
238
+ };
239
+ const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
240
+ ctx.status = 200;
241
+ ctx.body = data;
242
+ });
243
+ exports.revertClient = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
244
+ // Check app can be reverted
245
+ const db = new CouchDB(ctx.params.appId);
246
+ const application = yield db.get(DocumentTypes.APP_METADATA);
247
+ if (!application.revertableVersion) {
248
+ ctx.throw(400, "There is no version to revert to");
249
+ }
250
+ // Update client library and manifest
251
+ if (!env.isTest()) {
252
+ yield revertClientLibrary(ctx.params.appId);
253
+ }
254
+ // Update versions in app package
255
+ const appPackageUpdates = {
256
+ version: application.revertableVersion,
257
+ revertableVersion: null,
258
+ };
259
+ const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
260
+ ctx.status = 200;
261
+ ctx.body = data;
262
+ });
263
+ exports.delete = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
264
+ const db = new CouchDB(ctx.params.appId);
265
+ const result = yield db.destroy();
266
+ /* istanbul ignore next */
267
+ if (!env.isTest() && !ctx.query.unpublish) {
268
+ yield deleteApp(ctx.params.appId);
269
+ }
270
+ // make sure the app/role doesn't stick around after the app has been deleted
271
+ yield removeAppFromUserRoles(ctx, ctx.params.appId);
272
+ ctx.status = 200;
273
+ ctx.body = result;
274
+ });
275
+ exports.sync = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
276
+ const appId = ctx.params.appId;
277
+ if (!isDevAppID(appId)) {
278
+ ctx.throw(400, "This action cannot be performed for production apps");
279
+ }
280
+ const prodAppId = getDeployedAppID(appId);
281
+ const replication = new Replication({
282
+ source: prodAppId,
283
+ target: appId,
151
284
  });
152
- };
153
- exports.fetchAppPackage = function (ctx) {
154
- return __awaiter(this, void 0, void 0, function* () {
155
- const db = new CouchDB(ctx.params.appId);
156
- const application = yield db.get(DocumentTypes.APP_METADATA);
157
- const layouts = yield getLayouts(db);
158
- let screens = yield getScreens(db);
159
- // Only filter screens if the user is not a builder
160
- if (!(ctx.user.builder && ctx.user.builder.global)) {
161
- const userRoleId = getUserRoleId(ctx);
162
- const accessController = new AccessController(ctx.params.appId);
163
- screens = yield accessController.checkScreensAccess(screens, userRoleId);
164
- }
285
+ let error;
286
+ try {
287
+ yield replication.replicate({
288
+ filter: function (doc) {
289
+ return doc._id !== DocumentTypes.APP_METADATA;
290
+ },
291
+ });
292
+ }
293
+ catch (err) {
294
+ error = err;
295
+ }
296
+ if (error) {
297
+ ctx.throw(400, error);
298
+ }
299
+ else {
165
300
  ctx.body = {
166
- application,
167
- screens,
168
- layouts,
169
- clientLibPath: clientLibraryPath(ctx.params.appId),
170
- };
171
- });
172
- };
173
- exports.create = function (ctx) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- const { useTemplate, templateKey, templateString } = ctx.request.body;
176
- const instanceConfig = {
177
- useTemplate,
178
- key: templateKey,
179
- templateString,
180
- };
181
- if (ctx.request.files && ctx.request.files.templateFile) {
182
- instanceConfig.file = ctx.request.files.templateFile;
183
- }
184
- const instance = yield createInstance(instanceConfig);
185
- const appId = instance._id;
186
- const url = yield getAppUrlIfNotInUse(ctx);
187
- const db = new CouchDB(appId);
188
- let _rev;
189
- try {
190
- // if template there will be an existing doc
191
- const existing = yield db.get(DocumentTypes.APP_METADATA);
192
- _rev = existing._rev;
193
- }
194
- catch (err) {
195
- // nothing to do
196
- }
197
- const newApplication = {
198
- _id: DocumentTypes.APP_METADATA,
199
- _rev,
200
- appId: instance._id,
201
- type: "app",
202
- version: packageJson.version,
203
- componentLibraries: ["@budibase/standard-components"],
204
- name: ctx.request.body.name,
205
- url: url,
206
- template: ctx.request.body.template,
207
- instance: instance,
208
- tenantId: getTenantId(),
209
- updatedAt: new Date().toISOString(),
210
- createdAt: new Date().toISOString(),
211
- };
212
- const response = yield db.put(newApplication, { force: true });
213
- newApplication._rev = response.rev;
214
- // Only create the default home screens and layout if we aren't importing
215
- // an app
216
- if (useTemplate !== "true") {
217
- yield createEmptyAppPackage(ctx, newApplication);
218
- }
219
- /* istanbul ignore next */
220
- if (!env.isTest()) {
221
- yield createApp(appId);
222
- }
223
- ctx.status = 200;
224
- ctx.body = newApplication;
225
- });
226
- };
227
- exports.update = function (ctx) {
228
- return __awaiter(this, void 0, void 0, function* () {
229
- const data = yield updateAppPackage(ctx, ctx.request.body, ctx.params.appId);
230
- ctx.status = 200;
231
- ctx.body = data;
232
- });
233
- };
234
- exports.updateClient = function (ctx) {
235
- return __awaiter(this, void 0, void 0, function* () {
236
- // Get current app version
237
- const db = new CouchDB(ctx.params.appId);
238
- const application = yield db.get(DocumentTypes.APP_METADATA);
239
- const currentVersion = application.version;
240
- // Update client library and manifest
241
- if (!env.isTest()) {
242
- yield backupClientLibrary(ctx.params.appId);
243
- yield updateClientLibrary(ctx.params.appId);
244
- }
245
- // Update versions in app package
246
- const appPackageUpdates = {
247
- version: packageJson.version,
248
- revertableVersion: currentVersion,
249
- };
250
- const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
251
- ctx.status = 200;
252
- ctx.body = data;
253
- });
254
- };
255
- exports.revertClient = function (ctx) {
256
- return __awaiter(this, void 0, void 0, function* () {
257
- // Check app can be reverted
258
- const db = new CouchDB(ctx.params.appId);
259
- const application = yield db.get(DocumentTypes.APP_METADATA);
260
- if (!application.revertableVersion) {
261
- ctx.throw(400, "There is no version to revert to");
262
- }
263
- // Update client library and manifest
264
- if (!env.isTest()) {
265
- yield revertClientLibrary(ctx.params.appId);
266
- }
267
- // Update versions in app package
268
- const appPackageUpdates = {
269
- version: application.revertableVersion,
270
- revertableVersion: null,
301
+ message: "App sync completed successfully.",
271
302
  };
272
- const data = yield updateAppPackage(ctx, appPackageUpdates, ctx.params.appId);
273
- ctx.status = 200;
274
- ctx.body = data;
275
- });
276
- };
277
- exports.delete = function (ctx) {
278
- return __awaiter(this, void 0, void 0, function* () {
279
- const db = new CouchDB(ctx.params.appId);
280
- const result = yield db.destroy();
281
- /* istanbul ignore next */
282
- if (!env.isTest() && !ctx.query.unpublish) {
283
- yield deleteApp(ctx.params.appId);
284
- }
285
- // make sure the app/role doesn't stick around after the app has been deleted
286
- yield removeAppFromUserRoles(ctx, ctx.params.appId);
287
- ctx.status = 200;
288
- ctx.body = result;
289
- });
290
- };
303
+ }
304
+ });
291
305
  const updateAppPackage = (ctx, appPackage, appId) => __awaiter(void 0, void 0, void 0, function* () {
292
306
  const url = yield getAppUrlIfNotInUse(ctx);
293
307
  const db = new CouchDB(appId);
@@ -33,14 +33,24 @@ exports.fetchSelf = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
33
33
  ctx.body = yield outputProcessing(ctx, userTable, Object.assign(Object.assign({}, user), metadata));
34
34
  }
35
35
  catch (err) {
36
+ let response;
36
37
  // user didn't exist in app, don't pretend they do
37
38
  if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) {
38
- ctx.body = {};
39
+ response = {};
39
40
  }
40
41
  // user has a role of some sort, return them
42
+ else if (err.status === 404) {
43
+ const metadata = {
44
+ _id: userId,
45
+ };
46
+ const dbResp = yield db.put(metadata);
47
+ user._rev = dbResp.rev;
48
+ response = user;
49
+ }
41
50
  else {
42
- ctx.body = user;
51
+ response = user;
43
52
  }
53
+ ctx.body = response;
44
54
  }
45
55
  }
46
56
  else {
@@ -8,13 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- const { performBackup } = require("../../utilities/fileSystem");
11
+ const { streamBackup } = require("../../utilities/fileSystem");
12
12
  exports.exportAppDump = function (ctx) {
13
13
  return __awaiter(this, void 0, void 0, function* () {
14
14
  const { appId } = ctx.query;
15
- const appname = decodeURI(ctx.query.appname);
16
- const backupIdentifier = `${appname}Backup${new Date().getTime()}.txt`;
15
+ const appName = decodeURI(ctx.query.appname);
16
+ const backupIdentifier = `${appName}-export-${new Date().getTime()}.txt`;
17
17
  ctx.attachment(backupIdentifier);
18
- ctx.body = yield performBackup(appId, backupIdentifier);
18
+ ctx.body = yield streamBackup(appId);
19
19
  });
20
20
  };
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const CouchDB = require("../../../db");
12
12
  const Deployment = require("./Deployment");
13
- const { Replication } = require("@budibase/auth/db");
13
+ const { Replication, getDeployedAppID } = require("@budibase/auth/db");
14
14
  const { DocumentTypes, getAutomationParams } = require("../../../db/utils");
15
15
  const { disableAllCrons, enableCronTrigger, } = require("../../../automations/utils");
16
16
  // the max time we can wait for an invalidation to complete before considering it failed
@@ -82,7 +82,7 @@ function initDeployedApp(prodAppId) {
82
82
  function deployApp(deployment) {
83
83
  return __awaiter(this, void 0, void 0, function* () {
84
84
  try {
85
- const productionAppId = deployment.appId.replace("_dev", "");
85
+ const productionAppId = getDeployedAppID(deployment.appId);
86
86
  const replication = new Replication({
87
87
  source: deployment.appId,
88
88
  target: productionAppId,
@@ -96,21 +96,8 @@ function deployApp(deployment) {
96
96
  appDoc.instance._id = productionAppId;
97
97
  yield db.put(appDoc);
98
98
  console.log("New app doc written successfully.");
99
- console.log("Setting up live repl between dev and prod");
100
- // Set up live sync between the live and dev instances
101
- const liveReplication = new Replication({
102
- source: productionAppId,
103
- target: deployment.appId,
104
- });
105
- liveReplication.subscribe({
106
- filter: function (doc) {
107
- return doc._id !== DocumentTypes.APP_METADATA;
108
- },
109
- });
110
- console.log("Set up live repl between dev and prod");
111
- console.log("Initialising deployed app");
112
99
  yield initDeployedApp(productionAppId);
113
- console.log("Init complete, setting deployment to successful");
100
+ console.log("Deployed app initialised, setting deployment to successful");
114
101
  deployment.setStatus(DeploymentStatus.SUCCESS);
115
102
  yield storeDeploymentHistory(deployment);
116
103
  }
@@ -16,11 +16,11 @@ const { request } = require("../../utilities/workerRequests");
16
16
  const { clearLock } = require("../../utilities/redis");
17
17
  const { Replication } = require("@budibase/auth").db;
18
18
  const { DocumentTypes } = require("../../db/utils");
19
- function redirect(ctx, method) {
19
+ function redirect(ctx, method, path = "global") {
20
20
  return __awaiter(this, void 0, void 0, function* () {
21
21
  const { devPath } = ctx.params;
22
22
  const queryString = ctx.originalUrl.split("?")[1] || "";
23
- const response = yield fetch(checkSlashesInUrl(`${env.WORKER_URL}/api/global/${devPath}?${queryString}`), request(ctx, {
23
+ const response = yield fetch(checkSlashesInUrl(`${env.WORKER_URL}/api/${path}/${devPath}?${queryString}`), request(ctx, {
24
24
  method,
25
25
  body: ctx.request.body,
26
26
  }, true));
@@ -45,15 +45,21 @@ function redirect(ctx, method) {
45
45
  ctx.cookies;
46
46
  });
47
47
  }
48
- exports.redirectGet = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
49
- yield redirect(ctx, "GET");
50
- });
51
- exports.redirectPost = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
52
- yield redirect(ctx, "POST");
53
- });
54
- exports.redirectDelete = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
55
- yield redirect(ctx, "DELETE");
56
- });
48
+ exports.buildRedirectGet = path => {
49
+ return (ctx) => __awaiter(void 0, void 0, void 0, function* () {
50
+ yield redirect(ctx, "GET", path);
51
+ });
52
+ };
53
+ exports.buildRedirectPost = path => {
54
+ return (ctx) => __awaiter(void 0, void 0, void 0, function* () {
55
+ yield redirect(ctx, "POST", path);
56
+ });
57
+ };
58
+ exports.buildRedirectDelete = path => {
59
+ return (ctx) => __awaiter(void 0, void 0, void 0, function* () {
60
+ yield redirect(ctx, "DELETE", path);
61
+ });
62
+ };
57
63
  exports.clearLock = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
58
64
  const { appId } = ctx.params;
59
65
  try {
@@ -132,6 +132,7 @@ exports.getResourcePerms = function (ctx) {
132
132
  for (let role of roles) {
133
133
  const rolePerms = role.permissions;
134
134
  if (rolePerms &&
135
+ rolePerms[resourceId] &&
135
136
  (rolePerms[resourceId] === level ||
136
137
  rolePerms[resourceId].indexOf(level) !== -1)) {
137
138
  permissions[level] = getExternalRoleID(role._id);
@@ -14,6 +14,7 @@ const { generateQueryID, getQueryParams } = require("../../db/utils");
14
14
  const { integrations } = require("../../integrations");
15
15
  const { BaseQueryVerbs } = require("../../constants");
16
16
  const env = require("../../environment");
17
+ const ScriptRunner = require("../../utilities/scriptRunner");
17
18
  // simple function to append "readable" to all read queries
18
19
  function enrichQueries(input) {
19
20
  const wasArray = Array.isArray(input);
@@ -35,11 +36,29 @@ function formatResponse(resp) {
35
36
  resp = { response: resp };
36
37
  }
37
38
  }
38
- if (!Array.isArray(resp)) {
39
- resp = [resp];
40
- }
41
39
  return resp;
42
40
  }
41
+ function runAndTransform(integration, queryVerb, enrichedQuery, transformer) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ let rows = formatResponse(yield integration[queryVerb](enrichedQuery));
44
+ // transform as required
45
+ if (transformer) {
46
+ const runner = new ScriptRunner(transformer, { data: rows });
47
+ rows = runner.execute();
48
+ }
49
+ // needs to an array for next step
50
+ if (!Array.isArray(rows)) {
51
+ rows = [rows];
52
+ }
53
+ // map into JSON if just raw primitive here
54
+ if (rows.find(row => typeof row !== "object")) {
55
+ rows = rows.map(value => ({ value }));
56
+ }
57
+ // get all the potential fields in the schema
58
+ let keys = rows.flatMap(Object.keys);
59
+ return { rows, keys };
60
+ });
61
+ }
43
62
  exports.fetch = function (ctx) {
44
63
  return __awaiter(this, void 0, void 0, function* () {
45
64
  const db = new CouchDB(ctx.appId);
@@ -119,12 +138,10 @@ exports.preview = function (ctx) {
119
138
  if (!Integration) {
120
139
  ctx.throw(400, "Integration type does not exist.");
121
140
  }
122
- const { fields, parameters, queryVerb } = ctx.request.body;
141
+ const { fields, parameters, queryVerb, transformer } = ctx.request.body;
123
142
  const enrichedQuery = yield enrichQueryFields(fields, parameters);
124
143
  const integration = new Integration(datasource.config);
125
- const rows = formatResponse(yield integration[queryVerb](enrichedQuery));
126
- // get all the potential fields in the schema
127
- const keys = rows.flatMap(Object.keys);
144
+ const { rows, keys } = yield runAndTransform(integration, queryVerb, enrichedQuery, transformer);
128
145
  ctx.body = {
129
146
  rows,
130
147
  schemaFields: [...new Set(keys)],
@@ -147,7 +164,8 @@ exports.execute = function (ctx) {
147
164
  const enrichedQuery = yield enrichQueryFields(query.fields, ctx.request.body.parameters);
148
165
  const integration = new Integration(datasource.config);
149
166
  // call the relevant CRUD method on the integration class
150
- ctx.body = formatResponse(yield integration[query.queryVerb](enrichedQuery));
167
+ const { rows } = yield runAndTransform(integration, query.queryVerb, enrichedQuery, query.transformer);
168
+ ctx.body = rows;
151
169
  // cleanup
152
170
  if (integration.end) {
153
171
  integration.end();