@budibase/server 1.0.21 → 1.0.23-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 (238) hide show
  1. package/__mocks__/node-fetch.ts +3 -0
  2. package/builder/assets/bb-spaceship.8f6e81e1.svg +227 -0
  3. package/builder/assets/{index.c2e9e4e2.js → index.26923a83.js} +208 -204
  4. package/builder/assets/{index.4fb3f887.css → index.4a13c4cb.css} +1 -1
  5. package/builder/assets/{vendor.470042a4.js → vendor.f9faf6ab.js} +88 -88
  6. package/builder/index.html +3 -3
  7. package/coverage/clover.xml +654 -567
  8. package/coverage/coverage-final.json +22 -20
  9. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/application.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/automation.js.html +22 -10
  14. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/datasource.js.html +14 -14
  18. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/hosting.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/index.html +28 -43
  21. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/query/index.html +126 -0
  26. package/coverage/lcov-report/api/controllers/{query.js.html → query/index.js.html} +159 -27
  27. package/coverage/lcov-report/api/controllers/query/validation.js.html +203 -0
  28. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  32. package/coverage/lcov-report/api/controllers/row/index.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  40. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/table/internal.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/table/utils.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/user.js.html +108 -9
  45. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  46. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  47. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  48. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  49. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  50. package/coverage/lcov-report/api/controllers/webhook.js.html +18 -6
  51. package/coverage/lcov-report/api/index.html +1 -1
  52. package/coverage/lcov-report/api/index.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/application.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/hosting.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/index.html +9 -9
  66. package/coverage/lcov-report/api/routes/index.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/query.js.html +11 -98
  72. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/row.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  76. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  77. package/coverage/lcov-report/api/routes/static.js.html +1 -1
  78. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  79. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  80. package/coverage/lcov-report/api/routes/user.js.html +32 -2
  81. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  82. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  83. package/coverage/lcov-report/automations/actions.js.html +1 -1
  84. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  85. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  86. package/coverage/lcov-report/automations/index.html +20 -20
  87. package/coverage/lcov-report/automations/index.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/createRow.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/deleteRow.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/index.html +1 -1
  97. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  98. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +5 -8
  99. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  100. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  101. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  102. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  103. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  104. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  105. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  107. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  108. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  109. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  110. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  111. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  112. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  113. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  114. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  115. package/coverage/lcov-report/automations/utils.js.html +44 -11
  116. package/coverage/lcov-report/constants/index.html +1 -1
  117. package/coverage/lcov-report/constants/index.js.html +22 -22
  118. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  119. package/coverage/lcov-report/constants/screens.js.html +1 -1
  120. package/coverage/lcov-report/db/client.js.html +18 -18
  121. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  122. package/coverage/lcov-report/db/index.html +15 -15
  123. package/coverage/lcov-report/db/index.js.html +3 -3
  124. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  125. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  126. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  127. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  128. package/coverage/lcov-report/db/newid.js.html +4 -4
  129. package/coverage/lcov-report/db/utils.js.html +91 -64
  130. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  131. package/coverage/lcov-report/events/index.html +1 -1
  132. package/coverage/lcov-report/events/index.js.html +1 -1
  133. package/coverage/lcov-report/events/utils.js.html +1 -1
  134. package/coverage/lcov-report/index.html +76 -61
  135. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  136. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  137. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  138. package/coverage/lcov-report/middleware/authorized.js.html +2 -2
  139. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  140. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  141. package/coverage/lcov-report/middleware/index.html +1 -1
  142. package/coverage/lcov-report/middleware/joi-validator.js.html +3 -3
  143. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  144. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  145. package/coverage/lcov-report/middleware/usageQuota.js.html +1 -1
  146. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  147. package/coverage/lcov-report/threads/automation.js.html +3 -6
  148. package/coverage/lcov-report/threads/index.html +35 -20
  149. package/coverage/lcov-report/threads/index.js.html +1 -1
  150. package/coverage/lcov-report/threads/query.js.html +62 -17
  151. package/coverage/lcov-report/threads/utils.js.html +119 -0
  152. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  153. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  154. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  155. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  156. package/coverage/lcov-report/utilities/global.js.html +1 -1
  157. package/coverage/lcov-report/utilities/index.html +19 -19
  158. package/coverage/lcov-report/utilities/index.js.html +66 -33
  159. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  160. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  161. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  162. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  163. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  164. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  165. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  166. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  167. package/coverage/lcov-report/utilities/security.js.html +2 -2
  168. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  169. package/coverage/lcov-report/utilities/users.js.html +1 -1
  170. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  171. package/coverage/lcov.info +1058 -918
  172. package/dist/api/controllers/automation.js +7 -5
  173. package/dist/api/controllers/query/import/index.js +79 -0
  174. package/dist/api/controllers/query/import/sources/base/index.js +63 -0
  175. package/dist/api/controllers/query/import/sources/base/openapi.js +42 -0
  176. package/dist/api/controllers/query/import/sources/curl.js +90 -0
  177. package/dist/api/controllers/query/import/sources/openapi2.js +139 -0
  178. package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  179. package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  180. package/dist/api/controllers/{query.js → query/index.js} +42 -6
  181. package/dist/api/controllers/query/validation.js +37 -0
  182. package/dist/api/controllers/user.js +37 -1
  183. package/dist/api/controllers/webhook.js +4 -0
  184. package/dist/api/routes/query.js +2 -32
  185. package/dist/api/routes/user.js +3 -1
  186. package/dist/automations/steps/outgoingWebhook.js +2 -3
  187. package/dist/automations/utils.js +10 -0
  188. package/dist/db/utils.js +8 -0
  189. package/dist/definitions/datasource.js +6 -1
  190. package/dist/integrations/rest.js +207 -117
  191. package/dist/package.json +10 -4
  192. package/dist/threads/automation.js +1 -2
  193. package/dist/threads/query.js +15 -5
  194. package/dist/threads/utils.js +13 -0
  195. package/dist/tsconfig.tsbuildinfo +1 -1
  196. package/dist/utilities/index.js +10 -0
  197. package/package.json +11 -5
  198. package/src/api/controllers/automation.js +8 -4
  199. package/src/api/controllers/query/import/index.ts +85 -0
  200. package/src/api/controllers/query/import/sources/base/index.ts +85 -0
  201. package/src/api/controllers/query/import/sources/base/openapi.ts +24 -0
  202. package/src/api/controllers/query/import/sources/curl.ts +94 -0
  203. package/src/api/controllers/query/import/sources/openapi2.ts +159 -0
  204. package/src/api/controllers/query/import/sources/tests/curl/curl.spec.js +104 -0
  205. package/src/api/controllers/query/import/sources/tests/curl/data/delete.txt +1 -0
  206. package/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt +2 -0
  207. package/src/api/controllers/query/import/sources/tests/curl/data/get.txt +1 -0
  208. package/src/api/controllers/query/import/sources/tests/curl/data/headers.txt +3 -0
  209. package/src/api/controllers/query/import/sources/tests/curl/data/patch.txt +2 -0
  210. package/src/api/controllers/query/import/sources/tests/curl/data/path.txt +1 -0
  211. package/src/api/controllers/query/import/sources/tests/curl/data/post.txt +2 -0
  212. package/src/api/controllers/query/import/sources/tests/curl/data/put.txt +2 -0
  213. package/src/api/controllers/query/import/sources/tests/curl/data/query.txt +1 -0
  214. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +253 -0
  215. package/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml +160 -0
  216. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +1054 -0
  217. package/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml +711 -0
  218. package/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js +239 -0
  219. package/src/api/controllers/query/import/tests/index.spec.js +115 -0
  220. package/src/api/controllers/{query.js → query/index.js} +50 -6
  221. package/src/api/controllers/query/validation.js +41 -0
  222. package/src/api/controllers/user.js +33 -0
  223. package/src/api/controllers/webhook.js +4 -0
  224. package/src/api/routes/query.js +5 -34
  225. package/src/api/routes/user.js +10 -0
  226. package/src/automations/steps/outgoingWebhook.js +2 -3
  227. package/src/automations/utils.js +11 -0
  228. package/src/db/utils.js +9 -0
  229. package/src/definitions/common.ts +2 -16
  230. package/src/definitions/datasource.ts +73 -1
  231. package/src/integrations/base/IntegrationBase.ts +4 -4
  232. package/src/integrations/oracle.ts +1 -1
  233. package/src/integrations/rest.ts +227 -137
  234. package/src/integrations/tests/rest.spec.js +167 -19
  235. package/src/threads/automation.js +1 -2
  236. package/src/threads/query.js +20 -5
  237. package/src/threads/utils.js +13 -0
  238. package/src/utilities/index.js +11 -0
@@ -1,6 +1,6 @@
1
- import { SourceNames } from "./datasource"
1
+ export { Query, Datasource } from "./datasource"
2
2
 
3
- interface Base {
3
+ export interface Base {
4
4
  _id?: string
5
5
  _rev?: string
6
6
  }
@@ -93,17 +93,3 @@ export interface Automation extends Base {
93
93
  trigger?: AutomationStep
94
94
  }
95
95
  }
96
-
97
- export interface Datasource extends Base {
98
- type: string
99
- name: string
100
- source: SourceNames
101
- // the config is defined by the schema
102
- config: {
103
- [key: string]: string | number | boolean
104
- }
105
- plus: boolean
106
- entities?: {
107
- [key: string]: Table
108
- }
109
- }
@@ -1,4 +1,4 @@
1
- import { Row, Table } from "./common"
1
+ import { Row, Table, Base } from "./common"
2
2
 
3
3
  export enum Operation {
4
4
  CREATE = "CREATE",
@@ -181,3 +181,75 @@ export interface SqlQuery {
181
181
  export interface QueryOptions {
182
182
  disableReturning?: boolean
183
183
  }
184
+
185
+ export interface Datasource extends Base {
186
+ type: string
187
+ name: string
188
+ source: SourceNames
189
+ // the config is defined by the schema
190
+ config: {
191
+ [key: string]: string | number | boolean
192
+ }
193
+ plus: boolean
194
+ entities?: {
195
+ [key: string]: Table
196
+ }
197
+ }
198
+
199
+ export enum AuthType {
200
+ BASIC = "basic",
201
+ BEARER = "bearer",
202
+ }
203
+
204
+ interface AuthConfig {
205
+ _id: string
206
+ name: string
207
+ type: AuthType
208
+ config: BasicAuthConfig | BearerAuthConfig
209
+ }
210
+
211
+ export interface BasicAuthConfig {
212
+ username: string
213
+ password: string
214
+ }
215
+
216
+ export interface BearerAuthConfig {
217
+ token: string
218
+ }
219
+
220
+ export interface QueryParameter {
221
+ name: string
222
+ default: string
223
+ }
224
+
225
+ export interface RestQueryFields {
226
+ path: string
227
+ queryString?: string
228
+ headers: { [key: string]: any }
229
+ disabledHeaders: { [key: string]: any }
230
+ requestBody: any
231
+ bodyType: string
232
+ json: object
233
+ method: string
234
+ authConfigId: string
235
+ }
236
+
237
+ export interface RestConfig {
238
+ url: string
239
+ defaultHeaders: {
240
+ [key: string]: any
241
+ }
242
+ authConfigs: AuthConfig[]
243
+ }
244
+
245
+ export interface Query {
246
+ _id?: string
247
+ datasourceId: string
248
+ name: string
249
+ parameters: QueryParameter[]
250
+ fields: RestQueryFields | any
251
+ transformer: string | null
252
+ schema: any
253
+ readable: boolean
254
+ queryVerb: string
255
+ }
@@ -1,6 +1,6 @@
1
1
  export interface IntegrationBase {
2
- create?(query: any): Promise<any[]>
3
- read?(query: any): Promise<any[]>
4
- update?(query: any): Promise<any[]>
5
- delete?(query: any): Promise<any[]>
2
+ create?(query: any): Promise<any[] | any>
3
+ read?(query: any): Promise<any[] | any>
4
+ update?(query: any): Promise<any[] | any>
5
+ delete?(query: any): Promise<any[] | any>
6
6
  }
@@ -450,7 +450,7 @@ module OracleModule {
450
450
  })
451
451
  return lastRow.rows
452
452
  } else {
453
- return [{ [ operation.toLowerCase() ]: true }]
453
+ return [{ [operation.toLowerCase()]: true }]
454
454
  }
455
455
  }
456
456
  }
@@ -2,29 +2,65 @@ import {
2
2
  Integration,
3
3
  DatasourceFieldTypes,
4
4
  QueryTypes,
5
+ RestConfig,
6
+ RestQueryFields as RestQuery,
7
+ AuthType,
8
+ BasicAuthConfig,
9
+ BearerAuthConfig,
5
10
  } from "../definitions/datasource"
6
11
  import { IntegrationBase } from "./base/IntegrationBase"
7
12
 
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
+
8
45
  module RestModule {
9
46
  const fetch = require("node-fetch")
10
-
11
- interface RestConfig {
12
- url: string
13
- defaultHeaders: {
14
- [key: string]: any
15
- }
16
- }
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")
17
52
 
18
53
  const SCHEMA: Integration = {
19
54
  docs: "https://github.com/node-fetch/node-fetch",
20
55
  description:
21
- "Representational state transfer (REST) is a de-facto standard for a software architecture for interactive applications that typically use multiple Web services. ",
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.",
22
57
  friendlyName: "REST API",
23
58
  datasource: {
24
59
  url: {
25
60
  type: DatasourceFieldTypes.STRING,
26
- default: "localhost",
27
- required: true,
61
+ default: "",
62
+ required: false,
63
+ deprecated: true,
28
64
  },
29
65
  defaultHeaders: {
30
66
  type: DatasourceFieldTypes.OBJECT,
@@ -37,97 +73,30 @@ module RestModule {
37
73
  readable: true,
38
74
  displayName: "POST",
39
75
  type: QueryTypes.FIELDS,
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
- },
76
+ fields: coreFields,
55
77
  },
56
78
  read: {
57
79
  displayName: "GET",
58
80
  readable: true,
59
81
  type: QueryTypes.FIELDS,
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
- },
82
+ fields: coreFields,
72
83
  },
73
84
  update: {
74
85
  displayName: "PUT",
75
86
  readable: true,
76
87
  type: QueryTypes.FIELDS,
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
- },
88
+ fields: coreFields,
92
89
  },
93
90
  patch: {
94
91
  displayName: "PATCH",
95
92
  readable: true,
96
93
  type: QueryTypes.FIELDS,
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
- },
94
+ fields: coreFields,
112
95
  },
113
96
  delete: {
114
97
  displayName: "DELETE",
115
98
  type: QueryTypes.FIELDS,
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
- },
99
+ fields: coreFields,
131
100
  },
132
101
  },
133
102
  }
@@ -137,99 +106,220 @@ module RestModule {
137
106
  private headers: {
138
107
  [key: string]: string
139
108
  } = {}
109
+ private startTimeMs: number = performance.now()
140
110
 
141
111
  constructor(config: RestConfig) {
142
112
  this.config = config
143
113
  }
144
114
 
145
115
  async parseResponse(response: any) {
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()
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
+ },
151
165
  }
152
166
  }
153
167
 
154
168
  getUrl(path: string, queryString: string): string {
155
- return `${this.config.url}/${path}?${queryString}`
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
156
178
  }
157
179
 
158
- async create({ path = "", queryString = "", headers = {}, json = {} }) {
159
- this.headers = {
160
- ...this.config.defaultHeaders,
161
- ...headers,
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
162
187
  }
163
-
164
- const response = await fetch(this.getUrl(path, queryString), {
165
- method: "POST",
166
- headers: this.headers,
167
- body: JSON.stringify(json),
168
- })
169
-
170
- return await this.parseResponse(response)
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
228
+ }
229
+ return input
171
230
  }
172
231
 
173
- async read({ path = "", queryString = "", headers = {} }) {
174
- this.headers = {
175
- ...this.config.defaultHeaders,
176
- ...headers,
177
- }
232
+ getAuthHeaders(authConfigId: string): { [key: string]: any } {
233
+ let headers: any = {}
178
234
 
179
- const response = await fetch(this.getUrl(path, queryString), {
180
- headers: this.headers,
181
- })
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
+ }
182
257
 
183
- return await this.parseResponse(response)
258
+ return headers
184
259
  }
185
260
 
186
- async update({ path = "", queryString = "", headers = {}, json = {} }) {
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
+
187
274
  this.headers = {
188
275
  ...this.config.defaultHeaders,
189
276
  ...headers,
277
+ ...authHeaders,
278
+ }
279
+
280
+ if (disabledHeaders) {
281
+ for (let headerKey of Object.keys(this.headers)) {
282
+ if (disabledHeaders[headerKey]) {
283
+ delete this.headers[headerKey]
284
+ }
285
+ }
190
286
  }
191
287
 
192
- const response = await fetch(this.getUrl(path, queryString), {
193
- method: "PUT",
194
- headers: this.headers,
195
- body: JSON.stringify(json),
196
- })
288
+ let input: any = { method, headers: this.headers }
289
+ if (requestBody) {
290
+ input = this.addBody(bodyType, requestBody, input)
291
+ }
197
292
 
293
+ this.startTimeMs = performance.now()
294
+ const url = this.getUrl(path, queryString)
295
+ const response = await fetch(url, input)
198
296
  return await this.parseResponse(response)
199
297
  }
200
298
 
201
- async patch({ path = "", queryString = "", headers = {}, json = {} }) {
202
- this.headers = {
203
- ...this.config.defaultHeaders,
204
- ...headers,
205
- }
206
-
207
- const response = await fetch(this.getUrl(path, queryString), {
208
- method: "PATCH",
209
- headers: this.headers,
210
- body: JSON.stringify(json),
211
- })
299
+ async create(opts: RestQuery) {
300
+ return this._req({ ...opts, method: "POST" })
301
+ }
212
302
 
213
- return await this.parseResponse(response)
303
+ async read(opts: RestQuery) {
304
+ return this._req({ ...opts, method: "GET" })
214
305
  }
215
306
 
216
- async delete({ path = "", queryString = "", headers = {} }) {
217
- this.headers = {
218
- ...this.config.defaultHeaders,
219
- ...headers,
220
- }
307
+ async update(opts: RestQuery) {
308
+ return this._req({ ...opts, method: "PUT" })
309
+ }
221
310
 
222
- const response = await fetch(this.getUrl(path, queryString), {
223
- method: "DELETE",
224
- headers: this.headers,
225
- })
311
+ async patch(opts: RestQuery) {
312
+ return this._req({ ...opts, method: "PATCH" })
313
+ }
226
314
 
227
- return await this.parseResponse(response)
315
+ async delete(opts: RestQuery) {
316
+ return this._req({ ...opts, method: "DELETE" })
228
317
  }
229
318
  }
230
319
 
231
320
  module.exports = {
232
321
  schema: SCHEMA,
233
322
  integration: RestIntegration,
323
+ AuthType,
234
324
  }
235
325
  }