From 65e64c83b74d45997da04226cc6f9a84000c2db2 Mon Sep 17 00:00:00 2001 From: Lordfirespeed <28568841+Lordfirespeed@users.noreply.github.com> Date: Mon, 23 Sep 2024 00:21:57 +0100 Subject: [PATCH] feat!: don't populate `req.body`, return the parsed body instead --- README.md | 9 ++++--- src/content-types/custom.ts | 13 ++++----- src/content-types/json.ts | 34 +++++++++++------------- src/content-types/multipart-form-data.ts | 22 +++++++-------- src/content-types/raw-multipart.ts | 22 +++++++-------- src/content-types/raw.ts | 22 +++++++-------- src/content-types/text.ts | 22 +++++++-------- src/content-types/urlencoded.ts | 22 +++++++-------- src/get-read.ts | 16 +++++------ src/types.ts | 7 ----- src/utils/iconv.ts | 2 +- tests/custom.test.ts | 23 ++++++---------- tests/json.test.ts | 15 +++++------ tests/raw.test.ts | 21 +++++---------- tests/text.test.ts | 21 +++++---------- tests/urlencoded.test.ts | 21 +++++---------- 16 files changed, 122 insertions(+), 170 deletions(-) diff --git a/README.md b/README.md index 03851da..4250790 100644 --- a/README.md +++ b/README.md @@ -92,10 +92,11 @@ Custom function for `parsec`. ```js // curl -d "this text must be uppercased" localhost -await custom( - req, - (d) => d.toUpperCase(), - (err) => {} +await makeCustom( + req, + (d) => d.toUpperCase(), + (err) => { + } ) res.end(req.body) // "THIS TEXT MUST BE UPPERCASED" ``` diff --git a/src/content-types/custom.ts b/src/content-types/custom.ts index 4411d18..299ab28 100644 --- a/src/content-types/custom.ts +++ b/src/content-types/custom.ts @@ -1,12 +1,13 @@ import { getRead } from '@/get-read' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' +import { hasNoBody } from '@/utils/has-no-body' -export const custom = (fn: (body: string) => T) => { +export const makeCustom = (fn: (body: string) => T) => { const read = getRead(fn) - return async (req: Request & HasBody & MaybeParsed, res: Response, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - req.body = await read(req, res) - next() + return async (req: Request & MaybeParsed, res: Response): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + return await read(req, res) } } diff --git a/src/content-types/json.ts b/src/content-types/json.ts index 70c2ae7..7bdc489 100644 --- a/src/content-types/json.ts +++ b/src/content-types/json.ts @@ -1,18 +1,17 @@ import { ContentType } from '@otterhttp/content-type' import { type ReadOptions, getRead } from '@/get-read' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { compose } from '@/utils/compose-functions' import { ClientCharsetError } from '@/utils/errors' import { hasNoBody } from '@/utils/has-no-body' import { typeChecker } from '@/utils/type-checker' -export type JsonBodyParsingOptions< - Body = unknown, - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, -> = Omit & { +export type JsonBodyParsingOptions = Response> = Omit< + ReadOptions, + 'defaultCharset' +> & { /** * JSON reviver to pass into JSON.parse. * @@ -65,11 +64,11 @@ function ensureCharsetIsUtf8(_req: unknown, _res: unknown, charset: string | und }) } -export function json< - Body = unknown, - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: JsonBodyParsingOptions) { +type ParsedJson = never | string | number | boolean | null | { [property: string]: ParsedJson } | ParsedJson[] + +export function makeJson = Response>( + options?: JsonBodyParsingOptions, +) { const optionsCopy: ReadOptions = Object.assign({ defaultCharset: 'utf-8' }, options) optionsCopy.limit ??= '100kb' optionsCopy.inflate ??= true @@ -79,7 +78,7 @@ export function json< const strict = options?.strict ?? true const matcher = options?.matcher ?? typeChecker(ContentType.parse('application/*+json')) - function parse(body: string) { + function parse(body: string): ParsedJson { if (body.length === 0) return {} if (strict) { @@ -93,11 +92,10 @@ export function json< } const read = getRead(parse, optionsCopy) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() - req.body = await read(req, res) - next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined + return await read(req, res) } } diff --git a/src/content-types/multipart-form-data.ts b/src/content-types/multipart-form-data.ts index 1ba8a16..0ab3d56 100644 --- a/src/content-types/multipart-form-data.ts +++ b/src/content-types/multipart-form-data.ts @@ -3,13 +3,13 @@ import { ClientError, HttpError } from '@otterhttp/errors' import { type RawReadOptions, type ReadOptions, getRawRead } from '@/get-read' import { type ParsedMultipartFormData, parseMultipartFormData } from '@/parsers/multipart-form-data' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { hasNoBody } from '@/utils/has-no-body' import { typeChecker } from '@/utils/type-checker' export type MultipartFormDataBodyParsingOptions< - Req extends Request & HasBody = Request & HasBody, + Req extends Request = Request, Res extends Response = Response, > = RawReadOptions & { /** @@ -22,10 +22,9 @@ export type MultipartFormDataBodyParsingOptions< matcher?: (req: Req, res: Res) => boolean } -export function multipartFormData< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: MultipartFormDataBodyParsingOptions) { +export function makeMultipartFormData = Response>( + options?: MultipartFormDataBodyParsingOptions, +) { const optionsCopy: ReadOptions = Object.assign({}, options) optionsCopy.limit ??= '10mb' optionsCopy.inflate ??= true @@ -40,10 +39,10 @@ export function multipartFormData< } const rawRead = getRawRead(options) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined if (req.headers['content-type'] == null) failBoundaryParameter() const contentType = ContentType.parse(req.headers['content-type']) @@ -53,7 +52,7 @@ export function multipartFormData< const rawBody = await rawRead(req, res) try { - req.body = parseMultipartFormData(rawBody, boundary) + return parseMultipartFormData(rawBody, boundary) } catch (err) { if (err instanceof HttpError) throw err throw new ClientError('Multipart body parsing failed', { @@ -62,7 +61,6 @@ export function multipartFormData< cause: err instanceof Error ? err : undefined, }) } - next() } } diff --git a/src/content-types/raw-multipart.ts b/src/content-types/raw-multipart.ts index 34a663e..9319f92 100644 --- a/src/content-types/raw-multipart.ts +++ b/src/content-types/raw-multipart.ts @@ -3,13 +3,13 @@ import { ClientError, HttpError } from '@otterhttp/errors' import { type RawReadOptions, type ReadOptions, getRawRead } from '@/get-read' import { type ParsedMultipartData, parseMultipart } from '@/parsers/multipart' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { hasNoBody } from '@/utils/has-no-body' import { typeChecker } from '@/utils/type-checker' export type RawMultipartBodyParsingOptions< - Req extends Request & HasBody = Request & HasBody, + Req extends Request = Request, Res extends Response = Response, > = RawReadOptions & { /** @@ -22,10 +22,9 @@ export type RawMultipartBodyParsingOptions< matcher?: (req: Req, res: Res) => boolean } -export function rawMultipart< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: RawMultipartBodyParsingOptions) { +export function makeRawMultipart = Response>( + options?: RawMultipartBodyParsingOptions, +) { const optionsCopy: ReadOptions = Object.assign({}, options) optionsCopy.limit ??= '10mb' optionsCopy.inflate ??= true @@ -40,10 +39,10 @@ export function rawMultipart< } const rawRead = getRawRead(options) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined if (req.headers['content-type'] == null) failBoundaryParameter() const contentType = ContentType.parse(req.headers['content-type']) @@ -53,7 +52,7 @@ export function rawMultipart< const rawBody = await rawRead(req, res) try { - req.body = parseMultipart(rawBody, boundary) + return parseMultipart(rawBody, boundary) } catch (err) { if (err instanceof HttpError) throw err throw new ClientError('Multipart body parsing failed', { @@ -62,7 +61,6 @@ export function rawMultipart< cause: err instanceof Error ? err : undefined, }) } - next() } } diff --git a/src/content-types/raw.ts b/src/content-types/raw.ts index d0c14d7..b695f97 100644 --- a/src/content-types/raw.ts +++ b/src/content-types/raw.ts @@ -1,10 +1,10 @@ import { type RawReadOptions, getRawRead } from '@/get-read' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { hasNoBody } from '@/utils/has-no-body' export type RawBodyParsingOptions< - Req extends Request & HasBody = Request & HasBody, + Req extends Request = Request, Res extends Response = Response, > = RawReadOptions & { /** @@ -17,10 +17,9 @@ export type RawBodyParsingOptions< matcher?: (req: Req, res: Res) => boolean } -export function raw< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: RawBodyParsingOptions) { +export function makeRaw = Response>( + options?: RawBodyParsingOptions, +) { const optionsCopy: RawReadOptions = Object.assign({}, options) optionsCopy.limit ??= '100kb' optionsCopy.inflate ??= true @@ -28,11 +27,10 @@ export function raw< const matcher = options?.matcher ?? (() => true) const read = getRawRead(options) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() - req.body = await read(req, res) - next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined + return await read(req, res) } } diff --git a/src/content-types/text.ts b/src/content-types/text.ts index 029ffd1..dbcb575 100644 --- a/src/content-types/text.ts +++ b/src/content-types/text.ts @@ -1,13 +1,13 @@ import { ContentType } from '@otterhttp/content-type' import { type ReadOptions, getRead } from '@/get-read' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { hasNoBody } from '@/utils/has-no-body' import { typeChecker } from '@/utils/type-checker' export type TextBodyParsingOptions< - Req extends Request & HasBody = Request & HasBody, + Req extends Request = Request, Res extends Response = Response, > = ReadOptions & { /** @@ -20,10 +20,9 @@ export type TextBodyParsingOptions< matcher?: (req: Req, res: Res) => boolean } -export function text< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: TextBodyParsingOptions) { +export function makeText = Response>( + options?: TextBodyParsingOptions, +) { const optionsCopy: ReadOptions = Object.assign({}, options) optionsCopy.limit ??= '100kb' optionsCopy.inflate ??= true @@ -31,11 +30,10 @@ export function text< const matcher = options?.matcher ?? typeChecker(ContentType.parse('text/*')) const read = getRead((x) => x.toString(), optionsCopy) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() - req.body = await read(req, res) - next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined + return await read(req, res) } } diff --git a/src/content-types/urlencoded.ts b/src/content-types/urlencoded.ts index 3cc3731..47ae205 100644 --- a/src/content-types/urlencoded.ts +++ b/src/content-types/urlencoded.ts @@ -2,7 +2,7 @@ import { type ParsedUrlQuery, parse } from 'node:querystring' import { ContentType } from '@otterhttp/content-type' import { type ReadOptions, getRead } from '@/get-read' -import type { HasBody, MaybeParsed, NextFunction, Request, Response } from '@/types' +import type { MaybeParsed, Request, Response } from '@/types' import { alreadyParsed } from '@/utils/already-parsed-symbol' import { compose } from '@/utils/compose-functions' import { ClientCharsetError } from '@/utils/errors' @@ -10,7 +10,7 @@ import { hasNoBody } from '@/utils/has-no-body' import { typeChecker } from '@/utils/type-checker' export type UrlencodedBodyParsingOptions< - Req extends Request & HasBody = Request & HasBody, + Req extends Request = Request, Res extends Response = Response, > = Omit & { /** @@ -36,10 +36,9 @@ function ensureCharsetIsUtf8(_req: unknown, _res: unknown, charset: string | und }) } -export function urlencoded< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, ->(options?: UrlencodedBodyParsingOptions) { +export function makeUrlencoded = Response>( + options?: UrlencodedBodyParsingOptions, +) { const optionsCopy: ReadOptions = Object.assign({ defaultCharset: 'utf-8' }, options) optionsCopy.limit ??= '100kb' optionsCopy.inflate ??= true @@ -48,12 +47,11 @@ export function urlencoded< const matcher = options?.matcher ?? typeChecker(ContentType.parse('application/*+x-www-form-urlencoded')) const read = getRead((x) => parse(x), optionsCopy) - return async (req: Req & MaybeParsed, res: Res, next: NextFunction) => { - if (req[alreadyParsed] === true) return next() - if (hasNoBody(req.method)) return next() - if (!matcher(req, res)) return next() - req.body = await read(req, res) - next() + return async (req: Req & MaybeParsed, res: Res): Promise => { + if (req[alreadyParsed] === true) return undefined + if (hasNoBody(req.method)) return undefined + if (!matcher(req, res)) return undefined + return await read(req, res) } } diff --git a/src/get-read.ts b/src/get-read.ts index 896fea9..013dd5b 100644 --- a/src/get-read.ts +++ b/src/get-read.ts @@ -14,7 +14,7 @@ import { LengthValidator } from '@/utils/length-validator' import { Limiter } from '@/utils/limiter' import { RawSink } from '@/utils/raw-sink' import { requestPipeline } from '@/utils/request-pipeline' -import type { HasBody, MaybeParsed, Request, Response } from './types' +import type { MaybeParsed, Request, Response } from './types' const supportedEncodings = new Map Transform>([ ['deflate', () => zlib.createInflate()], @@ -70,11 +70,11 @@ const getRawContentStreamer = (options?: StreamRawContentOptions) => { } } -type RawPreVerifyFunction< - Req extends Request & HasBody = Request & HasBody, - Res extends Response = Response, -> = (req: Req, res: Res) => void | Promise -type RawVerifyFunction = Response> = ( +type RawPreVerifyFunction = Response> = ( + req: Req, + res: Res, +) => void | Promise +type RawVerifyFunction = Response> = ( req: Req, res: Res, buf: Buffer, @@ -145,12 +145,12 @@ export const getRawRead = (options?: RawReadOptions) => { } } -type PreVerifyFunction = Response> = ( +type PreVerifyFunction = Response> = ( req: Req, res: Res, charset: string | undefined, ) => void | Promise -type VerifyFunction = Response> = ( +type VerifyFunction = Response> = ( req: Req, res: Res, blob: Buffer, diff --git a/src/types.ts b/src/types.ts index 8cdf5c8..92fbe64 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,13 +1,6 @@ import type { IncomingMessage, ServerResponse } from 'node:http' import { alreadyParsed } from '@/utils/already-parsed-symbol' -export type NextFunction = () => void - -// Extend the request object with body -export type HasBody = { - body?: T -} - export type MaybeParsed = { [alreadyParsed]?: true } diff --git a/src/utils/iconv.ts b/src/utils/iconv.ts index 20546b6..77b3be2 100644 --- a/src/utils/iconv.ts +++ b/src/utils/iconv.ts @@ -1,7 +1,7 @@ import * as _iconv from 'iconv-lite' // @ts-expect-error -const iconv = _iconv.default as typeof _iconv +const iconv = _iconv.default as typeof _iconv export const charsetExists = iconv.encodingExists export const decodeCharset = iconv.decode diff --git a/tests/custom.test.ts b/tests/custom.test.ts index c862e72..ff2424c 100644 --- a/tests/custom.test.ts +++ b/tests/custom.test.ts @@ -2,24 +2,17 @@ import { createServer } from 'node:http' import { makeFetch } from 'supertest-fetch' import { test } from 'vitest' -import { type HasBody, type Request, type Response, custom } from '@/index' +import { type Request, makeCustom } from '@/index' -const customInstance = custom((d) => d.toUpperCase()) -const loggingCustom = async (req: Request & HasBody, res: Response) => { - try { - await customInstance(req, res, () => undefined) - } catch (err) { - console.log(err) - } -} +const custom = makeCustom((d) => d.toUpperCase()) test('should parse custom body', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingCustom(req, res) + const server = createServer(async (req: Request, res) => { + const body = await custom(req, res) res.setHeader('Content-Type', 'text/plain') - res.end(req.body) + res.end(body) }) await makeFetch(server)('/', { @@ -33,12 +26,12 @@ test('should parse custom body', async () => { }) test('custom should ignore GET request', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingCustom(req, res) + const server = createServer(async (req: Request, res) => { + const body = await custom(req, res) res.setHeader('Content-Type', 'text/plain') - res.end('GET is ignored') + res.end(body == null ? 'GET is ignored' : 'GET is not ignored') }) await makeFetch(server)('/', { diff --git a/tests/json.test.ts b/tests/json.test.ts index cb64ce4..3e4b408 100644 --- a/tests/json.test.ts +++ b/tests/json.test.ts @@ -5,23 +5,20 @@ import { assert, afterEach, describe, expect, it, vi } from 'vitest' import './test-utils/mock-get-content-length' -import { type HasBody, type JsonBodyParsingOptions, type Request, type Response, json } from '@/index' +import { type JsonBodyParsingOptions, type Request, type Response, makeJson } from '@/index' import { getContentLength } from '@/utils/get-request-content-length' type FetchInit = Parameters[1] function createServer(opts?: JsonBodyParsingOptions) { - const jsonInstance = json(opts) + const json = makeJson(opts) - return http.createServer(async (req: Request & HasBody, res: Response) => { - function next() { + return http.createServer(async (req: Request, res: Response) => { + try { + const body = await json(req, res) res.statusCode = 200 res.setHeader('Content-Type', 'application/json') - res.end(JSON.stringify(req.body)) - } - - try { - await jsonInstance(req, res, next) + res.end(JSON.stringify(body)) } catch (err) { if (err instanceof HttpError) { res.statusCode = err.statusCode diff --git a/tests/raw.test.ts b/tests/raw.test.ts index 4b63017..fd8a828 100644 --- a/tests/raw.test.ts +++ b/tests/raw.test.ts @@ -2,24 +2,17 @@ import { createServer } from 'node:http' import { makeFetch } from 'supertest-fetch' import { test } from 'vitest' -import { type HasBody, type Request, type Response, raw } from '@/index' +import { type Request, makeRaw } from '@/index' -const rawInstance = raw() -const loggingRaw = async (req: Request & HasBody, res: Response) => { - try { - await rawInstance(req, res, () => undefined) - } catch (err) { - console.log(err) - } -} +const raw = makeRaw() test('should parse raw body', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingRaw(req, res) + const server = createServer(async (req: Request, res) => { + const body = await raw(req, res) res.setHeader('Content-Type', 'text/plain') - res.end(req.body) + res.end(body) }) await makeFetch(server)('/', { @@ -33,8 +26,8 @@ test('should parse raw body', async () => { }) test('raw should ignore GET request', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingRaw(req, res) + const server = createServer(async (req: Request, res) => { + const body = await raw(req, res) res.setHeader('Content-Type', 'text/plain') diff --git a/tests/text.test.ts b/tests/text.test.ts index e7e44d5..7e19009 100644 --- a/tests/text.test.ts +++ b/tests/text.test.ts @@ -2,24 +2,17 @@ import { createServer } from 'node:http' import { makeFetch } from 'supertest-fetch' import { test } from 'vitest' -import { type HasBody, type Request, type Response, text } from '@/index' +import { type Request, makeText } from '@/index' -const textInstance = text() -const loggingText = async (req: Request & HasBody, res: Response) => { - try { - await textInstance(req, res, () => undefined) - } catch (err) { - console.log(err) - } -} +const text = makeText() test('should parse text body', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingText(req, res) + const server = createServer(async (req: Request, res) => { + const body = await text(req, res) res.setHeader('Content-Type', 'text/plain') - res.end(req.body) + res.end(body) }) await makeFetch(server)('/', { @@ -33,8 +26,8 @@ test('should parse text body', async () => { }) test('text should ignore GET request', async () => { - const server = createServer(async (req: Request & HasBody, res) => { - await loggingText(req, res) + const server = createServer(async (req: Request, res) => { + await text(req, res) res.setHeader('Content-Type', 'text/plain') diff --git a/tests/urlencoded.test.ts b/tests/urlencoded.test.ts index ede249d..e441402 100644 --- a/tests/urlencoded.test.ts +++ b/tests/urlencoded.test.ts @@ -2,24 +2,17 @@ import { createServer } from 'node:http' import { makeFetch } from 'supertest-fetch' import { test } from 'vitest' -import { type HasBody, type Request, type Response, urlencoded } from '@/index' +import { type Request, makeUrlencoded } from '@/index' -const urlencodedInstance = urlencoded() -const loggingUrlencoded = async (req: Request & HasBody>, res: Response) => { - try { - await urlencodedInstance(req, res, () => undefined) - } catch (err) { - console.log(err) - } -} +const urlencoded = makeUrlencoded() test('should parse urlencoded body', async () => { - const server = createServer(async (req: Request & HasBody>, res) => { - await loggingUrlencoded(req, res) + const server = createServer(async (req: Request, res) => { + const body = await urlencoded(req, res) res.setHeader('Content-Type', 'application/x-www-form-urlencoded') - res.end(JSON.stringify(req.body)) + res.end(JSON.stringify(body)) }) await makeFetch(server)('/', { @@ -33,8 +26,8 @@ test('should parse urlencoded body', async () => { }) test('urlencoded should ignore GET request', async () => { - const server = createServer(async (req: Request & HasBody>, res) => { - await loggingUrlencoded(req, res) + const server = createServer(async (req: Request, res) => { + const body = await urlencoded(req, res) res.end('GET is ignored') })