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

Addition of dereferencedCache has broken deeply nested external dependencies #226

Closed
mummybot opened this issue Apr 16, 2021 · 2 comments
Closed

Comments

@mummybot
Copy link

mummybot commented Apr 16, 2021

The addition of the dereferencedCache in PR #195 has broken deeply nested external dependencies if a local dependency exists in the root schema.

Given the following schema:

// schema.json
{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "country": {
      "type": "string",
      "enum": {
        "$ref": "./country-codes.json"
      }
    },
    "foreignCountry": {
      "type": "string",
      "enum": {
        "$ref": "#/definitions/countries"  // This being a local dependency prevents ./external-fail.json from resolving in nested schema.
      }
    },
    "externalFail": {
      "$ref": "./external-fail.json"
    }
  },
  "properties": {
    "pageOne": {
      "$ref": "./pageOne.json"
    }
  }
}
// pageOne.json
{
  "type": "object",
  "properties": {
    "nestedProperty": {
      "$ref": "./schema.json#/definitions/country",
      "#bespokeKey": {
        "append": {
          "component": "Callout",
          "props": {
            "type": "warning"
          },
          "on": [
            "GB",
            [
              "PROHIBITED",
              {
                "$ref": "./external-fail.json"
              }
           ]
          ]
        }
      },
      "not": {
        "enum": {
          "$ref": "./external-fail.json"
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "nestedProperty": {
            "type": "string",
            "enum": {
              "$ref": "./external-success.json"
            }
          }
        }
      },
      "then": {
        "required": ["otherBooleanProperty"],
        "properties": {
          "otherBooleanProperty": {
            "type": "boolean"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "nestedProperty": {
            "type": "string",
            "enum": {
              "$ref": "./external-success.json"
            }
          },
          "otherBooleanProperty": {
            "const": false
          }
        }
      },
      "then": {
        "properties": {
          "nestedOtherProperty": {
            "$ref": "./schema.json#/definitions/country",
            "#bespokeKey": {
              "append": {
                "component": "Callout",
                "props": {
                  "type": "warning"
                },
                "on": [
                  [
                    "PROHIBITED",
                    {
                      "$ref": "./external-fail.json"
                    }
                  ]
                ]
              }
            },
            "not": {
              "enum": {
                "$ref": "./external-fail.json"
              }
            }
          }
        }
      }
    }
  ]
}
// external-fail.json
["AU", "US", "GB"]

Expected

//...
    "nestedProperty": {
      "type": "string",
      "enum": ["JP", "US", "GB", "AU"],
      "#bespokeKey": {
        "append": {
          "component": "Callout",
          "props": {
            "type": "warning"
          },
          "on": [
            "GB",
            [
              "PROHIBITED",
              ["AU", "US", "GB"]
            ]
          ]
        }
      },
      "not": {
        "enum": ["AU", "US", "GB"]
      }
    }
  },
//...

Actual

//...
    "nestedProperty": {
      "type": "string",
      "enum": ["JP", "US", "GB", "AU"],
      "#bespokeKey": {
        "append": {
          "component": "Callout",
          "props": {
            "type": "warning"
          },
          "on": [
            "GB",
            [
              "PROHIBITED",
              {
                "$ref": "./external-fail.json"
              }
            ]
          ]
        }
      },
      "not": {
        "enum": {
          "$ref": "./external-fail.json"
        }
      }
    }
//...

If I comment out https://github.com/APIDevTools/json-schema-ref-parser/blob/master/lib/dereference.js#L177 then it all works (by not adding to cache and therefore not skipping).

@mummybot
Copy link
Author

mummybot commented Apr 16, 2021

In the example above I think this is due to it matching the nestedProperty which has a ref, and then assuming that there are no other refs within that property. not is valid schema, and can be an external ref. Any key within a parent property with an external ref should still be checked for other external refs.

@mummybot
Copy link
Author

FYI @paztis

philsturgeon pushed a commit to mummybot/json-schema-ref-parser that referenced this issue May 4, 2021
mummybot added a commit to mummybot/json-schema-ref-parser that referenced this issue Jun 8, 2021
mummybot added a commit to mummybot/json-schema-ref-parser that referenced this issue Jun 8, 2021
…om:mummybot/json-schema-ref-parser into bug/APIDevTools#226/external-from-external
@jonluca jonluca closed this as completed Mar 6, 2024
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

No branches or pull requests

2 participants