Skip to content

Commit e53bb48

Browse files
committed
docs: Use fetch for fake api proxy
1 parent 9ff5624 commit e53bb48

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

api/fake-seam-connect.ts

+42-25
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { readFileSync } from 'node:fs'
22
import path from 'node:path'
33
import process from 'node:process'
4-
import { Readable, type Stream } from 'node:stream'
4+
import type { Readable } from 'node:stream'
55

66
import {
77
createFake as createFakeDevicedb,
@@ -10,8 +10,6 @@ import {
1010
} from '@seamapi/fake-devicedb'
1111
import { createFake } from '@seamapi/fake-seam-connect'
1212
import type { VercelRequest, VercelResponse } from '@vercel/node'
13-
import axios from 'axios'
14-
import getRawBody from 'raw-body'
1513

1614
// eslint-disable-next-line import/no-relative-parent-imports
1715
import { seedFake } from '../.storybook/seed-fake.js'
@@ -40,7 +38,8 @@ export default async (
4038
req: VercelRequest,
4139
res: VercelResponse
4240
): Promise<void> => {
43-
const { apipath, ...getParams } = req.query
41+
const { method } = req
42+
const { apipath, ...query } = req.query
4443

4544
const fake = await createFake()
4645
seedFake(fake.database)
@@ -58,28 +57,47 @@ export default async (
5857
if (host == null) throw new Error('Missing Host header')
5958
await fake.startServer({ baseUrl: `https://${host}/api` })
6059

61-
const requestBuffer = await getRawBody(req)
60+
const body = await buffer(req)
6261

6362
if (typeof apipath !== 'string') {
6463
throw new Error('Expected apipath to be a string')
6564
}
6665

67-
const { status, data, headers } = await axios.request({
68-
url: `${fake.serverUrl}/${apipath}`,
69-
params: getParams,
70-
method: req.method,
71-
headers: { ...req.headers },
72-
data: getRequestStreamFromBuffer(requestBuffer),
73-
timeout: 10_000,
74-
validateStatus: () => true,
75-
maxRedirects: 0,
76-
responseType: 'arraybuffer',
66+
const serverUrl = fake.serverUrl
67+
if (serverUrl == null) {
68+
throw new Error('Fake serverUrl was null')
69+
}
70+
71+
if (method == null) {
72+
throw new Error('Request method undefined')
73+
}
74+
75+
const url = new URL(apipath, serverUrl)
76+
for (const [k, v] of Object.entries(query)) {
77+
if (typeof v === 'string') url.searchParams.append(k, v)
78+
}
79+
80+
const reqHeaders: Record<string, string> = {}
81+
for (const [k, v] of Object.entries(req.headers)) {
82+
if (k === 'content-length') continue
83+
if (typeof v === 'string') reqHeaders[k] = v
84+
}
85+
const proxyRes = await fetch(url, {
86+
redirect: 'follow',
87+
mode: 'cors',
88+
credentials: 'include',
89+
method,
90+
headers: reqHeaders,
91+
...(['GET', 'HEAD', 'OPTIONS'].includes(method) ? {} : { body }),
7792
})
7893

94+
const { status, headers } = proxyRes
95+
const data = await proxyRes.arrayBuffer()
96+
7997
res.status(status)
8098

81-
for (const [key, value] of Object.entries(headers)) {
82-
if (!unproxiedHeaders.has(key)) res.setHeader(key, value as string)
99+
for (const [key, value] of headers) {
100+
if (!unproxiedHeaders.has(key)) res.setHeader(key, value)
83101
}
84102

85103
res.end(Buffer.from(data as Buffer))
@@ -95,12 +113,11 @@ const getFakeDevicedb = async (): Promise<FakeDevicedb> => {
95113
return fake
96114
}
97115

98-
// https://stackoverflow.com/a/44091532/559475
99-
const getRequestStreamFromBuffer = (requestBuffer: Buffer): Stream => {
100-
const requestStream = new Readable()
101-
// eslint-disable-next-line @typescript-eslint/no-empty-function
102-
requestStream._read = () => {}
103-
requestStream.push(requestBuffer)
104-
requestStream.push(null)
105-
return requestStream
116+
const buffer = async (readable: Readable): Promise<ArrayBuffer> => {
117+
const chunks = []
118+
for await (const chunk of readable) {
119+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)
120+
}
121+
const buf = Buffer.concat(chunks)
122+
return new Uint8Array(buf).buffer
106123
}

package-lock.json

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@
164164
"@vitejs/plugin-react": "^4.0.0",
165165
"@vitest/coverage-v8": "^0.34.4",
166166
"@vitest/ui": "^0.34.4",
167-
"axios": "^1.4.0",
168167
"concurrently": "^8.0.1",
169168
"copy-webpack-plugin": "^11.0.0",
170169
"del-cli": "^5.0.0",
@@ -182,7 +181,6 @@
182181
"happy-dom": "^12.10.3",
183182
"http-proxy-middleware": "^2.0.6",
184183
"prettier": "^3.0.0",
185-
"raw-body": "^2.5.2",
186184
"react": "^18.2.0",
187185
"react-dom": "^18.2.0",
188186
"sass": "^1.62.1",

0 commit comments

Comments
 (0)