@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
@@ -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,9 +1,9 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "0.9.188",
4
+ "version": "0.9.190-alpha.10",
5
5
  "description": "Budibase Web Server",
6
- "main": "src/index.js",
6
+ "main": "src/index.ts",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "https://github.com/Budibase/budibase.git"
@@ -14,7 +14,8 @@
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
+ "build:docs": "node ./scripts/docs/generate.js open",
18
19
  "run:docker": "node dist/index.js",
19
20
  "dev:stack:up": "node scripts/dev/manage.js up",
20
21
  "dev:stack:down": "node scripts/dev/manage.js down",
@@ -68,9 +69,11 @@
68
69
  "author": "Budibase",
69
70
  "license": "GPL-3.0",
70
71
  "dependencies": {
71
- "@budibase/auth": "^0.9.188",
72
- "@budibase/client": "^0.9.188",
73
- "@budibase/string-templates": "^0.9.188",
72
+ "@budibase/auth": "^0.9.190-alpha.10",
73
+ "@budibase/client": "^0.9.190-alpha.10",
74
+ "@budibase/string-templates": "^0.9.190-alpha.10",
75
+ "@bull-board/api": "^3.7.0",
76
+ "@bull-board/koa": "^3.7.0",
74
77
  "@elastic/elasticsearch": "7.10.0",
75
78
  "@koa/router": "8.0.0",
76
79
  "@sendgrid/mail": "7.1.1",
@@ -80,7 +83,6 @@
80
83
  "aws-sdk": "^2.767.0",
81
84
  "bcryptjs": "2.4.3",
82
85
  "bull": "^3.22.4",
83
- "bull-board": "^2.0.1",
84
86
  "chmodr": "1.2.0",
85
87
  "csvtojson": "2.0.10",
86
88
  "dotenv": "8.2.0",
@@ -105,7 +107,7 @@
105
107
  "mssql": "6.2.3",
106
108
  "mysql2": "^2.3.1",
107
109
  "node-fetch": "2.6.0",
108
- "open": "7.3.0",
110
+ "open": "^8.4.0",
109
111
  "pg": "8.5.1",
110
112
  "pino-pretty": "4.0.0",
111
113
  "posthog-node": "^1.1.4",
@@ -120,6 +122,7 @@
120
122
  "uuid": "3.3.2",
121
123
  "validate.js": "0.13.1",
122
124
  "vm2": "^3.9.3",
125
+ "worker-farm": "^1.7.0",
123
126
  "yargs": "13.2.4",
124
127
  "zlib": "1.0.5"
125
128
  },
@@ -128,19 +131,22 @@
128
131
  "@babel/preset-env": "^7.14.4",
129
132
  "@budibase/standard-components": "^0.9.139",
130
133
  "@jest/test-sequencer": "^24.8.0",
134
+ "@types/apidoc": "^0.50.0",
131
135
  "@types/bull": "^3.15.1",
132
136
  "@types/jest": "^26.0.23",
133
137
  "@types/koa": "^2.13.3",
134
138
  "@types/koa-router": "^7.4.2",
135
139
  "@types/node": "^15.12.4",
140
+ "@types/oracledb": "^5.2.1",
136
141
  "@typescript-eslint/parser": "4.28.0",
142
+ "apidoc": "^0.50.2",
137
143
  "babel-jest": "^27.0.2",
138
144
  "copyfiles": "^2.4.1",
139
145
  "docker-compose": "^0.23.6",
140
146
  "eslint": "^6.8.0",
141
- "express": "^4.17.1",
142
147
  "jest": "^27.0.5",
143
148
  "nodemon": "^2.0.4",
149
+ "path-to-regexp": "^6.2.0",
144
150
  "prettier": "^2.3.1",
145
151
  "rimraf": "^3.0.2",
146
152
  "supertest": "^4.0.2",
@@ -149,5 +155,8 @@
149
155
  "typescript": "^4.3.5",
150
156
  "update-dotenv": "^1.1.1"
151
157
  },
152
- "gitHead": "a4b88dc2cadf867494a468f21474bdc5d54fe66a"
158
+ "optionalDependencies": {
159
+ "oracledb": "^5.3.0"
160
+ },
161
+ "gitHead": "ac1660540c4eb261483022732bdd9ed99474472d"
153
162
  }
@@ -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,31 @@
1
+ ### Documentation
2
+
3
+ This directory contains the scripts required to generate the APIDoc based documentation.
4
+ You can find the docs about comment structure at the [APIDocs page](https://apidocjs.com/).
5
+
6
+ In general most API endpoints will look like:
7
+ ```js
8
+ /**
9
+ * @api {post} /api/:param/url Give it a name
10
+ * @apiName Give it a name
11
+ * @apiGroup group
12
+ * @apiPermission permission
13
+ * @apiDescription Describe what the endpoint does, any special cases the user
14
+ * should be aware of.
15
+ *
16
+ * @apiParam {string} param describe a URL parameter.
17
+ *
18
+ * @apiParam (Body) input describe a field on the body.
19
+ *
20
+ * @apiSuccess {object} output describe the output.
21
+ */
22
+ ```
23
+
24
+ There are a few key points to note when writing API docs:
25
+ 1. Don't use `@apiBody` - this isn't currently supported by our swagger converter.
26
+ 2. Make sure to always have an `@api` definition at the start, which must always have the
27
+ HTTP verb, the endpoint URL and the name.
28
+ 3. There are three ways you can specify parameters used as inputs for your endpoint,
29
+ `@apiParam` for a URL param, `@apiParam (Body)` for a field on the request body and `@apiParam (Query)`
30
+ for query string parameters.
31
+ 4. The `@apiGroup` should be the same for all API Doc comments in a route file.
@@ -0,0 +1,74 @@
1
+ const fs = require("fs")
2
+ const { join } = require("path")
3
+ const { createDoc } = require("apidoc")
4
+ const packageJson = require("../../package.json")
5
+ const toSwagger = require("./toSwagger")
6
+ const open = require("open")
7
+
8
+ const config = {
9
+ name: "Budibase API",
10
+ version: packageJson.version,
11
+ description: "Documenting the Budibase backend API",
12
+ title: "Budibase app service API",
13
+ }
14
+
15
+ const shouldOpen = process.argv[2]
16
+ const disallowed = []
17
+
18
+ function filter(parsedRouteFiles) {
19
+ const tagToSearch = "url"
20
+ for (let routeFile of parsedRouteFiles) {
21
+ for (let route of routeFile) {
22
+ let routeInfo = route["local"]
23
+ if (disallowed.includes(routeInfo[tagToSearch])) {
24
+ const idx = routeFile.indexOf(route)
25
+ routeFile.splice(idx, 1)
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ async function generate() {
32
+ // start by writing a config file
33
+ const configPath = join(__dirname, "config.json")
34
+ fs.writeFileSync(configPath, JSON.stringify(config))
35
+ const mainPath = join(__dirname, "..", "..")
36
+ const srcPath = join(mainPath, "src", "api", "routes")
37
+ const assetsPath = join(mainPath, "builder", "assets", "docs")
38
+ if (!fs.existsSync(assetsPath)) {
39
+ fs.mkdirSync(assetsPath, { recursive: true })
40
+ }
41
+ const options = {
42
+ src: [srcPath],
43
+ dest: assetsPath,
44
+ filters: {
45
+ main: {
46
+ postFilter: filter,
47
+ },
48
+ },
49
+ config: configPath,
50
+ }
51
+ const doc = createDoc(options)
52
+ if (typeof doc !== "boolean") {
53
+ const swagger = toSwagger(JSON.parse(doc.data), JSON.parse(doc.project))
54
+ fs.writeFileSync(join(assetsPath, "swagger.json"), JSON.stringify(swagger))
55
+ fs.writeFileSync(join(assetsPath, "apidoc.json"), doc.data)
56
+ fs.writeFileSync(join(assetsPath, "project.json"), doc.project)
57
+ console.log(
58
+ `Docs generated successfully, find in ${assetsPath}, swagger.json, apidoc.json and project.json`
59
+ )
60
+ } else {
61
+ throw "Unable to generate docs."
62
+ }
63
+ // delete the temporary config file
64
+ fs.unlinkSync(configPath)
65
+ setTimeout(async () => {
66
+ if (shouldOpen === "open") {
67
+ await open(join(assetsPath, "index.html"), { wait: false })
68
+ }
69
+ }, 2000)
70
+ }
71
+
72
+ generate().catch(err => {
73
+ console.error(err)
74
+ })
@@ -0,0 +1,320 @@
1
+ let _ = require("lodash")
2
+ let { pathToRegexp } = require("path-to-regexp")
3
+
4
+ /********************************************************
5
+ * Based on: https://github.com/fsbahman/apidoc-swagger *
6
+ ********************************************************/
7
+
8
+ let swagger = {
9
+ swagger: "2.0",
10
+ info: {},
11
+ paths: {},
12
+ definitions: {},
13
+ }
14
+
15
+ function toSwagger(apidocJson, projectJson) {
16
+ swagger.info = addInfo(projectJson)
17
+ swagger.paths = extractPaths(apidocJson)
18
+ return swagger
19
+ }
20
+
21
+ let tagsRegex = /(<([^>]+)>)/gi
22
+ // Removes <p> </p> tags from text
23
+ function removeTags(text) {
24
+ return text ? text.replace(tagsRegex, "") : text
25
+ }
26
+
27
+ function addInfo(projectJson) {
28
+ let info = {}
29
+ info["title"] = projectJson.title || projectJson.name
30
+ info["version"] = projectJson.version
31
+ info["description"] = projectJson.description
32
+ return info
33
+ }
34
+
35
+ /**
36
+ * Extracts paths provided in json format
37
+ * post, patch, put request parameters are extracted in body
38
+ * get and delete are extracted to path parameters
39
+ * @param apidocJson
40
+ * @returns {{}}
41
+ */
42
+ function extractPaths(apidocJson) {
43
+ let apiPaths = groupByUrl(apidocJson)
44
+ let paths = {}
45
+ for (let i = 0; i < apiPaths.length; i++) {
46
+ let verbs = apiPaths[i].verbs
47
+ let url = verbs[0].url
48
+ let pattern = pathToRegexp(url, null)
49
+ let matches = pattern.exec(url)
50
+
51
+ // Surrounds URL parameters with curly brackets -> :email with {email}
52
+ let pathKeys = []
53
+ for (let j = 1; j < matches.length; j++) {
54
+ let key = matches[j].substr(1)
55
+ url = url.replace(matches[j], "{" + key + "}")
56
+ pathKeys.push(key)
57
+ }
58
+
59
+ for (let j = 0; j < verbs.length; j++) {
60
+ let verb = verbs[j]
61
+ let type = verb.type
62
+
63
+ let obj = (paths[url] = paths[url] || {})
64
+
65
+ if (type === "post" || type === "patch" || type === "put") {
66
+ _.extend(
67
+ obj,
68
+ createPostPushPutOutput(verb, swagger.definitions, pathKeys)
69
+ )
70
+ } else {
71
+ _.extend(obj, createGetDeleteOutput(verb, swagger.definitions))
72
+ }
73
+ }
74
+ }
75
+ return paths
76
+ }
77
+
78
+ function createPostPushPutOutput(verbs, definitions, pathKeys) {
79
+ let pathItemObject = {}
80
+ let verbDefinitionResult = createVerbDefinitions(verbs, definitions)
81
+
82
+ let params = []
83
+ let pathParams = createPathParameters(verbs, pathKeys)
84
+ pathParams = _.filter(pathParams, function (param) {
85
+ let hasKey = pathKeys.indexOf(param.name) !== -1
86
+ return !(param.in === "path" && !hasKey)
87
+ })
88
+
89
+ params = params.concat(pathParams)
90
+ let required =
91
+ verbs.parameter &&
92
+ verbs.parameter.fields &&
93
+ verbs.parameter.fields.Parameter &&
94
+ verbs.parameter.fields.Parameter.length > 0
95
+
96
+ params.push({
97
+ in: "body",
98
+ name: "body",
99
+ description: removeTags(verbs.description),
100
+ required: required,
101
+ schema: {
102
+ $ref: "#/definitions/" + verbDefinitionResult.topLevelParametersRef,
103
+ },
104
+ })
105
+
106
+ pathItemObject[verbs.type] = {
107
+ tags: [verbs.group],
108
+ summary: removeTags(verbs.description),
109
+ consumes: ["application/json"],
110
+ produces: ["application/json"],
111
+ parameters: params,
112
+ }
113
+
114
+ if (verbDefinitionResult.topLevelSuccessRef) {
115
+ pathItemObject[verbs.type].responses = {
116
+ 200: {
117
+ description: "successful operation",
118
+ schema: {
119
+ type: verbDefinitionResult.topLevelSuccessRefType,
120
+ items: {
121
+ $ref: "#/definitions/" + verbDefinitionResult.topLevelSuccessRef,
122
+ },
123
+ },
124
+ },
125
+ }
126
+ }
127
+
128
+ return pathItemObject
129
+ }
130
+
131
+ function createVerbDefinitions(verbs, definitions) {
132
+ let result = {
133
+ topLevelParametersRef: null,
134
+ topLevelSuccessRef: null,
135
+ topLevelSuccessRefType: null,
136
+ }
137
+ let defaultObjectName = verbs.name
138
+
139
+ let fieldArrayResult = {}
140
+ if (verbs && verbs.parameter && verbs.parameter.fields) {
141
+ fieldArrayResult = createFieldArrayDefinitions(
142
+ verbs.parameter.fields.Parameter,
143
+ definitions,
144
+ verbs.name,
145
+ defaultObjectName
146
+ )
147
+ result.topLevelParametersRef = fieldArrayResult.topLevelRef
148
+ }
149
+
150
+ if (verbs && verbs.success && verbs.success.fields) {
151
+ fieldArrayResult = createFieldArrayDefinitions(
152
+ verbs.success.fields["Success 200"],
153
+ definitions,
154
+ verbs.name,
155
+ defaultObjectName
156
+ )
157
+ result.topLevelSuccessRef = fieldArrayResult.topLevelRef
158
+ result.topLevelSuccessRefType = fieldArrayResult.topLevelRefType
159
+ }
160
+
161
+ return result
162
+ }
163
+
164
+ function createFieldArrayDefinitions(
165
+ fieldArray,
166
+ definitions,
167
+ topLevelRef,
168
+ defaultObjectName
169
+ ) {
170
+ let result = {
171
+ topLevelRef: topLevelRef,
172
+ topLevelRefType: null,
173
+ }
174
+
175
+ if (!fieldArray) {
176
+ return result
177
+ }
178
+
179
+ for (let i = 0; i < fieldArray.length; i++) {
180
+ let parameter = fieldArray[i]
181
+
182
+ let nestedName = createNestedName(parameter.field)
183
+ let objectName = nestedName.objectName
184
+ if (!objectName) {
185
+ objectName = defaultObjectName
186
+ }
187
+ let type = parameter.type
188
+ if (i === 0) {
189
+ result.topLevelRefType = type
190
+ if (parameter.type === "Object") {
191
+ objectName = nestedName.propertyName
192
+ nestedName.propertyName = null
193
+ } else if (parameter.type === "Array") {
194
+ objectName = nestedName.propertyName
195
+ nestedName.propertyName = null
196
+ result.topLevelRefType = "array"
197
+ }
198
+ result.topLevelRef = objectName
199
+ }
200
+
201
+ definitions[objectName] = definitions[objectName] || {
202
+ properties: {},
203
+ required: [],
204
+ }
205
+
206
+ if (nestedName.propertyName) {
207
+ let prop = {
208
+ type: (parameter.type || "").toLowerCase(),
209
+ description: removeTags(parameter.description),
210
+ }
211
+ if (parameter.type === "Object") {
212
+ prop.$ref = "#/definitions/" + parameter.field
213
+ }
214
+
215
+ let typeIndex = type.indexOf("[]")
216
+ if (typeIndex !== -1 && typeIndex === type.length - 2) {
217
+ prop.type = "array"
218
+ prop.items = {
219
+ type: type.slice(0, type.length - 2),
220
+ }
221
+ }
222
+
223
+ definitions[objectName]["properties"][nestedName.propertyName] = prop
224
+ if (!parameter.optional) {
225
+ let arr = definitions[objectName]["required"]
226
+ if (arr.indexOf(nestedName.propertyName) === -1) {
227
+ arr.push(nestedName.propertyName)
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ return result
234
+ }
235
+
236
+ function createNestedName(field) {
237
+ let propertyName = field
238
+ let objectName
239
+ let propertyNames = field.split(".")
240
+ if (propertyNames && propertyNames.length > 1) {
241
+ propertyName = propertyNames[propertyNames.length - 1]
242
+ propertyNames.pop()
243
+ objectName = propertyNames.join(".")
244
+ }
245
+
246
+ return {
247
+ propertyName: propertyName,
248
+ objectName: objectName,
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Generate get, delete method output
254
+ * @param verbs
255
+ * @param definitions
256
+ * @returns {{}}
257
+ */
258
+ function createGetDeleteOutput(verbs, definitions) {
259
+ let pathItemObject = {}
260
+ verbs.type = verbs.type === "del" ? "delete" : verbs.type
261
+
262
+ let verbDefinitionResult = createVerbDefinitions(verbs, definitions)
263
+ pathItemObject[verbs.type] = {
264
+ tags: [verbs.group],
265
+ summary: removeTags(verbs.description),
266
+ consumes: ["application/json"],
267
+ produces: ["application/json"],
268
+ parameters: createPathParameters(verbs),
269
+ }
270
+ if (verbDefinitionResult.topLevelSuccessRef) {
271
+ pathItemObject[verbs.type].responses = {
272
+ 200: {
273
+ description: "successful operation",
274
+ schema: {
275
+ type: verbDefinitionResult.topLevelSuccessRefType,
276
+ items: {
277
+ $ref: "#/definitions/" + verbDefinitionResult.topLevelSuccessRef,
278
+ },
279
+ },
280
+ },
281
+ }
282
+ }
283
+ return pathItemObject
284
+ }
285
+
286
+ /**
287
+ * Iterate through all method parameters and create array of parameter objects which are stored as path parameters
288
+ * @param verbs
289
+ * @returns {Array}
290
+ */
291
+ function createPathParameters(verbs) {
292
+ let pathItemObject = []
293
+ if (verbs.parameter && verbs.parameter.fields.Parameter) {
294
+ for (let i = 0; i < verbs.parameter.fields.Parameter.length; i++) {
295
+ let param = verbs.parameter.fields.Parameter[i]
296
+ let field = param.field
297
+ let type = param.type
298
+ pathItemObject.push({
299
+ name: field,
300
+ in: type === "file" ? "formData" : "path",
301
+ required: !param.optional,
302
+ type: param.type.toLowerCase(),
303
+ description: removeTags(param.description),
304
+ })
305
+ }
306
+ }
307
+ return pathItemObject
308
+ }
309
+
310
+ function groupByUrl(apidocJson) {
311
+ return _.chain(apidocJson)
312
+ .groupBy("url")
313
+ .toPairs()
314
+ .map(function (element) {
315
+ return _.zipObject(["url", "verbs"], element)
316
+ })
317
+ .value()
318
+ }
319
+
320
+ module.exports = toSwagger
@@ -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" ]