Skip to content

Commit

Permalink
Use fetch for fake api proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
razor-x committed Oct 31, 2023
1 parent a58dcbe commit 8855f18
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 42 deletions.
62 changes: 39 additions & 23 deletions api/fake-seam-connect.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { readFileSync } from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { Readable, type Stream } from 'node:stream'
import type { Readable } from 'node:stream'

import {
createFake as createFakeDevicedb,
type Fake as FakeDevicedb,
} from '@seamapi/fake-devicedb'
import { createFake } from '@seamapi/fake-seam-connect'
import type { VercelRequest, VercelResponse } from '@vercel/node'
import axios from 'axios'
import getRawBody from 'raw-body'

// eslint-disable-next-line import/no-relative-parent-imports
import { seedFake } from '../.storybook/seed-fake.js'
Expand Down Expand Up @@ -39,7 +37,8 @@ export default async (
req: VercelRequest,
res: VercelResponse
): Promise<void> => {
const { apipath, ...getParams } = req.query
const { method } = req
const { apipath, ...query } = req.query

const fake = await createFake()
seedFake(fake.database)
Expand All @@ -57,24 +56,42 @@ export default async (
if (host == null) throw new Error('Missing Host header')
await fake.startServer({ baseUrl: `https://${host}/api` })

const requestBuffer = await getRawBody(req)
const body = await buffer(req)

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

const { status, data, headers } = await axios.request({
url: `${fake.serverUrl}/${apipath}`,
params: getParams,
method: req.method,
headers: { ...req.headers },
data: getRequestStreamFromBuffer(requestBuffer),
timeout: 10_000,
validateStatus: () => true,
maxRedirects: 0,
responseType: 'arraybuffer',
const serverUrl = fake.serverUrl
if (serverUrl == null) {
throw new Error('Fake serverUrl was null')
}

if (method == null) {
throw new Error('Request method undefined')
}

const url = new URL(apipath, serverUrl)
for (const [k, v] of Object.entries(query)) {
if (typeof v === 'string') url.searchParams.append(k, v)
}

const reqHeaders: Record<string, string> = {}
for (const [k, v] of Object.entries(req.headers)) {
if (k === 'content-length') continue
if (typeof v === 'string') reqHeaders[k] = v
}

const proxyRes = await fetch(url, {
redirect: 'follow',
method,
headers: reqHeaders,
...(['GET', 'HEAD'].includes(method) ? {} : { body }),
})

const { status, headers } = proxyRes
const data = await proxyRes.arrayBuffer()

res.status(status)

for (const [key, value] of Object.entries(headers)) {
Expand All @@ -94,12 +111,11 @@ const getFakeDevicedb = async (): Promise<FakeDevicedb> => {
return fake
}

// https://stackoverflow.com/a/44091532/559475
const getRequestStreamFromBuffer = (requestBuffer: Buffer): Stream => {
const requestStream = new Readable()
// eslint-disable-next-line @typescript-eslint/no-empty-function
requestStream._read = () => {}
requestStream.push(requestBuffer)
requestStream.push(null)
return requestStream
const buffer = async (readable: Readable): Promise<ArrayBuffer> => {
const chunks = []
for await (const chunk of readable) {
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)
}
const buf = Buffer.concat(chunks)
return new Uint8Array(buf).buffer
}
17 changes: 0 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@
"@vitejs/plugin-react": "^4.0.0",
"@vitest/coverage-v8": "^0.34.4",
"@vitest/ui": "^0.34.4",
"axios": "^1.4.0",
"concurrently": "^8.0.1",
"copy-webpack-plugin": "^11.0.0",
"del-cli": "^5.0.0",
Expand All @@ -180,7 +179,6 @@
"http-proxy-middleware": "^2.0.6",
"jsdom": "^22.1.0",
"prettier": "^3.0.0",
"raw-body": "^2.5.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.62.1",
Expand Down

0 comments on commit 8855f18

Please sign in to comment.