Package Exports
- openapi-zod-client
- openapi-zod-client/dist/openapi-zod-client.cjs.js
- openapi-zod-client/dist/openapi-zod-client.esm.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (openapi-zod-client) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
openapi-zod-client
Generates a zodios (typescript http client with zod validation) from a (json/yaml) OpenAPI spec (or just make your own output template and do w/e you want with the generated schemas/endpoints/etc !)
can be used programmatically (do w/e you want with the computed schemas/endpoints)
or used as a CLI (generates a prettier .ts file with deduplicated variables when pointing to the same schema/$ref)
client typesafety using zodios
tested (using vitest) against official OpenAPI specs samples
Usage
with local install:
pnpm i -D openapi-zod-client
pnpm openapi-zod-client "./input/file.json" -o "./output/client.ts"
or directly
pnpx openapi-zod-client "./input/file.yaml" -o "./output/client.ts"
you can pass a custom handlebars template and/or a custom prettier config with something like pnpm openapi-zod-client ./example/petstore.yaml -o ./example/petstore-schemas.ts -t ./example/schemas-only.hbs -p ./example/prettier-custom.json
, there is an example here
Example
You can check an example input (the petstore example when you open/reset editor.swagger.io) and output
there's also an example of a programmatic usage
or you can check the tests in the
src
folder which are mostly just inline snapshots of the outputs
tl;dr
input:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
"200":
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
"201":
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
"200":
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
output:
import { Zodios } from "@zodios/core";
import { z } from "zod";
const v7LgRCMpuZ0 = z.object({ id: z.bigint(), name: z.string(), tag: z.string().optional() }).optional();
const vWZd2G8UeSs = z.array(v7LgRCMpuZ0).optional();
const v77smkx5YEB = z.object({ code: z.bigint(), message: z.string() }).optional();
const variables = {
Error: v77smkx5YEB,
Pet: v7LgRCMpuZ0,
Pets: vWZd2G8UeSs,
createPets: v77smkx5YEB,
listPets: v77smkx5YEB,
showPetById: v77smkx5YEB,
};
const endpoints = [
{
method: "get",
path: "/pets",
requestFormat: "json",
parameters: [
{
name: "limit",
type: "Query",
schema: z.bigint().optional(),
},
],
response: variables["Pets"],
},
{
method: "post",
path: "/pets",
requestFormat: "json",
response: variables["Error"],
},
{
method: "get",
path: "/pets/{petId}",
requestFormat: "json",
response: variables["Pet"],
},
] as const;
export const api = new Zodios("baseurl", endpoints);
TODO
- handle default values (output
z.default(xxx)
) - handle OA spec
format: date-time
-> outputz.date()
/preprocess
? - handle string/number constraints -> output z.
min max length email url uuid startsWith endsWith regex trim nonempty gt gte lt lte int positive nonnegative negative nonpositive multipleOf
- handle OA
prefixItems
-> outputz.tuple
- handle recursive schemas -> output
z.lazy()
- add an argument to control which response should be added (currently by status code === "200" or when there is a "default")
Contributing:
pnpm i && pnpm gen