stoplightio / elements

Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown.
https://stoplight.io/open-source/elements/
Apache License 2.0
1.79k stars 206 forks source link

Schemas of prefixItems in tuple validated arrays don't display nested. #2229

Open blockjoe opened 2 years ago

blockjoe commented 2 years ago

JSON Schema allows for declaring fixed size, mixed type arrays that function similarly to something like a Tuple.

More details of this can be found here.

Context

Given that arrays of a single object type display the schema of containing elements (what @stoplight/json-schema-viewer calls ComplexArrays), it would be very helpful to have this same context for Tuple validated arrays.

Current Behavior

As of now, the following request body schema:

"request_body": {
  "required": true,
  "content": {
    "application/json": {
      "schema": {
    "title": "eth_getBlockByHashRequest",
    "type": "object",
    "required": [
      "jsonrpc",
      "method",
      "params",
      "id"
    ],
    "properties": {
      "jsonrpc": {
        "title": "jsonrpc version",
        "type": "string",
        "enum": [
          "2.0"
        ]
      },
      "method": {
        "title": "RPC Method Name",
        "type": "string",
        "enum": [
          "eth_getBlockByHash"
        ]
      },
      "params": {
        "title": "Needed RPC Params",
        "type": "array",
        "prefixItems": [
          {
        "title": "Block hash",
        "type": "string",
        "pattern": "^0x([0-9a-f][0-9a-f]){0,32}$"
          },
          {
        "title": "Hydrated transactions",
        "type": "boolean"
          }
        ],
        "minItems": 2,
        "maxItems": 2
      },
      "id": {
        "title": "RPC Request ID",
        "type": "integer"
      }
    }
      }
    }
  },
  "description": ""
}

current

This also means that the TryIt component doesn't use the schema of the prefixItems to pre-popluate the array with anything. I'm not sure if addressing this would mean that these changes would propagate through anything else that takes this node data, or if there's another layer of complexity there that also might need to be addressed.

Expected Behavior

It would be great to see something similar to the following:

├── jsonrpc - string
│     Allowed value: 2.0
├── method - string
│     Allowed value: eth_getBlockByHash
├── params - array
│   ├── string
│   │      Match pattern: "^0x([0-9a-f][0-9a-f]){0,32}$"
│   └── boolean
│   >= 2 items; <= 2 items
└── id integer

where the schemas of prefixItems are displayed in the order that they're referenced.

Possible Solution(s)

I'm pretty sure that there needs to at least be an additional case in this part of json-schema-viewer, but I'm not really sure how handle the prefixItems part of the schema, as its something that doesn't look like it's parsed at the node level.

mnaumanali94 commented 2 years ago

@blockjoe This is a good enhancement. Would you mind creating a PR? The team would really appreciate that.

blockjoe commented 2 years ago

@blockjoe This is a good enhancement. Would you mind creating a PR? The team would really appreciate that.

I'd be happy to submit a PR. The only thing I wasn't sure of is where exactly in your stack this would happen.

Is it safe to assume that the prefixItems will be accessible from the context that gets passed to the React components? Or is there somewhere that this field needs to be parsed before it becomes accessible?

dschnare commented 1 year ago

I ran into this limitation today myself. Although I needed prefixItems and items to work together.

schema:
  type: object
  properties:
    myList:
       type: array
       example: [ [{ value: 'my-header' }, { value: 'my-header' }], ['row 1 value', 'row 1 other value'], ['row 2 value', row 2 other value'] ]
       prefixItems:
         - type: array
            items:
              type: object
              properties:
                value:
                  type: string
       items:
         type: array
         items:
           type: string

So to be complete there would have to be support for items in the context of prefixItems as well (e.g. if items was set to false meaning no additional items are allowed besides those defined by prefixItems).

myList array[prefixed]
  [0] array [object]
      value  string
  [n+1] array [string]

Where n+1 would be n+2 if prefixItems was length 2.

Then if items was not set or set to false:

myList array[tuple]
  [0] array [object]
      value  string
dschnare commented 1 year ago

It looks like this would involve modifying @stoplight/json-schema-viewe, @stoplight/json-tree and possibly @stoplight/elements-core. I'll have to come back to this just don't have the time to dive further unfortunately.