Transform Valibot schemas to openApi
  • TypeScript 89.1%
  • JavaScript 10.9%
Find a file
github-actions 4b88c41b7c Version bump
2025-09-08 17:09:30 +00:00
.github/workflows npm ci 2025-02-19 16:45:18 -06:00
docs update docs 2024-12-09 14:24:49 -06:00
src improve types 2025-02-20 11:07:41 -06:00
.gitignore fix ignore 2024-12-06 14:20:20 -06:00
eslint.config.js eslint, prettier, clean up 2024-12-05 15:26:59 -06:00
jsr.json Version bump 2025-09-08 17:09:30 +00:00
LICENSE Initial commit 2024-12-05 10:25:53 -06:00
mod.ts hopefully improve types 2025-02-19 20:40:05 -06:00
package-lock.json add dep 2024-12-06 08:48:10 -06:00
package.json Version bump 2025-09-08 17:09:30 +00:00
README.md add image 2024-12-09 14:37:48 -06:00
tsconfig.json try exporting types again 2025-02-19 11:13:50 -06:00

valibot-openapi-generator

Uses Valibot schemas to generate Open API documentation

Install

Install from JSR,

npx jsr add @camflan/valibot-openapi-generator

Status

This is being used in production but needs a lot of help to become as powerful as it can be. Please PR any help, especially around some of the ignored type errors

Inspiration/sources

I used hono-openapi as the starting point, many thanks to that repository and those contributors.

Example usage

const openApiSpec = getOpenAPISpecs(
  [
    describeRoute("/accounts", {
      summary: "List accounts",
      description: "Lists all accounts you have access to",
      method: "GET",
      responses: {
        200: {
          content: {
            "application/json": {
              schema: v.object({
                accounts: v.array(
                  v.object({
                    id: v.string(),
                    email: v.string(),
                    name: v.string(),
                  }),
                ),
              }),
            },
          },
          description: "OK",
        },
        500: {
          description: "Server error",
        },
      },
    }),
    describeRoute("/accounts/{accountId}", {
      summary: "Account detail",
      description: "Shows detailed information for a specific account",
      method: "GET",
      parameters: [
        {
          in: "path",
          name: "accountId",
          required: true,
        },
      ],
      responses: {
        200: {
          content: {
            "application/json": {
              schema: v.object({
                account: v.object({
                  id: v.string(),
                  email: v.string(),
                  name: v.string(),
                }),
              }),
            },
          },
          description: "OK",
        },
        401: {
          description: "Not authorized",
        },
        500: {
          description: "Server error",
        },
      },
    }),
  ],
  {
    documentation: {
      info: {
        title: "My first schema",
        version: "1",
      },
    },
  },
);

Example output in an OpenAPI explorer

JSON output for the above example
```json { "openapi": "3.1.0", "info": { "description": "Development documentation", "title": "My first schema", "version": "1" }, "components": { "schemas": {} }, "paths": { "/accounts": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "accounts": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["email", "id", "name"], "additionalProperties": false } } }, "required": ["accounts"], "additionalProperties": false } } }, "description": "OK" }, "500": { "description": "Server error" } }, "operationId": "getAccounts", "description": "Lists all accounts you have access to", "summary": "List accounts" } }, "/accounts/{accountId}": { "get": { "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "account": { "type": "object", "properties": { "email": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["email", "id", "name"], "additionalProperties": false } }, "required": ["account"], "additionalProperties": false } } }, "description": "OK" }, "401": { "description": "Not authorized" }, "500": { "description": "Server error" } }, "operationId": "getAccountsByAccountId", "description": "Shows detailed information for a specific account", "parameters": [{ "in": "path", "name": "accountId", "required": true }], "summary": "Account detail" } } }, "tags": [] } ```