@svadmin/core 0.47.0 → 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/core",
3
- "version": "0.47.0",
3
+ "version": "0.47.1",
4
4
  "author": "zuohuadong",
5
5
  "repository": {
6
6
  "type": "git",
@@ -165,34 +165,7 @@ export function parseCSV(text: string): string[][] {
165
165
  return rows;
166
166
  }
167
167
 
168
- // ─── Universal Schema Validator Helper ──────────────────────────
169
-
170
- /**
171
- * Universal schema interface compatible with TypeBox, Standard Schema (v1), Valibot, Zod,
172
- * Yup, Joi, etc.
173
- */
174
- export interface SchemaValidatorLike {
175
- Check?: (value: unknown) => boolean;
176
- Errors?: (value: unknown) => Iterable<{ path?: string; message: string; schema?: unknown }>;
177
- safeParse?: (data: unknown) => {
178
- success: boolean;
179
- data?: unknown;
180
- error?: {
181
- issues?: Array<{ path?: Array<string | number>; message: string }>;
182
- errors?: Array<{ path?: Array<string | number>; message: string }>;
183
- };
184
- };
185
- parse?: (data: unknown) => unknown;
186
- validate?: (data: unknown) => {
187
- error?: {
188
- details?: Array<{ path?: Array<string | number>; message: string }>;
189
- message?: string;
190
- };
191
- };
192
- '~standard'?: {
193
- validate: (data: unknown) => unknown | Promise<unknown>;
194
- };
195
- }
168
+ // ─── TypeBox Validator Helper ───────────────────────────────────
196
169
 
197
170
  /**
198
171
  * TypeBox validator interface matching TypeCompiler.Compile or Value.Errors
@@ -202,134 +175,6 @@ export type TypeBoxValidatorLike = {
202
175
  Errors: (value: unknown) => Iterable<{ path?: string; message: string }>;
203
176
  };
204
177
 
205
- /**
206
- * Creates a synchronous form validator function from any TypeBox, Standard Schema v1,
207
- * Valibot, Zod, Yup, or Joi object.
208
- *
209
- * @example
210
- * ```ts
211
- * import { Type } from '@sinclair/typebox';
212
- * import { TypeCompiler } from '@sinclair/typebox/compiler';
213
- * import { createSchemaValidator, useForm } from '@svadmin/core';
214
- *
215
- * const userSchema = Type.Object({
216
- * name: Type.String({ minLength: 2 }),
217
- * email: Type.String({ format: 'email' }),
218
- * });
219
- *
220
- * const form = useForm({
221
- * resource: 'users',
222
- * validate: createSchemaValidator(TypeCompiler.Compile(userSchema)),
223
- * });
224
- * ```
225
- */
226
- export function createSchemaValidator(
227
- schema: SchemaValidatorLike | unknown
228
- ): (values: Record<string, unknown>) => Record<string, string> | null {
229
- if (!schema || typeof schema !== 'object') {
230
- return () => null;
231
- }
232
-
233
- const s = schema as SchemaValidatorLike;
234
-
235
- return (values: Record<string, unknown>) => {
236
- const errors: Record<string, string> = {};
237
-
238
- // 0. TypeBox TypeCompiler compiled validator (.Check & .Errors)
239
- if (typeof s.Check === 'function' && typeof s.Errors === 'function') {
240
- if (s.Check(values)) return null;
241
- for (const err of s.Errors(values)) {
242
- const rawPath = err.path || '';
243
- const cleanPath = rawPath.replace(/^\//, '').replace(/\//g, '.');
244
- const key = cleanPath || '_root';
245
- if (!errors[key]) errors[key] = err.message;
246
- }
247
- return Object.keys(errors).length > 0 ? errors : null;
248
- }
249
-
250
- // 0b. TypeBox Value.Errors iterator provider
251
- if (typeof s.Errors === 'function') {
252
- for (const err of s.Errors(values)) {
253
- const rawPath = err.path || '';
254
- const cleanPath = rawPath.replace(/^\//, '').replace(/\//g, '.');
255
- const key = cleanPath || '_root';
256
- if (!errors[key]) errors[key] = err.message;
257
- }
258
- return Object.keys(errors).length > 0 ? errors : null;
259
- }
260
-
261
- // 1. Standard Schema v1 (~standard)
262
- if (s['~standard'] && typeof s['~standard'].validate === 'function') {
263
- const res = s['~standard'].validate(values);
264
- if (res && typeof res === 'object' && 'issues' in res && Array.isArray((res as { issues?: Array<{ path?: Array<unknown>; message: string }> }).issues)) {
265
- for (const issue of (res as { issues: Array<{ path?: Array<unknown>; message: string }> }).issues) {
266
- const rawPath = issue.path?.[0];
267
- const key = typeof rawPath === 'object' && rawPath !== null && 'key' in rawPath
268
- ? String((rawPath as { key: unknown }).key)
269
- : rawPath != null
270
- ? String(rawPath)
271
- : '_root';
272
- if (!errors[key]) errors[key] = issue.message;
273
- }
274
- }
275
- return Object.keys(errors).length > 0 ? errors : null;
276
- }
277
-
278
- // 2. Zod / Valibot safeParse
279
- if (typeof s.safeParse === 'function') {
280
- const res = s.safeParse(values);
281
- if (!res.success && res.error) {
282
- const issues = res.error.issues ?? res.error.errors ?? [];
283
- for (const issue of issues) {
284
- const key = issue.path?.[0] != null ? String(issue.path[0]) : '_root';
285
- if (!errors[key]) errors[key] = issue.message;
286
- }
287
- }
288
- return Object.keys(errors).length > 0 ? errors : null;
289
- }
290
-
291
- // 3. Joi / generic .validate()
292
- if (typeof s.validate === 'function') {
293
- const res = s.validate(values);
294
- if (res && typeof res === 'object' && res.error) {
295
- const details = res.error.details;
296
- if (Array.isArray(details) && details.length > 0) {
297
- for (const d of details) {
298
- const key = d.path?.[0] != null ? String(d.path[0]) : '_root';
299
- if (!errors[key]) errors[key] = d.message;
300
- }
301
- } else if (res.error.message) {
302
- errors._root = res.error.message;
303
- }
304
- }
305
- return Object.keys(errors).length > 0 ? errors : null;
306
- }
307
-
308
- // 4. Synchronous .parse() that throws (e.g. standard Zod parse or Yup validateSync)
309
- if (typeof s.parse === 'function') {
310
- try {
311
- s.parse(values);
312
- } catch (err: unknown) {
313
- if (err && typeof err === 'object') {
314
- const issues = (err as { issues?: Array<{ path?: Array<string | number>; message: string }>; errors?: Array<{ path?: Array<string | number>; message: string }> }).issues ??
315
- (err as { errors?: Array<{ path?: Array<string | number>; message: string }> }).errors;
316
- if (Array.isArray(issues)) {
317
- for (const issue of issues) {
318
- const key = issue.path?.[0] != null ? String(issue.path[0]) : '_root';
319
- if (!errors[key]) errors[key] = issue.message;
320
- }
321
- } else if ('message' in err && typeof (err as { message: unknown }).message === 'string') {
322
- errors._root = (err as { message: string }).message;
323
- }
324
- }
325
- }
326
- return Object.keys(errors).length > 0 ? errors : null;
327
- }
328
-
329
- return null;
330
- };
331
- }
332
-
333
178
  /**
334
179
  * Creates a synchronous form validator function specifically optimized for TypeBox
335
180
  * compiled validators (from TypeCompiler.Compile) or TypeBox value checks.
@@ -354,7 +199,18 @@ export function createSchemaValidator(
354
199
  * ```
355
200
  */
356
201
  export function createTypeBoxValidator(
357
- compiledOrSchema: TypeBoxValidatorLike | SchemaValidatorLike | unknown
202
+ validator: TypeBoxValidatorLike
358
203
  ): (values: Record<string, unknown>) => Record<string, string> | null {
359
- return createSchemaValidator(compiledOrSchema);
204
+ return (values) => {
205
+ if (validator.Check?.(values)) return null;
206
+
207
+ const errors: Record<string, string> = {};
208
+ for (const error of validator.Errors(values)) {
209
+ const path = (error.path ?? '').replace(/^\//, '').replace(/\//g, '.');
210
+ const key = path || '_root';
211
+ if (!errors[key]) errors[key] = error.message;
212
+ }
213
+
214
+ return Object.keys(errors).length > 0 ? errors : null;
215
+ };
360
216
  }
package/src/helpers.ts CHANGED
@@ -8,10 +8,9 @@ export {
8
8
  getDefaultFilter, getDefaultSortOrder,
9
9
  unionFilters, unionSorters,
10
10
  file2Base64, parseCSV,
11
- createSchemaValidator,
12
11
  createTypeBoxValidator,
13
12
  } from './helpers-pure';
14
- export type { SchemaValidatorLike, TypeBoxValidatorLike } from './helpers-pure';
13
+ export type { TypeBoxValidatorLike } from './helpers-pure';
15
14
 
16
15
 
17
16
  // ─── Document Title Helper ────────────────────────────────────
@@ -61,7 +60,7 @@ export function generateDefaultDocumentTitle(options?: {
61
60
  * - `type === 'number'` fields (must be a valid number)
62
61
  * - Custom per-field `field.validate()` callback
63
62
  *
64
- * This eliminates the need for hand-written Zod schemas in most CRUD scenarios.
63
+ * This eliminates the need for hand-written schemas in most CRUD scenarios.
65
64
  *
66
65
  * @example
67
66
  * ```ts
package/src/index.ts CHANGED
@@ -203,10 +203,9 @@ export {
203
203
  unionFilters, unionSorters,
204
204
  file2Base64, generateDefaultDocumentTitle,
205
205
  deriveValidator,
206
- createSchemaValidator,
207
206
  createTypeBoxValidator,
208
207
  } from './helpers';
209
- export type { SchemaValidatorLike, TypeBoxValidatorLike } from './helpers';
208
+ export type { TypeBoxValidatorLike } from './helpers';
210
209
  export { TableState } from './table-state.svelte';
211
210
  export type { TableStateOptions } from './table-state.svelte';
212
211
  export type { UseInfiniteListOptions } from './hooks.svelte';