Skip to main content

UseValibotPlugin

UseValibotPlugin uses Valibot to generate type definitions and validation schemas for components/schemas in OpenAPI documents. Valibot is a lightweight schema validation library offering smaller bundle size and better type inference.

tip

Compared to traditional TypeScript type definitions, using Valibot enables runtime data validation, ensuring type safety for API response data.

Installing Dependencies

Before using this plugin, install Valibot:

Configuration

.keqrc.ts
import { UseValibotPlugin } from '@keq-request/cli/plugins'

export default defineKeqConfig({
  outdir: "./src/apis",
  modules: {
    catService: "./cat-service-swagger.json",
  },
  plugins: [new UseValibotPlugin()],
})

Use Case

Suppose your OpenAPI document defines a Schema like this:

{
  "components": {
    "schemas": {
      "Cat": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "breed": {
            "type": "string"
          },
          "age": {
            "type": "integer",
            "minimum": 0,
            "maximum": 30
          }
        }
      }
    }
  }
}

Without UseValibotPlugin

By default, the CLI generates pure TypeScript type definitions:

export interface Cat {
  id: number
  name: string
  breed?: string
  age?: number
}

This only provides compile-time type checking and cannot validate data at runtime.

With UseValibotPlugin

With the plugin configured, the CLI generates Valibot schemas:

import * as v from 'valibot'

export const CatSchema = v.object({
  id: v.pipe(v.number(), v.integer()),
  name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
  breed: v.optional(v.string()),
  age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(30))),
})

export type Cat = v.InferOutput<typeof CatSchema>

You can use the generated schema for runtime validation:

Validating API Response Data

import { CatSchema } from './apis/cat-service'
import * as v from 'valibot'

// Validate API response data
const response = await fetch('/api/cats/1')
const data = await response.json()

try {
  const cat = v.parse(CatSchema, data)
  console.log(cat) // Type-safe cat data
} catch (error) {
  console.error('Data validation failed:', error)
}

Form Validation and Request Submission

In practice, you can combine form validation with request body validation to ensure only valid data gets submitted:

import { CatSchema, Cat } from './apis/cat-service'
import * as v from 'valibot'

// Form data is likely a Partial type
type CatFormData = Partial<Cat>

async function submitCatForm(formData: CatFormData) {
  if (!v.is(CatSchema, formData)) {
    // Do Something...
    return
  }

  // Validation passed, send request
  const response = await fetch('/api/cats', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(formData),
  })

  const result = await response.json()
  console.log('Cat created successfully')
}