@kmudrick/io-ts-openapi
TypeScript icon, indicating that this package has built-in type declarations

0.0.22 • Public • Published

@kmudrick/io-ts-openapi

Generates typescript io-ts codecs from the models of an OpenAPI Spec

Background

io-ts is a fantastic Typescript library that uses parser combinators for building static types and typed runtime codecs that can be used for validation (type guards), encoding, and decoding.

This project uses io-ts-codegen to generate these types and codecs from the models of an openapi document.

Future enhancements will target support for refined types and alternate implementations (like Js-Joda for Date/Time types).

Usage

npx @kmudrick/io-ts-openapi --help

Options:
  --help     Show help                                        [boolean]
  --version  Show version number                              [boolean]
  --input                                           [string] [required]
  --output                                          [string] [required]
  --useJoda                                           [boolean] [default: false]

Example

For example, to read specs/petstore.yaml and write the types and codecs to petstore.ts:

npx @kmudrick/io-ts-openapi \
    --input specs/petstore.yaml \
    --output petstore.ts

Successfully wrote petstore.ts

For this given 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

Will produce this typescript output for the models Pet, Pets, and Error

import * as t from "io-ts";
export type SampleUnion = Readonly<
  | {
      code: number;
      message: string;
    }
  | {
      id: number;
      name: string;
      tag?: string;
    }
>;
export type Pet = Readonly<{
  id: number;
  name: string;
  tag?: string;
}>;
export type Pets = Readonly<
  Array<{
    id: number;
    name: string;
    tag?: string;
  }>
>;
export type Error = Readonly<{
  code: number;
  message: string;
}>;
export const SampleUnion = t.readonly(
  t.union([
    t.type({
      code: t.number,
      message: t.string,
    }),
    t.intersection([
      t.type({
        id: t.number,
        name: t.string,
      }),
      t.partial({
        tag: t.string,
      }),
    ]),
  ]),
  "SampleUnion"
);
export const Pet = t.readonly(
  t.intersection([
    t.type({
      id: t.number,
      name: t.string,
    }),
    t.partial({
      tag: t.string,
    }),
  ]),
  "Pet"
);
export const Pets = t.readonly(
  t.array(
    t.intersection([
      t.type({
        id: t.number,
        name: t.string,
      }),
      t.partial({
        tag: t.string,
      }),
    ])
  ),
  "Pets"
);
export const Error = t.readonly(
  t.type({
    code: t.number,
    message: t.string,
  }),
  "Error"
);

JS Joda Support

js-joda is an excellent immutable date/time library for JS.

To enable date strings to use LocalDate and date-time strings to use LocalDateTime, simply use the ``--useJoda` switch.

A model that looks like:

LocalDateValue:
  type: object
  required:
    - value
  properties:
    value:
      type: string
      format: date

Will produce:

import * as t from "io-ts";
import { LocalDate } from "@js-joda/core";
import { LocalDateFromISOString } from "@kmudrick/io-ts-openapi/dist/src/types";

export type LocalDateValue = Readonly<{
  value: LocalDate
}>
export const LocalDateValue = t.readonly(t.type({
  value: LocalDateFromISOString
}), 'LocalDateValue')

The source for LocalDateFromISOString can be found here

Readme

Keywords

none

Package Sidebar

Install

npm i @kmudrick/io-ts-openapi

Weekly Downloads

1

Version

0.0.22

License

MIT

Unpacked Size

79.1 kB

Total Files

42

Last publish

Collaborators

  • kmudrick