wetzel icon indicating copy to clipboard operation
wetzel copied to clipboard

Handle circular refs in schema

Open BrunnerLivio opened this issue 3 years ago • 4 comments

I use a circular model for my JSON schema. So as an example JSON, something like this:

{
  "guides": [{
    // This can go on forever recursively
     "children": [{
        "children": [{
           "name": "My Item"
        }]
     }]
  }]
}

Here is JSON schema

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "DocsConfigNavigation": {
            "anyOf": [
                {
                    "$ref": "#/definitions/DocsConfigNavigationPage"
                },
                {
                    "$ref": "#/definitions/DocsConfigNavigationCategory"
                }
            ]
        },
        "DocsConfigNavigationCategory": {
            "properties": {
                "children": {
                    "items": {
                        "$ref": "#/definitions/DocsConfigNavigation"
                    },
                    "type": "array"
                }
            },
            "required": [
                "children"
            ],
            "type": "object"
        },
        "DocsConfigNavigationPage": {
            "properties": {
                "name": {
                    "type": "string"
                }
            },
            "type": "object"
        }
    },
    "properties": {
        "guides": {
            "items": {
                "$ref": "#/definitions/DocsConfigNavigation"
            },
            "type": "array"
        }
    },
    "type": "object"
}

This results in the following error:

$ wetzel docs.schema.json
/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/defaultValue.js:14
function defaultValue(value, fallback) {
                     ^

RangeError: Maximum call stack size exceeded
    at defaultValue (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/defaultValue.js:14:22)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:28:24)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:90:16)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:90:16)
    at replaceRef (/Users/brunnel6/.npm-packages/lib/node_modules/wetzel/lib/replaceRef.js:96:32)

BrunnerLivio avatar Aug 12 '21 09:08 BrunnerLivio

I looked into this a bit. Sadly it appears the current strategy internally is to replace every $ref with a full copy of the referenced schema when building the documentation for its containing type. Thus, a circular reference creates infinite recursion, and cannot be fully expanded using the current architecture.

I'm sure it's not impossible to fix, but it's a structural change, not a quick tweak. Contributions welcome!

emackey avatar Sep 24 '21 14:09 emackey

Hi. I don't use circular references, but regular ones and receive this error:

 throw new Error(`No title found in $ref ${ref}`);

Does simple refs are supported?

volodink avatar Nov 24 '21 11:11 volodink

@volodink That's off-topic here, but generally this documentation tool requires the title attribute in certain places where it would normally be considered optional by other tools. That's because this tool is attempting to build cross-links and TOC anchors and such things. Try adding a title to the referenced schema.

emackey avatar Nov 28 '21 15:11 emackey

Got it, thanks!

volodink avatar Nov 28 '21 15:11 volodink