@yamaimo-illus/typespec-to-zod
v0.6.0
Published
Zod schema generator via TypeSpec-generated yaml
Downloads
567
Maintainers
Readme
typespec-to-zod
This library is effortlessly converts YAML from TypeSpec into Zod schemas.
Usage
Provide the CLI with the input/output file path and additional options as shown below.
typespec-to-zod -i path/to/openapi.yaml -o path/to/generated.ts -c -p -q -n nullish
Command-line options
The tool supports a variety of command-line options to customize the output:
| Options | Description | Default |
|-----------------------|--------------------------------------------|---------|
| -i, --input
| Path to the OpenAPI YAML file. | N/A |
| -o, --output
| Output file path for the generated schema. | N/A |
| -c, --components
| Flag to generate components. | false |
| -p, --paths
| Flag to generate paths. | false |
| -q, --queries
| Flag to generate queries. | false |
| -n, --nullable-mode
| Set null handling mode: nullish/optional | nullish |
Examples
Supported TypeSpec built-in types
See Built-in types | TypeSpec.
Numeric types
These are the mappings from TypeSpec numeric types to Zod:
| TypeSpec Type | Zod Type Conversion | |----------------|-----------------------| | numeric | z.number() | | integer | z.number() | | float | z.number() | | int64 | z.number().int() | | int32 | z.number().int() | | int16 | z.number().int() | | int8 | z.number().int() | | safeint | z.number().int() | | uint64 | z.number().int() | | uint32 | z.number().int() | | uint16 | z.number().int() | | uint8 | z.number().int() | | float32 | z.number() | | float64 | z.number() | | decimal | z.number() | | decimal128 | z.number() |
Example TypeSpec:
model NumericTypes {
numericProperty: numeric;
integerProperty: integer;
floatProperty: float;
int64Property: int64;
int32Property: int32;
int16Property: int16;
int8Property: int8;
safeintProperty: safeint;
uint64Property: uint64;
uint32Property: uint32;
uint16Property: uint16;
uint8Property: uint8;
float32Property: float32;
float64Property: float64;
decimalProperty: decimal;
decimal128Property: decimal128;
}
Generated Zod schema:
export const schemaNumericTypes = z.object({
numericProperty: z.number(),
integerProperty: z.number(),
floatProperty: z.number(),
int64Property: z.number().int(),
int32Property: z.number().int(),
int16Property: z.number().int(),
int8Property: z.number().int(),
safeintProperty: z.number().int(),
uint64Property: z.number().int(),
uint32Property: z.number().int(),
uint16Property: z.number().int(),
uint8Property: z.number().int(),
float32Property: z.number(),
float64Property: z.number(),
decimalProperty: z.number(),
decimal128Property: z.number()
})
Date and Time types
These types involve conversions that consider date and time formatting:
| TypeSpec Type | Zod Type Conversion | |----------------|-----------------------| | plainDate | z.string().date() | | plainTime | z.string().time() | | utcDateTime | z.string().datetime() | | offsetDateTime | z.string().datetime() | | duration | z.string().duration |
Example TypeSpec:
model DateAndTimeTypes {
plainDateProperty: plainDate;
plainTimeProperty: plainTime;
utcDateTimeProperty: utcDateTime;
offsetDateTimeProperty: offsetDateTime;
durationProperty: duration;
}
Generated Zod schema:
export const schemaDateAndTimeTypes = z.object({
plainDateProperty: z.string().date(),
plainTimeProperty: z.string().time(),
utcDateTimeProperty: z.string().datetime(),
offsetDateTimeProperty: z.string().datetime(),
durationProperty: z.string().duration()
})
Other core types
These are additional core types and their mappings:
| TypeSpec Type | Zod Type Conversion | |-------------------|------------------------------------------------| | bytes | Not supported but it generated as z.string() | | string | z.string() | | boolean | z.boolean() | | null | z.unknown() | | Array<Element> | z.array(z.Element()) | | Record<Element> | Not supported but it generated as z.object({}) | | unknown | z.unknown() | | void | NOT SUPPORTED | | never | NOT SUPPORTED |
Example TypeSpec:
model OtherCoreTypes {
bytesProperty: bytes;
stringProperty: string;
booleanProperty: boolean;
nullProperty: null;
ArrayProperty: numeric[];
recordProperty: Record<numeric>;
unknownProperty: unknown;
// voidProperty: void; Not Supported
// neverProperty: never; Not Supported
}
Generated Zod schema:
export const schemaOtherCoreTypes = z.object({
bytesProperty: z.string(),
stringProperty: z.string(),
booleanProperty: z.boolean(),
nullProperty: z.unknown(),
ArrayProperty: z.array(z.number()),
recordProperty: z.record(z.string(), z.number()),
unknownProperty: z.unknown()
})
String types
The tool also supports string-specific types and their conversions:
| TypeSpec Type | Zod Type Conversion | |----------------|----------------------| | url | z.string().url() |
Example TypeSpec:
model StringTypes {
urlProperty: url;
}
Generated Zod schema:
export const schemaStringTypes = z.object({
urlProperty: z.string().url()
})
Supported TypeSpec Decorators
These decorators in TypeSpec can be converted to specific constraints in Zod schemas:
| TypeSpec Decorator | Zod Type Conversion | |---------------------|---------------------| | @minItems() | .min() | | @maxItems() | .max() | | @minLength() | .min() | | @maxLength() | .max() | | @minValue() | .gte() | | @maxValue() | .lte() | | @exclusiveMinimum() | .gt() | | @exclusiveMaximum() | .lt() |
Example TypeSpec:
model TypeSpecDecorators {
@minItems(1)
@maxItems(5)
items: string[];
@minLength(1)
@maxLength(5)
name: string;
@minValue(1)
@maxValue(5)
age: int16;
@minValueExclusive(1)
@maxValueExclusive(5)
count: int16;
}
Generated Zod schema:
export const schemaTypeSpecDecorators = z.object({
items: z.array(z.string()).min(1).max(5),
name: z.string().min(1).max(5),
age: z.number().int().gte(1).lte(5),
count: z.number().int().gt(1).lt(5)
})
Supported TypeSpec Format Decorators
These format decorators in TypeSpec can be converted to specific constraints in Zod schemas:
| TypeSpec Format | Zod Type Conversion | |----------------------|---------------------| | @format("date-time") | .datetime() | | @format("date") | .date() | | @format("time") | .time() | | @format("duration") | .duration() | | @format("ip") | .ip() | | @format("email") | .email() | | @format("uuid") | .uuid() | | @format("cuid") | .cuid() | | @format("cuid2") | .cuid2() | | @format("uri") | .url() | | @format("url") | .url() |
Extended Syntax for Doc Decorator
By using the zod:
identifier within a doc comment, you can instruct the typespec-to-zod
tool to generate Zod schemas with specific requirements.
This feature provides greater flexibility and control over the validation rules directly from the TypeSpec model.
Example TypeSpec:
model ExtendedSyntaxForDocDecorator {
@doc("Username zod: z.string().min(2, { message: 'Must be 2 or more characters long' })")
name: string;
}
Generated Zod schema:
export const schemaExtendedSyntaxForDocDecorator = z.object({
// Username
name: z.string().min(2, { message: 'Must be 2 or more characters long' })
})
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.