Readme

@skmtc/gen-valibot

Coverage

OpenAPI to Valibot schema generator for Skmtc.

Supported Features

  • Primitive types: string, number, integer, boolean
  • Complex types: object, array, union (oneOf/anyOf)
  • Modifiers: nullable, optional
  • Enums: Single values (literal) and multiple values (picklist)
  • String formats: date-time (isoDateTime)
  • Integer validation: Uses v.pipe(v.number(), v.integer())
  • References: Schema references via $ref
  • Additional properties: Record types and intersections
  • Nested structures: Deeply nested objects and arrays

Getting started

Install Skmtc

deno install -g -A --unstable-worker-options jsr:@skmtc/cli -n skmtc -f

Skmtc runs on Deno. You can install it using

  • curl -fsSL https://deno.land/install.sh | sh on MacOS/Linux
  • irm https://deno.land/install.ps1 | iex on Windows

Create project and generate artifacts using TUI

skmtc

Create project and generate artifacts using CLI

# Create project
skmtc init <project name>

# Install Valibot generator
skmtc install @skmtc/gen-valibot <project name>

# Bundle generator code
skmtc bundle <project name>

# Generate artifacts from OpenAPI schema
skmtc generate <project name> <path or url to openapi schema>

Usage Examples

Basic Types

Input (OpenAPI Schema)Valibot Schema
{
  "components": {
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "age": { "type": "number" },
          "isActive": { "type": "boolean" }
        },
        "required": ["id", "age"]
      }
    }
  }
}
import * as v from "valibot"

export const user = v.object({
  id: v.string(),
  age: v.number(),
  isActive: v.optional(v.boolean())
})

Enums and Literals

Input (OpenAPI Schema)Valibot Schema
{
  "Status": {
    "type": "string",
    "enum": ["active", "inactive", "pending"]
  },
  "Role": {
    "type": "string",
    "enum": ["admin"]
  }
}
export const status = v.picklist(["active", "inactive", "pending"])
export const role = v.literal("admin")

Arrays and Nested Objects

Input (OpenAPI Schema)Valibot Schema
{
  "Team": {
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "members": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "id": { "type": "string" },
            "role": { "type": "string" }
          },
          "required": ["id", "role"]
        }
      }
    },
    "required": ["name", "members"]
  }
}
export const team = v.object({
  name: v.string(),
  members: v.array(v.object({
    id: v.string(),
    role: v.string()
  }))
})

Nullable and Optional Fields

Input (OpenAPI Schema)Valibot Schema
{
  "Profile": {
    "type": "object",
    "properties": {
      "bio": {
        "type": "string",
        "nullable": true
      },
      "website": { "type": "string" }
    },
    "required": ["bio"]
  }
}
export const profile = v.object({
  bio: v.nullable(v.string()),
  website: v.optional(v.string())
})

Union Types

Input (OpenAPI Schema)Valibot Schema
{
  "Pet": {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["cat"] },
          "meow": { "type": "boolean" }
        },
        "required": ["type", "meow"]
      },
      {
        "type": "object",
        "properties": {
          "type": { "type": "string", "enum": ["dog"] },
          "bark": { "type": "boolean" }
        },
        "required": ["type", "bark"]
      }
    ]
  }
}
export const pet = v.union([
  v.object({
    type: v.literal("cat"),
    meow: v.boolean()
  }),
  v.object({
    type: v.literal("dog"),
    bark: v.boolean()
  })
])

String Formats

Input (OpenAPI Schema)Valibot Schema
{
  "Event": {
    "type": "object",
    "properties": {
      "createdAt": {
        "type": "string",
        "format": "date-time"
      }
    },
    "required": ["createdAt"]
  }
}
export const event = v.object({
  createdAt: v.pipe(v.string(), v.isoDateTime())
})

Additional Properties

Input (OpenAPI Schema)Valibot Schema
{
  "Metadata": {
    "type": "object",
    "additionalProperties": { "type": "string" }
  }
}
export const metadata = v.record(v.string(), v.string())

With both properties and additionalProperties:

Input (OpenAPI Schema)Valibot Schema
{
  "Config": {
    "type": "object",
    "properties": {
      "id": { "type": "string" }
    },
    "required": ["id"],
    "additionalProperties": { "type": "number" }
  }
}
export const config = v.intersect([
  v.object({ id: v.string() }),
  v.record(v.string(), v.number())
])

Testing

Run tests for this generator:

cd gen-valibot && deno task test

Or with coverage:

deno task test:coverage

Support

License

MIT.