Skip to content

How to set limit on circular $refs (infinitely deep schema) #403

@SilentArctic

Description

@SilentArctic

@apidevtools/json-schema-ref-parser: ^15.1.2

Hello! I'm having an issue where dereferencing a schema that references itself is creating a (near) infinitely long result. I've written a custom http resolver and am aware that could be the issue, so maybe you can help me solve two problems at once?

Schema

{
  "$id": "<remote base url>/schemas/varyingDisplay_sub_schema.json",
   "type": "array",
   "items": {
      "oneOf": [
         {
            "title": "String",
            "type": "string"
         },

         {
            "title": "Advanced Text",
            "type": "object",
            "properties": {
               "type": {
                  "type": "string",
                  "enum": [
                     "text",
                     "sidebar",
                     "example",
                     "read-aloud",
                     "codeblock"
                  ]
               },
               "title": {
                  "type": "string",
                  "description": "Section Title."
               },
               "forceTitleLevel": {
                  "type": "integer"
               },
               "page": {
                  "type": "integer"
               },
               "hasModal": {
                  "type": "boolean"
               },
               "entries": { "$ref": "#" },
               "_ref": {
                  "type": "object",
                  "properties": {
                     "name": {
                        "type": "string"
                     },
                     "source": {
                        "type": "string"
                     }
                  },
                  "required": [
                     "name"
                  ],
                  "optional": [
                     "source"
                  ],
                  "additionalProperties": false
               }
            },
            "required": [
               "entries"
            ],
            "optional": [
               "type",
               "title",
               "page",
               "forceTitleLevel",
               "hasModal",
               "_ref"
            ],
            "additionalProperties": false
         }
      ]
   }
}

custom resolver

import $RefParser, { type FileInfo } from "@apidevtools/json-schema-ref-parser";

const schema$RefResolver = (baseUrl: string) => ({
   order: 200,
   headers: null,
   timeout: 60_000,
   redirects: 0,
   withCredentials: false,
   safeUrlResolver: true,

   async read(file: FileInfo) {
      const fileName = file.url.split('/').slice(-1);
      const url = `${baseUrl}/schemas/${fileName}`;

      const schemaData = await fetch(url);
      const schema = await schemaData.json();

      return schema;
   },
});

const baseUrl = 'http://<local base url>';
$RefParser.dereference(schema, {
   resolve: { http: schema$RefResolver(baseUrl },
});

Problem 1 (why the custom resolver):

  • Without it, the $ref schemas are fetched at https:<external base url>/varyingDisplay_sub_schema.json
    • This forces me to use the prod schema when I need to use a schema in dev
    • As you can see, the /schemas path is left off of the url
  • Is there a better way to do this so I'm not overwriting the read method?

Problem 2 (Infinite derefed schemas):

  • As you can see from my schema, there are two possible options:
    • array of strings
    • array of objects
      • These objects reference the root schema under the entries property
  • After dereferencing the schema I'm left with a oneOf array that contains the string option, and the object option which contains itself for near infinity.
  • Is there any way to limit the depth of circular refs?
    • Is this functionality already built in and I'm overriding it to fix my first problem?

Thanks for your time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions