Skip to content

Commit

Permalink
feat: support the already parsed body
Browse files Browse the repository at this point in the history
  • Loading branch information
3imed-jaberi committed Apr 16, 2023
1 parent 73d432b commit cf7ac14
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ app.use((ctx) => {
);
```

- **enableRawChecking**: support the already parsed body on the raw request by override and prioritize the parsed value over the sended payload. (default is `false`)

```js
app.use(
bodyParser({
enableRawChecking: true,
})
);
```

- **disableBodyParser**: you can dynamic disable body parser by set `ctx.disableBodyParser = true`.

```js
Expand Down
14 changes: 14 additions & 0 deletions src/body-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ declare module 'koa' {
}
}

declare module 'http' {
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
interface IncomingMessage {
body?: any;
}
}
/**
* Middleware wrapper which delegate options to the core code
*/
Expand All @@ -23,6 +29,7 @@ export function bodyParserWrapper(opts: BodyParserOptions = {}) {
onerror,
enableTypes = ['json', 'form'],
extendTypes = {} as NonNullable<BodyParserOptions['extendTypes']>,
enableRawChecking = false,
...restOpts
} = opts;
const isEnabledBodyAs = getIsEnabledBodyAs(enableTypes);
Expand Down Expand Up @@ -60,6 +67,13 @@ export function bodyParserWrapper(opts: BodyParserOptions = {}) {

return async function (ctx: Koa.Context, next: Koa.Next) {
if (ctx.request.body !== undefined || ctx.disableBodyParser) return next();
// raw request parsed and contain 'body' values and it's enabled to override the koa request
if (enableRawChecking && ctx.req.body !== undefined) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
ctx.request.body = ctx.req.body;
return next();
}

try {
const response = await parseBody(ctx);
ctx.request.body = 'parsed' in response ? response.parsed : {};
Expand Down
4 changes: 4 additions & 0 deletions src/body-parser.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export type BodyParserOptions = {
* error handler, can help to customize the response on error case
*/
onerror?: (error: Error, ctx: Koa.Context) => void;
/**
* False to disable the raw request body checking to prevent koa request override
*/
enableRawChecking?: boolean;
/**
* co-body parser will only parse when request type hits enableTypes
* @default ['json', 'form']
Expand Down
44 changes: 43 additions & 1 deletion test/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,21 @@ import type { BodyParserOptions } from "../src/body-parser.types";
import { UnsupportedBodyTypeError } from "../src/body-parser.utils";

const fixtures = path.join(__dirname, "fixtures");
const createApp = (options?: BodyParserOptions) => {
type CreateAppConfig = BodyParserOptions & {
rawParsedBody?: Record<string, string>;
};

const createApp = (config: CreateAppConfig = {}) => {
const { rawParsedBody, ...options } = config;
const app = new Koa();
rawParsedBody &&
app.use((ctx, next) => {
ctx.req.body = rawParsedBody;
console.log("==== middelware ====", rawParsedBody);

return next();
});

app.use(bodyParser(options));
return app;
};
Expand Down Expand Up @@ -464,4 +477,33 @@ describe("test/body-parser.test.ts", () => {
.expect("empty", done);
});
});

describe("enableRawChecking", () => {
it("should override koa request with raw request body if exist and enableRawChecking is truthy", (done) => {
const rawParsedBody = { rawFoo: "rawBar" };
const app = createApp({ rawParsedBody, enableRawChecking: true });
app.use(async (ctx) => {
ctx.body = ctx.request.body;
});

server = app.listen();
request(server)
.post("/")
.send({ foo: "bar" })
.expect(rawParsedBody, done);
});
it("shouldn't override koa request with raw request body if not exist and enableRawChecking is truthy", (done) => {
const rawParsedBody = undefined;
const app = createApp({ rawParsedBody, enableRawChecking: true });
app.use(async (ctx) => {
ctx.body = ctx.request.body;
});

server = app.listen();
request(server)
.post("/")
.send({ foo: "bar" })
.expect({ foo: "bar" }, done);
});
});
});

0 comments on commit cf7ac14

Please sign in to comment.