This commit is contained in:
saltyaom
2026-02-09 09:38:34 +07:00
parent 8acd13c283
commit 08c0cadbe1
6 changed files with 52 additions and 34 deletions
+5
View File
@@ -1,6 +1,11 @@
# 1.4.23
Bug fix:
- [#1700](https://github.com/elysiajs/elysia/issues/1700) distinct union object
- [#1683](https://github.com/elysiajs/elysia/pull/1683) response validation returns 500 instead of 422 for nested schemas in dynamic mode
Change:
- update exact-mirror to 0.2.7
# 1.4.22 - 14 Jan 2026
Improvement:
- use imperative check for `replaceURLPath` instead of allocating `new URL`
+3 -3
View File
@@ -6,7 +6,7 @@
"name": "elysia",
"dependencies": {
"cookie": "^1.1.1",
"exact-mirror": "^0.2.6",
"exact-mirror": "^0.2.7",
"fast-decode-uri-component": "^1.0.1",
"memoirist": "^0.4.0",
},
@@ -34,7 +34,7 @@
"peerDependencies": {
"@sinclair/typebox": ">= 0.34.0 < 1",
"@types/bun": ">= 1.2.0",
"exact-mirror": ">= 0.0.9",
"exact-mirror": "^0.2.6",
"file-type": ">= 20.0.0",
"openapi-types": ">= 12.0.0",
"typescript": ">= 5.0.0",
@@ -363,7 +363,7 @@
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"exact-mirror": ["exact-mirror@0.2.6", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-7s059UIx9/tnOKSySzUk5cPGkoILhTE4p6ncf6uIPaQ+9aRBQzQjc9+q85l51+oZ+P6aBxh084pD0CzBQPcFUA=="],
"exact-mirror": ["exact-mirror@0.2.7", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-+MeEmDcLA4o/vjK2zujgk+1VTxPR4hdp23qLqkWfStbECtAq9gmsvQa3LW6z/0GXZyHJobrCnmy1cdeE7BjsYg=="],
"expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="],
+16 -20
View File
@@ -1,24 +1,20 @@
import { Elysia, t } from '../src'
import { req } from '../test/utils'
const verifyToken = new Elysia()
.macro('verifyToken', {
headers: t.Object({
authorization: t.String()
}),
resolve({ headers }) {
// headers should be typed as { authorization: string }
// but TypeScript shows: Record<string, string | undefined>
const token = headers.authorization // Type is 'string | undefined', not 'string'
? headers.authorization.substring(7)
: undefined
return { token }
const app = new Elysia()
.get('/health', () => ({ status: 'healthy' }) as const, {
response: {
200: t.Union([
t.Object({
status: t.Literal('a'),
a: t.Object({ b: t.Integer() }) // <-- if you comment this line, you won't have an error
}),
t.Object({ status: t.Literal('healthy') })
])
}
})
.get(
'/',
({ token }) => {},
{
verifyToken: true
}
)
.listen(3000)
app.handle(req('/health'))
.then((x) => x.status)
.then(console.log)
+1 -1
View File
@@ -191,7 +191,7 @@
},
"dependencies": {
"cookie": "^1.1.1",
"exact-mirror": "^0.2.6",
"exact-mirror": "^0.2.7",
"fast-decode-uri-component": "^1.0.1",
"memoirist": "^0.4.0"
},
+6 -9
View File
@@ -8,7 +8,7 @@ import type {
import { StatusMap, InvertedStatusMap } from './utils'
import type { ElysiaTypeCheck } from './schema'
import { Prettify, StandardSchemaV1Like } from './types'
import { StandardSchemaV1Like } from './types'
// ? Cloudflare worker support
const env =
@@ -160,7 +160,7 @@ interface ValueErrorWithSummary extends ValueError {
summary?: string
}
export const mapValueError = (error: ValueError): ValueErrorWithSummary => {
export const mapValueError = (error: ValueError | undefined): ValueErrorWithSummary | undefined => {
if (!error) return error
let { message, path, value, type } = error
@@ -388,7 +388,7 @@ export class ValidationError extends Error {
// @ts-ignore private field
const schema = validator?.schema ?? validator
if (!isProduction && !allowUnsafeValidationDetails) {
if (!isProduction && !allowUnsafeValidationDetails)
try {
expected = Value.Create(schema)
} catch (error) {
@@ -399,7 +399,6 @@ export class ValidationError extends Error {
error
}
}
}
customError =
error?.schema?.message || error?.schema?.error !== undefined
@@ -418,7 +417,7 @@ export class ValidationError extends Error {
property: accessor,
message: error?.message,
summary:
mapValueError(error).summary,
mapValueError(error)?.summary,
found: value,
expected,
errors:
@@ -458,7 +457,7 @@ export class ValidationError extends Error {
on: type,
property: accessor,
message: error?.message,
summary: mapValueError(error).summary,
summary: mapValueError(error)?.summary,
expected,
found: value,
errors:
@@ -596,9 +595,7 @@ export class ValidationError extends Error {
on: this.type,
property: this.valueError?.path || 'root',
message,
summary: this.valueError
? mapValueError(this.valueError).summary
: undefined,
summary: mapValueError(this.valueError)?.summary,
found: value,
expected,
errors
+21 -1
View File
@@ -370,7 +370,7 @@ describe('Response Validator', () => {
})
it('return static undefined with status based schema', async () => {
const app = new Elysia().get('/', undefined, {
const app = new Elysia().get('/', undefined as any, {
response: {
200: t.Union([
t.Void(),
@@ -562,4 +562,24 @@ describe('Response Validator', () => {
expect(result.join('')).toContain('data: {"name":"Name"}')
})
it('handle distinct union', () => {
const app = new Elysia()
.get('/health', () => ({ status: 'healthy' }) as const, {
response: {
200: t.Union([
t.Object({
status: t.Literal('a'),
a: t.Object({ b: t.Integer() })
}),
t.Object({ status: t.Literal('healthy') })
])
}
})
.listen(3000)
const status = app.handle(req('/health')).then((x) => x.status)
expect(status).resolves.toBe(200)
})
})