diff --git a/package.json b/package.json index 541195bb..c98bdbb8 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "nunjucks": "^3.2.3", "openapi3-ts": "^2.0.2", "ora": "^5.4.1", + "redoc": "2.0.0-rc.76", "reflect-metadata": "^0.1.13", "tslib": "^2.3.0", "tslog": "^3.3.3", diff --git a/packages/build/src/containers/container.ts b/packages/build/src/containers/container.ts index 9af5ca38..4af9d805 100644 --- a/packages/build/src/containers/container.ts +++ b/packages/build/src/containers/container.ts @@ -26,9 +26,7 @@ export class Container { schemaParserModule(options['schema-parser']) ); await this.inversifyContainer.loadAsync(extensionModule(options)); - await this.inversifyContainer.loadAsync( - documentGeneratorModule(options['document-generator']) - ); + await this.inversifyContainer.loadAsync(documentGeneratorModule()); } public async unload() { diff --git a/packages/build/src/containers/modules/documentGenerator.ts b/packages/build/src/containers/modules/documentGenerator.ts index b92141d2..af8052b3 100644 --- a/packages/build/src/containers/modules/documentGenerator.ts +++ b/packages/build/src/containers/modules/documentGenerator.ts @@ -1,22 +1,10 @@ -import { - IDocumentGeneratorOptions, - SpecGenerator, -} from '@vulcan-sql/build/models'; +import { SpecGenerator } from '@vulcan-sql/build/models'; import { AsyncContainerModule, interfaces } from 'inversify'; import { DocumentGenerator } from '../../lib/document-generator'; -import { DocumentGeneratorOptions } from '../../options/documentGenerator'; import { TYPES } from '../types'; -export const documentGeneratorModule = (options?: IDocumentGeneratorOptions) => +export const documentGeneratorModule = () => new AsyncContainerModule(async (bind) => { - // Options - bind( - TYPES.DocumentGeneratorInputOptions - ).toConstantValue(options || ({} as any)); - bind(TYPES.DocumentGeneratorOptions) - .to(DocumentGeneratorOptions) - .inSingletonScope(); - // Document generator bind(TYPES.DocumentGenerator).to(DocumentGenerator); bind>( diff --git a/packages/build/src/containers/types.ts b/packages/build/src/containers/types.ts index 28d18200..a9ea01f3 100644 --- a/packages/build/src/containers/types.ts +++ b/packages/build/src/containers/types.ts @@ -8,8 +8,6 @@ export const TYPES = { SchemaParserMiddleware: Symbol.for('SchemaParserMiddleware'), // Document DocumentGenerator: Symbol.for('DocumentGenerator'), - DocumentGeneratorInputOptions: Symbol.for('DocumentGeneratorInputOptions'), - DocumentGeneratorOptions: Symbol.for('DocumentGeneratorOptions'), Factory_SpecGenerator: Symbol.for('Factory_SpecGenerator'), // Extension Extension_SchemaReader: Symbol.for('Extension_SchemaReader'), diff --git a/packages/build/src/lib/document-generator/documentGenerator.ts b/packages/build/src/lib/document-generator/documentGenerator.ts index 6cdfb616..75e8c9b3 100644 --- a/packages/build/src/lib/document-generator/documentGenerator.ts +++ b/packages/build/src/lib/document-generator/documentGenerator.ts @@ -1,8 +1,11 @@ -import { APISchema } from '@vulcan-sql/core'; +import { + APISchema, + DocumentOptions, + TYPES as CORE_TYPES, +} from '@vulcan-sql/core'; import { inject, injectable, interfaces } from 'inversify'; import { TYPES } from '../../containers/types'; import { SpecGenerator } from '../../models/extensions'; -import { DocumentGeneratorOptions } from '../../options/documentGenerator'; import * as jsYAML from 'js-yaml'; import * as path from 'path'; import { promises as fs } from 'fs'; @@ -15,7 +18,7 @@ export class DocumentGenerator { constructor( @inject(TYPES.Factory_SpecGenerator) specGeneratorFactory: interfaces.AutoNamedFactory, - @inject(TYPES.DocumentGeneratorOptions) options: DocumentGeneratorOptions + @inject(CORE_TYPES.DocumentOptions) options: DocumentOptions ) { this.specGenerators = []; for (const spec of options.specs) { diff --git a/packages/build/src/lib/document-generator/spec-generator/oas3/oas3SpecGenerator.ts b/packages/build/src/lib/document-generator/spec-generator/oas3/oas3SpecGenerator.ts index 8262c4bd..e6185156 100644 --- a/packages/build/src/lib/document-generator/spec-generator/oas3/oas3SpecGenerator.ts +++ b/packages/build/src/lib/document-generator/spec-generator/oas3/oas3SpecGenerator.ts @@ -16,12 +16,12 @@ import { ResponseProperty, VulcanExtensionId, VulcanInternalExtension, + DocumentSpec, } from '@vulcan-sql/core'; import { isEmpty } from 'lodash'; -import { DocumentGeneratorSpec } from '@vulcan-sql/build/models'; @VulcanInternalExtension() -@VulcanExtensionId(DocumentGeneratorSpec.oas3) +@VulcanExtensionId(DocumentSpec.oas3) export class OAS3SpecGenerator extends SpecGenerator { // Follow the OpenAPI specification version 3.0.3 // see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md diff --git a/packages/build/src/models/buildOptions.ts b/packages/build/src/models/buildOptions.ts index e32b2ffa..588b372b 100644 --- a/packages/build/src/models/buildOptions.ts +++ b/packages/build/src/models/buildOptions.ts @@ -1,8 +1,6 @@ import { ICoreOptions } from '@vulcan-sql/core'; -import { IDocumentGeneratorOptions } from './documentGeneratorOptions'; import { ISchemaParserOptions } from './schemaParserOptions'; export interface IBuildOptions extends ICoreOptions { 'schema-parser'?: ISchemaParserOptions; - 'document-generator'?: IDocumentGeneratorOptions; } diff --git a/packages/build/src/models/documentGeneratorOptions.ts b/packages/build/src/models/documentGeneratorOptions.ts deleted file mode 100644 index 976301e6..00000000 --- a/packages/build/src/models/documentGeneratorOptions.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum DocumentGeneratorSpec { - oas3 = 'oas3', -} - -export interface IDocumentGeneratorOptions { - /** Target specification of our APIs, e.g. OpenAPI, Tinyspec ...etc. */ - specs?: (string | DocumentGeneratorSpec)[]; - folderPath: string; -} diff --git a/packages/build/src/models/index.ts b/packages/build/src/models/index.ts index 92f21b7c..b9b5db6a 100644 --- a/packages/build/src/models/index.ts +++ b/packages/build/src/models/index.ts @@ -1,4 +1,3 @@ export * from './buildOptions'; export * from './schemaParserOptions'; export * from './extensions'; -export * from './documentGeneratorOptions'; diff --git a/packages/build/src/options/documentGenerator.ts b/packages/build/src/options/documentGenerator.ts deleted file mode 100644 index 8e633456..00000000 --- a/packages/build/src/options/documentGenerator.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { injectable, inject, optional } from 'inversify'; -import { TYPES } from '@vulcan-sql/build/containers'; -import { IDocumentGeneratorOptions } from '@vulcan-sql/build/models'; -import { IsOptional, IsArray, validateSync, IsString } from 'class-validator'; - -@injectable() -export class DocumentGeneratorOptions implements IDocumentGeneratorOptions { - @IsArray() - @IsOptional() - public readonly specs = ['oas3']; - - @IsString() - public readonly folderPath!: string; - - constructor( - @inject(TYPES.DocumentGeneratorInputOptions) - @optional() - options: Partial = {} - ) { - Object.assign(this, options); - const errors = validateSync(this); - if (errors.length > 0) { - throw new Error( - 'Invalid document generator options: ' + errors.join(', ') - ); - } - } -} diff --git a/packages/build/src/options/index.ts b/packages/build/src/options/index.ts index c4127ed3..1084ca58 100644 --- a/packages/build/src/options/index.ts +++ b/packages/build/src/options/index.ts @@ -1,2 +1 @@ export * from './schemaParser'; -export * from './documentGenerator'; diff --git a/packages/build/test/builder/builder.spec.ts b/packages/build/test/builder/builder.spec.ts index d264e608..0b05df1f 100644 --- a/packages/build/test/builder/builder.spec.ts +++ b/packages/build/test/builder/builder.spec.ts @@ -1,13 +1,10 @@ import { VulcanBuilder } from '../../src'; import * as path from 'path'; -import { - DocumentGeneratorSpec, - IBuildOptions, - SchemaReaderType, -} from '@vulcan-sql/build/models'; +import { IBuildOptions, SchemaReaderType } from '@vulcan-sql/build/models'; import { ArtifactBuilderProviderType, ArtifactBuilderSerializerType, + DocumentSpec, TemplateProviderType, } from '@vulcan-sql/core'; @@ -18,8 +15,8 @@ it('Builder.build should work', async () => { reader: SchemaReaderType.LocalFile, folderPath: path.resolve(__dirname, 'source'), }, - 'document-generator': { - specs: [DocumentGeneratorSpec.oas3], + document: { + specs: [DocumentSpec.oas3], folderPath: path.resolve(__dirname), }, artifact: { diff --git a/packages/build/test/document-generator/document-generator.spec.ts b/packages/build/test/document-generator/document-generator.spec.ts index 92f20d9f..195dbd2a 100644 --- a/packages/build/test/document-generator/document-generator.spec.ts +++ b/packages/build/test/document-generator/document-generator.spec.ts @@ -18,6 +18,7 @@ it('Document generator should write YAML files while generating documents', asyn { specs: ['spec1', 'spec2'], folderPath: __dirname, + router: [], } ); diff --git a/packages/core/src/containers/container.ts b/packages/core/src/containers/container.ts index b488aeca..461e646a 100644 --- a/packages/core/src/containers/container.ts +++ b/packages/core/src/containers/container.ts @@ -1,7 +1,7 @@ import { ICoreOptions } from '@vulcan-sql/core/models'; import { Container as InversifyContainer } from 'inversify'; import { ProjectOptions } from '../options'; -import { extensionModule } from './modules'; +import { documentModule, extensionModule } from './modules'; import { artifactBuilderModule, executorModule, @@ -33,6 +33,7 @@ export class Container { ); await this.inversifyContainer.loadAsync(validatorLoaderModule()); await this.inversifyContainer.loadAsync(extensionModule(options)); + await this.inversifyContainer.loadAsync(documentModule(options.document)); } public async unload() { diff --git a/packages/core/src/containers/modules/document.ts b/packages/core/src/containers/modules/document.ts new file mode 100644 index 00000000..d438bd43 --- /dev/null +++ b/packages/core/src/containers/modules/document.ts @@ -0,0 +1,11 @@ +import { AsyncContainerModule } from 'inversify'; +import { TYPES } from '../types'; +import { IDocumentOptions } from '../../models'; +import { DocumentOptions } from '../../options'; + +export const documentModule = (options: IDocumentOptions = {}) => + new AsyncContainerModule(async (bind) => { + // Options + bind(TYPES.DocumentInputOptions).toConstantValue(options); + bind(TYPES.DocumentOptions).to(DocumentOptions); + }); diff --git a/packages/core/src/containers/modules/index.ts b/packages/core/src/containers/modules/index.ts index 0d81815b..fee7461b 100644 --- a/packages/core/src/containers/modules/index.ts +++ b/packages/core/src/containers/modules/index.ts @@ -3,3 +3,4 @@ export * from './executor'; export * from './templateEngine'; export * from './validatorLoader'; export * from './extension'; +export * from './document'; diff --git a/packages/core/src/containers/types.ts b/packages/core/src/containers/types.ts index 76148881..cb972f81 100644 --- a/packages/core/src/containers/types.ts +++ b/packages/core/src/containers/types.ts @@ -30,6 +30,9 @@ export const TYPES = { Factory_DataSource: Symbol.for('Factory_DataSource'), // Validator ValidatorLoader: Symbol.for('ValidatorLoader'), + // Document + DocumentInputOptions: Symbol.for('DocumentInputOptions'), + DocumentOptions: Symbol.for('DocumentOptions'), // Extensions ExtensionConfig: Symbol.for('ExtensionConfig'), ExtensionName: Symbol.for('ExtensionName'), diff --git a/packages/core/src/models/coreOptions.ts b/packages/core/src/models/coreOptions.ts index ebc7eb25..3ce76995 100644 --- a/packages/core/src/models/coreOptions.ts +++ b/packages/core/src/models/coreOptions.ts @@ -1,4 +1,5 @@ import { IArtifactBuilderOptions } from './artifactBuilderOptions'; +import { IDocumentOptions } from './documentOptions'; import { IExecutorOptions } from './executorOptions'; import { ITemplateEngineOptions } from './templateEngineOptions'; @@ -21,5 +22,6 @@ export interface ICoreOptions { template?: ITemplateEngineOptions; executor?: IExecutorOptions; extensions?: ExtensionAliases; + document?: IDocumentOptions; [moduleAlias: string]: any; } diff --git a/packages/core/src/models/documentOptions.ts b/packages/core/src/models/documentOptions.ts new file mode 100644 index 00000000..bc615407 --- /dev/null +++ b/packages/core/src/models/documentOptions.ts @@ -0,0 +1,14 @@ +export enum DocumentSpec { + oas3 = 'oas3', +} + +export enum DocumentRouterType { + redoc = 'redoc', +} + +export interface IDocumentOptions { + /** Target specification of our APIs, e.g. OpenAPI, Tinyspec ...etc. */ + specs?: (string | DocumentSpec)[]; + folderPath?: string; + router?: (string | DocumentRouterType)[]; +} diff --git a/packages/core/src/models/index.ts b/packages/core/src/models/index.ts index 23ca9008..71211818 100644 --- a/packages/core/src/models/index.ts +++ b/packages/core/src/models/index.ts @@ -5,3 +5,4 @@ export * from './coreOptions'; export * from './templateEngineOptions'; export * from './extensions'; export * from './executorOptions'; +export * from './documentOptions'; diff --git a/packages/core/src/options/document.ts b/packages/core/src/options/document.ts new file mode 100644 index 00000000..b5ad679e --- /dev/null +++ b/packages/core/src/options/document.ts @@ -0,0 +1,31 @@ +import { injectable, inject, optional } from 'inversify'; +import { IsOptional, IsArray, validateSync, IsString } from 'class-validator'; +import { DocumentRouterType, DocumentSpec, IDocumentOptions } from '../models'; +import { TYPES } from '@vulcan-sql/core/types'; + +@injectable() +export class DocumentOptions implements IDocumentOptions { + @IsArray() + @IsOptional() + public readonly specs: string[] = [DocumentSpec.oas3]; + + @IsString() + public readonly folderPath: string = '.'; + + @IsArray() + public readonly router: string[] = [DocumentRouterType.redoc]; + + constructor( + @inject(TYPES.DocumentInputOptions) + @optional() + options: Partial = {} + ) { + Object.assign(this, options); + const errors = validateSync(this); + if (errors.length > 0) { + throw new Error( + 'Invalid document generator options: ' + errors.join(', ') + ); + } + } +} diff --git a/packages/core/src/options/index.ts b/packages/core/src/options/index.ts index 4efbece9..bd28f079 100644 --- a/packages/core/src/options/index.ts +++ b/packages/core/src/options/index.ts @@ -2,3 +2,4 @@ export * from './artifactBuilder'; export * from './templateEngine'; export * from './project'; export * from './executor'; +export * from './document'; diff --git a/packages/core/test/options/documentOptions.spec.ts b/packages/core/test/options/documentOptions.spec.ts new file mode 100644 index 00000000..6e145f99 --- /dev/null +++ b/packages/core/test/options/documentOptions.spec.ts @@ -0,0 +1,47 @@ +import { + DocumentRouterType, + DocumentSpec, + IDocumentOptions, + TYPES, +} from '../../src'; +import { Container } from 'inversify'; +import { DocumentOptions } from '../../src/options'; + +let container: Container; + +beforeEach(() => { + container = new Container(); + container.bind(TYPES.DocumentOptions).to(DocumentOptions).inSingletonScope(); +}); + +it('Should provide correct default option values', async () => { + // Action + const options = container.get(TYPES.DocumentOptions); + // Assert + expect(options.folderPath).toBe('.'); + expect(options.specs).toEqual([DocumentSpec.oas3]); + expect(options.router).toEqual([DocumentRouterType.redoc]); +}); + +it('Can override some option properties', async () => { + // Arrange + container + .bind>(TYPES.DocumentInputOptions) + .toConstantValue({ + folderPath: './some/folder', + }); + const options = container.get(TYPES.DocumentOptions); + // Assert + expect(options.folderPath).toBe('./some/folder'); + expect(options.specs).toEqual([DocumentSpec.oas3]); + expect(options.router).toEqual([DocumentRouterType.redoc]); +}); + +it('Schema validation should work', async () => { + // Arrange + container.bind(TYPES.DocumentInputOptions).toConstantValue({ + folderPath: true, + }); + // Act. Assert + expect(() => container.get(TYPES.DocumentOptions)).toThrow(); +}); diff --git a/packages/integration-testing/src/example1/buildAndServe.spec.ts b/packages/integration-testing/src/example1/buildAndServe.spec.ts index 47b9d5c0..6716cd1d 100644 --- a/packages/integration-testing/src/example1/buildAndServe.spec.ts +++ b/packages/integration-testing/src/example1/buildAndServe.spec.ts @@ -2,16 +2,17 @@ import { VulcanBuilder, IBuildOptions, SchemaReaderType, - DocumentGeneratorSpec, } from '@vulcan-sql/build'; import { ArtifactBuilderProviderType, ArtifactBuilderSerializerType, TemplateProviderType, + DocumentSpec, } from '@vulcan-sql/core'; import { VulcanServer, ServeConfig, APIProviderType } from '@vulcan-sql/serve'; import * as path from 'path'; import * as supertest from 'supertest'; +import faker from '@faker-js/faker'; const projectConfig: ServeConfig & IBuildOptions = { name: 'example project 1', @@ -30,8 +31,8 @@ const projectConfig: ServeConfig & IBuildOptions = { reader: SchemaReaderType.LocalFile, folderPath: path.resolve(__dirname, 'sqls'), }, - 'document-generator': { - specs: [DocumentGeneratorSpec.oas3], + document: { + specs: [DocumentSpec.oas3], folderPath: __dirname, }, types: [APIProviderType.RESTFUL], @@ -47,6 +48,7 @@ const projectConfig: ServeConfig & IBuildOptions = { 'enforce-https': { enabled: false, }, + port: faker.datatype.number({ min: 20000, max: 30000 }), }; let server: VulcanServer; @@ -63,7 +65,7 @@ it('Example1: Build and serve should work', async () => { const agent = supertest(httpServer); const result = await agent.get( - '/user?id=436193eb-f686-4105-ad7b-b5945276c14a' + '/api/user/436193eb-f686-4105-ad7b-b5945276c14a' ); expect(result.body).toContainEqual({ id: '436193eb-f686-4105-ad7b-b5945276c14a', diff --git a/packages/integration-testing/src/example1/sqls/user.yaml b/packages/integration-testing/src/example1/sqls/user.yaml index 16490c9e..ba605469 100644 --- a/packages/integration-testing/src/example1/sqls/user.yaml +++ b/packages/integration-testing/src/example1/sqls/user.yaml @@ -1,7 +1,7 @@ -url: /user +urlPath: /user/:id request: - fieldName: id - fieldIn: query + fieldIn: path description: user id validators: - uuid diff --git a/packages/serve/project.json b/packages/serve/project.json index f0985a1d..532dcaa9 100644 --- a/packages/serve/project.json +++ b/packages/serve/project.json @@ -28,7 +28,10 @@ "outputPath": "dist/packages/serve", "main": "packages/serve/src/index.ts", "tsConfig": "packages/serve/tsconfig.lib.json", - "assets": ["packages/serve/*.md"], + "assets": [ + "packages/serve/*.md", + "packages/serve/src/lib/document-router/redoc-document-router/template/*.*" + ], "buildableProjectDepsInPackageJsonType": "dependencies" }, "dependsOn": [ diff --git a/packages/serve/src/containers/container.ts b/packages/serve/src/containers/container.ts index 1dc09829..a9612f5a 100644 --- a/packages/serve/src/containers/container.ts +++ b/packages/serve/src/containers/container.ts @@ -2,6 +2,7 @@ import { Container as InversifyContainer } from 'inversify'; import { Container as CoreContainer } from '@vulcan-sql/core'; import { applicationModule, + documentRouterModule, extensionModule, routeGeneratorModule, } from './modules'; @@ -25,6 +26,7 @@ export class Container { this.inversifyContainer.load(routeGeneratorModule()); await this.inversifyContainer.loadAsync(extensionModule(config)); await this.inversifyContainer.loadAsync(applicationModule()); + await this.inversifyContainer.loadAsync(documentRouterModule()); } public async unload() { diff --git a/packages/serve/src/containers/modules/documentRouter.ts b/packages/serve/src/containers/modules/documentRouter.ts new file mode 100644 index 00000000..fa4aad3f --- /dev/null +++ b/packages/serve/src/containers/modules/documentRouter.ts @@ -0,0 +1,10 @@ +import { TYPES } from '@vulcan-sql/serve/containers'; +import { DocumentRouter } from '@vulcan-sql/serve/models'; +import { AsyncContainerModule, interfaces } from 'inversify'; + +export const documentRouterModule = () => + new AsyncContainerModule(async (bind) => { + bind>( + TYPES.Factory_DocumentRouter + ).toAutoNamedFactory(TYPES.Extension_DocumentRouter); + }); diff --git a/packages/serve/src/containers/modules/extension.ts b/packages/serve/src/containers/modules/extension.ts index 6156336a..c1382f98 100644 --- a/packages/serve/src/containers/modules/extension.ts +++ b/packages/serve/src/containers/modules/extension.ts @@ -4,6 +4,7 @@ import { ServeConfig } from '../../models/serveOptions'; import { BuiltInRouteMiddlewares } from '@vulcan-sql/serve/middleware'; import { BuiltInFormatters } from '@vulcan-sql/serve/response-formatter'; import { BuiltInAuthenticators } from '../../lib/auth'; +import { BuiltInDocumentRouters } from '../../lib/document-router'; export const extensionModule = (options: ServeConfig) => new AsyncContainerModule(async (bind) => { @@ -16,6 +17,8 @@ export const extensionModule = (options: ServeConfig) => loader.loadInternalExtensionModule(BuiltInFormatters); // authenticator (single module) loader.loadInternalExtensionModule(BuiltInAuthenticators); + // document router (single module) + loader.loadInternalExtensionModule(BuiltInDocumentRouters); loader.bindExtensions(bind); }); diff --git a/packages/serve/src/containers/modules/index.ts b/packages/serve/src/containers/modules/index.ts index 079db97d..277f46dc 100644 --- a/packages/serve/src/containers/modules/index.ts +++ b/packages/serve/src/containers/modules/index.ts @@ -1,3 +1,4 @@ export * from './routeGenerator'; export * from './extension'; export * from './application'; +export * from './documentRouter'; diff --git a/packages/serve/src/containers/types.ts b/packages/serve/src/containers/types.ts index b727e337..f6ae6c7a 100644 --- a/packages/serve/src/containers/types.ts +++ b/packages/serve/src/containers/types.ts @@ -8,8 +8,11 @@ export const TYPES = { // Application VulcanApplication: Symbol.for('VulcanApplication'), + // Document router + Factory_DocumentRouter: Symbol.for('Factory_DocumentRouter'), // Extensions Extension_RouteMiddleware: Symbol.for('Extension_RouteMiddleware'), Extension_Authenticator: Symbol.for('Extension_Authenticator'), Extension_Formatter: Symbol.for('Extension_Formatter'), + Extension_DocumentRouter: Symbol.for('Extension_DocumentRouter'), }; diff --git a/packages/serve/src/lib/document-router/index.ts b/packages/serve/src/lib/document-router/index.ts new file mode 100644 index 00000000..0acafffd --- /dev/null +++ b/packages/serve/src/lib/document-router/index.ts @@ -0,0 +1,5 @@ +export * from './redoc-document-router'; + +import { RedocDocumentRouters } from './redoc-document-router'; + +export const BuiltInDocumentRouters = [RedocDocumentRouters]; diff --git a/packages/serve/src/lib/document-router/redoc-document-router/index.ts b/packages/serve/src/lib/document-router/redoc-document-router/index.ts new file mode 100644 index 00000000..9bdf6327 --- /dev/null +++ b/packages/serve/src/lib/document-router/redoc-document-router/index.ts @@ -0,0 +1 @@ +export * from './redocDocumentRouters'; diff --git a/packages/serve/src/lib/document-router/redoc-document-router/redocDocumentRouters.ts b/packages/serve/src/lib/document-router/redoc-document-router/redocDocumentRouters.ts new file mode 100644 index 00000000..1162ab02 --- /dev/null +++ b/packages/serve/src/lib/document-router/redoc-document-router/redocDocumentRouters.ts @@ -0,0 +1,86 @@ +import { + DocumentOptions, + DocumentRouterType, + DocumentSpec, + ProjectOptions, + TYPES as CORE_TYPES, + VulcanExtensionId, + VulcanInternalExtension, +} from '@vulcan-sql/core'; +import * as nunjucks from 'nunjucks'; +import { Next } from 'koa'; +import * as Router from 'koa-router'; +import { DocumentRouter } from '@vulcan-sql/serve/models'; +import * as fs from 'fs'; +import * as path from 'path'; +import { inject } from 'inversify'; + +@VulcanInternalExtension('redoc') +@VulcanExtensionId(DocumentRouterType.redoc) +export class RedocDocumentRouters extends DocumentRouter { + private router = new Router(); + private docContent = ''; + private projectOption: ProjectOptions; + // remove leading, trailing slashes + private urlPrefix = + this.getConfig()?.url?.replace(/\/+$/, '').replace(/^\/+/, '') || 'doc'; + + constructor( + @inject(CORE_TYPES.ExtensionConfig) config: any, + @inject(CORE_TYPES.ExtensionName) moduleName: string, + @inject(CORE_TYPES.DocumentOptions) documentOptions: DocumentOptions, + @inject(CORE_TYPES.ProjectOptions) projectOption: ProjectOptions + ) { + super(config, moduleName, documentOptions); + this.projectOption = projectOption; + } + + public override async onActivate() { + // Set routes + // html index + this.router.get(`/${this.urlPrefix}`, async (ctx, next) => { + await next(); + ctx.response.body = this.docContent; + }); + // spec file + // TODO: it should be spec.yaml but extension will be removed by response-format/middleware, wait for fixing + const specUrl = `/${this.urlPrefix}/spec`; + this.router.get(specUrl, async (ctx, next) => { + await next(); + ctx.response.body = await this.getSpec(DocumentSpec.oas3); + }); + // redoc js file + // redoc's package.json point to bundles/redoc.lib.js file which we can't use directly + // we should use the file redoc.standalone.js at the same folder instead. + const redocPath = path.resolve( + require.resolve('redoc'), + '..', + 'redoc.standalone.js' + ); + // TODO: it should be redoc.js but extension will be removed by response-format/middleware, wait for fixing + const bundleFileUrl = `/${this.urlPrefix}/redoc`; + this.router.get(bundleFileUrl, async (ctx, next) => { + await next(); + ctx.response.body = fs.createReadStream(redocPath); + ctx.set('Content-Type', 'application/javascript'); + }); + + // Load template and render it + const template = await fs.promises.readFile( + path.resolve(__dirname, 'template', 'redoc.html'), + 'utf-8' + ); + this.docContent = nunjucks.renderString(template, { + title: `${this.projectOption.name} - Vulcan`, + specUrl, + bundleFileUrl, + }); + } + + public async handle( + context: Router.RouterContext, + next: Next + ): Promise { + await this.router.routes()(context, next); + } +} diff --git a/packages/serve/src/lib/document-router/redoc-document-router/template/redoc.html b/packages/serve/src/lib/document-router/redoc-document-router/template/redoc.html new file mode 100644 index 00000000..7505832e --- /dev/null +++ b/packages/serve/src/lib/document-router/redoc-document-router/template/redoc.html @@ -0,0 +1,28 @@ + + + + {{ title }} + + + + + + + + + + + + + diff --git a/packages/serve/src/lib/middleware/docRouterMiddleware.ts b/packages/serve/src/lib/middleware/docRouterMiddleware.ts new file mode 100644 index 00000000..824dc8ce --- /dev/null +++ b/packages/serve/src/lib/middleware/docRouterMiddleware.ts @@ -0,0 +1,43 @@ +import { + BuiltInMiddleware, + DocumentRouter, + KoaContext, + Next, +} from '@vulcan-sql/serve/models'; +import { + VulcanInternalExtension, + TYPES as CORE_TYPES, + DocumentOptions, +} from '@vulcan-sql/core'; +import { inject, interfaces } from 'inversify'; +import { TYPES } from '@vulcan-sql/serve/containers'; +import * as compose from 'koa-compose'; + +@VulcanInternalExtension() +export class DocRouterMiddleware extends BuiltInMiddleware { + private servers: DocumentRouter[] = []; + + constructor( + @inject(CORE_TYPES.ExtensionConfig) config: any, + @inject(CORE_TYPES.ExtensionName) name: string, + @inject(TYPES.Factory_DocumentRouter) + documentRouterFactory: interfaces.AutoNamedFactory, + @inject(CORE_TYPES.DocumentOptions) options: DocumentOptions + ) { + super(config, name); + for (const serverType of options.router) { + this.servers.push(documentRouterFactory(serverType)); + } + } + + public override async onActivate(): Promise { + for (const serve of this.servers) await serve.activate(); + } + + public async handle(context: KoaContext, next: Next) { + const execute = compose( + this.servers.map((server) => server.handle.bind(server)) + ); + await execute(context, next); + } +} diff --git a/packages/serve/src/lib/middleware/index.ts b/packages/serve/src/lib/middleware/index.ts index affd294e..8d64186c 100644 --- a/packages/serve/src/lib/middleware/index.ts +++ b/packages/serve/src/lib/middleware/index.ts @@ -5,6 +5,7 @@ export * from './rateLimitMiddleware'; export * from './authMiddleware'; export * from './response-format'; export * from './enforceHttpsMiddleware'; +export * from './docRouterMiddleware'; import { CorsMiddleware } from './corsMiddleware'; import { AuthMiddleware } from './authMiddleware'; @@ -14,6 +15,7 @@ import { AuditLoggingMiddleware } from './auditLogMiddleware'; import { ResponseFormatMiddleware } from './response-format'; import { EnforceHttpsMiddleware } from './enforceHttpsMiddleware'; import { ClassType, ExtensionBase } from '@vulcan-sql/core'; +import { DocRouterMiddleware } from './docRouterMiddleware'; // The order is the middleware running order export const BuiltInRouteMiddlewares: ClassType[] = [ @@ -24,4 +26,5 @@ export const BuiltInRouteMiddlewares: ClassType[] = [ RateLimitMiddleware, AuthMiddleware, ResponseFormatMiddleware, + DocRouterMiddleware, ]; diff --git a/packages/serve/src/lib/route/route-component/restfulRoute.ts b/packages/serve/src/lib/route/route-component/restfulRoute.ts index ea94b7c8..b326efd6 100644 --- a/packages/serve/src/lib/route/route-component/restfulRoute.ts +++ b/packages/serve/src/lib/route/route-component/restfulRoute.ts @@ -6,7 +6,7 @@ export class RestfulRoute extends BaseRoute { constructor(options: RouteOptions) { super(options); const { apiSchema } = options; - this.urlPath = apiSchema.urlPath; + this.urlPath = this.combineURLs('/api', apiSchema.urlPath); } public async respond(ctx: KoaContext) { @@ -34,4 +34,8 @@ export class RestfulRoute extends BaseRoute { pagination, }; } + + private combineURLs(baseURL: string, relativeURL = ''): string { + return baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, ''); + } } diff --git a/packages/serve/src/models/extensions/documentRouter.ts b/packages/serve/src/models/extensions/documentRouter.ts new file mode 100644 index 00000000..5730ce86 --- /dev/null +++ b/packages/serve/src/models/extensions/documentRouter.ts @@ -0,0 +1,37 @@ +import { + DocumentOptions, + DocumentSpec, + ExtensionBase, + VulcanExtension, +} from '@vulcan-sql/core'; +import { TYPES } from '@vulcan-sql/serve/types'; +import { KoaContext, Next } from '@vulcan-sql/serve/models'; +import { TYPES as CORE_TYPES } from '@vulcan-sql/core'; +import { inject } from 'inversify'; +import * as fs from 'fs'; +import * as path from 'path'; + +@VulcanExtension(TYPES.Extension_DocumentRouter) +export abstract class DocumentRouter extends ExtensionBase { + private documentOptions: DocumentOptions; + + constructor( + @inject(CORE_TYPES.ExtensionConfig) config: any, + @inject(CORE_TYPES.ExtensionName) moduleName: string, + @inject(CORE_TYPES.DocumentOptions) documentOptions: DocumentOptions + ) { + super(config, moduleName); + this.documentOptions = documentOptions; + } + + public abstract handle(context: KoaContext, next: Next): Promise; + + protected async getSpec(type: string = DocumentSpec.oas3) { + const filePath = path.resolve( + this.documentOptions.folderPath, + `spec-${type}.yaml` + ); + if (!fs.existsSync(filePath)) throw new Error(`File ${filePath} not found`); + return fs.createReadStream(filePath); + } +} diff --git a/packages/serve/src/models/extensions/index.ts b/packages/serve/src/models/extensions/index.ts index 1ebacdf1..88bea15d 100644 --- a/packages/serve/src/models/extensions/index.ts +++ b/packages/serve/src/models/extensions/index.ts @@ -1,3 +1,4 @@ export * from './routeMiddleware'; export * from './responseFormatter'; export * from './authenticator'; +export * from './documentRouter'; diff --git a/packages/serve/src/models/extensions/responseFormatter.ts b/packages/serve/src/models/extensions/responseFormatter.ts index 72a0d672..a635d36c 100644 --- a/packages/serve/src/models/extensions/responseFormatter.ts +++ b/packages/serve/src/models/extensions/responseFormatter.ts @@ -30,11 +30,8 @@ export abstract class BaseResponseFormatter implements IFormatter { public formatToResponse(ctx: KoaContext) { - // return empty csv stream data or column is not exist + // keep response body the same if it is not provided by template engine, e.g. document router content ...etc. if (!has(ctx.response.body, 'data') || !has(ctx.response.body, 'columns')) { - const stream = new Stream.Readable(); - stream.push(null); - this.toResponse(stream, ctx); return; } // if response has data and columns. diff --git a/packages/serve/test/app.spec.ts b/packages/serve/test/app.spec.ts index 71b7a067..bb8d824f 100644 --- a/packages/serve/test/app.spec.ts +++ b/packages/serve/test/app.spec.ts @@ -16,6 +16,7 @@ import { extensionModule as coreExtensionModule, TYPES as CORE_TYPES, DataSource, + DocumentOptions, } from '@vulcan-sql/core'; import { RouteGenerator, @@ -66,6 +67,13 @@ describe('Test vulcan server for practicing middleware', () => { .toConstantValue(stubTemplateEngine); container.bind(TYPES.RouteGenerator).to(RouteGenerator); container.bind(TYPES.VulcanApplication).to(VulcanApplication); + container.bind(TYPES.Factory_DocumentRouter).toConstantValue(() => null); + container.bind(CORE_TYPES.DocumentOptions).toDynamicValue( + () => + new DocumentOptions({ + router: [], + }) + ); }); afterEach(() => { @@ -293,6 +301,13 @@ describe('Test vulcan server for calling restful APIs', () => { .toConstantValue(stubTemplateEngine); container.bind(TYPES.RouteGenerator).to(RouteGenerator); container.bind(TYPES.VulcanApplication).to(VulcanApplication); + container.bind(TYPES.Factory_DocumentRouter).toConstantValue(() => null); + container.bind(CORE_TYPES.DocumentOptions).toDynamicValue( + () => + new DocumentOptions({ + router: [], + }) + ); }); afterEach(() => { @@ -318,7 +333,7 @@ describe('Test vulcan server for calling restful APIs', () => { .listen(faker.datatype.number({ min: 20000, max: 30000 })); // arrange input api url - const apiUrl = KoaRouter.url(schema.urlPath, ctx.params); + const apiUrl = KoaRouter.url('/api' + schema.urlPath, ctx.params); // arrange expected result const expected: RequestParameters = {}; diff --git a/packages/serve/test/document-router/redocDocumentRouter.spec.ts b/packages/serve/test/document-router/redocDocumentRouter.spec.ts new file mode 100644 index 00000000..00316b11 --- /dev/null +++ b/packages/serve/test/document-router/redocDocumentRouter.spec.ts @@ -0,0 +1,72 @@ +import { DocumentOptions, ProjectOptions } from '@vulcan-sql/core'; +import { RedocDocumentRouters } from '../../src/lib/document-router'; +import * as Koa from 'koa'; +import * as supertest from 'supertest'; +import faker from '@faker-js/faker'; +import { Server } from 'http'; + +let http: Server; + +afterEach(() => { + http?.close(); +}); + +it('Should serve redoc server with all the required contents', async () => { + // Arrange + const server = new RedocDocumentRouters( + {}, + '', + new DocumentOptions({ + folderPath: __dirname, + }), + new ProjectOptions() + ); + await server.activate(); + const app = new Koa(); + http = app.listen(faker.datatype.number({ min: 20000, max: 30000 })); + app.use(server.handle.bind(server)); + const agent = supertest.agent(http); + + // Act + const doc = await agent.get('/doc'); + const redocBundle = await agent.get('/doc/redoc'); + const spec = await agent.get('/doc/spec'); + + // Assert + expect(doc.text.startsWith(``)).toBeTruthy(); + expect( + redocBundle.text.startsWith( + `/*! For license information please see redoc.standalone.js.LICENSE.txt */` + ) + ).toBeTruthy(); + expect(spec.body.toString()).toEqual(`name: "123"`); +}); + +it('Should follow the url path we set', async () => { + // Arrange + const server = new RedocDocumentRouters( + { + url: 'some-path-other-than-doc', + }, + '', + new DocumentOptions(), + new ProjectOptions() + ); + await server.activate(); + const app = new Koa(); + http = app.listen(faker.datatype.number({ min: 20000, max: 30000 })); + app.use(server.handle.bind(server)); + const agent = supertest.agent(http); + + // Act + const doc = await agent.get('/some-path-other-than-doc'); + const redocBundle = await agent.get('/some-path-other-than-doc/redoc'); + + // Assert + expect(doc.text.startsWith(``)).toBeTruthy(); + expect( + redocBundle.text.startsWith( + `/*! For license information please see redoc.standalone.js.LICENSE.txt */` + ) + ).toBeTruthy(); +}); diff --git a/packages/serve/test/document-router/spec-oas3.yaml b/packages/serve/test/document-router/spec-oas3.yaml new file mode 100644 index 00000000..371b4ecf --- /dev/null +++ b/packages/serve/test/document-router/spec-oas3.yaml @@ -0,0 +1 @@ +name: "123" \ No newline at end of file diff --git a/packages/serve/test/middlewares/built-in-middlewares/docServerMiddleware.spec.ts b/packages/serve/test/middlewares/built-in-middlewares/docServerMiddleware.spec.ts new file mode 100644 index 00000000..fc130422 --- /dev/null +++ b/packages/serve/test/middlewares/built-in-middlewares/docServerMiddleware.spec.ts @@ -0,0 +1,75 @@ +import { DocumentOptions } from '@vulcan-sql/core'; +import { DocRouterMiddleware, DocumentRouter } from '@vulcan-sql/serve'; +import * as compose from 'koa-compose'; +import * as sinon from 'ts-sinon'; + +describe('Test doc server middlewares', () => { + let mockDocServer: Record>>; + let mockOption: DocumentOptions; + const mockDocServerFactory = (name: string) => mockDocServer[name]; + + beforeEach(() => { + mockDocServer = { + m1: sinon.stubInterface(), + m2: sinon.stubInterface(), + m3: sinon.stubInterface(), + }; + mockOption = new DocumentOptions({ + router: ['m1', 'm2'], + }); + }); + + it('Should active corresponding document router', async () => { + // Arrange + const middleware = new DocRouterMiddleware( + {}, + '', + mockDocServerFactory, + mockOption + ); + // Act + await middleware.activate(); + // Assert + expect(mockDocServer['m1'].activate?.called).toBeTruthy(); + expect(mockDocServer['m2'].activate?.called).toBeTruthy(); + expect(mockDocServer['m3'].activate?.called).toBeFalsy(); + }); + + it('Should execute middleware with correct order', async () => { + // mid1 -> mid2(m1 -> m2) -> mid3 -> | next | -> mid3 -> mid2(m2 -> m1) -> mid1 + // 1 -> 2 -> 3 -> 4 -> -> 5 -> 6 -> 7 -> 8 + // Arrange + const executeOrder: number[] = []; + const mid1 = async (context: any, next: any) => { + executeOrder.push(1); + await next(); + executeOrder.push(8); + }; + mockDocServer['m1'].handle.callsFake(async (context, next) => { + executeOrder.push(2); + await next(); + executeOrder.push(7); + }); + mockDocServer['m2'].handle.callsFake(async (context, next) => { + executeOrder.push(3); + await next(); + executeOrder.push(6); + }); + const mid2 = new DocRouterMiddleware( + {}, + '', + mockDocServerFactory, + mockOption + ); + const mid3 = async (context: any, next: any) => { + executeOrder.push(4); + await next(); + executeOrder.push(5); + }; + // Act + const execute = compose([mid1, mid2.handle.bind(mid2), mid3]); + await execute({}); + // Assert + expect(executeOrder).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + }); +}); diff --git a/packages/serve/test/response-formatter/csv.spec.ts b/packages/serve/test/response-formatter/csv.spec.ts index f6db20a8..4a2c3487 100644 --- a/packages/serve/test/response-formatter/csv.spec.ts +++ b/packages/serve/test/response-formatter/csv.spec.ts @@ -28,18 +28,17 @@ describe('Test array string to csv string', () => { }); describe('Test to respond to csv', () => { - it('Test to get empty stream when not found "data" or "columns" in ctx.response.body', () => { + it('Test to keep original response when not found "data" or "columns" in ctx.response.body', () => { // Arrange + const expected = 'hello'; const stubResponse = sinon.stubInterface(); stubResponse.set.callsFake(() => null); + stubResponse.body = expected; const ctx = { ...sinon.stubInterface(), url: faker.internet.url(), response: stubResponse, }; - const expected = new Stream.Readable(); - expected.push(null); - // Act const formatter = new CsvFormatter({}, ''); formatter.formatToResponse(ctx); diff --git a/packages/serve/test/response-formatter/json.spec.ts b/packages/serve/test/response-formatter/json.spec.ts index d486b8b4..84686709 100644 --- a/packages/serve/test/response-formatter/json.spec.ts +++ b/packages/serve/test/response-formatter/json.spec.ts @@ -7,17 +7,17 @@ import faker from '@faker-js/faker'; import { arrayToStream, streamToString } from '../test-utils'; describe('Test to respond to json', () => { - it('Test to get empty stream when not found "data" or "columns" in ctx.response.body', () => { + it('Test to keep original response when not found "data" or "columns" in ctx.response.body', () => { // Arrange + const expected = 'hello'; const stubResponse = sinon.stubInterface(); stubResponse.set.callsFake(() => null); + stubResponse.body = expected; const ctx = { ...sinon.stubInterface(), url: faker.internet.url(), response: stubResponse, }; - const expected = new Stream.Readable(); - expected.push(null); // Act const formatter = new JsonFormatter({}, ''); formatter.formatToResponse(ctx); diff --git a/packages/serve/test/route/routeGenerator.spec.ts b/packages/serve/test/route/routeGenerator.spec.ts index 91f3aafe..cf443300 100644 --- a/packages/serve/test/route/routeGenerator.spec.ts +++ b/packages/serve/test/route/routeGenerator.spec.ts @@ -28,6 +28,8 @@ describe('Test route generator ', () => { const fakeSchemas: Array = Array( faker.datatype.number({ min: 2, max: 4 }) ).fill(sinon.stubInterface()); + // url path must be set or router won't initialize + fakeSchemas.forEach((schema) => (schema.urlPath = '/')); beforeEach(() => { container = new Container(); diff --git a/tsconfig.base.json b/tsconfig.base.json index e89b974a..7f0b712c 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -75,6 +75,8 @@ "@vulcan-sql/serve": ["packages/serve/src/index"], "@vulcan-sql/serve/app": ["packages/serve/src/lib/app.ts"], "@vulcan-sql/serve/containers": ["packages/serve/src/containers/index"], + "@vulcan-sql/serve/types": ["packages/serve/src/containers/types"], + "@vulcan-sql/serve/loader": ["packages/serve/src/lib/loader"], "@vulcan-sql/serve/middleware": [ "packages/serve/src/lib/middleware/index" ], diff --git a/yarn.lock b/yarn.lock index 28c1bd4c..48debf14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -248,6 +248,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/runtime@^7.17.8": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -357,6 +364,11 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@exodus/schemasafe@^1.0.0-rc.2": + version "1.0.0-rc.7" + resolved "https://registry.yarnpkg.com/@exodus/schemasafe/-/schemasafe-1.0.0-rc.7.tgz#aded6839c2369883dafa46608a135c82b42ed76b" + integrity sha512-+1mBLsa+vvlV0lwEAP1hwgmOPkjMnoJ8hyCMfCCJga0sVDwDzrPJjnxZwdDaUmOh/vbFHQGBTk+FxsVjoI/CjQ== + "@faker-js/faker@^6.3.1": version "6.3.1" resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-6.3.1.tgz#1ae963dd40405450a2945408cba553e1afa3e0fb" @@ -793,6 +805,32 @@ dependencies: esquery "^1.0.1" +"@redocly/ajv@^8.6.5": + version "8.6.5" + resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.6.5.tgz#b6e737248b791905b3f600fb329779a807f0f774" + integrity sha512-3P2TY/u4c6OBqkP+1cTH1iGAEv0O34PV3vV2Wnos/nNHu62OTrtC4zcaxttG0pHtPtn42StrhGq7SsiFgP4Bfw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +"@redocly/openapi-core@^1.0.0-beta.104": + version "1.0.0-beta.108" + resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.0.0-beta.108.tgz#fbf1b4e31c148f8816d2d63aa37b7831e305ec0f" + integrity sha512-4Lq7KB+XiBvVzpaY/M0a8qog/Zr8kGrvJbRW2z7Sk2Zpc/m+8LTuZbRh15eMoneVc13M9qbHFIRh3PG18g3Tng== + dependencies: + "@redocly/ajv" "^8.6.5" + "@types/node" "^14.11.8" + colorette "^1.2.0" + js-levenshtein "^1.1.6" + js-yaml "^4.1.0" + lodash.isequal "^4.5.0" + minimatch "^5.0.1" + node-fetch "^2.6.1" + pluralize "^8.0.0" + yaml-ast-parser "0.0.43" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -1173,7 +1211,7 @@ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.7", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -1280,6 +1318,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83" integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A== +"@types/node@^14.11.8": + version "14.18.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.26.tgz#239e19f8b4ea1a9eb710528061c1d733dc561996" + integrity sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA== + "@types/node@^14.6.1": version "14.18.16" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.16.tgz#878f670ba3f00482bf859b6550b6010610fc54b5" @@ -1952,6 +1995,11 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw== + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2055,6 +2103,11 @@ class-validator@^0.13.2: libphonenumber-js "^1.9.43" validator "^13.7.0" +classnames@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + cli-cursor@3.1.0, cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -2096,6 +2149,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== +clsx@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + co-body@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.1.0.tgz#d87a8efc3564f9bfe3aced8ef5cd04c7a8766547" @@ -2153,6 +2211,11 @@ colorette@1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2376,6 +2439,11 @@ decimal.js@^10.2.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decko@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decko/-/decko-1.2.0.tgz#fd43c735e967b8013306884a56fbe665996b6817" + integrity sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -2524,6 +2592,11 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +dompurify@^2.2.8: + version "2.3.11" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.11.tgz#868f0765cb992a8af052d57b1d29ef6c929c13f1" + integrity sha512-q4c/TZfHWTPGgNBaMimQ1+bEfgo2d1G5wEnolfF3+IX2WoVw/QzOwqTyu+ylTLZDGzmsTQUnZ1gKpAGedceXMA== + dotenv@8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -2587,6 +2660,11 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es6-promise@^3.2.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + integrity sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg== + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2756,6 +2834,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2886,7 +2969,7 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-safe-stringify@^2.1.1: +fast-safe-stringify@^2.0.7, fast-safe-stringify@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== @@ -3030,6 +3113,11 @@ for-own@^1.0.0: dependencies: for-in "^1.0.1" +foreach@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.6.tgz#87bcc8a1a0e74000ff2bf9802110708cfb02eb6e" + integrity sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg== + form-data@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" @@ -3410,6 +3498,11 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http2-client@^1.2.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/http2-client/-/http2-client-1.3.5.tgz#20c9dc909e3cc98284dd20af2432c524086df181" + integrity sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA== + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -4233,7 +4326,12 @@ joi@^17.6.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -js-tokens@^4.0.0: +js-levenshtein@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" + integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -4296,6 +4394,13 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-pointer@0.6.2, json-pointer@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/json-pointer/-/json-pointer-0.6.2.tgz#f97bd7550be5e9ea901f8c9264c9d436a22a93cd" + integrity sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw== + dependencies: + foreach "^2.0.4" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -4541,6 +4646,11 @@ lodash.get@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + lodash.map@^4.5.1: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -4574,6 +4684,13 @@ longest@^2.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-2.0.1.tgz#781e183296aa94f6d4d916dc335d0d17aefa23f8" integrity sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q== +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -4581,6 +4698,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -4619,6 +4741,16 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mark.js@^8.11.1: + version "8.11.1" + resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5" + integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ== + +marked@^4.0.15: + version "4.0.19" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.19.tgz#d36198d1ac1255525153c351c68c75bc1d7aee46" + integrity sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ== + md5@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" @@ -4741,6 +4873,18 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mobx-react-lite@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.4.0.tgz#d59156a96889cdadad751e5e4dab95f28926dfff" + integrity sha512-bRuZp3C0itgLKHu/VNxi66DN/XVkQG7xtoBVWxpvC5FhAqbOCP21+nPhULjnzEqd7xBMybp6KwytdUpZKEgpIQ== + +mobx-react@^7.2.0: + version "7.5.2" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.5.2.tgz#362d6dc7271698caf3b56229c3c68fb0b30e682e" + integrity sha512-NP44ONwSqTy+3KlD7y9k7xbsuGD+8mgUj3IeI65SbxF1IOB42/j9TbosgUEDn//CCuU6OmQ7k9oiu9eSpRBHnw== + dependencies: + mobx-react-lite "^3.4.0" + moment@^2.27.0: version "2.29.4" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" @@ -4869,6 +5013,20 @@ node-addon-api@^3.2.1: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== +node-fetch-h2@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz#c6188325f9bd3d834020bf0f2d6dc17ced2241ac" + integrity sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg== + dependencies: + http2-client "^1.2.5" + +node-fetch@^2.6.1: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-gyp-build@^4.3.0: version "4.4.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" @@ -4879,6 +5037,13 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= +node-readfiles@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/node-readfiles/-/node-readfiles-0.2.0.tgz#dbbd4af12134e2e635c245ef93ffcf6f60673a5d" + integrity sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA== + dependencies: + es6-promise "^3.2.1" + node-releases@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" @@ -4949,6 +5114,57 @@ nx@14.0.3: yargs "^17.4.0" yargs-parser "21.0.1" +oas-kit-common@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/oas-kit-common/-/oas-kit-common-1.0.8.tgz#6d8cacf6e9097967a4c7ea8bcbcbd77018e1f535" + integrity sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ== + dependencies: + fast-safe-stringify "^2.0.7" + +oas-linter@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/oas-linter/-/oas-linter-3.2.2.tgz#ab6a33736313490659035ca6802dc4b35d48aa1e" + integrity sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ== + dependencies: + "@exodus/schemasafe" "^1.0.0-rc.2" + should "^13.2.1" + yaml "^1.10.0" + +oas-resolver@^2.5.6: + version "2.5.6" + resolved "https://registry.yarnpkg.com/oas-resolver/-/oas-resolver-2.5.6.tgz#10430569cb7daca56115c915e611ebc5515c561b" + integrity sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ== + dependencies: + node-fetch-h2 "^2.3.0" + oas-kit-common "^1.0.8" + reftools "^1.1.9" + yaml "^1.10.0" + yargs "^17.0.1" + +oas-schema-walker@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz#74c3cd47b70ff8e0b19adada14455b5d3ac38a22" + integrity sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ== + +oas-validator@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/oas-validator/-/oas-validator-5.0.8.tgz#387e90df7cafa2d3ffc83b5fb976052b87e73c28" + integrity sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw== + dependencies: + call-me-maybe "^1.0.1" + oas-kit-common "^1.0.8" + oas-linter "^3.2.2" + oas-resolver "^2.5.6" + oas-schema-walker "^1.1.5" + reftools "^1.1.9" + should "^13.2.1" + yaml "^1.10.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -5035,6 +5251,14 @@ open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" +openapi-sampler@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/openapi-sampler/-/openapi-sampler-1.3.0.tgz#5b99ceb4156b00d2aa3f860e52ccb768a5695793" + integrity sha512-2QfjK1oM9Sv0q82Ae1RrUe3yfFmAyjF548+6eAeb+h/cL1Uj51TW4UezraBEvwEdzoBgfo4AaTLVFGTKj+yYDw== + dependencies: + "@types/json-schema" "^7.0.7" + json-pointer "0.6.2" + openapi3-ts@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/openapi3-ts/-/openapi3-ts-2.0.2.tgz#a200dd838bf24c9086c8eedcfeb380b7eb31e82a" @@ -5156,6 +5380,11 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -5205,6 +5434,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +perfect-scrollbar@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.5.tgz#41a211a2fb52a7191eff301432134ea47052b27f" + integrity sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g== + pg-connection-string@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10" @@ -5306,6 +5540,18 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +polished@^4.1.3: + version "4.2.2" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1" + integrity sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ== + dependencies: + "@babel/runtime" "^7.17.8" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -5357,6 +5603,11 @@ pretty-format@^27.0.0, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +prismjs@^1.27.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -5370,6 +5621,15 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types@^15.5.0, prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -5420,11 +5680,24 @@ raw-body@^2.3.3: iconv-lite "0.4.24" unpipe "1.0.0" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-tabs@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-3.2.3.tgz#ccbb3e1241ad3f601047305c75db661239977f2f" + integrity sha512-jx325RhRVnS9DdFbeF511z0T0WEqEoMl1uCE3LoZ6VaZZm7ytatxbum0B8bCTmaiV0KsU+4TtLGTGevCic7SWg== + dependencies: + clsx "^1.1.0" + prop-types "^15.5.0" + readable-stream@^2.0.0: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -5461,11 +5734,49 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redoc@2.0.0-rc.76: + version "2.0.0-rc.76" + resolved "https://registry.yarnpkg.com/redoc/-/redoc-2.0.0-rc.76.tgz#1d8644f8cd5be5bee1781fc6c4104a9a3abab124" + integrity sha512-7PbH/0GUaH9GoGjaCI8tfCvkzVQY3BGhiBX9lLgpJ6oGAhvioiac7kjTwltRxl5+sDr58AyyB/4XyTBEPqbupw== + dependencies: + "@redocly/openapi-core" "^1.0.0-beta.104" + classnames "^2.3.1" + decko "^1.2.0" + dompurify "^2.2.8" + eventemitter3 "^4.0.7" + json-pointer "^0.6.2" + lunr "^2.3.9" + mark.js "^8.11.1" + marked "^4.0.15" + mobx-react "^7.2.0" + openapi-sampler "^1.3.0" + path-browserify "^1.0.1" + perfect-scrollbar "^1.5.5" + polished "^4.1.3" + prismjs "^1.27.0" + prop-types "^15.7.2" + react-tabs "^3.2.2" + slugify "~1.4.7" + stickyfill "^1.1.1" + style-loader "^3.3.1" + swagger2openapi "^7.0.6" + url-template "^2.0.8" + reflect-metadata@0.1.13, reflect-metadata@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +reftools@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/reftools/-/reftools-1.1.9.tgz#e16e19f662ccd4648605312c06d34e5da3a2b77e" + integrity sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -5697,6 +6008,50 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +should-equal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" + integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== + dependencies: + should-type "^1.4.0" + +should-format@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" + integrity sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q== + dependencies: + should-type "^1.3.0" + should-type-adaptors "^1.0.1" + +should-type-adaptors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" + integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== + dependencies: + should-type "^1.3.0" + should-util "^1.0.0" + +should-type@^1.3.0, should-type@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" + integrity sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ== + +should-util@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.1.tgz#fb0d71338f532a3a149213639e2d32cbea8bcb28" + integrity sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g== + +should@^13.2.1: + version "13.2.3" + resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" + integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== + dependencies: + should-equal "^2.0.0" + should-format "^3.0.3" + should-type "^1.4.0" + should-type-adaptors "^1.0.1" + should-util "^1.0.0" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -5738,6 +6093,11 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slugify@~1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.7.tgz#e42359d505afd84a44513280868e31202a79a628" + integrity sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg== + smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -5882,6 +6242,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stickyfill@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stickyfill/-/stickyfill-1.1.1.tgz#39413fee9d025c74a7e59ceecb23784cc0f17f02" + integrity sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA== + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -5940,6 +6305,11 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + superagent@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/superagent/-/superagent-7.1.3.tgz#783ff8330e7c2dad6ad8f0095edc772999273b6b" @@ -5999,6 +6369,23 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swagger2openapi@^7.0.6: + version "7.0.8" + resolved "https://registry.yarnpkg.com/swagger2openapi/-/swagger2openapi-7.0.8.tgz#12c88d5de776cb1cbba758994930f40ad0afac59" + integrity sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g== + dependencies: + call-me-maybe "^1.0.1" + node-fetch "^2.6.1" + node-fetch-h2 "^2.3.0" + node-readfiles "^0.2.0" + oas-kit-common "^1.0.8" + oas-resolver "^2.5.6" + oas-schema-walker "^1.1.5" + oas-validator "^5.0.8" + reftools "^1.1.9" + yaml "^1.10.0" + yargs "^17.0.1" + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6141,6 +6528,11 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + tree-kill@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -6349,6 +6741,11 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + integrity sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -6428,6 +6825,11 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -6463,6 +6865,14 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -6545,6 +6955,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml-ast-parser@0.0.43: + version "0.0.43" + resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" + integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== + yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" @@ -6573,6 +6988,19 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.0.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + yargs@^17.4.0: version "17.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284"