@kubb/adapter-oas
Parse and convert OpenAPI 2.0, 3.0, and 3.1 specifications into Kubb's universal AST. Handles discriminators, date formats, and server URL resolution.
- Downloads
- 9.6k / mo
- Stars
- 1.7k
- Bundle size
- 665.5 kB
- Updated
- 3d ago
The OpenAPI adapter is the bridge between your spec and every Kubb plugin. It reads the file at input.path, validates it, and converts every schema and operation into Kubb's universal AST that downstream plugins consume.
Configure it once on defineConfig. Its choices (date representation, integer width, server URL) apply to every plugin in the build.
Installation
bun add -d @kubb/adapter-oas@betapnpm add -D @kubb/adapter-oas@betanpm install --save-dev @kubb/adapter-oas@betayarn add -D @kubb/adapter-oas@betaOptions
validate
Validates the OpenAPI spec with @readme/openapi-parser before parsing. Set to false only when you have a known-invalid spec that you still want to generate from.
| Type: | boolean |
|---|---|
| Required: | false |
| Default: | true |
import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({ validate: false }),
plugins: [],
})contentType
Preferred media type when extracting request and response schemas. Operations with multiple media types fall back to this one.
Defaults to the first JSON-compatible media type found in the spec (application/json, application/vnd.api+json, any *+json).
| Type: | 'application/json' | string |
|---|---|
| Required: | false |
import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({ contentType: 'application/vnd.api+json' }),
plugins: [],
})serverIndex
Index into the servers array from your OpenAPI spec, used to compute the base URL for plugins that need it (@kubb/plugin-client, @kubb/plugin-msw, ...).
Most projects pick 0 for the primary server. Use higher indices to point at staging or localhost when your spec defines multiple environments.
| Type: | number |
|---|---|
| Required: | false |
TIP
Plugins read baseURL from this server unless they override it explicitly.
openapi: 3.0.3
servers:
- url: http://petstore.swagger.io/api
- url: http://localhost:3000import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({ serverIndex: 0 }),
plugins: [],
})import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({ serverIndex: 1 }),
plugins: [],
})serverVariables
Values substituted into {variable} placeholders in the selected server URL. Only used when serverIndex is set. Variables you do not provide use their default value from the spec.
| Type: | Record<string, string> |
|---|---|
| Required: | false |
openapi: 3.0.3
servers:
- url: https://api.{env}.example.com
variables:
env:
default: dev
enum: [dev, staging, prod]import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({
serverIndex: 0,
serverVariables: { env: 'prod' },
}),
plugins: [],
})
// baseURL becomes: https://api.prod.example.comdiscriminator
How discriminator fields on oneOf/anyOf schemas are interpreted.
'strict'(default) — child schemas stay exactly as written. The discriminator narrows types at the call site but child shapes are not modified.'inherit'— Kubb propagates the discriminator property with the appropriate literal value into each child schema, so each branch'stypefield is precisely typed.
| Type: | 'strict' | 'inherit' |
|---|---|
| Required: | false |
| Default: | 'strict' |
openapi: 3.0.3
components:
schemas:
Animal:
required: [type]
type: object
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
discriminator:
propertyName: type
mapping:
cat: '#/components/schemas/Cat'
dog: '#/components/schemas/Dog'
Cat:
type: object
properties:
type:
type: string
indoor:
type: boolean
Dog:
type: object
properties:
type:
type: string
name:
type: stringexport type Cat = {
type: string
indoor?: boolean
}
export type Dog = {
type: string
name?: string
}
export type Animal = Cat | Dogexport type Cat = {
type: 'cat'
indoor?: boolean
}
export type Dog = {
type: 'dog'
name?: string
}
export type Animal = Cat | Dogstrict
Child schemas are emitted verbatim. The discriminator property has whatever type the OpenAPI spec gave it.
inherit
Each child schema gets the discriminator value as a literal (type: 'cat', type: 'dog'). Catches more bugs at compile time.
dateType
How format: date-time schemas are represented downstream.
false— fall through to a plainstring(no validation).'string'(default) — datetime string (z.string().datetime(), ISO 8601).'stringOffset'— datetime string with timezone offset.'stringLocal'— local datetime string (no timezone).'date'— JavaScriptDateobject. Best for client code; requires JSON parsing to revive.
| Type: | false | 'string' | 'stringOffset' | 'stringLocal' | 'date' |
|---|---|
| Required: | false |
| Default: | 'string' |
// format: date-time → plain string
type CreatedAt = string// format: date-time → ISO 8601 datetime string
type CreatedAt = string// format: date-time → ISO 8601 datetime with offset
type CreatedAt = string// format: date-time → local ISO 8601 datetime
type CreatedAt = string// format: date-time → JavaScript Date
type CreatedAt = DateintegerType
How type: integer (and format: int64) maps to TypeScript.
'number'(default) — fits most JSON APIs; loses precision aboveNumber.MAX_SAFE_INTEGER.'bigint'— exact for 64-bit IDs, butJSON.stringify/JSON.parsecannot round-trip it. Use only when you also handle bigint serialization explicitly.
| Type: | 'number' | 'bigint' |
|---|---|
| Required: | false |
| Default: | 'number' |
type Pet = {
id: number
}type Pet = {
id: bigint
}unknownType
AST type used when a schema's type cannot be inferred from the spec (additionalProperties: true, missing type, etc.).
Pick 'unknown' to force callers to narrow before using the value. 'any' is the loosest; 'void' is rarely useful but matches some legacy APIs.
| Type: | 'any' | 'unknown' | 'void' |
|---|---|
| Required: | false |
| Default: | 'any' |
type Pet = {
extra: any
}type Pet = {
extra: unknown
}type Pet = {
extra: void
}emptySchemaType
AST type used for fully empty schemas ({}). Defaults to the value of unknownType. Override only when empty schemas should be treated differently from unresolvable ones.
| Type: | 'any' | 'unknown' | 'void' |
|---|---|
| Required: | false |
| Default: | unknownType | 'any' |
TIP
A common pattern: unknownType: 'unknown' for safety, emptySchemaType: 'any' to keep empty 204 response bodies frictionless to use.
// empty schema {} → any
type EmptyModel = any// empty schema {} → unknown
type EmptyModel = unknownenumSuffix
Suffix appended to derived enum names when Kubb has to invent one (typically for inline enums on object properties).
Inline enums on a status property would be named statusEnum with the default. Change this to align with your project's naming convention.
| Type: | string |
|---|---|
| Required: | false |
| Default: | 'enum' |
// Property `status` with inline enum values
const statusEnum = { available: 'available', pending: 'pending' } as const
type StatusEnum = (typeof statusEnum)[keyof typeof statusEnum]const statusType = { available: 'available', pending: 'pending' } as const
type StatusType = (typeof statusType)[keyof typeof statusType]Example
import { defineConfig } from 'kubb'
import { adapterOas } from '@kubb/adapter-oas'
import { pluginTs } from '@kubb/plugin-ts'
export default defineConfig({
input: { path: './petStore.yaml' },
output: { path: './src/gen' },
adapter: adapterOas({
validate: true,
serverIndex: 0,
serverVariables: { env: 'prod' },
discriminator: 'inherit',
dateType: 'date',
integerType: 'number',
unknownType: 'unknown',
emptySchemaType: 'unknown',
enumSuffix: 'enum',
}),
plugins: [
pluginTs(),
],
})