{"_id":"@api-platform/zod","name":"@api-platform/zod","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@api-platform/zod","version":"0.1.0","description":"Generate Zod schemas from JSON-LD / Hydra API documentation","license":"MIT","type":"module","exports":{".":"./src/index.js"},"scripts":{"test":"node --experimental-vm-modules node_modules/.bin/jest","lint":"prettier --check .","format":"prettier --write ."},"peerDependencies":{"zod":"^4.0.0"},"dependencies":{"@api-platform/api-doc-parser":"^0.16.9"},"devDependencies":{"@jest/globals":"^30.0.0","jest":"^30.0.0","prettier":"^3.8.1","zod":"^4.0.0"},"gitHead":"fdd42c807c292c7a925609407f505bae22dd1280","_id":"@api-platform/zod@0.1.0","_nodeVersion":"25.8.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-AJq1B89bVBypAZDYiwZdJcYkuuKdJoLazjQ0sGkd2D0hH+WTYI06wFM7ymp2ydn+URTyZUICbCdhOpnyDXycpw==","shasum":"527f4787126b0c498e3bb4fa8571c75c593d994d","tarball":"https://registry.npmjs.org/@api-platform/zod/-/zod-0.1.0.tgz","fileCount":15,"unpackedSize":47966,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFFnapVCLStPAfCiFddYxbMThMuHchohOz4jF2OiymJiAiAngwzxz0U61fBtW/kRXdQ9DM1hPVJYu1nEahlFSZWZuA=="}]},"_npmUser":{"name":"dunglas","email":"dunglas@gmail.com"},"directories":{},"maintainers":[{"name":"dunglas","email":"dunglas@gmail.com"},{"name":"simperfit","email":"hamza.simperfit@gmail.com"},{"name":"mysiar","email":"psynowiec@gmail.com"},{"name":"meyerbaptiste","email":"baptiste.meyer@gmail.com"},{"name":"teohhanhui","email":"teohhanhui@gmail.com"},{"name":"soyuka","email":"soyuka@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/zod_0.1.0_1773052029188_0.6476978350722855"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-09T10:27:09.066Z","0.1.0":"2026-03-09T10:27:09.324Z","modified":"2026-03-09T10:27:09.692Z"},"maintainers":[{"name":"dunglas","email":"dunglas@gmail.com"},{"name":"simperfit","email":"hamza.simperfit@gmail.com"},{"name":"mysiar","email":"psynowiec@gmail.com"},{"name":"meyerbaptiste","email":"baptiste.meyer@gmail.com"},{"name":"teohhanhui","email":"teohhanhui@gmail.com"},{"name":"soyuka","email":"soyuka@gmail.com"}],"description":"Generate Zod schemas from JSON-LD / Hydra API documentation","license":"MIT","readme":"# @api-platform/zod\n\nGenerate [Zod](https://zod.dev) schemas from [JSON-LD](https://json-ld.org/) / [Hydra](https://www.hydra-cg.com/) API documentation.\n\nThis library parses API documentation via [`@api-platform/api-doc-parser`](https://github.com/api-platform/api-doc-parser) and dynamically generates Zod schemas for each resource. It follows the [resilient client pattern](https://soyuka.me/resilient-api-clients-typescript/) — loose objects, IRI references, and runtime validation of only what's needed.\n\n## Installation\n\n```bash\nnpm install @api-platform/zod zod\n```\n\nRequires Zod v4.\n\n## Quick Start\n\n```js\nimport { createSchemas } from \"@api-platform/zod\";\nimport { safeParse } from \"zod/v4\";\n\n// Generate schemas from an API entrypoint\nconst { schemas, collections } = await createSchemas(\"https://api.example.com\");\n\n// schemas.Book -> z.looseObject({ '@id': z.string(), '@type': z.literal('Book'), title: z.string(), ... })\n// collections.Book -> Hydra collection schema wrapping Book\n\n// Validate API responses\nconst result = safeParse(schemas.Book, responseData);\nif (result.success) {\n  console.log(result.data.title);\n}\n```\n\n## API\n\n### `createSchemas(entrypoint, options?)`\n\nHigh-level function that fetches and parses API documentation, then generates Zod schemas.\n\n```js\nconst { schemas, collections, resources, api, response } = await createSchemas(\n  \"https://api.example.com\",\n);\n```\n\n**Parameters:**\n\n- `entrypoint` — The API entrypoint URL\n- `options` — Options passed to `parseHydraDocumentation`\n\n**Returns:**\n\n- `schemas` — `{ [ResourceName]: ZodSchema }` for each resource\n- `collections` — `{ [ResourceName]: ZodSchema }` Hydra collection schemas\n- `resources` — The parsed resource objects from api-doc-parser\n- `api` — The full parsed API object\n- `response` — The HTTP response\n\n### `schemasFromResources(resources)`\n\nLower-level function that works with pre-parsed Resource objects (from api-doc-parser). Useful when you already have the parsed API documentation.\n\n```js\nimport { schemasFromResources } from \"@api-platform/zod\";\n\nconst { schemas, collections } = schemasFromResources(api.resources);\n```\n\n### `resourceToSchema(resource, schemaMap?)`\n\nConverts a single api-doc-parser Resource into a `z.looseObject` schema with `@id`, `@type`, and all readable fields.\n\n```js\nimport { resourceToSchema } from \"@api-platform/zod\";\n\nconst bookSchema = resourceToSchema(bookResource);\n```\n\n### `fieldToZod(field, schemaMap?)`\n\nConverts a single api-doc-parser Field into a Zod type.\n\n```js\nimport { fieldToZod } from \"@api-platform/zod\";\n\nconst zodType = fieldToZod(field);\n```\n\n### `collectionSchema(itemSchema)`\n\nCreates a Hydra collection schema wrapping the given item schema.\n\n```js\nimport { collectionSchema } from \"@api-platform/zod\";\n\nconst booksCollectionSchema = collectionSchema(bookSchema);\n```\n\n## Type Mapping\n\n| Field Type                                                                      | Zod Type                |\n| ------------------------------------------------------------------------------- | ----------------------- |\n| `string`, `password`, `byte`, `binary`, `hexBinary`, `base64Binary`, `duration` | `z.string()`            |\n| `email`                                                                         | `z.string().email()`    |\n| `url`                                                                           | `z.string().url()`      |\n| `uuid`                                                                          | `z.string().uuid()`     |\n| `integer`                                                                       | `z.int()`               |\n| `positiveInteger`                                                               | `z.int().min(1)`        |\n| `negativeInteger`                                                               | `z.int().max(-1)`       |\n| `nonNegativeInteger`                                                            | `z.int().min(0)`        |\n| `nonPositiveInteger`                                                            | `z.int().max(0)`        |\n| `number`, `decimal`, `double`, `float`                                          | `z.number()`            |\n| `boolean`                                                                       | `z.boolean()`           |\n| `date`                                                                          | `z.string().date()`     |\n| `dateTime`                                                                      | `z.string().datetime()` |\n| `time`                                                                          | `z.string().time()`     |\n\n### Special Cases\n\n- **References** — Rendered as `z.string()` (IRI strings in JSON-LD)\n- **Embedded resources** — Resolved via `z.lazy()` to support circular references\n- **Enums** — `z.enum([...values])`\n- **Nullable fields** — Wrapped with `z.nullable()`\n- **Optional fields** (`required: false`) — Wrapped with `z.optional()`\n- **Array fields** (`maxCardinality !== 1`) — Wrapped with `z.array()`\n\n## Resilient Client Pattern\n\nSchemas use `z.looseObject()`, which allows unknown properties to pass through without being stripped. This means your client code won't break when the API adds new fields — you validate only the fields you depend on.\n\n```js\n// Extra fields in the response are preserved, not stripped\nconst result = safeParse(schemas.Book, {\n  \"@id\": \"/api/books/1\",\n  \"@type\": \"Book\",\n  title: \"The Great Gatsby\",\n  newFieldAddedLater: \"still available\",\n});\n// result.data.newFieldAddedLater === 'still available'\n```\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md","_rev":"1-42d2f8e61e7b31ab0e33058ec7d115d7"}