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

Type Arrays not Supported #177

Closed
stdavis opened this issue Oct 14, 2019 · 5 comments
Closed

Type Arrays not Supported #177

stdavis opened this issue Oct 14, 2019 · 5 comments

Comments

@stdavis
Copy link

stdavis commented Oct 14, 2019

What did you do

Ran jsonschema2md against a schema file that has an array as a value for type. e.g.

What did you expect to happen

The docs to recognize that the type for the object could be either a string or an object.

What happened

The parser returned a message: "Unknown type object,string"

What's your environment

  • Operating System: macOS Catalina
  • node.js version: 10.16.0

Do you have example files:

For this schema

"baseLayers": {
  "type": "array",
  "items": {
    "type": [
      "object",
      "string"
    ],
    "properties": {
      "id": {
        "description": "The name of the layer",
        "type": "string"
      },
      "Factory": {
        "description": "The name of the esrijs module associated with the layer type",
        "type": "string"
      },
      "urlTemplate": {
        "description": "The urlTemplate for the layer. \"{quadWord}\" will be automatically replaced with the appropriate value at runtime.",
        "type": "string"
      }
    },
    "required": [
      "id",
      "Factory",
      "urlTemplate"
    ]
  }
},

I'm getting following Markdown

##### baseLayers Type

Array type: multiple

All items must be of the type: Unknown type `object,string`.

```json
{
  "type": "array",
  "items": {
    "type": ["object", "string"],
    "properties": {
      "id": {
        "description": "The name of the layer",
        "type": "string"
      },
      "Factory": {
        "description": "The name of the esrijs module associated with the layer type",
        "type": "string"
      },
      "urlTemplate": {
        "description": "The urlTemplate for the layer. \"{quadWord}\" will be automatically replaced with the appropriate value at runtime.",
        "type": "string"
      }
    },
    "required": ["id", "Factory", "urlTemplate"],
    "simpletype": "multiple"
  },
  "simpletype": "multiple"
}
@trieloff trieloff changed the title Support Arrays as Value for Type Support Arrays as Value for Root Type Oct 17, 2019
@trieloff
Copy link
Collaborator

Right now, we expect every schema file to be an object at the root. I realize that this is not ideal.

@stdavis
Copy link
Author

stdavis commented Oct 17, 2019

Actually, that's not my root object. That's nested within my root. I just pulled it out as an example. So what am I doing wrong? Here's my entire file:

{
  "$schema": "http://json-schema.org/schema#",
  "type": "object",
  "properties": {
    "tabs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "description": "The name of the tab that shows up in the actual tab control",
            "type": "string"
          },
          "webMapId": {
            "description": "The id of the web map that you would like displayed in the tab",
            "type": "string"
          },
          "hideLayerSelector": {
            "description": "Determines whether the layer selector widget is displayed or not",
            "type": "boolean",
            "default": false
          },
          "useDefaultAGOLPopup": {
            "type": "boolean"
          },
          "filter": {
            "description": "Contains configs for the filter widget.",
            "type": "object",
            "properties": {
              "layerNames": {
                "description": "Defines all of the layer names as they show up in the web map",
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "checkboxes": {
                "description": "Defines checkboxes for toggling visibility of one to many layers.",
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "layerNames": {
                      "description": "Defines the layer(s) that you want to toggle. Values must match the property names of `layerNames` above.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "phase": {
                      "description": "Defines the zero-based index of the phase that this checkbox is associated with.",
                      "type": "number"
                    },
                    "symbol": {
                      "description": "Defines the type of symbol component to be displayed.",
                      "type": "string",
                      "enum": [
                        "simple",
                        "classes",
                        "linePoint",
                        "phase",
                        "dynamic",
                        "static"
                      ]
                    },
                    "symbolImageFile": {
                      "description": "Defines the filename for the image that should be used with the static legend symbol. Note that the file needs to be placed in the root of the application.",
                      "type": "string"
                    },
                    "symbolLayerIds": {
                      "description": "Defines the layer ids (as strings) for which you would like to show symbols. Up to three values may be specified. If you would like multiple symbols overlayed, separate them with a \",\" (e.g. \"23,45\"). If you would like to define a specific symbol class within a layer you can use \"-<class index>\" (e.g. \"69-1\"",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "symbolLabels": {
                      "description": "Optionally define text that will show in a popover when hovering over the associated symbol. Note that the order of this property should match the order of `symbolLayerIds`.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "staticColors": {
                      "description": "Used to define colors for the `staticColors` symbol type.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "label": {
                            "type": "string"
                          },
                          "hsa": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "label"
                  ],
                  "oneOf": [
                    {
                      "required": [ "layerNames" ]
                    },
                    {
                      "required": [ "phase" ]
                    }
                  ]
                },
                "phases": {
                  "description": "Defines the field name and values that correspond to each of the phases (1, 2, 3 & unfunded) for the appropriate layers.",
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "description": "The first value is the field name and subsequent values correspond to the phases. The unfunded phase value is optional.",
                      "type": ["string", "number"]
                    }
                  }
                }
              },
              "groups": {
                "description": "Defines the checkbox groups.",
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "checkboxes": {
                      "description": "Checkboxes to be included in the group. Values must match the property names for `checkboxes` above.",
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "radio": {
                      "description": "Controls whether the children are checkboxes or radio buttons.",
                      "type": "boolean"
                    },
                    "showFilterByPhasing": {
                      "description": "Controls whether the \"(filter by phasing)\" checkbox is displayed",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "label",
                    "checkboxes"
                  ]
                }
              }
            }
          }
        },
        "required": [
          "name",
          "webMapId"
        ]
      }
    },
    "sherlock": {
      "description": "Configuration options for the map search widget",
      "type": "object",
      "properties": {
        "serviceUrl": {
          "description": "The URL to the service that you would like to search features on.",
          "type": "string"
        },
        "searchField": {
          "description": "The name of the field that you would like the search to be applied to.",
          "type": "string"
        },
        "placeHolder": {
          "description": "The place holder text that shows up in the text box before a user starts typing.",
          "type": "string"
        }
      },
      "required": [
        "serviceUrl",
        "searchField"
      ]
    },
    "layerSelector": {
      "description": "Configuration options for the base map selector widget",
      "type": "object",
      "properties": {
        "baseLayers": {
          "type": "array",
          "items": {
            "type": [
              "object",
              "string"
            ],
            "properties": {
              "id": {
                "description": "The name of the layer",
                "type": "string"
              },
              "Factory": {
                "description": "The name of the esrijs module associated with the layer type",
                "type": "string"
              },
              "urlTemplate": {
                "description": "The urlTemplate for the layer. \"{quadWord}\" will be automatically replaced with the appropriate value at runtime.",
                "type": "string"
              }
            },
            "required": [
              "id",
              "Factory",
              "urlTemplate"
            ]
          }
        },
        "overlays": {
          "type": "array",
          "items": {
            "type": [
              "object",
              "string"
            ],
            "properties": {
              "id": {
                "description": "The name of the layer",
                "type": "string"
              },
              "Factory": {
                "description": "The name of the esrijs module associated with the layer type",
                "type": "string"
              },
              "url": {
                "description": "The url for the layer",
                "type": "string"
              },
              "opacity": {
                "type": "number"
              }
            },
            "required": [
              "id",
              "Factory",
              "url"
            ]
          }
        }
      }
    },
    "minimumLegendSizes": {
      "type": "object",
      "properties": {
        "pointSize": {
          "type": "number"
        },
        "polylineWidth": {
          "type": "number"
        }
      },
      "required": [
        "pointSize",
        "polylineWidth"
      ]
    },
    "defaultExtent": {
      "type": "object",
      "properties": {
        "zoomLevel": {
          "type": "number"
        },
        "x": {
          "type": "number"
        },
        "y": {
          "type": "number"
        }
      },
      "required": [
        "zoomLevel",
        "x",
        "y"
      ]
    },
    "links": {
      "type": "object",
      "properties": {
        "landingPage": {
          "description": "This is the URL for the links on the logo (larger screens) and \"Wasatch Choice\" tab link (smaller screens)",
          "type": "string"
        }
      }
    }
  },
  "required": [
    "tabs",
    "sherlock",
    "layerSelector",
    "minimumLegendSizes",
    "defaultExtent",
    "links"
  ]
}

@trieloff
Copy link
Collaborator

It's having trouble with this:

"type": ["object", "string"],

You can refactor it to something like this (written directly in GitHub, not validated, so take it with a grain of salt):

"baseLayers": {
  "type": "array",
  "oneOf": [
  { "type": "string" },
  { "type": "object",
    "properties": {
      "id": {
        "description": "The name of the layer",
        "type": "string"
      },
      "Factory": {
        "description": "The name of the esrijs module associated with the layer type",
        "type": "string"
      },
      "urlTemplate": {
        "description": "The urlTemplate for the layer. \"{quadWord}\" will be automatically replaced with the appropriate value at runtime.",
        "type": "string"
      }
    },
    "required": [
      "id",
      "Factory",
      "urlTemplate"
    ]
  }}]
},

We can handle the oneOf or anyOf switches reasonably well, but support for the type arrays is limited to support for nullable properties like "type": ["string", "null"].

@trieloff trieloff changed the title Support Arrays as Value for Root Type Type Arrays not Supported Oct 18, 2019
@stdavis
Copy link
Author

stdavis commented Oct 21, 2019

I appreciate the workaround suggestion. I was able to refactor to something similar to your example and it's working better now.

Thanks!

stdavis added a commit to agrc/wfrc-wasatch-choice that referenced this issue Oct 21, 2019
@trieloff trieloff mentioned this issue Dec 11, 2019
7 tasks
trieloff pushed a commit that referenced this issue Dec 16, 2019
# [4.0.0](v3.3.1...v4.0.0) (2019-12-16)

### Bug Fixes

* **i18n:** use correct file name format ([43a74f4](43a74f4))
* **markdown:** constraint values can be zero now ([2e057fd](2e057fd))
* **markdown:** handle null as a constant value ([e652e11](e652e11))
* **proxy:** remove logging statements ([616a1d9](616a1d9))
* **schemas:** remove references going nowhere ([2186142](2186142))

### Build System

* **dependencies:** remove unused dependencies ([dbc9192](dbc9192))

### Code Refactoring

* **cli:** remove bluebird, lodash, simplify arg parsing ([b6b1822](b6b1822))

### Continuous Integration

* **test:** require node 10 ([ba4a947](ba4a947))

### Documentation

* **changelog:** mention changes for v4 ([4dfe90c](4dfe90c)), closes [#126](#126) [#174](#174) [#72](#72) [#73](#73) [#94](#94) [#52](#52) [#20](#20) [#125](#125) [#177](#177) [#34](#34) [#123](#123)

### Features

* **cli:** generate JSON schema output ([dd18f3b](dd18f3b)), closes [#176](#176)
* **formats:** add support for formats: json-pointer, relative-json-pointer, regex, and uri-template ([689c158](689c158))
* **i18n:** new internationalization system ([1a664de](1a664de))
* **i18n:** provide complete en_US translation ([5eb0c89](5eb0c89))
* **markdown:** add header surpression ([6225b9f](6225b9f))
* **markdown:** add support for `default` keyword ([72a0fde](72a0fde))
* **markdown:** add support for comments ([07bb52f](07bb52f))
* **markdown:** add YAML frontmatter support ([4df92e6](4df92e6))
* **markdown:** create and write markdown ([e521541](e521541))
* **markdown:** generate additional detail ([cc07df2](cc07df2))
* **markdown:** generate header again ([011427c](011427c))
* **markdown:** generate some property details ([fa34cf1](fa34cf1))
* **markdown:** generate type details ([c9f19e1](c9f19e1))
* **markdown:** highlight keyword usage for documentation ([d35e4ed](d35e4ed)), closes [#100](#100)
* **markdown:** list nested schemas in README ([608674b](608674b))
* **markdown:** list nested schemas in README ([87e8489](87e8489))
* **markdown:** show examples ([c8e8dfa](c8e8dfa))
* **markdown:** show extensibility and abstraction in header ([90a9a8e](90a9a8e))
* **markdown:** show id and status in header ([08e1923](08e1923))
* **markdown:** show id and status in header ([b6fcf53](b6fcf53))
* **markdown:** show join types ([12af018](12af018))
* **markdown:** show some info about properties, switch i18n library ([f8a32df](f8a32df))
* **markdown:** show type, link, additional and custom properties in header ([eff129a](eff129a))
* **markdown:** show value constraints ([515969c](515969c))
* **markdown:** support item arrays and additionalItems ([c9fbcdf](c9fbcdf)), closes [#31](#31)
* **markdown:** support patternProperties and additionalProperties ([1386ee3](1386ee3)), closes [#95](#95) [#180](#180)
* **proxy:** generate meta information ([ac65ac6](ac65ac6))
* **proxy:** generate slugs ([eacbf38](eacbf38))
* **proxy:** resolve references ([4cea068](4cea068))
* **readme:** generate readme again ([d6b9e5e](d6b9e5e))
* **readme:** mention the most common schema version ([fc583d7](fc583d7))
* **schema:** add full support for "A Vocabulary for the Contents of String-Encoded Data" ([96ca3a6](96ca3a6))
* **schema:** add support for keyword `$defs` ([70b63c8](70b63c8))
* **schema:** add support for keyword `deprecated` ([934b856](934b856))
* **schema:** add support for readOnly and writeOnly schemas and properties ([7452882](7452882))

### BREAKING CHANGES

* **changelog:**
* **i18n:** The file format for the i18n files has changed

You can now specify the language to use using `-l` and `jsonschema2md` will pick up the correct language configuration.
* **test:** Node 8 is no longer supported
* **dependencies:** Removes the JSON schema validation feature entirely
* **cli:** Repaces lodash with ferrum, removed bluebird, changes the meaning of `--schema-out` or `-x` to be no longer relative to output dir

The `--schema-out` or `-x` command line option is no longer relative to the output path (specified with `-o` or `--out`)
@trieloff
Copy link
Collaborator

🎉 This issue has been resolved in version 4.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants