miyaji255 / hono-typia-openapi

Open API Schema Generator for Hono with typia
MIT License
11 stars 1 forks source link

hono-typia-openapi

npm version CI

This is an Open API Schema Generator for Hono with typia.

Installation

npm install hono-typia-openapi

Usage

You can use the hto command or Plugins to generate the OpenAPI schema.

Simple Case

hto -a <app-file> -t <title>

And, in <app-file>, you write the following:

import { Hono } from "hono";
import typia, { tags } from "typia";
import { typiaValidator } from "@hono/typia-validator";

interface HelloRequest {
  /** Your name */
  name: string & tags.MaxLength<16>;
}

const app = new Hono()
  .get("/hello", (c) => {
    return c.json(200, { message: "Hello, World!" });
  })
  .post(
    "/hello",
    typiaValidator("json", typia.createValidator<HelloRequest>()),
    (c) => {
      const { name } = c.req.valid("json");
      return c.json(200, { message: `Hello, ${name}!` });
    },
  );

// Generator uses this type to get the application schema.
export type AppType = typeof app;

Then, you can get the OpenAPI schema in the openapi.json file.

Options

You can specify the following options:

Option Description
-t, --title <title> The title of the application
-O, --openapi <openapi> The version of the OpenAPI specification. ['3.1', '3.0'] (default: 3.1)
-d, --description <description> The description of the API
-V, --app-version <version> The version of the API
-a, --app-file <appFile> The path to the Hono app file
-n, --app-type <appType> Hono app type name (default: AppType)
-o, --output <output> The path to the output swagger file (default: openapi.json)
--tsconfig <tsconfig> The path to the tsconfig file
-h, --help Display this message
-v, --version Display version number

You can also specify options with a configuration file.

Supported configuration file formats:

import { defineConfig } from "hono-typia-openapi/config";

export default defineConfig({
  title: "My API",
  description: "This is my API",
  version: "1.0.0",
  appFile: "./app.ts",
  appType: "AppType",
  output: "./openapi.json",
  tsconfig: "./tsconfig.json",
});

Plugins

Plugins of this package are created with Unplugin. You can use your favorite bundler.

Vite

Here is an example of using the Vite plugin:

// vite.config.ts
import { defineConfig } from "vite";
import HtoPlugin from "hono-typia-openapi/vite";

export default defineConfig(({ command }) => ({
  plugins: [
    HtoPlugin({
      title: "My API",
      appFile: `${__dirname}/src/app.ts`,
      output: `${__dirname}/openapi.json`,
      tsconfig: `${__dirname}/tsconfig.json`,
      watchMode: command === "serve",
    }),
  ],
}));

Show Swagger UI with Hono

You can show the Swagger UI with @hono/swagger-ui:

import { Hono } from "hono";
import typia, { tags } from "typia";
import { typiaValidator } from "@hono/typia-validator";
import { swaggerUI } from "@hono/swagger-ui";

interface HelloRequest {
  /** Your name */
  name: string & tags.MaxLength<16>;
}

const app = new Hono()
  .get("/hello", (c) => {
    return c.json({ message: "Hello, World!" }, 200);
  })
  .post(
    "/hello",
    typiaValidator("json", typia.createValidator<HelloRequest>()),
    (c) => {
      const { name } = c.req.valid("json");
      return c.json({ message: `Hello, ${name}!` }, 200);
    },
  );

// You can strip this part in production with Dead Code Elimination and Replace Identifiers
if (process.env.NODE_ENV === "development") {
  docs = (await import("fs/promises")).readFile("./openapi.json", "utf-8");
  app
    .get("docs", (c) => c.json(JSON.parse(docs), 200))
    .get("docs/ui", swaggerUI({ url: "/docs" }));
}

export type AppType = typeof app;