Skip to content

Commit 2335f5e

Browse files
authored
feat: handle number and object responses correctly in functions (#440)
* chore: add package to output status messages * feat: default to html api function response * feat: handle res.json separately from res.send * feat: handle number, boolean and object types with res.send * test: update default content type for function responses * test: add tests for new function responses * chore: update package-lock files
1 parent eb1a1a2 commit 2335f5e

File tree

8 files changed

+64697
-4597
lines changed

8 files changed

+64697
-4597
lines changed

demo/package-lock.json

Lines changed: 37139 additions & 3997 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/package-lock.json

Lines changed: 27503 additions & 597 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"pathe": "^0.3.0",
5757
"pretty-bytes": "^5.6.0",
5858
"semver": "^7.3.5",
59+
"statuses": "^2.0.1",
5960
"tempy": "^1.0.0",
6061
"uuid": "^8.3.2"
6162
},

plugin/src/templates/api/utils.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import cookie from 'cookie'
1313
import type { GatsbyFunctionResponse } from 'gatsby'
1414
import { GatsbyFunctionRequest } from 'gatsby'
1515
import fetch, { Headers } from 'node-fetch'
16+
import statuses from 'statuses'
1617

1718
interface NetlifyFunctionParams {
1819
event: HandlerEvent
@@ -133,7 +134,7 @@ export const createResponseObject = ({ onResEnd }) => {
133134
response.statusCode = statusCode
134135
},
135136
})
136-
res.headers = { 'content-type': 'text/plain; charset=utf-8' }
137+
res.headers = { 'content-type': 'text/html; charset=utf-8' }
137138

138139
res.writeHead = (status, headers) => {
139140
response.statusCode = status
@@ -207,6 +208,22 @@ export const createResponseObject = ({ onResEnd }) => {
207208
if (res.finished) {
208209
return res
209210
}
211+
212+
if (typeof data === 'number') {
213+
return res
214+
.status(data)
215+
.setHeader('content-type', 'text/plain; charset=utf-8')
216+
.end(statuses.message[data] || String(data))
217+
}
218+
219+
if (typeof data === 'boolean' || typeof data === 'object') {
220+
if (Buffer.isBuffer(data)) {
221+
res.setHeader('content-type', 'application/octet-stream')
222+
} else if (data !== null) {
223+
return res.json(data)
224+
}
225+
}
226+
210227
res.end(data)
211228
return res
212229
}
@@ -216,7 +233,7 @@ export const createResponseObject = ({ onResEnd }) => {
216233
return res
217234
}
218235
res.setHeader('content-type', 'application/json')
219-
res.send(JSON.stringify(data))
236+
res.end(JSON.stringify(data))
220237
return res
221238
}
222239

plugin/test/fixtures/functions-without-gatsby-plugin/e2e-tests/test-helpers.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,38 @@ exports.runTests = function runTests(env, host) {
117117
})
118118
expect(res.headers.get('content-type')).toEqual('application/json')
119119
})
120+
test(`returns json correctly via send`, async () => {
121+
const res = await fetchTwice(`${host}/api/i-am-json-too`)
122+
const result = await res.json()
123+
124+
expect(result).toEqual({
125+
amIJSON: true,
126+
})
127+
expect(res.headers.get('content-type')).toEqual('application/json')
128+
})
129+
test(`returns boolean correctly via send`, async () => {
130+
const res = await fetchTwice(`${host}/api/i-am-false`)
131+
const result = await res.json()
132+
133+
expect(result).toEqual(false)
134+
expect(res.headers.get('content-type')).toEqual('application/json')
135+
})
136+
test(`returns status correctly via send`, async () => {
137+
const res = await fetchTwice(`${host}/api/i-am-status`)
138+
const result = await res.text()
139+
140+
expect(result).toEqual('OK')
141+
expect(res.headers.get('content-type')).toEqual(
142+
'text/plain; charset=utf-8',
143+
)
144+
})
120145
test(`returns text correctly`, async () => {
121146
const res = await fetchTwice(`${host}/api/i-am-text`)
122147
const result = await res.text()
123148

124149
expect(result).toEqual('I am text')
125150
expect(res.headers.get('content-type')).toEqual(
126-
'text/plain; charset=utf-8',
151+
'text/html; charset=utf-8',
127152
)
128153
})
129154
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function topLevel(req, res) {
2+
res.send(false)
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function topLevel(req, res) {
2+
res.send({ amIJSON: true })
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function topLevel(req, res) {
2+
res.send(200)
3+
}

0 commit comments

Comments
 (0)