Skip to content

Commit 359ef9e

Browse files
committed
refactor(form): remove unnecessary standard and Yup resolvers, optimize ZodResolver usage
1 parent e23682f commit 359ef9e

File tree

10 files changed

+75
-268
lines changed

10 files changed

+75
-268
lines changed

playground/src/app/(demo)/form/modules/ZodResolver.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

3-
import { useEffect } from 'react';
4-
import { Button, Card, Form, FormField, Input, createStandardResolver, useForm } from 'soybean-react-ui';
3+
import { Button, Card, Form, FormField, Input, useForm } from 'soybean-react-ui';
54
import { z } from 'zod';
65

76
// Define Zod Schema
@@ -32,16 +31,13 @@ const initialValues: Inputs = {
3231
const ZodResolverDemo = () => {
3332
const [form] = useForm<Inputs>();
3433

35-
useEffect(() => {
36-
form.use(createStandardResolver(zodSchema));
37-
}, [form]);
38-
3934
return (
4035
<Card title="Form with ZodResolver">
4136
<Form
4237
className="w-[480px] max-sm:w-full space-y-4"
4338
form={form}
4439
initialValues={initialValues}
40+
schema={zodSchema}
4541
>
4642
<FormField
4743
label="Username"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Middleware } from '../middleware';
2+
3+
import type { StandardSchemaV1, StandardSchemaV1NormalizedIssue } from './standard';
4+
import { createStandardResolver, isStandardSchema } from './standard';
5+
import { createGenericResolver } from './utils';
6+
7+
export type FormSchema<Values = any> =
8+
| StandardSchemaV1<Values>
9+
| ((state: Values, name: string | string[] | undefined) => Promise<StandardSchemaV1NormalizedIssue[]>);
10+
11+
function noopMiddleware<Values = any>(): Middleware<Values> {
12+
return () => next => action => next(action);
13+
}
14+
15+
export function resolveSchema<Values = any>(schema: FormSchema<Values>): Middleware<Values> {
16+
if (isStandardSchema(schema)) {
17+
return createStandardResolver(schema);
18+
}
19+
20+
if (typeof schema === 'function') {
21+
return createGenericResolver(schema);
22+
}
23+
24+
console.warn('[resolveSchema] Unsupported schema type, ignored:', schema);
25+
26+
return noopMiddleware();
27+
}

primitives/filed-form /src/form-core/resolver/standard.ts

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
/* eslint-disable consistent-return */
2-
import type { AllPathsKeys } from 'skyroc-type-utils';
32

4-
import { keyOfName } from '../../utils/util';
5-
import type { Middleware } from '../middleware';
6-
7-
import { dispatchIssues } from './utils';
3+
import { createGenericResolver } from './utils';
84

95
/**
106
* The Standard Schema interface.
@@ -113,59 +109,31 @@ interface StandardSchemaV1PathSegment {
113109
readonly key: PropertyKey;
114110
}
115111

116-
function isStandardSchema(obj: any): obj is StandardSchemaV1 {
112+
export function isStandardSchema(obj: any): obj is StandardSchemaV1 {
117113
return obj && obj['~standard'] && typeof obj['~standard'].validate === 'function';
118114
}
119115

120116
/**
121117
* Standard Schema Resolver
122118
* 支持 sync/async validate,同时处理 validateField 和 validateFields
123119
*/
124-
export function createStandardResolver<Values = any>(
125-
schema: StandardSchemaV1<Values, unknown>
126-
): Middleware<Values, AllPathsKeys<Values>> {
127-
if (!isStandardSchema(schema)) {
128-
throw new Error('Invalid StandardSchema object');
129-
}
130-
131-
return ({ dispatch, getState }) =>
132-
next =>
133-
async action => {
134-
if (action.type !== 'validateField' && action.type !== 'validateFields') {
135-
return next(action);
136-
}
137-
138-
const state = getState();
139-
const result = await Promise.resolve(schema['~standard'].validate(state));
140-
141-
console.log('result', result);
142-
143-
if (!('issues' in result)) {
144-
// ✅ 没有错误,清空所有
145-
dispatch({ entries: [], type: 'setExternalErrors' });
146-
return;
147-
}
148-
149-
// 把 issues 转成统一格式
150-
const issues: StandardSchemaV1NormalizedIssue[] =
151-
result.issues?.map(issue => ({
152-
message: issue.message,
153-
path: issue.path?.map(seg => (typeof seg === 'object' && 'key' in seg ? String(seg.key) : String(seg))) || []
154-
})) || [];
155120

156-
// === validateField ===
157-
if (action.type === 'validateField') {
158-
const name = keyOfName(action.name);
121+
export function createStandardResolver<Values = any>(schema: StandardSchemaV1<Values>) {
122+
return createGenericResolver<Values>(async state => {
123+
const result = await Promise.resolve(schema['~standard'].validate(state));
159124

160-
const filtered = issues.filter(it => it.path?.join('.') === name || (it.path?.length === 0 && name === 'root'));
125+
if (!('issues' in result)) return [];
161126

162-
dispatchIssues<Values>(dispatch, filtered);
163-
return;
164-
}
127+
const issues = result.issues?.map(issue => {
128+
const path = issue.path
129+
? issue.path.map(seg => (typeof seg === 'object' && 'key' in seg ? String(seg.key) : String(seg)))
130+
: [];
131+
return {
132+
message: issue.message,
133+
path
134+
};
135+
});
165136

166-
// === validateFields ===
167-
if (action.type === 'validateFields') {
168-
dispatchIssues<Values>(dispatch, issues);
169-
}
170-
};
137+
return issues || [];
138+
});
171139
}

primitives/filed-form /src/form-core/resolver/utils.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,36 @@ export function dispatchIssues<Values = any>(
2828
dispatch({ entries, type: 'setExternalErrors' });
2929
}
3030

31-
/**
32-
* 工厂函数:生成通用 resolver
33-
*/
34-
export function createGenericResolver(
35-
validate: (state: any, name?: string | string[]) => Promise<StandardSchemaV1NormalizedIssue[]>
36-
): Middleware {
31+
export function createGenericResolver<Values = any>(
32+
validate: (state: Values, name?: string | string[]) => Promise<StandardSchemaV1NormalizedIssue[]>
33+
): Middleware<Values> {
3734
return ({ dispatch, getState }) =>
3835
next =>
3936
async action => {
40-
if (action.type === 'validateField' || action.type === 'validateFields') {
41-
const issues = await validate(getState(), action.name);
37+
if (action.type !== 'validateField' && action.type !== 'validateFields') {
38+
return next(action);
39+
}
4240

43-
dispatchIssues(dispatch, issues);
41+
const state = getState();
42+
43+
if (action.type === 'validateField') {
44+
const name = keyOfName(action.name) as AllPathsKeys<Values>;
45+
const issues = await validate(state, name);
46+
47+
const filtered = issues.filter(it => it.path.join('.') === name);
48+
49+
if (filtered.length > 0) {
50+
dispatchIssues(dispatch, filtered);
51+
} else {
52+
dispatch({ entries: [[name, []]], type: 'setExternalErrors' });
53+
}
4454

4555
return;
4656
}
4757

48-
return next(action);
58+
if (action.type === 'validateFields') {
59+
const issues = await validate(state, action.name?.map(keyOfName));
60+
dispatchIssues(dispatch, issues);
61+
}
4962
};
5063
}

primitives/filed-form /src/form-core/resolver/yup.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

primitives/filed-form /src/form-core/resolver/zod.ts

Lines changed: 0 additions & 14 deletions
This file was deleted.

primitives/filed-form /src/form-core/resolvers.ts

Lines changed: 0 additions & 115 deletions
This file was deleted.

primitives/filed-form /src/form-core/schemaResolvers.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)