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

Fix $ref issue with special characters (#183) #184

Merged
merged 8 commits into from
Dec 24, 2019
Merged

Fix $ref issue with special characters (#183) #184

merged 8 commits into from
Dec 24, 2019

Conversation

jy95
Copy link
Contributor

@jy95 jy95 commented Dec 16, 2019

Attempt to fix #183 .
In my opinion ( as some of the tests uses circular structure ) , it is better to give choice to final user to use dereference / bundle if they got a similar situation like mine.

For example :

new OpenApiValidator({
    unsafeRefs: true
}).install(app)

@@ -23,7 +23,7 @@ export class OpenAPIFramework {
visitor: OpenAPIFrameworkVisitor,
): Promise<OpenAPIFrameworkInit> {
const args = this.args;
const apiDoc = await this.copy(await this.loadSpec(args.apiDoc));
const apiDoc = await this.copy(await this.loadSpec(args.apiDoc, args.unsafeRefs));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be possible to use dereference instead of bundle, yet use lodash.clonedeep to copy the spec? it would be great if we can remove the need for an option

Copy link
Contributor Author

@jy95 jy95 Dec 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give me your full code proposal and I will test on my project to tell you if it works.
If not, I am afraid it is the only solution : bundle works great on detecting circular refs ( like some of your tests ) but doesn't work with escaped paths ( as explained in the $ref parser documentation, dereference doesn't have protection against circular dependacies so it will probably fail your tests with circular $refs )...

EDIT : I added a test case in order to reproduce the bug.

Copy link
Owner

@cdimascio cdimascio Dec 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the doc in dereference mentions

JSON Schema files can contain circular $ref pointers, and JSON Schema $Ref Parser fully supports them. Circular references can be resolved and dereferenced just like any other reference. However, if you intend to serialize the dereferenced schema as JSON, then you should be aware that JSON.stringify does not support circular references by default, so you will need to use a custom replacer function.

You can disable circular references by setting the dereference.circular option to false. Then, if a circular reference is found, a ReferenceError will be thrown.

Or you can choose to just ignore circular references altogether by setting the dereference.circular option to "ignore". In this case, all non-circular references will still be dereferenced as normal, but any circular references will remain in the schema.

Another option is to use the bundle method rather than the dereference method. Bundling does not result in circular references, because it simply converts external $ref pointers to internal ones.

The exprss-openapi-api validator code does end up serializing the apiDoc with JSON.stringify(). The copy method on line 26 does this. I wonder if things will work with dereference if we modify the way that copy function works. For example, we could use lodash.deepCopy or JSON.stringify with a replacer function.

If we're able to use dereference for all cases, we can avoid the need for an option. It seems to make dereference work we need to avoid serializing apiDoc since it may have circular refs

Copy link
Contributor Author

@jy95 jy95 Dec 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is worth a try : if this passes my example of specification above then we can consider the problem solved.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤞 let me know how it turns out

Copy link
Contributor Author

@jy95 jy95 Dec 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can fork this branch and try (as I added a test : it is more easily to check) : I am not completly sure how you would like to change the code to handle this situation

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deepclone doesn't help, unfortunately. appears we indeed require an option

perhaps instead of $unsafeRefs(since dereference doesn't necessarily mean refs are unsafe), we provide an option to use bundle or dereference. its a bit of an implementation detail that ends up getting exposed, but perhaps we can remove this option at some point in the future (if json-ref-parser provides an alternative)

Perhaps something like:

  $refParser: {
     mode: 'bundle' | 'dereference
  }

where $refParser.mode = 'bundle' is the default when not present

thoughts?

Copy link
Contributor Author

@jy95 jy95 Dec 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM : Feel free to rename it as you wish

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will look at this shortly and get this in

@jy95
Copy link
Contributor Author

jy95 commented Dec 18, 2019

@cdimascio I add a test to reproduce the bug - You can try what you think in order to solve the bug.
( If your solution didn't work, you can squash commits of this PR before merging )

@jy95
Copy link
Contributor Author

jy95 commented Dec 19, 2019

@cdimascio Sorry for the many commits : my linter rules aren't the same that Codacy ( you can squash them before merging )

@cdimascio cdimascio merged commit 8da3c03 into cdimascio:master Dec 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue with some $ref
2 participants