ak-zod-form-kit
Version:
A powerful utility library for processing, transforming, and validating form data with Zod.
133 lines • 6.04 kB
TypeScript
import { ZodObject, ZodRawShape, ZodTypeAny } from 'zod';
import { SchemaModification, ValidationStrategy } from './types';
/**
* Crée un schéma Zod dynamique avec un contrôle précis de la validation.
*
* L'ordre des opérations est CRITIQUE :
* 1. D'abord les modifications structurelles (merge/union)
* 2. Ensuite les stratégies de validation
*
* @param baseSchema Schéma Zod de base
* @param inputData Données pour guider les champs dynamiques (optionnel)
* @param validationStrategy Stratégie de validation (défaut: "strict")
* @param schemaModification Modification structurelle (défaut: "default")
* @param additionalSchemas Schémas supplémentaires pour fusion (optionnel)
*
* @example
* // Cas de base : validation stricte
* // Accepte uniquement un objet avec un champ 'name' de type string.
* // Tout champ supplémentaire provoquera une erreur.
* const strictSchema = createDynamicZodSchema(
* z.object({ name: z.string() })
* );
*
* @example
* // Cas avec suppression des champs supplémentaires
* // Seuls les champs 'name' et 'age' seront conservés après validation.
* const removeExtraSchema = createDynamicZodSchema(
* z.object({ name: z.string(), age: z.number() }),
* {}, // inputData n'est pas pertinent ici
* "removeExtraFields"
* );
* // const parsedData = removeExtraSchema.parse({ name: "Alice", age: 30, extra: "field" });
* // console.log(parsedData); // { name: "Alice", age: 30 }
*
* @example
* // Cas avec autorisation des champs supplémentaires
* // Le schéma de base accepte 'name', mais 'inputData' contient 'id'.
* // Le schéma résultant acceptera 'name' et 'id' (typé comme unknown), et tout autre champ.
* const allowExtraSchema = createDynamicZodSchema(
* z.object({ name: z.string() }),
* { name: "Bob", id: 123 }, // inputData pour guider les champs dynamiques
* "allowExtraFields"
* );
* // const parsedData = allowExtraSchema.parse({ name: "Charlie", id: 456, other: "data" });
* // console.log(parsedData); // { name: "Charlie", id: 456, other: "data" }
*
* @example
* // Cas avec rendu partiel et strict ("partial-strict")
* // Permet à 'name' et 'email' d'être optionnels, mais rejette tout autre champ.
* const partialStrictSchema = createDynamicZodSchema(
* z.object({ name: z.string(), email: z.string().email() }),
* {},
* "partial-strict"
* );
* // const parsedData = partialStrictSchema.parse({ name: "David" }); // Valide
* // const parsedData = partialStrictSchema.parse({ email: "d@example.com" }); // Valide
* // try { partialStrictSchema.parse({ age: 25 }); } catch (e) { console.error(e); } // Erreur, 'age' est un champ extra
*
* @example
* // Cas avec rendu profondément partiel ("deepPartial")
* // Rend tous les champs, y compris les imbriqués, optionnels.
* const deepPartialSchema = createDynamicZodSchema(
* z.object({
* user: z.object({
* id: z.number(),
* profile: z.object({
* name: z.string(),
* age: z.number().optional()
* })
* })
* }),
* {},
* "deepPartial"
* );
* // const parsedData1 = deepPartialSchema.parse({ user: { profile: { name: "Eve" } } }); // Valide, 'id' et 'age' sont optionnels
* // const parsedData2 = deepPartialSchema.parse({ user: {} }); // Valide, tous les champs imbriqués sont optionnels
* // const parsedData3 = deepPartialSchema.parse({}); // Valide, tout est optionnel
*
* @example
* // Cas avec rendu partiel (non-récursif) ("partial")
* // Rend uniquement les champs de premier niveau optionnels.
* const partialSchema = createDynamicZodSchema(
* z.object({
* user: z.object({
* id: z.number(),
* profile: z.object({
* name: z.string(),
* age: z.number()
* })
* })
* }),
* {},
* "partial"
* );
* // const parsedData1 = partialSchema.parse({ user: { id: 1, profile: { name: "Frank", age: 30 } } }); // Valide
* // const parsedData2 = partialSchema.parse({ user: { profile: { name: "Grace", age: 25 } } }); // Valide, 'id' est manquant mais 'user' est optionnel
* // try { partialSchema.parse({ user: { id: 1, profile: { name: "Henry" } } }); } catch (e) { console.error(e); } // Erreur, 'age' est requis dans 'profile'
*
* @example
* // Cas de fusion avec logique ET ("mergeWithAnd")
* // Combine un schéma de base avec un ou plusieurs schémas supplémentaires.
* // Les données doivent satisfaire TOUS les schémas fusionnés.
* const schemaPart1 = z.object({ id: z.number() });
* const schemaPart2 = z.object({ name: z.string() });
* const mergedAndSchema = createDynamicZodSchema(
* schemaPart1,
* {},
* "strict", // La stratégie de validation s'applique au schéma fusionné
* "mergeWithAnd",
* [schemaPart2, z.object({ isActive: z.boolean() })]
* );
* // Ce schéma attendra { id: number, name: string, isActive: boolean }.
* // const parsedData = mergedAndSchema.parse({ id: 1, name: "Frank", isActive: true }); // Valide
* // try { mergedAndSchema.parse({ id: 1, name: "Frank" }); } catch (e) { console.error(e); } // Erreur, 'isActive' est manquant
*
* @example
* // Cas de fusion avec logique OU ("mergeWithOr")
* // Crée une union de schémas. Les données doivent satisfaire AU MOINS UN des schémas.
* const schemaOption1 = z.object({ type: z.literal("car"), wheels: z.number() });
* const schemaOption2 = z.object({ type: z.literal("boat"), sails: z.number() });
* const mergedOrSchema = createDynamicZodSchema(
* schemaOption1,
* {},
* "strict",
* "mergeWithOr",
* [schemaOption2]
* );
* // const parsedData1 = mergedOrSchema.parse({ type: "car", wheels: 4 }); // Valide
* // const parsedData2 = mergedOrSchema.parse({ type: "boat", sails: 1 }); // Valide
* // try { mergedOrSchema.parse({ type: "plane", wings: 2 }); } catch (e) { console.error(e); } // Erreur
*/
export declare function createDynamicZodSchema<T extends ZodRawShape>(baseSchema: ZodObject<T>, inputData?: Record<string, unknown>, validationStrategy?: ValidationStrategy, schemaModification?: SchemaModification, additionalSchemas?: ZodTypeAny[]): ZodTypeAny;
//# sourceMappingURL=createDynamicZodSchema.d.ts.map