@budibase/server 1.0.80 → 1.0.81-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/__mocks__/node-fetch.ts +1 -0
  2. package/builder/assets/{index.c8d1e8f0.css → index.8b1dc06c.css} +2 -2
  3. package/builder/assets/index.e4d4c510.js +1291 -0
  4. package/builder/assets/{vendor.20f80cec.js → vendor.a7c6ad0a.js} +190 -216
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +2531 -2440
  7. package/coverage/coverage-final.json +138 -137
  8. package/coverage/lcov-report/api/controllers/analytics.js.html +6 -6
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
  10. package/coverage/lcov-report/api/controllers/application.js.html +152 -149
  11. package/coverage/lcov-report/api/controllers/auth.js.html +7 -7
  12. package/coverage/lcov-report/api/controllers/automation.js.html +21 -21
  13. package/coverage/lcov-report/api/controllers/backup.js.html +3 -3
  14. package/coverage/lcov-report/api/controllers/cloud.js.html +11 -11
  15. package/coverage/lcov-report/api/controllers/component.js.html +5 -5
  16. package/coverage/lcov-report/api/controllers/datasource.js.html +16 -16
  17. package/coverage/lcov-report/api/controllers/dev.js.html +19 -19
  18. package/coverage/lcov-report/api/controllers/index.html +16 -16
  19. package/coverage/lcov-report/api/controllers/integration.js.html +4 -4
  20. package/coverage/lcov-report/api/controllers/layout.js.html +6 -6
  21. package/coverage/lcov-report/api/controllers/metadata.js.html +9 -9
  22. package/coverage/lcov-report/api/controllers/migrations.js.html +4 -4
  23. package/coverage/lcov-report/api/controllers/permission.js.html +15 -15
  24. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  25. package/coverage/lcov-report/api/controllers/query/index.js.html +26 -26
  26. package/coverage/lcov-report/api/controllers/query/validation.js.html +10 -10
  27. package/coverage/lcov-report/api/controllers/role.js.html +9 -9
  28. package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
  29. package/coverage/lcov-report/api/controllers/row/external.js.html +86 -23
  30. package/coverage/lcov-report/api/controllers/row/index.html +46 -46
  31. package/coverage/lcov-report/api/controllers/row/index.js.html +76 -49
  32. package/coverage/lcov-report/api/controllers/row/internal.js.html +144 -84
  33. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +204 -204
  34. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +24 -24
  35. package/coverage/lcov-report/api/controllers/row/utils.js.html +29 -29
  36. package/coverage/lcov-report/api/controllers/screen.js.html +7 -7
  37. package/coverage/lcov-report/api/controllers/script.js.html +4 -4
  38. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +49 -49
  39. package/coverage/lcov-report/api/controllers/table/external.js.html +62 -20
  40. package/coverage/lcov-report/api/controllers/table/index.html +20 -20
  41. package/coverage/lcov-report/api/controllers/table/index.js.html +47 -44
  42. package/coverage/lcov-report/api/controllers/table/internal.js.html +50 -50
  43. package/coverage/lcov-report/api/controllers/table/utils.js.html +80 -80
  44. package/coverage/lcov-report/api/controllers/templates.js.html +5 -5
  45. package/coverage/lcov-report/api/controllers/user.js.html +19 -19
  46. package/coverage/lcov-report/api/controllers/view/exporters.js.html +4 -4
  47. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  48. package/coverage/lcov-report/api/controllers/view/index.js.html +14 -14
  49. package/coverage/lcov-report/api/controllers/view/utils.js.html +12 -12
  50. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +7 -7
  51. package/coverage/lcov-report/api/controllers/webhook.js.html +18 -27
  52. package/coverage/lcov-report/api/index.html +10 -10
  53. package/coverage/lcov-report/api/index.js.html +37 -28
  54. package/coverage/lcov-report/api/routes/analytics.js.html +6 -6
  55. package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
  56. package/coverage/lcov-report/api/routes/application.js.html +9 -9
  57. package/coverage/lcov-report/api/routes/auth.js.html +6 -6
  58. package/coverage/lcov-report/api/routes/automation.js.html +19 -109
  59. package/coverage/lcov-report/api/routes/backup.js.html +8 -8
  60. package/coverage/lcov-report/api/routes/cloud.js.html +8 -8
  61. package/coverage/lcov-report/api/routes/component.js.html +8 -8
  62. package/coverage/lcov-report/api/routes/datasource.js.html +18 -156
  63. package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
  64. package/coverage/lcov-report/api/routes/dev.js.html +13 -13
  65. package/coverage/lcov-report/api/routes/index.html +35 -35
  66. package/coverage/lcov-report/api/routes/index.js.html +38 -32
  67. package/coverage/lcov-report/api/routes/integration.js.html +8 -8
  68. package/coverage/lcov-report/api/routes/layout.js.html +8 -8
  69. package/coverage/lcov-report/api/routes/metadata.js.html +9 -9
  70. package/coverage/lcov-report/api/routes/migrations.js.html +7 -7
  71. package/coverage/lcov-report/api/routes/permission.js.html +16 -58
  72. package/coverage/lcov-report/api/routes/query.js.html +10 -10
  73. package/coverage/lcov-report/api/routes/role.js.html +15 -78
  74. package/coverage/lcov-report/api/routes/routing.js.html +8 -8
  75. package/coverage/lcov-report/api/routes/row.js.html +80 -14
  76. package/coverage/lcov-report/api/routes/screen.js.html +14 -95
  77. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/static.js.html +13 -13
  79. package/coverage/lcov-report/api/routes/table.js.html +17 -62
  80. package/coverage/lcov-report/api/routes/templates.js.html +8 -8
  81. package/coverage/lcov-report/api/routes/user.js.html +8 -8
  82. package/coverage/lcov-report/api/routes/utils/index.html +111 -0
  83. package/coverage/lcov-report/api/routes/utils/validators.js.html +737 -0
  84. package/coverage/lcov-report/api/routes/view.js.html +10 -10
  85. package/coverage/lcov-report/api/routes/webhook.js.html +14 -62
  86. package/coverage/lcov-report/automations/actions.js.html +24 -24
  87. package/coverage/lcov-report/automations/automationUtils.js.html +5 -5
  88. package/coverage/lcov-report/automations/bullboard.js.html +16 -16
  89. package/coverage/lcov-report/automations/index.html +1 -1
  90. package/coverage/lcov-report/automations/index.js.html +7 -7
  91. package/coverage/lcov-report/automations/steps/bash.js.html +6 -6
  92. package/coverage/lcov-report/automations/steps/createRow.js.html +7 -7
  93. package/coverage/lcov-report/automations/steps/delay.js.html +4 -4
  94. package/coverage/lcov-report/automations/steps/deleteRow.js.html +7 -7
  95. package/coverage/lcov-report/automations/steps/discord.js.html +7 -7
  96. package/coverage/lcov-report/automations/steps/executeQuery.js.html +6 -6
  97. package/coverage/lcov-report/automations/steps/executeScript.js.html +6 -6
  98. package/coverage/lcov-report/automations/steps/filter.js.html +12 -9
  99. package/coverage/lcov-report/automations/steps/index.html +1 -1
  100. package/coverage/lcov-report/automations/steps/integromat.js.html +5 -5
  101. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -8
  102. package/coverage/lcov-report/automations/steps/queryRows.js.html +11 -11
  103. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +5 -5
  104. package/coverage/lcov-report/automations/steps/serverLog.js.html +3 -3
  105. package/coverage/lcov-report/automations/steps/slack.js.html +5 -5
  106. package/coverage/lcov-report/automations/steps/updateRow.js.html +6 -6
  107. package/coverage/lcov-report/automations/steps/utils.js.html +3 -3
  108. package/coverage/lcov-report/automations/steps/zapier.js.html +5 -5
  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 +26 -26
  118. package/coverage/lcov-report/automations/utils.js.html +35 -35
  119. package/coverage/lcov-report/constants/index.html +5 -5
  120. package/coverage/lcov-report/constants/index.js.html +40 -28
  121. package/coverage/lcov-report/constants/layouts.js.html +5 -5
  122. package/coverage/lcov-report/constants/screens.js.html +4 -4
  123. package/coverage/lcov-report/db/client.js.html +18 -18
  124. package/coverage/lcov-report/db/inMemoryView.js.html +7 -7
  125. package/coverage/lcov-report/db/index.html +15 -15
  126. package/coverage/lcov-report/db/index.js.html +3 -3
  127. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +21 -21
  128. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  129. package/coverage/lcov-report/db/linkedRows/index.js.html +36 -36
  130. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +30 -30
  131. package/coverage/lcov-report/db/newid.js.html +4 -4
  132. package/coverage/lcov-report/db/utils.js.html +123 -87
  133. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  134. package/coverage/lcov-report/events/index.html +1 -1
  135. package/coverage/lcov-report/events/index.js.html +8 -8
  136. package/coverage/lcov-report/events/utils.js.html +18 -18
  137. package/coverage/lcov-report/index.html +91 -76
  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 +5 -5
  141. package/coverage/lcov-report/middleware/authorized.js.html +29 -29
  142. package/coverage/lcov-report/middleware/builder.js.html +16 -16
  143. package/coverage/lcov-report/middleware/currentapp.js.html +44 -44
  144. package/coverage/lcov-report/middleware/index.html +1 -1
  145. package/coverage/lcov-report/middleware/joi-validator.js.html +14 -14
  146. package/coverage/lcov-report/middleware/resourceId.js.html +29 -29
  147. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  148. package/coverage/lcov-report/middleware/usageQuota.js.html +17 -17
  149. package/coverage/lcov-report/middleware/utils.js.html +4 -4
  150. package/coverage/lcov-report/threads/automation.js.html +1 -1
  151. package/coverage/lcov-report/threads/index.html +19 -19
  152. package/coverage/lcov-report/threads/index.js.html +10 -10
  153. package/coverage/lcov-report/threads/query.js.html +123 -39
  154. package/coverage/lcov-report/threads/utils.js.html +14 -14
  155. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  156. package/coverage/lcov-report/utilities/budibaseDir.js.html +7 -7
  157. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  158. package/coverage/lcov-report/utilities/csvParser.js.html +6 -6
  159. package/coverage/lcov-report/utilities/global.js.html +28 -28
  160. package/coverage/lcov-report/utilities/index.html +18 -18
  161. package/coverage/lcov-report/utilities/index.js.html +24 -24
  162. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +9 -9
  163. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  164. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  165. package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
  166. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  167. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +60 -60
  168. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +13 -13
  169. package/coverage/lcov-report/utilities/scriptRunner.js.html +5 -5
  170. package/coverage/lcov-report/utilities/security.js.html +8 -8
  171. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  172. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  173. package/coverage/lcov-report/utilities/usageQuota/index.js.html +12 -12
  174. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +8 -8
  175. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  176. package/coverage/lcov-report/utilities/users.js.html +5 -5
  177. package/coverage/lcov-report/utilities/workerRequests.js.html +200 -53
  178. package/coverage/lcov.info +3555 -3411
  179. package/dist/api/controllers/application.js +1 -0
  180. package/dist/api/controllers/public/applications.js +94 -0
  181. package/dist/api/controllers/public/mapping/applications.js +29 -0
  182. package/dist/api/controllers/public/mapping/index.js +11 -0
  183. package/dist/api/controllers/public/mapping/queries.js +36 -0
  184. package/dist/api/controllers/public/mapping/rows.js +24 -0
  185. package/dist/api/controllers/public/mapping/tables.js +23 -0
  186. package/dist/api/controllers/public/mapping/types.js +2 -0
  187. package/dist/api/controllers/public/mapping/users.js +29 -0
  188. package/dist/api/controllers/public/queries.js +38 -0
  189. package/dist/api/controllers/public/rows.js +97 -0
  190. package/dist/api/controllers/public/tables.js +75 -0
  191. package/dist/api/controllers/public/users.js +95 -0
  192. package/dist/api/controllers/public/utils.js +49 -0
  193. package/dist/api/controllers/row/external.js +18 -0
  194. package/dist/api/controllers/row/index.js +11 -0
  195. package/dist/api/controllers/row/internal.js +15 -1
  196. package/dist/api/controllers/table/external.js +8 -2
  197. package/dist/api/controllers/table/index.js +2 -1
  198. package/dist/api/controllers/webhook.js +3 -5
  199. package/dist/api/index.js +3 -1
  200. package/dist/api/routes/automation.js +3 -31
  201. package/dist/api/routes/datasource.js +3 -50
  202. package/dist/api/routes/index.js +2 -0
  203. package/dist/api/routes/permission.js +4 -14
  204. package/dist/api/routes/public/applications.js +141 -0
  205. package/dist/api/routes/public/index.js +101 -0
  206. package/dist/api/routes/public/middleware/mapper.js +94 -0
  207. package/dist/api/routes/public/queries.js +77 -0
  208. package/dist/api/routes/public/rows.js +229 -0
  209. package/dist/api/routes/public/tables.js +154 -0
  210. package/dist/api/routes/public/users.js +137 -0
  211. package/dist/api/routes/public/utils/Endpoint.js +36 -0
  212. package/dist/api/routes/role.js +3 -19
  213. package/dist/api/routes/row.js +18 -5
  214. package/dist/api/routes/screen.js +2 -23
  215. package/dist/api/routes/table.js +3 -17
  216. package/dist/api/routes/tests/utilities/index.js +23 -0
  217. package/dist/api/routes/utils/validators.js +200 -0
  218. package/dist/api/routes/webhook.js +2 -17
  219. package/dist/automations/steps/filter.js +2 -2
  220. package/dist/automations/steps/queryRows.js +1 -1
  221. package/dist/automations/utils.js +2 -2
  222. package/dist/constants/index.js +3 -0
  223. package/dist/db/utils.js +11 -0
  224. package/dist/definitions/openapi.js +6 -0
  225. package/dist/environment.js +1 -0
  226. package/dist/integrations/base/sql.js +16 -1
  227. package/dist/integrations/base/sqlTable.js +21 -9
  228. package/dist/integrations/googlesheets.js +3 -0
  229. package/dist/integrations/microsoftSqlServer.js +60 -43
  230. package/dist/integrations/mysql.js +3 -0
  231. package/dist/integrations/oracle.js +14 -19
  232. package/dist/integrations/postgres.js +34 -28
  233. package/dist/integrations/utils.js +32 -15
  234. package/dist/package.json +11 -7
  235. package/dist/tests/utilities/TestConfiguration.js +25 -8
  236. package/dist/threads/query.js +33 -8
  237. package/dist/tsconfig.tsbuildinfo +1 -1
  238. package/dist/utilities/workerRequests.js +50 -15
  239. package/package.json +12 -8
  240. package/scripts/integrations/mssql/data/setup.sql +18 -1
  241. package/scripts/integrations/oracle/oracle.md +2 -2
  242. package/scripts/integrations/postgres/init.sql +11 -3
  243. package/scripts/likeCypress.ts +9 -6
  244. package/specs/generate.js +94 -0
  245. package/specs/openapi.json +2232 -0
  246. package/specs/openapi.yaml +1538 -0
  247. package/specs/parameters.js +59 -0
  248. package/specs/resources/application.js +101 -0
  249. package/specs/resources/index.js +24 -0
  250. package/specs/resources/misc.js +12 -0
  251. package/specs/resources/query.js +189 -0
  252. package/specs/resources/row.js +125 -0
  253. package/specs/resources/table.js +191 -0
  254. package/specs/resources/user.js +126 -0
  255. package/specs/resources/utils/Resource.js +26 -0
  256. package/specs/resources/utils/index.js +11 -0
  257. package/specs/security.js +7 -0
  258. package/src/api/controllers/application.js +1 -0
  259. package/src/api/controllers/public/applications.ts +74 -0
  260. package/src/api/controllers/public/mapping/applications.ts +32 -0
  261. package/src/api/controllers/public/mapping/index.ts +13 -0
  262. package/src/api/controllers/public/mapping/queries.ts +39 -0
  263. package/src/api/controllers/public/mapping/rows.ts +31 -0
  264. package/src/api/controllers/public/mapping/tables.ts +26 -0
  265. package/src/api/controllers/public/mapping/types.ts +13 -0
  266. package/src/api/controllers/public/mapping/users.ts +32 -0
  267. package/src/api/controllers/public/queries.ts +20 -0
  268. package/src/api/controllers/public/rows.ts +77 -0
  269. package/src/api/controllers/public/tables.ts +56 -0
  270. package/src/api/controllers/public/users.ts +82 -0
  271. package/src/api/controllers/public/utils.ts +38 -0
  272. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  273. package/src/api/controllers/row/external.js +21 -0
  274. package/src/api/controllers/row/index.js +9 -0
  275. package/src/api/controllers/row/internal.js +20 -0
  276. package/src/api/controllers/table/external.js +16 -2
  277. package/src/api/controllers/table/index.js +2 -1
  278. package/src/api/controllers/webhook.js +3 -6
  279. package/src/api/index.js +4 -1
  280. package/src/api/routes/automation.js +3 -33
  281. package/src/api/routes/datasource.js +6 -52
  282. package/src/api/routes/index.js +2 -0
  283. package/src/api/routes/permission.js +4 -18
  284. package/src/api/routes/public/applications.ts +156 -0
  285. package/src/api/routes/public/index.ts +118 -0
  286. package/src/api/routes/public/middleware/mapper.ts +81 -0
  287. package/src/api/routes/public/queries.ts +81 -0
  288. package/src/api/routes/public/rows.ts +242 -0
  289. package/src/api/routes/public/tables.ts +169 -0
  290. package/src/api/routes/public/tests/compare.spec.js +184 -0
  291. package/src/api/routes/public/users.ts +144 -0
  292. package/src/api/routes/public/utils/Endpoint.ts +51 -0
  293. package/src/api/routes/role.js +3 -24
  294. package/src/api/routes/row.js +24 -2
  295. package/src/api/routes/screen.js +2 -29
  296. package/src/api/routes/table.js +4 -19
  297. package/src/api/routes/tests/utilities/index.js +24 -0
  298. package/src/api/routes/utils/validators.js +219 -0
  299. package/src/api/routes/webhook.js +2 -18
  300. package/src/automations/steps/filter.js +3 -2
  301. package/src/automations/steps/queryRows.js +1 -1
  302. package/src/automations/utils.js +2 -2
  303. package/src/constants/index.js +4 -0
  304. package/src/db/utils.js +12 -0
  305. package/src/definitions/common.ts +4 -0
  306. package/src/definitions/datasource.ts +7 -0
  307. package/src/definitions/openapi.ts +943 -0
  308. package/src/environment.js +1 -0
  309. package/src/integrations/base/datasourcePlus.ts +3 -0
  310. package/src/integrations/base/sql.ts +16 -1
  311. package/src/integrations/base/sqlTable.ts +35 -13
  312. package/src/integrations/googlesheets.ts +5 -2
  313. package/src/integrations/microsoftSqlServer.ts +86 -61
  314. package/src/integrations/mysql.ts +4 -0
  315. package/src/integrations/oracle.ts +27 -35
  316. package/src/integrations/postgres.ts +33 -26
  317. package/src/integrations/utils.ts +43 -15
  318. package/src/tests/utilities/TestConfiguration.js +23 -2
  319. package/src/threads/query.js +37 -9
  320. package/src/utilities/workerRequests.js +65 -16
  321. package/builder/assets/index.22a39cc9.js +0 -1352
  322. package/scripts/proxy/generateProxyConfig.js +0 -70
@@ -103,30 +103,11 @@ module PostgresModule {
103
103
  },
104
104
  }
105
105
 
106
- async function internalQuery(client: any, query: SqlQuery) {
107
- // need to handle a specific issue with json data types in postgres,
108
- // new lines inside the JSON data will break it
109
- if (query && query.sql) {
110
- const matches = query.sql.match(JSON_REGEX)
111
- if (matches && matches.length > 0) {
112
- for (let match of matches) {
113
- const escaped = escapeDangerousCharacters(match)
114
- query.sql = query.sql.replace(match, escaped)
115
- }
116
- }
117
- }
118
- try {
119
- return await client.query(query.sql, query.bindings || [])
120
- } catch (err) {
121
- // @ts-ignore
122
- throw new Error(err)
123
- }
124
- }
125
-
126
106
  class PostgresIntegration extends Sql implements DatasourcePlus {
127
107
  static pool: any
128
108
  private readonly client: any
129
109
  private readonly config: PostgresConfig
110
+ private index: number = 1
130
111
  public tables: Record<string, Table> = {}
131
112
  public schemaErrors: Record<string, string> = {}
132
113
 
@@ -163,6 +144,32 @@ module PostgresModule {
163
144
  this.setSchema()
164
145
  }
165
146
 
147
+ getBindingIdentifier(): string {
148
+ return `$${this.index++}`
149
+ }
150
+
151
+ async internalQuery(query: SqlQuery) {
152
+ const client = this.client
153
+ this.index = 1
154
+ // need to handle a specific issue with json data types in postgres,
155
+ // new lines inside the JSON data will break it
156
+ if (query && query.sql) {
157
+ const matches = query.sql.match(JSON_REGEX)
158
+ if (matches && matches.length > 0) {
159
+ for (let match of matches) {
160
+ const escaped = escapeDangerousCharacters(match)
161
+ query.sql = query.sql.replace(match, escaped)
162
+ }
163
+ }
164
+ }
165
+ try {
166
+ return await client.query(query.sql, query.bindings || [])
167
+ } catch (err) {
168
+ // @ts-ignore
169
+ throw new Error(err)
170
+ }
171
+ }
172
+
166
173
  setSchema() {
167
174
  if (!this.config.schema) {
168
175
  this.config.schema = "public"
@@ -241,22 +248,22 @@ module PostgresModule {
241
248
  }
242
249
 
243
250
  async create(query: SqlQuery | string) {
244
- const response = await internalQuery(this.client, getSqlQuery(query))
251
+ const response = await this.internalQuery(getSqlQuery(query))
245
252
  return response.rows.length ? response.rows : [{ created: true }]
246
253
  }
247
254
 
248
255
  async read(query: SqlQuery | string) {
249
- const response = await internalQuery(this.client, getSqlQuery(query))
256
+ const response = await this.internalQuery(getSqlQuery(query))
250
257
  return response.rows
251
258
  }
252
259
 
253
260
  async update(query: SqlQuery | string) {
254
- const response = await internalQuery(this.client, getSqlQuery(query))
261
+ const response = await this.internalQuery(getSqlQuery(query))
255
262
  return response.rows.length ? response.rows : [{ updated: true }]
256
263
  }
257
264
 
258
265
  async delete(query: SqlQuery | string) {
259
- const response = await internalQuery(this.client, getSqlQuery(query))
266
+ const response = await this.internalQuery(getSqlQuery(query))
260
267
  return response.rows.length ? response.rows : [{ deleted: true }]
261
268
  }
262
269
 
@@ -266,11 +273,11 @@ module PostgresModule {
266
273
  if (Array.isArray(input)) {
267
274
  const responses = []
268
275
  for (let query of input) {
269
- responses.push(await internalQuery(this.client, query))
276
+ responses.push(await this.internalQuery(query))
270
277
  }
271
278
  return responses
272
279
  } else {
273
- const response = await internalQuery(this.client, input)
280
+ const response = await this.internalQuery(input)
274
281
  return response.rows.length ? response.rows : [{ [operation]: true }]
275
282
  }
276
283
  }
@@ -6,35 +6,63 @@ import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants"
6
6
  const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
7
7
  const ROW_ID_REGEX = /^\[.*]$/g
8
8
 
9
- const SQL_TYPE_MAP = {
10
- text: FieldTypes.LONGFORM,
11
- varchar: FieldTypes.STRING,
9
+ const SQL_NUMBER_TYPE_MAP = {
12
10
  integer: FieldTypes.NUMBER,
11
+ int: FieldTypes.NUMBER,
13
12
  bigint: FieldTypes.NUMBER,
14
13
  decimal: FieldTypes.NUMBER,
15
14
  smallint: FieldTypes.NUMBER,
16
15
  real: FieldTypes.NUMBER,
17
- "double precision": FieldTypes.NUMBER,
18
- timestamp: FieldTypes.DATETIME,
19
- time: FieldTypes.DATETIME,
20
- boolean: FieldTypes.BOOLEAN,
21
- json: FieldTypes.JSON,
22
- date: FieldTypes.DATETIME,
23
- blob: FieldTypes.LONGFORM,
24
- enum: FieldTypes.STRING,
25
16
  float: FieldTypes.NUMBER,
26
- int: FieldTypes.NUMBER,
27
17
  numeric: FieldTypes.NUMBER,
28
18
  mediumint: FieldTypes.NUMBER,
29
19
  dec: FieldTypes.NUMBER,
30
20
  double: FieldTypes.NUMBER,
31
21
  fixed: FieldTypes.NUMBER,
32
- datetime: FieldTypes.DATETIME,
33
- tinyint: FieldTypes.BOOLEAN,
34
- long: FieldTypes.LONGFORM,
22
+ "double precision": FieldTypes.NUMBER,
35
23
  number: FieldTypes.NUMBER,
36
24
  binary_float: FieldTypes.NUMBER,
37
25
  binary_double: FieldTypes.NUMBER,
26
+ money: FieldTypes.NUMBER,
27
+ smallmoney: FieldTypes.NUMBER,
28
+ }
29
+
30
+ const SQL_DATE_TYPE_MAP = {
31
+ timestamp: FieldTypes.DATETIME,
32
+ time: FieldTypes.DATETIME,
33
+ datetime: FieldTypes.DATETIME,
34
+ smalldatetime: FieldTypes.DATETIME,
35
+ date: FieldTypes.DATETIME,
36
+ }
37
+
38
+ const SQL_STRING_TYPE_MAP = {
39
+ varchar: FieldTypes.STRING,
40
+ char: FieldTypes.STRING,
41
+ nchar: FieldTypes.STRING,
42
+ nvarchar: FieldTypes.STRING,
43
+ ntext: FieldTypes.STRING,
44
+ enum: FieldTypes.STRING,
45
+ blob: FieldTypes.LONGFORM,
46
+ long: FieldTypes.LONGFORM,
47
+ text: FieldTypes.LONGFORM,
48
+ }
49
+
50
+ const SQL_BOOLEAN_TYPE_MAP = {
51
+ boolean: FieldTypes.BOOLEAN,
52
+ bit: FieldTypes.BOOLEAN,
53
+ tinyint: FieldTypes.BOOLEAN,
54
+ }
55
+
56
+ const SQL_MISC_TYPE_MAP = {
57
+ json: FieldTypes.JSON,
58
+ }
59
+
60
+ const SQL_TYPE_MAP = {
61
+ ...SQL_NUMBER_TYPE_MAP,
62
+ ...SQL_DATE_TYPE_MAP,
63
+ ...SQL_STRING_TYPE_MAP,
64
+ ...SQL_BOOLEAN_TYPE_MAP,
65
+ ...SQL_MISC_TYPE_MAP,
38
66
  }
39
67
 
40
68
  export enum SqlClients {
@@ -25,6 +25,8 @@ const { createASession } = require("@budibase/backend-core/sessions")
25
25
  const { user: userCache } = require("@budibase/backend-core/cache")
26
26
  const newid = require("../../db/newid")
27
27
  const context = require("@budibase/backend-core/context")
28
+ const { generateDevInfoID, SEPARATOR } = require("@budibase/backend-core/db")
29
+ const { encrypt } = require("@budibase/backend-core/encryption")
28
30
 
29
31
  const GLOBAL_USER_ID = "us_uuid1"
30
32
  const EMAIL = "babs@babs.com"
@@ -47,6 +49,10 @@ class TestConfiguration {
47
49
  return this.request
48
50
  }
49
51
 
52
+ getApp() {
53
+ return this.app
54
+ }
55
+
50
56
  getAppId() {
51
57
  return this.appId
52
58
  }
@@ -83,6 +89,20 @@ class TestConfiguration {
83
89
  }
84
90
  }
85
91
 
92
+ async generateApiKey(userId = GLOBAL_USER_ID) {
93
+ const db = getGlobalDB(TENANT_ID)
94
+ const id = generateDevInfoID(userId)
95
+ let devInfo
96
+ try {
97
+ devInfo = await db.get(id)
98
+ } catch (err) {
99
+ devInfo = { _id: id, userId }
100
+ }
101
+ devInfo.apiKey = encrypt(`${TENANT_ID}${SEPARATOR}${newid()}`)
102
+ await db.put(devInfo)
103
+ return devInfo.apiKey
104
+ }
105
+
86
106
  async globalUser({
87
107
  id = GLOBAL_USER_ID,
88
108
  builder = true,
@@ -135,7 +155,7 @@ class TestConfiguration {
135
155
  cleanup(this.allApps.map(app => app.appId))
136
156
  }
137
157
 
138
- defaultHeaders() {
158
+ defaultHeaders(extras = {}) {
139
159
  const auth = {
140
160
  userId: GLOBAL_USER_ID,
141
161
  sessionId: "sessionid",
@@ -154,6 +174,7 @@ class TestConfiguration {
154
174
  `${Cookies.CurrentApp}=${appToken}`,
155
175
  ],
156
176
  [Headers.CSRF_TOKEN]: CSRF_TOKEN,
177
+ ...extras,
157
178
  }
158
179
  if (this.appId) {
159
180
  headers[Headers.APP_ID] = this.appId
@@ -226,7 +247,7 @@ class TestConfiguration {
226
247
 
227
248
  async getTable(tableId = null) {
228
249
  tableId = tableId || this.table._id
229
- return this._req(null, { id: tableId }, controllers.table.find)
250
+ return this._req(null, { tableId }, controllers.table.find)
230
251
  }
231
252
 
232
253
  async createLinkedTable(relationshipType = null, links = ["link"]) {
@@ -2,8 +2,12 @@ const threadUtils = require("./utils")
2
2
  threadUtils.threadSetup()
3
3
  const ScriptRunner = require("../utilities/scriptRunner")
4
4
  const { integrations } = require("../integrations")
5
- const { processStringSync } = require("@budibase/string-templates")
5
+ const {
6
+ processStringSync,
7
+ findHBSBlocks,
8
+ } = require("@budibase/string-templates")
6
9
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
10
+ const { isSQL } = require("../integrations/utils")
7
11
 
8
12
  class QueryRunner {
9
13
  constructor(input, flags = { noRecursiveQuery: false }) {
@@ -23,23 +27,47 @@ class QueryRunner {
23
27
  this.hasRerun = false
24
28
  }
25
29
 
30
+ interpolateSQL(fields, parameters, integration) {
31
+ let sql = fields.sql
32
+ if (!sql) {
33
+ return fields
34
+ }
35
+ const bindings = findHBSBlocks(sql)
36
+ let variables = []
37
+ for (let binding of bindings) {
38
+ let variable = integration.getBindingIdentifier()
39
+ variables.push(binding)
40
+ sql = sql.replace(binding, variable)
41
+ }
42
+ // replicate the knex structure
43
+ fields.sql = sql
44
+ fields.bindings = this.enrichQueryFields(variables, parameters)
45
+ return fields
46
+ }
47
+
26
48
  async execute() {
27
49
  let { datasource, fields, queryVerb, transformer } = this
50
+ const Integration = integrations[datasource.source]
51
+ if (!Integration) {
52
+ throw "Integration type does not exist."
53
+ }
54
+ const integration = new Integration(datasource.config)
55
+
28
56
  // pre-query, make sure datasource variables are added to parameters
29
57
  const parameters = await this.addDatasourceVariables()
30
- let query = this.enrichQueryFields(fields, parameters)
58
+ let query
59
+ // handle SQL injections by interpolating the variables
60
+ if (isSQL(datasource)) {
61
+ query = this.interpolateSQL(fields, parameters, integration)
62
+ } else {
63
+ query = this.enrichQueryFields(fields, parameters)
64
+ }
31
65
 
32
66
  // Add pagination values for REST queries
33
67
  if (this.pagination) {
34
68
  query.paginationValues = this.pagination
35
69
  }
36
70
 
37
- const Integration = integrations[datasource.source]
38
- if (!Integration) {
39
- throw "Integration type does not exist."
40
- }
41
- const integration = new Integration(datasource.config)
42
-
43
71
  let output = threadUtils.formatResponse(await integration[queryVerb](query))
44
72
  let rows = output,
45
73
  info = undefined,
@@ -179,7 +207,7 @@ class QueryRunner {
179
207
  }
180
208
 
181
209
  enrichQueryFields(fields, parameters = {}) {
182
- const enrichedQuery = {}
210
+ const enrichedQuery = Array.isArray(fields) ? [] : {}
183
211
 
184
212
  // enrich the fields with dynamic parameters
185
213
  for (let key of Object.keys(fields)) {
@@ -26,11 +26,31 @@ function request(ctx, request) {
26
26
  delete request.body
27
27
  }
28
28
  if (ctx && ctx.headers) {
29
- request.headers.cookie = ctx.headers.cookie
29
+ request.headers = ctx.headers
30
30
  }
31
31
  return request
32
32
  }
33
33
 
34
+ async function checkResponse(response, errorMsg, { ctx } = {}) {
35
+ if (response.status !== 200) {
36
+ let error
37
+ try {
38
+ error = await response.json()
39
+ } catch (err) {
40
+ error = await response.text()
41
+ }
42
+ const msg = `Unable to ${errorMsg} - ${
43
+ error.message ? error.message : error
44
+ }`
45
+ if (ctx) {
46
+ ctx.throw(400, msg)
47
+ } else {
48
+ throw msg
49
+ }
50
+ }
51
+ return response.json()
52
+ }
53
+
34
54
  exports.request = request
35
55
 
36
56
  // have to pass in the tenant ID as this could be coming from an automation
@@ -50,25 +70,17 @@ exports.sendSmtpEmail = async (to, from, subject, contents, automation) => {
50
70
  },
51
71
  })
52
72
  )
53
-
54
- if (response.status !== 200) {
55
- const error = await response.text()
56
- throw `Unable to send email - ${error}`
57
- }
58
- return response.json()
73
+ return checkResponse(response, "send email")
59
74
  }
60
75
 
61
76
  exports.getGlobalSelf = async (ctx, appId = null) => {
62
- const endpoint = `/api/global/users/self`
77
+ const endpoint = `/api/global/self`
63
78
  const response = await fetch(
64
79
  checkSlashesInUrl(env.WORKER_URL + endpoint),
65
80
  // we don't want to use API key when getting self
66
81
  request(ctx, { method: "GET" })
67
82
  )
68
- if (response.status !== 200) {
69
- ctx.throw(400, "Unable to get self globally.")
70
- }
71
- let json = await response.json()
83
+ let json = await checkResponse(response, "get self globally", { ctx })
72
84
  if (appId) {
73
85
  json = updateAppRole(json)
74
86
  }
@@ -83,8 +95,45 @@ exports.removeAppFromUserRoles = async (ctx, appId) => {
83
95
  method: "DELETE",
84
96
  })
85
97
  )
86
- if (response.status !== 200) {
87
- throw "Unable to remove app role"
88
- }
89
- return response.json()
98
+ return checkResponse(response, "remove app role")
99
+ }
100
+
101
+ exports.allGlobalUsers = async ctx => {
102
+ const response = await fetch(
103
+ checkSlashesInUrl(env.WORKER_URL + "/api/global/users"),
104
+ // we don't want to use API key when getting self
105
+ request(ctx, { method: "GET" })
106
+ )
107
+ return checkResponse(response, "get users", { ctx })
108
+ }
109
+
110
+ exports.saveGlobalUser = async ctx => {
111
+ const response = await fetch(
112
+ checkSlashesInUrl(env.WORKER_URL + "/api/global/users"),
113
+ // we don't want to use API key when getting self
114
+ request(ctx, { method: "POST", body: ctx.request.body })
115
+ )
116
+ return checkResponse(response, "save user", { ctx })
117
+ }
118
+
119
+ exports.deleteGlobalUser = async ctx => {
120
+ const response = await fetch(
121
+ checkSlashesInUrl(
122
+ env.WORKER_URL + `/api/global/users/${ctx.params.userId}`
123
+ ),
124
+ // we don't want to use API key when getting self
125
+ request(ctx, { method: "DELETE" })
126
+ )
127
+ return checkResponse(response, "delete user", { ctx, body: ctx.request.body })
128
+ }
129
+
130
+ exports.readGlobalUser = async ctx => {
131
+ const response = await fetch(
132
+ checkSlashesInUrl(
133
+ env.WORKER_URL + `/api/global/users/${ctx.params.userId}`
134
+ ),
135
+ // we don't want to use API key when getting self
136
+ request(ctx, { method: "GET" })
137
+ )
138
+ return checkResponse(response, "get user", { ctx })
90
139
  }