Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolveSubtree does not support 3.1 spec #3728

Closed
meijey opened this issue Dec 4, 2024 · 2 comments
Closed

resolveSubtree does not support 3.1 spec #3728

meijey opened this issue Dec 4, 2024 · 2 comments

Comments

@meijey
Copy link

meijey commented Dec 4, 2024

Q&A (please complete the following information)

  • OS: Linux ubuntu 22.04
  • Environment: Chrome 130, Node.js v20.17.0]
  • Method of installation: npm
  • Swagger-Client version: 3.32.2
  • Swagger/OpenAPI version: OpenAPI 3.0 + OpenAPI 3.1

Swagger/OpenAPI definition:
https://petstore3.swagger.io/api/v3/openapi.json (working)
https://petstore31.swagger.io/api/v31/openapi.json (cannot be resolved partly)

Swagger-Client usage:

SwaggerClient.resolveSubtree(spec, [''], { returnEntireTree: true }

Describe the bug you're encountering

Hi,
I'm using swagger-js in openApi-red for Node-RED.
On startup I partly resolve all files in use to check for errors and to normalize the file. To reduce loading times, especially for huge files, this is made with SwaggerClient.resolveSubtree(spec, [''], { returnEntireTree: true }).

This works fine with openAPI 2.0 and 3.0 files.
Files with version 3.1 will return null.

The error seems to occur here:

Exception has occurred: EvaluationJsonPointerError: JSON Pointer evaluation failed while evaluating token "" against an ObjectElement
  at /workspace/openApi-red/node_modules/@swagger-api/apidom-json-pointer/src/evaluate.cjs:29:15
    at Array.reduce (<anonymous>)
    at evaluate (/workspace/openApi-red/node_modules/@swagger-api/apidom-json-pointer/src/evaluate.cjs:25:17)
    at resolveOpenAPI31Strategy (/workspace/openApi-red/node_modules/swagger-client/lib/resolver/strategies/openapi-3-1-apidom/resolve.js:77:61)
    at Object.resolve (/workspace/openApi-red/node_modules/swagger-client/lib/resolver/strategies/openapi-3-1-apidom/index.js:31:33)
    at resolve (/workspace/openApi-red/node_modules/swagger-client/lib/resolver/index.js:29:19)
    at Function.resolve (/workspace/openApi-red/node_modules/swagger-client/lib/resolver/index.js:36:10)
    at asyncTest (/workspace/openApi-red/test.js:16:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

This may be related to this ticket in swagger-ui: swagger-api/swagger-ui#10191.

To reproduce...

This test case shows which way is working and with what file version and which is not.

test.js

const SwaggerClient = require('swagger-client')

const resolveSpecs = async () => {
  // const jsonString = await fetch('https://petstore3.swagger.io/api/v3/openapi.json') // Working
  const jsonString = await fetch('https://petstore31.swagger.io/api/v31/openapi.json') // Not working
  const spec = await jsonString.json()

  // const resolved = await new SwaggerClient({ spec, pathDiscriminator: [''] }) // works with 3.0 + 3.1
  // const resolved = await SwaggerClient.resolve({ spec }) // works with 3.0 + 3.1
  // const resolved = await SwaggerClient.resolve({ spec, pathDiscriminator: [''] }) // works with 3.0 but not with 3.1
  const resolved = await SwaggerClient.resolveSubtree(spec, [''], { returnEntireTree: true }) // works with 3.0 but not with 3.1
  console.log('spec', resolved.spec)
}
resolveSpecs()

Expected behavior

Getting a (partly) resolved specification with version 3.0 and 3.1.

@char0n
Copy link
Member

char0n commented Jan 3, 2025

Hi @meijey,

Thanks for the detailed report. I've addressed the issue in #3760. Let me dissect what the PR is actually addressing:

1. Passing pathDiscriminator in constructor

This wasn't supported before. pathDiscriminator was ignored. The PR remedies that.

new SwaggerClient({ spec, pathDiscriminator: [] })

2. Handling of invalid pathDiscriminator

If invalid pathDiscriminator is passed in, then the OpenAPI 3.1.0 resolution in now aligned with OpenAPI 3.0.x one. What's actually happening is that no resolution happens and original spec is returned instead of null.


Then we're getting to your examples. All of those examples use [''] as pathDiscriminator value. [''] value represents a list of parsed JSON Pointer tokens (RFC 6901).

If we compile [''] pathDiscriminator into JSON Pointer, we'll get /.

[''] -> '/'

JSON Pointer / represents a following evaluation:

object = { '': 3 }
evalute(object, '/');  => 3

It evaluates the JSON Pointer on object with key represented as empty string. Which doesn't exist inside valid OpenAPI Description.

The inconsistency addressed by my PR, is the result of you using invalid pathDiscriminator and uncovering inconsistent spec handling.


You described you're doing the following: (I assume you want to resolve entire OpenAPI Description)

SwaggerClient.resolveSubtree(spec, [''], { returnEntireTree: true });

If we fix your pathDiscriminator we'll get into:

SwaggerClient.resolveSubtree(spec, [], { returnEntireTree: true });

Which is equivalent to:

SwaggerClient.resolve({ spec });

I hope it clears things out a bit.

swagger-bot pushed a commit that referenced this issue Jan 3, 2025
## [3.33.1](v3.33.0...v3.33.1) (2025-01-03)

### Bug Fixes

* **resolver:** align resolver strategies behavior on invalid path discriminator ([#3760](#3760)) ([d727487](d727487)), closes [#3728](#3728)
@char0n
Copy link
Member

char0n commented Jan 3, 2025

@char0n char0n closed this as completed Jan 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants