@budibase/server 0.9.185-alpha.2 → 0.9.185-alpha.20

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 (251) hide show
  1. package/Dockerfile +7 -1
  2. package/__mocks__/oracledb.ts +31 -0
  3. package/builder/assets/bb-space-man.5be51a45.svg +290 -0
  4. package/builder/assets/index.7d405e74.css +1 -0
  5. package/builder/assets/index.83e08172.js +1316 -0
  6. package/builder/assets/oracle.66592424.png +0 -0
  7. package/builder/assets/vendor.470042a4.js +152 -0
  8. package/builder/assets/vendor.5e1fe644.css +1 -0
  9. package/builder/index.html +4 -4
  10. package/coverage/clover.xml +785 -687
  11. package/coverage/coverage-final.json +90 -88
  12. package/coverage/lcov-report/api/controllers/analytics.js.html +2 -2
  13. package/coverage/lcov-report/api/controllers/apikeys.js.html +2 -2
  14. package/coverage/lcov-report/api/controllers/application.js.html +43 -13
  15. package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
  16. package/coverage/lcov-report/api/controllers/automation.js.html +3 -3
  17. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/component.js.html +4 -4
  20. package/coverage/lcov-report/api/controllers/datasource.js.html +129 -21
  21. package/coverage/lcov-report/api/controllers/dev.js.html +16 -7
  22. package/coverage/lcov-report/api/controllers/hosting.js.html +10 -10
  23. package/coverage/lcov-report/api/controllers/index.html +77 -77
  24. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/layout.js.html +3 -3
  26. package/coverage/lcov-report/api/controllers/metadata.js.html +3 -3
  27. package/coverage/lcov-report/api/controllers/permission.js.html +3 -3
  28. package/coverage/lcov-report/api/controllers/query.js.html +48 -210
  29. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  30. package/coverage/lcov-report/api/controllers/routing.js.html +3 -3
  31. package/coverage/lcov-report/api/controllers/row/external.js.html +2 -2
  32. package/coverage/lcov-report/api/controllers/row/index.html +10 -10
  33. package/coverage/lcov-report/api/controllers/row/index.js.html +2 -2
  34. package/coverage/lcov-report/api/controllers/row/internal.js.html +9 -9
  35. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +2 -2
  36. package/coverage/lcov-report/api/controllers/row/utils.js.html +2 -2
  37. package/coverage/lcov-report/api/controllers/screen.js.html +2 -2
  38. package/coverage/lcov-report/api/controllers/script.js.html +3 -3
  39. package/coverage/lcov-report/api/controllers/table/external.js.html +29 -8
  40. package/coverage/lcov-report/api/controllers/table/index.html +20 -20
  41. package/coverage/lcov-report/api/controllers/table/index.js.html +3 -3
  42. package/coverage/lcov-report/api/controllers/table/internal.js.html +2 -2
  43. package/coverage/lcov-report/api/controllers/table/utils.js.html +8 -8
  44. package/coverage/lcov-report/api/controllers/templates.js.html +4 -4
  45. package/coverage/lcov-report/api/controllers/user.js.html +2 -2
  46. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.html +9 -9
  48. package/coverage/lcov-report/api/controllers/view/index.js.html +5 -5
  49. package/coverage/lcov-report/api/controllers/view/utils.js.html +11 -11
  50. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +3 -3
  51. package/coverage/lcov-report/api/controllers/webhook.js.html +4 -4
  52. package/coverage/lcov-report/api/index.html +1 -1
  53. package/coverage/lcov-report/api/index.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/dev.js.html +2 -2
  65. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/index.html +4 -4
  67. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/query.js.html +5 -2
  73. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/static.js.html +2 -2
  79. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  81. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  82. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  83. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  84. package/coverage/lcov-report/automations/actions.js.html +2 -2
  85. package/coverage/lcov-report/automations/automationUtils.js.html +3 -3
  86. package/coverage/lcov-report/automations/bullboard.js.html +71 -20
  87. package/coverage/lcov-report/automations/index.html +33 -48
  88. package/coverage/lcov-report/automations/index.js.html +2 -2
  89. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/discord.js.html +3 -3
  94. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/executeScript.js.html +3 -3
  96. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/index.html +14 -14
  98. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +3 -3
  100. package/coverage/lcov-report/automations/steps/queryRows.js.html +3 -3
  101. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/utils.js.html +7 -7
  106. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/app.js.html +2 -2
  108. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +2 -2
  109. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/index.js.html +8 -8
  111. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +2 -2
  112. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +2 -2
  113. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +2 -2
  114. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +2 -2
  115. package/coverage/lcov-report/automations/triggers.js.html +22 -10
  116. package/coverage/lcov-report/automations/utils.js.html +42 -12
  117. package/coverage/lcov-report/constants/index.html +5 -5
  118. package/coverage/lcov-report/constants/index.js.html +44 -23
  119. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  120. package/coverage/lcov-report/constants/screens.js.html +1 -1
  121. package/coverage/lcov-report/db/client.js.html +2 -2
  122. package/coverage/lcov-report/db/inMemoryView.js.html +2 -2
  123. package/coverage/lcov-report/db/index.html +2 -2
  124. package/coverage/lcov-report/db/index.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +6 -6
  126. package/coverage/lcov-report/db/linkedRows/index.html +10 -10
  127. package/coverage/lcov-report/db/linkedRows/index.js.html +5 -5
  128. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +6 -6
  129. package/coverage/lcov-report/db/newid.js.html +3 -3
  130. package/coverage/lcov-report/db/utils.js.html +57 -57
  131. package/coverage/lcov-report/events/AutomationEmitter.js.html +6 -6
  132. package/coverage/lcov-report/events/index.html +6 -6
  133. package/coverage/lcov-report/events/index.js.html +1 -1
  134. package/coverage/lcov-report/events/utils.js.html +5 -5
  135. package/coverage/lcov-report/index.html +86 -71
  136. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  137. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  138. package/coverage/lcov-report/middleware/appInfo.js.html +2 -2
  139. package/coverage/lcov-report/middleware/authorized.js.html +4 -4
  140. package/coverage/lcov-report/middleware/builder.js.html +16 -7
  141. package/coverage/lcov-report/middleware/currentapp.js.html +6 -6
  142. package/coverage/lcov-report/middleware/index.html +21 -21
  143. package/coverage/lcov-report/middleware/joi-validator.js.html +2 -2
  144. package/coverage/lcov-report/middleware/resourceId.js.html +18 -18
  145. package/coverage/lcov-report/middleware/selfhost.js.html +2 -2
  146. package/coverage/lcov-report/middleware/usageQuota.js.html +4 -4
  147. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  148. package/coverage/lcov-report/{automations/thread.js.html → threads/automation.js.html} +90 -33
  149. package/coverage/lcov-report/threads/index.html +141 -0
  150. package/coverage/lcov-report/threads/index.js.html +278 -0
  151. package/coverage/lcov-report/threads/query.js.html +278 -0
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  154. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  155. package/coverage/lcov-report/utilities/csvParser.js.html +2 -2
  156. package/coverage/lcov-report/utilities/global.js.html +2 -2
  157. package/coverage/lcov-report/utilities/index.html +21 -21
  158. package/coverage/lcov-report/utilities/index.js.html +12 -9
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +30 -9
  160. package/coverage/lcov-report/utilities/queue/index.html +14 -14
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +4 -4
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +2 -2
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +3 -3
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +16 -7
  167. package/coverage/lcov-report/utilities/security.js.html +3 -3
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/users.js.html +1 -1
  170. package/coverage/lcov-report/utilities/workerRequests.js.html +5 -5
  171. package/coverage/lcov.info +1247 -1070
  172. package/dist/api/controllers/application.js +11 -1
  173. package/dist/api/controllers/datasource.js +31 -7
  174. package/dist/api/controllers/deploy/index.js +2 -0
  175. package/dist/api/controllers/dev.js +4 -1
  176. package/dist/api/controllers/query.js +27 -57
  177. package/dist/api/controllers/table/external.js +8 -1
  178. package/dist/api/routes/query.js +1 -1
  179. package/dist/app.js +2 -11
  180. package/dist/automations/bullboard.js +37 -10
  181. package/dist/automations/triggers.js +7 -3
  182. package/dist/automations/utils.js +11 -2
  183. package/dist/constants/index.js +6 -0
  184. package/dist/definitions/datasource.js +1 -0
  185. package/dist/environment.js +13 -0
  186. package/dist/integrations/base/IntegrationBase.js +2 -0
  187. package/dist/integrations/base/sql.js +40 -8
  188. package/dist/integrations/index.js +6 -0
  189. package/dist/integrations/mysql.js +3 -1
  190. package/dist/integrations/oracle.js +345 -0
  191. package/dist/integrations/utils.js +17 -2
  192. package/dist/middleware/builder.js +4 -1
  193. package/dist/package.json +11 -6
  194. package/dist/{automations/thread.js → threads/automation.js} +26 -8
  195. package/dist/threads/index.js +64 -0
  196. package/dist/threads/query.js +64 -0
  197. package/dist/tsconfig.tsbuildinfo +1 -1
  198. package/dist/utilities/index.js +1 -0
  199. package/dist/utilities/queue/inMemoryQueue.js +8 -0
  200. package/dist/utilities/scriptRunner.js +4 -1
  201. package/package.json +12 -7
  202. package/scripts/dev/manage.js +1 -0
  203. package/scripts/integrations/oracle/docker-compose.yml +19 -0
  204. package/scripts/integrations/oracle/instantclient/linux/x86-64/basiclite-21.4.zip +0 -0
  205. package/scripts/integrations/oracle/instantclient/linux/x86-64/install.sh +23 -0
  206. package/scripts/integrations/oracle/oracle.md +90 -0
  207. package/scripts/integrations/postgres/docker-compose.yml +3 -3
  208. package/scripts/likeCypress.ts +33 -0
  209. package/src/api/controllers/application.js +11 -1
  210. package/src/api/controllers/datasource.js +45 -9
  211. package/src/api/controllers/deploy/index.js +2 -0
  212. package/src/api/controllers/dev.js +4 -1
  213. package/src/api/controllers/query.js +26 -80
  214. package/src/api/controllers/table/external.js +8 -1
  215. package/src/api/routes/query.js +1 -0
  216. package/src/app.ts +2 -10
  217. package/src/automations/bullboard.js +28 -11
  218. package/src/automations/tests/automation.spec.js +3 -4
  219. package/src/automations/triggers.js +7 -3
  220. package/src/automations/utils.js +12 -2
  221. package/src/constants/index.js +7 -0
  222. package/src/definitions/datasource.ts +1 -0
  223. package/src/environment.js +15 -0
  224. package/src/integrations/airtable.ts +2 -1
  225. package/src/integrations/arangodb.ts +2 -1
  226. package/src/integrations/base/IntegrationBase.ts +6 -0
  227. package/src/integrations/base/datasourcePlus.ts +2 -1
  228. package/src/integrations/base/sql.ts +41 -9
  229. package/src/integrations/couchdb.ts +2 -1
  230. package/src/integrations/dynamodb.ts +2 -1
  231. package/src/integrations/elasticsearch.ts +2 -1
  232. package/src/integrations/index.ts +7 -0
  233. package/src/integrations/mongodb.ts +2 -1
  234. package/src/integrations/mysql.ts +1 -1
  235. package/src/integrations/oracle.ts +445 -0
  236. package/src/integrations/rest.ts +2 -1
  237. package/src/integrations/s3.ts +2 -1
  238. package/src/integrations/tests/oracle.spec.js +94 -0
  239. package/src/integrations/utils.ts +16 -2
  240. package/src/middleware/builder.js +4 -1
  241. package/src/{automations/thread.js → threads/automation.js} +27 -8
  242. package/src/threads/index.js +66 -0
  243. package/src/threads/query.js +66 -0
  244. package/src/utilities/index.js +1 -0
  245. package/src/utilities/queue/inMemoryQueue.js +7 -0
  246. package/src/utilities/scriptRunner.js +4 -1
  247. package/tsconfig.json +1 -1
  248. package/builder/assets/index.0eadd2f5.js +0 -201
  249. package/builder/assets/index.a79ec0ef.css +0 -29
  250. package/builder/assets/vendor.278a305c.js +0 -9
  251. package/builder/assets/vendor.d75d5eb7.css +0 -1
@@ -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
  */
@@ -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.185-alpha.2",
4
+ "version": "0.9.185-alpha.20",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.js",
7
7
  "repository": {
@@ -68,9 +68,11 @@
68
68
  "author": "Budibase",
69
69
  "license": "AGPL-3.0-or-later",
70
70
  "dependencies": {
71
- "@budibase/auth": "^0.9.185-alpha.2",
72
- "@budibase/client": "^0.9.185-alpha.2",
73
- "@budibase/string-templates": "^0.9.185-alpha.2",
71
+ "@budibase/auth": "^0.9.185-alpha.20",
72
+ "@budibase/client": "^0.9.185-alpha.20",
73
+ "@budibase/string-templates": "^0.9.185-alpha.20",
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": "5bb8900cdd92acf802ce2529ccabbeaa745f4b37"
154
+ "optionalDependencies": {
155
+ "oracledb": "^5.3.0"
156
+ },
157
+ "gitHead": "5f40c6e234ea415c93ced4a2d13a0c2194be94a2"
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,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
@@ -45,6 +45,8 @@ const {
45
45
  } = require("../../utilities/fileSystem/clientLibrary")
46
46
  const { getTenantId, isMultiTenant } = require("@budibase/auth/tenancy")
47
47
  const { syncGlobalUsers } = require("./user")
48
+ const { app: appCache } = require("@budibase/auth/cache")
49
+ const { cleanupAutomations } = require("../../automations/utils")
48
50
 
49
51
  const URL_REGEX_SLASH = /\/|\\/g
50
52
 
@@ -254,6 +256,7 @@ exports.create = async ctx => {
254
256
  await createApp(appId)
255
257
  }
256
258
 
259
+ await appCache.invalidateAppMetadata(appId, newApplication)
257
260
  ctx.status = 200
258
261
  ctx.body = newApplication
259
262
  }
@@ -317,8 +320,12 @@ exports.delete = async ctx => {
317
320
  if (!env.isTest() && !ctx.query.unpublish) {
318
321
  await deleteApp(ctx.params.appId)
319
322
  }
323
+ if (ctx.query && ctx.query.unpublish) {
324
+ await cleanupAutomations(ctx.params.appId)
325
+ }
320
326
  // make sure the app/role doesn't stick around after the app has been deleted
321
327
  await removeAppFromUserRoles(ctx, ctx.params.appId)
328
+ await appCache.invalidateAppMetadata(ctx.params.appId)
322
329
 
323
330
  ctx.status = 200
324
331
  ctx.body = result
@@ -387,7 +394,10 @@ const updateAppPackage = async (ctx, appPackage, appId) => {
387
394
  // Redis, shouldn't ever store it
388
395
  delete newAppPackage.lockedBy
389
396
 
390
- 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
391
401
  }
392
402
 
393
403
  const createEmptyAppPackage = async (ctx, app) => {
@@ -7,7 +7,7 @@ const {
7
7
  BudibaseInternalDB,
8
8
  getTableParams,
9
9
  } = require("../../db/utils")
10
- const { BuildSchemaErrors } = require("../../constants")
10
+ const { BuildSchemaErrors, InvalidColumns } = require("../../constants")
11
11
  const { integrations } = require("../../integrations")
12
12
  const { getDatasourceAndQuery } = require("./row/utils")
13
13
 
@@ -119,8 +119,16 @@ exports.destroy = async function (ctx) {
119
119
  const db = new CouchDB(ctx.appId)
120
120
 
121
121
  // Delete all queries for the datasource
122
- const rows = await db.allDocs(getQueryParams(ctx.params.datasourceId, null))
123
- await db.bulkDocs(rows.rows.map(row => ({ ...row.doc, _deleted: true })))
122
+ const queries = await db.allDocs(
123
+ getQueryParams(ctx.params.datasourceId, null)
124
+ )
125
+ await db.bulkDocs(
126
+ queries.rows.map(row => ({
127
+ _id: row.id,
128
+ _rev: row.value.rev,
129
+ _deleted: true,
130
+ }))
131
+ )
124
132
 
125
133
  // delete the datasource
126
134
  await db.remove(ctx.params.datasourceId, ctx.params.revId)
@@ -144,6 +152,23 @@ exports.query = async function (ctx) {
144
152
  }
145
153
  }
146
154
 
155
+ function getErrorTables(errors, errorType) {
156
+ return Object.entries(errors)
157
+ .filter(entry => entry[1] === errorType)
158
+ .map(([name]) => name)
159
+ }
160
+
161
+ function updateError(error, newError, tables) {
162
+ if (!error) {
163
+ error = ""
164
+ }
165
+ if (error.length > 0) {
166
+ error += "\n"
167
+ }
168
+ error += `${newError} ${tables.join(", ")}`
169
+ return error
170
+ }
171
+
147
172
  const buildSchemaHelper = async datasource => {
148
173
  const Connector = integrations[datasource.source]
149
174
 
@@ -168,12 +193,23 @@ const buildSchemaHelper = async datasource => {
168
193
  const errors = connector.schemaErrors
169
194
  let error = null
170
195
  if (errors && Object.keys(errors).length > 0) {
171
- const noKeyTables = Object.entries(errors)
172
- .filter(entry => entry[1] === BuildSchemaErrors.NO_KEY)
173
- .map(([name]) => name)
174
- error = `No primary key constraint found for the following: ${noKeyTables.join(
175
- ", "
176
- )}`
196
+ const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY)
197
+ const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN)
198
+ if (noKey.length) {
199
+ error = updateError(
200
+ error,
201
+ "No primary key constraint found for the following:",
202
+ noKey
203
+ )
204
+ }
205
+ if (invalidCol.length) {
206
+ const invalidCols = Object.values(InvalidColumns).join(", ")
207
+ error = updateError(
208
+ error,
209
+ `Cannot use columns ${invalidCols} found in following:`,
210
+ invalidCol
211
+ )
212
+ }
177
213
  }
178
214
  return { tables: connector.tables, error }
179
215
  }
@@ -6,6 +6,7 @@ const {
6
6
  disableAllCrons,
7
7
  enableCronTrigger,
8
8
  } = require("../../../automations/utils")
9
+ const { app: appCache } = require("@budibase/auth/cache")
9
10
 
10
11
  // the max time we can wait for an invalidation to complete before considering it failed
11
12
  const MAX_PENDING_TIME_MS = 30 * 60000
@@ -103,6 +104,7 @@ async function deployApp(deployment) {
103
104
  appDoc.appId = productionAppId
104
105
  appDoc.instance._id = productionAppId
105
106
  await db.put(appDoc)
107
+ await appCache.invalidateAppMetadata(productionAppId)
106
108
  console.log("New app doc written successfully.")
107
109
  await initDeployedApp(productionAppId)
108
110
  console.log("Deployed app initialised, setting deployment to successful")
@@ -6,6 +6,7 @@ const { request } = require("../../utilities/workerRequests")
6
6
  const { clearLock } = require("../../utilities/redis")
7
7
  const { Replication } = require("@budibase/auth").db
8
8
  const { DocumentTypes } = require("../../db/utils")
9
+ const { app: appCache } = require("@budibase/auth/cache")
9
10
 
10
11
  async function redirect(ctx, method, path = "global") {
11
12
  const { devPath } = ctx.params
@@ -24,7 +25,8 @@ async function redirect(ctx, method, path = "global") {
24
25
  )
25
26
  )
26
27
  if (response.status !== 200) {
27
- ctx.throw(response.status, response.statusText)
28
+ const err = await response.text()
29
+ ctx.throw(400, err)
28
30
  }
29
31
  const cookie = response.headers.get("set-cookie")
30
32
  if (cookie) {
@@ -106,6 +108,7 @@ exports.revert = async ctx => {
106
108
  appDoc.appId = appId
107
109
  appDoc.instance._id = appId
108
110
  await db.put(appDoc)
111
+ await appCache.invalidateAppMetadata(appId)
109
112
  ctx.body = {
110
113
  message: "Reverted changes successfully.",
111
114
  }
@@ -1,10 +1,11 @@
1
1
  const { processString } = require("@budibase/string-templates")
2
2
  const CouchDB = require("../../db")
3
3
  const { generateQueryID, getQueryParams } = require("../../db/utils")
4
- const { integrations } = require("../../integrations")
5
4
  const { BaseQueryVerbs } = require("../../constants")
6
5
  const env = require("../../environment")
7
- const ScriptRunner = require("../../utilities/scriptRunner")
6
+ const { Thread, ThreadType } = require("../../threads")
7
+
8
+ const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 })
8
9
 
9
10
  // simple function to append "readable" to all read queries
10
11
  function enrichQueries(input) {
@@ -18,47 +19,6 @@ function enrichQueries(input) {
18
19
  return wasArray ? queries : queries[0]
19
20
  }
20
21
 
21
- function formatResponse(resp) {
22
- if (typeof resp === "string") {
23
- try {
24
- resp = JSON.parse(resp)
25
- } catch (err) {
26
- resp = { response: resp }
27
- }
28
- }
29
- return resp
30
- }
31
-
32
- async function runAndTransform(
33
- integration,
34
- queryVerb,
35
- enrichedQuery,
36
- transformer
37
- ) {
38
- let rows = formatResponse(await integration[queryVerb](enrichedQuery))
39
-
40
- // transform as required
41
- if (transformer) {
42
- const runner = new ScriptRunner(transformer, { data: rows })
43
- rows = runner.execute()
44
- }
45
-
46
- // needs to an array for next step
47
- if (!Array.isArray(rows)) {
48
- rows = [rows]
49
- }
50
-
51
- // map into JSON if just raw primitive here
52
- if (rows.find(row => typeof row !== "object")) {
53
- rows = rows.map(value => ({ value }))
54
- }
55
-
56
- // get all the potential fields in the schema
57
- let keys = rows.flatMap(Object.keys)
58
-
59
- return { rows, keys }
60
- }
61
-
62
22
  exports.fetch = async function (ctx) {
63
23
  const db = new CouchDB(ctx.appId)
64
24
 
@@ -143,30 +103,23 @@ exports.preview = async function (ctx) {
143
103
 
144
104
  const datasource = await db.get(ctx.request.body.datasourceId)
145
105
 
146
- const Integration = integrations[datasource.source]
147
-
148
- if (!Integration) {
149
- ctx.throw(400, "Integration type does not exist.")
150
- }
151
-
152
106
  const { fields, parameters, queryVerb, transformer } = ctx.request.body
153
107
  const enrichedQuery = await enrichQueryFields(fields, parameters)
154
- const integration = new Integration(datasource.config)
155
108
 
156
- const { rows, keys } = await runAndTransform(
157
- integration,
158
- queryVerb,
159
- enrichedQuery,
160
- transformer
161
- )
109
+ try {
110
+ const { rows, keys } = await Runner.run({
111
+ datasource,
112
+ queryVerb,
113
+ query: enrichedQuery,
114
+ transformer,
115
+ })
162
116
 
163
- ctx.body = {
164
- rows,
165
- schemaFields: [...new Set(keys)],
166
- }
167
- // cleanup
168
- if (integration.end) {
169
- integration.end()
117
+ ctx.body = {
118
+ rows,
119
+ schemaFields: [...new Set(keys)],
120
+ }
121
+ } catch (err) {
122
+ ctx.throw(400, err)
170
123
  }
171
124
  }
172
125
 
@@ -176,29 +129,22 @@ exports.execute = async function (ctx) {
176
129
  const query = await db.get(ctx.params.queryId)
177
130
  const datasource = await db.get(query.datasourceId)
178
131
 
179
- const Integration = integrations[datasource.source]
180
-
181
- if (!Integration) {
182
- ctx.throw(400, "Integration type does not exist.")
183
- }
184
-
185
132
  const enrichedQuery = await enrichQueryFields(
186
133
  query.fields,
187
134
  ctx.request.body.parameters
188
135
  )
189
- const integration = new Integration(datasource.config)
190
136
 
191
137
  // call the relevant CRUD method on the integration class
192
- const { rows } = await runAndTransform(
193
- integration,
194
- query.queryVerb,
195
- enrichedQuery,
196
- query.transformer
197
- )
198
- ctx.body = rows
199
- // cleanup
200
- if (integration.end) {
201
- integration.end()
138
+ try {
139
+ const { rows } = await Runner.run({
140
+ datasource,
141
+ queryVerb: query.queryVerb,
142
+ query: enrichedQuery,
143
+ transformer: query.transformer,
144
+ })
145
+ ctx.body = rows
146
+ } catch (err) {
147
+ ctx.throw(400, err)
202
148
  }
203
149
  }
204
150
 
@@ -161,9 +161,13 @@ function isRelationshipSetup(column) {
161
161
  exports.save = async function (ctx) {
162
162
  const appId = ctx.appId
163
163
  const table = ctx.request.body
164
- // can't do this
164
+ // can't do this right now
165
165
  delete table.dataImport
166
166
  const datasourceId = getDatasourceId(ctx.request.body)
167
+ // table doesn't exist already, note that it is created
168
+ if (!table._id) {
169
+ table.created = true
170
+ }
167
171
  let tableToSave = {
168
172
  type: "table",
169
173
  _id: buildExternalTableId(datasourceId, table.name),
@@ -265,6 +269,9 @@ exports.save = async function (ctx) {
265
269
  exports.destroy = async function (ctx) {
266
270
  const appId = ctx.appId
267
271
  const tableToDelete = await getTable(appId, ctx.params.tableId)
272
+ if (!tableToDelete || !tableToDelete.created) {
273
+ ctx.throw(400, "Cannot delete tables which weren't created in Budibase.")
274
+ }
268
275
  const datasourceId = getDatasourceId(tableToDelete)
269
276
 
270
277
  const db = new CouchDB(appId)
@@ -66,6 +66,7 @@ router
66
66
  )
67
67
  .get(
68
68
  "/api/queries/:queryId",
69
+ paramResource("queryId"),
69
70
  authorized(PermissionTypes.QUERY, PermissionLevels.READ),
70
71
  queryController.find
71
72
  )
package/src/app.ts CHANGED
@@ -41,16 +41,8 @@ app.use(
41
41
  )
42
42
 
43
43
  if (!env.isTest()) {
44
- const bullApp = bullboard.init()
45
- app.use(async (ctx: ExtendableContext, next: () => any) => {
46
- if (ctx.path.startsWith(bullboard.pathPrefix)) {
47
- ctx.status = 200
48
- ctx.respond = false
49
- bullApp(ctx.req, ctx.res)
50
- } else {
51
- await next()
52
- }
53
- })
44
+ const plugin = bullboard.init()
45
+ app.use(plugin)
54
46
  }
55
47
 
56
48
  app.context.eventEmitter = eventEmitter