@kubb/adapter-oas 5.0.0-beta.63 → 5.0.0-beta.64
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/dist/index.cjs +50 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +51 -82
- package/dist/index.js.map +1 -1
- package/package.json +4 -6
- package/src/adapter.bench.ts +0 -60
- package/src/adapter.ts +0 -207
- package/src/bundler.ts +0 -71
- package/src/constants.ts +0 -135
- package/src/dedupe.ts +0 -237
- package/src/dialect.ts +0 -42
- package/src/discriminator.ts +0 -132
- package/src/factory.ts +0 -180
- package/src/guards.ts +0 -68
- package/src/index.ts +0 -15
- package/src/mime.ts +0 -21
- package/src/operation.ts +0 -194
- package/src/parser.ts +0 -1129
- package/src/refs.ts +0 -86
- package/src/resolvers.ts +0 -590
- package/src/schemaDiagnostics.ts +0 -76
- package/src/stream.ts +0 -221
- package/src/types.ts +0 -235
- /package/dist/{chunk-C0LytTxp.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/adapter-oas",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.64",
|
|
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",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"directory": "packages/adapter-oas"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"src",
|
|
23
22
|
"dist",
|
|
24
23
|
"!/**/**.test.**",
|
|
25
24
|
"!/**/__tests__/**",
|
|
@@ -43,15 +42,14 @@
|
|
|
43
42
|
},
|
|
44
43
|
"dependencies": {
|
|
45
44
|
"@readme/openapi-parser": "^6.1.3",
|
|
45
|
+
"@scalar/openapi-upgrader": "^0.2.9",
|
|
46
46
|
"api-ref-bundler": "0.5.1",
|
|
47
|
-
"swagger2openapi": "^7.0.8",
|
|
48
47
|
"yaml": "^2.9.0",
|
|
49
|
-
"@kubb/ast": "5.0.0-beta.
|
|
50
|
-
"@kubb/core": "5.0.0-beta.
|
|
48
|
+
"@kubb/ast": "5.0.0-beta.64",
|
|
49
|
+
"@kubb/core": "5.0.0-beta.64"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
52
|
"@types/json-schema": "^7.0.15",
|
|
54
|
-
"@types/swagger2openapi": "^7.0.4",
|
|
55
53
|
"openapi-types": "^12.1.3",
|
|
56
54
|
"@internals/utils": "0.0.0"
|
|
57
55
|
},
|
package/src/adapter.bench.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import { existsSync } from 'node:fs'
|
|
3
|
-
import { bench, describe } from 'vitest'
|
|
4
|
-
import { adapterOas } from './adapter.ts'
|
|
5
|
-
import { parseDocument } from './factory.ts'
|
|
6
|
-
import { parseOas } from './parser.ts'
|
|
7
|
-
import type { Document } from './types.ts'
|
|
8
|
-
import type { AdapterSource } from '@kubb/core'
|
|
9
|
-
|
|
10
|
-
const petStorePath = path.resolve(import.meta.dirname, '../mocks/petStore.yaml')
|
|
11
|
-
const stripeSpecPath = '/tmp/kubb-stripe-spec3.json'
|
|
12
|
-
const hasStripe = existsSync(stripeSpecPath)
|
|
13
|
-
|
|
14
|
-
let petStoreDoc: Document | undefined
|
|
15
|
-
|
|
16
|
-
async function getPetStoreDocument(): Promise<Document> {
|
|
17
|
-
if (!petStoreDoc) {
|
|
18
|
-
petStoreDoc = await parseDocument(petStorePath)
|
|
19
|
-
}
|
|
20
|
-
return petStoreDoc
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('parseOas() performance', () => {
|
|
24
|
-
bench(
|
|
25
|
-
'petStore spec',
|
|
26
|
-
async () => {
|
|
27
|
-
const doc = await getPetStoreDocument()
|
|
28
|
-
parseOas(doc)
|
|
29
|
-
},
|
|
30
|
-
{ iterations: 5, warmupIterations: 1 },
|
|
31
|
-
)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
describe.skipIf(!hasStripe)('Stripe spec — batch vs streaming (1,385 schemas)', () => {
|
|
35
|
-
const stripeSource: AdapterSource = { type: 'path', path: stripeSpecPath }
|
|
36
|
-
|
|
37
|
-
bench(
|
|
38
|
-
'batch — adapter.parse()',
|
|
39
|
-
async () => {
|
|
40
|
-
const adapter = adapterOas({ validate: false })
|
|
41
|
-
await adapter.parse(stripeSource)
|
|
42
|
-
},
|
|
43
|
-
{ iterations: 3, warmupIterations: 1 },
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
bench(
|
|
47
|
-
'streaming — adapter.stream() drain',
|
|
48
|
-
async () => {
|
|
49
|
-
const adapter = adapterOas({ validate: false })
|
|
50
|
-
const stream = await adapter.stream!(stripeSource)
|
|
51
|
-
for await (const _ of stream.schemas) {
|
|
52
|
-
/* drain */
|
|
53
|
-
}
|
|
54
|
-
for await (const _ of stream.operations) {
|
|
55
|
-
/* drain */
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
{ iterations: 3, warmupIterations: 1 },
|
|
59
|
-
)
|
|
60
|
-
})
|
package/src/adapter.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { ast, createAdapter } from '@kubb/core'
|
|
2
|
-
import type { AdapterSource } from '@kubb/core'
|
|
3
|
-
import { DEFAULT_PARSER_OPTIONS } from './constants.ts'
|
|
4
|
-
import { assertInputExists, parseDocument, parseFromConfig, validateDocument } from './factory.ts'
|
|
5
|
-
import { createSchemaParser } from './parser.ts'
|
|
6
|
-
import { getSchemas } from './resolvers.ts'
|
|
7
|
-
import { createInputStream, preScan, resolveBaseUrl } from './stream.ts'
|
|
8
|
-
import type { AdapterOas, Document } from './types.ts'
|
|
9
|
-
import { collect, narrowSchema } from '@kubb/ast'
|
|
10
|
-
import { extractRefName } from '@kubb/ast/utils'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* The `name` of `@kubb/adapter-oas`, used to identify this adapter in a Kubb config.
|
|
14
|
-
*/
|
|
15
|
-
export const adapterOasName = 'oas' satisfies AdapterOas['name']
|
|
16
|
-
|
|
17
|
-
/**
|
|
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.
|
|
22
|
-
*
|
|
23
|
-
* Configure once on `defineConfig`. The adapter's choices (date representation,
|
|
24
|
-
* integer width, server URL) apply to every plugin in the build.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* import { defineConfig } from 'kubb'
|
|
29
|
-
* import { adapterOas } from '@kubb/adapter-oas'
|
|
30
|
-
* import { pluginTs } from '@kubb/plugin-ts'
|
|
31
|
-
*
|
|
32
|
-
* export default defineConfig({
|
|
33
|
-
* input: { path: './petStore.yaml' },
|
|
34
|
-
* output: { path: './src/gen' },
|
|
35
|
-
* adapter: adapterOas({
|
|
36
|
-
* serverIndex: 0,
|
|
37
|
-
* discriminator: 'inherit',
|
|
38
|
-
* dateType: 'date',
|
|
39
|
-
* }),
|
|
40
|
-
* plugins: [pluginTs()],
|
|
41
|
-
* })
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export const adapterOas = createAdapter<AdapterOas>((options) => {
|
|
45
|
-
const {
|
|
46
|
-
validate = true,
|
|
47
|
-
contentType,
|
|
48
|
-
serverIndex,
|
|
49
|
-
serverVariables,
|
|
50
|
-
discriminator = 'strict',
|
|
51
|
-
dedupe = true,
|
|
52
|
-
dateType = DEFAULT_PARSER_OPTIONS.dateType,
|
|
53
|
-
integerType = DEFAULT_PARSER_OPTIONS.integerType,
|
|
54
|
-
unknownType = DEFAULT_PARSER_OPTIONS.unknownType,
|
|
55
|
-
enumSuffix = DEFAULT_PARSER_OPTIONS.enumSuffix,
|
|
56
|
-
emptySchemaType = unknownType || DEFAULT_PARSER_OPTIONS.emptySchemaType,
|
|
57
|
-
} = options
|
|
58
|
-
|
|
59
|
-
const parserOptions: ast.ParserOptions = {
|
|
60
|
-
...DEFAULT_PARSER_OPTIONS,
|
|
61
|
-
dateType,
|
|
62
|
-
integerType,
|
|
63
|
-
unknownType,
|
|
64
|
-
emptySchemaType,
|
|
65
|
-
enumSuffix,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let nameMapping = new Map<string, string>()
|
|
69
|
-
let parsedDocument: Document | null = null
|
|
70
|
-
|
|
71
|
-
// Cache per source and per document so one adapter instance reused across a `defineConfig` array
|
|
72
|
-
// parses each config's spec instead of replaying the first one. Keying the document by its source
|
|
73
|
-
// object still collapses a config's concurrent `stream()` (build) and `parse()` (studio) calls,
|
|
74
|
-
// which share one source object, onto a single parse. The document-derived caches key off the
|
|
75
|
-
// resulting document, so distinct configs (distinct documents) stay isolated.
|
|
76
|
-
const documentCache = new WeakMap<AdapterSource, Promise<Document>>()
|
|
77
|
-
const schemasCache = new WeakMap<Document, Promise<ReturnType<typeof getSchemas>['schemas']>>()
|
|
78
|
-
const schemaParserCache = new WeakMap<Document, ReturnType<typeof createSchemaParser>>()
|
|
79
|
-
const preScanCache = new WeakMap<Document, ReturnType<typeof preScan>>()
|
|
80
|
-
|
|
81
|
-
function ensureDocument(source: AdapterSource): Promise<Document> {
|
|
82
|
-
const cached = documentCache.get(source)
|
|
83
|
-
if (cached) return cached
|
|
84
|
-
|
|
85
|
-
const promise = (async () => {
|
|
86
|
-
const fresh = await parseFromConfig(source)
|
|
87
|
-
if (validate) await validateDocument(fresh)
|
|
88
|
-
parsedDocument = fresh
|
|
89
|
-
return fresh
|
|
90
|
-
})()
|
|
91
|
-
documentCache.set(source, promise)
|
|
92
|
-
return promise
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function ensureSchemas(document: Document): Promise<ReturnType<typeof getSchemas>['schemas']> {
|
|
96
|
-
const cached = schemasCache.get(document)
|
|
97
|
-
if (cached) return cached
|
|
98
|
-
|
|
99
|
-
const promise = Promise.resolve().then(() => {
|
|
100
|
-
const result = getSchemas(document, { contentType })
|
|
101
|
-
nameMapping = result.nameMapping
|
|
102
|
-
return result.schemas
|
|
103
|
-
})
|
|
104
|
-
schemasCache.set(document, promise)
|
|
105
|
-
return promise
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function ensureSchemaParser(document: Document): ReturnType<typeof createSchemaParser> {
|
|
109
|
-
const cached = schemaParserCache.get(document)
|
|
110
|
-
if (cached) return cached
|
|
111
|
-
|
|
112
|
-
const parser = createSchemaParser({ document, contentType })
|
|
113
|
-
schemaParserCache.set(document, parser)
|
|
114
|
-
return parser
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function ensurePreScan(
|
|
118
|
-
document: Document,
|
|
119
|
-
schemas: ReturnType<typeof getSchemas>['schemas'],
|
|
120
|
-
parseSchema: ReturnType<typeof ensureSchemaParser>['parseSchema'],
|
|
121
|
-
parseOperation: ReturnType<typeof ensureSchemaParser>['parseOperation'],
|
|
122
|
-
): ReturnType<typeof preScan> {
|
|
123
|
-
const cached = preScanCache.get(document)
|
|
124
|
-
if (cached) return cached
|
|
125
|
-
|
|
126
|
-
const result = preScan({ schemas, parseSchema, parseOperation, document, parserOptions, discriminator, dedupe })
|
|
127
|
-
preScanCache.set(document, result)
|
|
128
|
-
return result
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async function createStream(source: AdapterSource): Promise<ast.InputNode<true>> {
|
|
132
|
-
const document = await ensureDocument(source)
|
|
133
|
-
const schemas = await ensureSchemas(document)
|
|
134
|
-
const { parseSchema, parseOperation } = ensureSchemaParser(document)
|
|
135
|
-
const { refAliasMap, enumNames, circularNames, discriminatorChildMap, dedupePlan } = ensurePreScan(document, schemas, parseSchema, parseOperation)
|
|
136
|
-
|
|
137
|
-
return createInputStream({
|
|
138
|
-
schemas,
|
|
139
|
-
parseSchema,
|
|
140
|
-
parseOperation,
|
|
141
|
-
document,
|
|
142
|
-
parserOptions,
|
|
143
|
-
refAliasMap,
|
|
144
|
-
discriminatorChildMap,
|
|
145
|
-
dedupePlan,
|
|
146
|
-
meta: {
|
|
147
|
-
title: document.info?.title,
|
|
148
|
-
description: document.info?.description,
|
|
149
|
-
version: document.info?.version,
|
|
150
|
-
baseURL: resolveBaseUrl({ document, serverIndex, serverVariables }),
|
|
151
|
-
circularNames,
|
|
152
|
-
enumNames,
|
|
153
|
-
},
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
name: adapterOasName,
|
|
159
|
-
get options() {
|
|
160
|
-
return {
|
|
161
|
-
validate,
|
|
162
|
-
contentType,
|
|
163
|
-
serverIndex,
|
|
164
|
-
serverVariables,
|
|
165
|
-
discriminator,
|
|
166
|
-
dedupe,
|
|
167
|
-
dateType,
|
|
168
|
-
integerType,
|
|
169
|
-
unknownType,
|
|
170
|
-
emptySchemaType,
|
|
171
|
-
enumSuffix,
|
|
172
|
-
nameMapping,
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
get document() {
|
|
176
|
-
return parsedDocument
|
|
177
|
-
},
|
|
178
|
-
async validate(input, options) {
|
|
179
|
-
await assertInputExists(input)
|
|
180
|
-
const document = await parseDocument(input)
|
|
181
|
-
await validateDocument(document, options)
|
|
182
|
-
},
|
|
183
|
-
getImports(node, resolve) {
|
|
184
|
-
return collect(node, {
|
|
185
|
-
schema(schemaNode) {
|
|
186
|
-
const schemaRef = narrowSchema(schemaNode, 'ref')
|
|
187
|
-
if (!schemaRef?.ref) return null
|
|
188
|
-
|
|
189
|
-
const rawName = extractRefName(schemaRef.ref)
|
|
190
|
-
const schemaName = nameMapping.get(rawName) ?? rawName
|
|
191
|
-
const result = resolve(schemaName)
|
|
192
|
-
if (!result) return null
|
|
193
|
-
|
|
194
|
-
return ast.factory.createImport({ name: [result.name], path: result.path })
|
|
195
|
-
},
|
|
196
|
-
})
|
|
197
|
-
},
|
|
198
|
-
async parse(source) {
|
|
199
|
-
const streamNode = await createStream(source)
|
|
200
|
-
|
|
201
|
-
const [schemas, operations] = await Promise.all([Array.fromAsync(streamNode.schemas), Array.fromAsync(streamNode.operations)])
|
|
202
|
-
|
|
203
|
-
return ast.factory.createInput({ schemas, operations, meta: streamNode.meta })
|
|
204
|
-
},
|
|
205
|
-
stream: createStream,
|
|
206
|
-
}
|
|
207
|
-
})
|
package/src/bundler.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { read } from '@internals/utils'
|
|
2
|
-
import { bundle } from 'api-ref-bundler'
|
|
3
|
-
import { parse } from 'yaml'
|
|
4
|
-
import type { Document } from './types.ts'
|
|
5
|
-
|
|
6
|
-
const urlRegExp = /^https?:\/+/i
|
|
7
|
-
|
|
8
|
-
async function readSource(sourcePath: string): Promise<string> {
|
|
9
|
-
if (urlRegExp.test(sourcePath)) {
|
|
10
|
-
// api-ref-bundler joins relative refs with posix normalization, collapsing `https://` to
|
|
11
|
-
// `https:/`. The WHATWG URL parser restores the double slash.
|
|
12
|
-
const url = new URL(sourcePath)
|
|
13
|
-
const response = await fetch(url)
|
|
14
|
-
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw new Error(`Cannot fetch the OAS document at ${url.href} (HTTP ${response.status})`)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return response.text()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return read(sourcePath)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function resolveSource(sourcePath: string): Promise<object | string> {
|
|
26
|
-
const data = await readSource(sourcePath)
|
|
27
|
-
|
|
28
|
-
if (sourcePath.toLowerCase().endsWith('.md')) {
|
|
29
|
-
return data
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return parse(data) as object
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Bundles a multi-file OpenAPI document into a single document via `api-ref-bundler`.
|
|
37
|
-
*
|
|
38
|
-
* External file schemas are hoisted into named `components.schemas` entries, so a property
|
|
39
|
-
* pointing at `./schemas/User.yaml` ends up referencing `#/components/schemas/User`. Generators
|
|
40
|
-
* can then emit a named type with an import instead of inlining the shape. Sources are read with
|
|
41
|
-
* the Bun-aware `read` util for local YAML and JSON files, and with `fetch` for HTTP(S) URLs.
|
|
42
|
-
*
|
|
43
|
-
* @example Local file
|
|
44
|
-
* `const document = await bundleDocument('./openapi.yaml')`
|
|
45
|
-
*
|
|
46
|
-
* @example Remote URL
|
|
47
|
-
* `const document = await bundleDocument('https://example.com/openapi.yaml')`
|
|
48
|
-
*/
|
|
49
|
-
export async function bundleDocument(pathOrUrl: string): Promise<Document> {
|
|
50
|
-
const cache = new Map<string, Promise<object | string>>()
|
|
51
|
-
|
|
52
|
-
const resolver = (sourcePath: string) => {
|
|
53
|
-
// api-ref-bundler refers to the same URL as both `https://` and the posix-normalized
|
|
54
|
-
// `https:/`, so cache on the canonical href to fetch each source once.
|
|
55
|
-
const key = urlRegExp.test(sourcePath) ? new URL(sourcePath).href : sourcePath
|
|
56
|
-
const cached = cache.get(key)
|
|
57
|
-
if (cached) {
|
|
58
|
-
return cached
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const result = resolveSource(sourcePath)
|
|
62
|
-
cache.set(key, result)
|
|
63
|
-
return result
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// api-ref-bundler swallows resolver errors and leaves refs unresolved, so surface an
|
|
67
|
-
// unreadable input document as a hard error before bundling.
|
|
68
|
-
await resolver(pathOrUrl)
|
|
69
|
-
|
|
70
|
-
return (await bundle(pathOrUrl, resolver)) as Document
|
|
71
|
-
}
|
package/src/constants.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { ast } from '@kubb/core'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Default parser options applied when no explicit options are provided.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* import { DEFAULT_PARSER_OPTIONS, parseOas } from '@kubb/adapter-oas'
|
|
9
|
-
*
|
|
10
|
-
* const { root } = parseOas(document, { ...DEFAULT_PARSER_OPTIONS, dateType: 'date' })
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export const DEFAULT_PARSER_OPTIONS = {
|
|
14
|
-
dateType: 'string',
|
|
15
|
-
integerType: 'bigint',
|
|
16
|
-
unknownType: 'any',
|
|
17
|
-
emptySchemaType: 'any',
|
|
18
|
-
enumSuffix: 'enum',
|
|
19
|
-
} as const satisfies ast.ParserOptions
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* JSON-Pointer prefix for schemas declared under `components.schemas` in an OpenAPI document.
|
|
23
|
-
*
|
|
24
|
-
* Used when building or parsing `$ref` strings.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* `${SCHEMA_REF_PREFIX}Pet` // '#/components/schemas/Pet'
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export const SCHEMA_REF_PREFIX = '#/components/schemas/' as const
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* HTTP methods that count as operations on an OpenAPI path item. Other keys
|
|
35
|
-
* (`parameters`, `summary`, `$ref`, vendor extensions) are skipped when iterating operations.
|
|
36
|
-
*/
|
|
37
|
-
export const SUPPORTED_METHODS: ReadonlySet<string> = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'])
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* OpenAPI version string written into the stub document created during multi-spec merges.
|
|
41
|
-
*/
|
|
42
|
-
export const MERGE_OPENAPI_VERSION = '3.0.0' as const
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Fallback `info.title` placed in the stub document when merging multiple API files.
|
|
46
|
-
*/
|
|
47
|
-
export const MERGE_DEFAULT_TITLE = 'Merged API' as const
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Fallback `info.version` placed in the stub document when merging multiple API files.
|
|
51
|
-
*/
|
|
52
|
-
export const MERGE_DEFAULT_VERSION = '1.0.0' as const
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Set of JSON Schema keywords that prevent a schema fragment from being inlined during `allOf` flattening.
|
|
56
|
-
*
|
|
57
|
-
* A fragment that contains any of these keys carries structural meaning of its own and must stay as a separate
|
|
58
|
-
* intersection member rather than being merged into the parent.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* import { structuralKeys } from '@kubb/adapter-oas'
|
|
63
|
-
*
|
|
64
|
-
* const isStructural = Object.keys(fragment).some((key) => structuralKeys.has(key))
|
|
65
|
-
* // true when fragment has e.g. 'properties' or 'oneOf'
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export const structuralKeys = new Set(['properties', 'items', 'additionalProperties', 'oneOf', 'anyOf', 'allOf', 'not'] as const)
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Formats `convertFormat` maps to a dedicated type without going through `formatMap`:
|
|
72
|
-
* `int64` and the date/time family. Keep this in sync with the `convertFormat`
|
|
73
|
-
* special-cases in `parser.ts`. `isHandledFormat` reads it so the
|
|
74
|
-
* `KUBB_UNSUPPORTED_FORMAT` diagnostic and the parser agree on what is handled.
|
|
75
|
-
*/
|
|
76
|
-
export const specialCasedFormats: ReadonlySet<string> = new Set(['int64', 'date-time', 'date', 'time'])
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Static map from OAS `format` strings to Kubb `SchemaType` values.
|
|
80
|
-
*
|
|
81
|
-
* Only formats whose AST type differs from the OAS `type` field appear here.
|
|
82
|
-
* Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled
|
|
83
|
-
* separately in the parser. `ipv4` and `ipv6` map to their own dedicated schema types. `hostname`
|
|
84
|
-
* and `idn-hostname` map to `'url'` as the closest generic string-format type.
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```ts
|
|
88
|
-
* import { formatMap } from '@kubb/adapter-oas'
|
|
89
|
-
*
|
|
90
|
-
* formatMap['uuid'] // 'uuid'
|
|
91
|
-
* formatMap['binary'] // 'blob'
|
|
92
|
-
* formatMap['float'] // 'number'
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
export const formatMap = {
|
|
96
|
-
uuid: 'uuid',
|
|
97
|
-
email: 'email',
|
|
98
|
-
'idn-email': 'email',
|
|
99
|
-
uri: 'url',
|
|
100
|
-
'uri-reference': 'url',
|
|
101
|
-
url: 'url',
|
|
102
|
-
ipv4: 'ipv4',
|
|
103
|
-
ipv6: 'ipv6',
|
|
104
|
-
hostname: 'url',
|
|
105
|
-
'idn-hostname': 'url',
|
|
106
|
-
binary: 'blob',
|
|
107
|
-
byte: 'blob',
|
|
108
|
-
// Numeric formats override the OAS `type` because format is more specific.
|
|
109
|
-
// See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.7
|
|
110
|
-
int32: 'integer',
|
|
111
|
-
float: 'number',
|
|
112
|
-
double: 'number',
|
|
113
|
-
} as const satisfies Record<string, ast.SchemaType>
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Vendor extension keys that attach human-readable labels to enum values, checked in priority order.
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```ts
|
|
120
|
-
* import { enumExtensionKeys } from '@kubb/adapter-oas'
|
|
121
|
-
*
|
|
122
|
-
* const key = enumExtensionKeys.find((k) => k in schema) // 'x-enumNames' | 'x-enum-varnames' | undefined
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
export const enumExtensionKeys = ['x-enumNames', 'x-enum-varnames'] as const
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Maps the `unknownType`/`emptySchemaType` option string to its `ScalarSchemaType` constant.
|
|
129
|
-
* A `Map` (over a plain object) lets callers test key membership with `.has()`.
|
|
130
|
-
*/
|
|
131
|
-
export const typeOptionMap = new Map<'any' | 'unknown' | 'void', ast.ScalarSchemaType>([
|
|
132
|
-
['any', ast.schemaTypes.any],
|
|
133
|
-
['unknown', ast.schemaTypes.unknown],
|
|
134
|
-
['void', ast.schemaTypes.void],
|
|
135
|
-
])
|