Skip to content

Commit 5dd1ee3

Browse files
committed
🧹 chore: merge main
2 parents 0797c3f + e7dfe29 commit 5dd1ee3

File tree

7 files changed

+102
-55
lines changed

7 files changed

+102
-55
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 1.1.26 - 4 Dev 2024
2+
Bug fix:
3+
- [#907](https://github.com/elysiajs/elysia/issues/907), [#872](https://github.com/elysiajs/elysia/issues/872), [#926](https://github.com/elysiajs/elysia/issues/926) BooleanString is not behave correctly if property is not provided
4+
- [#929](https://github.com/elysiajs/elysia/issues/929) Non-ASCII characters cause querystring index to be incorrectly slice
5+
- [#912](https://github.com/elysiajs/elysia/issues/912) handle JavaScript date numeric offset
6+
17
# 1.1.25 - 14 Nov 2024
28
Bug fix:
39
- [#908](https://github.com/elysiajs/elysia/pull/908) boolean-string converted to string

bun.lockb

-4.13 KB
Binary file not shown.

example/a.ts

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,5 @@
1+
import { Value } from '@sinclair/typebox/value'
12
import { Elysia, t } from '../src'
3+
import { req } from '../test/utils'
24

3-
new Request('', {
4-
duplex: 'half',
5-
})
6-
7-
const app = new Elysia().get(
8-
'/',
9-
() => {
10-
return {
11-
duration: 200
12-
}
13-
},
14-
{
15-
response: {
16-
200: t.Object({
17-
duration: t.Number()
18-
}),
19-
400: t.Object({
20-
stuff: t.Number()
21-
})
22-
},
23-
afterResponse({ response }) {
24-
// expectTypeOf<typeof response>().toEqualTypeOf<
25-
// | {
26-
// duration: number
27-
// }
28-
// | {
29-
// stuff: number
30-
// }
31-
// >()
32-
// return undefined as any
33-
}
34-
}
35-
)
5+
console.log(Value.Create(t.Date()) instanceof Date)

src/compose.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ export const composeHandler = ({
699699
'}'
700700
} else {
701701
fnLiteral +=
702-
'if(c.qi!==-1){' + `let url = '&' + c.url.slice(c.qi + 1)\n`
702+
'if(c.qi!==-1){' + `let url = '&' + decodeURIComponent(c.url.slice(c.qi + 1))\n`
703703

704704
let index = 0
705705
for (const {
@@ -727,8 +727,8 @@ export const composeHandler = ({
727727
`else\n` +
728728
`a${index}+=','\n` +
729729
`let temp\n` +
730-
`if(memory===-1)temp=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
731-
`else temp=decodeURIComponent(url.slice(start, memory).replace(/\\+/g,' '))\n` +
730+
`if(memory===-1)temp=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
731+
`else temp=decodeURIComponent(url.slice(start, memory).replace(/\\+|%20/g,' '))\n` +
732732
`const charCode = temp.charCodeAt(0)\n` +
733733
`if(charCode !== 91 && charCode !== 123)\n` +
734734
`temp='"'+temp+'"'\n` +
@@ -751,10 +751,10 @@ export const composeHandler = ({
751751
`if(a${index}===undefined)` +
752752
`a${index}=[]\n` +
753753
`if(memory===-1){` +
754-
`a${index}.push(decodeURIComponent(url.slice(start)).replace(/\\+/g,' '))\n` +
754+
`a${index}.push(decodeURIComponent(url.slice(start)).replace(/\\+|%20/g,' '))\n` +
755755
`break` +
756756
`}` +
757-
`else a${index}.push(decodeURIComponent(url.slice(start, memory)).replace(/\\+/g,' '))\n` +
757+
`else a${index}.push(decodeURIComponent(url.slice(start, memory)).replace(/\\+|%20/g,' '))\n` +
758758
`memory=url.indexOf('&${key}=',memory)\n` +
759759
`if(memory===-1) break\n` +
760760
`}`
@@ -764,8 +764,8 @@ export const composeHandler = ({
764764
`if(memory!==-1){` +
765765
`const start=memory+${key.length + 2}\n` +
766766
`memory=url.indexOf('&',start)\n` +
767-
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))` +
768-
`else a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+/g,' '))` +
767+
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))` +
768+
`else a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+|%20/g,' '))` +
769769
`if(a${index}!==undefined)` +
770770
`try{` +
771771
`a${index}=JSON.parse(a${index})` +
@@ -778,9 +778,9 @@ export const composeHandler = ({
778778
`if(memory!==-1){` +
779779
`const start=memory+${key.length + 2}\n` +
780780
`memory=url.indexOf('&',start)\n` +
781-
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
781+
`if(memory===-1)a${index}=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
782782
`else{` +
783-
`a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+/g,' '))`
783+
`a${index}=decodeURIComponent(url.slice(start,memory).replace(/\\+|%20/g,' '))`
784784

785785
if (anyOf)
786786
fnLiteral +=
@@ -793,8 +793,8 @@ export const composeHandler = ({
793793
`if(first)first=false\n` +
794794
`else deepMemory = url.indexOf('&', start)\n` +
795795
`let value\n` +
796-
`if(deepMemory===-1)value=decodeURIComponent(url.slice(start).replace(/\\+/g,' '))\n` +
797-
`else value=decodeURIComponent(url.slice(start, deepMemory).replace(/\\+/g,' '))\n` +
796+
`if(deepMemory===-1)value=decodeURIComponent(url.slice(start).replace(/\\+|%20/g,' '))\n` +
797+
`else value=decodeURIComponent(url.slice(start, deepMemory).replace(/\\+|%20/g,' '))\n` +
798798
`const vStart=value.charCodeAt(0)\n` +
799799
`const vEnd=value.charCodeAt(value.length - 1)\n` +
800800
`if((vStart===91&&vEnd===93)||(vStart===123&&vEnd===125))\n` +

src/type-system.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,22 @@ export const ElysiaType = {
369369
t.String({
370370
format: 'date-time',
371371
default: new Date().toISOString()
372-
})
372+
}),
373+
t.Number()
373374
],
374375
property
375376
)
376377
)
377378
.Decode((value) => {
379+
if(typeof value === "number") {
380+
const date = new Date(value)
381+
382+
if (!Value.Check(schema, date))
383+
throw new ValidationError('property', schema, date)
384+
385+
return date
386+
}
387+
378388
if (value instanceof Date) return value
379389

380390
const date = new Date(value)
@@ -409,7 +419,7 @@ export const ElysiaType = {
409419
.Decode((value) => {
410420
if (typeof value === 'string') return value === 'true'
411421

412-
if (property && !Value.Check(schema, value))
422+
if (value !== undefined && !Value.Check(schema, value))
413423
throw new ValidationError('property', schema, value)
414424

415425
return value

test/type-system/date.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('TypeSystem - Date', () => {
1616
expect(Value.Check(schema, '2021/1/1')).toEqual(true)
1717

1818
expect(Value.Check(schema, 'yay')).toEqual(false)
19-
expect(Value.Check(schema, 42)).toEqual(false)
19+
expect(Value.Check(schema, 42)).toEqual(true)
2020
expect(Value.Check(schema, {})).toEqual(false)
2121
expect(Value.Check(schema, undefined)).toEqual(false)
2222
expect(Value.Check(schema, null)).toEqual(false)
@@ -36,7 +36,7 @@ describe('TypeSystem - Date', () => {
3636
'The encoded value does not match the expected schema'
3737
)
3838
expect(() => Value.Encode(schema, 'yay')).toThrow(error)
39-
expect(() => Value.Encode(schema, 42)).toThrow(error)
39+
expect(() => Value.Encode(schema, 42)).not.toThrow(error)
4040
expect(() => Value.Encode(schema, {})).toThrow(error)
4141
expect(() => Value.Encode(schema, undefined)).toThrow(error)
4242
expect(() => Value.Encode(schema, null)).toThrow(error)
@@ -56,7 +56,7 @@ describe('TypeSystem - Date', () => {
5656
'Unable to decode value as it does not match the expected schema'
5757
)
5858
expect(() => Value.Decode(schema, 'yay')).toThrow(error)
59-
expect(() => Value.Decode(schema, 42)).toThrow(error)
59+
expect(() => Value.Decode(schema, 42)).not.toThrow(error)
6060
expect(() => Value.Decode(schema, {})).toThrow(error)
6161
expect(() => Value.Decode(schema, undefined)).toThrow(error)
6262
expect(() => Value.Decode(schema, null)).toThrow(error)

test/validator/query.test.ts

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,34 @@ describe('Query Validator', () => {
200200
expect(await res.json()).toEqual({ param1: true })
201201
})
202202

203+
it('parse optional boolean string with second parameter', async () => {
204+
const schema = t.Object({
205+
registered: t.Optional(t.Boolean()),
206+
other: t.String()
207+
})
208+
const app = new Elysia().get('/', ({ query }) => query, {
209+
query: schema
210+
})
211+
const res = await app.handle(req('/?other=sucrose'))
212+
213+
expect(res.status).toBe(200)
214+
expect(await res.json()).toEqual({ other: 'sucrose' })
215+
})
216+
217+
it('parse optional boolean string with default value', async () => {
218+
const schema = t.Object({
219+
registered: t.Optional(t.Boolean({ default: true })),
220+
other: t.String()
221+
})
222+
const app = new Elysia().get('/', ({ query }) => query, {
223+
query: schema
224+
})
225+
const res = await app.handle(req('/?other=sucrose'))
226+
227+
expect(res.status).toBe(200)
228+
expect(await res.json()).toEqual({ other: 'sucrose', registered: true })
229+
})
230+
203231
it('validate optional object', async () => {
204232
const app = new Elysia().get(
205233
'/',
@@ -654,12 +682,11 @@ describe('Query Validator', () => {
654682
})
655683

656684
it('parse + in query', async () => {
657-
const api = new Elysia()
658-
.get('', ({ query }) => query, {
659-
query: t.Object({
660-
keyword: t.String()
661-
})
685+
const api = new Elysia().get('', ({ query }) => query, {
686+
query: t.Object({
687+
keyword: t.String()
662688
})
689+
})
663690

664691
const url = new URL('http://localhost:3000/')
665692
url.searchParams.append('keyword', 'hello world')
@@ -670,7 +697,41 @@ describe('Query Validator', () => {
670697
.then((response) => response.json())
671698

672699
expect(result).toEqual({
673-
'keyword': 'hello world'
700+
keyword: 'hello world'
701+
})
702+
})
703+
704+
// https://github.com/elysiajs/elysia/issues/929
705+
it('slice non-ASCII querystring offset correctly', async () => {
706+
const app = new Elysia().get('/', () => 'ok', {
707+
query: t.Object({
708+
key1: t.Union([t.Array(t.String()), t.String()])
709+
})
710+
})
711+
712+
const response = await Promise.all(
713+
[
714+
'/?key1=ab&key1=cd&z=が',
715+
'/?key1=ab&z=が',
716+
'/?key1=ab&key1=cd&z=x',
717+
'/?z=が&key1=ab&key1=cd',
718+
'/?key1=で&key1=が&z=x'
719+
].map((path) => app.handle(req(path)).then((x) => x.status))
720+
).then((responses) => responses.every((status) => status === 200))
721+
722+
expect(response).toBeTrue()
723+
})
724+
725+
// https://github.com/elysiajs/elysia/issues/912
726+
it('handle JavaScript date numeric offset', () => {
727+
const api = new Elysia().get('/', ({ query }) => query, {
728+
query: t.Object({
729+
date: t.Date()
730+
})
674731
})
732+
733+
api.handle(req(`/?date=${Date.now()}`))
734+
.then((x) => x.json())
735+
.then(console.log)
675736
})
676737
})

0 commit comments

Comments
 (0)