diff --git a/package.json b/package.json index e45ac2c5..8c50a6d2 100644 --- a/package.json +++ b/package.json @@ -51,5 +51,8 @@ "tslint-config-prettier": "1.18.0", "tslint-plugin-prettier": "2.3.0", "typescript": "4.7.2" + }, + "dependencies": { + "bootstrap": "^5.3.0" } } diff --git a/packages/openapi-framework/index.ts b/packages/openapi-framework/index.ts index ab53a186..61710313 100644 --- a/packages/openapi-framework/index.ts +++ b/packages/openapi-framework/index.ts @@ -5,7 +5,7 @@ import OpenAPIRequestValidator from 'openapi-request-validator'; import OpenAPIResponseValidator from 'openapi-response-validator'; import OpenAPISchemaValidator from 'openapi-schema-validator'; import OpenAPISecurityHandler from 'openapi-security-handler'; -import { OpenAPI, OpenAPIV2, OpenAPIV3 } from 'openapi-types'; +import { OpenAPI, OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { Logger } from 'ts-log'; import BasePath from './src/BasePath'; import { @@ -148,6 +148,7 @@ export default class OpenAPIFramework implements IOpenAPIFramework { 'validateApiDoc' in args ? !!args.validateApiDoc : true; this.validator = new OpenAPISchemaValidator({ version: + (this.apiDoc as OpenAPIV3_1.Document).openapi || (this.apiDoc as OpenAPIV3.Document).openapi || (this.apiDoc as OpenAPIV2.Document).swagger, extensions: this.apiDoc[`x-${this.name}-schema-extension`], diff --git a/packages/openapi-request-validator/index.ts b/packages/openapi-request-validator/index.ts index 700c81be..95e9c5be 100644 --- a/packages/openapi-request-validator/index.ts +++ b/packages/openapi-request-validator/index.ts @@ -8,7 +8,7 @@ import Ajv, { } from 'ajv'; import addFormats from 'ajv-formats'; import { convertParametersToJSONSchema } from 'openapi-jsonschema-parameters'; -import { IJsonSchema, OpenAPI, OpenAPIV3 } from 'openapi-types'; +import { IJsonSchema, OpenAPI, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; import { dummyLogger, Logger } from 'ts-log'; const contentTypeParser = require('content-type'); const LOCAL_DEFINITION_REGEX = /^#\/([^\/]+)\/([^\/]+)$/; @@ -30,7 +30,7 @@ export interface OpenAPIRequestValidatorArgs { loggingKey?: string; logger?: Logger; parameters?: OpenAPI.Parameters; - requestBody?: OpenAPIV3.RequestBodyObject; + requestBody?: OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject; schemas?: IJsonSchema[]; componentSchemas?: IJsonSchema[]; errorTransformer?( @@ -57,7 +57,7 @@ export default class OpenAPIRequestValidator private isBodyRequired: boolean; private logger: Logger = dummyLogger; private loggingKey: string = ''; - private requestBody: OpenAPIV3.RequestBodyObject; + private requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject; private requestBodyValidators: RequestBodyValidators = {}; private validateBody: ValidateFunction; private validateFormData: ValidateFunction; @@ -454,7 +454,7 @@ function extendedErrorMapper(mapper) { function getSchemaForMediaType( contentTypeHeader: string, - requestBodySpec: OpenAPIV3.RequestBodyObject, + requestBodySpec: OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject, logger: Logger, loggingKey: string ): string { @@ -594,6 +594,7 @@ function withAddedLocation(location, errors) { function resolveAndSanitizeRequestBodySchema( requestBodySchema: | OpenAPIV3.ReferenceObject + | OpenAPIV3_1.ReferenceObject | OpenAPIV3.NonArraySchemaObject | OpenAPIV3.ArraySchemaObject, v: Ajv @@ -634,6 +635,7 @@ function resolveAndSanitizeRequestBodySchema( } else if ('allOf' in requestBodySchema) { requestBodySchema.allOf = requestBodySchema.allOf.map((val): | OpenAPIV3.ReferenceObject + | OpenAPIV3_1.ReferenceObject | OpenAPIV3.NonArraySchemaObject | OpenAPIV3.ArraySchemaObject => { val = sanitizeReadonlyPropertiesFromRequired(val); @@ -642,6 +644,7 @@ function resolveAndSanitizeRequestBodySchema( } else if ('oneOf' in requestBodySchema) { requestBodySchema.oneOf = requestBodySchema.oneOf.map((val): | OpenAPIV3.ReferenceObject + | OpenAPIV3_1.ReferenceObject | OpenAPIV3.NonArraySchemaObject | OpenAPIV3.ArraySchemaObject => { val = sanitizeReadonlyPropertiesFromRequired(val); @@ -650,6 +653,7 @@ function resolveAndSanitizeRequestBodySchema( } else if ('anyOf' in requestBodySchema) { requestBodySchema.anyOf = requestBodySchema.anyOf.map((val): | OpenAPIV3.ReferenceObject + | OpenAPIV3_1.ReferenceObject | OpenAPIV3.NonArraySchemaObject | OpenAPIV3.ArraySchemaObject => { val = sanitizeReadonlyPropertiesFromRequired(val); @@ -662,6 +666,7 @@ function resolveAndSanitizeRequestBodySchema( function sanitizeReadonlyPropertiesFromRequired( schema: | OpenAPIV3.ReferenceObject + | OpenAPIV3_1.ReferenceObject | OpenAPIV3.NonArraySchemaObject | OpenAPIV3.ArraySchemaObject ) { diff --git a/packages/openapi-response-validator/index.ts b/packages/openapi-response-validator/index.ts index e306013d..788e2498 100644 --- a/packages/openapi-response-validator/index.ts +++ b/packages/openapi-response-validator/index.ts @@ -4,7 +4,7 @@ import Ajv, { ErrorObject, ValidateFunction, } from 'ajv'; -import { IJsonSchema, OpenAPIV2, OpenAPIV3 } from 'openapi-types'; +import { IJsonSchema, OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'; const LOCAL_DEFINITION_REGEX = /^#\/([^\/]+)\/([^\/]+)$/; @@ -22,14 +22,14 @@ export interface OpenAPIResponseValidatorArgs { definitions?: { [definitionName: string]: IJsonSchema; }; - components?: OpenAPIV3.ComponentsObject; + components?: OpenAPIV3.ComponentsObject | OpenAPIV3_1.ComponentsObject; externalSchemas?: { [index: string]: IJsonSchema; }; loggingKey?: string; responses: { [responseCode: string]: { - schema: OpenAPIV2.Schema | OpenAPIV3.SchemaObject; + schema: OpenAPIV2.Schema | OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject; }; }; diff --git a/packages/openapi-schema-validator/CHANGELOG.md b/packages/openapi-schema-validator/CHANGELOG.md index f0abdcbf..601fff2f 100644 --- a/packages/openapi-schema-validator/CHANGELOG.md +++ b/packages/openapi-schema-validator/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 3.0.3 - 2019-01-31 +### Fixed +- Add openapi-3.1.json and update logic to use it(#837) + ### Fixed - openapi-types: OpenAPIV3: relax security requirement object types (#327) diff --git a/packages/openapi-schema-validator/index.ts b/packages/openapi-schema-validator/index.ts index 65fbe817..9285c91c 100644 --- a/packages/openapi-schema-validator/index.ts +++ b/packages/openapi-schema-validator/index.ts @@ -2,6 +2,7 @@ import ajv, { ValidateFunction, ErrorObject } from 'ajv'; import addFormats from 'ajv-formats'; const openapi2Schema = require('./resources/openapi-2.0.json'); const openapi3Schema = require('./resources/openapi-3.0.json'); +const openapi31Schema = require('./resources/openapi-3.1.json'); const merge = require('lodash.merge'); import { IJsonSchema, OpenAPI } from 'openapi-types'; @@ -27,10 +28,17 @@ export default class OpenAPISchemaValidator implements IOpenAPISchemaValidator { constructor(args: OpenAPISchemaValidatorArgs) { const v = new ajv({ allErrors: true, strict: false }); addFormats(v); - const version = (args && parseInt(String(args.version), 10)) || 2; + let openApiSchema; + switch (args.version) { + case '3.1': + openApiSchema = openapi31Schema + break; + default: + openApiSchema = (args && parseInt(String(args.version), 10)) || 2 === 2? openapi2Schema : openapi3Schema; + } const schema = merge( {}, - version === 2 ? openapi2Schema : openapi3Schema, + openApiSchema, args ? args.extensions : {} ); v.addSchema(schema); diff --git a/packages/openapi-schema-validator/resources/openapi-3.1.json b/packages/openapi-schema-validator/resources/openapi-3.1.json new file mode 100644 index 00000000..5486dc82 --- /dev/null +++ b/packages/openapi-schema-validator/resources/openapi-3.1.json @@ -0,0 +1,23 @@ +{ + "$id": "https://spec.openapis.org/oas/3.1/schema-base/2022-10-07", + "$schema": "https://json-schema.org/draft/2020-12/schema", + + "description": "The description of OpenAPI v3.1.x documents using the OpenAPI JSON Schema dialect, as defined by https://spec.openapis.org/oas/v3.1.0", + + "$ref": "https://spec.openapis.org/oas/3.1/schema/2022-10-07", + "properties": { + "jsonSchemaDialect": { "$ref": "#/$defs/dialect" } + }, + + "$defs": { + "dialect": { "const": "https://spec.openapis.org/oas/3.1/dialect/base" }, + + "schema": { + "$dynamicAnchor": "meta", + "$ref": "https://spec.openapis.org/oas/3.1/dialect/base", + "properties": { + "$schema": { "$ref": "#/$defs/dialect" } + } + } + } +} \ No newline at end of file