From 63db95a5a747661414536d7d14adde625c1fe4a9 Mon Sep 17 00:00:00 2001 From: rentu Date: Fri, 6 Dec 2024 14:13:46 +0800 Subject: [PATCH] fix(spec-parser): graph spec hang issue, 2XX not support issue --- packages/spec-parser/package.json | 2 +- packages/spec-parser/pnpm-lock.yaml | 17 +- packages/spec-parser/src/constants.ts | 1 + packages/spec-parser/src/specParser.ts | 21 ++- packages/spec-parser/test/specParser.test.ts | 182 ++++++++++++++----- 5 files changed, 166 insertions(+), 57 deletions(-) diff --git a/packages/spec-parser/package.json b/packages/spec-parser/package.json index 6e63079f85..4e321e63ae 100644 --- a/packages/spec-parser/package.json +++ b/packages/spec-parser/package.json @@ -40,6 +40,7 @@ "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", "@microsoft/teams-manifest": "workspace:*", + "@apidevtools/json-schema-ref-parser": "^11.7.2", "fs-extra": "^11.2.0", "js-yaml": "^4.1.0", "openapi-types": "^7.2.3", @@ -49,7 +50,6 @@ "access": "public" }, "devDependencies": { - "@apidevtools/json-schema-ref-parser": "^9.0.6", "@apidevtools/openapi-schemas": "2.1.0", "@apidevtools/swagger-methods": "3.0.2", "@istanbuljs/nyc-config-typescript": "^1.0.2", diff --git a/packages/spec-parser/pnpm-lock.yaml b/packages/spec-parser/pnpm-lock.yaml index dfde37b5ba..50837e0d4e 100644 --- a/packages/spec-parser/pnpm-lock.yaml +++ b/packages/spec-parser/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@apidevtools/json-schema-ref-parser': + specifier: ^11.7.2 + version: 11.7.2 '@apidevtools/swagger-parser': specifier: ^10.1.0 version: 10.1.0(openapi-types@7.2.3) @@ -25,9 +28,6 @@ dependencies: version: 7.0.8 devDependencies: - '@apidevtools/json-schema-ref-parser': - specifier: ^9.0.6 - version: 9.0.6 '@apidevtools/openapi-schemas': specifier: 2.1.0 version: 2.1.0 @@ -317,12 +317,22 @@ packages: '@jridgewell/trace-mapping': 0.3.22 dev: true + /@apidevtools/json-schema-ref-parser@11.7.2: + resolution: {integrity: sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==} + engines: {node: '>= 16'} + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + dev: false + /@apidevtools/json-schema-ref-parser@9.0.6: resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==} dependencies: '@jsdevtools/ono': 7.1.3 call-me-maybe: 1.0.2 js-yaml: 3.14.1 + dev: false /@apidevtools/openapi-schemas@2.1.0: resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} @@ -829,7 +839,6 @@ packages: /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} diff --git a/packages/spec-parser/src/constants.ts b/packages/spec-parser/src/constants.ts index 8a30d3e6c3..ecca1e3ec8 100644 --- a/packages/spec-parser/src/constants.ts +++ b/packages/spec-parser/src/constants.ts @@ -74,6 +74,7 @@ export class ConstantString { "207", "208", "226", + "2XX", "default", ]; static readonly AllOperationMethods = [ diff --git a/packages/spec-parser/src/specParser.ts b/packages/spec-parser/src/specParser.ts index 773d040029..d7866044c8 100644 --- a/packages/spec-parser/src/specParser.ts +++ b/packages/spec-parser/src/specParser.ts @@ -33,6 +33,7 @@ import { wrapAdaptiveCard } from "./adaptiveCardWrapper"; import { ValidatorFactory } from "./validators/validatorFactory"; import { Validator } from "./validators/validator"; import { createHash } from "crypto"; +import { $RefParser } from "@apidevtools/json-schema-ref-parser"; /** * A class that parses an OpenAPI specification file and provides methods to validate, list, and generate artifacts. @@ -47,6 +48,8 @@ export class SpecParser { private unResolveSpec: OpenAPIV3.Document | undefined; private isSwaggerFile: boolean | undefined; + private readonly refParser; + private defaultOptions: ParseOptions = { allowMissingId: true, allowSwagger: true, @@ -70,6 +73,7 @@ export class SpecParser { constructor(pathOrDoc: string | OpenAPIV3.Document, options?: ParseOptions) { this.pathOrSpec = pathOrDoc; this.parser = new SwaggerParser(); + this.refParser = new $RefParser(); this.options = { ...this.defaultOptions, ...(options ?? {}), @@ -87,11 +91,14 @@ export class SpecParser { try { await this.loadSpec(); - if (!this.parser.$refs.circular) { + if (!this.refParser.$refs.circular) { await this.parser.validate(this.spec!); } else { + // The following code hangs for Graph API, support will be added when SwaggerParser is updated. + /* const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec)); await this.parser.validate(clonedUnResolveSpec); + */ } } catch (e) { return { @@ -122,7 +129,7 @@ export class SpecParser { } // Remote reference not supported - const refPaths = this.parser.$refs.paths(); + const refPaths = this.refParser.$refs.paths(); // refPaths [0] is the current spec file path if (refPaths.length > 1) { errors.push({ @@ -273,7 +280,7 @@ export class SpecParser { } const clonedUnResolveSpec = JSON.parse(JSON.stringify(newUnResolvedSpec)); - const newSpec = (await this.parser.dereference(clonedUnResolveSpec)) as OpenAPIV3.Document; + const newSpec = await this.deReferenceSpec(clonedUnResolveSpec); return [newUnResolvedSpec, newSpec]; } catch (err) { if (err instanceof SpecParserError) { @@ -283,6 +290,11 @@ export class SpecParser { } } + private async deReferenceSpec(spec: any): Promise { + const result = await this.refParser.dereference(spec); + return result as OpenAPIV3.Document; + } + /** * Generates and update artifacts from the OpenAPI specification file. Generate Adaptive Cards, update Teams app manifest, and generate a new OpenAPI specification file. * @param manifestPath A file path of the Teams app manifest file to update. @@ -479,7 +491,8 @@ export class SpecParser { } const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec)); - this.spec = (await this.parser.dereference(clonedUnResolveSpec)) as OpenAPIV3.Document; + + this.spec = await this.deReferenceSpec(clonedUnResolveSpec); } } diff --git a/packages/spec-parser/test/specParser.test.ts b/packages/spec-parser/test/specParser.test.ts index 9fc2d5a4c4..244c5dafec 100644 --- a/packages/spec-parser/test/specParser.test.ts +++ b/packages/spec-parser/test/specParser.test.ts @@ -45,7 +45,7 @@ describe("SpecParser", () => { const specParser = new SpecParser("/path/to/spec.yaml"); const spec = { openapi: "3.0.0" }; sinon.stub(specParser.parser, "parse").resolves(spec as any); - sinon.stub(specParser.parser, "dereference").resolves(spec as any); + sinon.stub((specParser as any).refParser, "dereference").resolves(spec as any); const parseStub = sinon .stub(specParser.parser, "validate") .rejects(new Error("Invalid spec")); @@ -127,7 +127,7 @@ describe("SpecParser", () => { const openapiSpecObj = await converter.convert(spec as any, {}); const dereferenceStub = sinon - .stub(specParser.parser, "dereference") + .stub((specParser as any).refParser, "dereference") .resolves(openapiSpecObj.openapi); const validateStub = sinon .stub(specParser.parser, "validate") @@ -214,7 +214,7 @@ describe("SpecParser", () => { const openapiSpecObj = await converter.convert(spec as any, {}); const dereferenceStub = sinon - .stub(specParser.parser, "dereference") + .stub((specParser as any).refParser, "dereference") .resolves(openapiSpecObj.openapi); const validateStub = sinon .stub(specParser.parser, "validate") @@ -238,7 +238,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -260,7 +262,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -286,7 +290,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -316,7 +322,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -431,7 +439,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -492,7 +502,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath, { allowMissingId: false }); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); @@ -559,7 +571,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); expect(result.status).to.equal(ValidationStatus.Valid); @@ -614,7 +628,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath, { projectType: ProjectType.Copilot }); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); expect(result.status).to.equal(ValidationStatus.Valid); @@ -771,7 +787,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath, { projectType: ProjectType.Copilot }); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const createValidatorSpy = sinon.spy(ValidatorFactory, "create"); const result1 = await specParser.validate(); @@ -822,7 +840,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); expect(result.errors[0].type).equal(ErrorType.SpecVersionNotSupported); @@ -881,7 +901,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath, { projectType: ProjectType.TeamsAi }); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); const result = await specParser.validate(); expect(result.status).to.equal(ValidationStatus.Valid); @@ -937,7 +959,9 @@ describe("SpecParser", () => { try { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const validateStub = sinon.stub(specParser.parser, "validate").resolves(spec as any); sinon.stub(SMEValidator.prototype, "validateSpec").throws(new Error("validateSpec error")); @@ -993,7 +1017,9 @@ describe("SpecParser", () => { signal.aborted = true; return Promise.resolve(); }); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); await specParser.generateForCopilot( manifestPath, filter, @@ -1016,7 +1042,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon .stub(SpecFilter, "specFilter") .callsFake((filter: string[], unResolveSpec: any) => { @@ -1055,7 +1083,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").resolves(); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1114,7 +1144,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1186,7 +1218,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns(spec as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1266,7 +1300,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns(spec as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1302,7 +1338,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").resolves(); const outputFileStub = sinon.stub(fs, "outputFile").throws(new Error("outputFile error")); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1373,7 +1411,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").callsFake((path, data) => { @@ -1444,7 +1484,9 @@ describe("SpecParser", () => { signal.aborted = true; return Promise.resolve(); }); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); await specParser.generate(manifestPath, filter, specPath, adaptiveCardFolder, signal); expect.fail("Expected an error to be thrown"); } catch (err) { @@ -1460,7 +1502,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon .stub(SpecFilter, "specFilter") .callsFake((filter: string[], unResolveSpec: any) => { @@ -1517,7 +1561,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1556,7 +1602,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1615,7 +1663,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1683,7 +1733,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1763,7 +1815,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1840,7 +1894,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -1956,7 +2012,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -2069,7 +2127,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -2187,7 +2247,9 @@ describe("SpecParser", () => { }, }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -2262,7 +2324,7 @@ describe("SpecParser", () => { const cloneSpec = JSON.parse(JSON.stringify(spec)); cloneSpec.paths["/hello"].get.operationId = "getHello"; const dereferenceStub = sinon - .stub(specParser.parser, "dereference") + .stub((specParser as any).refParser, "dereference") .resolves(cloneSpec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").returns({} as any); const outputFileStub = sinon.stub(fs, "outputFile").resolves(); @@ -2306,7 +2368,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon.stub(SpecFilter, "specFilter").resolves(); const outputFileStub = sinon.stub(fs, "outputFile").throws(new Error("outputFile error")); const outputJSONStub = sinon.stub(fs, "outputJSON").resolves(); @@ -2340,7 +2404,9 @@ describe("SpecParser", () => { const specParser = new SpecParser("path/to/spec.yaml"); const spec = { openapi: "3.0.0", paths: {} }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const specFilterStub = sinon .stub(SpecFilter, "specFilter") .throws(new SpecParserError("specFilter error", ErrorType.FilterSpecFailed)); @@ -2454,7 +2520,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -2552,7 +2620,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -2634,7 +2704,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -2707,7 +2779,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -2783,7 +2857,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); expect(result).to.deep.equal({ @@ -2918,7 +2994,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -3064,7 +3142,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -3159,7 +3239,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -3221,7 +3303,9 @@ describe("SpecParser", () => { }; const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); @@ -3300,7 +3384,9 @@ describe("SpecParser", () => { const specParser = new SpecParser(specPath); const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); - const dereferenceStub = sinon.stub(specParser.parser, "dereference").resolves(spec as any); + const dereferenceStub = sinon + .stub((specParser as any).refParser, "dereference") + .resolves(spec as any); const result = await specParser.list(); expect(result).to.deep.equal({ @@ -3383,7 +3469,7 @@ describe("SpecParser", () => { const parseStub = sinon.stub(specParser.parser, "parse").resolves(spec as any); const dereferenceStub = sinon - .stub(specParser.parser, "dereference") + .stub((specParser as any).refParser, "dereference") .callsFake(async (api: string | OpenAPI.Document) => { expect((api as OpenAPIV3.Document).servers![0].url == "https://server1"); return api as any;