@budibase/server 0.9.188 → 0.9.190-alpha.10

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 (314) hide show
  1. package/Dockerfile +7 -1
  2. package/__mocks__/mssql.ts +1 -1
  3. package/__mocks__/oracledb.ts +31 -0
  4. package/__mocks__/pg.ts +3 -0
  5. package/builder/assets/bb-space-man.5be51a45.svg +290 -0
  6. package/builder/assets/index.2bd3b345.js +1316 -0
  7. package/builder/assets/index.4fb3f887.css +1 -0
  8. package/builder/assets/oracle.66592424.png +0 -0
  9. package/builder/assets/vendor.470042a4.js +152 -0
  10. package/builder/assets/vendor.5e1fe644.css +1 -0
  11. package/builder/index.html +4 -4
  12. package/coverage/clover.xml +1608 -1191
  13. package/coverage/coverage-final.json +97 -93
  14. package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
  15. package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
  16. package/coverage/lcov-report/api/controllers/application.js.html +113 -80
  17. package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
  18. package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
  19. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  22. package/coverage/lcov-report/api/controllers/datasource.js.html +245 -41
  23. package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
  24. package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
  25. package/coverage/lcov-report/api/controllers/index.html +98 -98
  26. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/layout.js.html +9 -9
  28. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
  29. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  30. package/coverage/lcov-report/api/controllers/query.js.html +79 -229
  31. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  32. package/coverage/lcov-report/api/controllers/routing.js.html +29 -29
  33. package/coverage/lcov-report/api/controllers/row/external.js.html +17 -8
  34. package/coverage/lcov-report/api/controllers/row/index.html +26 -26
  35. package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
  36. package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
  37. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  38. package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
  39. package/coverage/lcov-report/api/controllers/screen.js.html +3 -3
  40. package/coverage/lcov-report/api/controllers/script.js.html +3 -3
  41. package/coverage/lcov-report/api/controllers/table/external.js.html +1001 -0
  42. package/coverage/lcov-report/api/controllers/table/index.html +56 -26
  43. package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
  44. package/coverage/lcov-report/api/controllers/table/internal.js.html +533 -0
  45. package/coverage/lcov-report/api/controllers/table/utils.js.html +175 -52
  46. package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
  47. package/coverage/lcov-report/api/controllers/user.js.html +390 -33
  48. package/coverage/lcov-report/api/controllers/view/exporters.js.html +19 -4
  49. package/coverage/lcov-report/api/controllers/view/index.html +22 -22
  50. package/coverage/lcov-report/api/controllers/view/index.js.html +52 -13
  51. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  52. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
  53. package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
  54. package/coverage/lcov-report/api/index.html +1 -1
  55. package/coverage/lcov-report/api/index.js.html +5 -5
  56. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  67. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/index.html +4 -4
  69. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/query.js.html +5 -2
  75. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/row.js.html +536 -2
  78. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  81. package/coverage/lcov-report/api/routes/table.js.html +464 -2
  82. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  83. package/coverage/lcov-report/api/routes/user.js.html +17 -2
  84. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  85. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  86. package/coverage/lcov-report/automations/actions.js.html +2 -2
  87. package/coverage/lcov-report/automations/automationUtils.js.html +4 -4
  88. package/coverage/lcov-report/automations/bullboard.js.html +71 -20
  89. package/coverage/lcov-report/automations/index.html +35 -50
  90. package/coverage/lcov-report/automations/index.js.html +2 -2
  91. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
  96. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
  98. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/index.html +14 -14
  100. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
  102. package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
  103. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  106. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  107. package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
  108. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  110. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  111. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  112. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  113. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  114. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  116. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  117. package/coverage/lcov-report/automations/triggers.js.html +22 -10
  118. package/coverage/lcov-report/automations/utils.js.html +46 -16
  119. package/coverage/lcov-report/constants/index.html +5 -5
  120. package/coverage/lcov-report/constants/index.js.html +87 -21
  121. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  122. package/coverage/lcov-report/constants/screens.js.html +2 -2
  123. package/coverage/lcov-report/db/client.js.html +2 -2
  124. package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
  125. package/coverage/lcov-report/db/index.html +2 -2
  126. package/coverage/lcov-report/db/index.js.html +1 -1
  127. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
  128. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  129. package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
  130. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
  131. package/coverage/lcov-report/db/newid.js.html +4 -4
  132. package/coverage/lcov-report/db/utils.js.html +75 -75
  133. package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
  134. package/coverage/lcov-report/events/index.html +6 -6
  135. package/coverage/lcov-report/events/index.js.html +1 -1
  136. package/coverage/lcov-report/events/utils.js.html +5 -5
  137. package/coverage/lcov-report/index.html +106 -91
  138. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  139. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  140. package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
  141. package/coverage/lcov-report/middleware/authorized.js.html +19 -16
  142. package/coverage/lcov-report/middleware/builder.js.html +22 -13
  143. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  144. package/coverage/lcov-report/middleware/index.html +23 -23
  145. package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
  146. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  147. package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
  148. package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
  149. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  150. package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +90 -33
  151. package/coverage/lcov-report/threads/index.html +141 -0
  152. package/coverage/lcov-report/threads/index.js.html +278 -0
  153. package/coverage/lcov-report/threads/query.js.html +278 -0
  154. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  155. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  156. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  157. package/coverage/lcov-report/utilities/csvParser.js.html +144 -15
  158. package/coverage/lcov-report/utilities/global.js.html +38 -23
  159. package/coverage/lcov-report/utilities/index.html +48 -48
  160. package/coverage/lcov-report/utilities/index.js.html +49 -16
  161. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +31 -10
  162. package/coverage/lcov-report/utilities/queue/index.html +14 -14
  163. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  164. package/coverage/lcov-report/utilities/routing/index.js.html +2 -2
  165. package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
  166. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
  167. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
  168. package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
  169. package/coverage/lcov-report/utilities/security.js.html +3 -3
  170. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  171. package/coverage/lcov-report/utilities/users.js.html +1 -1
  172. package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
  173. package/coverage/lcov.info +2687 -1942
  174. package/dist/api/controllers/application.js +16 -6
  175. package/dist/api/controllers/auth.js +3 -3
  176. package/dist/api/controllers/datasource.js +67 -16
  177. package/dist/api/controllers/deploy/index.js +2 -0
  178. package/dist/api/controllers/dev.js +4 -1
  179. package/dist/api/controllers/query.js +32 -62
  180. package/dist/api/controllers/row/ExternalRequest.js +83 -36
  181. package/dist/api/controllers/row/external.js +3 -1
  182. package/dist/api/controllers/row/utils.js +6 -12
  183. package/dist/api/controllers/table/external.js +249 -0
  184. package/dist/api/controllers/table/index.js +49 -123
  185. package/dist/api/controllers/table/internal.js +146 -0
  186. package/dist/api/controllers/table/utils.js +62 -28
  187. package/dist/api/controllers/user.js +123 -11
  188. package/dist/api/controllers/view/exporters.js +4 -0
  189. package/dist/api/controllers/view/index.js +14 -2
  190. package/dist/api/routes/query.js +1 -1
  191. package/dist/api/routes/row.js +178 -0
  192. package/dist/api/routes/table.js +150 -1
  193. package/dist/api/routes/user.js +2 -1
  194. package/dist/app.js +2 -11
  195. package/dist/automations/bullboard.js +37 -10
  196. package/dist/automations/triggers.js +7 -3
  197. package/dist/automations/utils.js +11 -2
  198. package/dist/constants/index.js +19 -0
  199. package/dist/definitions/datasource.js +17 -1
  200. package/dist/environment.js +13 -0
  201. package/dist/integrations/base/IntegrationBase.js +2 -0
  202. package/dist/integrations/base/datasourcePlus.js +2 -0
  203. package/dist/integrations/base/sql.js +350 -177
  204. package/dist/integrations/base/sqlTable.js +143 -0
  205. package/dist/integrations/base/utils.js +30 -0
  206. package/dist/integrations/index.js +6 -0
  207. package/dist/integrations/microsoftSqlServer.js +117 -9
  208. package/dist/integrations/mysql.js +16 -85
  209. package/dist/integrations/oracle.js +367 -0
  210. package/dist/integrations/postgres.js +35 -28
  211. package/dist/integrations/utils.js +71 -9
  212. package/dist/middleware/authorized.js +2 -1
  213. package/dist/middleware/builder.js +4 -1
  214. package/dist/package.json +18 -9
  215. package/dist/tests/utilities/TestConfiguration.js +2 -1
  216. package/dist/{automations/thread.js → threads/automation.js} +26 -8
  217. package/dist/threads/index.js +64 -0
  218. package/dist/threads/query.js +64 -0
  219. package/dist/tsconfig.tsbuildinfo +1 -1
  220. package/dist/utilities/csvParser.js +46 -5
  221. package/dist/utilities/global.js +6 -2
  222. package/dist/utilities/index.js +11 -0
  223. package/dist/utilities/queue/inMemoryQueue.js +8 -0
  224. package/dist/utilities/scriptRunner.js +4 -1
  225. package/package.json +19 -10
  226. package/scripts/dev/manage.js +1 -0
  227. package/scripts/docs/README.md +31 -0
  228. package/scripts/docs/generate.js +74 -0
  229. package/scripts/docs/toSwagger.js +320 -0
  230. package/scripts/integrations/mssql/data/Dockerfile +9 -0
  231. package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
  232. package/scripts/integrations/mssql/data/setup.sql +54 -0
  233. package/scripts/integrations/mssql/docker-compose.yaml +12 -0
  234. package/scripts/integrations/mssql/reset.sh +3 -0
  235. package/scripts/integrations/oracle/docker-compose.yml +19 -0
  236. package/scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip +0 -0
  237. package/scripts/integrations/oracle/instantclient/linux/x86-64/install.sh +23 -0
  238. package/scripts/integrations/oracle/oracle.md +90 -0
  239. package/scripts/integrations/postgres/docker-compose.yml +3 -3
  240. package/scripts/likeCypress.ts +33 -0
  241. package/src/api/controllers/application.js +18 -7
  242. package/src/api/controllers/auth.js +3 -0
  243. package/src/api/controllers/datasource.js +84 -16
  244. package/src/api/controllers/deploy/index.js +2 -0
  245. package/src/api/controllers/dev.js +4 -1
  246. package/src/api/controllers/query.js +35 -85
  247. package/src/api/controllers/row/ExternalRequest.ts +99 -38
  248. package/src/api/controllers/row/external.js +4 -1
  249. package/src/api/controllers/row/utils.js +8 -11
  250. package/src/api/controllers/table/external.js +307 -0
  251. package/src/api/controllers/table/index.js +47 -137
  252. package/src/api/controllers/table/internal.js +151 -0
  253. package/src/api/controllers/table/utils.js +74 -33
  254. package/src/api/controllers/user.js +132 -13
  255. package/src/api/controllers/view/exporters.js +5 -0
  256. package/src/api/controllers/view/index.js +15 -2
  257. package/src/api/routes/query.js +1 -0
  258. package/src/api/routes/row.js +178 -0
  259. package/src/api/routes/table.js +154 -0
  260. package/src/api/routes/tests/application.spec.js +0 -2
  261. package/src/api/routes/tests/datasource.spec.js +2 -2
  262. package/src/api/routes/tests/misc.spec.js +5 -1
  263. package/src/api/routes/tests/query.spec.js +38 -9
  264. package/src/api/routes/tests/screen.spec.js +1 -1
  265. package/src/api/routes/user.js +5 -0
  266. package/src/app.ts +2 -10
  267. package/src/automations/bullboard.js +28 -11
  268. package/src/automations/tests/automation.spec.js +3 -4
  269. package/src/automations/triggers.js +7 -3
  270. package/src/automations/utils.js +12 -2
  271. package/src/constants/index.js +22 -0
  272. package/src/definitions/common.ts +7 -1
  273. package/src/definitions/datasource.ts +21 -3
  274. package/src/environment.js +15 -0
  275. package/src/integrations/airtable.ts +2 -1
  276. package/src/integrations/arangodb.ts +2 -1
  277. package/src/integrations/base/IntegrationBase.ts +6 -0
  278. package/src/integrations/base/datasourcePlus.ts +9 -0
  279. package/src/integrations/base/sql.ts +375 -218
  280. package/src/integrations/base/sqlTable.ts +180 -0
  281. package/src/integrations/base/utils.ts +22 -0
  282. package/src/integrations/couchdb.ts +2 -1
  283. package/src/integrations/dynamodb.ts +2 -1
  284. package/src/integrations/elasticsearch.ts +2 -1
  285. package/src/integrations/index.ts +7 -0
  286. package/src/integrations/microsoftSqlServer.ts +145 -13
  287. package/src/integrations/mongodb.ts +2 -1
  288. package/src/integrations/mysql.ts +23 -95
  289. package/src/integrations/oracle.ts +464 -0
  290. package/src/integrations/postgres.ts +45 -35
  291. package/src/integrations/rest.ts +2 -1
  292. package/src/integrations/s3.ts +2 -1
  293. package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
  294. package/src/integrations/tests/oracle.spec.js +94 -0
  295. package/src/integrations/tests/postgres.spec.js +4 -0
  296. package/src/integrations/utils.ts +78 -8
  297. package/src/middleware/authorized.js +2 -1
  298. package/src/middleware/builder.js +4 -1
  299. package/src/tests/utilities/TestConfiguration.js +2 -1
  300. package/src/{automations/thread.js → threads/automation.js} +27 -8
  301. package/src/threads/index.js +66 -0
  302. package/src/threads/query.js +66 -0
  303. package/src/utilities/csvParser.js +48 -5
  304. package/src/utilities/global.js +7 -2
  305. package/src/utilities/index.js +11 -0
  306. package/src/utilities/queue/inMemoryQueue.js +7 -0
  307. package/src/utilities/scriptRunner.js +4 -1
  308. package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
  309. package/src/utilities/tests/csvParser.spec.js +3 -0
  310. package/tsconfig.json +1 -1
  311. package/builder/assets/index.550fdba7.js +0 -201
  312. package/builder/assets/index.7469e1e4.css +0 -29
  313. package/builder/assets/vendor.278a305c.js +0 -9
  314. package/builder/assets/vendor.d75d5eb7.css +0 -1
@@ -13,10 +13,9 @@ const env = require("../../environment");
13
13
  const packageJson = require("../../../package.json");
14
14
  const { createLinkView, createRoutingView, createAllSearchIndex, } = require("../../db/views/staticViews");
15
15
  const { getTemplateStream, createApp, deleteApp, } = require("../../utilities/fileSystem");
16
- const { generateAppID, getLayoutParams, getScreenParams, generateScreenID, generateDevAppID, DocumentTypes, AppStatus, } = require("../../db/utils");
16
+ const { generateAppID, getLayoutParams, getScreenParams, generateDevAppID, DocumentTypes, AppStatus, } = require("../../db/utils");
17
17
  const { BUILTIN_ROLE_IDS, AccessController } = require("@budibase/auth/roles");
18
18
  const { BASE_LAYOUTS } = require("../../constants/layouts");
19
- const { createHomeScreen } = require("../../constants/screens");
20
19
  const { cloneDeep } = require("lodash/fp");
21
20
  const { processObject } = require("@budibase/string-templates");
22
21
  const { getAllApps, isDevAppID, getDeployedAppID, Replication, } = require("@budibase/auth/db");
@@ -26,6 +25,9 @@ const { clientLibraryPath, stringToReadStream } = require("../../utilities");
26
25
  const { getAllLocks } = require("../../utilities/redis");
27
26
  const { updateClientLibrary, backupClientLibrary, revertClientLibrary, } = require("../../utilities/fileSystem/clientLibrary");
28
27
  const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy");
28
+ const { syncGlobalUsers } = require("./user");
29
+ const { app: appCache } = require("@budibase/auth/cache");
30
+ const { cleanupAutomations } = require("../../automations/utils");
29
31
  const URL_REGEX_SLASH = /\/|\\/g;
30
32
  // utility function, need to do away with this
31
33
  function getLayouts(db) {
@@ -213,6 +215,7 @@ exports.create = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
213
215
  if (!env.isTest()) {
214
216
  yield createApp(appId);
215
217
  }
218
+ yield appCache.invalidateAppMetadata(appId, newApplication);
216
219
  ctx.status = 200;
217
220
  ctx.body = newApplication;
218
221
  });
@@ -267,8 +270,12 @@ exports.delete = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
267
270
  if (!env.isTest() && !ctx.query.unpublish) {
268
271
  yield deleteApp(ctx.params.appId);
269
272
  }
273
+ if (ctx.query && ctx.query.unpublish) {
274
+ yield cleanupAutomations(ctx.params.appId);
275
+ }
270
276
  // make sure the app/role doesn't stick around after the app has been deleted
271
277
  yield removeAppFromUserRoles(ctx, ctx.params.appId);
278
+ yield appCache.invalidateAppMetadata(ctx.params.appId);
272
279
  ctx.status = 200;
273
280
  ctx.body = result;
274
281
  });
@@ -277,6 +284,7 @@ exports.sync = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
277
284
  if (!isDevAppID(appId)) {
278
285
  ctx.throw(400, "This action cannot be performed for production apps");
279
286
  }
287
+ // replicate prod to dev
280
288
  const prodAppId = getDeployedAppID(appId);
281
289
  try {
282
290
  const prodDb = new CouchDB(prodAppId, { skip_setup: true });
@@ -307,6 +315,8 @@ exports.sync = (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
307
315
  catch (err) {
308
316
  error = err;
309
317
  }
318
+ // sync the users
319
+ yield syncGlobalUsers(appId);
310
320
  if (error) {
311
321
  ctx.throw(400, error);
312
322
  }
@@ -327,7 +337,10 @@ const updateAppPackage = (ctx, appPackage, appId) => __awaiter(void 0, void 0, v
327
337
  // the locked by property is attached by server but generated from
328
338
  // Redis, shouldn't ever store it
329
339
  delete newAppPackage.lockedBy;
330
- return yield db.put(newAppPackage);
340
+ const response = yield db.put(newAppPackage);
341
+ // remove any cached metadata, so that it will be updated
342
+ yield appCache.invalidateAppMetadata(appId);
343
+ return response;
331
344
  });
332
345
  const createEmptyAppPackage = (ctx, app) => __awaiter(void 0, void 0, void 0, function* () {
333
346
  const db = new CouchDB(app.appId);
@@ -336,8 +349,5 @@ const createEmptyAppPackage = (ctx, app) => __awaiter(void 0, void 0, void 0, fu
336
349
  const cloned = cloneDeep(layout);
337
350
  screensAndLayouts.push(yield processObject(cloned, app));
338
351
  }
339
- const homeScreen = createHomeScreen(app);
340
- homeScreen._id = generateScreenID();
341
- screensAndLayouts.push(homeScreen);
342
352
  yield db.bulkDocs(screensAndLayouts);
343
353
  });
@@ -22,6 +22,8 @@ exports.fetchSelf = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
22
22
  return;
23
23
  }
24
24
  const user = yield getFullUser(ctx, userId);
25
+ // this shouldn't be returned by the app self
26
+ delete user.roles;
25
27
  if (appId) {
26
28
  const db = new CouchDB(appId);
27
29
  // remove the full roles structure
@@ -40,9 +42,7 @@ exports.fetchSelf = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
40
42
  }
41
43
  // user has a role of some sort, return them
42
44
  else if (err.status === 404) {
43
- const metadata = {
44
- _id: userId,
45
- };
45
+ const metadata = Object.assign(Object.assign({}, user), { _id: userId });
46
46
  const dbResp = yield db.put(metadata);
47
47
  user._rev = dbResp.rev;
48
48
  response = user;
@@ -10,8 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const CouchDB = require("../../db");
12
12
  const { generateDatasourceID, getDatasourceParams, getQueryParams, DocumentTypes, BudibaseInternalDB, getTableParams, } = require("../../db/utils");
13
+ const { BuildSchemaErrors, InvalidColumns } = require("../../constants");
13
14
  const { integrations } = require("../../integrations");
14
- const { makeExternalQuery } = require("./row/utils");
15
+ const { getDatasourceAndQuery } = require("./row/utils");
15
16
  exports.fetch = function (ctx) {
16
17
  return __awaiter(this, void 0, void 0, function* () {
17
18
  const database = new CouchDB(ctx.appId);
@@ -33,11 +34,15 @@ exports.buildSchemaFromDb = function (ctx) {
33
34
  return __awaiter(this, void 0, void 0, function* () {
34
35
  const db = new CouchDB(ctx.appId);
35
36
  const datasource = yield db.get(ctx.params.datasourceId);
36
- const tables = yield buildSchemaHelper(datasource);
37
+ const { tables, error } = yield buildSchemaHelper(datasource);
37
38
  datasource.entities = tables;
38
- const response = yield db.put(datasource);
39
- datasource._rev = response.rev;
40
- ctx.body = datasource;
39
+ const dbResp = yield db.put(datasource);
40
+ datasource._rev = dbResp.rev;
41
+ const response = { datasource };
42
+ if (error) {
43
+ response.error = error;
44
+ }
45
+ ctx.body = response;
41
46
  });
42
47
  };
43
48
  exports.update = function (ctx) {
@@ -57,7 +62,7 @@ exports.update = function (ctx) {
57
62
  }
58
63
  ctx.status = 200;
59
64
  ctx.message = "Datasource saved successfully.";
60
- ctx.body = datasource;
65
+ ctx.body = { datasource };
61
66
  });
62
67
  };
63
68
  exports.save = function (ctx) {
@@ -66,12 +71,14 @@ exports.save = function (ctx) {
66
71
  const plus = ctx.request.body.datasource.plus;
67
72
  const fetchSchema = ctx.request.body.fetchSchema;
68
73
  const datasource = Object.assign({ _id: generateDatasourceID({ plus }), type: plus ? DocumentTypes.DATASOURCE_PLUS : DocumentTypes.DATASOURCE }, ctx.request.body.datasource);
74
+ let schemaError = null;
69
75
  if (fetchSchema) {
70
- let tables = yield buildSchemaHelper(datasource);
76
+ const { tables, error } = yield buildSchemaHelper(datasource);
77
+ schemaError = error;
71
78
  datasource.entities = tables;
72
79
  }
73
- const response = yield db.put(datasource);
74
- datasource._rev = response.rev;
80
+ const dbResp = yield db.put(datasource);
81
+ datasource._rev = dbResp.rev;
75
82
  // Drain connection pools when configuration is changed
76
83
  if (datasource.source) {
77
84
  const source = integrations[datasource.source];
@@ -79,17 +86,23 @@ exports.save = function (ctx) {
79
86
  yield source.pool.end();
80
87
  }
81
88
  }
82
- ctx.status = 200;
83
- ctx.message = "Datasource saved successfully.";
84
- ctx.body = datasource;
89
+ const response = { datasource };
90
+ if (schemaError) {
91
+ response.error = schemaError;
92
+ }
93
+ ctx.body = response;
85
94
  });
86
95
  };
87
96
  exports.destroy = function (ctx) {
88
97
  return __awaiter(this, void 0, void 0, function* () {
89
98
  const db = new CouchDB(ctx.appId);
90
99
  // Delete all queries for the datasource
91
- const rows = yield db.allDocs(getQueryParams(ctx.params.datasourceId, null));
92
- yield db.bulkDocs(rows.rows.map(row => (Object.assign(Object.assign({}, row.doc), { _deleted: true }))));
100
+ const queries = yield db.allDocs(getQueryParams(ctx.params.datasourceId, null));
101
+ yield db.bulkDocs(queries.rows.map(row => ({
102
+ _id: row.id,
103
+ _rev: row.value.rev,
104
+ _deleted: true,
105
+ })));
93
106
  // delete the datasource
94
107
  yield db.remove(ctx.params.datasourceId, ctx.params.revId);
95
108
  ctx.message = `Datasource deleted.`;
@@ -107,18 +120,56 @@ exports.query = function (ctx) {
107
120
  return __awaiter(this, void 0, void 0, function* () {
108
121
  const queryJson = ctx.request.body;
109
122
  try {
110
- ctx.body = yield makeExternalQuery(ctx.appId, queryJson);
123
+ ctx.body = yield getDatasourceAndQuery(ctx.appId, queryJson);
111
124
  }
112
125
  catch (err) {
113
126
  ctx.throw(400, err);
114
127
  }
115
128
  });
116
129
  };
130
+ function getErrorTables(errors, errorType) {
131
+ return Object.entries(errors)
132
+ .filter(entry => entry[1] === errorType)
133
+ .map(([name]) => name);
134
+ }
135
+ function updateError(error, newError, tables) {
136
+ if (!error) {
137
+ error = "";
138
+ }
139
+ if (error.length > 0) {
140
+ error += "\n";
141
+ }
142
+ error += `${newError} ${tables.join(", ")}`;
143
+ return error;
144
+ }
117
145
  const buildSchemaHelper = (datasource) => __awaiter(void 0, void 0, void 0, function* () {
118
146
  const Connector = integrations[datasource.source];
119
147
  // Connect to the DB and build the schema
120
148
  const connector = new Connector(datasource.config);
121
149
  yield connector.buildSchema(datasource._id, datasource.entities);
122
150
  datasource.entities = connector.tables;
123
- return connector.tables;
151
+ // make sure they all have a display name selected
152
+ for (let entity of Object.values(datasource.entities)) {
153
+ if (entity.primaryDisplay) {
154
+ continue;
155
+ }
156
+ const notAutoColumn = Object.values(entity.schema).find(schema => !schema.autocolumn);
157
+ if (notAutoColumn) {
158
+ entity.primaryDisplay = notAutoColumn.name;
159
+ }
160
+ }
161
+ const errors = connector.schemaErrors;
162
+ let error = null;
163
+ if (errors && Object.keys(errors).length > 0) {
164
+ const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY);
165
+ const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN);
166
+ if (noKey.length) {
167
+ error = updateError(error, "No primary key constraint found for the following:", noKey);
168
+ }
169
+ if (invalidCol.length) {
170
+ const invalidCols = Object.values(InvalidColumns).join(", ");
171
+ error = updateError(error, `Cannot use columns ${invalidCols} found in following:`, invalidCol);
172
+ }
173
+ }
174
+ return { tables: connector.tables, error };
124
175
  });
@@ -13,6 +13,7 @@ const Deployment = require("./Deployment");
13
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
+ const { app: appCache } = require("@budibase/auth/cache");
16
17
  // the max time we can wait for an invalidation to complete before considering it failed
17
18
  const MAX_PENDING_TIME_MS = 30 * 60000;
18
19
  const DeploymentStatus = {
@@ -95,6 +96,7 @@ function deployApp(deployment) {
95
96
  appDoc.appId = productionAppId;
96
97
  appDoc.instance._id = productionAppId;
97
98
  yield db.put(appDoc);
99
+ yield appCache.invalidateAppMetadata(productionAppId);
98
100
  console.log("New app doc written successfully.");
99
101
  yield initDeployedApp(productionAppId);
100
102
  console.log("Deployed app initialised, setting deployment to successful");
@@ -16,6 +16,7 @@ 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
+ const { app: appCache } = require("@budibase/auth/cache");
19
20
  function redirect(ctx, method, path = "global") {
20
21
  return __awaiter(this, void 0, void 0, function* () {
21
22
  const { devPath } = ctx.params;
@@ -25,7 +26,8 @@ function redirect(ctx, method, path = "global") {
25
26
  body: ctx.request.body,
26
27
  }, true));
27
28
  if (response.status !== 200) {
28
- ctx.throw(response.status, response.statusText);
29
+ const err = yield response.text();
30
+ ctx.throw(400, err);
29
31
  }
30
32
  const cookie = response.headers.get("set-cookie");
31
33
  if (cookie) {
@@ -102,6 +104,7 @@ exports.revert = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
102
104
  appDoc.appId = appId;
103
105
  appDoc.instance._id = appId;
104
106
  yield db.put(appDoc);
107
+ yield appCache.invalidateAppMetadata(appId);
105
108
  ctx.body = {
106
109
  message: "Reverted changes successfully.",
107
110
  };
@@ -10,11 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  const { processString } = require("@budibase/string-templates");
12
12
  const CouchDB = require("../../db");
13
- const { generateQueryID, getQueryParams } = require("../../db/utils");
14
- const { integrations } = require("../../integrations");
13
+ const { generateQueryID, getQueryParams, isProdAppID, } = require("../../db/utils");
15
14
  const { BaseQueryVerbs } = require("../../constants");
16
- const env = require("../../environment");
17
- const ScriptRunner = require("../../utilities/scriptRunner");
15
+ const { Thread, ThreadType } = require("../../threads");
16
+ const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 });
18
17
  // simple function to append "readable" to all read queries
19
18
  function enrichQueries(input) {
20
19
  const wasArray = Array.isArray(input);
@@ -26,38 +25,6 @@ function enrichQueries(input) {
26
25
  }
27
26
  return wasArray ? queries : queries[0];
28
27
  }
29
- function formatResponse(resp) {
30
- if (typeof resp === "string") {
31
- try {
32
- resp = JSON.parse(resp);
33
- }
34
- catch (err) {
35
- resp = { response: resp };
36
- }
37
- }
38
- return resp;
39
- }
40
- function runAndTransform(integration, queryVerb, enrichedQuery, transformer) {
41
- return __awaiter(this, void 0, void 0, function* () {
42
- let rows = formatResponse(yield integration[queryVerb](enrichedQuery));
43
- // transform as required
44
- if (transformer) {
45
- const runner = new ScriptRunner(transformer, { data: rows });
46
- rows = runner.execute();
47
- }
48
- // needs to an array for next step
49
- if (!Array.isArray(rows)) {
50
- rows = [rows];
51
- }
52
- // map into JSON if just raw primitive here
53
- if (rows.find(row => typeof row !== "object")) {
54
- rows = rows.map(value => ({ value }));
55
- }
56
- // get all the potential fields in the schema
57
- let keys = rows.flatMap(Object.keys);
58
- return { rows, keys };
59
- });
60
- }
61
28
  exports.fetch = function (ctx) {
62
29
  return __awaiter(this, void 0, void 0, function* () {
63
30
  const db = new CouchDB(ctx.appId);
@@ -94,7 +61,9 @@ function enrichQueryFields(fields, parameters = {}) {
94
61
  }
95
62
  else if (typeof fields[key] === "string") {
96
63
  // enrich string value as normal
97
- enrichedQuery[key] = yield processString(fields[key], parameters);
64
+ enrichedQuery[key] = yield processString(fields[key], parameters, {
65
+ noHelpers: true,
66
+ });
98
67
  }
99
68
  else {
100
69
  enrichedQuery[key] = fields[key];
@@ -121,10 +90,9 @@ exports.find = function (ctx) {
121
90
  const db = new CouchDB(ctx.appId);
122
91
  const query = enrichQueries(yield db.get(ctx.params.queryId));
123
92
  // remove properties that could be dangerous in real app
124
- if (env.isProd()) {
93
+ if (isProdAppID(ctx.appId)) {
125
94
  delete query.fields;
126
95
  delete query.parameters;
127
- delete query.schema;
128
96
  }
129
97
  ctx.body = query;
130
98
  });
@@ -133,21 +101,22 @@ exports.preview = function (ctx) {
133
101
  return __awaiter(this, void 0, void 0, function* () {
134
102
  const db = new CouchDB(ctx.appId);
135
103
  const datasource = yield db.get(ctx.request.body.datasourceId);
136
- const Integration = integrations[datasource.source];
137
- if (!Integration) {
138
- ctx.throw(400, "Integration type does not exist.");
139
- }
140
104
  const { fields, parameters, queryVerb, transformer } = ctx.request.body;
141
105
  const enrichedQuery = yield enrichQueryFields(fields, parameters);
142
- const integration = new Integration(datasource.config);
143
- const { rows, keys } = yield runAndTransform(integration, queryVerb, enrichedQuery, transformer);
144
- ctx.body = {
145
- rows,
146
- schemaFields: [...new Set(keys)],
147
- };
148
- // cleanup
149
- if (integration.end) {
150
- integration.end();
106
+ try {
107
+ const { rows, keys } = yield Runner.run({
108
+ datasource,
109
+ queryVerb,
110
+ query: enrichedQuery,
111
+ transformer,
112
+ });
113
+ ctx.body = {
114
+ rows,
115
+ schemaFields: [...new Set(keys)],
116
+ };
117
+ }
118
+ catch (err) {
119
+ ctx.throw(400, err);
151
120
  }
152
121
  });
153
122
  };
@@ -156,18 +125,19 @@ exports.execute = function (ctx) {
156
125
  const db = new CouchDB(ctx.appId);
157
126
  const query = yield db.get(ctx.params.queryId);
158
127
  const datasource = yield db.get(query.datasourceId);
159
- const Integration = integrations[datasource.source];
160
- if (!Integration) {
161
- ctx.throw(400, "Integration type does not exist.");
162
- }
163
128
  const enrichedQuery = yield enrichQueryFields(query.fields, ctx.request.body.parameters);
164
- const integration = new Integration(datasource.config);
165
129
  // call the relevant CRUD method on the integration class
166
- const { rows } = yield runAndTransform(integration, query.queryVerb, enrichedQuery, query.transformer);
167
- ctx.body = rows;
168
- // cleanup
169
- if (integration.end) {
170
- integration.end();
130
+ try {
131
+ const { rows } = yield Runner.run({
132
+ datasource,
133
+ queryVerb: query.queryVerb,
134
+ query: enrichedQuery,
135
+ transformer: query.transformer,
136
+ });
137
+ ctx.body = rows;
138
+ }
139
+ catch (err) {
140
+ ctx.throw(400, err);
171
141
  }
172
142
  });
173
143
  };