@budibase/server 1.0.27-alpha.0 → 1.0.30

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 (234) hide show
  1. package/__mocks__/node-fetch.ts +0 -3
  2. package/builder/assets/{index.e2f56628.js → index.2ccab04a.js} +204 -208
  3. package/builder/assets/{index.4a13c4cb.css → index.4fb3f887.css} +1 -1
  4. package/builder/assets/{vendor.f9faf6ab.js → vendor.470042a4.js} +88 -88
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +512 -589
  7. package/coverage/coverage-final.json +19 -20
  8. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/application.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/automation.js.html +10 -22
  13. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/datasource.js.html +14 -14
  17. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/index.html +43 -28
  20. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/{query/index.js.html → query.js.html} +27 -159
  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/index.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/internalSearch.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 +1 -1
  34. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/user.js.html +9 -108
  42. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  47. package/coverage/lcov-report/api/controllers/webhook.js.html +6 -18
  48. package/coverage/lcov-report/api/index.html +1 -1
  49. package/coverage/lcov-report/api/index.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/index.html +9 -9
  63. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/query.js.html +98 -11
  69. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/user.js.html +2 -32
  78. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  80. package/coverage/lcov-report/automations/actions.js.html +1 -1
  81. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  82. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  83. package/coverage/lcov-report/automations/index.html +20 -20
  84. package/coverage/lcov-report/automations/index.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  87. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/index.html +1 -1
  94. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +8 -5
  96. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  99. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  111. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  112. package/coverage/lcov-report/automations/utils.js.html +11 -44
  113. package/coverage/lcov-report/constants/index.html +1 -1
  114. package/coverage/lcov-report/constants/index.js.html +22 -22
  115. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  116. package/coverage/lcov-report/constants/screens.js.html +1 -1
  117. package/coverage/lcov-report/db/client.js.html +18 -18
  118. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  119. package/coverage/lcov-report/db/index.html +15 -15
  120. package/coverage/lcov-report/db/index.js.html +3 -3
  121. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  122. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  123. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  124. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  125. package/coverage/lcov-report/db/newid.js.html +4 -4
  126. package/coverage/lcov-report/db/utils.js.html +64 -91
  127. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  128. package/coverage/lcov-report/events/index.html +1 -1
  129. package/coverage/lcov-report/events/index.js.html +1 -1
  130. package/coverage/lcov-report/events/utils.js.html +1 -1
  131. package/coverage/lcov-report/index.html +60 -75
  132. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  133. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  134. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  135. package/coverage/lcov-report/middleware/authorized.js.html +2 -2
  136. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  137. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  138. package/coverage/lcov-report/middleware/index.html +1 -1
  139. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  140. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  141. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  142. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  143. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  144. package/coverage/lcov-report/threads/automation.js.html +1 -1
  145. package/coverage/lcov-report/threads/index.html +19 -19
  146. package/coverage/lcov-report/threads/index.js.html +1 -1
  147. package/coverage/lcov-report/threads/query.js.html +12 -63
  148. package/coverage/lcov-report/threads/utils.js.html +1 -1
  149. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  150. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  151. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  152. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  153. package/coverage/lcov-report/utilities/global.js.html +1 -1
  154. package/coverage/lcov-report/utilities/index.html +19 -19
  155. package/coverage/lcov-report/utilities/index.js.html +33 -66
  156. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  157. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  158. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  159. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  160. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  161. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  162. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  163. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  164. package/coverage/lcov-report/utilities/security.js.html +2 -2
  165. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  166. package/coverage/lcov-report/utilities/users.js.html +1 -1
  167. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  168. package/coverage/lcov.info +851 -969
  169. package/dist/api/controllers/automation.js +5 -7
  170. package/dist/api/controllers/{query/index.js → query.js} +6 -42
  171. package/dist/api/controllers/user.js +1 -37
  172. package/dist/api/controllers/webhook.js +0 -4
  173. package/dist/api/routes/query.js +32 -2
  174. package/dist/api/routes/user.js +1 -3
  175. package/dist/automations/steps/outgoingWebhook.js +3 -2
  176. package/dist/automations/utils.js +0 -10
  177. package/dist/db/utils.js +0 -8
  178. package/dist/definitions/datasource.js +1 -6
  179. package/dist/integrations/rest.js +117 -207
  180. package/dist/package.json +4 -10
  181. package/dist/threads/query.js +2 -14
  182. package/dist/tsconfig.tsbuildinfo +1 -1
  183. package/dist/utilities/index.js +0 -10
  184. package/package.json +5 -11
  185. package/src/api/controllers/automation.js +4 -8
  186. package/src/api/controllers/{query/index.js → query.js} +6 -50
  187. package/src/api/controllers/user.js +0 -33
  188. package/src/api/controllers/webhook.js +0 -4
  189. package/src/api/routes/query.js +34 -5
  190. package/src/api/routes/user.js +0 -10
  191. package/src/automations/steps/outgoingWebhook.js +3 -2
  192. package/src/automations/utils.js +0 -11
  193. package/src/db/utils.js +0 -9
  194. package/src/definitions/common.ts +16 -2
  195. package/src/definitions/datasource.ts +1 -73
  196. package/src/integrations/base/IntegrationBase.ts +4 -4
  197. package/src/integrations/oracle.ts +1 -1
  198. package/src/integrations/rest.ts +137 -227
  199. package/src/integrations/tests/rest.spec.js +19 -167
  200. package/src/threads/query.js +2 -19
  201. package/src/utilities/index.js +0 -11
  202. package/builder/assets/bb-spaceship.8f6e81e1.svg +0 -227
  203. package/coverage/lcov-report/api/controllers/query/index.html +0 -126
  204. package/coverage/lcov-report/api/controllers/query/validation.js.html +0 -203
  205. package/dist/api/controllers/query/import/index.js +0 -79
  206. package/dist/api/controllers/query/import/sources/base/index.js +0 -63
  207. package/dist/api/controllers/query/import/sources/base/openapi.js +0 -42
  208. package/dist/api/controllers/query/import/sources/curl.js +0 -90
  209. package/dist/api/controllers/query/import/sources/openapi2.js +0 -139
  210. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +0 -253
  211. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +0 -1054
  212. package/dist/api/controllers/query/validation.js +0 -37
  213. package/src/api/controllers/query/import/index.ts +0 -85
  214. package/src/api/controllers/query/import/sources/base/index.ts +0 -85
  215. package/src/api/controllers/query/import/sources/base/openapi.ts +0 -24
  216. package/src/api/controllers/query/import/sources/curl.ts +0 -94
  217. package/src/api/controllers/query/import/sources/openapi2.ts +0 -159
  218. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +0 -104
  219. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +0 -1
  220. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +0 -2
  221. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +0 -1
  222. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +0 -3
  223. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +0 -2
  224. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +0 -1
  225. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +0 -2
  226. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +0 -2
  227. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +0 -1
  228. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +0 -253
  229. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +0 -160
  230. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +0 -1054
  231. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +0 -711
  232. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +0 -239
  233. package/src/api/controllers/query/import/tests/index.spec.js +0 -115
  234. package/src/api/controllers/query/validation.js +0 -41
@@ -2,65 +2,29 @@ import {
2
2
  Integration,
3
3
  DatasourceFieldTypes,
4
4
  QueryTypes,
5
- RestConfig,
6
- RestQueryFields as RestQuery,
7
- AuthType,
8
- BasicAuthConfig,
9
- BearerAuthConfig,
10
5
  } from "../definitions/datasource"
11
6
  import { IntegrationBase } from "./base/IntegrationBase"
12
7
 
13
- const BodyTypes = {
14
- NONE: "none",
15
- FORM_DATA: "form",
16
- XML: "xml",
17
- ENCODED: "encoded",
18
- JSON: "json",
19
- TEXT: "text",
20
- }
21
-
22
- const coreFields = {
23
- path: {
24
- type: DatasourceFieldTypes.STRING,
25
- display: "URL",
26
- },
27
- queryString: {
28
- type: DatasourceFieldTypes.STRING,
29
- },
30
- headers: {
31
- type: DatasourceFieldTypes.OBJECT,
32
- },
33
- enabledHeaders: {
34
- type: DatasourceFieldTypes.OBJECT,
35
- },
36
- requestBody: {
37
- type: DatasourceFieldTypes.JSON,
38
- },
39
- bodyType: {
40
- type: DatasourceFieldTypes.STRING,
41
- enum: Object.values(BodyTypes),
42
- },
43
- }
44
-
45
8
  module RestModule {
46
9
  const fetch = require("node-fetch")
47
- const { formatBytes } = require("../utilities")
48
- const { performance } = require("perf_hooks")
49
- const FormData = require("form-data")
50
- const { URLSearchParams } = require("url")
51
- const { parseStringPromise: xmlParser, Builder: XmlBuilder } = require("xml2js")
10
+
11
+ interface RestConfig {
12
+ url: string
13
+ defaultHeaders: {
14
+ [key: string]: any
15
+ }
16
+ }
52
17
 
53
18
  const SCHEMA: Integration = {
54
19
  docs: "https://github.com/node-fetch/node-fetch",
55
20
  description:
56
- "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.",
21
+ "Representational state transfer (REST) is a de-facto standard for a software architecture for interactive applications that typically use multiple Web services. ",
57
22
  friendlyName: "REST API",
58
23
  datasource: {
59
24
  url: {
60
25
  type: DatasourceFieldTypes.STRING,
61
- default: "",
62
- required: false,
63
- deprecated: true,
26
+ default: "localhost",
27
+ required: true,
64
28
  },
65
29
  defaultHeaders: {
66
30
  type: DatasourceFieldTypes.OBJECT,
@@ -73,30 +37,97 @@ module RestModule {
73
37
  readable: true,
74
38
  displayName: "POST",
75
39
  type: QueryTypes.FIELDS,
76
- fields: coreFields,
40
+ urlDisplay: true,
41
+ fields: {
42
+ path: {
43
+ type: DatasourceFieldTypes.STRING,
44
+ },
45
+ queryString: {
46
+ type: DatasourceFieldTypes.STRING,
47
+ },
48
+ headers: {
49
+ type: DatasourceFieldTypes.OBJECT,
50
+ },
51
+ requestBody: {
52
+ type: DatasourceFieldTypes.JSON,
53
+ },
54
+ },
77
55
  },
78
56
  read: {
79
57
  displayName: "GET",
80
58
  readable: true,
81
59
  type: QueryTypes.FIELDS,
82
- fields: coreFields,
60
+ urlDisplay: true,
61
+ fields: {
62
+ path: {
63
+ type: DatasourceFieldTypes.STRING,
64
+ },
65
+ queryString: {
66
+ type: DatasourceFieldTypes.STRING,
67
+ },
68
+ headers: {
69
+ type: DatasourceFieldTypes.OBJECT,
70
+ },
71
+ },
83
72
  },
84
73
  update: {
85
74
  displayName: "PUT",
86
75
  readable: true,
87
76
  type: QueryTypes.FIELDS,
88
- fields: coreFields,
77
+ urlDisplay: true,
78
+ fields: {
79
+ path: {
80
+ type: DatasourceFieldTypes.STRING,
81
+ },
82
+ queryString: {
83
+ type: DatasourceFieldTypes.STRING,
84
+ },
85
+ headers: {
86
+ type: DatasourceFieldTypes.OBJECT,
87
+ },
88
+ requestBody: {
89
+ type: DatasourceFieldTypes.JSON,
90
+ },
91
+ },
89
92
  },
90
93
  patch: {
91
94
  displayName: "PATCH",
92
95
  readable: true,
93
96
  type: QueryTypes.FIELDS,
94
- fields: coreFields,
97
+ urlDisplay: true,
98
+ fields: {
99
+ path: {
100
+ type: DatasourceFieldTypes.STRING,
101
+ },
102
+ queryString: {
103
+ type: DatasourceFieldTypes.STRING,
104
+ },
105
+ headers: {
106
+ type: DatasourceFieldTypes.OBJECT,
107
+ },
108
+ requestBody: {
109
+ type: DatasourceFieldTypes.JSON,
110
+ },
111
+ },
95
112
  },
96
113
  delete: {
97
114
  displayName: "DELETE",
98
115
  type: QueryTypes.FIELDS,
99
- fields: coreFields,
116
+ urlDisplay: true,
117
+ fields: {
118
+ path: {
119
+ type: DatasourceFieldTypes.STRING,
120
+ },
121
+ queryString: {
122
+ type: DatasourceFieldTypes.STRING,
123
+ },
124
+ headers: {
125
+ type: DatasourceFieldTypes.OBJECT,
126
+ },
127
+ requestBody: {
128
+ type: DatasourceFieldTypes.JSON,
129
+ },
130
+ },
100
131
  },
101
132
  },
102
133
  }
@@ -106,220 +137,99 @@ module RestModule {
106
137
  private headers: {
107
138
  [key: string]: string
108
139
  } = {}
109
- private startTimeMs: number = performance.now()
110
140
 
111
141
  constructor(config: RestConfig) {
112
142
  this.config = config
113
143
  }
114
144
 
115
145
  async parseResponse(response: any) {
116
- let data, raw, headers
117
- const contentType = response.headers.get("content-type") || ""
118
- try {
119
- if (contentType.includes("application/json")) {
120
- data = await response.json()
121
- raw = JSON.stringify(data)
122
- } else if (
123
- contentType.includes("text/xml") ||
124
- contentType.includes("application/xml")
125
- ) {
126
- const rawXml = await response.text()
127
- data =
128
- (await xmlParser(rawXml, {
129
- explicitArray: false,
130
- trim: true,
131
- explicitRoot: false,
132
- })) || {}
133
- // there is only one structure, its an array, return the array so it appears as rows
134
- const keys = Object.keys(data)
135
- if (keys.length === 1 && Array.isArray(data[keys[0]])) {
136
- data = data[keys[0]]
137
- }
138
- raw = rawXml
139
- } else {
140
- data = await response.text()
141
- raw = data
142
- }
143
- } catch (err) {
144
- throw "Failed to parse response body."
145
- }
146
- const size = formatBytes(
147
- response.headers.get("content-length") || Buffer.byteLength(raw, "utf8")
148
- )
149
- const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
150
- headers = response.headers.raw()
151
- for (let [key, value] of Object.entries(headers)) {
152
- headers[key] = Array.isArray(value) ? value[0] : value
153
- }
154
- return {
155
- data,
156
- info: {
157
- code: response.status,
158
- size,
159
- time,
160
- },
161
- extra: {
162
- raw,
163
- headers,
164
- },
146
+ const contentType = response.headers.get("content-type")
147
+ if (contentType && contentType.indexOf("application/json") !== -1) {
148
+ return await response.json()
149
+ } else {
150
+ return await response.text()
165
151
  }
166
152
  }
167
153
 
168
154
  getUrl(path: string, queryString: string): string {
169
- const main = `${path}?${queryString}`
170
- let complete = main
171
- if (this.config.url && !main.startsWith(this.config.url)) {
172
- complete = !this.config.url ? main : `${this.config.url}/${main}`
173
- }
174
- if (!complete.startsWith("http")) {
175
- complete = `http://${complete}`
176
- }
177
- return complete
155
+ return `${this.config.url}/${path}?${queryString}`
178
156
  }
179
157
 
180
- addBody(bodyType: string, body: string | any, input: any) {
181
- let error, object, string
182
- try {
183
- string = typeof body !== "string" ? JSON.stringify(body) : body
184
- object = typeof body === "object" ? body : JSON.parse(body)
185
- } catch (err) {
186
- error = err
187
- }
188
- if (!input.headers) {
189
- input.headers = {}
190
- }
191
- switch (bodyType) {
192
- case BodyTypes.NONE:
193
- break
194
- case BodyTypes.TEXT:
195
- // content type defaults to plaintext
196
- input.body = string
197
- break
198
- case BodyTypes.ENCODED:
199
- const params = new URLSearchParams()
200
- for (let [key, value] of Object.entries(object)) {
201
- params.append(key, value)
202
- }
203
- input.body = params
204
- break
205
- case BodyTypes.FORM_DATA:
206
- const form = new FormData()
207
- for (let [key, value] of Object.entries(object)) {
208
- form.append(key, value)
209
- }
210
- input.body = form
211
- break
212
- case BodyTypes.XML:
213
- if (object != null) {
214
- string = (new XmlBuilder()).buildObject(object)
215
- }
216
- input.body = string
217
- input.headers["Content-Type"] = "application/xml"
218
- break
219
- default:
220
- case BodyTypes.JSON:
221
- // if JSON error, throw it
222
- if (error) {
223
- throw "Invalid JSON for request body"
224
- }
225
- input.body = string
226
- input.headers["Content-Type"] = "application/json"
227
- break
158
+ async create({ path = "", queryString = "", headers = {}, json = {} }) {
159
+ this.headers = {
160
+ ...this.config.defaultHeaders,
161
+ ...headers,
228
162
  }
229
- return input
230
- }
231
163
 
232
- getAuthHeaders(authConfigId: string): { [key: string]: any } {
233
- let headers: any = {}
164
+ const response = await fetch(this.getUrl(path, queryString), {
165
+ method: "POST",
166
+ headers: this.headers,
167
+ body: JSON.stringify(json),
168
+ })
234
169
 
235
- if (this.config.authConfigs && authConfigId) {
236
- const authConfig = this.config.authConfigs.filter(
237
- c => c._id === authConfigId
238
- )[0]
239
- // check the config still exists before proceeding
240
- // if not - do nothing
241
- if (authConfig) {
242
- let config
243
- switch (authConfig.type) {
244
- case AuthType.BASIC:
245
- config = authConfig.config as BasicAuthConfig
246
- headers.Authorization = `Basic ${Buffer.from(
247
- `${config.username}:${config.password}`
248
- ).toString("base64")}`
249
- break
250
- case AuthType.BEARER:
251
- config = authConfig.config as BearerAuthConfig
252
- headers.Authorization = `Bearer ${config.token}`
253
- break
254
- }
255
- }
256
- }
257
-
258
- return headers
170
+ return await this.parseResponse(response)
259
171
  }
260
172
 
261
- async _req(query: RestQuery) {
262
- const {
263
- path = "",
264
- queryString = "",
265
- headers = {},
266
- method = "GET",
267
- disabledHeaders,
268
- bodyType,
269
- requestBody,
270
- authConfigId,
271
- } = query
272
- const authHeaders = this.getAuthHeaders(authConfigId)
273
-
173
+ async read({ path = "", queryString = "", headers = {} }) {
274
174
  this.headers = {
275
175
  ...this.config.defaultHeaders,
276
176
  ...headers,
277
- ...authHeaders,
278
177
  }
279
178
 
280
- if (disabledHeaders) {
281
- for (let headerKey of Object.keys(this.headers)) {
282
- if (disabledHeaders[headerKey]) {
283
- delete this.headers[headerKey]
284
- }
285
- }
286
- }
179
+ const response = await fetch(this.getUrl(path, queryString), {
180
+ headers: this.headers,
181
+ })
182
+
183
+ return await this.parseResponse(response)
184
+ }
287
185
 
288
- let input: any = { method, headers: this.headers }
289
- if (requestBody) {
290
- input = this.addBody(bodyType, requestBody, input)
186
+ async update({ path = "", queryString = "", headers = {}, json = {} }) {
187
+ this.headers = {
188
+ ...this.config.defaultHeaders,
189
+ ...headers,
291
190
  }
292
191
 
293
- this.startTimeMs = performance.now()
294
- const url = this.getUrl(path, queryString)
295
- const response = await fetch(url, input)
192
+ const response = await fetch(this.getUrl(path, queryString), {
193
+ method: "PUT",
194
+ headers: this.headers,
195
+ body: JSON.stringify(json),
196
+ })
197
+
296
198
  return await this.parseResponse(response)
297
199
  }
298
200
 
299
- async create(opts: RestQuery) {
300
- return this._req({ ...opts, method: "POST" })
301
- }
201
+ async patch({ path = "", queryString = "", headers = {}, json = {} }) {
202
+ this.headers = {
203
+ ...this.config.defaultHeaders,
204
+ ...headers,
205
+ }
302
206
 
303
- async read(opts: RestQuery) {
304
- return this._req({ ...opts, method: "GET" })
305
- }
207
+ const response = await fetch(this.getUrl(path, queryString), {
208
+ method: "PATCH",
209
+ headers: this.headers,
210
+ body: JSON.stringify(json),
211
+ })
306
212
 
307
- async update(opts: RestQuery) {
308
- return this._req({ ...opts, method: "PUT" })
213
+ return await this.parseResponse(response)
309
214
  }
310
215
 
311
- async patch(opts: RestQuery) {
312
- return this._req({ ...opts, method: "PATCH" })
313
- }
216
+ async delete({ path = "", queryString = "", headers = {} }) {
217
+ this.headers = {
218
+ ...this.config.defaultHeaders,
219
+ ...headers,
220
+ }
221
+
222
+ const response = await fetch(this.getUrl(path, queryString), {
223
+ method: "DELETE",
224
+ headers: this.headers,
225
+ })
314
226
 
315
- async delete(opts: RestQuery) {
316
- return this._req({ ...opts, method: "DELETE" })
227
+ return await this.parseResponse(response)
317
228
  }
318
229
  }
319
230
 
320
231
  module.exports = {
321
232
  schema: SCHEMA,
322
233
  integration: RestIntegration,
323
- AuthType,
324
234
  }
325
235
  }
@@ -1,9 +1,6 @@
1
1
  jest.mock("node-fetch", () =>
2
2
  jest.fn(() => ({
3
3
  headers: {
4
- raw: () => {
5
- return { "content-type": ["application/json"] }
6
- },
7
4
  get: () => ["application/json"]
8
5
  },
9
6
  json: jest.fn(),
@@ -12,12 +9,6 @@ jest.mock("node-fetch", () =>
12
9
  )
13
10
  const fetch = require("node-fetch")
14
11
  const RestIntegration = require("../rest")
15
- const { AuthType } = require("../rest")
16
-
17
- const HEADERS = {
18
- "Accept": "application/json",
19
- "Content-Type": "application/json"
20
- }
21
12
 
22
13
  class TestConfiguration {
23
14
  constructor(config = {}) {
@@ -33,24 +24,26 @@ describe("REST Integration", () => {
33
24
  config = new TestConfiguration({
34
25
  url: BASE_URL,
35
26
  })
36
- jest.clearAllMocks()
37
27
  })
38
28
 
39
29
  it("calls the create method with the correct params", async () => {
40
30
  const query = {
41
31
  path: "api",
42
32
  queryString: "test=1",
43
- headers: HEADERS,
44
- bodyType: "json",
45
- requestBody: JSON.stringify({
33
+ headers: {
34
+ Accept: "application/json",
35
+ },
36
+ json: {
46
37
  name: "test",
47
- }),
38
+ },
48
39
  }
49
40
  const response = await config.integration.create(query)
50
41
  expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, {
51
42
  method: "POST",
52
43
  body: '{"name":"test"}',
53
- headers: HEADERS,
44
+ headers: {
45
+ Accept: "application/json",
46
+ },
54
47
  })
55
48
  })
56
49
 
@@ -67,7 +60,6 @@ describe("REST Integration", () => {
67
60
  headers: {
68
61
  Accept: "text/html",
69
62
  },
70
- method: "GET",
71
63
  })
72
64
  })
73
65
 
@@ -78,16 +70,17 @@ describe("REST Integration", () => {
78
70
  headers: {
79
71
  Accept: "application/json",
80
72
  },
81
- bodyType: "json",
82
- requestBody: JSON.stringify({
73
+ json: {
83
74
  name: "test",
84
- }),
75
+ },
85
76
  }
86
77
  const response = await config.integration.update(query)
87
78
  expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, {
88
- method: "PUT",
79
+ method: "POST",
89
80
  body: '{"name":"test"}',
90
- headers: HEADERS,
81
+ headers: {
82
+ Accept: "application/json",
83
+ },
91
84
  })
92
85
  })
93
86
 
@@ -98,157 +91,16 @@ describe("REST Integration", () => {
98
91
  headers: {
99
92
  Accept: "application/json",
100
93
  },
101
- bodyType: "json",
102
- requestBody: JSON.stringify({
94
+ json: {
103
95
  name: "test",
104
- }),
96
+ },
105
97
  }
106
98
  const response = await config.integration.delete(query)
107
99
  expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?test=1`, {
108
100
  method: "DELETE",
109
- headers: HEADERS,
110
- body: '{"name":"test"}',
111
- })
112
- })
113
-
114
- describe("request body", () => {
115
- const input = { a: 1, b: 2 }
116
-
117
- it("should allow no body", () => {
118
- const output = config.integration.addBody("none", null, {})
119
- expect(output.body).toBeUndefined()
120
- expect(Object.keys(output.headers).length).toEqual(0)
121
- })
122
-
123
- it("should allow text body", () => {
124
- const output = config.integration.addBody("text", "hello world", {})
125
- expect(output.body).toEqual("hello world")
126
- // gets added by fetch
127
- expect(Object.keys(output.headers).length).toEqual(0)
128
- })
129
-
130
- it("should allow form data", () => {
131
- const FormData = require("form-data")
132
- const output = config.integration.addBody("form", input, {})
133
- expect(output.body instanceof FormData).toEqual(true)
134
- expect(output.body._valueLength).toEqual(2)
135
- // gets added by fetch
136
- expect(Object.keys(output.headers).length).toEqual(0)
137
- })
138
-
139
- it("should allow encoded form data", () => {
140
- const { URLSearchParams } = require("url")
141
- const output = config.integration.addBody("encoded", input, {})
142
- expect(output.body instanceof URLSearchParams).toEqual(true)
143
- expect(output.body.toString()).toEqual("a=1&b=2")
144
- // gets added by fetch
145
- expect(Object.keys(output.headers).length).toEqual(0)
146
- })
147
-
148
- it("should allow JSON", () => {
149
- const output = config.integration.addBody("json", input, {})
150
- expect(output.body).toEqual(JSON.stringify(input))
151
- expect(output.headers["Content-Type"]).toEqual("application/json")
152
- })
153
-
154
- it("should allow XML", () => {
155
- const output = config.integration.addBody("xml", input, {})
156
- expect(output.body.includes("<a>1</a>")).toEqual(true)
157
- expect(output.body.includes("<b>2</b>")).toEqual(true)
158
- expect(output.headers["Content-Type"]).toEqual("application/xml")
159
- })
160
- })
161
-
162
- describe("response", () => {
163
- function buildInput(json, text, header) {
164
- return {
165
- status: 200,
166
- json: json ? async () => json : undefined,
167
- text: text ? async () => text : undefined,
168
- headers: { get: key => key === "content-length" ? 100 : header, raw: () => ({ "content-type": header }) }
169
- }
170
- }
171
-
172
- it("should be able to parse JSON response", async () => {
173
- const input = buildInput({a: 1}, null, "application/json")
174
- const output = await config.integration.parseResponse(input)
175
- expect(output.data).toEqual({a: 1})
176
- expect(output.info.code).toEqual(200)
177
- expect(output.info.size).toEqual("100B")
178
- expect(output.extra.raw).toEqual(JSON.stringify({a: 1}))
179
- expect(output.extra.headers["content-type"]).toEqual("application/json")
180
- })
181
-
182
- it("should be able to parse text response", async () => {
183
- const text = "hello world"
184
- const input = buildInput(null, text, "text/plain")
185
- const output = await config.integration.parseResponse(input)
186
- expect(output.data).toEqual(text)
187
- expect(output.extra.raw).toEqual(text)
188
- expect(output.extra.headers["content-type"]).toEqual("text/plain")
189
- })
190
-
191
- it("should be able to parse XML response", async () => {
192
- const text = "<root><a>1</a><b>2</b></root>"
193
- const input = buildInput(null, text, "application/xml")
194
- const output = await config.integration.parseResponse(input)
195
- expect(output.data).toEqual({a: "1", b: "2"})
196
- expect(output.extra.raw).toEqual(text)
197
- expect(output.extra.headers["content-type"]).toEqual("application/xml")
198
- })
199
- })
200
-
201
- describe("authentication", () => {
202
- const basicAuth = {
203
- _id: "c59c14bd1898a43baa08da68959b24686",
204
- name: "basic-1",
205
- type : AuthType.BASIC,
206
- config : {
207
- username: "user",
208
- password: "password"
209
- }
210
- }
211
-
212
- const bearerAuth = {
213
- _id: "0d91d732f34e4befabeff50b392a8ff3",
214
- name: "bearer-1",
215
- type : AuthType.BEARER,
216
- config : {
217
- "token": "mytoken"
218
- }
219
- }
220
-
221
- beforeEach(() => {
222
- config = new TestConfiguration({
223
- url: BASE_URL,
224
- authConfigs : [basicAuth, bearerAuth]
225
- })
226
- })
227
-
228
- it("adds basic auth", async () => {
229
- const query = {
230
- authConfigId: "c59c14bd1898a43baa08da68959b24686"
231
- }
232
- await config.integration.read(query)
233
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
234
- method: "GET",
235
- headers: {
236
- Authorization: "Basic dXNlcjpwYXNzd29yZA=="
237
- },
238
- })
239
- })
240
-
241
- it("adds bearer auth", async () => {
242
- const query = {
243
- authConfigId: "0d91d732f34e4befabeff50b392a8ff3"
244
- }
245
- await config.integration.read(query)
246
- expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
247
- method: "GET",
248
- headers: {
249
- Authorization: "Bearer mytoken"
250
- },
251
- })
101
+ headers: {
102
+ Accept: "application/json",
103
+ },
252
104
  })
253
105
  })
254
106
  })