Skip to content

Commit

Permalink
feat(vae): 新增 cast 方法
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 7, 2023
1 parent d17183d commit ef63d25
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 16 deletions.
77 changes: 61 additions & 16 deletions src/vae/VaeSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
moveToBottom,
pick,
set,
toArray,
toPlainObject,
values,
} from '../utils'
import { VaeArraySchema } from './VaeArraySchema'
Expand Down Expand Up @@ -89,6 +91,22 @@ export type VaeSchemaParseOptions = {
* @default false
*/
preserveUnknownKeys?: boolean

/**
* 是否 cast 模式
*
* @default false
*/
cast?: boolean
}

export type VaeSchemaCastOptions = {
/**
* 是否保留未知属性
*
* @default false
*/
preserveUnknownKeys?: boolean
}

export type VaeSchemaParseResult<T> =
Expand Down Expand Up @@ -361,22 +379,40 @@ export abstract class VaeSchema<T extends any = any> {
}
}
} else if (!fn(data)) {
ctx.addIssue({
path: fullPath,
message:
typeof message === 'function'
? message({
path: fullPath,
params: messageParams || {},
value: data,
label: this._options.label,
})
: message,
})
if (options.abortEarly) {
return {
success: false,
issues: ctx.issues,
if (options.cast) {
data = dataIsNil
? data
: this._options.type === 'string'
? String(data)
: this._options.type === 'number'
? Number(data)
: this._options.type === 'boolean'
? Boolean(data)
: this._options.type === 'date'
? new Date(data as any)
: this._options.type === 'array'
? toArray(data)
: this._options.type === 'object'
? toPlainObject(data)
: null
} else {
ctx.addIssue({
path: fullPath,
message:
typeof message === 'function'
? message({
path: fullPath,
params: messageParams || {},
value: data,
label: this._options.label,
})
: message,
})
if (options.abortEarly) {
return {
success: false,
issues: ctx.issues,
}
}
}
break
Expand Down Expand Up @@ -411,4 +447,13 @@ export abstract class VaeSchema<T extends any = any> {
// @ts-ignore
throw new VaeError(res.issues)
}

cast(data: any, options?: VaeSchemaCastOptions): any {
const res = this.parse(data, {
cast: true,
preserveUnknownKeys: options?.preserveUnknownKeys,
})
// @ts-ignore
return res.data
}
}
27 changes: 27 additions & 0 deletions src/vae/__snapshots__/vae.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,33 @@ Object {
}
`;

exports[`vae cast 1`] = `
Object {
"extra": Object {
"gender": undefined,
},
"id": undefined,
"images": Array [
"2",
],
"type": 2,
}
`;

exports[`vae cast 2`] = `
Object {
"ddd": 1,
"extra": Object {
"gender": undefined,
},
"id": 1,
"images": Array [
"2",
],
"type": 2,
}
`;

exports[`vae clone 1`] = `
Object {
"issues": Array [
Expand Down
40 changes: 40 additions & 0 deletions src/vae/vae.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,4 +631,44 @@ describe('vae', () => {
),
).toMatchSnapshot()
})

test('cast', () => {
const schema = v.object<{
id: number
images: string[]
extra: {
gender: number
}
type: number
}>({
id: v.number().required().id(),
images: v.array(a => a.required().element(v.string())),
extra: v.object({
gender: v.number().required().enum([0, 1]),
}),
type: v.number().enum([3, 4]),
})
expect(
schema.cast({
images: ['2'],
extra: {},
type: 2,
ddd: 1,
}),
).toMatchSnapshot()
expect(
schema.cast(
{
id: '1',
images: ['2'],
extra: {},
type: 2,
ddd: 1,
},
{
preserveUnknownKeys: true,
},
),
).toMatchSnapshot()
})
})

0 comments on commit ef63d25

Please sign in to comment.