@kubb/adapter-oas 5.0.0-beta.29 → 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/dist/index.cjs +186 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +186 -65
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/dialect.ts +38 -0
- package/src/parser.ts +105 -74
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.30",
|
|
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.
|
|
50
|
+
"@kubb/core": "5.0.0-beta.30"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/swagger2openapi": "^7.0.4",
|
package/src/dialect.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ast } from '@kubb/core'
|
|
2
|
+
import { isDiscriminator, isNullable, isReference } from './guards.ts'
|
|
3
|
+
import { resolveRef } from './refs.ts'
|
|
4
|
+
import type { SchemaObject } from './types.ts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The OpenAPI / Swagger dialect — the default used by `@kubb/adapter-oas`.
|
|
8
|
+
*
|
|
9
|
+
* Implements the spec-agnostic {@link ast.SchemaDialect} contract: it isolates the
|
|
10
|
+
* decisions that differ between specs (nullability, `$ref`, discriminator, binary,
|
|
11
|
+
* ref resolution) so the converter pipeline and dispatch rules stay shared. A
|
|
12
|
+
* future adapter (e.g. AsyncAPI) ships its own dialect — `type: ['null', …]`
|
|
13
|
+
* nullability, no discriminator object, binary via `contentEncoding` — and reuses
|
|
14
|
+
* the rest unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Formats (`uuid`, `email`, dates, …) are intentionally NOT here: they are shared
|
|
17
|
+
* JSON Schema vocabulary, so the converters keep that common case.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const parser = createSchemaParser(context) // uses oasDialect
|
|
22
|
+
* const parser = createSchemaParser(context, oasDialect) // explicit
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const oasDialect = ast.defineSchemaDialect({
|
|
26
|
+
name: 'oas',
|
|
27
|
+
isNullable,
|
|
28
|
+
isReference,
|
|
29
|
+
isDiscriminator,
|
|
30
|
+
isBinary: (schema: SchemaObject) => schema.type === 'string' && schema.contentMediaType === 'application/octet-stream',
|
|
31
|
+
resolveRef,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The concrete dialect type for `@kubb/adapter-oas`. Keeps the OAS guard predicates
|
|
36
|
+
* (`isReference`, `isDiscriminator`) intact so converters narrow schemas after a check.
|
|
37
|
+
*/
|
|
38
|
+
export type OasDialect = typeof oasDialect
|
package/src/parser.ts
CHANGED
|
@@ -2,8 +2,7 @@ import { pascalCase, URLPath } from '@internals/utils'
|
|
|
2
2
|
import { ast } from '@kubb/core'
|
|
3
3
|
import BaseOas from 'oas'
|
|
4
4
|
import { DEFAULT_PARSER_OPTIONS, enumExtensionKeys, SCHEMA_REF_PREFIX, typeOptionMap } from './constants.ts'
|
|
5
|
-
import {
|
|
6
|
-
import { resolveRef } from './refs.ts'
|
|
5
|
+
import { oasDialect, type OasDialect } from './dialect.ts'
|
|
7
6
|
import {
|
|
8
7
|
buildSchemaNode,
|
|
9
8
|
flattenSchema,
|
|
@@ -60,6 +59,13 @@ type SchemaContext = {
|
|
|
60
59
|
options: ast.ParserOptions
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
/**
|
|
63
|
+
* One entry in this adapter's schema-dispatch table — a {@link ast.DispatchRule} specialized
|
|
64
|
+
* to OAS schema context and Kubb `SchemaNode` output. See {@link ast.dispatch} for the contract
|
|
65
|
+
* a future adapter (e.g. AsyncAPI) follows: define a context type and an ordered rules table.
|
|
66
|
+
*/
|
|
67
|
+
type SchemaRule = ast.DispatchRule<SchemaContext, ast.SchemaNode>
|
|
68
|
+
|
|
63
69
|
/**
|
|
64
70
|
* Normalizes malformed `{ type: 'array', enum: [...] }` schemas by moving enum values into items.
|
|
65
71
|
*
|
|
@@ -88,7 +94,7 @@ function normalizeArrayEnum(schema: SchemaObject): SchemaObject {
|
|
|
88
94
|
*
|
|
89
95
|
* @internal
|
|
90
96
|
*/
|
|
91
|
-
export function createSchemaParser(ctx: OasParserContext) {
|
|
97
|
+
export function createSchemaParser(ctx: OasParserContext, dialect: OasDialect = oasDialect) {
|
|
92
98
|
const document = ctx.document
|
|
93
99
|
|
|
94
100
|
// Branch handlers — each converts one OAS schema pattern to a SchemaNode.
|
|
@@ -127,7 +133,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
127
133
|
if (refPath && !resolvingRefs.has(refPath)) {
|
|
128
134
|
if (!resolvedRefCache.has(refPath)) {
|
|
129
135
|
try {
|
|
130
|
-
const referenced = resolveRef<SchemaObject>(document, refPath)
|
|
136
|
+
const referenced = dialect.resolveRef<SchemaObject>(document, refPath)
|
|
131
137
|
if (referenced) {
|
|
132
138
|
resolvingRefs.add(refPath)
|
|
133
139
|
resolvedSchema = parseSchema({ schema: referenced }, rawOptions)
|
|
@@ -188,13 +194,13 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
188
194
|
}> = []
|
|
189
195
|
const allOfMembers: Array<ast.SchemaNode> = (schema.allOf as Array<SchemaObject | ReferenceObject>)
|
|
190
196
|
.filter((item) => {
|
|
191
|
-
if (!isReference(item) || !name) return true
|
|
192
|
-
const deref = resolveRef<SchemaObject>(document, item.$ref)
|
|
193
|
-
if (!deref || !isDiscriminator(deref)) return true
|
|
197
|
+
if (!dialect.isReference(item) || !name) return true
|
|
198
|
+
const deref = dialect.resolveRef<SchemaObject>(document, item.$ref)
|
|
199
|
+
if (!deref || !dialect.isDiscriminator(deref)) return true
|
|
194
200
|
const parentUnion = deref.oneOf ?? deref.anyOf
|
|
195
201
|
if (!parentUnion) return true
|
|
196
202
|
const childRef = `${SCHEMA_REF_PREFIX}${name}`
|
|
197
|
-
const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef)
|
|
203
|
+
const inOneOf = parentUnion.some((oneOfItem) => dialect.isReference(oneOfItem) && oneOfItem.$ref === childRef)
|
|
198
204
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef)
|
|
199
205
|
if (inOneOf || inMapping) {
|
|
200
206
|
const discriminatorValue = ast.findDiscriminator(deref.discriminator.mapping, childRef)
|
|
@@ -218,9 +224,9 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
218
224
|
|
|
219
225
|
if (missingRequired.length) {
|
|
220
226
|
const resolvedMembers = (schema.allOf as Array<SchemaObject | ReferenceObject>).flatMap((item) => {
|
|
221
|
-
if (!isReference(item)) return [item as SchemaObject]
|
|
222
|
-
const deref = resolveRef<SchemaObject>(document, item.$ref)
|
|
223
|
-
return deref && !isReference(deref) ? [deref] : []
|
|
227
|
+
if (!dialect.isReference(item)) return [item as SchemaObject]
|
|
228
|
+
const deref = dialect.resolveRef<SchemaObject>(document, item.$ref)
|
|
229
|
+
return deref && !dialect.isReference(deref) ? [deref] : []
|
|
224
230
|
})
|
|
225
231
|
|
|
226
232
|
for (const key of missingRequired) {
|
|
@@ -287,10 +293,10 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
287
293
|
const strategy: 'one' | 'any' = schema.oneOf ? 'one' : 'any'
|
|
288
294
|
const unionBase = {
|
|
289
295
|
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
290
|
-
discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : undefined,
|
|
296
|
+
discriminatorPropertyName: dialect.isDiscriminator(schema) ? schema.discriminator.propertyName : undefined,
|
|
291
297
|
strategy,
|
|
292
298
|
}
|
|
293
|
-
const discriminator = isDiscriminator(schema) ? schema.discriminator : undefined
|
|
299
|
+
const discriminator = dialect.isDiscriminator(schema) ? schema.discriminator : undefined
|
|
294
300
|
const sharedPropertiesNode = schema.properties
|
|
295
301
|
? (() => {
|
|
296
302
|
const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema
|
|
@@ -303,7 +309,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
303
309
|
|
|
304
310
|
if (sharedPropertiesNode || discriminator?.mapping) {
|
|
305
311
|
const members = unionMembers.map((s) => {
|
|
306
|
-
const ref = isReference(s) ? s.$ref : undefined
|
|
312
|
+
const ref = dialect.isReference(s) ? s.$ref : undefined
|
|
307
313
|
const discriminatorValue = ast.findDiscriminator(discriminator?.mapping, ref)
|
|
308
314
|
const memberNode = parseSchema({ schema: s as SchemaObject, name }, rawOptions)
|
|
309
315
|
|
|
@@ -548,7 +554,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
548
554
|
? Object.entries(schema.properties).map(([propName, propSchema]) => {
|
|
549
555
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required
|
|
550
556
|
const resolvedPropSchema = propSchema as SchemaObject
|
|
551
|
-
const propNullable = isNullable(resolvedPropSchema)
|
|
557
|
+
const propNullable = dialect.isNullable(resolvedPropSchema)
|
|
552
558
|
|
|
553
559
|
const resolvedChildName = ast.childName(name, propName)
|
|
554
560
|
const propNode = parseSchema({ schema: resolvedPropSchema, name: resolvedChildName }, rawOptions)
|
|
@@ -612,7 +618,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
612
618
|
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
613
619
|
})
|
|
614
620
|
|
|
615
|
-
if (isDiscriminator(schema) && schema.discriminator.mapping) {
|
|
621
|
+
if (dialect.isDiscriminator(schema) && schema.discriminator.mapping) {
|
|
616
622
|
const discPropName = schema.discriminator.propertyName
|
|
617
623
|
const values = Object.keys(schema.discriminator.mapping)
|
|
618
624
|
const enumName = name ? ast.enumPropName(name, discPropName, options.enumSuffix) : undefined
|
|
@@ -721,12 +727,86 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
721
727
|
})
|
|
722
728
|
}
|
|
723
729
|
|
|
730
|
+
/**
|
|
731
|
+
* Converts a binary string schema (`type: 'string'`, `contentMediaType: 'application/octet-stream'`)
|
|
732
|
+
* into a `blob` node.
|
|
733
|
+
*/
|
|
734
|
+
function convertBlob({ schema, name, nullable, defaultValue }: SchemaContext): ast.SchemaNode {
|
|
735
|
+
return ast.createSchema({
|
|
736
|
+
type: 'blob',
|
|
737
|
+
primitive: 'string',
|
|
738
|
+
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
739
|
+
})
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Converts an OAS 3.1 multi-type array (e.g. `type: ['string', 'number']`) into a `UnionSchemaNode`.
|
|
744
|
+
*
|
|
745
|
+
* Returns `null` when only one non-`null` type remains (e.g. `['string', 'null']`), so `parseSchema`
|
|
746
|
+
* falls through and handles it as that single type with nullability already folded in.
|
|
747
|
+
*/
|
|
748
|
+
function convertMultiType({ schema, name, nullable, defaultValue, rawOptions }: SchemaContext): ast.SchemaNode | null {
|
|
749
|
+
const types = schema.type as Array<string>
|
|
750
|
+
const nonNullTypes = types.filter((t) => t !== 'null')
|
|
751
|
+
if (nonNullTypes.length <= 1) return null
|
|
752
|
+
|
|
753
|
+
const arrayNullable = types.includes('null') || nullable || undefined
|
|
754
|
+
return ast.createSchema({
|
|
755
|
+
type: 'union',
|
|
756
|
+
members: nonNullTypes.map((t) => parseSchema({ schema: { ...schema, type: t } as SchemaObject, name }, rawOptions)),
|
|
757
|
+
...buildSchemaNode(schema, name, arrayNullable, defaultValue),
|
|
758
|
+
})
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Ordered schema-dispatch table. Order is significant: composition keywords (`$ref`, `allOf`,
|
|
763
|
+
* `oneOf`/`anyOf`) take precedence over `const`/`format`, which take precedence over the plain
|
|
764
|
+
* `type`. The first matching rule that produces a node wins; see {@link SchemaRule} for the
|
|
765
|
+
* match/convert/fall-through contract.
|
|
766
|
+
*/
|
|
767
|
+
const schemaRules: Array<SchemaRule> = [
|
|
768
|
+
{ name: 'ref', match: ({ schema }) => dialect.isReference(schema), convert: convertRef },
|
|
769
|
+
{ name: 'allOf', match: ({ schema }) => !!schema.allOf?.length, convert: convertAllOf },
|
|
770
|
+
{ name: 'union', match: ({ schema }) => !!(schema.oneOf?.length || schema.anyOf?.length), convert: convertUnion },
|
|
771
|
+
{ name: 'const', match: ({ schema }) => 'const' in schema && schema.const !== undefined, convert: convertConst },
|
|
772
|
+
{ name: 'format', match: ({ schema }) => !!schema.format, convert: convertFormat },
|
|
773
|
+
{
|
|
774
|
+
name: 'blob',
|
|
775
|
+
match: ({ schema }) => dialect.isBinary(schema),
|
|
776
|
+
convert: convertBlob,
|
|
777
|
+
},
|
|
778
|
+
{ name: 'multi-type', match: ({ schema }) => Array.isArray(schema.type) && schema.type.length > 1, convert: convertMultiType },
|
|
779
|
+
{
|
|
780
|
+
name: 'constrained-string',
|
|
781
|
+
match: ({ schema, type }) => !type && (schema.minLength !== undefined || schema.maxLength !== undefined || schema.pattern !== undefined),
|
|
782
|
+
convert: convertString,
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
name: 'constrained-number',
|
|
786
|
+
match: ({ schema, type }) => !type && (schema.minimum !== undefined || schema.maximum !== undefined),
|
|
787
|
+
convert: (ctx) => convertNumeric(ctx, 'number'),
|
|
788
|
+
},
|
|
789
|
+
{ name: 'enum', match: ({ schema }) => !!schema.enum?.length, convert: convertEnum },
|
|
790
|
+
{
|
|
791
|
+
name: 'object',
|
|
792
|
+
match: ({ schema, type }) => type === 'object' || !!schema.properties || !!schema.additionalProperties || 'patternProperties' in schema,
|
|
793
|
+
convert: convertObject,
|
|
794
|
+
},
|
|
795
|
+
{ name: 'tuple', match: ({ schema }) => 'prefixItems' in schema, convert: convertTuple },
|
|
796
|
+
{ name: 'array', match: ({ schema, type }) => type === 'array' || 'items' in schema, convert: convertArray },
|
|
797
|
+
{ name: 'string', match: ({ type }) => type === 'string', convert: convertString },
|
|
798
|
+
{ name: 'number', match: ({ type }) => type === 'number', convert: (ctx) => convertNumeric(ctx, 'number') },
|
|
799
|
+
{ name: 'integer', match: ({ type }) => type === 'integer', convert: (ctx) => convertNumeric(ctx, 'integer') },
|
|
800
|
+
{ name: 'boolean', match: ({ type }) => type === 'boolean', convert: convertBoolean },
|
|
801
|
+
{ name: 'null', match: ({ type }) => type === 'null', convert: convertNull },
|
|
802
|
+
]
|
|
803
|
+
|
|
724
804
|
/**
|
|
725
805
|
* Central dispatcher that converts an OAS `SchemaObject` into a `SchemaNode`.
|
|
726
806
|
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
807
|
+
* Builds the per-schema context, then runs it through the ordered {@link schemaRules} table
|
|
808
|
+
* via {@link ast.dispatch}. When no rule produces a node, falls back to the configured
|
|
809
|
+
* `emptySchemaType`.
|
|
730
810
|
*/
|
|
731
811
|
function parseSchema({ schema, name }: { schema: SchemaObject; name?: string | null }, rawOptions?: Partial<ast.ParserOptions>): ast.SchemaNode {
|
|
732
812
|
const options: ast.ParserOptions = {
|
|
@@ -738,11 +818,11 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
738
818
|
return parseSchema({ schema: flattenedSchema, name }, rawOptions)
|
|
739
819
|
}
|
|
740
820
|
|
|
741
|
-
const nullable = isNullable(schema) || undefined
|
|
821
|
+
const nullable = dialect.isNullable(schema) || undefined
|
|
742
822
|
const defaultValue = schema.default === null && nullable ? undefined : schema.default
|
|
743
823
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type
|
|
744
824
|
|
|
745
|
-
const
|
|
825
|
+
const schemaCtx: SchemaContext = {
|
|
746
826
|
schema,
|
|
747
827
|
name,
|
|
748
828
|
nullable,
|
|
@@ -752,58 +832,8 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
752
832
|
options,
|
|
753
833
|
}
|
|
754
834
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
if (schema.allOf?.length) return convertAllOf(ctx)
|
|
758
|
-
const unionMembers = [...(schema.oneOf ?? []), ...(schema.anyOf ?? [])]
|
|
759
|
-
if (unionMembers.length) return convertUnion(ctx)
|
|
760
|
-
|
|
761
|
-
if ('const' in schema && schema.const !== undefined) return convertConst(ctx)
|
|
762
|
-
|
|
763
|
-
if (schema.format) {
|
|
764
|
-
const formatResult = convertFormat(ctx)
|
|
765
|
-
if (formatResult) return formatResult
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
if (schema.type === 'string' && schema.contentMediaType === 'application/octet-stream') {
|
|
769
|
-
return ast.createSchema({
|
|
770
|
-
type: 'blob',
|
|
771
|
-
primitive: 'string',
|
|
772
|
-
...buildSchemaNode(schema, name, nullable, defaultValue),
|
|
773
|
-
})
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
if (Array.isArray(schema.type) && schema.type.length > 1) {
|
|
777
|
-
const nonNullTypes = schema.type.filter((t) => t !== 'null') as Array<string>
|
|
778
|
-
const arrayNullable = schema.type.includes('null') || nullable || undefined
|
|
779
|
-
|
|
780
|
-
if (nonNullTypes.length > 1) {
|
|
781
|
-
return ast.createSchema({
|
|
782
|
-
type: 'union',
|
|
783
|
-
members: nonNullTypes.map((t) => parseSchema({ schema: { ...schema, type: t } as SchemaObject, name }, rawOptions)),
|
|
784
|
-
...buildSchemaNode(schema, name, arrayNullable, defaultValue),
|
|
785
|
-
})
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
if (!type) {
|
|
790
|
-
if (schema.minLength !== undefined || schema.maxLength !== undefined || schema.pattern !== undefined) {
|
|
791
|
-
return convertString(ctx)
|
|
792
|
-
}
|
|
793
|
-
if (schema.minimum !== undefined || schema.maximum !== undefined) {
|
|
794
|
-
return convertNumeric(ctx, 'number')
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
if (schema.enum?.length) return convertEnum(ctx)
|
|
799
|
-
if (type === 'object' || schema.properties || schema.additionalProperties || 'patternProperties' in schema) return convertObject(ctx)
|
|
800
|
-
if ('prefixItems' in schema) return convertTuple(ctx)
|
|
801
|
-
if (type === 'array' || 'items' in schema) return convertArray(ctx)
|
|
802
|
-
if (type === 'string') return convertString(ctx)
|
|
803
|
-
if (type === 'number') return convertNumeric(ctx, 'number')
|
|
804
|
-
if (type === 'integer') return convertNumeric(ctx, 'integer')
|
|
805
|
-
if (type === 'boolean') return convertBoolean(ctx)
|
|
806
|
-
if (type === 'null') return convertNull(ctx)
|
|
835
|
+
const node = ast.dispatch(schemaRules, schemaCtx)
|
|
836
|
+
if (node) return node
|
|
807
837
|
|
|
808
838
|
const emptyType = typeOptionMap.get(options.emptySchemaType)!
|
|
809
839
|
return ast.createSchema({
|
|
@@ -883,7 +913,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
883
913
|
const keys: Array<string> = []
|
|
884
914
|
for (const key in schema.properties) {
|
|
885
915
|
const prop = schema.properties[key]
|
|
886
|
-
if (prop && !isReference(prop) && (prop as Record<string, unknown>)[flag]) {
|
|
916
|
+
if (prop && !dialect.isReference(prop) && (prop as Record<string, unknown>)[flag]) {
|
|
887
917
|
keys.push(key)
|
|
888
918
|
}
|
|
889
919
|
}
|
|
@@ -969,6 +999,7 @@ export function createSchemaParser(ctx: OasParserContext) {
|
|
|
969
999
|
|
|
970
1000
|
return ast.createOperation({
|
|
971
1001
|
operationId,
|
|
1002
|
+
protocol: 'http',
|
|
972
1003
|
method: operation.method.toUpperCase() as ast.HttpMethod,
|
|
973
1004
|
path: urlPath.path,
|
|
974
1005
|
tags: operation.getTags().map((tag) => tag.name),
|