@budibase/server 1.3.12-alpha.3 → 1.3.14

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 (274) hide show
  1. package/__mocks__/mongodb.ts +1 -1
  2. package/builder/assets/{index.7886c551.css → index.a70e216a.css} +2 -2
  3. package/builder/assets/index.d8428ac8.js +876 -0
  4. package/builder/assets/vendor.5e1fe644.css +1 -0
  5. package/builder/assets/vendor.67dbd8fa.js +248 -0
  6. package/builder/index.html +4 -2
  7. package/coverage/clover.xml +335 -355
  8. package/coverage/coverage-final.json +22 -22
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/backup.js.html +8 -5
  13. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/component.js.html +13 -82
  15. package/coverage/lcov-report/api/controllers/datasource.js.html +20 -20
  16. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/index.html +32 -32
  18. package/coverage/lcov-report/api/controllers/integration.js.html +6 -6
  19. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  24. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/screen.js.html +12 -204
  34. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  47. package/coverage/lcov-report/api/index.html +1 -1
  48. package/coverage/lcov-report/api/index.js.html +12 -12
  49. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/index.html +1 -1
  60. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  74. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  77. package/coverage/lcov-report/automations/actions.js.html +1 -1
  78. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  79. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  80. package/coverage/lcov-report/automations/index.html +24 -24
  81. package/coverage/lcov-report/automations/index.js.html +18 -9
  82. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/index.html +1 -1
  89. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggers.js.html +126 -24
  108. package/coverage/lcov-report/constants/index.html +1 -1
  109. package/coverage/lcov-report/constants/index.js.html +1 -1
  110. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  111. package/coverage/lcov-report/constants/screens.js.html +1 -1
  112. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  113. package/coverage/lcov-report/db/index.html +18 -18
  114. package/coverage/lcov-report/db/index.js.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  116. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  117. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  118. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  119. package/coverage/lcov-report/db/newid.js.html +2 -2
  120. package/coverage/lcov-report/db/utils.js.html +20 -56
  121. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  122. package/coverage/lcov-report/events/index.html +1 -1
  123. package/coverage/lcov-report/events/index.js.html +1 -1
  124. package/coverage/lcov-report/events/utils.js.html +1 -1
  125. package/coverage/lcov-report/index.html +48 -48
  126. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  127. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  128. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  129. package/coverage/lcov-report/middleware/builder.js.html +12 -12
  130. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  131. package/coverage/lcov-report/middleware/index.html +1 -1
  132. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  133. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  134. package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
  135. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  136. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  137. package/coverage/lcov-report/utilities/budibaseDir.js.html +3 -3
  138. package/coverage/lcov-report/utilities/centralPath.js.html +4 -4
  139. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  140. package/coverage/lcov-report/utilities/global.js.html +16 -16
  141. package/coverage/lcov-report/utilities/index.html +19 -19
  142. package/coverage/lcov-report/utilities/index.js.html +66 -42
  143. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  144. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  145. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  146. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  147. package/coverage/lcov-report/utilities/rowProcessor/index.html +5 -5
  148. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  149. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +4 -4
  150. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  151. package/coverage/lcov-report/utilities/security.js.html +2 -2
  152. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  153. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  154. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +6 -3
  155. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  156. package/coverage/lcov-report/utilities/users.js.html +1 -1
  157. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  158. package/coverage/lcov.info +604 -652
  159. package/dist/api/controllers/application.js +5 -10
  160. package/dist/api/controllers/backup.js +2 -1
  161. package/dist/api/controllers/component.js +1 -18
  162. package/dist/api/controllers/datasource.js +4 -4
  163. package/dist/api/controllers/deploy/index.js +17 -2
  164. package/dist/api/controllers/integration.js +4 -4
  165. package/dist/api/controllers/row/ExternalRequest.js +1 -1
  166. package/dist/api/controllers/screen.js +2 -51
  167. package/dist/api/controllers/static/index.js +0 -1
  168. package/dist/api/controllers/static/templates/BudibaseApp.svelte +0 -10
  169. package/dist/api/controllers/static/templates/preview.hbs +1 -3
  170. package/dist/api/routes/index.js +0 -2
  171. package/dist/api/routes/static.js +1 -1
  172. package/dist/app.js +0 -9
  173. package/dist/automations/index.js +10 -5
  174. package/dist/automations/triggers.js +39 -5
  175. package/dist/automations/utils.js +16 -7
  176. package/dist/db/utils.js +1 -10
  177. package/dist/environment.js +0 -1
  178. package/dist/integrations/airtable.js +129 -126
  179. package/dist/integrations/arangodb.js +89 -86
  180. package/dist/integrations/base/query.js +2 -2
  181. package/dist/integrations/couchdb.js +83 -80
  182. package/dist/integrations/dynamodb.js +164 -161
  183. package/dist/integrations/elasticsearch.js +138 -135
  184. package/dist/integrations/firebase.js +157 -154
  185. package/dist/integrations/googlesheets.js +327 -323
  186. package/dist/integrations/index.js +51 -93
  187. package/dist/integrations/microsoftSqlServer.js +243 -240
  188. package/dist/integrations/mongodb.js +242 -239
  189. package/dist/integrations/mysql.js +219 -215
  190. package/dist/integrations/oracle.js +322 -318
  191. package/dist/integrations/postgres.js +265 -262
  192. package/dist/integrations/redis.js +139 -134
  193. package/dist/integrations/rest.js +296 -278
  194. package/dist/integrations/s3.js +64 -61
  195. package/dist/integrations/snowflake.js +86 -83
  196. package/dist/package.json +6 -8
  197. package/dist/threads/automation.js +6 -0
  198. package/dist/threads/query.js +2 -2
  199. package/dist/tsconfig.build.tsbuildinfo +1 -1
  200. package/dist/utilities/fileSystem/index.js +6 -71
  201. package/dist/utilities/index.js +8 -0
  202. package/dist/utilities/rowProcessor/utils.js +1 -1
  203. package/dist/utilities/usageQuota/rows.js +2 -1
  204. package/package.json +7 -9
  205. package/scripts/dev/manage.js +0 -1
  206. package/src/api/controllers/application.ts +2 -6
  207. package/src/api/controllers/backup.js +2 -1
  208. package/src/api/controllers/component.js +2 -25
  209. package/src/api/controllers/datasource.js +4 -4
  210. package/src/api/controllers/deploy/index.ts +17 -4
  211. package/src/api/controllers/integration.js +4 -4
  212. package/src/api/controllers/row/ExternalRequest.ts +1 -1
  213. package/src/api/controllers/screen.js +1 -65
  214. package/src/api/controllers/static/index.ts +0 -1
  215. package/src/api/controllers/static/templates/BudibaseApp.svelte +0 -10
  216. package/src/api/controllers/static/templates/preview.hbs +1 -3
  217. package/src/api/routes/index.ts +0 -2
  218. package/src/api/routes/static.ts +1 -1
  219. package/src/api/routes/tests/query.spec.js +28 -11
  220. package/src/api/routes/tests/static.spec.js +2 -2
  221. package/src/app.ts +0 -12
  222. package/src/automations/index.js +6 -3
  223. package/src/automations/triggers.js +44 -10
  224. package/src/automations/utils.ts +21 -9
  225. package/src/db/utils.js +0 -12
  226. package/src/definitions/datasource.ts +1 -0
  227. package/src/environment.js +0 -1
  228. package/src/integrations/airtable.ts +118 -116
  229. package/src/integrations/arangodb.ts +89 -87
  230. package/src/integrations/base/query.ts +2 -2
  231. package/src/integrations/couchdb.ts +89 -83
  232. package/src/integrations/dynamodb.ts +175 -173
  233. package/src/integrations/elasticsearch.ts +122 -120
  234. package/src/integrations/firebase.ts +159 -157
  235. package/src/integrations/googlesheets.ts +338 -328
  236. package/src/integrations/index.ts +21 -59
  237. package/src/integrations/microsoftSqlServer.ts +251 -249
  238. package/src/integrations/mongodb.ts +258 -261
  239. package/src/integrations/mysql.ts +234 -229
  240. package/src/integrations/oracle.ts +380 -373
  241. package/src/integrations/postgres.ts +268 -264
  242. package/src/integrations/redis.ts +132 -128
  243. package/src/integrations/rest.ts +330 -312
  244. package/src/integrations/s3.ts +71 -68
  245. package/src/integrations/snowflake.ts +82 -80
  246. package/src/integrations/tests/{airtable.spec.ts → airtable.spec.js} +18 -21
  247. package/src/integrations/tests/{arangodb.spec.ts → arangodb.spec.js} +9 -12
  248. package/src/integrations/tests/{couchdb.spec.ts → couchdb.spec.js} +27 -33
  249. package/src/integrations/tests/{dynamodb.spec.ts → dynamodb.spec.js} +41 -45
  250. package/src/integrations/tests/{elasticsearch.spec.ts → elasticsearch.spec.js} +21 -22
  251. package/src/integrations/tests/{firebase.spec.ts → firebase.spec.js} +28 -33
  252. package/src/integrations/tests/{microsoftSqlServer.spec.ts → microsoftSqlServer.spec.js} +11 -12
  253. package/src/integrations/tests/{mongo.spec.ts → mongo.spec.js} +35 -46
  254. package/src/integrations/tests/{mysql.spec.ts → mysql.spec.js} +15 -17
  255. package/src/integrations/tests/{oracle.spec.ts → oracle.spec.js} +17 -19
  256. package/src/integrations/tests/{postgres.spec.ts → postgres.spec.js} +17 -19
  257. package/src/integrations/tests/{redis.spec.ts → redis.spec.js} +18 -27
  258. package/src/integrations/tests/{rest.spec.ts → rest.spec.js} +49 -22
  259. package/src/integrations/tests/{s3.spec.ts → s3.spec.js} +8 -10
  260. package/src/integrations/tests/{sql.spec.ts → sql.spec.js} +177 -228
  261. package/src/module.d.ts +0 -1
  262. package/src/threads/automation.ts +6 -0
  263. package/src/threads/query.ts +2 -2
  264. package/src/utilities/fileSystem/index.js +6 -75
  265. package/src/utilities/index.js +8 -0
  266. package/src/utilities/rowProcessor/utils.js +1 -1
  267. package/src/utilities/usageQuota/rows.js +2 -1
  268. package/builder/assets/index.e759397f.js +0 -994
  269. package/dist/api/controllers/plugin.js +0 -119
  270. package/dist/api/routes/plugin.js +0 -38
  271. package/dist/watch.js +0 -77
  272. package/src/api/controllers/plugin.ts +0 -110
  273. package/src/api/routes/plugin.ts +0 -13
  274. package/src/watch.ts +0 -38
@@ -14,11 +14,7 @@ import {
14
14
  BearerAuthConfig,
15
15
  } from "../definitions/datasource"
16
16
  import { get } from "lodash"
17
- const fetch = require("node-fetch")
18
- const { formatBytes } = require("../utilities")
19
- const { performance } = require("perf_hooks")
20
- const FormData = require("form-data")
21
- const { URLSearchParams } = require("url")
17
+ import qs from "querystring"
22
18
 
23
19
  const BodyTypes = {
24
20
  NONE: "none",
@@ -55,353 +51,375 @@ const coreFields = {
55
51
  },
56
52
  }
57
53
 
58
- const { parseStringPromise: xmlParser, Builder: XmlBuilder } = require("xml2js")
59
-
60
- const SCHEMA: Integration = {
61
- docs: "https://github.com/node-fetch/node-fetch",
62
- description:
63
- "With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",
64
- friendlyName: "REST API",
65
- type: "API",
66
- datasource: {
67
- url: {
68
- type: DatasourceFieldType.STRING,
69
- default: "",
70
- required: false,
71
- deprecated: true,
72
- },
73
- defaultHeaders: {
74
- type: DatasourceFieldType.OBJECT,
75
- required: false,
76
- default: {},
77
- },
78
- },
79
- query: {
80
- create: {
81
- readable: true,
82
- displayName: "POST",
83
- type: QueryType.FIELDS,
84
- fields: coreFields,
85
- },
86
- read: {
87
- displayName: "GET",
88
- readable: true,
89
- type: QueryType.FIELDS,
90
- fields: coreFields,
91
- },
92
- update: {
93
- displayName: "PUT",
94
- readable: true,
95
- type: QueryType.FIELDS,
96
- fields: coreFields,
97
- },
98
- patch: {
99
- displayName: "PATCH",
100
- readable: true,
101
- type: QueryType.FIELDS,
102
- fields: coreFields,
54
+ module RestModule {
55
+ const fetch = require("node-fetch")
56
+ const { formatBytes } = require("../utilities")
57
+ const { performance } = require("perf_hooks")
58
+ const FormData = require("form-data")
59
+ const { URLSearchParams } = require("url")
60
+ const {
61
+ parseStringPromise: xmlParser,
62
+ Builder: XmlBuilder,
63
+ } = require("xml2js")
64
+
65
+ const SCHEMA: Integration = {
66
+ docs: "https://github.com/node-fetch/node-fetch",
67
+ description:
68
+ "With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",
69
+ friendlyName: "REST API",
70
+ type: "API",
71
+ datasource: {
72
+ url: {
73
+ type: DatasourceFieldType.STRING,
74
+ default: "",
75
+ required: false,
76
+ deprecated: true,
77
+ },
78
+ defaultHeaders: {
79
+ type: DatasourceFieldType.OBJECT,
80
+ required: false,
81
+ default: {},
82
+ },
83
+ legacyHttpParser: {
84
+ display: "Legacy HTTP Support",
85
+ type: DatasourceFieldType.BOOLEAN,
86
+ required: false,
87
+ default: false,
88
+ },
103
89
  },
104
- delete: {
105
- displayName: "DELETE",
106
- type: QueryType.FIELDS,
107
- fields: coreFields,
90
+ query: {
91
+ create: {
92
+ readable: true,
93
+ displayName: "POST",
94
+ type: QueryType.FIELDS,
95
+ fields: coreFields,
96
+ },
97
+ read: {
98
+ displayName: "GET",
99
+ readable: true,
100
+ type: QueryType.FIELDS,
101
+ fields: coreFields,
102
+ },
103
+ update: {
104
+ displayName: "PUT",
105
+ readable: true,
106
+ type: QueryType.FIELDS,
107
+ fields: coreFields,
108
+ },
109
+ patch: {
110
+ displayName: "PATCH",
111
+ readable: true,
112
+ type: QueryType.FIELDS,
113
+ fields: coreFields,
114
+ },
115
+ delete: {
116
+ displayName: "DELETE",
117
+ type: QueryType.FIELDS,
118
+ fields: coreFields,
119
+ },
108
120
  },
109
- },
110
- }
111
-
112
- class RestIntegration implements IntegrationBase {
113
- private config: RestConfig
114
- private headers: {
115
- [key: string]: string
116
- } = {}
117
- private startTimeMs: number = performance.now()
118
-
119
- constructor(config: RestConfig) {
120
- this.config = config
121
121
  }
122
122
 
123
- async parseResponse(response: any, pagination: PaginationConfig | null) {
124
- let data, raw, headers
125
- const contentType = response.headers.get("content-type") || ""
126
- try {
127
- if (contentType.includes("application/json")) {
128
- data = await response.json()
129
- raw = JSON.stringify(data)
130
- } else if (
131
- contentType.includes("text/xml") ||
132
- contentType.includes("application/xml")
133
- ) {
134
- const rawXml = await response.text()
135
- data =
136
- (await xmlParser(rawXml, {
137
- explicitArray: false,
138
- trim: true,
139
- explicitRoot: false,
140
- })) || {}
141
- // there is only one structure, its an array, return the array so it appears as rows
142
- const keys = Object.keys(data)
143
- if (keys.length === 1 && Array.isArray(data[keys[0]])) {
144
- data = data[keys[0]]
145
- }
146
- raw = rawXml
147
- } else {
148
- data = await response.text()
149
- raw = data
150
- }
151
- } catch (err) {
152
- throw "Failed to parse response body."
153
- }
154
- const size = formatBytes(
155
- response.headers.get("content-length") || Buffer.byteLength(raw, "utf8")
156
- )
157
- const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
158
- headers = response.headers.raw()
159
- for (let [key, value] of Object.entries(headers)) {
160
- headers[key] = Array.isArray(value) ? value[0] : value
161
- }
162
-
163
- // Check if a pagination cursor exists in the response
164
- let nextCursor = null
165
- if (pagination?.responseParam) {
166
- nextCursor = get(data, pagination.responseParam)
167
- }
123
+ class RestIntegration implements IntegrationBase {
124
+ private config: RestConfig
125
+ private headers: {
126
+ [key: string]: string
127
+ } = {}
128
+ private startTimeMs: number = performance.now()
168
129
 
169
- return {
170
- data,
171
- info: {
172
- code: response.status,
173
- size,
174
- time,
175
- },
176
- extra: {
177
- raw,
178
- headers,
179
- },
180
- pagination: {
181
- cursor: nextCursor,
182
- },
130
+ constructor(config: RestConfig) {
131
+ this.config = config
183
132
  }
184
- }
185
133
 
186
- getUrl(
187
- path: string,
188
- queryString: string,
189
- pagination: PaginationConfig | null,
190
- paginationValues: PaginationValues | null
191
- ): string {
192
- // Add pagination params to query string if required
193
- if (pagination?.location === "query" && paginationValues) {
194
- const { pageParam, sizeParam } = pagination
195
- const params = new URLSearchParams()
196
-
197
- // Append page number or cursor param if configured
198
- if (pageParam && paginationValues.page != null) {
199
- params.append(pageParam, paginationValues.page)
134
+ async parseResponse(response: any, pagination: PaginationConfig | null) {
135
+ let data, raw, headers
136
+ const contentType = response.headers.get("content-type") || ""
137
+ try {
138
+ if (contentType.includes("application/json")) {
139
+ data = await response.json()
140
+ raw = JSON.stringify(data)
141
+ } else if (
142
+ contentType.includes("text/xml") ||
143
+ contentType.includes("application/xml")
144
+ ) {
145
+ const rawXml = await response.text()
146
+ data =
147
+ (await xmlParser(rawXml, {
148
+ explicitArray: false,
149
+ trim: true,
150
+ explicitRoot: false,
151
+ })) || {}
152
+ // there is only one structure, its an array, return the array so it appears as rows
153
+ const keys = Object.keys(data)
154
+ if (keys.length === 1 && Array.isArray(data[keys[0]])) {
155
+ data = data[keys[0]]
156
+ }
157
+ raw = rawXml
158
+ } else {
159
+ data = await response.text()
160
+ raw = data
161
+ }
162
+ } catch (err) {
163
+ throw "Failed to parse response body."
164
+ }
165
+ const size = formatBytes(
166
+ response.headers.get("content-length") || Buffer.byteLength(raw, "utf8")
167
+ )
168
+ const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
169
+ headers = response.headers.raw()
170
+ for (let [key, value] of Object.entries(headers)) {
171
+ headers[key] = Array.isArray(value) ? value[0] : value
200
172
  }
201
173
 
202
- // Append page size param if configured
203
- if (sizeParam && paginationValues.limit != null) {
204
- params.append(sizeParam, paginationValues.limit)
174
+ // Check if a pagination cursor exists in the response
175
+ let nextCursor = null
176
+ if (pagination?.responseParam) {
177
+ nextCursor = get(data, pagination.responseParam)
205
178
  }
206
179
 
207
- // Prepend query string with pagination params
208
- let paginationString = params.toString()
209
- if (paginationString) {
210
- queryString = `${paginationString}&${queryString}`
180
+ return {
181
+ data,
182
+ info: {
183
+ code: response.status,
184
+ size,
185
+ time,
186
+ },
187
+ extra: {
188
+ raw,
189
+ headers,
190
+ },
191
+ pagination: {
192
+ cursor: nextCursor,
193
+ },
211
194
  }
212
195
  }
213
196
 
214
- const main = `${path}?${queryString}`
215
- let complete = main
216
- if (this.config.url && !main.startsWith("http")) {
217
- complete = !this.config.url ? main : `${this.config.url}/${main}`
218
- }
219
- if (!complete.startsWith("http")) {
220
- complete = `http://${complete}`
221
- }
222
- return complete
223
- }
197
+ getUrl(
198
+ path: string,
199
+ queryString: string,
200
+ pagination: PaginationConfig | null,
201
+ paginationValues: PaginationValues | null
202
+ ): string {
203
+ // Add pagination params to query string if required
204
+ if (pagination?.location === "query" && paginationValues) {
205
+ const { pageParam, sizeParam } = pagination
206
+ const params = new URLSearchParams()
224
207
 
225
- addBody(
226
- bodyType: string,
227
- body: string | any,
228
- input: any,
229
- pagination: PaginationConfig | null,
230
- paginationValues: PaginationValues | null
231
- ) {
232
- if (!input.headers) {
233
- input.headers = {}
234
- }
235
- if (bodyType === BodyTypes.NONE) {
236
- return input
237
- }
238
- let error,
239
- object: any = {},
240
- string = ""
241
- try {
242
- if (body) {
243
- string = typeof body !== "string" ? JSON.stringify(body) : body
244
- object = typeof body === "object" ? body : JSON.parse(body)
245
- }
246
- } catch (err) {
247
- error = err
248
- }
208
+ // Append page number or cursor param if configured
209
+ if (pageParam && paginationValues.page != null) {
210
+ params.append(pageParam, paginationValues.page)
211
+ }
249
212
 
250
- // Util to add pagination values to a certain body type
251
- const addPaginationToBody = (insertFn: Function) => {
252
- if (pagination?.location === "body") {
253
- if (pagination?.pageParam && paginationValues?.page != null) {
254
- insertFn(pagination.pageParam, paginationValues.page)
213
+ // Append page size param if configured
214
+ if (sizeParam && paginationValues.limit != null) {
215
+ params.append(sizeParam, paginationValues.limit)
255
216
  }
256
- if (pagination?.sizeParam && paginationValues?.limit != null) {
257
- insertFn(pagination.sizeParam, paginationValues.limit)
217
+
218
+ // Prepend query string with pagination params
219
+ let paginationString = params.toString()
220
+ if (paginationString) {
221
+ queryString = `${paginationString}&${queryString}`
258
222
  }
259
223
  }
224
+
225
+ // make sure the query string is fully encoded
226
+ const main = `${path}?${qs.encode(qs.decode(queryString))}`
227
+ let complete = main
228
+ if (this.config.url && !main.startsWith("http")) {
229
+ complete = !this.config.url ? main : `${this.config.url}/${main}`
230
+ }
231
+ if (!complete.startsWith("http")) {
232
+ complete = `http://${complete}`
233
+ }
234
+ return complete
260
235
  }
261
236
 
262
- switch (bodyType) {
263
- case BodyTypes.TEXT:
264
- // content type defaults to plaintext
265
- input.body = string
266
- break
267
- case BodyTypes.ENCODED:
268
- const params = new URLSearchParams()
269
- for (let [key, value] of Object.entries(object)) {
270
- params.append(key, value)
271
- }
272
- addPaginationToBody((key: string, value: any) => {
273
- params.append(key, value)
274
- })
275
- input.body = params
276
- break
277
- case BodyTypes.FORM_DATA:
278
- const form = new FormData()
279
- for (let [key, value] of Object.entries(object)) {
280
- form.append(key, value)
281
- }
282
- addPaginationToBody((key: string, value: any) => {
283
- form.append(key, value)
284
- })
285
- input.body = form
286
- break
287
- case BodyTypes.XML:
288
- if (object != null && Object.keys(object).length) {
289
- string = new XmlBuilder().buildObject(object)
237
+ addBody(
238
+ bodyType: string,
239
+ body: string | any,
240
+ input: any,
241
+ pagination: PaginationConfig | null,
242
+ paginationValues: PaginationValues | null
243
+ ) {
244
+ if (!input.headers) {
245
+ input.headers = {}
246
+ }
247
+ if (bodyType === BodyTypes.NONE) {
248
+ return input
249
+ }
250
+ let error,
251
+ object: any = {},
252
+ string = ""
253
+ try {
254
+ if (body) {
255
+ string = typeof body !== "string" ? JSON.stringify(body) : body
256
+ object = typeof body === "object" ? body : JSON.parse(body)
290
257
  }
291
- input.body = string
292
- input.headers["Content-Type"] = "application/xml"
293
- break
294
- case BodyTypes.JSON:
295
- // if JSON error, throw it
296
- if (error) {
297
- throw "Invalid JSON for request body"
258
+ } catch (err) {
259
+ error = err
260
+ }
261
+
262
+ // Util to add pagination values to a certain body type
263
+ const addPaginationToBody = (insertFn: Function) => {
264
+ if (pagination?.location === "body") {
265
+ if (pagination?.pageParam && paginationValues?.page != null) {
266
+ insertFn(pagination.pageParam, paginationValues.page)
267
+ }
268
+ if (pagination?.sizeParam && paginationValues?.limit != null) {
269
+ insertFn(pagination.sizeParam, paginationValues.limit)
270
+ }
298
271
  }
299
- addPaginationToBody((key: string, value: any) => {
300
- object[key] = value
301
- })
302
- input.body = JSON.stringify(object)
303
- input.headers["Content-Type"] = "application/json"
304
- break
272
+ }
273
+
274
+ switch (bodyType) {
275
+ case BodyTypes.TEXT:
276
+ // content type defaults to plaintext
277
+ input.body = string
278
+ break
279
+ case BodyTypes.ENCODED:
280
+ const params = new URLSearchParams()
281
+ for (let [key, value] of Object.entries(object)) {
282
+ params.append(key, value)
283
+ }
284
+ addPaginationToBody((key: string, value: any) => {
285
+ params.append(key, value)
286
+ })
287
+ input.body = params
288
+ break
289
+ case BodyTypes.FORM_DATA:
290
+ const form = new FormData()
291
+ for (let [key, value] of Object.entries(object)) {
292
+ form.append(key, value)
293
+ }
294
+ addPaginationToBody((key: string, value: any) => {
295
+ form.append(key, value)
296
+ })
297
+ input.body = form
298
+ break
299
+ case BodyTypes.XML:
300
+ if (object != null && Object.keys(object).length) {
301
+ string = new XmlBuilder().buildObject(object)
302
+ }
303
+ input.body = string
304
+ input.headers["Content-Type"] = "application/xml"
305
+ break
306
+ case BodyTypes.JSON:
307
+ // if JSON error, throw it
308
+ if (error) {
309
+ throw "Invalid JSON for request body"
310
+ }
311
+ addPaginationToBody((key: string, value: any) => {
312
+ object[key] = value
313
+ })
314
+ input.body = JSON.stringify(object)
315
+ input.headers["Content-Type"] = "application/json"
316
+ break
317
+ }
318
+ return input
305
319
  }
306
- return input
307
- }
308
320
 
309
- getAuthHeaders(authConfigId: string): { [key: string]: any } {
310
- let headers: any = {}
311
-
312
- if (this.config.authConfigs && authConfigId) {
313
- const authConfig = this.config.authConfigs.filter(
314
- c => c._id === authConfigId
315
- )[0]
316
- // check the config still exists before proceeding
317
- // if not - do nothing
318
- if (authConfig) {
319
- let config
320
- switch (authConfig.type) {
321
- case AuthType.BASIC:
322
- config = authConfig.config as BasicAuthConfig
323
- headers.Authorization = `Basic ${Buffer.from(
324
- `${config.username}:${config.password}`
325
- ).toString("base64")}`
326
- break
327
- case AuthType.BEARER:
328
- config = authConfig.config as BearerAuthConfig
329
- headers.Authorization = `Bearer ${config.token}`
330
- break
321
+ getAuthHeaders(authConfigId: string): { [key: string]: any } {
322
+ let headers: any = {}
323
+
324
+ if (this.config.authConfigs && authConfigId) {
325
+ const authConfig = this.config.authConfigs.filter(
326
+ c => c._id === authConfigId
327
+ )[0]
328
+ // check the config still exists before proceeding
329
+ // if not - do nothing
330
+ if (authConfig) {
331
+ let config
332
+ switch (authConfig.type) {
333
+ case AuthType.BASIC:
334
+ config = authConfig.config as BasicAuthConfig
335
+ headers.Authorization = `Basic ${Buffer.from(
336
+ `${config.username}:${config.password}`
337
+ ).toString("base64")}`
338
+ break
339
+ case AuthType.BEARER:
340
+ config = authConfig.config as BearerAuthConfig
341
+ headers.Authorization = `Bearer ${config.token}`
342
+ break
343
+ }
331
344
  }
332
345
  }
346
+
347
+ return headers
333
348
  }
334
349
 
335
- return headers
336
- }
350
+ async _req(query: RestQuery) {
351
+ const {
352
+ path = "",
353
+ queryString = "",
354
+ headers = {},
355
+ method = "GET",
356
+ disabledHeaders,
357
+ bodyType,
358
+ requestBody,
359
+ authConfigId,
360
+ pagination,
361
+ paginationValues,
362
+ } = query
363
+ const authHeaders = this.getAuthHeaders(authConfigId)
337
364
 
338
- async _req(query: RestQuery) {
339
- const {
340
- path = "",
341
- queryString = "",
342
- headers = {},
343
- method = "GET",
344
- disabledHeaders,
345
- bodyType,
346
- requestBody,
347
- authConfigId,
348
- pagination,
349
- paginationValues,
350
- } = query
351
- const authHeaders = this.getAuthHeaders(authConfigId)
352
-
353
- this.headers = {
354
- ...this.config.defaultHeaders,
355
- ...headers,
356
- ...authHeaders,
357
- }
365
+ this.headers = {
366
+ ...this.config.defaultHeaders,
367
+ ...headers,
368
+ ...authHeaders,
369
+ }
358
370
 
359
- if (disabledHeaders) {
360
- for (let headerKey of Object.keys(this.headers)) {
361
- if (disabledHeaders[headerKey]) {
362
- delete this.headers[headerKey]
371
+ if (disabledHeaders) {
372
+ for (let headerKey of Object.keys(this.headers)) {
373
+ if (disabledHeaders[headerKey]) {
374
+ delete this.headers[headerKey]
375
+ }
363
376
  }
364
377
  }
378
+
379
+ let input: any = { method, headers: this.headers }
380
+ input = this.addBody(
381
+ bodyType,
382
+ requestBody,
383
+ input,
384
+ pagination,
385
+ paginationValues
386
+ )
387
+
388
+ if (this.config.legacyHttpParser) {
389
+ // https://github.com/nodejs/node/issues/43798
390
+ input.extraHttpOptions = { insecureHTTPParser: true }
391
+ }
392
+
393
+ this.startTimeMs = performance.now()
394
+ const url = this.getUrl(path, queryString, pagination, paginationValues)
395
+ const response = await fetch(url, input)
396
+ return await this.parseResponse(response, pagination)
365
397
  }
366
398
 
367
- let input: any = { method, headers: this.headers }
368
- input = this.addBody(
369
- bodyType,
370
- requestBody,
371
- input,
372
- pagination,
373
- paginationValues
374
- )
375
-
376
- this.startTimeMs = performance.now()
377
- const url = this.getUrl(path, queryString, pagination, paginationValues)
378
- const response = await fetch(url, input)
379
- return await this.parseResponse(response, pagination)
380
- }
399
+ async create(opts: RestQuery) {
400
+ return this._req({ ...opts, method: "POST" })
401
+ }
381
402
 
382
- async create(opts: RestQuery) {
383
- return this._req({ ...opts, method: "POST" })
384
- }
403
+ async read(opts: RestQuery) {
404
+ return this._req({ ...opts, method: "GET" })
405
+ }
385
406
 
386
- async read(opts: RestQuery) {
387
- return this._req({ ...opts, method: "GET" })
388
- }
407
+ async update(opts: RestQuery) {
408
+ return this._req({ ...opts, method: "PUT" })
409
+ }
389
410
 
390
- async update(opts: RestQuery) {
391
- return this._req({ ...opts, method: "PUT" })
392
- }
411
+ async patch(opts: RestQuery) {
412
+ return this._req({ ...opts, method: "PATCH" })
413
+ }
393
414
 
394
- async patch(opts: RestQuery) {
395
- return this._req({ ...opts, method: "PATCH" })
415
+ async delete(opts: RestQuery) {
416
+ return this._req({ ...opts, method: "DELETE" })
417
+ }
396
418
  }
397
419
 
398
- async delete(opts: RestQuery) {
399
- return this._req({ ...opts, method: "DELETE" })
420
+ module.exports = {
421
+ schema: SCHEMA,
422
+ integration: RestIntegration,
423
+ AuthType,
400
424
  }
401
425
  }
402
-
403
- export default {
404
- schema: SCHEMA,
405
- integration: RestIntegration,
406
- AuthType,
407
- }