JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 656
  • Score
    100M100P100Q91321F
  • License BSD-3-Clause

Automatically transforms Typescript types into OpenAPI specifications.

Package Exports

  • ts-oas
  • ts-oas/dist/index.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 (ts-oas) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Typescript OpenAPI Spec Generator

npm version

Automatically transforms Typescript types into OpenAPI specifications. Needs interfaces/types in a particular format.

Benenfits

  • Write once, use many. Typescript is one of the most fluent ways to declare API specifications. Using ts-oas, we are able to utilize the generated specs for not only the documentations, also input validations (eg. ajv), serializing, testing and more.
  • Automation first. Simply write a script and regenerate specs accordingly after making any change in types.
  • Headless. Works with any server-side framework, unlike some other tools.

Features

  • Supports JSDoc annotations. Using pre-defined and user-defined keywords, meta-data can be included in every schema objects.
  • Reference schemas and components. Schema references can be generated and addressed in accord with their correspond type references.
  • Schema processor function for any desired post-process (if JSDoc isn't enough).
  • Generate schemas separately.

Install

npm i ts-oas

Getting Started

Firstly, We need types for each API, compatible with below format:

type Api = {
    path: string;
    method: HTTPMethod;
    body?: Record<string, any>;
    params?: Record<string, any>;
    query?: Record<string, any>;
    responses: Partial<Record<HttpStatusCode, any>>;
};

A quick example

We have interfaces.ts where our API types are present:

import { ApiMapper } from "ts-oas";
// Recommended to use ApiMapper to help to keep the format valid.
export type GetBarAPI = ApiMapper<{
    path: "/foo/bar/:id";
    method: "GET";
    params: {
        id: number;
    };
    query: {
        from_date: Date;
    };
    responses: {
        /**
         * @contentType application/json
         */
        "200": Bar;
        "404": { success: false };
    };
}>;

/**
 * Sample description.
 * @summary Add a Bar
 */
export type AddBarAPI = ApiMapper<{
    path: "/foo/bar";
    method: "POST";
    body: Bar;
    responses: {
        "201": {};
    };
}>;

export type Bar = {
    /**
     * Description for barName.
     */
    barName: string;
    barType: "one" | "two";
};

In script.ts file:

import TypescriptOAS, { createProgram } from "ts-oas";
import { resolve } from "path";
import { writeFileSync } from "fs";
import { inspect } from "util";

// Create a Typescript program. Or any generic ts program can be used.
const tsProgram = createProgram(
    ["interfaces.ts"],
    {
        strictNullChecks: true,
    },
    resolve()
);

// initiate the OAS generator.
const tsoas = new TypescriptOAS(tsProgram, {
    ref: true,
});

// get the complete OAS. Determine which types must be used for API specs by passing the type names(Regex/exact name)
const specObject = tsoas.getOpenApiSpec([/API$/]); // /API$/ -> All types that ends with "API"

// write results to a file.
writeFileSync("./schemas.ts", `const spec = ${inspect(specObject, { depth: null })};\n`);

Run the above script and open schema.ts file.

Get schemas separately

Schemas with any format can be generated by:

const schema = tsoas.getSchemas(["Bar"]);
console.log(schema);

Documentations

JSDoc annotations

Keyword Fields Examples
@default any @default foo @default 3 @default ["a", "b", "c"]
@format strings @format email
@items arrays @items.minimum 1 @items.format email @items {"type":"integer", "minimum":0} @default ["a", "b", "c"]
@$ref any @ref http://my-schema.org
@title any @title foo
@minimum
@maximum
@exclusiveMinimum
@exclusiveMaximum
numbers @minimum 10 @maximum 100
@minLength
@maxLength
strings @minLength 10 @maxLength 100
@minItems
@maxItems
arrays @minItems 10 @maxItems 100
@minProperties
@maxProperties
objects @minProperties 10 @maxProperties 100
@additionalProperties objects @additionalProperties
@ignore any @ignore
@pattern strings @pattern /^[0-9a-z]+$/g
@example any @example foo @example {"abc":true} @example require('./examples.ts').myExampleConst
@examples any @example ["foo", "bar"] @example require('./examples.ts').myExampleArrayConst

Special keywords for root of API types

@summary @operationId @tags @hide @body.description @body.contentType

Example
/**
 * Sample description.
 * @summary Summary of Endpoint
 * @operationId addBar
 * @tags foos,bars
 * @hide
 * @body.description Description for body of request.
 * @body.contentType application/json
 */
export type AddBarAPI = ApiMapper<{
    path: "/foo/bar";
    method: "POST";
    body: Bar;
    responses: {
        "201": {};
    };
}>;

Special keywords for response items

@contentType

Example
    ...
    responses: {
        /**
        * Description for response 200.
        * @contentType application/json
        */
        "200": { success: true };
    };

Inspirations

ts-oas is highly inspired by typescript-json-schema. While using the so-called library, it took a lot of workarounds to create compatible OpenAPI v3.0 specs. Plus, editing a schema enforced us to use schema-walker tools which added lots of overhead. So we came to add a schema-processor custom function option.

Connecting Typescript types to serializer and validators to cut down the developing times, was the main purpose of developing this tool.

Contributing

Any contributions are welcome.