@kubb/adapter-oas 5.0.0-beta.3 → 5.0.0-beta.30
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/README.md +98 -0
- package/dist/index.cjs +778 -417
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +37 -66
- package/dist/index.js +778 -414
- package/dist/index.js.map +1 -1
- package/extension.yaml +431 -0
- package/package.json +6 -4
- package/src/adapter.bench.ts +64 -0
- package/src/adapter.ts +90 -48
- package/src/dialect.ts +38 -0
- package/src/discriminator.ts +57 -40
- package/src/factory.ts +1 -4
- package/src/index.ts +2 -2
- package/src/parser.ts +219 -134
- package/src/refs.ts +16 -4
- package/src/resolvers.ts +50 -21
- package/src/stream.ts +175 -0
- package/src/types.ts +21 -11
package/extension.yaml
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
$schema: https://kubb.dev/schemas/extension.json
|
|
2
|
+
kind: adapter
|
|
3
|
+
id: adapter-oas
|
|
4
|
+
name: OpenAPI
|
|
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
|
+
category: openapi
|
|
7
|
+
type: official
|
|
8
|
+
npmPackage: '@kubb/adapter-oas'
|
|
9
|
+
docsPath: /adapters/adapter-oas
|
|
10
|
+
repo: https://github.com/kubb-labs/kubb
|
|
11
|
+
maintainers:
|
|
12
|
+
- name: Stijn Van Hulle
|
|
13
|
+
github: stijnvanhulle
|
|
14
|
+
compatibility:
|
|
15
|
+
kubb: '>=5.0.0'
|
|
16
|
+
node: '>=22'
|
|
17
|
+
tags:
|
|
18
|
+
- openapi
|
|
19
|
+
- swagger
|
|
20
|
+
- api-spec
|
|
21
|
+
- parser
|
|
22
|
+
- converter
|
|
23
|
+
resources:
|
|
24
|
+
documentation: https://kubb.dev/adapters/adapter-oas
|
|
25
|
+
repository: https://github.com/kubb-labs/kubb
|
|
26
|
+
issues: https://github.com/kubb-labs/kubb/issues
|
|
27
|
+
changelog: https://github.com/kubb-labs/kubb/blob/main/packages/adapter-oas/CHANGELOG.md
|
|
28
|
+
featured: true
|
|
29
|
+
icon:
|
|
30
|
+
light: https://kubb.dev/feature/openapi.svg
|
|
31
|
+
intro: |-
|
|
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
|
+
|
|
34
|
+
Configure it once on `defineConfig`. Its choices (date representation, integer width, server URL) apply to every plugin in the build.
|
|
35
|
+
options:
|
|
36
|
+
- name: validate
|
|
37
|
+
type: boolean
|
|
38
|
+
required: false
|
|
39
|
+
default: 'true'
|
|
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
|
+
|
|
58
|
+
- name: contentType
|
|
59
|
+
type: "'application/json' | string"
|
|
60
|
+
required: false
|
|
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`).
|
|
65
|
+
codeBlock:
|
|
66
|
+
lang: typescript
|
|
67
|
+
title: kubb.config.ts
|
|
68
|
+
twoslash: false
|
|
69
|
+
code: |-
|
|
70
|
+
import { defineConfig } from 'kubb'
|
|
71
|
+
import { adapterOas } from '@kubb/adapter-oas'
|
|
72
|
+
|
|
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
|
+
|
|
80
|
+
- name: serverIndex
|
|
81
|
+
type: number
|
|
82
|
+
required: false
|
|
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.
|
|
89
|
+
examples:
|
|
90
|
+
- name: OpenAPI spec
|
|
91
|
+
files:
|
|
92
|
+
- lang: yaml
|
|
93
|
+
twoslash: false
|
|
94
|
+
code: |-
|
|
95
|
+
openapi: 3.0.3
|
|
96
|
+
servers:
|
|
97
|
+
- url: http://petstore.swagger.io/api
|
|
98
|
+
- url: http://localhost:3000
|
|
99
|
+
- name: 'Use the production server'
|
|
100
|
+
files:
|
|
101
|
+
- lang: typescript
|
|
102
|
+
twoslash: false
|
|
103
|
+
code: |-
|
|
104
|
+
import { defineConfig } from 'kubb'
|
|
105
|
+
import { adapterOas } from '@kubb/adapter-oas'
|
|
106
|
+
|
|
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'
|
|
114
|
+
files:
|
|
115
|
+
- lang: typescript
|
|
116
|
+
twoslash: false
|
|
117
|
+
code: |-
|
|
118
|
+
import { defineConfig } from 'kubb'
|
|
119
|
+
import { adapterOas } from '@kubb/adapter-oas'
|
|
120
|
+
|
|
121
|
+
export default defineConfig({
|
|
122
|
+
input: { path: './petStore.yaml' },
|
|
123
|
+
output: { path: './src/gen' },
|
|
124
|
+
adapter: adapterOas({ serverIndex: 1 }),
|
|
125
|
+
plugins: [],
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
- name: serverVariables
|
|
129
|
+
type: Record<string, string>
|
|
130
|
+
required: false
|
|
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.
|
|
133
|
+
examples:
|
|
134
|
+
- name: OpenAPI spec
|
|
135
|
+
files:
|
|
136
|
+
- lang: yaml
|
|
137
|
+
twoslash: false
|
|
138
|
+
code: |-
|
|
139
|
+
openapi: 3.0.3
|
|
140
|
+
servers:
|
|
141
|
+
- url: https://api.{env}.example.com
|
|
142
|
+
variables:
|
|
143
|
+
env:
|
|
144
|
+
default: dev
|
|
145
|
+
enum: [dev, staging, prod]
|
|
146
|
+
- name: kubb.config.ts
|
|
147
|
+
files:
|
|
148
|
+
- lang: typescript
|
|
149
|
+
twoslash: false
|
|
150
|
+
code: |-
|
|
151
|
+
import { defineConfig } from 'kubb'
|
|
152
|
+
import { adapterOas } from '@kubb/adapter-oas'
|
|
153
|
+
|
|
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: [],
|
|
162
|
+
})
|
|
163
|
+
// baseURL becomes: https://api.prod.example.com
|
|
164
|
+
|
|
165
|
+
- name: discriminator
|
|
166
|
+
type: "'strict' | 'inherit'"
|
|
167
|
+
required: false
|
|
168
|
+
default: "'strict'"
|
|
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.
|
|
174
|
+
details:
|
|
175
|
+
- title: strict
|
|
176
|
+
body: 'Child schemas are emitted verbatim. The discriminator property has whatever type the OpenAPI spec gave it.'
|
|
177
|
+
- title: inherit
|
|
178
|
+
body: "Each child schema gets the discriminator value as a literal (`type: 'cat'`, `type: 'dog'`). Catches more bugs at compile time."
|
|
179
|
+
examples:
|
|
180
|
+
- name: OpenAPI spec
|
|
181
|
+
files:
|
|
182
|
+
- lang: yaml
|
|
183
|
+
twoslash: false
|
|
184
|
+
code: |-
|
|
185
|
+
openapi: 3.0.3
|
|
186
|
+
components:
|
|
187
|
+
schemas:
|
|
188
|
+
Animal:
|
|
189
|
+
required: [type]
|
|
190
|
+
type: object
|
|
191
|
+
oneOf:
|
|
192
|
+
- $ref: '#/components/schemas/Cat'
|
|
193
|
+
- $ref: '#/components/schemas/Dog'
|
|
194
|
+
discriminator:
|
|
195
|
+
propertyName: type
|
|
196
|
+
mapping:
|
|
197
|
+
cat: '#/components/schemas/Cat'
|
|
198
|
+
dog: '#/components/schemas/Dog'
|
|
199
|
+
Cat:
|
|
200
|
+
type: object
|
|
201
|
+
properties:
|
|
202
|
+
type:
|
|
203
|
+
type: string
|
|
204
|
+
indoor:
|
|
205
|
+
type: boolean
|
|
206
|
+
Dog:
|
|
207
|
+
type: object
|
|
208
|
+
properties:
|
|
209
|
+
type:
|
|
210
|
+
type: string
|
|
211
|
+
name:
|
|
212
|
+
type: string
|
|
213
|
+
- name: "'strict' (default)"
|
|
214
|
+
files:
|
|
215
|
+
- lang: typescript
|
|
216
|
+
twoslash: false
|
|
217
|
+
code: |-
|
|
218
|
+
export type Cat = {
|
|
219
|
+
type: string
|
|
220
|
+
indoor?: boolean
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export type Dog = {
|
|
224
|
+
type: string
|
|
225
|
+
name?: string
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export type Animal = Cat | Dog
|
|
229
|
+
- name: "'inherit'"
|
|
230
|
+
files:
|
|
231
|
+
- lang: typescript
|
|
232
|
+
twoslash: false
|
|
233
|
+
code: |-
|
|
234
|
+
export type Cat = {
|
|
235
|
+
type: 'cat'
|
|
236
|
+
indoor?: boolean
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export type Dog = {
|
|
240
|
+
type: 'dog'
|
|
241
|
+
name?: string
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export type Animal = Cat | Dog
|
|
245
|
+
|
|
246
|
+
- name: dateType
|
|
247
|
+
type: false | 'string' | 'stringOffset' | 'stringLocal' | 'date'
|
|
248
|
+
required: false
|
|
249
|
+
default: "'string'"
|
|
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.
|
|
258
|
+
examples:
|
|
259
|
+
- name: 'false'
|
|
260
|
+
files:
|
|
261
|
+
- lang: typescript
|
|
262
|
+
twoslash: false
|
|
263
|
+
code: |-
|
|
264
|
+
// format: date-time → plain string
|
|
265
|
+
type CreatedAt = string
|
|
266
|
+
- name: "'string' (default)"
|
|
267
|
+
files:
|
|
268
|
+
- lang: typescript
|
|
269
|
+
twoslash: false
|
|
270
|
+
code: |-
|
|
271
|
+
// format: date-time → ISO 8601 datetime string
|
|
272
|
+
type CreatedAt = string
|
|
273
|
+
- name: "'stringOffset'"
|
|
274
|
+
files:
|
|
275
|
+
- lang: typescript
|
|
276
|
+
twoslash: false
|
|
277
|
+
code: |-
|
|
278
|
+
// format: date-time → ISO 8601 datetime with offset
|
|
279
|
+
type CreatedAt = string
|
|
280
|
+
- name: "'stringLocal'"
|
|
281
|
+
files:
|
|
282
|
+
- lang: typescript
|
|
283
|
+
twoslash: false
|
|
284
|
+
code: |-
|
|
285
|
+
// format: date-time → local ISO 8601 datetime
|
|
286
|
+
type CreatedAt = string
|
|
287
|
+
- name: "'date'"
|
|
288
|
+
files:
|
|
289
|
+
- lang: typescript
|
|
290
|
+
twoslash: false
|
|
291
|
+
code: |-
|
|
292
|
+
// format: date-time → JavaScript Date
|
|
293
|
+
type CreatedAt = Date
|
|
294
|
+
|
|
295
|
+
- name: integerType
|
|
296
|
+
type: "'number' | 'bigint'"
|
|
297
|
+
required: false
|
|
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.
|
|
304
|
+
examples:
|
|
305
|
+
- name: "'number' (default)"
|
|
306
|
+
files:
|
|
307
|
+
- lang: typescript
|
|
308
|
+
twoslash: false
|
|
309
|
+
code: |-
|
|
310
|
+
type Pet = {
|
|
311
|
+
id: number
|
|
312
|
+
}
|
|
313
|
+
- name: "'bigint'"
|
|
314
|
+
files:
|
|
315
|
+
- lang: typescript
|
|
316
|
+
twoslash: false
|
|
317
|
+
code: |-
|
|
318
|
+
type Pet = {
|
|
319
|
+
id: bigint
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
- name: unknownType
|
|
323
|
+
type: "'any' | 'unknown' | 'void'"
|
|
324
|
+
required: false
|
|
325
|
+
default: "'any'"
|
|
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.
|
|
330
|
+
examples:
|
|
331
|
+
- name: "'any' (default)"
|
|
332
|
+
files:
|
|
333
|
+
- lang: typescript
|
|
334
|
+
twoslash: false
|
|
335
|
+
code: |-
|
|
336
|
+
type Pet = {
|
|
337
|
+
extra: any
|
|
338
|
+
}
|
|
339
|
+
- name: "'unknown'"
|
|
340
|
+
files:
|
|
341
|
+
- lang: typescript
|
|
342
|
+
twoslash: false
|
|
343
|
+
code: |-
|
|
344
|
+
type Pet = {
|
|
345
|
+
extra: unknown
|
|
346
|
+
}
|
|
347
|
+
- name: "'void'"
|
|
348
|
+
files:
|
|
349
|
+
- lang: typescript
|
|
350
|
+
twoslash: false
|
|
351
|
+
code: |-
|
|
352
|
+
type Pet = {
|
|
353
|
+
extra: void
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
- name: emptySchemaType
|
|
357
|
+
type: "'any' | 'unknown' | 'void'"
|
|
358
|
+
required: false
|
|
359
|
+
default: unknownType | 'any'
|
|
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.
|
|
364
|
+
examples:
|
|
365
|
+
- name: "'any' (default)"
|
|
366
|
+
files:
|
|
367
|
+
- lang: typescript
|
|
368
|
+
twoslash: false
|
|
369
|
+
code: |-
|
|
370
|
+
// empty schema {} → any
|
|
371
|
+
type EmptyModel = any
|
|
372
|
+
- name: "'unknown'"
|
|
373
|
+
files:
|
|
374
|
+
- lang: typescript
|
|
375
|
+
twoslash: false
|
|
376
|
+
code: |-
|
|
377
|
+
// empty schema {} → unknown
|
|
378
|
+
type EmptyModel = unknown
|
|
379
|
+
|
|
380
|
+
- name: enumSuffix
|
|
381
|
+
type: string
|
|
382
|
+
required: false
|
|
383
|
+
default: "'enum'"
|
|
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.
|
|
388
|
+
examples:
|
|
389
|
+
- name: "'enum' (default)"
|
|
390
|
+
files:
|
|
391
|
+
- lang: typescript
|
|
392
|
+
twoslash: false
|
|
393
|
+
code: |-
|
|
394
|
+
// Property `status` with inline enum values
|
|
395
|
+
const statusEnum = { available: 'available', pending: 'pending' } as const
|
|
396
|
+
type StatusEnum = (typeof statusEnum)[keyof typeof statusEnum]
|
|
397
|
+
- name: "'type'"
|
|
398
|
+
files:
|
|
399
|
+
- lang: typescript
|
|
400
|
+
twoslash: false
|
|
401
|
+
code: |-
|
|
402
|
+
const statusType = { available: 'available', pending: 'pending' } as const
|
|
403
|
+
type StatusType = (typeof statusType)[keyof typeof statusType]
|
|
404
|
+
examples:
|
|
405
|
+
- name: kubb.config.ts
|
|
406
|
+
files:
|
|
407
|
+
- lang: typescript
|
|
408
|
+
twoslash: false
|
|
409
|
+
code: |-
|
|
410
|
+
import { defineConfig } from 'kubb'
|
|
411
|
+
import { adapterOas } from '@kubb/adapter-oas'
|
|
412
|
+
import { pluginTs } from '@kubb/plugin-ts'
|
|
413
|
+
|
|
414
|
+
export default defineConfig({
|
|
415
|
+
input: { path: './petStore.yaml' },
|
|
416
|
+
output: { path: './src/gen' },
|
|
417
|
+
adapter: adapterOas({
|
|
418
|
+
validate: true,
|
|
419
|
+
serverIndex: 0,
|
|
420
|
+
serverVariables: { env: 'prod' },
|
|
421
|
+
discriminator: 'inherit',
|
|
422
|
+
dateType: 'date',
|
|
423
|
+
integerType: 'number',
|
|
424
|
+
unknownType: 'unknown',
|
|
425
|
+
emptySchemaType: 'unknown',
|
|
426
|
+
enumSuffix: 'enum',
|
|
427
|
+
}),
|
|
428
|
+
plugins: [
|
|
429
|
+
pluginTs(),
|
|
430
|
+
],
|
|
431
|
+
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/adapter-oas",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
4
|
-
"description": "OpenAPI
|
|
3
|
+
"version": "5.0.0-beta.30",
|
|
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",
|
|
7
7
|
"codegen",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"src",
|
|
23
23
|
"dist",
|
|
24
|
+
"extension.yaml",
|
|
24
25
|
"!/**/**.test.**",
|
|
25
26
|
"!/**/__tests__/**",
|
|
26
27
|
"!/**/__snapshots__/**"
|
|
@@ -42,11 +43,11 @@
|
|
|
42
43
|
"registry": "https://registry.npmjs.org/"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@redocly/openapi-core": "^2.
|
|
46
|
+
"@redocly/openapi-core": "^2.31.2",
|
|
46
47
|
"oas": "^32.1.18",
|
|
47
48
|
"oas-normalize": "^16.0.4",
|
|
48
49
|
"swagger2openapi": "^7.0.8",
|
|
49
|
-
"@kubb/core": "5.0.0-beta.
|
|
50
|
+
"@kubb/core": "5.0.0-beta.30"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@types/swagger2openapi": "^7.0.4",
|
|
@@ -67,6 +68,7 @@
|
|
|
67
68
|
"release": "pnpm publish --no-git-check",
|
|
68
69
|
"release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
|
|
69
70
|
"start": "tsdown --watch",
|
|
71
|
+
"bench": "vitest bench",
|
|
70
72
|
"test": "vitest --passWithNoTests",
|
|
71
73
|
"typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
|
|
72
74
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { bench, describe } from 'vitest'
|
|
5
|
+
import { adapterOas } from './adapter.ts'
|
|
6
|
+
import { parseDocument } from './factory.ts'
|
|
7
|
+
import { parseOas } from './parser.ts'
|
|
8
|
+
import type { Document } from './types.ts'
|
|
9
|
+
import type { AdapterSource } from '@kubb/core'
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
12
|
+
const __dirname = path.dirname(__filename)
|
|
13
|
+
|
|
14
|
+
const petStorePath = path.resolve(__dirname, '../mocks/petStore.yaml')
|
|
15
|
+
const stripeSpecPath = '/tmp/kubb-stripe-spec3.json'
|
|
16
|
+
const hasStripe = existsSync(stripeSpecPath)
|
|
17
|
+
|
|
18
|
+
let petStoreDoc: Document | undefined
|
|
19
|
+
|
|
20
|
+
async function getPetStoreDocument(): Promise<Document> {
|
|
21
|
+
if (!petStoreDoc) {
|
|
22
|
+
petStoreDoc = await parseDocument(petStorePath)
|
|
23
|
+
}
|
|
24
|
+
return petStoreDoc
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('parseOas() performance', () => {
|
|
28
|
+
bench(
|
|
29
|
+
'petStore spec',
|
|
30
|
+
async () => {
|
|
31
|
+
const doc = await getPetStoreDocument()
|
|
32
|
+
parseOas(doc)
|
|
33
|
+
},
|
|
34
|
+
{ iterations: 5, warmupIterations: 1 },
|
|
35
|
+
)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe.skipIf(!hasStripe)('Stripe spec — batch vs streaming (1,385 schemas)', () => {
|
|
39
|
+
const stripeSource: AdapterSource = { type: 'path', path: stripeSpecPath }
|
|
40
|
+
|
|
41
|
+
bench(
|
|
42
|
+
'batch — adapter.parse()',
|
|
43
|
+
async () => {
|
|
44
|
+
const adapter = adapterOas({ validate: false })
|
|
45
|
+
await adapter.parse(stripeSource)
|
|
46
|
+
},
|
|
47
|
+
{ iterations: 3, warmupIterations: 1 },
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
bench(
|
|
51
|
+
'streaming — adapter.stream() drain',
|
|
52
|
+
async () => {
|
|
53
|
+
const adapter = adapterOas({ validate: false })
|
|
54
|
+
const stream = await adapter.stream!(stripeSource)
|
|
55
|
+
for await (const _ of stream.schemas) {
|
|
56
|
+
/* drain */
|
|
57
|
+
}
|
|
58
|
+
for await (const _ of stream.operations) {
|
|
59
|
+
/* drain */
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{ iterations: 3, warmupIterations: 1 },
|
|
63
|
+
)
|
|
64
|
+
})
|