@budibase/server 0.9.186 → 0.9.190-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/Dockerfile +7 -1
  2. package/LICENSE +1 -1
  3. package/__mocks__/mssql.ts +1 -1
  4. package/__mocks__/oracledb.ts +31 -0
  5. package/__mocks__/pg.ts +3 -0
  6. package/builder/assets/bb-space-man.5be51a45.svg +290 -0
  7. package/builder/assets/index.43f4c913.js +1316 -0
  8. package/builder/assets/index.7d405e74.css +1 -0
  9. package/builder/assets/oracle.66592424.png +0 -0
  10. package/builder/assets/vendor.470042a4.js +152 -0
  11. package/builder/assets/vendor.5e1fe644.css +1 -0
  12. package/builder/index.html +4 -4
  13. package/coverage/clover.xml +1520 -1087
  14. package/coverage/coverage-final.json +93 -89
  15. package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
  16. package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
  17. package/coverage/lcov-report/api/controllers/application.js.html +64 -13
  18. package/coverage/lcov-report/api/controllers/auth.js.html +19 -10
  19. package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
  20. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  23. package/coverage/lcov-report/api/controllers/datasource.js.html +232 -28
  24. package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
  25. package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
  26. package/coverage/lcov-report/api/controllers/index.html +91 -91
  27. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
  29. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
  30. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  31. package/coverage/lcov-report/api/controllers/query.js.html +53 -209
  32. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  33. package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
  34. package/coverage/lcov-report/api/controllers/row/external.js.html +17 -8
  35. package/coverage/lcov-report/api/controllers/row/index.html +26 -26
  36. package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
  37. package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
  38. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  39. package/coverage/lcov-report/api/controllers/row/utils.js.html +21 -30
  40. package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
  41. package/coverage/lcov-report/api/controllers/script.js.html +3 -3
  42. package/coverage/lcov-report/api/controllers/table/external.js.html +1001 -0
  43. package/coverage/lcov-report/api/controllers/table/index.html +56 -26
  44. package/coverage/lcov-report/api/controllers/table/index.js.html +80 -350
  45. package/coverage/lcov-report/api/controllers/table/internal.js.html +545 -0
  46. package/coverage/lcov-report/api/controllers/table/utils.js.html +175 -52
  47. package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
  48. package/coverage/lcov-report/api/controllers/user.js.html +390 -33
  49. package/coverage/lcov-report/api/controllers/view/exporters.js.html +19 -4
  50. package/coverage/lcov-report/api/controllers/view/index.html +22 -22
  51. package/coverage/lcov-report/api/controllers/view/index.js.html +52 -13
  52. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  53. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
  54. package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
  55. package/coverage/lcov-report/api/index.html +1 -1
  56. package/coverage/lcov-report/api/index.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  68. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/index.html +4 -4
  70. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/query.js.html +5 -2
  76. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  82. package/coverage/lcov-report/api/routes/table.js.html +35 -2
  83. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  84. package/coverage/lcov-report/api/routes/user.js.html +17 -2
  85. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  86. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  87. package/coverage/lcov-report/automations/actions.js.html +2 -2
  88. package/coverage/lcov-report/automations/automationUtils.js.html +4 -4
  89. package/coverage/lcov-report/automations/bullboard.js.html +71 -20
  90. package/coverage/lcov-report/automations/index.html +35 -50
  91. package/coverage/lcov-report/automations/index.js.html +2 -2
  92. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
  97. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
  99. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/index.html +14 -14
  101. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
  103. package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
  104. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  106. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  107. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  108. package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
  109. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  111. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  113. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  114. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  116. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  117. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  118. package/coverage/lcov-report/automations/triggers.js.html +22 -10
  119. package/coverage/lcov-report/automations/utils.js.html +42 -12
  120. package/coverage/lcov-report/constants/index.html +5 -5
  121. package/coverage/lcov-report/constants/index.js.html +87 -21
  122. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  123. package/coverage/lcov-report/constants/screens.js.html +1 -1
  124. package/coverage/lcov-report/db/client.js.html +2 -2
  125. package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
  126. package/coverage/lcov-report/db/index.html +2 -2
  127. package/coverage/lcov-report/db/index.js.html +1 -1
  128. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
  129. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  130. package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
  131. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
  132. package/coverage/lcov-report/db/newid.js.html +3 -3
  133. package/coverage/lcov-report/db/utils.js.html +57 -57
  134. package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
  135. package/coverage/lcov-report/events/index.html +6 -6
  136. package/coverage/lcov-report/events/index.js.html +1 -1
  137. package/coverage/lcov-report/events/utils.js.html +5 -5
  138. package/coverage/lcov-report/index.html +108 -93
  139. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  140. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  141. package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
  142. package/coverage/lcov-report/middleware/authorized.js.html +58 -34
  143. package/coverage/lcov-report/middleware/builder.js.html +16 -7
  144. package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
  145. package/coverage/lcov-report/middleware/index.html +27 -27
  146. package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
  147. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  148. package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
  149. package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
  150. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  151. package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +90 -33
  152. package/coverage/lcov-report/threads/index.html +141 -0
  153. package/coverage/lcov-report/threads/index.js.html +278 -0
  154. package/coverage/lcov-report/threads/query.js.html +278 -0
  155. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  156. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  157. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  158. package/coverage/lcov-report/utilities/csvParser.js.html +144 -15
  159. package/coverage/lcov-report/utilities/global.js.html +26 -11
  160. package/coverage/lcov-report/utilities/index.html +48 -48
  161. package/coverage/lcov-report/utilities/index.js.html +47 -14
  162. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
  163. package/coverage/lcov-report/utilities/queue/index.html +14 -14
  164. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  165. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  166. package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
  167. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
  168. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
  169. package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
  170. package/coverage/lcov-report/utilities/security.js.html +3 -3
  171. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  172. package/coverage/lcov-report/utilities/users.js.html +1 -1
  173. package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
  174. package/coverage/lcov.info +2558 -1787
  175. package/dist/api/controllers/application.js +15 -1
  176. package/dist/api/controllers/auth.js +3 -3
  177. package/dist/api/controllers/datasource.js +67 -16
  178. package/dist/api/controllers/deploy/index.js +2 -0
  179. package/dist/api/controllers/dev.js +4 -1
  180. package/dist/api/controllers/query.js +30 -58
  181. package/dist/api/controllers/row/ExternalRequest.js +37 -14
  182. package/dist/api/controllers/row/external.js +3 -1
  183. package/dist/api/controllers/row/utils.js +6 -12
  184. package/dist/api/controllers/table/external.js +249 -0
  185. package/dist/api/controllers/table/index.js +49 -123
  186. package/dist/api/controllers/table/internal.js +150 -0
  187. package/dist/api/controllers/table/utils.js +62 -28
  188. package/dist/api/controllers/user.js +123 -11
  189. package/dist/api/controllers/view/exporters.js +4 -0
  190. package/dist/api/controllers/view/index.js +14 -2
  191. package/dist/api/routes/query.js +1 -1
  192. package/dist/api/routes/table.js +7 -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 +5 -0
  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 +338 -180
  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 +14 -84
  209. package/dist/integrations/oracle.js +345 -0
  210. package/dist/integrations/postgres.js +35 -28
  211. package/dist/integrations/utils.js +71 -9
  212. package/dist/middleware/authorized.js +22 -11
  213. package/dist/middleware/builder.js +4 -1
  214. package/dist/package.json +13 -8
  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 +14 -9
  226. package/scripts/dev/manage.js +1 -0
  227. package/scripts/integrations/mssql/data/Dockerfile +9 -0
  228. package/scripts/integrations/mssql/data/entrypoint.sh +24 -0
  229. package/scripts/integrations/mssql/data/setup.sql +54 -0
  230. package/scripts/integrations/mssql/docker-compose.yaml +12 -0
  231. package/scripts/integrations/mssql/reset.sh +3 -0
  232. package/scripts/integrations/oracle/docker-compose.yml +19 -0
  233. package/scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip +0 -0
  234. package/scripts/integrations/oracle/instantclient/linux/x86-64/install.sh +23 -0
  235. package/scripts/integrations/oracle/oracle.md +90 -0
  236. package/scripts/integrations/postgres/docker-compose.yml +3 -3
  237. package/scripts/likeCypress.ts +33 -0
  238. package/src/api/controllers/application.js +18 -1
  239. package/src/api/controllers/auth.js +3 -0
  240. package/src/api/controllers/datasource.js +84 -16
  241. package/src/api/controllers/deploy/index.js +2 -0
  242. package/src/api/controllers/dev.js +4 -1
  243. package/src/api/controllers/query.js +29 -81
  244. package/src/api/controllers/row/ExternalRequest.ts +47 -16
  245. package/src/api/controllers/row/external.js +4 -1
  246. package/src/api/controllers/row/utils.js +8 -11
  247. package/src/api/controllers/table/external.js +307 -0
  248. package/src/api/controllers/table/index.js +47 -137
  249. package/src/api/controllers/table/internal.js +155 -0
  250. package/src/api/controllers/table/utils.js +74 -33
  251. package/src/api/controllers/user.js +132 -13
  252. package/src/api/controllers/view/exporters.js +5 -0
  253. package/src/api/controllers/view/index.js +15 -2
  254. package/src/api/routes/query.js +1 -0
  255. package/src/api/routes/table.js +11 -0
  256. package/src/api/routes/tests/datasource.spec.js +2 -2
  257. package/src/api/routes/tests/misc.spec.js +5 -1
  258. package/src/api/routes/tests/query.spec.js +0 -1
  259. package/src/api/routes/user.js +5 -0
  260. package/src/app.ts +2 -10
  261. package/src/automations/bullboard.js +28 -11
  262. package/src/automations/tests/automation.spec.js +3 -4
  263. package/src/automations/triggers.js +7 -3
  264. package/src/automations/utils.js +12 -2
  265. package/src/constants/index.js +22 -0
  266. package/src/definitions/common.ts +7 -1
  267. package/src/definitions/datasource.ts +10 -3
  268. package/src/environment.js +15 -0
  269. package/src/integrations/airtable.ts +2 -1
  270. package/src/integrations/arangodb.ts +2 -1
  271. package/src/integrations/base/IntegrationBase.ts +6 -0
  272. package/src/integrations/base/datasourcePlus.ts +9 -0
  273. package/src/integrations/base/sql.ts +362 -222
  274. package/src/integrations/base/sqlTable.ts +180 -0
  275. package/src/integrations/base/utils.ts +22 -0
  276. package/src/integrations/couchdb.ts +2 -1
  277. package/src/integrations/dynamodb.ts +2 -1
  278. package/src/integrations/elasticsearch.ts +2 -1
  279. package/src/integrations/index.ts +7 -0
  280. package/src/integrations/microsoftSqlServer.ts +145 -13
  281. package/src/integrations/mongodb.ts +2 -1
  282. package/src/integrations/mysql.ts +20 -94
  283. package/src/integrations/oracle.ts +445 -0
  284. package/src/integrations/postgres.ts +45 -35
  285. package/src/integrations/rest.ts +2 -1
  286. package/src/integrations/s3.ts +2 -1
  287. package/src/integrations/tests/microsoftSqlServer.spec.js +22 -15
  288. package/src/integrations/tests/oracle.spec.js +94 -0
  289. package/src/integrations/tests/postgres.spec.js +4 -0
  290. package/src/integrations/utils.ts +74 -8
  291. package/src/middleware/authorized.js +26 -18
  292. package/src/middleware/builder.js +4 -1
  293. package/src/middleware/tests/authorized.spec.js +2 -0
  294. package/src/tests/utilities/TestConfiguration.js +2 -1
  295. package/src/{automations/thread.js → threads/automation.js} +27 -8
  296. package/src/threads/index.js +66 -0
  297. package/src/threads/query.js +66 -0
  298. package/src/utilities/csvParser.js +48 -5
  299. package/src/utilities/global.js +7 -2
  300. package/src/utilities/index.js +11 -0
  301. package/src/utilities/queue/inMemoryQueue.js +7 -0
  302. package/src/utilities/scriptRunner.js +4 -1
  303. package/src/utilities/tests/__snapshots__/csvParser.spec.js.snap +0 -6
  304. package/src/utilities/tests/csvParser.spec.js +3 -0
  305. package/tsconfig.json +1 -1
  306. package/builder/assets/index.10556cc1.js +0 -201
  307. package/builder/assets/index.7469e1e4.css +0 -29
  308. package/builder/assets/vendor.278a305c.js +0 -9
  309. package/builder/assets/vendor.d75d5eb7.css +0 -1
@@ -56,7 +56,7 @@ function parse(csvString, parsers) {
56
56
  });
57
57
  result.subscribe(row => {
58
58
  // For each CSV row parse all the columns that need parsed
59
- for (let key in parsers) {
59
+ for (let key of Object.keys(parsers)) {
60
60
  if (!schema[key] || schema[key].success) {
61
61
  // get the validator for the column type
62
62
  const validator = VALIDATORS[parsers[key].type];
@@ -79,15 +79,55 @@ function parse(csvString, parsers) {
79
79
  });
80
80
  });
81
81
  }
82
- function transform({ schema, csvString }) {
82
+ function updateSchema({ schema, existingTable }) {
83
+ if (!schema) {
84
+ return schema;
85
+ }
86
+ const finalSchema = {};
87
+ const schemaKeyMap = {};
88
+ Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key));
89
+ for (let [key, field] of Object.entries(existingTable.schema)) {
90
+ const lcKey = key.toLowerCase();
91
+ const foundKey = schemaKeyMap[lcKey];
92
+ if (foundKey) {
93
+ finalSchema[key] = schema[foundKey];
94
+ finalSchema[key].type = field.type;
95
+ }
96
+ }
97
+ return finalSchema;
98
+ }
99
+ function transform({ schema, csvString, existingTable }) {
83
100
  return __awaiter(this, void 0, void 0, function* () {
84
101
  const colParser = {};
85
- for (let key in schema) {
102
+ // make sure the table has all the columns required for import
103
+ if (existingTable) {
104
+ schema = updateSchema({ schema, existingTable });
105
+ }
106
+ for (let key of Object.keys(schema)) {
86
107
  colParser[key] = PARSERS[schema[key].type] || schema[key].type;
87
108
  }
88
109
  try {
89
- const json = yield csv({ colParser }).fromString(csvString);
90
- return json;
110
+ const data = yield csv({ colParser }).fromString(csvString);
111
+ const schemaKeyMap = {};
112
+ Object.keys(schema).forEach(key => (schemaKeyMap[key.toLowerCase()] = key));
113
+ for (let element of data) {
114
+ if (!data) {
115
+ continue;
116
+ }
117
+ for (let key of Object.keys(element)) {
118
+ const mappedKey = schemaKeyMap[key.toLowerCase()];
119
+ // isn't a column in the table, remove it
120
+ if (mappedKey == null) {
121
+ delete element[key];
122
+ }
123
+ // casing is different, fix it in row
124
+ else if (key !== mappedKey) {
125
+ element[mappedKey] = element[key];
126
+ delete element[key];
127
+ }
128
+ }
129
+ }
130
+ return data;
91
131
  }
92
132
  catch (err) {
93
133
  console.error(`Error transforming CSV to JSON for data import`, err);
@@ -98,4 +138,5 @@ function transform({ schema, csvString }) {
98
138
  module.exports = {
99
139
  parse,
100
140
  transform,
141
+ updateSchema,
101
142
  };
@@ -50,9 +50,12 @@ exports.getCachedSelf = (ctx, appId) => __awaiter(void 0, void 0, void 0, functi
50
50
  const user = yield userCache.getUser(ctx.user._id);
51
51
  return processUser(appId, user);
52
52
  });
53
- exports.getGlobalUser = (appId, userId) => __awaiter(void 0, void 0, void 0, function* () {
53
+ exports.getRawGlobalUser = (userId) => __awaiter(void 0, void 0, void 0, function* () {
54
54
  const db = getGlobalDB();
55
- let user = yield db.get(getGlobalIDFromUserMetadataID(userId));
55
+ return db.get(getGlobalIDFromUserMetadataID(userId));
56
+ });
57
+ exports.getGlobalUser = (appId, userId) => __awaiter(void 0, void 0, void 0, function* () {
58
+ let user = yield exports.getRawGlobalUser(userId);
56
59
  return processUser(appId, user);
57
60
  });
58
61
  exports.getGlobalUsers = (appId = null, users = null) => __awaiter(void 0, void 0, void 0, function* () {
@@ -71,6 +74,7 @@ exports.getGlobalUsers = (appId = null, users = null) => __awaiter(void 0, void
71
74
  .filter(user => user != null)
72
75
  .map(user => {
73
76
  delete user.password;
77
+ delete user.forceResetPassword;
74
78
  return user;
75
79
  });
76
80
  if (!appId) {
@@ -52,6 +52,7 @@ exports.objectStoreUrl = () => {
52
52
  * via a specific endpoint (under /api/assets/client).
53
53
  * @param {string} appId In production we need the appId to look up the correct bucket, as the
54
54
  * version of the client lib may differ between apps.
55
+ * @param {string} version The version to retrieve.
55
56
  * @return {string} The URL to be inserted into appPackage response or server rendered
56
57
  * app index file.
57
58
  */
@@ -131,3 +132,13 @@ exports.stringToReadStream = string => {
131
132
  },
132
133
  });
133
134
  };
135
+ exports.doesDatabaseExist = (dbName) => __awaiter(void 0, void 0, void 0, function* () {
136
+ try {
137
+ const db = new CouchDB(dbName, { skip_setup: true });
138
+ const info = yield db.info();
139
+ return info && !info.error;
140
+ }
141
+ catch (err) {
142
+ return false;
143
+ }
144
+ });
@@ -93,5 +93,13 @@ class InMemoryQueue {
93
93
  getRepeatableJobs() {
94
94
  return [];
95
95
  }
96
+ /**
97
+ * Implemented for tests
98
+ */
99
+ clean() {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ return [];
102
+ });
103
+ }
96
104
  }
97
105
  module.exports = InMemoryQueue;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  const fetch = require("node-fetch");
3
3
  const { VM, VMScript } = require("vm2");
4
+ const JS_TIMEOUT_MS = 1000;
4
5
  class ScriptRunner {
5
6
  constructor(script, context) {
6
7
  const code = `let fn = () => {\n${script}\n}; results.out = fn();`;
7
- this.vm = new VM();
8
+ this.vm = new VM({
9
+ timeout: JS_TIMEOUT_MS,
10
+ });
8
11
  this.results = { out: "" };
9
12
  this.vm.setGlobals(context);
10
13
  this.vm.setGlobal("fetch", fetch);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "0.9.186",
4
+ "version": "0.9.190-alpha.0",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -14,7 +14,7 @@
14
14
  "test": "jest --coverage --maxWorkers=2",
15
15
  "test:watch": "jest --watch",
16
16
  "predocker": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client",
17
- "build:docker": "yarn run predocker && docker build . -t app-service",
17
+ "build:docker": "yarn run predocker && docker build . -t app-service --label version=$BUDIBASE_RELEASE_VERSION",
18
18
  "run:docker": "node dist/index.js",
19
19
  "dev:stack:up": "node scripts/dev/manage.js up",
20
20
  "dev:stack:down": "node scripts/dev/manage.js down",
@@ -66,11 +66,13 @@
66
66
  "budibase"
67
67
  ],
68
68
  "author": "Budibase",
69
- "license": "AGPL-3.0-or-later",
69
+ "license": "GPL-3.0",
70
70
  "dependencies": {
71
- "@budibase/auth": "^0.9.186",
72
- "@budibase/client": "^0.9.186",
73
- "@budibase/string-templates": "^0.9.186",
71
+ "@budibase/auth": "^0.9.190-alpha.0",
72
+ "@budibase/client": "^0.9.190-alpha.0",
73
+ "@budibase/string-templates": "^0.9.190-alpha.0",
74
+ "@bull-board/api": "^3.7.0",
75
+ "@bull-board/koa": "^3.7.0",
74
76
  "@elastic/elasticsearch": "7.10.0",
75
77
  "@koa/router": "8.0.0",
76
78
  "@sendgrid/mail": "7.1.1",
@@ -80,7 +82,6 @@
80
82
  "aws-sdk": "^2.767.0",
81
83
  "bcryptjs": "2.4.3",
82
84
  "bull": "^3.22.4",
83
- "bull-board": "^2.0.1",
84
85
  "chmodr": "1.2.0",
85
86
  "csvtojson": "2.0.10",
86
87
  "dotenv": "8.2.0",
@@ -120,6 +121,7 @@
120
121
  "uuid": "3.3.2",
121
122
  "validate.js": "0.13.1",
122
123
  "vm2": "^3.9.3",
124
+ "worker-farm": "^1.7.0",
123
125
  "yargs": "13.2.4",
124
126
  "zlib": "1.0.5"
125
127
  },
@@ -133,12 +135,12 @@
133
135
  "@types/koa": "^2.13.3",
134
136
  "@types/koa-router": "^7.4.2",
135
137
  "@types/node": "^15.12.4",
138
+ "@types/oracledb": "^5.2.1",
136
139
  "@typescript-eslint/parser": "4.28.0",
137
140
  "babel-jest": "^27.0.2",
138
141
  "copyfiles": "^2.4.1",
139
142
  "docker-compose": "^0.23.6",
140
143
  "eslint": "^6.8.0",
141
- "express": "^4.17.1",
142
144
  "jest": "^27.0.5",
143
145
  "nodemon": "^2.0.4",
144
146
  "prettier": "^2.3.1",
@@ -149,5 +151,8 @@
149
151
  "typescript": "^4.3.5",
150
152
  "update-dotenv": "^1.1.1"
151
153
  },
152
- "gitHead": "4385ee6fc2e2e2ec9738aa29ee9cae463c2de54b"
154
+ "optionalDependencies": {
155
+ "oracledb": "^5.3.0"
156
+ },
157
+ "gitHead": "58c1927f6a5dcbab760fbdb9d581b1ef1bb9dabf"
153
158
  }
@@ -50,6 +50,7 @@ async function init() {
50
50
  SELF_HOSTED: 1,
51
51
  DISABLE_ACCOUNT_PORTAL: "",
52
52
  MULTI_TENANCY: "",
53
+ DISABLE_THREADING: 1,
53
54
  }
54
55
  let envFile = ""
55
56
  Object.keys(envFileJson).forEach(key => {
@@ -0,0 +1,9 @@
1
+ FROM mcr.microsoft.com/mssql/server
2
+
3
+ ENV ACCEPT_EULA=Y
4
+ ENV SA_PASSWORD=Passw0rd
5
+
6
+ COPY ./data /
7
+
8
+ ENTRYPOINT [ "/bin/bash", "entrypoint.sh" ]
9
+ CMD [ "/opt/mssql/bin/sqlservr" ]
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ if [ "$1" = '/opt/mssql/bin/sqlservr' ]; then
5
+ # If this is the container's first run, initialize the application database
6
+ if [ ! -f /tmp/app-initialized ]; then
7
+ # Initialize the application database asynchronously in a background process. This allows a) the SQL Server process to be the main process in the container, which allows graceful shutdown and other goodies, and b) us to only start the SQL Server process once, as opposed to starting, stopping, then starting it again.
8
+ function initialize_app_database() {
9
+ # Wait a bit for SQL Server to start. SQL Server's process doesn't provide a clever way to check if it's up or not, and it needs to be up before we can import the application database
10
+ sleep 30s
11
+
12
+ echo "RUNNING BUDIBASE SETUP"
13
+
14
+ #run the setup script to create the DB and the schema in the DB
15
+ /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -i setup.sql
16
+
17
+ # Note that the container has been initialized so future starts won't wipe changes to the data
18
+ touch /tmp/app-initialized
19
+ }
20
+ initialize_app_database &
21
+ fi
22
+ fi
23
+
24
+ exec "$@"
@@ -0,0 +1,54 @@
1
+ USE master;
2
+
3
+ IF OBJECT_ID ('dbo.products', 'U') IS NOT NULL
4
+ DROP TABLE products;
5
+ GO
6
+ CREATE TABLE products
7
+ (
8
+ id int IDENTITY(1,1),
9
+ name varchar (20),
10
+ description varchar(30),
11
+ CONSTRAINT pk_products PRIMARY KEY NONCLUSTERED (id)
12
+ );
13
+
14
+ IF OBJECT_ID ('dbo.tasks', 'U') IS NOT NULL
15
+ DROP TABLE tasks;
16
+ GO
17
+ CREATE TABLE tasks
18
+ (
19
+ taskid int IDENTITY(1,1),
20
+ taskname varchar (20),
21
+ productid int,
22
+ CONSTRAINT pk_tasks PRIMARY KEY NONCLUSTERED (taskid),
23
+ CONSTRAINT fk_products FOREIGN KEY (productid) REFERENCES products (id),
24
+ );
25
+
26
+ IF OBJECT_ID ('dbo.people', 'U') IS NOT NULL
27
+ DROP TABLE people;
28
+ GO
29
+ CREATE TABLE people
30
+ (
31
+ name varchar(30),
32
+ age varchar(20),
33
+ CONSTRAINT pk_people PRIMARY KEY NONCLUSTERED (name, age)
34
+ );
35
+
36
+ INSERT products
37
+ (name, description)
38
+ VALUES
39
+ ('Bananas', 'Fruit thing');
40
+
41
+ INSERT products
42
+ (name, description)
43
+ VALUES
44
+ ('Meat', 'Animal thing');
45
+
46
+ INSERT tasks
47
+ (taskname, productid)
48
+ VALUES
49
+ ('Processing', 1);
50
+
51
+ INSERT people
52
+ (name, age)
53
+ VALUES
54
+ ('Bob', '30');
@@ -0,0 +1,12 @@
1
+ version: "3.8"
2
+ services:
3
+ # password: Passw0rd
4
+ # user: sa
5
+ # database: master
6
+ mssql:
7
+ image: bb/mssql
8
+ build:
9
+ context: .
10
+ dockerfile: data/Dockerfile
11
+ ports:
12
+ - "1433:1433"
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ docker-compose down
3
+ docker volume prune -f
@@ -0,0 +1,19 @@
1
+ # For more information see:
2
+ # https://container-registry.oracle.com/
3
+ # - Database > Express
4
+ version: "3.8"
5
+ services:
6
+ db:
7
+ container_name: oracle-xe
8
+ platform: linux/x86_64
9
+ image: container-registry.oracle.com/database/express:18.4.0-xe
10
+ environment:
11
+ ORACLE_PWD: oracle
12
+ ports:
13
+ - 1521:1521
14
+ - 5500:5500
15
+ volumes:
16
+ - oracle_data:/opt/oracle/oradata
17
+
18
+ volumes:
19
+ oracle_data:
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+
3
+ # Must be root to continue
4
+ if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi
5
+
6
+ # Allow for re-runs
7
+ rm -rf /opt/oracle
8
+
9
+ echo "Installing oracle instant client"
10
+
11
+ # copy and unzip package
12
+ mkdir -p /opt/oracle
13
+ cp scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip /opt/oracle
14
+ cd /opt/oracle
15
+ unzip -qq basiclite-21.4.zip -d .
16
+ rm *.zip
17
+ mv instantclient* instantclient
18
+
19
+ # update runtime link path
20
+ sh -c "echo /opt/oracle/instantclient > /etc/ld.so.conf.d/oracle-instantclient.conf"
21
+ ldconfig /etc/ld.so.conf.d
22
+
23
+ echo "Installation complete"
@@ -0,0 +1,90 @@
1
+ # Installation
2
+
3
+ ## Database
4
+
5
+ **Important**
6
+ - Oracle database is supported only on **x86-64 architecture**
7
+ - Oracle database is **not supported on Mac ARM architecture** (either via docker or linux virtualization)
8
+
9
+ To install oracle express edition simply run `docker-compose up`
10
+
11
+ - A single instance pluggable database (PDB) will be created named `xepdb`
12
+ - The default password is configured in the compose file as `oracle`
13
+ - The `system`, `sys` and `pdbadmin` users all share this password
14
+
15
+ ## Instant Client
16
+
17
+ Before oracle can be connected to from nodejs, the oracle client must be installed.
18
+ For more information see https://www.oracle.com/database/technologies/instant-client/downloads.html
19
+
20
+ **Important**
21
+ - Oracle client is supported only on **x86-64 architecture**
22
+ - Oracle client is **not supported on Mac ARM architecture**
23
+
24
+ ### Linux
25
+ Run the provided install script for linux from the `server` root path:
26
+
27
+ ```bash
28
+ sudo /bin/bash -e scripts/integrations/oracle/instantclient/linux/x86-64/install.sh
29
+ ```
30
+ For more information see: https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html#ic_x64_inst
31
+
32
+ ### Mac
33
+ **This has not yet been tested**
34
+
35
+ See: https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html#ic_osx_inst
36
+
37
+ # Management
38
+ To connect to oracle sql command line:
39
+
40
+ ```bash
41
+ docker exec -it oracle-xe sqlplus -l system/oracle@localhost/xepdb1
42
+ ```
43
+
44
+ To create a new schema (where a user is the same as a schema in oracle) named `sales`:
45
+
46
+ ```sql
47
+ define USERNAME = sales
48
+
49
+ create user &USERNAME;
50
+
51
+ alter user &USERNAME
52
+ default tablespace users
53
+ temporary tablespace temp
54
+ quota unlimited on users;
55
+
56
+ grant create session,
57
+ create view,
58
+ create sequence,
59
+ create procedure,
60
+ create table,
61
+ create trigger,
62
+ create type,
63
+ create materialized view
64
+ to &USERNAME;
65
+ ```
66
+
67
+ To set the password for the sales schema use:
68
+
69
+ ```sql
70
+ define USERNAME = sales
71
+ define PASSWORD = sales
72
+
73
+ alter user &USERNAME identified by &PASSWORD;
74
+ ```
75
+
76
+ As before the database schema can now be connected to using:
77
+ ```bash
78
+ docker exec -it oracle-xe sqlplus -l sales/sales@localhost:1521/xepdb1
79
+ ```
80
+
81
+ ## HR Schema
82
+
83
+ The `HR` schema is populated with dummy data by default in oracle for testing purposes.
84
+ To connect to the HR schema first update the user password and unlock the account by performing
85
+ ```sql
86
+ ALTER USER hr ACCOUNT UNLOCK;
87
+ ALTER USER hr IDENTIFIED BY hr
88
+ ```
89
+ You should now be able to connect to the hr schema using the credentials hr/hr
90
+
@@ -11,7 +11,7 @@ services:
11
11
  ports:
12
12
  - "5432:5432"
13
13
  volumes:
14
- #- pg_data:/var/lib/postgresql/data/
14
+ - pg_data:/var/lib/postgresql/data/
15
15
  - ./init.sql:/docker-entrypoint-initdb.d/init.sql
16
16
 
17
17
  pgadmin:
@@ -24,5 +24,5 @@ services:
24
24
  ports:
25
25
  - "5050:80"
26
26
 
27
- #volumes:
28
- # pg_data:
27
+ volumes:
28
+ pg_data:
@@ -0,0 +1,33 @@
1
+ /******************************************************
2
+ * This script just makes it easy to re-create *
3
+ * a cypress like environment for testing the backend *
4
+ ******************************************************/
5
+ const path = require("path")
6
+ const tmpdir = path.join(require("os").tmpdir(), ".budibase")
7
+
8
+ const MAIN_PORT = "10001"
9
+ const WORKER_PORT = "10002"
10
+
11
+ // @ts-ignore
12
+ process.env.PORT = MAIN_PORT
13
+ process.env.BUDIBASE_API_KEY = "6BE826CB-6B30-4AEC-8777-2E90464633DE"
14
+ process.env.NODE_ENV = "cypress"
15
+ process.env.ENABLE_ANALYTICS = "false"
16
+ process.env.JWT_SECRET = "budibase"
17
+ process.env.COUCH_URL = `leveldb://${tmpdir}/.data/`
18
+ process.env.SELF_HOSTED = "1"
19
+ process.env.WORKER_URL = `http://localhost:${WORKER_PORT}/`
20
+ process.env.MINIO_URL = `http://localhost:${MAIN_PORT}/`
21
+ process.env.MINIO_ACCESS_KEY = "budibase"
22
+ process.env.MINIO_SECRET_KEY = "budibase"
23
+ process.env.COUCH_DB_USER = "budibase"
24
+ process.env.COUCH_DB_PASSWORD = "budibase"
25
+ process.env.INTERNAL_API_KEY = "budibase"
26
+ process.env.ALLOW_DEV_AUTOMATIONS = "1"
27
+
28
+ // don't make this a variable or top level require
29
+ // it will cause environment module to be loaded prematurely
30
+ const server = require("../src/app")
31
+ process.env.PORT = WORKER_PORT
32
+ const worker = require("../../worker/src/index")
33
+ process.env.PORT = MAIN_PORT
@@ -44,6 +44,9 @@ const {
44
44
  revertClientLibrary,
45
45
  } = require("../../utilities/fileSystem/clientLibrary")
46
46
  const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy")
47
+ const { syncGlobalUsers } = require("./user")
48
+ const { app: appCache } = require("@budibase/auth/cache")
49
+ const { cleanupAutomations } = require("../../automations/utils")
47
50
 
48
51
  const URL_REGEX_SLASH = /\/|\\/g
49
52
 
@@ -253,6 +256,7 @@ exports.create = async ctx => {
253
256
  await createApp(appId)
254
257
  }
255
258
 
259
+ await appCache.invalidateAppMetadata(appId, newApplication)
256
260
  ctx.status = 200
257
261
  ctx.body = newApplication
258
262
  }
@@ -316,8 +320,12 @@ exports.delete = async ctx => {
316
320
  if (!env.isTest() && !ctx.query.unpublish) {
317
321
  await deleteApp(ctx.params.appId)
318
322
  }
323
+ if (ctx.query && ctx.query.unpublish) {
324
+ await cleanupAutomations(ctx.params.appId)
325
+ }
319
326
  // make sure the app/role doesn't stick around after the app has been deleted
320
327
  await removeAppFromUserRoles(ctx, ctx.params.appId)
328
+ await appCache.invalidateAppMetadata(ctx.params.appId)
321
329
 
322
330
  ctx.status = 200
323
331
  ctx.body = result
@@ -328,6 +336,8 @@ exports.sync = async (ctx, next) => {
328
336
  if (!isDevAppID(appId)) {
329
337
  ctx.throw(400, "This action cannot be performed for production apps")
330
338
  }
339
+
340
+ // replicate prod to dev
331
341
  const prodAppId = getDeployedAppID(appId)
332
342
 
333
343
  try {
@@ -357,6 +367,10 @@ exports.sync = async (ctx, next) => {
357
367
  } catch (err) {
358
368
  error = err
359
369
  }
370
+
371
+ // sync the users
372
+ await syncGlobalUsers(appId)
373
+
360
374
  if (error) {
361
375
  ctx.throw(400, error)
362
376
  } else {
@@ -380,7 +394,10 @@ const updateAppPackage = async (ctx, appPackage, appId) => {
380
394
  // Redis, shouldn't ever store it
381
395
  delete newAppPackage.lockedBy
382
396
 
383
- return await db.put(newAppPackage)
397
+ const response = await db.put(newAppPackage)
398
+ // remove any cached metadata, so that it will be updated
399
+ await appCache.invalidateAppMetadata(appId)
400
+ return response
384
401
  }
385
402
 
386
403
  const createEmptyAppPackage = async (ctx, app) => {
@@ -14,6 +14,8 @@ exports.fetchSelf = async ctx => {
14
14
  }
15
15
 
16
16
  const user = await getFullUser(ctx, userId)
17
+ // this shouldn't be returned by the app self
18
+ delete user.roles
17
19
 
18
20
  if (appId) {
19
21
  const db = new CouchDB(appId)
@@ -36,6 +38,7 @@ exports.fetchSelf = async ctx => {
36
38
  // user has a role of some sort, return them
37
39
  else if (err.status === 404) {
38
40
  const metadata = {
41
+ ...user,
39
42
  _id: userId,
40
43
  }
41
44
  const dbResp = await db.put(metadata)