|
1 | 1 | // Contrato API compartido (única fuente de verdad de los payloads del servidor). |
2 | 2 | // El frontend tipa contra estas mismas formas en app/src/data/types.ts. |
3 | | -import { z } from 'zod' |
4 | | - |
5 | | -export const dateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional() |
6 | | - |
7 | | -export const loginSchema = z.object({ |
8 | | - username: z.string().min(1), |
9 | | - password: z.string().min(1), |
10 | | -}) |
11 | | - |
12 | | -export const registerSchema = z.object({ |
13 | | - username: z.string().min(3).max(50), |
14 | | - password: z.string().min(6), |
15 | | - language: z.string().regex(/^(es|en|zh-CN)$/).optional(), |
16 | | - role: z.enum(['user', 'admin']).optional(), |
17 | | -}) |
18 | | - |
19 | | -export const profileSchema = z.object({ |
20 | | - email: z.string().email().optional().nullable(), |
21 | | - phone: z.string().optional().nullable(), |
22 | | - language: z.string().regex(/^(es|en|zh-CN)$/).optional(), |
23 | | -}) |
24 | | - |
25 | | -export const passwordSchema = z.object({ |
26 | | - current: z.string().min(1), |
27 | | - password: z.string().min(6), |
28 | | -}) |
29 | | - |
30 | | -export const historyQuerySchema = z.object({ |
31 | | - limit: z.coerce.number().int().min(1).max(1000).default(1000), |
32 | | - offset: z.coerce.number().int().min(0).default(0), |
33 | | -}) |
34 | | - |
35 | | -export const auditQuerySchema = z.object({ |
36 | | - limit: z.coerce.number().int().min(1).max(200).default(50), |
37 | | - offset: z.coerce.number().int().min(0).default(0), |
38 | | -}) |
39 | | - |
40 | | -export const adminPasswordSchema = z.object({ password: z.string().min(6) }) |
41 | | -export const adminLanguageSchema = z.object({ language: z.string().regex(/^(es|en|zh-CN)$/) }) |
42 | | -export const adminRoleSchema = z.object({ role: z.enum(['user', 'admin']) }) |
| 3 | +// Factory: recibe zod del consumidor (shared/ no tiene node_modules propio). |
| 4 | +export function createSchemas(z) { |
| 5 | + return { |
| 6 | + dateSchema: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), |
| 7 | + |
| 8 | + loginSchema: z.object({ |
| 9 | + username: z.string().min(1), |
| 10 | + password: z.string().min(1), |
| 11 | + }), |
| 12 | + |
| 13 | + registerSchema: z.object({ |
| 14 | + username: z.string().min(3).max(50), |
| 15 | + password: z.string().min(6), |
| 16 | + language: z.string().regex(/^(es|en|zh-CN)$/).optional(), |
| 17 | + role: z.enum(['user', 'admin']).optional(), |
| 18 | + }), |
| 19 | + |
| 20 | + profileSchema: z.object({ |
| 21 | + email: z.string().email().optional().nullable(), |
| 22 | + phone: z.string().optional().nullable(), |
| 23 | + language: z.string().regex(/^(es|en|zh-CN)$/).optional(), |
| 24 | + }), |
| 25 | + |
| 26 | + passwordSchema: z.object({ |
| 27 | + current: z.string().min(1), |
| 28 | + password: z.string().min(6), |
| 29 | + }), |
| 30 | + |
| 31 | + historyQuerySchema: z.object({ |
| 32 | + limit: z.coerce.number().int().min(1).max(1000).default(1000), |
| 33 | + offset: z.coerce.number().int().min(0).default(0), |
| 34 | + }), |
| 35 | + |
| 36 | + auditQuerySchema: z.object({ |
| 37 | + limit: z.coerce.number().int().min(1).max(200).default(50), |
| 38 | + offset: z.coerce.number().int().min(0).default(0), |
| 39 | + }), |
| 40 | + |
| 41 | + adminPasswordSchema: z.object({ password: z.string().min(6) }), |
| 42 | + adminLanguageSchema: z.object({ language: z.string().regex(/^(es|en|zh-CN)$/) }), |
| 43 | + adminRoleSchema: z.object({ role: z.enum(['user', 'admin']) }), |
| 44 | + } |
| 45 | +} |
0 commit comments