diff --git a/changelogs/internal/newsfragments/2076.clarification b/changelogs/internal/newsfragments/2076.clarification new file mode 100644 index 00000000..3cf1fb94 --- /dev/null +++ b/changelogs/internal/newsfragments/2076.clarification @@ -0,0 +1 @@ +Support more locations for examples in OpenAPI definitions and JSON schemas. \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/2076.clarification b/changelogs/server_server/newsfragments/2076.clarification new file mode 100644 index 00000000..b3cad0d2 --- /dev/null +++ b/changelogs/server_server/newsfragments/2076.clarification @@ -0,0 +1 @@ +Remove an erroneous `room_id` field in a few examples. diff --git a/data/api/server-server/invites-v1.yaml b/data/api/server-server/invites-v1.yaml index c328f05e..7d241c37 100644 --- a/data/api/server-server/invites-v1.yaml +++ b/data/api/server-server/invites-v1.yaml @@ -75,22 +75,6 @@ paths: example: $ref: ../../event-schemas/examples/invite_room_state.json type: object - example: { - "room_id": "!somewhere:example.org", - "type": "m.room.member", - "state_key": "@joe:elsewhere.com", - "origin": "example.org", - "origin_server_ts": 1549041175876, - "sender": "@someone:example.org", - "content": { - "membership": "invite" - }, - "signatures": { - "example.com": { - "ed25519:key_version": "SomeSignatureHere" - }, - } - } required: true responses: "200": diff --git a/data/api/server-server/invites-v2.yaml b/data/api/server-server/invites-v2.yaml index 8984b6d1..f42c8eea 100644 --- a/data/api/server-server/invites-v2.yaml +++ b/data/api/server-server/invites-v2.yaml @@ -78,25 +78,6 @@ paths: required: - room_version - event - example: { - "room_version": "2", - "event": { - "room_id": "!somewhere:example.org", - "type": "m.room.member", - "state_key": "@joe:elsewhere.com", - "origin": "example.org", - "origin_server_ts": 1549041175876, - "sender": "@someone:example.org", - "content": { - "membership": "invite" - }, - "signatures": { - "example.com": { - "ed25519:key_version": "SomeSignatureHere" - }, - } - } - } required: true responses: "200": diff --git a/data/api/server-server/joins-v2.yaml b/data/api/server-server/joins-v2.yaml index bb45b1be..91e6a83e 100644 --- a/data/api/server-server/joins-v2.yaml +++ b/data/api/server-server/joins-v2.yaml @@ -140,7 +140,6 @@ paths: - type - content example: { - "room_id": "!somewhere:example.org", "type": "m.room.member", "state_key": "@someone:example.org", "origin": "example.org", diff --git a/data/api/server-server/knocks.yaml b/data/api/server-server/knocks.yaml index cba9d32b..01bfa637 100644 --- a/data/api/server-server/knocks.yaml +++ b/data/api/server-server/knocks.yaml @@ -270,7 +270,6 @@ paths: - type - content example: { - "room_id": "!somewhere:example.org", "type": "m.room.member", "state_key": "@someone:example.org", "origin": "example.org", diff --git a/layouts/partials/events/example.html b/layouts/partials/events/example.html index 90752fbd..c24cd66b 100644 --- a/layouts/partials/events/example.html +++ b/layouts/partials/events/example.html @@ -13,10 +13,4 @@ {{ $path := delimit (slice "event-schemas/examples" .name) "/" }} {{ $example_content := partial "json-schema/resolve-refs" (dict "schema" .schema "path" $path) }} -{{ $example_json := jsonify (dict "indent" " ") $example_content }} -{{ $example_json = replace $example_json "\\u003c" "<" }} -{{ $example_json = replace $example_json "\\u003e" ">" | safeHTML }} - -```json -{{ $example_json }} -``` +{{ partial "render-example" (dict "example" $example_content) }} diff --git a/layouts/partials/json-schema/resolve-example.html b/layouts/partials/json-schema/resolve-example.html deleted file mode 100644 index 8fa98400..00000000 --- a/layouts/partials/json-schema/resolve-example.html +++ /dev/null @@ -1,46 +0,0 @@ -{{/* - - For complex objects, example content is sometimes attached to the - object's individual properties (and subproperties...), so to get - a complete example for the whole object we need to iterate through - its properties (and subproperties...) and assemble them. - - That's what this template does. - -*/}} - -{{ $this_object := . }} - -{{ $example := $this_object.example }} - -{{ if not $example }} - - {{ if eq $this_object.type "object" }} - {{ $example = dict }} - - {{ range $key, $property := $this_object.properties}} - {{ $this_property_example := partial "json-schema/resolve-example" $property }} - {{ if $this_property_example }} - {{ $example = merge (dict $key $this_property_example) $example }} - {{ end }} - {{ end }} - - {{ else if eq $this_object.type "array" }} - - {{/* the "items" within an array can either be an object (where we have a - list of items which match the schema), or a list (for tuple - validation, where each item has a different schema). - - TODO: support tuple validation here. - */}} - {{ if reflect.IsMap $this_object.items }} - {{ $items_example := partial "json-schema/resolve-example" $this_object.items }} - {{ if $items_example }} - {{ $example = slice $items_example }} - {{ end }} - {{ end }} - {{ end }} - -{{ end }} - -{{ return $example }} diff --git a/layouts/partials/json-schema/resolve-examples.html b/layouts/partials/json-schema/resolve-examples.html new file mode 100644 index 00000000..dd126540 --- /dev/null +++ b/layouts/partials/json-schema/resolve-examples.html @@ -0,0 +1,71 @@ +{{/* + + Find examples in the given JSON schema. + + Tries to find examples in the `examples` and `example` keys of the schema + first. + + If it doesn't succeed, iterates through the properties and subproperties to + collect their examples, to merge them into a complete example for the whole + object. + + Parameter: the JSON schema to extract the examples from. + +*/}} + +{{ $this_object := . }} +{{ $examples := slice }} + +{{ if $this_object.examples }} + {{/* This is an array of examples, we can just use it */}} + {{ $examples = $this_object.examples }} +{{ else if $this_object.example }} + {{ $examples = slice $this_object.example }} +{{ else }} + {{/* Resolve the nested examples */}} + {{ if eq $this_object.type "object" }} + {{ $example := dict }} + + {{ range $key, $property := $this_object.properties}} + {{ $this_property_examples := partial "json-schema/resolve-examples" $property }} + {{/* + It would be too complex to handle several nested examples, + just use the first one. + */}} + {{ with index $this_property_examples 0 }} + {{ $example = merge (dict $key .) $example }} + {{ end }} + {{ end }} + + {{/* + Add the assembled example to the list if either (a) the example is + non-empty, or (b) the object itself is meant to be empty (so an + empty example is correct). + */}} + {{ if (or $example (not $this_object.properties)) }} + {{ $examples = slice $example }} + {{ end }} + + {{ else if eq $this_object.type "array" }} + + {{/* the "items" within an array can either be an object (where we have a + list of items which match the schema), or a list (for tuple + validation, where each item has a different schema). + + TODO: support tuple validation here. + */}} + {{ if reflect.IsMap $this_object.items }} + {{ $items_examples := partial "json-schema/resolve-examples" $this_object.items }} + {{/* + It would be too complex to handle several nested examples, + just use the first one. + */}} + {{ with index $items_examples 0 }} + {{ $examples = slice (slice .) }} + {{ end }} + {{ end }} + {{ end }} + +{{ end }} + +{{ return $examples }} diff --git a/layouts/partials/openapi/render-media-type-objects.html b/layouts/partials/openapi/render-media-type-objects.html new file mode 100644 index 00000000..7c48320e --- /dev/null +++ b/layouts/partials/openapi/render-media-type-objects.html @@ -0,0 +1,104 @@ +{{/* + + Render a map of [Media Type Objects](https://spec.openapis.org/oas/v3.1.1#media-type-object). + This map can be found as the `content` field of requests and responses. + + Parameters: + + * `content`: A map of MIME type to Media Type Object + * `kind`: the kind of object that is rendered, either `request` or `response`. + * `anchor_base`: a prefix to add to the HTML anchors generated for each object + + This template renders: + + * Object tables if the map contains an `application/json` MIME type, or a + table with the MIME types and the corresponding description of the object. + * The examples of the Media Type Objects. + +*/}} + +{{/* + Request and response bodies can have several content types. If there is a + JSON type, we display that; otherwise we just show the content types and + descriptions. +*/}} +{{ $json_body := index .content "application/json" }} +{{ if $json_body }} + {{/* + Display the JSON schemas + */}} + + {{ $schema := $json_body.schema }} + + {{/* + All this is to work out how to express the content of the response + in the case where it is an array. + */}} + {{ if eq $schema.type "array" }} + {{ $type_of := "" }} + {{ if $schema.items.anyOf }} + {{ $types := slice }} + {{ range $schema.items.anyOf }} + {{ if .title }} + {{ $types = $types | append .title}} + {{ else }} + {{ $types = $types | append .type }} + {{ end }} + {{ end }} + {{ $type_of = delimit $types ", "}} + {{ else }} + {{ $type_of = $schema.items.title }} + {{ end }} +
Array of {{ $type_of }}
.
Array of {{ $type_of }}
.