Merge pull request #13640 from Budibase/fix/BUDI-8147
Typing improvements for REST integration - fixing no responses
This commit is contained in:
commit
c99e8103e2
|
@ -26,13 +26,13 @@ import { parse } from "content-disposition"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Builder as XmlBuilder } from "xml2js"
|
import { Builder as XmlBuilder } from "xml2js"
|
||||||
|
|
||||||
const BodyTypes = {
|
enum BodyType {
|
||||||
NONE: "none",
|
NONE = "none",
|
||||||
FORM_DATA: "form",
|
FORM_DATA = "form",
|
||||||
XML: "xml",
|
XML = "xml",
|
||||||
ENCODED: "encoded",
|
ENCODED = "encoded",
|
||||||
JSON: "json",
|
JSON = "json",
|
||||||
TEXT: "text",
|
TEXT = "text",
|
||||||
}
|
}
|
||||||
|
|
||||||
const coreFields = {
|
const coreFields = {
|
||||||
|
@ -54,7 +54,7 @@ const coreFields = {
|
||||||
},
|
},
|
||||||
bodyType: {
|
bodyType: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
enum: Object.values(BodyTypes),
|
enum: Object.values(BodyType),
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
type: DatasourceFieldType.OBJECT,
|
type: DatasourceFieldType.OBJECT,
|
||||||
|
@ -131,7 +131,10 @@ class RestIntegration implements IntegrationBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async parseResponse(response: any, pagination: PaginationConfig | null) {
|
async parseResponse(response: any, pagination: PaginationConfig | null) {
|
||||||
let data, raw, headers, filename
|
let data: any[] | string | undefined,
|
||||||
|
raw: string | undefined,
|
||||||
|
headers: Record<string, string> = {},
|
||||||
|
filename: string | undefined
|
||||||
|
|
||||||
const contentType = response.headers.get("content-type") || ""
|
const contentType = response.headers.get("content-type") || ""
|
||||||
const contentDisposition = response.headers.get("content-disposition") || ""
|
const contentDisposition = response.headers.get("content-disposition") || ""
|
||||||
|
@ -149,7 +152,7 @@ class RestIntegration implements IntegrationBase {
|
||||||
} else {
|
} else {
|
||||||
if (response.status === 204) {
|
if (response.status === 204) {
|
||||||
data = []
|
data = []
|
||||||
raw = []
|
raw = ""
|
||||||
} else if (contentType.includes("application/json")) {
|
} else if (contentType.includes("application/json")) {
|
||||||
data = await response.json()
|
data = await response.json()
|
||||||
raw = JSON.stringify(data)
|
raw = JSON.stringify(data)
|
||||||
|
@ -162,16 +165,18 @@ class RestIntegration implements IntegrationBase {
|
||||||
raw = xmlResponse.rawXml
|
raw = xmlResponse.rawXml
|
||||||
} else {
|
} else {
|
||||||
data = await response.text()
|
data = await response.text()
|
||||||
raw = data
|
raw = data as string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw `Failed to parse response body: ${err}`
|
throw `Failed to parse response body: ${err}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const size = formatBytes(
|
let contentLength: string = response.headers.get("content-length")
|
||||||
response.headers.get("content-length") || Buffer.byteLength(raw, "utf8")
|
if (!contentLength && raw) {
|
||||||
)
|
contentLength = Buffer.byteLength(raw, "utf8").toString()
|
||||||
|
}
|
||||||
|
const size = formatBytes(contentLength || "0")
|
||||||
const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
|
const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
|
||||||
headers = response.headers.raw()
|
headers = response.headers.raw()
|
||||||
for (let [key, value] of Object.entries(headers)) {
|
for (let [key, value] of Object.entries(headers)) {
|
||||||
|
@ -255,7 +260,7 @@ class RestIntegration implements IntegrationBase {
|
||||||
if (!input.headers) {
|
if (!input.headers) {
|
||||||
input.headers = {}
|
input.headers = {}
|
||||||
}
|
}
|
||||||
if (bodyType === BodyTypes.NONE) {
|
if (bodyType === BodyType.NONE) {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
let error,
|
let error,
|
||||||
|
@ -283,11 +288,11 @@ class RestIntegration implements IntegrationBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bodyType) {
|
switch (bodyType) {
|
||||||
case BodyTypes.TEXT:
|
case BodyType.TEXT:
|
||||||
// content type defaults to plaintext
|
// content type defaults to plaintext
|
||||||
input.body = string
|
input.body = string
|
||||||
break
|
break
|
||||||
case BodyTypes.ENCODED: {
|
case BodyType.ENCODED: {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
for (let [key, value] of Object.entries(object)) {
|
for (let [key, value] of Object.entries(object)) {
|
||||||
params.append(key, value as string)
|
params.append(key, value as string)
|
||||||
|
@ -298,7 +303,7 @@ class RestIntegration implements IntegrationBase {
|
||||||
input.body = params
|
input.body = params
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case BodyTypes.FORM_DATA: {
|
case BodyType.FORM_DATA: {
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
for (let [key, value] of Object.entries(object)) {
|
for (let [key, value] of Object.entries(object)) {
|
||||||
form.append(key, value)
|
form.append(key, value)
|
||||||
|
@ -309,14 +314,14 @@ class RestIntegration implements IntegrationBase {
|
||||||
input.body = form
|
input.body = form
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case BodyTypes.XML:
|
case BodyType.XML:
|
||||||
if (object != null && Object.keys(object).length) {
|
if (object != null && Object.keys(object).length) {
|
||||||
string = new XmlBuilder().buildObject(object)
|
string = new XmlBuilder().buildObject(object)
|
||||||
}
|
}
|
||||||
input.body = string
|
input.body = string
|
||||||
input.headers["Content-Type"] = "application/xml"
|
input.headers["Content-Type"] = "application/xml"
|
||||||
break
|
break
|
||||||
case BodyTypes.JSON:
|
case BodyType.JSON:
|
||||||
// if JSON error, throw it
|
// if JSON error, throw it
|
||||||
if (error) {
|
if (error) {
|
||||||
throw "Invalid JSON for request body"
|
throw "Invalid JSON for request body"
|
||||||
|
|
|
@ -245,13 +245,13 @@ describe("REST Integration", () => {
|
||||||
expect(output.extra.headers["content-type"]).toEqual("application/xml")
|
expect(output.extra.headers["content-type"]).toEqual("application/xml")
|
||||||
})
|
})
|
||||||
|
|
||||||
test.each(contentTypes)(
|
test.each([...contentTypes, undefined])(
|
||||||
"should not throw an error on 204 no content",
|
"should not throw an error on 204 no content",
|
||||||
async contentType => {
|
async contentType => {
|
||||||
const input = buildInput(undefined, null, contentType, 204)
|
const input = buildInput(undefined, null, contentType, 204)
|
||||||
const output = await config.integration.parseResponse(input)
|
const output = await config.integration.parseResponse(input)
|
||||||
expect(output.data).toEqual([])
|
expect(output.data).toEqual([])
|
||||||
expect(output.extra.raw).toEqual([])
|
expect(output.extra.raw).toEqual("")
|
||||||
expect(output.info.code).toEqual(204)
|
expect(output.info.code).toEqual(204)
|
||||||
expect(output.extra.headers["content-type"]).toEqual(contentType)
|
expect(output.extra.headers["content-type"]).toEqual(contentType)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue