Skip to content

Commit 0d2e399

Browse files
committed
📘 feat: parser
1 parent 220e922 commit 0d2e399

File tree

4 files changed

+83
-31
lines changed

4 files changed

+83
-31
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "elysia",
33
"description": "Ergonomic Framework for Human",
4-
"version": "1.2.0-exp.51",
4+
"version": "1.2.0-exp.52",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",

src/compose.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ export const composeHandler = ({
943943
break
944944

945945
default:
946-
if ((parser[0] as string) in app.parser) {
946+
if ((parser[0] as string) in app['~parser']) {
947947
fnLiteral += hasHeaders
948948
? `let contentType = c.headers['content-type']`
949949
: `let contentType = c.request.headers.get('content-type')`
@@ -1092,7 +1092,7 @@ export const composeHandler = ({
10921092
`break` +
10931093
'\n'
10941094

1095-
for (const key of Object.keys(app.parser))
1095+
for (const key of Object.keys(app['~parser']))
10961096
fnLiteral +=
10971097
`case '${key}':` +
10981098
`let bo${key}=parser['${key}'](c,contentType)\n` +
@@ -1958,7 +1958,7 @@ export const composeHandler = ({
19581958
// @ts-expect-error private property
19591959
getServer: () => app.getServer(),
19601960
TypeBoxError,
1961-
parser: app.parser,
1961+
parser: app['~parser'],
19621962
...adapter.inject
19631963
})
19641964
} catch (error) {

src/index.ts

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ export default class Elysia<
314314
return this.server
315315
}
316316

317-
parser: Record<string, BodyHandler<any, any>> = {}
317+
'~parser': Record<string, BodyHandler<any, any>> = {}
318318

319319
private _promisedModules: PromiseGroup | undefined
320320
private get promisedModules() {
@@ -1023,6 +1023,28 @@ export default class Elysia<
10231023
>
10241024
): this
10251025

1026+
onParse<const Parsers extends keyof Metadata['parser']>(
1027+
parser: Parsers
1028+
): this
1029+
1030+
onParse(
1031+
options: { as?: LifeCycleType } | MaybeArray<Function> | string,
1032+
handler?: MaybeArray<Function>
1033+
): unknown {
1034+
if (!handler) {
1035+
if (typeof options === 'string')
1036+
return this.on('parse', this['~parser'][options] as any)
1037+
1038+
return this.on('parse', options as any)
1039+
}
1040+
1041+
return this.on(
1042+
options as { as?: LifeCycleType },
1043+
'parse',
1044+
handler as any
1045+
)
1046+
}
1047+
10261048
/**
10271049
* ### parse | Life cycle event
10281050
* Callback function to handle body parsing
@@ -1042,7 +1064,7 @@ export default class Elysia<
10421064
* })
10431065
* ```
10441066
*/
1045-
onParse<
1067+
parser<
10461068
const Parser extends string,
10471069
const Schema extends RouteSchema,
10481070
const Handler extends BodyHandler<
@@ -1079,25 +1101,10 @@ export default class Elysia<
10791101
Routes,
10801102
Ephemeral,
10811103
Volatile
1082-
>
1083-
1084-
onParse(
1085-
options: { as?: LifeCycleType } | MaybeArray<Function> | string,
1086-
handler?: MaybeArray<Function>
1087-
): unknown {
1088-
if (!handler) return this.on('parse', options as any)
1089-
1090-
if (typeof options === 'string') {
1091-
this.parser[options] = handler as any
1092-
1093-
return this
1094-
}
1104+
> {
1105+
this['~parser'][name] = parser as any
10951106

1096-
return this.on(
1097-
options as { as?: LifeCycleType },
1098-
'parse',
1099-
handler as any
1100-
)
1107+
return this as any
11011108
}
11021109

11031110
/**
@@ -3527,6 +3534,11 @@ export default class Elysia<
35273534
plugin.model(this.definitions.type as any)
35283535
plugin.error(this.definitions.error as any)
35293536

3537+
this['~parser'] = {
3538+
...plugin['~parser'],
3539+
...this['~parser']
3540+
}
3541+
35303542
this.headers(plugin.setHeaders)
35313543

35323544
if (name) {

test/lifecycle/parser.test.ts

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ describe('Parser', () => {
290290

291291
it('handle custom parser then fallback to named default', async () => {
292292
const app = new Elysia()
293-
.onParse('custom', ({ contentType, request }) => {
293+
.parser('custom', ({ contentType, request }) => {
294294
if (contentType.startsWith('application/x-elysia'))
295295
return { name: 'Eden' }
296296
})
@@ -325,7 +325,7 @@ describe('Parser', () => {
325325

326326
it('handle custom parser then fallback to unknown', async () => {
327327
const app = new Elysia()
328-
.onParse('custom', ({ contentType, request }) => {
328+
.parser('custom', ({ contentType, request }) => {
329329
if (contentType.startsWith('application/x-elysia'))
330330
return { name: 'Eden' }
331331
})
@@ -361,13 +361,18 @@ describe('Parser', () => {
361361
expect(response).toEqual([{ name: 'Aru' }, { name: 'Eden' }])
362362
})
363363

364-
it('handle multiple custom parsers then fallback to unknown', async () => {
365-
const app = new Elysia()
366-
.onParse('custom', ({ contentType, request }) => {
364+
it('handle parser from plugin', async () => {
365+
const plugin = new Elysia().parser(
366+
'custom',
367+
({ contentType, request }) => {
367368
if (contentType === 'application/x-elysia')
368369
return { name: 'Eden' }
369-
})
370-
.onParse('custom2', ({ contentType, request }) => {
370+
}
371+
)
372+
373+
const app = new Elysia()
374+
.use(plugin)
375+
.parser('custom2', ({ contentType, request }) => {
371376
if (contentType === 'application/x-elysia-2')
372377
return { name: 'Pardofelis' }
373378
})
@@ -417,4 +422,39 @@ describe('Parser', () => {
417422
{ name: 'Pardofelis' }
418423
])
419424
})
425+
426+
it('handle custom parser then fallback to named default', async () => {
427+
const app = new Elysia()
428+
.parser('custom', ({ contentType, request }) => {
429+
if (contentType.startsWith('application/x-elysia'))
430+
return { name: 'Eden' }
431+
})
432+
.post('/json', ({ body }) => body, {
433+
parse: ['custom', 'json']
434+
})
435+
436+
const response = await Promise.all([
437+
app
438+
.handle(
439+
new Request('http://localhost:3000/json', {
440+
method: 'POST',
441+
body: JSON.stringify({ name: 'Aru' })
442+
})
443+
)
444+
.then((x) => x.json()),
445+
app
446+
.handle(
447+
new Request('http://localhost:3000/json', {
448+
method: 'POST',
449+
headers: {
450+
'content-type': 'application/x-elysia'
451+
},
452+
body: JSON.stringify({ name: 'Aru' })
453+
})
454+
)
455+
.then((x) => x.json())
456+
])
457+
458+
expect(response).toEqual([{ name: 'Aru' }, { name: 'Eden' }])
459+
})
420460
})

0 commit comments

Comments
 (0)