apigee-127 / swagger-tools

A Node.js and browser module that provides tooling around Swagger.
MIT License
701 stars 375 forks source link

$ref url encoding issue #625

Open madaster97 opened 3 years ago

madaster97 commented 3 years ago

Overview

I recently attempted to use this lib to autogen a server from this API specification.

When I attempt this, I run into an issue where all url encoded $refs do not resolve.

This is an example output (1 of 5 sets) when I attempt to npm start using this library's codegen from the swagger editor:

API Errors:
#/paths/~1cds-services/get/responses/200/schema/$ref: 
Definition could not be resolved: #/definitions/CDS%20Service%20Information

API Warnings:
#/definitions/CDS Service Information: 
Definition is defined but is not used: #/definitions/CDS Service Information

Note, in the spec above there are definition names with spaces, and attempting to construct a $ref with a space throws an error in swagger editor:

Semantic Error at ...
$ref values must be RFC3986-compliant percent-encoded URIs

Code Issue

I was able to find the spot that handles $ref and definition matching, but there are likely other areas where this is relevant. In this line, the cacheEntry.definitions object has keys corresponding to the definition names (e.g. CDS Service Information) while the defPtr (definition pointer) is a raw $ref that has not been URL decoded (e.g. CDS%20Service%20Information).

// defPathOrPtr is set to '#/definitions/CDS%20Service%20Information'
var addReference = function (cacheEntry, defPathOrPtr, refPathOrPtr, results, omitError) {
  ...
  // defPtr resolves to '#/definitions/CDS%20Service%20Information'
  var defPtr = _.isArray(defPathOrPtr) ? JsonRefs.pathToPtr(defPathOrPtr) : defPathOrPtr;
  ...
  // cacheEntry.definitions has a '#/definitions/CDS Service Information' key that is missed
  def = cacheEntry.definitions[defPtr];
  ...
}

When attempting to key out the defPtr property, we receive undefined since the object has no matching key.

Workarounds

  1. Code change in this repo, call decodeUriComponent before using any $ref pointer as a key/prop
  2. Style change for spec writers. Ensure defn. names do not require url encoding $ref. For instance, Pascal-casing would work for the example spec above.