{"version":3,"file":"zod.mjs","sources":["../../src/utils/zod.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport * as z from 'zod/v4';\n\nimport type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`\n * target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves\n * the conversion direction used before these defaults were pinned.\n */\nexport const OPENAPI_SCHEMA_CONVERSION_OPTIONS = {\n  target: 'draft-2020-12',\n  io: 'output',\n} as const satisfies Pick<z.core.RegistryToJSONSchemaParams, 'target' | 'io'>;\n\nconst ZOD_SHARED_BUCKET = '__shared';\n\n/**\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` (and close variants)\n * when an identified nested schema is missing from the conversion registry.\n */\nconst ZOD_SHARED_REF_RE = /^#\\/components\\/schemas\\/__shared#?\\/(?:\\$defs|definitions)\\/(.+)$/;\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n  return typeof value === 'object' && value !== null && Array.isArray(value) === false;\n};\n\n/**\n * Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.\n * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs\n * as registry IDs.\n */\nexport const stripJsonSchemaId = <T extends object>(schema: T): T => {\n  if ('$id' in schema) {\n    delete (schema as { $id?: string }).$id;\n  }\n  return schema;\n};\n\n/**\n * Generates a path string for referencing a component schema by its identifier.\n *\n * @param id - The identifier of the component schema.\n * @returns The constructed path string for the specified component schema.\n */\nexport const toComponentsPath = (id: string) => `#/components/schemas/${id}`;\n\nconst rewriteZodSharedRef = (ref: string): string => {\n  const match = ZOD_SHARED_REF_RE.exec(ref);\n  const id = match?.[1];\n\n  if (id === undefined || id.length === 0) {\n    return ref;\n  }\n\n  return toComponentsPath(id);\n};\n\nconst rewriteZodSharedRefs = (value: unknown, seen: WeakSet<object> = new WeakSet()): void => {\n  if (Array.isArray(value)) {\n    if (seen.has(value)) {\n      return;\n    }\n    seen.add(value);\n    for (const item of value) {\n      rewriteZodSharedRefs(item, seen);\n    }\n    return;\n  }\n\n  if (isPlainObject(value) === false) {\n    return;\n  }\n\n  if (seen.has(value)) {\n    return;\n  }\n  seen.add(value);\n\n  const ref = value.$ref;\n  if (typeof ref === 'string') {\n    value.$ref = rewriteZodSharedRef(ref);\n  }\n\n  for (const nested of Object.values(value)) {\n    rewriteZodSharedRefs(nested, seen);\n  }\n};\n\n/**\n * Moves Zod's sibling `__shared` bucket into named component schemas and rewrites\n * `$ref`s that targeted that bucket.\n *\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified\n * nested schema is not in the conversion registry. Those definitions must become\n * first-class `components.schemas` entries; `__shared` is never written out.\n *\n * @returns Named schemas lifted from `__shared` (after `$id` stripping). Route\n *   conversion copies these into the shared harvest bag so ComponentsWriter can\n *   merge them into the document.\n */\nexport const liftZodSharedDefinitions = (\n  schemas: Record<string, unknown>\n): Record<string, OpenAPIV3_1.SchemaObject> => {\n  const harvested: Record<string, OpenAPIV3_1.SchemaObject> = {};\n  const shared = schemas[ZOD_SHARED_BUCKET];\n\n  if (isPlainObject(shared)) {\n    const defs = shared.$defs ?? shared.definitions;\n\n    if (isPlainObject(defs)) {\n      for (const [id, def] of Object.entries(defs)) {\n        if (isPlainObject(def) === false) {\n          continue;\n        }\n\n        const cleaned = stripJsonSchemaId(def) as OpenAPIV3_1.SchemaObject;\n        harvested[id] = cleaned;\n\n        if (schemas[id] === undefined) {\n          schemas[id] = cleaned;\n        }\n      }\n    }\n\n    delete schemas[ZOD_SHARED_BUCKET];\n  }\n\n  const seen = new WeakSet<object>();\n  rewriteZodSharedRefs(schemas, seen);\n  rewriteZodSharedRefs(harvested, seen);\n\n  for (const schema of Object.values(schemas)) {\n    if (isPlainObject(schema)) {\n      stripJsonSchemaId(schema);\n    }\n  }\n\n  return harvested;\n};\n\nexport type ZodToOpenAPIOptions = {\n  /**\n   * Shared harvest bag filled with named schemas lifted from Zod's `__shared`\n   * bucket. Assemblers pass `context.registries.extractedComponentSchemas` so\n   * ComponentsWriter can merge them into `components.schemas`.\n   */\n  extractedComponentSchemas?: Record<string, OpenAPIV3_1.SchemaObject>;\n};\n\n/**\n * Converts a Zod schema to an OpenAPI Schema Object.\n *\n * @description\n * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).\n * It uses a local registry to handle the conversion process and generates the appropriate\n * OpenAPI components. Identified nested schemas that Zod would otherwise park in\n * `__shared` are rewritten to `#/components/schemas/<id>` and copied into\n * `options.extractedComponentSchemas` when that bag is provided.\n *\n * @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.\n * @param schemaStore - The application-owned content-API schema store to copy named\n *   component definitions from. Conversion uses a local registry and does not read a\n *   live Zod registry from the store.\n * @param options - Optional harvest bag shared across assemblers and ComponentsWriter.\n *\n * @returns An OpenAPI Schema Object representing the input Zod schema structure.\n * If the conversion cannot be completed, returns undefined.\n *\n * @example\n * ```typescript\n * import * as z from 'zod/v4';\n *\n * // Create a Zod schema\n * const userSchema = z.object({\n *   id: z.number(),\n *   name: z.string(),\n *   email: z.string().email()\n * });\n *\n * // Convert to OpenAPI schema\n * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);\n * ```\n */\nexport const zodToOpenAPI = (\n  zodSchema: z.ZodType,\n  schemaStore: Core.ContentAPISchemaRegistry,\n  options?: ZodToOpenAPIOptions\n): OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject => {\n  try {\n    const id = randomUUID();\n    const registry = z.registry<{ id: string }>();\n\n    // Add the schema to the local registry with a custom, unique ID\n    registry.add(zodSchema, { id });\n\n    // Copy Strapi-owned definitions into the local registry so references resolve without\n    // generating \"__shared\" definitions.\n    for (const [key, value] of schemaStore.entries()) {\n      registry.add(value, { id: key });\n    }\n\n    // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant\n    const { schemas } = z.toJSONSchema(registry, {\n      ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n      uri: toComponentsPath,\n    });\n\n    const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};\n\n    if (options?.extractedComponentSchemas !== undefined) {\n      Object.assign(options.extractedComponentSchemas, harvested);\n    }\n\n    // TODO: make sure it's compliant\n    return stripJsonSchemaId(schemas[id] as OpenAPIV3_1.SchemaObject);\n  } catch {\n    throw new Error(\"Couldn't transform the zod schema into an OpenAPI schema\");\n  }\n};\n"],"names":["OPENAPI_SCHEMA_CONVERSION_OPTIONS","target","io","ZOD_SHARED_BUCKET","ZOD_SHARED_REF_RE","isPlainObject","value","Array","isArray","stripJsonSchemaId","schema","$id","toComponentsPath","id","rewriteZodSharedRef","ref","match","exec","undefined","length","rewriteZodSharedRefs","seen","WeakSet","has","add","item","$ref","nested","Object","values","liftZodSharedDefinitions","schemas","harvested","shared","defs","$defs","definitions","def","entries","cleaned","zodToOpenAPI","zodSchema","schemaStore","options","randomUUID","registry","z","key","toJSONSchema","uri","extractedComponentSchemas","assign","Error"],"mappings":"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"}