{"version":3,"file":"index-V304pPKn.cjs","sources":["../src/schemas/types.ts","../src/schemas/validators/index.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Tipos permitidos para los campos del schema de templates\n */\nexport const FieldTypeSchema = z.enum(['string', 'array_string', 'array_object']);\nexport type FieldType = z.infer<typeof FieldTypeSchema>;\n\n/**\n * Definición recursiva de un campo del schema\n *\n * Soporta hasta 2 niveles de anidación de array_object\n */\nexport const SchemaFieldSchema: z.ZodType<SchemaField> = z.lazy(() =>\n  z.object({\n    /** Clave del campo (nombre de la propiedad en el JSON de content) */\n    name: z.string().min(1, 'El nombre del campo no puede estar vacío'),\n\n    /** Etiqueta legible para mostrar al usuario */\n    label: z.string().min(1, 'El label del campo no puede estar vacío'),\n\n    /** Tipo de dato permitido */\n    type: FieldTypeSchema,\n\n    /** Indica si el campo es obligatorio */\n    required: z.boolean(),\n\n    /** Sub-campos solo cuando type es 'array_object' */\n    objectFields: z.array(SchemaFieldSchema).optional(),\n  }).refine(\n    (field) => {\n      // Si es array_object, debe tener objectFields\n      if (field.type === 'array_object') {\n        return field.objectFields && field.objectFields.length > 0;\n      }\n      // Si NO es array_object, no debe tener objectFields\n      return !field.objectFields;\n    },\n    {\n      message: 'array_object debe tener objectFields, otros tipos no deben tenerlo',\n    }\n  )\n);\n\nexport type SchemaField = {\n  name: string;\n  label: string;\n  type: FieldType;\n  required: boolean;\n  objectFields?: SchemaField[];\n};\n\n/**\n * Schema del template que define la estructura de campos\n */\nexport const TemplateSchemaSchema = z.object({\n  fields: z\n    .array(SchemaFieldSchema)\n    .min(1, 'El template debe tener al menos un campo')\n    .refine(\n      (fields) => {\n        // Validar que no haya nombres duplicados\n        const names = fields.map((f) => f.name);\n        return names.length === new Set(names).size;\n      },\n      {\n        message: 'No puede haber campos con nombres duplicados',\n      }\n    ),\n});\n\nexport type TemplateSchema = z.infer<typeof TemplateSchemaSchema>;\n\n/**\n * Definición completa de un Landing Page Template\n */\nexport const LandingPageTemplateSchema = z.object({\n  /** Nombre descriptivo del template */\n  name: z.string().min(1, 'El nombre del template no puede estar vacío'),\n\n  /** Slug único para identificar el template (formato kebab-case) */\n  slug: z\n    .string()\n    .min(1, 'El slug no puede estar vacío')\n    .regex(\n      /^[a-z0-9]+(-[a-z0-9]+)*$/,\n      'El slug debe estar en formato kebab-case (ej: \"hero-beneficios\")'\n    ),\n\n  /** Schema que define los campos requeridos */\n  schema: TemplateSchemaSchema,\n});\n\nexport type LandingPageTemplate = z.infer<typeof LandingPageTemplateSchema>;\n","import { z } from 'zod';\nimport {\n  SchemaFieldSchema,\n  LandingPageTemplateSchema,\n  type SchemaField,\n  type LandingPageTemplate,\n} from '../types';\n\n/**\n * Valida que un SchemaField cumpla con las reglas de negocio\n * @param field - Campo a validar\n * @param depth - Nivel de anidación (0 = raíz, 1 = primer nivel, etc.)\n * @throws {z.ZodError} Si el campo no es válido\n */\nexport function validateSchemaField(field: SchemaField, depth: number = 0): void {\n  // Validación base con Zod\n  SchemaFieldSchema.parse(field);\n\n  // Límite de anidación: máximo 2 niveles de array_object\n  const maxDepth = 2;\n\n  if (field.type === 'array_object' && field.objectFields) {\n    field.objectFields.forEach((subField) => {\n      if (subField.type === 'array_object' && depth >= maxDepth) {\n        throw new Error(\n          `Campo \"${field.name}.${subField.name}\" excede el límite de anidación (máximo ${maxDepth} niveles de array_object)`\n        );\n      }\n      validateSchemaField(subField, depth + 1);\n    });\n  }\n}\n\n/**\n * Valida que un LandingPageTemplate sea correcto\n * @param template - Template a validar\n * @throws {z.ZodError} Si el template no es válido\n */\nexport function validateTemplate(template: LandingPageTemplate): void {\n  // Validación base con Zod\n  LandingPageTemplateSchema.parse(template);\n\n  // Validar cada campo con reglas de anidación\n  template.schema.fields.forEach((field) => validateSchemaField(field));\n}\n\n/**\n * Valida el content de una landing page contra el schema del template\n *\n * Esta función genera dinámicamente un schema de Zod basado en el template\n * y valida que el content cumpla con la estructura esperada.\n *\n * @param content - El contenido a validar (JSON)\n * @param template - El template que define la estructura esperada\n * @returns El content validado y tipado\n * @throws {z.ZodError} Si el content no cumple con el schema\n */\nexport function validateContent<T = unknown>(\n  content: unknown,\n  template: LandingPageTemplate\n): T {\n  const contentSchema = generateContentSchema(template.schema.fields);\n  return contentSchema.parse(content) as T;\n}\n\n/**\n * Genera un schema de Zod dinámicamente basado en los campos del template\n *\n * @param fields - Array de SchemaField del template\n * @returns Schema de Zod para validar el content\n */\nfunction generateContentSchema(fields: SchemaField[]): z.ZodObject<any> {\n  const shape: Record<string, z.ZodTypeAny> = {};\n\n  for (const field of fields) {\n    let fieldSchema: z.ZodTypeAny;\n\n    switch (field.type) {\n      case 'string':\n        fieldSchema = z.string();\n        break;\n\n      case 'array_string':\n        fieldSchema = z.array(z.string());\n        break;\n\n      case 'array_object':\n        if (!field.objectFields || field.objectFields.length === 0) {\n          throw new Error(\n            `Campo \"${field.name}\" es array_object pero no tiene objectFields`\n          );\n        }\n        fieldSchema = z.array(generateContentSchema(field.objectFields));\n        break;\n\n      default:\n        throw new Error(`Tipo de campo desconocido: ${field.type}`);\n    }\n\n    // Si el campo no es requerido, hacerlo opcional\n    shape[field.name] = field.required ? fieldSchema : fieldSchema.optional();\n  }\n\n  return z.object(shape);\n}\n\n/**\n * Valida el content de forma segura sin lanzar errores\n *\n * @param content - El contenido a validar\n * @param template - El template que define la estructura\n * @returns Objeto con { success: boolean, data?: T, error?: z.ZodError }\n */\nexport function safeValidateContent<T = unknown>(\n  content: unknown,\n  template: LandingPageTemplate\n): { success: true; data: T } | { success: false; error: z.ZodError } {\n  try {\n    const data = validateContent<T>(content, template);\n    return { success: true, data };\n  } catch (error) {\n    if (error instanceof z.ZodError) {\n      return { success: false, error };\n    }\n    throw error;\n  }\n}\n"],"names":["FieldTypeSchema","z","SchemaFieldSchema","field","TemplateSchemaSchema","fields","names","f","LandingPageTemplateSchema","validateSchemaField","depth","maxDepth","subField","validateTemplate","template","validateContent","content","generateContentSchema","shape","fieldSchema","safeValidateContent","error"],"mappings":"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"}