npm package: @seiya8bit/otz
Description: Convert OpenAPI and TypeSpec definitions to Zod v4 validation schemas.
Author: seiya8bit
Latest version: 4.0.0

# @seiya8bit/otz

`otz` is a command-line tool that generates Zod schemas from your OpenAPI definitions.
Maps OpenAPI types and formats to Zod schemas, and generates validation messages useful for UI forms.

## Zod Version Compatibility

| otz version | Zod version |
| ----------- | ----------- |
| 3.x         | Zod v4      |
| 2.x         | Zod v3      |

If you are using Zod v3, install the v2 release:

```sh
npm install -D @seiya8bit/otz@2
```

## Requirements

- Node.js >= 22

## Install

```sh
npm install -D @seiya8bit/otz
```

## Quick start

```sh
otz -i path/to/openapi.yaml -o path/to/output.ts -c -p -q -n optional
```

## Features

- **Type & Format Conversion:** Translates OpenAPI `type` (e.g., `integer`) and `format` (e.g., `email`) properties into the appropriate Zod schema types.
- **Validation Rule Mapping:** Converts OpenAPI validation keywords like `minimum`, `exclusiveMinimum`, etc., into Zod validation checks (e.g., `.min()`, `.max()`).
- **Customizable Null Handling:** Choose how `nullable: true` properties are handled – map them to either `.nullish()` or `.optional()` in the generated Zod schemas.
- **Validation Message Generation:** Option to automatically include validation messages within the generated Zod schemas, perfect for displaying feedback in forms.
- **Split Definition Support:** Seamlessly handles OpenAPI definitions that are split across multiple files using `$ref`.

## Zod v4 Schema Support (Generated Output)

- **Base types:** `string`, `number`, `bigint`, `boolean`, `date`, `symbol`, `undefined`, `null`, `void`, `any`, `unknown`, `never`
- **Objects/arrays:** `object` -> `z.object({ ... })`, `array` -> `z.array(...)`
- **Enums:** string enums -> `z.enum([...])`; non-string enums -> `z.union([z.literal(...), ...])`
- **Unions:** `anyOf` / `oneOf` -> `z.union([...])`
- **Composition:** `allOf` (object only) -> `.merge(...)`
- **Nullability:** `nullable: true` -> `.nullish()` or `.optional()` (configurable)
- **Defaults:** `default` -> `.default(...)` (bigint defaults for `int64/uint64`)
- **Constraints:** `minItems/maxItems`, `minLength/maxLength`, `minimum/maximum` (+ `exclusive*`) -> `.min/.max/.gt/.gte/.lt/.lte`
- **Regex:** `pattern` -> `.regex(new RegExp(pattern))`
- **OpenAPI string formats:**
  - `email`, `uuid`, `uuidv4`, `uuidv6`, `uuidv7`
  - `uri`/`url` -> `z.url()`
  - `hostname`, `ipv4`, `ipv6`, `cidrv4`, `cidrv6`
  - `byte` -> `z.base64()`, `base64url`, `nanoid`, `cuid`, `cuid2`, `ulid`, `guid`, `emoji`
  - `date`, `time`, `date-time`, `duration` -> `z.iso.date/time/datetime/duration`
- **OpenAPI number formats:**
  - `integer` -> `z.int()`
  - `int32`, `int64`, `uint32`, `uint64`, `float`/`float32`, `double`/`float64`
- **additionalProperties:** `true` -> `z.record(z.unknown())`, `false` -> `.strict()`, schema -> `.catchall(schema)` or `z.record(schema)`

## Usage

Run the `otz` command, specifying the input OpenAPI file, the desired output path, and any relevant options.

## Command-Line Options

The following options are available for the `otz` command:

| Options               | Description                                                         | Required | Default  |
| --------------------- | ------------------------------------------------------------------- | -------- | -------- |
| `-i, --input`         | Path to the root OpenAPI definition file (YAML or JSON).            | ✅       | N/A      |
| `-o, --output`        | Output file path for the generated Zod schema.                      | ✅       | N/A      |
| `-c, --components`    | Generate schemas for definitions in components/schemas.             |          | false    |
| `-p, --paths`         | Generate schemas for request bodies and responses defined in paths. |          | false    |
| `-q, --queries`       | Generate schemas for query parameters defined in paths.             |          | false    |
| `-n, --nullable-mode` | Set null handling mode: nullish or optional.                        |          | optional |

## Split OpenAPI Definitions

For OpenAPI definitions split across multiple files, specify the root file in the `--input` option.

## Guides

- **For OpenAPI users:** See the [OpenAPI Usage Guide](README_OpenAPI.md) for details on converting existing OpenAPI files.
- **For TypeSpec users:** See the [TypeSpec Usage Guide](README_TypeSpec.md) for integrating `otz` into your TypeSpec workflow.

## Examples

- [Petstore(basic)](https://github.com/seiya8bit/otz/tree/main/examples/petstore)
- [with Hono(advanced)](https://github.com/seiya8bit/otz/tree/main/examples/with-hono)

## Contributing

Contributions are welcome!

If you find a bug or have a feature request, feel free to open an issue or submit a pull request.

## License

This project is licensed under the MIT License.