@kubb/adapter-oas 5.0.0-beta.21 → 5.0.0-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/extension.yaml CHANGED
@@ -2,7 +2,7 @@ $schema: https://kubb.dev/schemas/extension.json
2
2
  kind: adapter
3
3
  id: adapter-oas
4
4
  name: OpenAPI
5
- description: Parse and convert OpenAPI 2.0, 3.0, and 3.1 specifications into Kubb's universal AST with full support for discriminators, date types, and server configuration.
5
+ description: 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.
6
6
  category: openapi
7
7
  type: official
8
8
  npmPackage: '@kubb/adapter-oas'
@@ -29,63 +29,112 @@ featured: true
29
29
  icon:
30
30
  light: https://kubb.dev/feature/openapi.svg
31
31
  intro: |-
32
- The OpenAPI adapter parses and converts your OpenAPI specification into Kubb's internal AST (Abstract Syntax Tree), which all downstream plugins consume.
32
+ 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.
33
33
 
34
- The adapter is configured once in `defineConfig` and applies globally to all plugins.
34
+ Configure it once on `defineConfig`. Its choices (date representation, integer width, server URL) apply to every plugin in the build.
35
35
  options:
36
36
  - name: validate
37
37
  type: boolean
38
38
  required: false
39
39
  default: 'true'
40
- description: Validate the OpenAPI spec before parsing using `@readme/openapi-parser`.
40
+ description: |
41
+ 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.
42
+ examples:
43
+ - name: kubb.config.ts
44
+ files:
45
+ - lang: typescript
46
+ twoslash: false
47
+ code: |
48
+ import { defineConfig } from 'kubb'
49
+ import { adapterOas } from '@kubb/adapter-oas'
50
+
51
+ export default defineConfig({
52
+ input: { path: './petStore.yaml' },
53
+ output: { path: './src/gen' },
54
+ adapter: adapterOas({ validate: false }),
55
+ plugins: [],
56
+ })
57
+
41
58
  - name: contentType
42
59
  type: "'application/json' | string"
43
60
  required: false
44
- description: Preferred content-type used when extracting request/response schemas from the spec. Defaults to the first valid JSON media type found in the spec.
61
+ description: |
62
+ Preferred media type when extracting request and response schemas. Operations with multiple media types fall back to this one.
63
+
64
+ Defaults to the first JSON-compatible media type found in the spec (`application/json`, `application/vnd.api+json`, any `*+json`).
45
65
  codeBlock:
46
66
  lang: typescript
47
67
  title: kubb.config.ts
48
68
  twoslash: false
49
69
  code: |-
70
+ import { defineConfig } from 'kubb'
50
71
  import { adapterOas } from '@kubb/adapter-oas'
51
72
 
52
- adapterOas({ contentType: 'application/vnd.api+json' })
73
+ export default defineConfig({
74
+ input: { path: './petStore.yaml' },
75
+ output: { path: './src/gen' },
76
+ adapter: adapterOas({ contentType: 'application/vnd.api+json' }),
77
+ plugins: [],
78
+ })
79
+
53
80
  - name: serverIndex
54
81
  type: number
55
82
  required: false
56
- description: Index into the `servers` array from your OpenAPI spec for computing `baseURL`.
57
- tip: Defining the server here will make it possible to use that endpoint as `baseURL` in other plugins.
83
+ description: |
84
+ 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`, ...).
85
+
86
+ Most projects pick `0` for the primary server. Use higher indices to point at staging or localhost when your spec defines multiple environments.
87
+ tip: |
88
+ Plugins read `baseURL` from this server unless they override it explicitly.
58
89
  examples:
59
- - name: OpenAPI
90
+ - name: OpenAPI spec
60
91
  files:
61
92
  - lang: yaml
93
+ twoslash: false
62
94
  code: |-
63
95
  openapi: 3.0.3
64
96
  servers:
65
97
  - url: http://petstore.swagger.io/api
66
98
  - url: http://localhost:3000
67
- - name: serverIndex 0
99
+ - name: 'Use the production server'
68
100
  files:
69
101
  - lang: typescript
102
+ twoslash: false
70
103
  code: |-
104
+ import { defineConfig } from 'kubb'
71
105
  import { adapterOas } from '@kubb/adapter-oas'
72
106
 
73
- adapterOas({ serverIndex: 0 })
74
- - name: serverIndex 1
107
+ export default defineConfig({
108
+ input: { path: './petStore.yaml' },
109
+ output: { path: './src/gen' },
110
+ adapter: adapterOas({ serverIndex: 0 }),
111
+ plugins: [],
112
+ })
113
+ - name: 'Use the localhost server'
75
114
  files:
76
115
  - lang: typescript
116
+ twoslash: false
77
117
  code: |-
118
+ import { defineConfig } from 'kubb'
78
119
  import { adapterOas } from '@kubb/adapter-oas'
79
120
 
80
- adapterOas({ serverIndex: 1 })
121
+ export default defineConfig({
122
+ input: { path: './petStore.yaml' },
123
+ output: { path: './src/gen' },
124
+ adapter: adapterOas({ serverIndex: 1 }),
125
+ plugins: [],
126
+ })
127
+
81
128
  - name: serverVariables
82
129
  type: Record<string, string>
83
130
  required: false
84
- description: Override values for `{variable}` placeholders in the selected server URL. Only used when `serverIndex` is set. Variables not provided fall back to their `default` value from the spec.
131
+ description: |
132
+ 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.
85
133
  examples:
86
- - name: OpenAPI
134
+ - name: OpenAPI spec
87
135
  files:
88
136
  - lang: yaml
137
+ twoslash: false
89
138
  code: |-
90
139
  openapi: 3.0.3
91
140
  servers:
@@ -97,28 +146,41 @@ options:
97
146
  - name: kubb.config.ts
98
147
  files:
99
148
  - lang: typescript
149
+ twoslash: false
100
150
  code: |-
151
+ import { defineConfig } from 'kubb'
101
152
  import { adapterOas } from '@kubb/adapter-oas'
102
153
 
103
- adapterOas({
104
- serverIndex: 0,
105
- serverVariables: { env: 'prod' },
154
+ export default defineConfig({
155
+ input: { path: './petStore.yaml' },
156
+ output: { path: './src/gen' },
157
+ adapter: adapterOas({
158
+ serverIndex: 0,
159
+ serverVariables: { env: 'prod' },
160
+ }),
161
+ plugins: [],
106
162
  })
107
- // Results in baseURL: https://api.prod.example.com
163
+ // baseURL becomes: https://api.prod.example.com
164
+
108
165
  - name: discriminator
109
166
  type: "'strict' | 'inherit'"
110
167
  required: false
111
168
  default: "'strict'"
112
- description: How the discriminator field is interpreted when processing `oneOf`/`anyOf` schemas.
169
+ description: |
170
+ How `discriminator` fields on `oneOf`/`anyOf` schemas are interpreted.
171
+
172
+ - `'strict'` (default) — child schemas stay exactly as written. The discriminator narrows types at the call site but child shapes are not modified.
173
+ - `'inherit'` — Kubb propagates the discriminator property with the appropriate literal value into each child schema, so each branch's `type` field is precisely typed.
113
174
  details:
114
175
  - title: strict
115
- body: Uses `oneOf` schemas as written in the spec. The discriminator is used for type narrowing but child schemas are not modified.
176
+ body: 'Child schemas are emitted verbatim. The discriminator property has whatever type the OpenAPI spec gave it.'
116
177
  - title: inherit
117
- body: Propagates the discriminator property with appropriate enum values into each child schema, ensuring type safety and enabling better code generation.
178
+ body: "Each child schema gets the discriminator value as a literal (`type: 'cat'`, `type: 'dog'`). Catches more bugs at compile time."
118
179
  examples:
119
- - name: OpenAPI
180
+ - name: OpenAPI spec
120
181
  files:
121
182
  - lang: yaml
183
+ twoslash: false
122
184
  code: |-
123
185
  openapi: 3.0.3
124
186
  components:
@@ -148,9 +210,10 @@ options:
148
210
  type: string
149
211
  name:
150
212
  type: string
151
- - name: strict
213
+ - name: "'strict' (default)"
152
214
  files:
153
215
  - lang: typescript
216
+ twoslash: false
154
217
  code: |-
155
218
  export type Cat = {
156
219
  type: string
@@ -163,9 +226,10 @@ options:
163
226
  }
164
227
 
165
228
  export type Animal = Cat | Dog
166
- - name: inherit
229
+ - name: "'inherit'"
167
230
  files:
168
231
  - lang: typescript
232
+ twoslash: false
169
233
  code: |-
170
234
  export type Cat = {
171
235
  type: 'cat'
@@ -178,62 +242,70 @@ options:
178
242
  }
179
243
 
180
244
  export type Animal = Cat | Dog
245
+
181
246
  - name: dateType
182
247
  type: false | 'string' | 'stringOffset' | 'stringLocal' | 'date'
183
248
  required: false
184
249
  default: "'string'"
185
- description: "How `format: 'date-time'` schemas are represented in the generated AST and downstream output."
186
- details:
187
- - title: 'false'
188
- body: Falls through to a plain `string` type.
189
- - title: "'string'"
190
- body: Emits a datetime string node (e.g. `z.string().datetime()`).
191
- - title: "'stringOffset'"
192
- body: 'Emits a datetime node with timezone offset (`{ offset: true }`).'
193
- - title: "'stringLocal'"
194
- body: 'Emits a local datetime node (`{ local: true }`).'
195
- - title: "'date'"
196
- body: Emits a `date` node (JavaScript `Date` object).
250
+ description: |
251
+ How `format: date-time` schemas are represented downstream.
252
+
253
+ - `false` — fall through to a plain `string` (no validation).
254
+ - `'string'` (default) — datetime string (`z.string().datetime()`, ISO 8601).
255
+ - `'stringOffset'` datetime string with timezone offset.
256
+ - `'stringLocal'` — local datetime string (no timezone).
257
+ - `'date'` JavaScript `Date` object. Best for client code; requires JSON parsing to revive.
197
258
  examples:
198
259
  - name: 'false'
199
260
  files:
200
261
  - lang: typescript
262
+ twoslash: false
201
263
  code: |-
202
264
  // format: date-time → plain string
203
265
  type CreatedAt = string
204
266
  - name: "'string' (default)"
205
267
  files:
206
268
  - lang: typescript
269
+ twoslash: false
207
270
  code: |-
208
- // format: date-time → datetime string
209
- type CreatedAt = string // validated as ISO 8601 datetime
271
+ // format: date-time → ISO 8601 datetime string
272
+ type CreatedAt = string
210
273
  - name: "'stringOffset'"
211
274
  files:
212
275
  - lang: typescript
276
+ twoslash: false
213
277
  code: |-
214
- // format: date-time → datetime string with offset
215
- type CreatedAt = string // validated as ISO 8601 datetime with offset
278
+ // format: date-time → ISO 8601 datetime with offset
279
+ type CreatedAt = string
216
280
  - name: "'stringLocal'"
217
281
  files:
218
282
  - lang: typescript
283
+ twoslash: false
219
284
  code: |-
220
- // format: date-time → local datetime string
221
- type CreatedAt = string // validated as local ISO 8601 datetime
285
+ // format: date-time → local ISO 8601 datetime
286
+ type CreatedAt = string
222
287
  - name: "'date'"
223
288
  files:
224
289
  - lang: typescript
290
+ twoslash: false
225
291
  code: |-
226
292
  // format: date-time → JavaScript Date
227
293
  type CreatedAt = Date
294
+
228
295
  - name: integerType
229
296
  type: "'number' | 'bigint'"
230
297
  required: false
231
- default: "'bigint'"
232
- description: "Whether `type: 'integer'` and `format: 'int64'` produce `number` or `bigint` nodes."
298
+ default: "'number'"
299
+ description: |
300
+ How `type: integer` (and `format: int64`) maps to TypeScript.
301
+
302
+ - `'number'` (default) — fits most JSON APIs; loses precision above `Number.MAX_SAFE_INTEGER`.
303
+ - `'bigint'` — exact for 64-bit IDs, but `JSON.stringify`/`JSON.parse` cannot round-trip it. Use only when you also handle bigint serialization explicitly.
233
304
  examples:
234
305
  - name: "'number' (default)"
235
306
  files:
236
307
  - lang: typescript
308
+ twoslash: false
237
309
  code: |-
238
310
  type Pet = {
239
311
  id: number
@@ -241,19 +313,25 @@ options:
241
313
  - name: "'bigint'"
242
314
  files:
243
315
  - lang: typescript
316
+ twoslash: false
244
317
  code: |-
245
318
  type Pet = {
246
319
  id: bigint
247
320
  }
321
+
248
322
  - name: unknownType
249
323
  type: "'any' | 'unknown' | 'void'"
250
324
  required: false
251
325
  default: "'any'"
252
- description: AST type used when no schema type can be inferred from the OpenAPI spec.
326
+ description: |
327
+ AST type used when a schema's type cannot be inferred from the spec (`additionalProperties: true`, missing `type`, etc.).
328
+
329
+ Pick `'unknown'` to force callers to narrow before using the value. `'any'` is the loosest; `'void'` is rarely useful but matches some legacy APIs.
253
330
  examples:
254
331
  - name: "'any' (default)"
255
332
  files:
256
333
  - lang: typescript
334
+ twoslash: false
257
335
  code: |-
258
336
  type Pet = {
259
337
  extra: any
@@ -261,6 +339,7 @@ options:
261
339
  - name: "'unknown'"
262
340
  files:
263
341
  - lang: typescript
342
+ twoslash: false
264
343
  code: |-
265
344
  type Pet = {
266
345
  extra: unknown
@@ -268,65 +347,73 @@ options:
268
347
  - name: "'void'"
269
348
  files:
270
349
  - lang: typescript
350
+ twoslash: false
271
351
  code: |-
272
352
  type Pet = {
273
353
  extra: void
274
354
  }
355
+
275
356
  - name: emptySchemaType
276
357
  type: "'any' | 'unknown' | 'void'"
277
358
  required: false
278
359
  default: unknownType | 'any'
279
- description: AST type used for completely empty schemas (`{}`).
280
- tip: When not set, `emptySchemaType` falls back to the value of `unknownType`. Set it explicitly only when you want a different type for empty schemas than for unresolvable ones.
360
+ description: |
361
+ 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.
362
+ tip: |
363
+ A common pattern: `unknownType: 'unknown'` for safety, `emptySchemaType: 'any'` to keep empty 204 response bodies frictionless to use.
281
364
  examples:
282
365
  - name: "'any' (default)"
283
366
  files:
284
367
  - lang: typescript
368
+ twoslash: false
285
369
  code: |-
286
370
  // empty schema {} → any
287
371
  type EmptyModel = any
288
372
  - name: "'unknown'"
289
373
  files:
290
374
  - lang: typescript
375
+ twoslash: false
291
376
  code: |-
292
377
  // empty schema {} → unknown
293
378
  type EmptyModel = unknown
379
+
294
380
  - name: enumSuffix
295
381
  type: string
296
382
  required: false
297
383
  default: "'enum'"
298
- description: Suffix appended to derived enum names when building nested property schema names.
384
+ description: |
385
+ Suffix appended to derived enum names when Kubb has to invent one (typically for inline enums on object properties).
386
+
387
+ Inline enums on a `status` property would be named `statusEnum` with the default. Change this to align with your project's naming convention.
299
388
  examples:
300
389
  - name: "'enum' (default)"
301
390
  files:
302
391
  - lang: typescript
392
+ twoslash: false
303
393
  code: |-
304
- // property `status` with inline enum values
394
+ // Property `status` with inline enum values
305
395
  const statusEnum = { available: 'available', pending: 'pending' } as const
306
396
  type StatusEnum = (typeof statusEnum)[keyof typeof statusEnum]
307
397
  - name: "'type'"
308
398
  files:
309
399
  - lang: typescript
400
+ twoslash: false
310
401
  code: |-
311
- // enumSuffix: 'type'
312
402
  const statusType = { available: 'available', pending: 'pending' } as const
313
403
  type StatusType = (typeof statusType)[keyof typeof statusType]
314
404
  examples:
315
405
  - name: kubb.config.ts
316
406
  files:
317
407
  - lang: typescript
408
+ twoslash: false
318
409
  code: |-
319
410
  import { defineConfig } from 'kubb'
320
411
  import { adapterOas } from '@kubb/adapter-oas'
321
412
  import { pluginTs } from '@kubb/plugin-ts'
322
413
 
323
414
  export default defineConfig({
324
- input: {
325
- path: './petStore.yaml',
326
- },
327
- output: {
328
- path: './src/gen',
329
- },
415
+ input: { path: './petStore.yaml' },
416
+ output: { path: './src/gen' },
330
417
  adapter: adapterOas({
331
418
  validate: true,
332
419
  serverIndex: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/adapter-oas",
3
- "version": "5.0.0-beta.21",
3
+ "version": "5.0.0-beta.23",
4
4
  "description": "OpenAPI and Swagger adapter for Kubb. Parses and validates OAS 2.0/3.x specifications into a @kubb/ast RootNode for downstream code generation plugins.",
5
5
  "keywords": [
6
6
  "adapter",
@@ -47,7 +47,7 @@
47
47
  "oas": "^32.1.18",
48
48
  "oas-normalize": "^16.0.4",
49
49
  "swagger2openapi": "^7.0.8",
50
- "@kubb/core": "5.0.0-beta.21"
50
+ "@kubb/core": "5.0.0-beta.23"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/swagger2openapi": "^7.0.4",
package/src/adapter.ts CHANGED
@@ -10,15 +10,18 @@ import { createInputStream, preScan, resolveBaseUrl } from './stream.ts'
10
10
  import type { AdapterOas, Document } from './types.ts'
11
11
 
12
12
  /**
13
- * Stable string identifier for the OAS adapter used in Kubb's adapter registry.
13
+ * Canonical adapter name for `@kubb/adapter-oas`. Used for driver lookups.
14
14
  */
15
15
  export const adapterOasName = 'oas' satisfies AdapterOas['name']
16
16
 
17
17
  /**
18
- * Creates the default OpenAPI / Swagger adapter for Kubb.
18
+ * Default Kubb adapter for OpenAPI 2.0, 3.0, and 3.1 specifications. Reads the
19
+ * file at `input.path`, validates it, resolves the base URL, and converts every
20
+ * schema and operation into the universal AST that every downstream plugin
21
+ * consumes.
19
22
  *
20
- * Parses the spec, optionally validates it, resolves the base URL, and converts
21
- * everything into an `InputNode` that downstream plugins consume.
23
+ * Configure once on `defineConfig`. The adapter's choices (date representation,
24
+ * integer width, server URL) apply to every plugin in the build.
22
25
  *
23
26
  * @example
24
27
  * ```ts
@@ -27,8 +30,13 @@ export const adapterOasName = 'oas' satisfies AdapterOas['name']
27
30
  * import { pluginTs } from '@kubb/plugin-ts'
28
31
  *
29
32
  * export default defineConfig({
30
- * adapter: adapterOas({ dateType: 'date', serverIndex: 0 }),
31
- * input: { path: './openapi.yaml' },
33
+ * input: { path: './petStore.yaml' },
34
+ * output: { path: './src/gen' },
35
+ * adapter: adapterOas({
36
+ * serverIndex: 0,
37
+ * discriminator: 'inherit',
38
+ * dateType: 'date',
39
+ * }),
32
40
  * plugins: [pluginTs()],
33
41
  * })
34
42
  * ```
package/src/types.ts CHANGED
@@ -123,8 +123,9 @@ export type ResponseObject = OASResponseObject
123
123
  export type MediaTypeObject = OASMediaTypeObject
124
124
 
125
125
  /**
126
- * Configuration options for the OpenAPI adapter.
127
- * Controls spec validation, content-type selection, and server URL resolution.
126
+ * Configuration options for the OpenAPI adapter. Controls spec validation,
127
+ * content-type selection, server URL resolution, and how types are derived
128
+ * from the spec.
128
129
  *
129
130
  * @example
130
131
  * ```ts
@@ -138,23 +139,28 @@ export type MediaTypeObject = OASMediaTypeObject
138
139
  */
139
140
  export type AdapterOasOptions = {
140
141
  /**
141
- * Validate the OpenAPI spec before parsing.
142
+ * Validate the OpenAPI spec with `@readme/openapi-parser` before parsing.
143
+ * Set to `false` only when you have a known-invalid spec you still want to
144
+ * generate from.
145
+ *
142
146
  * @default true
143
147
  */
144
148
  validate?: boolean
145
149
  /**
146
- * Preferred content-type used when extracting request/response schemas.
147
- * Defaults to the first valid JSON media type found in the spec.
150
+ * Preferred media type when an operation defines several. Defaults to the
151
+ * first JSON-compatible media type found in the spec.
148
152
  */
149
153
  contentType?: ContentType
150
154
  /**
151
- * Index into `oas.api.servers` for computing `baseURL`.
152
- * `0` first server, `1` second server. Omit to leave `baseURL` undefined.
155
+ * Index into the `servers` array from your OpenAPI spec. Used to compute the
156
+ * base URL for plugins that need it. Most projects pick `0` for the primary
157
+ * server. Omit to leave `baseURL` undefined.
153
158
  */
154
159
  serverIndex?: number
155
160
  /**
156
161
  * Override values for `{variable}` placeholders in the selected server URL.
157
- * Only used when `serverIndex` is set.
162
+ * Only used when `serverIndex` is set. Variables you do not provide use
163
+ * their `default` value from the spec.
158
164
  *
159
165
  * @example
160
166
  * ```ts
@@ -165,9 +171,13 @@ export type AdapterOasOptions = {
165
171
  */
166
172
  serverVariables?: Record<string, string>
167
173
  /**
168
- * How the discriminator field is interpreted.
169
- * - `'strict'` uses `oneOf` schemas as written in the spec.
170
- * - `'inherit'` propagates discriminator values into child schemas from `discriminator.mapping`.
174
+ * How the `discriminator` field on `oneOf`/`anyOf` schemas is interpreted.
175
+ * - `'strict'` child schemas stay exactly as written; the discriminator
176
+ * narrows types at the call site but child shapes are not modified.
177
+ * - `'inherit'` — Kubb propagates the discriminator property as a literal
178
+ * value into each child schema, so each branch's discriminator field is
179
+ * precisely typed.
180
+ *
171
181
  * @default 'strict'
172
182
  */
173
183
  discriminator?: 'strict' | 'inherit'