mirror of
https://github.com/zoriya/typebox.git
synced 2025-12-06 06:46:10 +00:00
Union ValueError Iterator (#1015)
* feat: attach to ValueError the first error of each Union.anyOf visit * chore: small tweak * test: add test * chore: tweak test * fix: flatten nested union errors * feat: expose variant errors as ValueErrorIterator[] * feat: use a single ValueErrorIterator instance * update tests * implement requested changes * update test * update ErrorFunctionParameter * small fix
This commit is contained in:
@@ -34,6 +34,7 @@ import { GetErrorFunction } from './function'
|
||||
import { TypeBoxError } from '../type/error/index'
|
||||
import { Deref } from '../value/deref/index'
|
||||
import { Hash } from '../value/hash/index'
|
||||
import { Check } from '../value/check/index'
|
||||
import { Kind } from '../type/symbols/index'
|
||||
|
||||
import type { TSchema } from '../type/schema/index'
|
||||
@@ -167,6 +168,7 @@ export interface ValueError {
|
||||
path: string
|
||||
value: unknown
|
||||
message: string
|
||||
errors: ValueErrorIterator[]
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// ValueErrors
|
||||
@@ -205,8 +207,15 @@ export class ValueErrorIterator {
|
||||
// --------------------------------------------------------------------------
|
||||
// Create
|
||||
// --------------------------------------------------------------------------
|
||||
function Create(errorType: ValueErrorType, schema: TSchema, path: string, value: unknown): ValueError {
|
||||
return { type: errorType, schema, path, value, message: GetErrorFunction()({ errorType, path, schema, value }) }
|
||||
function Create(errorType: ValueErrorType, schema: TSchema, path: string, value: unknown, errors: ValueErrorIterator[] = []): ValueError {
|
||||
return {
|
||||
type: errorType,
|
||||
schema,
|
||||
path,
|
||||
value,
|
||||
message: GetErrorFunction()({ errorType, path, schema, value, errors }),
|
||||
errors,
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------------
|
||||
// Types
|
||||
@@ -516,15 +525,9 @@ function* FromUndefined(schema: TUndefined, references: TSchema[], path: string,
|
||||
if (!IsUndefined(value)) yield Create(ValueErrorType.Undefined, schema, path, value)
|
||||
}
|
||||
function* FromUnion(schema: TUnion, references: TSchema[], path: string, value: any): IterableIterator<ValueError> {
|
||||
let count = 0
|
||||
for (const subschema of schema.anyOf) {
|
||||
const errors = [...Visit(subschema, references, path, value)]
|
||||
if (errors.length === 0) return // matched
|
||||
count += errors.length
|
||||
}
|
||||
if (count > 0) {
|
||||
yield Create(ValueErrorType.Union, schema, path, value)
|
||||
}
|
||||
if (Check(schema, references, value)) return
|
||||
const errors = schema.anyOf.map((variant) => new ValueErrorIterator(Visit(variant, references, path, value)))
|
||||
yield Create(ValueErrorType.Union, schema, path, value, errors)
|
||||
}
|
||||
function* FromUint8Array(schema: TUint8Array, references: TSchema[], path: string, value: any): IterableIterator<ValueError> {
|
||||
if (!IsUint8Array(value)) return yield Create(ValueErrorType.Uint8Array, schema, path, value)
|
||||
|
||||
@@ -28,7 +28,7 @@ THE SOFTWARE.
|
||||
|
||||
import { TSchema } from '../type/schema/index'
|
||||
import { Kind } from '../type/symbols/index'
|
||||
import { ValueErrorType } from './errors'
|
||||
import { ValueErrorIterator, ValueErrorType } from './errors'
|
||||
|
||||
/** Creates an error message using en-US as the default locale */
|
||||
export function DefaultErrorFunction(error: ErrorFunctionParameter) {
|
||||
@@ -178,6 +178,8 @@ export type ErrorFunctionParameter = {
|
||||
schema: TSchema
|
||||
/** The value associated with the error */
|
||||
value: unknown
|
||||
/** Interior errors for this error */
|
||||
errors: ValueErrorIterator[]
|
||||
}
|
||||
export type ErrorFunction = (parameter: ErrorFunctionParameter) => string
|
||||
/** Manages error message providers */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@sinclair/typebox'
|
||||
import { ValueErrorType } from '@sinclair/typebox/errors'
|
||||
import { ValueErrorIterator, ValueErrorType } from '@sinclair/typebox/errors'
|
||||
import { Resolve } from './resolve'
|
||||
import { Assert } from '../../assert'
|
||||
|
||||
@@ -17,5 +17,7 @@ describe('errors/type/Union', () => {
|
||||
const R = Resolve(T, true)
|
||||
Assert.IsEqual(R.length, 1)
|
||||
Assert.IsEqual(R[0].type, ValueErrorType.Union)
|
||||
Assert.IsEqual(R[0].errors[0].First()?.type, ValueErrorType.String)
|
||||
Assert.IsEqual(R[0].errors[1].First()?.type, ValueErrorType.Number)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user