mirror of
https://github.com/langgenius/dify.git
synced 2026-06-07 16:32:01 +08:00
67 lines
2.1 KiB
TypeScript
67 lines
2.1 KiB
TypeScript
import type { AddressInfo } from 'node:net'
|
|
import { Buffer } from 'node:buffer'
|
|
import * as http from 'node:http'
|
|
|
|
// Records what the client actually put on the wire so API-client tests can
|
|
// assert method / path / query / body / headers without mocking fetch.
|
|
export type CapturedRequest = {
|
|
method?: string
|
|
url?: string
|
|
body?: string
|
|
headers?: http.IncomingHttpHeaders
|
|
}
|
|
|
|
export type StubServer = {
|
|
readonly url: string
|
|
readonly captured: CapturedRequest
|
|
readonly stop: () => Promise<void>
|
|
}
|
|
|
|
// Buffers the request body, captures the request line + headers, then replies
|
|
// with a JSON payload and a matching Content-Length.
|
|
export function jsonResponder(
|
|
status: number,
|
|
body: unknown,
|
|
captured: CapturedRequest,
|
|
): http.RequestListener {
|
|
return (req, res) => {
|
|
captured.method = req.method
|
|
captured.url = req.url
|
|
captured.headers = req.headers
|
|
const chunks: Buffer[] = []
|
|
req.on('data', c => chunks.push(c))
|
|
req.on('end', () => {
|
|
captured.body = Buffer.concat(chunks).toString('utf8')
|
|
const payload = JSON.stringify(body)
|
|
res.writeHead(status, {
|
|
'content-type': 'application/json',
|
|
'content-length': Buffer.byteLength(payload),
|
|
})
|
|
res.end(payload)
|
|
})
|
|
}
|
|
}
|
|
|
|
// Starts a throwaway loopback server. The handler is built from the same
|
|
// `captured` object the caller reads back via `stub.captured`, so there is no
|
|
// reassignment dance between the listener and the assertions.
|
|
export function startStubServer(
|
|
makeHandler: (captured: CapturedRequest) => http.RequestListener,
|
|
): Promise<StubServer> {
|
|
const captured: CapturedRequest = {}
|
|
const handler = makeHandler(captured)
|
|
return new Promise((resolve, reject) => {
|
|
const server = http.createServer((req, res) => handler(req, res))
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const addr = server.address() as AddressInfo
|
|
resolve({
|
|
url: `http://127.0.0.1:${addr.port}`,
|
|
captured,
|
|
stop: () =>
|
|
new Promise<void>((res, rej) => server.close(err => (err ? rej(err) : res()))),
|
|
})
|
|
})
|
|
server.on('error', reject)
|
|
})
|
|
}
|