51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import { z } from 'zod';
|
|
import { CODE_TYPES } from './codeTypes.js';
|
|
import { ROLES } from './models.js';
|
|
|
|
export const colorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, 'Color must be #RRGGBB');
|
|
|
|
export const cardFieldsSchema = z.object({
|
|
name: z.string().trim().min(1, 'Name is required').max(200),
|
|
color: colorSchema,
|
|
code: z.string().min(1, 'Code is required').max(4000),
|
|
codeType: z.enum(CODE_TYPES),
|
|
// Free text, may be multiline. No default: partial updates must not clear it.
|
|
// Multipart forms send CRLF line breaks: store plain LF.
|
|
comment: z
|
|
.string()
|
|
.transform((s) => s.replace(/\r\n?/g, '\n').trim())
|
|
.pipe(z.string().max(2000, 'Comment is too long (max 2000 characters)'))
|
|
.optional(),
|
|
});
|
|
export type CardFields = z.infer<typeof cardFieldsSchema>;
|
|
|
|
export const cardPatchSchema = cardFieldsSchema.partial().extend({
|
|
deleted: z.boolean().optional(),
|
|
});
|
|
export type CardPatch = z.infer<typeof cardPatchSchema>;
|
|
|
|
export const emailSchema = z.string().trim().toLowerCase().pipe(z.email());
|
|
|
|
export const groupInputSchema = z.object({
|
|
name: z.string().trim().min(1, 'Name is required').max(100),
|
|
});
|
|
|
|
export const userCreateSchema = z.object({
|
|
email: emailSchema,
|
|
role: z.enum(ROLES).default('user'),
|
|
groupId: z.string().optional(),
|
|
});
|
|
|
|
export const userPatchSchema = z.object({
|
|
role: z.enum(ROLES).optional(),
|
|
groupId: z.string().optional(),
|
|
});
|
|
|
|
export const keyCreateSchema = z.object({
|
|
label: z.string().trim().max(100).optional(),
|
|
});
|
|
|
|
export const currentGroupSchema = z.object({
|
|
groupId: z.string().min(1),
|
|
});
|