{"version":3,"file":"utils.mjs","sources":["../../../../src/core-api/routes/validation/utils.ts"],"sourcesContent":["import { transformUidToValidOpenApiName } from '@strapi/utils';\nimport type { Internal } from '@strapi/types';\nimport * as z from 'zod/v4';\n\n// Schema generation happens on-demand when schemas don't exist in the registry\n\n/**\n * Safely adds or updates a schema in Zod's global registry.\n *\n * If a schema with the given `id` already exists, it will be removed before adding the new one.\n *\n * This is useful for hot-reloading or preventing issues with cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param schema - The Zod schema to register.\n * @example\n * ```typescript\n * safeGlobalRegistrySet(\"mySchema\", z.object({ name: z.string() }));\n * ```\n */\nexport const safeGlobalRegistrySet = (id: Internal.UID.Schema, schema: z.ZodType) => {\n  try {\n    const { _idmap: idMap } = z.globalRegistry;\n\n    const transformedId = transformUidToValidOpenApiName(id);\n\n    const isReplacing = idMap.has(transformedId);\n\n    if (isReplacing) {\n      // Remove existing schema to prevent conflicts\n      idMap.delete(transformedId);\n    }\n\n    // Register the new schema with the transformed ID\n    strapi.log.debug(\n      `${isReplacing ? 'Replacing' : 'Registering'} schema ${transformedId} in global registry`\n    );\n    z.globalRegistry.add(schema, { id: transformedId });\n  } catch (error) {\n    strapi.log.error(\n      `Schema registration failed: Failed to register schema ${id} in global registry`\n    );\n\n    throw error;\n  }\n};\n\n/**\n * Safely creates and registers a Zod schema in the global registry, particularly useful for handling cyclical data structures.\n *\n * If a schema with the given `id` already exists in the global registry, it returns the existing schema.\n *\n * Otherwise, it registers a temporary `z.any()` schema, calls the provided `callback` to create the actual schema,\n * and then replaces the temporary schema with the actual one in the registry.\n *\n * This prevents infinite loops in cases of cyclical dependencies.\n *\n * @param id - The unique identifier for the schema in the global registry.\n * @param callback - A function that returns the Zod schema to be created and registered.\n * @returns The created or retrieved Zod schema.\n * @example\n * ```typescript\n * const CategorySchema = safeSchemaCreation(\"Category\", () =>\n *   z.object({\n *     name: z.string(),\n *     products: z.array(safeSchemaCreation(\"Product\", () =>\n *       z.object({\n *         name: z.string(),\n *         category: z.lazy(() => CategorySchema) // Cyclical reference\n *       })\n *     ))\n *   })\n * );\n * ```\n */\nexport const safeSchemaCreation = (id: Internal.UID.Schema, callback: () => z.ZodType) => {\n  try {\n    const { _idmap: idMap } = z.globalRegistry;\n\n    const transformedId = transformUidToValidOpenApiName(id);\n\n    // Return existing schema if already registered\n    const mapItem = idMap.get(transformedId);\n    if (mapItem) {\n      // Schema already exists, return it silently\n      return mapItem;\n    }\n\n    strapi.log.debug(`Schema ${transformedId} not found in registry, generating new schema`);\n\n    // Determine if this is a built-in schema or user content\n    const isBuiltInSchema = id.startsWith('plugin::') || id.startsWith('admin');\n\n    if (isBuiltInSchema) {\n      // Built-in schemas keep at debug level to avoid clutter\n      strapi.log.debug(`Initializing validation schema for ${transformedId}`);\n    } else {\n      // User content\n      const schemaName = transformedId\n        .replace('Document', '')\n        .replace('Entry', '')\n        .replace(/([A-Z])/g, ' $1')\n        .trim();\n      strapi.log.debug(`📝 Generating validation schema for \"${schemaName}\"`);\n    }\n\n    // Temporary any placeholder before replacing with the actual schema type\n    // Used to prevent infinite loops in cyclical data structures\n    safeGlobalRegistrySet(id, z.any());\n\n    // Generate the actual schema using the callback\n    const schema = callback();\n\n    // Replace the placeholder with the real schema\n    safeGlobalRegistrySet(id, schema);\n\n    // Show completion for user content only\n    if (!isBuiltInSchema) {\n      const fieldCount = Object.keys((schema as any)?._def?.shape || {}).length || 0;\n      const schemaName = transformedId\n        .replace('Document', '')\n        .replace('Entry', '')\n        .replace(/([A-Z])/g, ' $1')\n        .trim();\n      strapi.log.debug(`   ✅ \"${schemaName}\" schema created with ${fieldCount} fields`);\n    }\n\n    return schema;\n  } catch (error) {\n    strapi.log.error(`Schema creation failed: Failed to create schema ${id}`);\n\n    throw error;\n  }\n};\n"],"names":["safeGlobalRegistrySet","id","schema","_idmap","idMap","z","globalRegistry","transformedId","transformUidToValidOpenApiName","isReplacing","has","delete","strapi","log","debug","add","error","safeSchemaCreation","callback","mapItem","get","isBuiltInSchema","startsWith","schemaName","replace","trim","any","fieldCount","Object","keys","_def","shape","length"],"mappings":"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"}