diff --git a/.changeset/selfish-pandas-speak.md b/.changeset/selfish-pandas-speak.md index 06e3644ecb..25ec9fa3ce 100644 --- a/.changeset/selfish-pandas-speak.md +++ b/.changeset/selfish-pandas-speak.md @@ -1,6 +1,5 @@ --- -"@redocly/openapi-core": minor -"@redocly/cli": minor +"@redocly/openapi-core": patch --- -Update typings for OAS 3.0 and OAS 3.1 Schemas +Updated typings for OAS 3.0 and OAS 3.1 Schemas. diff --git a/packages/core/src/__tests__/lint.test.ts b/packages/core/src/__tests__/lint.test.ts index 3aa1ed00a0..4778a95dea 100644 --- a/packages/core/src/__tests__/lint.test.ts +++ b/packages/core/src/__tests__/lint.test.ts @@ -1674,4 +1674,99 @@ describe('lint', () => { expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); }); + + it('should throw an error for $schema not expected here - OAS 3.0.x', async () => { + const document = parseYamlToDocument( + outdent` + openapi: 3.0.4 + info: + title: test json schema validation keyword - allOf should use an OAS Schema, not JSON Schema + version: 1.0.0 + paths: + '/thing': + get: + summary: a sample api + responses: + '200': + description: OK + content: + 'application/json': + schema: + $schema: http://json-schema.org/draft-04/schema# + type: object + properties: {} + `, + '' + ); + + const configFilePath = path.join(__dirname, '..', '..', '..', 'redocly.yaml'); + + const results = await lintDocument({ + externalRefResolver: new BaseResolver(), + document, + config: await makeConfig({ + rules: { spec: 'error' }, + decorators: undefined, + configPath: configFilePath, + }), + }); + + expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` + [ + { + "from": undefined, + "location": [ + { + "pointer": "#/paths/~1thing/get/responses/200/content/application~1json/schema/$schema", + "reportOnKey": true, + "source": "", + }, + ], + "message": "Property \`$schema\` is not expected here.", + "ruleId": "spec", + "severity": "error", + "suggest": [], + }, + ] + `); + }); + + it('should allow for $schema to be defined - OAS 3.1.x', async () => { + const document = parseYamlToDocument( + outdent` + openapi: 3.1.1 + info: + title: test json schema validation keyword - allOf should use an OAS Schema, not JSON Schema + version: 1.0.0 + paths: + '/thing': + get: + summary: a sample api + responses: + '200': + description: OK + content: + 'application/json': + schema: + $schema: http://json-schema.org/draft-04/schema# + type: object + properties: {} + `, + '' + ); + + const configFilePath = path.join(__dirname, '..', '..', '..', 'redocly.yaml'); + + const results = await lintDocument({ + externalRefResolver: new BaseResolver(), + document, + config: await makeConfig({ + rules: { spec: 'error' }, + decorators: undefined, + configPath: configFilePath, + }), + }); + + expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); + }); }); diff --git a/packages/core/src/decorators/common/media-type-examples-override.ts b/packages/core/src/decorators/common/media-type-examples-override.ts index 8b8037fe37..b2a064943f 100644 --- a/packages/core/src/decorators/common/media-type-examples-override.ts +++ b/packages/core/src/decorators/common/media-type-examples-override.ts @@ -2,13 +2,13 @@ import { yamlAndJsonSyncReader } from '../../utils'; import { isRef } from '../../ref-utils'; import type { Oas3Decorator } from '../../visitors'; -import type { Oas3Operation, Oas3RequestBody, Oas3Response } from '../../typings/openapi'; +import type { Oas3_1Schema, Oas3Operation, Oas3RequestBody, Oas3Response, Oas3Schema } from '../../typings/openapi'; import type { NonUndefined, ResolveFn, UserContext } from '../../walk'; export const MediaTypeExamplesOverride: Oas3Decorator = ({ operationIds }) => { return { Operation: { - enter(operation: Oas3Operation, ctx: UserContext) { + enter(operation: Oas3Operation<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { const operationId = operation.operationId; if (!operationId) { @@ -23,7 +23,7 @@ export const MediaTypeExamplesOverride: Oas3Decorator = ({ operationIds }) => { if (properties.responses && operation.responses) { for (const responseCode of Object.keys(properties.responses)) { - const resolvedResponse = checkAndResolveRef<Oas3Response>( + const resolvedResponse = checkAndResolveRef<Oas3Response<Oas3Schema | Oas3_1Schema>>( operation.responses[responseCode], ctx.resolve ); @@ -46,7 +46,7 @@ export const MediaTypeExamplesOverride: Oas3Decorator = ({ operationIds }) => { } if (properties.request && operation.requestBody) { - const resolvedRequest = checkAndResolveRef<Oas3RequestBody>( + const resolvedRequest = checkAndResolveRef<Oas3RequestBody<Oas3Schema | Oas3_1Schema>>( operation.requestBody, ctx.resolve ); diff --git a/packages/core/src/decorators/common/operation-description-override.ts b/packages/core/src/decorators/common/operation-description-override.ts index c583fb4ff2..46df16160b 100644 --- a/packages/core/src/decorators/common/operation-description-override.ts +++ b/packages/core/src/decorators/common/operation-description-override.ts @@ -2,13 +2,13 @@ import { readFileAsStringSync } from '../../utils'; import type { Oas3Decorator, Oas2Decorator } from '../../visitors'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Operation } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const OperationDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ operationIds }) => { return { Operation: { - leave(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) { + leave(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (!operation.operationId) return; if (!operationIds) throw new Error( diff --git a/packages/core/src/decorators/oas3/remove-unused-components.ts b/packages/core/src/decorators/oas3/remove-unused-components.ts index 4780961b9c..f65ae6d999 100644 --- a/packages/core/src/decorators/oas3/remove-unused-components.ts +++ b/packages/core/src/decorators/oas3/remove-unused-components.ts @@ -2,17 +2,17 @@ import { isEmptyObject } from '../../utils'; import type { Location } from '../../ref-utils'; import type { Oas3Decorator } from '../../visitors'; -import type { Oas3Components, Oas3Definition } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Components, Oas3Definition } from '../../typings/openapi'; export const RemoveUnusedComponents: Oas3Decorator = () => { const components = new Map< string, - { usedIn: Location[]; componentType?: keyof Oas3Components; name: string } + { usedIn: Location[]; componentType?: keyof Oas3Components<Oas3Schema | Oas3_1Schema>; name: string } >(); function registerComponent( location: Location, - componentType: keyof Oas3Components, + componentType: keyof Oas3Components<Oas3Schema | Oas3_1Schema>, name: string ): void { components.set(location.absolutePointer, { @@ -22,7 +22,7 @@ export const RemoveUnusedComponents: Oas3Decorator = () => { }); } - function removeUnusedComponents(root: Oas3Definition, removedPaths: string[]): number { + function removeUnusedComponents(root: Oas3Definition<Oas3Schema | Oas3_1Schema>, removedPaths: string[]): number { const removedLengthStart = removedPaths.length; for (const [path, { usedIn, name, componentType }] of components) { diff --git a/packages/core/src/rules/common/no-ambiguous-paths.ts b/packages/core/src/rules/common/no-ambiguous-paths.ts index a8d2af5b27..3fcf2c1300 100644 --- a/packages/core/src/rules/common/no-ambiguous-paths.ts +++ b/packages/core/src/rules/common/no-ambiguous-paths.ts @@ -1,11 +1,11 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -import type { Oas3Paths } from '../../typings/openapi'; +import type { Oas3_1Schema, Oas3Paths, Oas3Schema } from '../../typings/openapi'; import type { Oas2Paths } from '../../typings/swagger'; export const NoAmbiguousPaths: Oas3Rule | Oas2Rule = () => { return { - Paths(pathMap: Oas3Paths | Oas2Paths, { report, location }: UserContext) { + Paths(pathMap: Oas3Paths<Oas3Schema | Oas3_1Schema> | Oas2Paths, { report, location }: UserContext) { const seenPaths: string[] = []; for (const currentPath of Object.keys(pathMap)) { diff --git a/packages/core/src/rules/common/no-http-verbs-in-paths.ts b/packages/core/src/rules/common/no-http-verbs-in-paths.ts index 59560154fd..dce002b902 100644 --- a/packages/core/src/rules/common/no-http-verbs-in-paths.ts +++ b/packages/core/src/rules/common/no-http-verbs-in-paths.ts @@ -2,14 +2,14 @@ import { isPathParameter, splitCamelCaseIntoWords } from '../../utils'; import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2PathItem } from '../../typings/swagger'; -import type { Oas3PathItem } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3PathItem } from '../../typings/openapi'; import type { UserContext } from '../../walk'; const httpMethods = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace']; export const NoHttpVerbsInPaths: Oas3Rule | Oas2Rule = ({ splitIntoWords }) => { return { - PathItem(_path: Oas2PathItem | Oas3PathItem, { key, report, location }: UserContext) { + PathItem(_path: Oas2PathItem | Oas3PathItem<Oas3Schema | Oas3_1Schema>, { key, report, location }: UserContext) { const pathKey = key.toString(); if (!pathKey.startsWith('/')) return; const pathSegments = pathKey.split('/'); diff --git a/packages/core/src/rules/common/no-identical-paths.ts b/packages/core/src/rules/common/no-identical-paths.ts index 988dec3e56..d5da26d802 100644 --- a/packages/core/src/rules/common/no-identical-paths.ts +++ b/packages/core/src/rules/common/no-identical-paths.ts @@ -1,11 +1,11 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -import type { Oas3Paths } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Paths } from '../../typings/openapi'; import type { Oas2Paths } from '../../typings/swagger'; export const NoIdenticalPaths: Oas3Rule | Oas2Rule = () => { return { - Paths(pathMap: Oas3Paths | Oas2Paths, { report, location }: UserContext) { + Paths(pathMap: Oas3Paths<Oas3Schema | Oas3_1Schema> | Oas2Paths, { report, location }: UserContext) { const Paths = new Map<string, string>(); for (const pathName of Object.keys(pathMap)) { const id = pathName.replace(/{.+?}/g, '{VARIABLE}'); diff --git a/packages/core/src/rules/common/no-invalid-parameter-examples.ts b/packages/core/src/rules/common/no-invalid-parameter-examples.ts index 740335dfeb..a20094a655 100644 --- a/packages/core/src/rules/common/no-invalid-parameter-examples.ts +++ b/packages/core/src/rules/common/no-invalid-parameter-examples.ts @@ -1,13 +1,13 @@ import { getAdditionalPropertiesOption, validateExample } from '../utils'; import type { UserContext } from '../../walk'; -import type { Oas3Parameter } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Parameter } from '../../typings/openapi'; export const NoInvalidParameterExamples: any = (opts: any) => { const allowAdditionalProperties = getAdditionalPropertiesOption(opts) ?? false; return { Parameter: { - leave(parameter: Oas3Parameter, ctx: UserContext) { + leave(parameter: Oas3Parameter<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { if (parameter.example !== undefined) { validateExample( parameter.example, diff --git a/packages/core/src/rules/common/operation-description.ts b/packages/core/src/rules/common/operation-description.ts index 6f2bb45c04..b5cd7999b3 100644 --- a/packages/core/src/rules/common/operation-description.ts +++ b/packages/core/src/rules/common/operation-description.ts @@ -3,11 +3,11 @@ import { validateDefinedAndNonEmpty } from '../utils'; import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { UserContext } from '../../walk'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; export const OperationDescription: Oas3Rule | Oas2Rule = () => { return { - Operation(operation: Oas2Operation | Oas3Operation, ctx: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { validateDefinedAndNonEmpty('description', operation, ctx); }, }; diff --git a/packages/core/src/rules/common/operation-operationId-unique.ts b/packages/core/src/rules/common/operation-operationId-unique.ts index 54aa597abc..7819ca2ebd 100644 --- a/packages/core/src/rules/common/operation-operationId-unique.ts +++ b/packages/core/src/rules/common/operation-operationId-unique.ts @@ -1,13 +1,13 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const OperationIdUnique: Oas3Rule | Oas2Rule = () => { const seenOperations = new Set(); return { - Operation(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (!operation.operationId) return; if (seenOperations.has(operation.operationId)) { report({ diff --git a/packages/core/src/rules/common/operation-operationId-url-safe.ts b/packages/core/src/rules/common/operation-operationId-url-safe.ts index 5f1c410809..7a3ffb920d 100644 --- a/packages/core/src/rules/common/operation-operationId-url-safe.ts +++ b/packages/core/src/rules/common/operation-operationId-url-safe.ts @@ -1,6 +1,6 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; // eslint-disable-next-line no-useless-escape @@ -8,7 +8,7 @@ const validUrlSymbols = /^[A-Za-z0-9-._~:/?#\[\]@!\$&'()*+,;=]*$/; export const OperationIdUrlSafe: Oas3Rule | Oas2Rule = () => { return { - Operation(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (operation.operationId && !validUrlSymbols.test(operation.operationId)) { report({ message: 'Operation `operationId` should not have URL invalid characters.', diff --git a/packages/core/src/rules/common/operation-operationId.ts b/packages/core/src/rules/common/operation-operationId.ts index b759a2ab01..c4323802ff 100644 --- a/packages/core/src/rules/common/operation-operationId.ts +++ b/packages/core/src/rules/common/operation-operationId.ts @@ -3,13 +3,13 @@ import { validateDefinedAndNonEmpty } from '../utils'; import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { UserContext } from '../../walk'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; export const OperationOperationId: Oas3Rule | Oas2Rule = () => { return { Root: { PathItem: { - Operation(operation: Oas2Operation | Oas3Operation, ctx: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { validateDefinedAndNonEmpty('operationId', operation, ctx); }, }, diff --git a/packages/core/src/rules/common/operation-parameters-unique.ts b/packages/core/src/rules/common/operation-parameters-unique.ts index 901dfb26d6..dc4f30a6c4 100644 --- a/packages/core/src/rules/common/operation-parameters-unique.ts +++ b/packages/core/src/rules/common/operation-parameters-unique.ts @@ -1,6 +1,6 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Parameter } from '../../typings/swagger'; -import type { Oas3Parameter } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Parameter } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const OperationParametersUnique: Oas3Rule | Oas2Rule = () => { @@ -13,7 +13,7 @@ export const OperationParametersUnique: Oas3Rule | Oas2Rule = () => { seenPathParams = new Set(); }, Parameter( - parameter: Oas2Parameter | Oas3Parameter, + parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>, { report, key, parentLocations }: UserContext ) { const paramId = `${parameter.in}___${parameter.name}`; @@ -30,7 +30,7 @@ export const OperationParametersUnique: Oas3Rule | Oas2Rule = () => { seenOperationParams = new Set(); }, Parameter( - parameter: Oas2Parameter | Oas3Parameter, + parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>, { report, key, parentLocations }: UserContext ) { const paramId = `${parameter.in}___${parameter.name}`; diff --git a/packages/core/src/rules/common/operation-singular-tag.ts b/packages/core/src/rules/common/operation-singular-tag.ts index 6e149f9ca9..df3e914e5c 100644 --- a/packages/core/src/rules/common/operation-singular-tag.ts +++ b/packages/core/src/rules/common/operation-singular-tag.ts @@ -1,11 +1,11 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const OperationSingularTag: Oas3Rule | Oas2Rule = () => { return { - Operation(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (operation.tags && operation.tags.length > 1) { report({ message: 'Operation `tags` object should have only one tag.', diff --git a/packages/core/src/rules/common/operation-summary.ts b/packages/core/src/rules/common/operation-summary.ts index 18743ad9ed..171b1b747e 100644 --- a/packages/core/src/rules/common/operation-summary.ts +++ b/packages/core/src/rules/common/operation-summary.ts @@ -3,11 +3,11 @@ import { validateDefinedAndNonEmpty } from '../utils'; import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { UserContext } from '../../walk'; import type { Oas2Operation } from '../../typings/swagger'; -import type { Oas3Operation } from '../../typings/openapi'; +import type { Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; export const OperationSummary: Oas3Rule | Oas2Rule = () => { return { - Operation(operation: Oas2Operation | Oas3Operation, ctx: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { validateDefinedAndNonEmpty('summary', operation, ctx); }, }; diff --git a/packages/core/src/rules/common/operation-tag-defined.ts b/packages/core/src/rules/common/operation-tag-defined.ts index e492dba7e2..ea70225e14 100644 --- a/packages/core/src/rules/common/operation-tag-defined.ts +++ b/packages/core/src/rules/common/operation-tag-defined.ts @@ -1,16 +1,16 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Definition, Oas2Operation } from '../../typings/swagger'; -import type { Oas3Definition, Oas3Operation } from '../../typings/openapi'; +import type { Oas3Definition, Oas3Operation, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const OperationTagDefined: Oas3Rule | Oas2Rule = () => { let definedTags: Set<string>; return { - Root(root: Oas2Definition | Oas3Definition) { + Root(root: Oas2Definition | Oas3Definition<Oas3Schema | Oas3_1Schema>) { definedTags = new Set((root.tags ?? []).map((t) => t.name)); }, - Operation(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (operation.tags) { for (let i = 0; i < operation.tags.length; i++) { if (!definedTags.has(operation.tags[i])) { diff --git a/packages/core/src/rules/common/parameter-description.ts b/packages/core/src/rules/common/parameter-description.ts index f1495b29e4..2580307b7b 100644 --- a/packages/core/src/rules/common/parameter-description.ts +++ b/packages/core/src/rules/common/parameter-description.ts @@ -1,11 +1,11 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Parameter } from '../../typings/swagger'; -import type { Oas3Parameter } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Parameter } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const ParameterDescription: Oas3Rule | Oas2Rule = () => { return { - Parameter(parameter: Oas2Parameter | Oas3Parameter, { report, location }: UserContext) { + Parameter(parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (parameter.description === undefined) { report({ message: 'Parameter object description must be present.', diff --git a/packages/core/src/rules/common/path-excludes-patterns.ts b/packages/core/src/rules/common/path-excludes-patterns.ts index 14988cbffd..3304c5314f 100644 --- a/packages/core/src/rules/common/path-excludes-patterns.ts +++ b/packages/core/src/rules/common/path-excludes-patterns.ts @@ -1,11 +1,11 @@ import type { Oas2Rule, Oas3Rule } from '../../visitors'; import type { Oas2PathItem } from '../../typings/swagger'; -import type { Oas3PathItem } from '../../typings/openapi'; +import type { Oas3PathItem, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const PathExcludesPatterns: Oas3Rule | Oas2Rule = ({ patterns }) => { return { - PathItem(_path: Oas2PathItem | Oas3PathItem, { report, key, location }: UserContext) { + PathItem(_path: Oas2PathItem | Oas3PathItem<Oas3Schema | Oas3_1Schema>, { report, key, location }: UserContext) { if (!patterns) throw new Error(`Parameter "patterns" is not provided for "path-excludes-patterns" rule`); const pathKey = key.toString(); diff --git a/packages/core/src/rules/common/path-http-verbs-order.ts b/packages/core/src/rules/common/path-http-verbs-order.ts index 3bfe0bcddd..4f1f2615b6 100644 --- a/packages/core/src/rules/common/path-http-verbs-order.ts +++ b/packages/core/src/rules/common/path-http-verbs-order.ts @@ -1,6 +1,6 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2PathItem } from '../../typings/swagger'; -import type { Oas3PathItem } from '../../typings/openapi'; +import type { Oas3PathItem, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { UserContext } from '../../walk'; const defaultOrder = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options', 'trace']; @@ -12,7 +12,7 @@ export const PathHttpVerbsOrder: Oas3Rule | Oas2Rule = (opts: any) => { } return { - PathItem(path: Oas2PathItem | Oas3PathItem, { report, location }: UserContext) { + PathItem(path: Oas2PathItem | Oas3PathItem<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { const httpVerbs = Object.keys(path).filter((k) => order.includes(k)); for (let i = 0; i < httpVerbs.length - 1; i++) { diff --git a/packages/core/src/rules/common/path-params-defined.ts b/packages/core/src/rules/common/path-params-defined.ts index bbb696b860..88c5ed50b5 100644 --- a/packages/core/src/rules/common/path-params-defined.ts +++ b/packages/core/src/rules/common/path-params-defined.ts @@ -1,6 +1,6 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Parameter } from '../../typings/swagger'; -import type { Oas3Parameter } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Parameter } from '../../typings/openapi'; import type { UserContext } from '../../walk'; const pathRegex = /\{([a-zA-Z0-9_.-]+)\}+/g; @@ -20,7 +20,7 @@ export const PathParamsDefined: Oas3Rule | Oas2Rule = () => { Array.from(key!.toString().matchAll(pathRegex)).map((m) => m[1]) ); }, - Parameter(parameter: Oas2Parameter | Oas3Parameter, { report, location }: UserContext) { + Parameter(parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (parameter.in === 'path' && parameter.name) { definedPathParams.add(parameter.name); if (!pathTemplateParams.has(parameter.name)) { @@ -48,7 +48,7 @@ export const PathParamsDefined: Oas3Rule | Oas2Rule = () => { } } }, - Parameter(parameter: Oas2Parameter | Oas3Parameter, { report, location }: UserContext) { + Parameter(parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (parameter.in === 'path' && parameter.name) { definedOperationParams.add(parameter.name); if (!pathTemplateParams.has(parameter.name)) { diff --git a/packages/core/src/rules/common/response-contains-header.ts b/packages/core/src/rules/common/response-contains-header.ts index 38ad9d6f75..ba875329cc 100644 --- a/packages/core/src/rules/common/response-contains-header.ts +++ b/packages/core/src/rules/common/response-contains-header.ts @@ -2,7 +2,7 @@ import { getMatchingStatusCodeRange } from '../../utils'; import type { Oas2Rule, Oas3Rule } from '../../visitors'; import type { UserContext } from '../../walk'; -import type { Oas3Response } from '../../typings/openapi'; +import type { Oas3Response, Oas3Schema, Oas3_1Schema } from '../../typings/openapi'; import type { Oas2Response } from '../../typings/swagger'; export const ResponseContainsHeader: Oas3Rule | Oas2Rule = (options) => { @@ -10,7 +10,7 @@ export const ResponseContainsHeader: Oas3Rule | Oas2Rule = (options) => { return { Operation: { Response: { - enter: (response: Oas2Response | Oas3Response, { report, location, key }: UserContext) => { + enter: (response: Oas2Response | Oas3Response<Oas3Schema | Oas3_1Schema>, { report, location, key }: UserContext) => { const expectedHeaders = names[key] || names[getMatchingStatusCodeRange(key)] || diff --git a/packages/core/src/rules/common/security-defined.ts b/packages/core/src/rules/common/security-defined.ts index 1e1ea0b98e..b27dfed6f6 100644 --- a/packages/core/src/rules/common/security-defined.ts +++ b/packages/core/src/rules/common/security-defined.ts @@ -8,6 +8,8 @@ import type { Oas2SecurityScheme, } from '../../typings/swagger'; import type { + Oas3Schema, + Oas3_1Schema, Oas3Definition, Oas3Operation, Oas3PathItem, @@ -31,7 +33,7 @@ export const SecurityDefined: Oas3Rule | Oas2Rule = (opts: { return { Root: { - leave(root: Oas2Definition | Oas3Definition, { report }: UserContext) { + leave(root: Oas2Definition | Oas3Definition<Oas3Schema | Oas3_1Schema>, { report }: UserContext) { for (const [name, scheme] of referencedSchemes.entries()) { if (scheme.defined) continue; for (const reportedFromLocation of scheme.from) { @@ -69,10 +71,10 @@ export const SecurityDefined: Oas3Rule | Oas2Rule = (opts: { } }, PathItem: { - enter(pathItem: Oas2PathItem | Oas3PathItem, { key }: UserContext) { + enter(pathItem: Oas2PathItem | Oas3PathItem<Oas3Schema | Oas3_1Schema>, { key }: UserContext) { path = key as string; }, - Operation(operation: Oas2Operation | Oas3Operation, { location, key }: UserContext) { + Operation(operation: Oas2Operation | Oas3Operation<Oas3Schema | Oas3_1Schema>, { location, key }: UserContext) { const isException = opts.exceptions?.some( (item) => item.path === path && diff --git a/packages/core/src/rules/common/tags-alphabetical.ts b/packages/core/src/rules/common/tags-alphabetical.ts index 63f85f2f52..0411406c4e 100644 --- a/packages/core/src/rules/common/tags-alphabetical.ts +++ b/packages/core/src/rules/common/tags-alphabetical.ts @@ -1,11 +1,11 @@ import type { Oas3Rule, Oas2Rule } from '../../visitors'; import type { Oas2Definition, Oas2Tag } from '../../typings/swagger'; -import type { Oas3Definition, Oas3Tag } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Definition, Oas3Tag } from '../../typings/openapi'; import type { UserContext } from '../../walk'; export const TagsAlphabetical: Oas3Rule | Oas2Rule = ({ ignoreCase = false }) => { return { - Root(root: Oas2Definition | Oas3Definition, { report, location }: UserContext) { + Root(root: Oas2Definition | Oas3Definition<Oas3Schema | Oas3_1Schema>, { report, location }: UserContext) { if (!root.tags) return; for (let i = 0; i < root.tags.length - 1; i++) { if (getTagName(root.tags[i], ignoreCase) > getTagName(root.tags[i + 1], ignoreCase)) { diff --git a/packages/core/src/rules/oas3/array-parameter-serialization.ts b/packages/core/src/rules/oas3/array-parameter-serialization.ts index 2ca6e206e5..8f48a28c28 100644 --- a/packages/core/src/rules/oas3/array-parameter-serialization.ts +++ b/packages/core/src/rules/oas3/array-parameter-serialization.ts @@ -12,7 +12,7 @@ export const ArrayParameterSerialization: Oas3Rule = ( ): Oas3Visitor => { return { Parameter: { - leave(node: Oas3Parameter, ctx) { + leave(node: Oas3Parameter<Oas3_1Schema>, ctx) { if (!node.schema) { return; } @@ -32,7 +32,7 @@ export const ArrayParameterSerialization: Oas3Rule = ( }; function shouldReportMissingStyleAndExplode( - node: Oas3Parameter, + node: Oas3Parameter<Oas3_1Schema>, schema: Oas3_1Schema, options: ArrayParameterSerializationOptions ) { diff --git a/packages/core/src/rules/oas3/component-name-unique.ts b/packages/core/src/rules/oas3/component-name-unique.ts index cbf21fd555..8a83365e88 100644 --- a/packages/core/src/rules/oas3/component-name-unique.ts +++ b/packages/core/src/rules/oas3/component-name-unique.ts @@ -7,6 +7,7 @@ import type { Oas3RequestBody, Oas3Response, Oas3Schema, + Oas3_1Schema, OasRef, } from '../../typings/openapi'; @@ -54,7 +55,7 @@ export const ComponentNameUnique: Oas3Rule | Oas2Rule = (options) => { }, }, Root: { - leave(root: Oas3Definition, ctx: UserContext) { + leave(root: Oas3Definition<Oas3Schema | Oas3_1Schema>, ctx: UserContext) { components.forEach((value, key, _) => { if (value.absolutePointers.size > 1) { const component = getComponentFromKey(key); @@ -90,7 +91,7 @@ export const ComponentNameUnique: Oas3Rule | Oas2Rule = (options) => { if (options.responses != 'off') { rule.NamedResponses = { - Response(_: Oas3Response, { location }: UserContext) { + Response(_: Oas3Response<Oas3Schema | Oas3_1Schema>, { location }: UserContext) { addComponentFromAbsoluteLocation(TYPE_NAME_RESPONSE, location); }, }; @@ -98,7 +99,7 @@ export const ComponentNameUnique: Oas3Rule | Oas2Rule = (options) => { if (options.parameters != 'off') { rule.NamedParameters = { - Parameter(_: Oas3Parameter, { location }: UserContext) { + Parameter(_: Oas3Parameter<Oas3Schema | Oas3_1Schema>, { location }: UserContext) { addComponentFromAbsoluteLocation(TYPE_NAME_PARAMETER, location); }, }; @@ -106,7 +107,7 @@ export const ComponentNameUnique: Oas3Rule | Oas2Rule = (options) => { if (options.requestBodies != 'off') { rule.NamedRequestBodies = { - RequestBody(_: Oas3RequestBody, { location }: UserContext) { + RequestBody(_: Oas3RequestBody<Oas3Schema | Oas3_1Schema>, { location }: UserContext) { addComponentFromAbsoluteLocation(TYPE_NAME_REQUEST_BODY, location); }, }; diff --git a/packages/core/src/rules/other/stats.ts b/packages/core/src/rules/other/stats.ts index 3ba9a152cc..faf1808195 100644 --- a/packages/core/src/rules/other/stats.ts +++ b/packages/core/src/rules/other/stats.ts @@ -1,4 +1,4 @@ -import type { Oas3Parameter, OasRef, Oas3Tag } from '../../typings/openapi'; +import type { Oas3Schema, Oas3_1Schema, Oas3Parameter, OasRef, Oas3Tag } from '../../typings/openapi'; import type { Oas2Parameter } from '../../typings/swagger'; import type { StatsAccumulator } from '../../typings/common'; @@ -58,7 +58,7 @@ export const Stats = (statsAccumulator: StatsAccumulator) => { }, }, Parameter: { - leave(parameter: Oas2Parameter | Oas3Parameter) { + leave(parameter: Oas2Parameter | Oas3Parameter<Oas3Schema | Oas3_1Schema>) { statsAccumulator.parameters.items!.add(parameter.name); }, }, diff --git a/packages/core/src/types/oas3_1.ts b/packages/core/src/types/oas3_1.ts index c9c5de778d..3f3d74e58a 100755 --- a/packages/core/src/types/oas3_1.ts +++ b/packages/core/src/types/oas3_1.ts @@ -182,6 +182,8 @@ export const Schema: NodeType = { const: null, $comment: { type: 'string' }, 'x-tags': { type: 'array', items: { type: 'string' } }, + $dynamicAnchor: { type: 'string' }, + $dynamicRef: { type: 'string' }, }, extensionsPrefix: 'x-', }; diff --git a/packages/core/src/typings/openapi.ts b/packages/core/src/typings/openapi.ts index 9497f91e71..0a70230525 100644 --- a/packages/core/src/typings/openapi.ts +++ b/packages/core/src/typings/openapi.ts @@ -1,13 +1,13 @@ -export interface Oas3Definition { +export interface Oas3Definition<T extends Oas3Schema | Oas3_1Schema> { openapi: string; info?: Oas3Info; servers?: Oas3Server[]; - paths?: Oas3Paths; - components?: Oas3Components; + paths?: Oas3Paths<T>; + components?: Oas3Components<T>; security?: Oas3SecurityRequirement[]; tags?: Oas3Tag[]; externalDocs?: Oas3ExternalDocs; - 'x-webhooks'?: Oas3_1Webhooks; + 'x-webhooks'?: Oas3_1Webhooks<T>; } export interface Oas3Info { @@ -32,8 +32,8 @@ export interface Oas3ServerVariable { description?: string; } -export interface Oas3Paths { - [path: string]: Referenced<Oas3PathItem>; +export interface Oas3Paths<T extends Oas3Schema | Oas3_1Schema> { + [path: string]: Referenced<Oas3PathItem<T>>; } export interface OasRef { $ref: string; @@ -41,19 +41,20 @@ export interface OasRef { export type Referenced<T> = OasRef | T; -export interface Oas3PathItem { +export interface Oas3PathItem<T extends Oas3Schema | Oas3_1Schema> { summary?: string; description?: string; - get?: Oas3Operation; - put?: Oas3Operation; - post?: Oas3Operation; - delete?: Oas3Operation; - options?: Oas3Operation; - head?: Oas3Operation; - patch?: Oas3Operation; - trace?: Oas3Operation; + get?: Oas3Operation<T>; + put?: Oas3Operation<T>; + post?: Oas3Operation<T>; + delete?: Oas3Operation<T>; + options?: Oas3Operation<T>; + head?: Oas3Operation<T>; + patch?: Oas3Operation<T>; + trace?: Oas3Operation<T>; servers?: Oas3Server[]; - parameters?: Array<Referenced<Oas3Parameter>>; + parameters?: Array<Referenced<Oas3Parameter<T>>>; + $ref?: Referenced<OasRef>; } export interface Oas3XCodeSample { @@ -62,16 +63,16 @@ export interface Oas3XCodeSample { source: string; } -export interface Oas3Operation { +export interface Oas3Operation<T extends Oas3Schema | Oas3_1Schema> { tags?: string[]; summary?: string; description?: string; externalDocs?: Oas3ExternalDocs; operationId?: string; - parameters?: Array<Referenced<Oas3Parameter>>; - requestBody?: Referenced<Oas3RequestBody>; - responses: Oas3Responses; - callbacks?: { [name: string]: Referenced<Oas3Callback> }; + parameters?: Array<Referenced<Oas3Parameter<T>>>; + requestBody?: Referenced<Oas3RequestBody<T>>; + responses: Oas3Responses<T>; + callbacks?: { [name: string]: Referenced<Oas3Callback<T>> }; deprecated?: boolean; security?: Oas3SecurityRequirement[]; servers?: Oas3Server[]; @@ -80,7 +81,7 @@ export interface Oas3Operation { 'x-hideTryItPanel'?: boolean; } -export interface Oas3Parameter { +export interface Oas3Parameter<T extends Oas3Schema | Oas3_1Schema> { name: string; in?: Oas3ParameterLocation; description?: string; @@ -90,10 +91,10 @@ export interface Oas3Parameter { style?: Oas3ParameterStyle; explode?: boolean; allowReserved?: boolean; - schema?: Referenced<Oas3Schema>; + schema?: Referenced<T>; example?: unknown; examples?: { [media: string]: Referenced<Oas3Example> }; - content?: { [media: string]: Oas3MediaType }; + content?: { [media: string]: Oas3MediaType<T> }; } export interface Oas3Example { @@ -112,7 +113,7 @@ export interface Oas3Xml { } // common fields for OpenAPI Schema v3.x -interface Oas3XSchemaBase { +interface Oas3XSchemaBase<T extends Oas3Schema | Oas3_1Schema> { $ref?: string; description?: string; default?: unknown; @@ -123,8 +124,10 @@ interface Oas3XSchemaBase { format?: string; externalDocs?: Oas3ExternalDocs; discriminator?: Oas3Discriminator; - nullable?: boolean; - + oneOf?: T[]; + anyOf?: T[]; + allOf?: T[]; + not?: T; title?: string; multipleOf?: number; maximum?: number; @@ -132,9 +135,11 @@ interface Oas3XSchemaBase { maxLength?: number; minLength?: number; pattern?: string; + items?: boolean | T; maxItems?: number; minItems?: number; uniqueItems?: boolean; + additionalProperties?: boolean | T; maxProperties?: number; minProperties?: number; enum?: unknown[]; @@ -144,30 +149,27 @@ interface Oas3XSchemaBase { 'x-tags'?: string[]; } -export interface Oas3Schema extends Oas3XSchemaBase { +export interface Oas3Schema extends Oas3XSchemaBase<Oas3Schema> { type?: string; properties?: { [name: string]: Referenced<Oas3Schema> }; - additionalProperties?: boolean | Oas3Schema; - items?: Oas3Schema; exclusiveMaximum?: boolean; exclusiveMinimum?: boolean; - oneOf?: Oas3Schema[]; - anyOf?: Oas3Schema[]; - allOf?: Oas3Schema[]; - not?: Oas3Schema; + nullable?: boolean; } -export interface Oas3_1Schema extends Oas3XSchemaBase { +export interface Oas3_1Schema extends Oas3XSchemaBase<Oas3_1Schema> { + $id?: string; + $schema?: string; + $anchor?: string; + $dynamicAnchor?: string; + $dynamicRef?: string; + $defs?: { [name: string]: Referenced<Oas3_1Schema> }; + $vocabulary?: { [uri: string]: boolean }; + $comment?: string; type?: string | string[]; properties?: { [name: string]: Referenced<Oas3_1Schema> }; - additionalProperties?: boolean | Oas3_1Schema; examples?: unknown[]; prefixItems?: Oas3_1Schema[]; - items?: Oas3_1Schema; - oneOf?: Oas3_1Schema[]; - anyOf?: Oas3_1Schema[]; - allOf?: Oas3_1Schema[]; - not?: Oas3_1Schema; exclusiveMaximum?: number; exclusiveMinimum?: number; const?: unknown; @@ -181,19 +183,19 @@ export interface Oas3_1Schema extends Oas3XSchemaBase { dependentRequired?: { [name: string]: string[] }; dependentSchemas?: { [name: string]: Referenced<Oas3_1Schema> }; patternProperties?: { [name: string]: Referenced<Oas3_1Schema> }; - unevaluatedItems?: Oas3_1Schema; - unevaluatedProperties?: Oas3_1Schema; + unevaluatedItems?: boolean | Oas3_1Schema; + unevaluatedProperties?: boolean | Oas3_1Schema; contentSchema?: Oas3_1Schema; contentMediaType?: string; contentEncoding?: string; } -export interface Oas3_1Definition extends Oas3Definition { - webhooks?: Oas3_1Webhooks; +export interface Oas3_1Definition<T extends Oas3Schema | Oas3_1Schema> extends Oas3Definition<T> { + webhooks?: Oas3_1Webhooks<T>; } -export interface Oas3_1Webhooks { - [webhook: string]: Referenced<Oas3PathItem>; +export interface Oas3_1Webhooks<T extends Oas3Schema | Oas3_1Schema> { + [webhook: string]: Referenced<Oas3PathItem<T>>; } export interface Oas3Discriminator { @@ -202,16 +204,16 @@ export interface Oas3Discriminator { 'x-explicitMappingOnly'?: boolean; } -export interface Oas3MediaType { - schema?: Referenced<Oas3Schema>; +export interface Oas3MediaType<T extends Oas3Schema | Oas3_1Schema> { + schema?: Referenced<T>; example?: unknown; examples?: { [name: string]: Referenced<Oas3Example> }; - encoding?: { [field: string]: Oas3Encoding }; + encoding?: { [field: string]: Oas3Encoding<T> }; } -export interface Oas3Encoding { +export interface Oas3Encoding<T extends Oas3Schema | Oas3_1Schema> { contentType: string; - headers?: { [name: string]: Referenced<Oas3Header> }; + headers?: { [name: string]: Referenced<Oas3Header<T>> }; style: Oas3ParameterStyle; explode: boolean; allowReserved: boolean; @@ -227,46 +229,55 @@ export type Oas3ParameterStyle = | 'pipeDelimited' | 'deepObject'; -export interface Oas3RequestBody { +export interface Oas3RequestBody<T extends Oas3Schema | Oas3_1Schema> { description?: string; required?: boolean; - content: { [mime: string]: Oas3MediaType }; + content: { [mime: string]: Oas3MediaType<T> }; } -export interface Oas3Responses { - [code: string]: Oas3Response; +export interface Oas3Responses<T extends Oas3Schema | Oas3_1Schema> { + [code: string]: Oas3Response<T>; } -export interface Oas3Response { +export interface Oas3Response<T extends Oas3Schema | Oas3_1Schema> { description?: string; - headers?: { [name: string]: Referenced<Oas3Header> }; - content?: { [mime: string]: Oas3MediaType }; + headers?: { [name: string]: Referenced<Oas3Header<T>> }; + content?: { [mime: string]: Oas3MediaType<T> }; links?: { [name: string]: Referenced<Oas3Link> }; } export interface Oas3Link { - $ref?: string; + operationRef?: string; + operationId?: string; + parameters?: { [ name: string]: unknown }; + requestBody?: unknown; + description?: string; + server?: Oas3Server; } -export type Oas3Header = Omit<Oas3Parameter, 'in' | 'name'>; +export type Oas3Header<T extends Oas3Schema | Oas3_1Schema> = Omit<Oas3Parameter<T>, 'in' | 'name'>; -export interface Oas3Callback { - [name: string]: Oas3PathItem; +export interface Oas3Callback<T extends Oas3Schema | Oas3_1Schema> { + [name: string]: Oas3PathItem<T>; } -export interface Oas3Components { - schemas?: { [name: string]: Referenced<Oas3Schema> }; - responses?: { [name: string]: Referenced<Oas3Response> }; - parameters?: { [name: string]: Referenced<Oas3Parameter> }; +export interface Oas3Components<T extends Oas3Schema | Oas3_1Schema> { + schemas?: { [name: string]: Referenced<T> }; + responses?: { [name: string]: Referenced<Oas3Response<T>> }; + parameters?: { [name: string]: Referenced<Oas3Parameter<T>> }; examples?: { [name: string]: Referenced<Oas3Example> }; - requestBodies?: { [name: string]: Referenced<Oas3RequestBody> }; - headers?: { [name: string]: Referenced<Oas3Header> }; + requestBodies?: { [name: string]: Referenced<Oas3RequestBody<T>> }; + headers?: { [name: string]: Referenced<Oas3Header<T>> }; securitySchemes?: { [name: string]: Referenced<Oas3SecurityScheme> }; links?: { [name: string]: Referenced<Oas3Link> }; - callbacks?: { [name: string]: Referenced<Oas3Callback> }; + callbacks?: { [name: string]: Referenced<Oas3Callback<T>> }; +} + +export interface Oas3_1Components<T extends Oas3Components<Oas3_1Schema>>{ + pathItems?: { [name: string]: Referenced<Oas3PathItem<Oas3_1Schema>> }; } -export type Oas3ComponentName = keyof Oas3Components; +export type Oas3ComponentName<T extends Oas3Schema | Oas3_1Schema> = keyof Oas3Components<T>; export interface Oas3SecurityRequirement { [name: string]: string[]; diff --git a/packages/core/src/visitors.ts b/packages/core/src/visitors.ts index ac7aa00cab..7acb865997 100644 --- a/packages/core/src/visitors.ts +++ b/packages/core/src/visitors.ts @@ -10,8 +10,10 @@ import type { Oas3Info, Oas3Contact, Oas3Components, + Oas3_1Components, Oas3License, Oas3Schema, + Oas3_1Schema, Oas3Header, Oas3Parameter, Oas3Operation, @@ -152,7 +154,7 @@ export type BaseVisitor = { }; type Oas3FlatVisitor = { - Root?: VisitFunctionOrObject<Oas3Definition>; + Root?: VisitFunctionOrObject<Oas3Definition<Oas3Schema | Oas3_1Schema>>; Tag?: VisitFunctionOrObject<Oas3Tag>; ExternalDocs?: VisitFunctionOrObject<Oas3ExternalDocs>; Server?: VisitFunctionOrObject<Oas3Server>; @@ -161,36 +163,36 @@ type Oas3FlatVisitor = { Info?: VisitFunctionOrObject<Oas3Info>; Contact?: VisitFunctionOrObject<Oas3Contact>; License?: VisitFunctionOrObject<Oas3License>; - Paths?: VisitFunctionOrObject<Record<string, Oas3PathItem>>; - PathItem?: VisitFunctionOrObject<Oas3PathItem>; - Callback?: VisitFunctionOrObject<Oas3Callback>; - CallbacksMap?: VisitFunctionOrObject<Record<string, Oas3Callback>>; - Parameter?: VisitFunctionOrObject<Oas3Parameter>; - Operation?: VisitFunctionOrObject<Oas3Operation>; - RequestBody?: VisitFunctionOrObject<Oas3RequestBody>; - MediaTypesMap?: VisitFunctionOrObject<Record<string, Oas3MediaType>>; - MediaType?: VisitFunctionOrObject<Oas3MediaType>; + Paths?: VisitFunctionOrObject<Record<string, Oas3PathItem<Oas3Schema | Oas3_1Schema>>>; + PathItem?: VisitFunctionOrObject<Oas3PathItem<Oas3Schema | Oas3_1Schema>>; + Callback?: VisitFunctionOrObject<Oas3Callback<Oas3Schema | Oas3_1Schema>>; + CallbacksMap?: VisitFunctionOrObject<Record<string, Oas3Callback<Oas3Schema | Oas3_1Schema>>>; + Parameter?: VisitFunctionOrObject<Oas3Parameter<Oas3Schema | Oas3_1Schema>>; + Operation?: VisitFunctionOrObject<Oas3Operation<Oas3Schema | Oas3_1Schema>>; + RequestBody?: VisitFunctionOrObject<Oas3RequestBody<Oas3Schema | Oas3_1Schema>>; + MediaTypesMap?: VisitFunctionOrObject<Record<string, Oas3MediaType<Oas3Schema | Oas3_1Schema>>>; + MediaType?: VisitFunctionOrObject<Oas3MediaType<Oas3Schema | Oas3_1Schema>>; Example?: VisitFunctionOrObject<Oas3Example>; - Encoding?: VisitFunctionOrObject<Oas3Encoding>; - Header?: VisitFunctionOrObject<Oas3Header>; - Responses?: VisitFunctionOrObject<Record<string, Oas3Response>>; - Response?: VisitFunctionOrObject<Oas3Response>; + Encoding?: VisitFunctionOrObject<Oas3Encoding<Oas3Schema | Oas3_1Schema>>; + Header?: VisitFunctionOrObject<Oas3Header<Oas3Schema | Oas3_1Schema>>; + Responses?: VisitFunctionOrObject<Record<string, Oas3Response<Oas3Schema | Oas3_1Schema>>>; + Response?: VisitFunctionOrObject<Oas3Response<Oas3Schema | Oas3_1Schema>>; Link?: VisitFunctionOrObject<Oas3Link>; Schema?: VisitFunctionOrObject<Oas3Schema>; Xml?: VisitFunctionOrObject<Oas3Xml>; SchemaProperties?: VisitFunctionOrObject<Record<string, Oas3Schema>>; DiscriminatorMapping?: VisitFunctionOrObject<Record<string, string>>; Discriminator?: VisitFunctionOrObject<Oas3Discriminator>; - Components?: VisitFunctionOrObject<Oas3Components>; + Components?: VisitFunctionOrObject<Oas3Components<Oas3Schema | Oas3_1Schema> | Oas3_1Components<Oas3_1Schema>>; NamedSchemas?: VisitFunctionOrObject<Record<string, Oas3Schema>>; - NamedResponses?: VisitFunctionOrObject<Record<string, Oas3Response>>; - NamedParameters?: VisitFunctionOrObject<Record<string, Oas3Parameter>>; + NamedResponses?: VisitFunctionOrObject<Record<string, Oas3Response<Oas3Schema | Oas3_1Schema>>>; + NamedParameters?: VisitFunctionOrObject<Record<string, Oas3Parameter<Oas3Schema | Oas3_1Schema>>>; NamedExamples?: VisitFunctionOrObject<Record<string, Oas3Example>>; - NamedRequestBodies?: VisitFunctionOrObject<Record<string, Oas3RequestBody>>; - NamedHeaders?: VisitFunctionOrObject<Record<string, Oas3Header>>; + NamedRequestBodies?: VisitFunctionOrObject<Record<string, Oas3RequestBody<Oas3Schema | Oas3_1Schema>>>; + NamedHeaders?: VisitFunctionOrObject<Record<string, Oas3Header<Oas3Schema | Oas3_1Schema>>>; NamedSecuritySchemes?: VisitFunctionOrObject<Record<string, Oas3SecurityScheme>>; NamedLinks?: VisitFunctionOrObject<Record<string, Oas3Link>>; - NamedCallbacks?: VisitFunctionOrObject<Record<string, Oas3Callback>>; + NamedCallbacks?: VisitFunctionOrObject<Record<string, Oas3Callback<Oas3Schema | Oas3_1Schema>>>; ImplicitFlow?: VisitFunctionOrObject<Oas3SecurityScheme['flows']['implicit']>; PasswordFlow?: VisitFunctionOrObject<Oas3SecurityScheme['flows']['password']>; ClientCredentials?: VisitFunctionOrObject<Oas3SecurityScheme['flows']['clientCredentials']>;