{
  "$schema": "https://hyperjs.ai/schema/registry-item.json",
  "name": "openapi-zod",
  "version": "0.1.0",
  "description": "SchemaConverter for Zod (v3 + v4) to @hyper/openapi.",
  "readme": "# @hyper/openapi-zod\n\nZod (v3 + v4) `SchemaConverter` for `@hyper/openapi`.\n\n## Install\n\nComponents are installed as source into your repo, not pulled from npm. `zod` is added to your `package.json` automatically as a peer dependency.\n\n```bash\nbunx hyper add openapi openapi-zod\n```\n\n## Usage\n\n```ts\nimport { Hyper } from \"@hyper/core\"\nimport { openapiPlugin } from \"@hyper/openapi\"\nimport { zodConverter } from \"@hyper/openapi-zod\"\n\nexport default new Hyper()\n  .use(openapiPlugin({ converter: zodConverter }))\n  .listen(3000)\n```\n\n## Docs\n\nSee the [main README](../../README.md) and [docs/](../../docs) for guides and integration recipes.\n\n## License\n\nMIT\n",
  "registryDeps": [
    "openapi"
  ],
  "peerDeps": {},
  "optionalPeerDeps": {},
  "files": [
    {
      "path": "openapi-zod/index.ts",
      "contents": "/**\n * @hyper/openapi-zod — SchemaConverter that understands Zod v3 and v4.\n *\n *   import { zodConverter } from \"@hyper/openapi-zod\"\n *   openapiHandlers(app, { converters: [zodConverter] })\n *\n * Detection:\n *  - Zod schemas expose `_def.typeName` (v3) or `_def.type` (v4).\n *  - We sniff structurally so Zod isn't required at import-time.\n *\n * This converter does not rely on `zod-to-json-schema`; it walks `_def`\n * directly for the subset of types we care about (object / array / string\n * / number / boolean / enum / union / optional / nullable / default).\n */\n\nimport type { JsonSchema, SchemaConverter } from \"@hyper/openapi\"\n\ninterface ZodLike {\n  readonly _def: ZodDef\n  readonly parse?: (...a: unknown[]) => unknown\n  readonly safeParse?: (...a: unknown[]) => unknown\n}\n\ninterface ZodDef {\n  readonly typeName?: string\n  readonly type?: string\n  readonly [k: string]: unknown\n}\n\nfunction isZod(s: unknown): s is ZodLike {\n  if (!s || typeof s !== \"object\") return false\n  const x = s as { _def?: unknown; parse?: unknown; safeParse?: unknown }\n  if (!x._def || typeof x._def !== \"object\") return false\n  return typeof x.parse === \"function\" || typeof x.safeParse === \"function\"\n}\n\nfunction defName(def: ZodDef): string | undefined {\n  return (def.typeName ?? def.type) as string | undefined\n}\n\nfunction toJson(schema: ZodLike): JsonSchema {\n  const def = schema._def\n  const name = defName(def)\n  switch (name) {\n    case \"ZodString\":\n    case \"string\":\n      return { type: \"string\" }\n    case \"ZodNumber\":\n    case \"number\":\n      return { type: \"number\" }\n    case \"ZodBoolean\":\n    case \"boolean\":\n      return { type: \"boolean\" }\n    case \"ZodLiteral\":\n    case \"literal\":\n      return { const: (def as { value: unknown }).value }\n    case \"ZodEnum\":\n    case \"enum\": {\n      const v = def as { values?: readonly unknown[]; entries?: Record<string, unknown> }\n      const values = v.values ?? (v.entries ? Object.values(v.entries) : [])\n      return { enum: values }\n    }\n    case \"ZodArray\":\n    case \"array\": {\n      const v = def as { type?: ZodLike; element?: ZodLike }\n      const inner = v.type ?? v.element\n      return { type: \"array\", ...(inner && { items: toJson(inner) }) }\n    }\n    case \"ZodObject\":\n    case \"object\": {\n      const shapeFn = (def as { shape?: () => Record<string, ZodLike> }).shape\n      const shape =\n        typeof shapeFn === \"function\"\n          ? shapeFn()\n          : ((def as { shape?: Record<string, ZodLike> }).shape ?? {})\n      const properties: Record<string, JsonSchema> = {}\n      const required: string[] = []\n      for (const [k, v] of Object.entries(shape)) {\n        const inner = toJson(v)\n        properties[k] = inner\n        const innerName = defName(v._def)\n        if (innerName !== \"ZodOptional\" && innerName !== \"optional\") required.push(k)\n      }\n      return {\n        type: \"object\",\n        properties,\n        ...(required.length > 0 && { required }),\n      }\n    }\n    case \"ZodOptional\":\n    case \"optional\": {\n      const inner = (def as { innerType: ZodLike }).innerType\n      return toJson(inner)\n    }\n    case \"ZodNullable\":\n    case \"nullable\": {\n      const inner = (def as { innerType: ZodLike }).innerType\n      const j = toJson(inner)\n      const t = j.type\n      return { ...j, type: Array.isArray(t) ? [...t, \"null\"] : t ? [t as string, \"null\"] : \"null\" }\n    }\n    case \"ZodDefault\":\n    case \"default\": {\n      const inner = (def as { innerType: ZodLike }).innerType\n      return { ...toJson(inner), default: (def as { defaultValue?: unknown }).defaultValue }\n    }\n    case \"ZodUnion\":\n    case \"union\": {\n      const options = (def as { options: readonly ZodLike[] }).options\n      return { anyOf: options.map(toJson) }\n    }\n    default:\n      return {}\n  }\n}\n\nexport const zodConverter: SchemaConverter = {\n  name: \"zod\",\n  canHandle: isZod,\n  toJsonSchema: (s) => toJson(s as ZodLike),\n}\n",
      "sha256": "fc3d5db756dd6ca5d1827b63657b956d043e5df1fbac7bdaac7d8888f1863c18"
    }
  ],
  "subpaths": {}
}