APIDevTools / swagger-parser

Swagger 2.0 and OpenAPI 3.0 parser/validator
https://apitools.dev/swagger-parser
MIT License
1.09k stars 154 forks source link

swagger-parser `10.0.3` version is not compatible with `typescript` version `4.4.2` #186

Closed jjtang1985 closed 1 year ago

jjtang1985 commented 3 years ago

Description

Dependabot created a PR for updating typescript version to 4.4.2, which failed due to the error below:

TypeError: Class is not a constructor

    at resolve (/.../node_modules/@apidevtools/json-schema-ref-parser/lib/index.js:162:18)

How to reproduce

  1. update typescript version to 4.4.2.
  2. run the following code and see errors
    async resolve(document); // typed as `OpenAPIV3.Document`

Expected behaviour

The type error is fixed.

Additional information

It's working with typescript version 4.3.5.

FrankEssenberger commented 2 years ago

Typescript tightened the rules for the this pointer see here: https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#typescript-44

As a consequence a this is undefined here in the parser: https://github.com/APIDevTools/json-schema-ref-parser/blob/f6886ab9ee576754791f2a194b140a637dd98a87/lib/index.js#L162

I guess in the mentioned place the usage of this should be adjusted to mathc the ES6 export standard mentioned in the TS changelog. However, this could be a breaking change because user could rely on the usage of this within the method when they fiddle around with the context.

milesj commented 2 years ago

Has anyone figured out a work around?

nspire909 commented 2 years ago

To fix this after updating to Angular 13 and TS 4.4, I just changed from importing an individual method to the entire object:

import { validate } from '@apidevtools/swagger-parser'; to import $SwaggerParser from '@apidevtools/swagger-parser';

And then use $SwaggerParser.validate instead of validate. Should work for the other methods also.

philsturgeon commented 2 years ago

Can somebody send a pull request if you've figured the problem out?

FrankEssenberger commented 2 years ago

We used the following work around in our project:

export async function resolveBound(
  document: OpenAPIV3.Document
): Promise<$Refs> {
  return resolve.bind(SwaggerParser)(document);

This sets the this pointer to the SwaggerParser and the old code works. Either you would have to wrap the public facing methods with something similar or you need to adjust the code that it does not use the this pointer the way it does currently.

philsturgeon commented 2 years ago

@FrankEssenberger thanks frank. I'd really appreciate it if you could find some time to send a pull request moving your workaround upatream as a solution. I am technically maintaining this project but I've never used it in my life, and I've already put about 10 hours into try fix the release process and various dependencies that are causing troubles, unpaid, just as a favor to the previous owner. If you've got tooling which uses this tool it would be awesome to help me get it fixed. 🙌🏻