CesiumGS / wetzel

Generate Markdown documentation from JSON Schema
Apache License 2.0
134 stars 54 forks source link

Handle circular refs in schema #56

Open BrunnerLivio opened 3 years ago

BrunnerLivio commented 3 years ago

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)
emackey commented 3 years ago

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!

volodink commented 2 years ago

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?

emackey commented 2 years ago

@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.

volodink commented 2 years ago

Got it, thanks!