{{/* Render a table listing the properties of an object, given: * `title`: optional caption for the table * `anchor`: optional HTML element id for the table * `properties`: optional dictionary of the properties to list, each given as: `property_name` : `property_data` * `additionalProperties`: optional dictionary for properties with undefined names, in the same format as `property_data` * `patternProperties`: optional dictionary for properties with names adhering to a regex pattern, in the same format as `property_data` * `required`: optional array containing the names of required properties. In some cases (such as response body specifications) this isn't used, and instead properties have a `required` boolean attribute. We support this too. */}} {{ $title := .title }} {{ $properties := .properties}} {{ $required := .required}} {{ if $properties }} {{ with $title }} {{ . }} {{ end }} Name Type Description {{ range $property_name, $property := $properties }} {{ $property := partial "json-schema/resolve-allof" $property }} {{/* Handle two ways of indicating "required", one for simple parameters, the other for request and response body objects. */}} {{ $required := cond (or (in $required $property_name) ( eq $property.required true )) true false }} {{ $property_name }} {{ partial "partials/property-type" $property }} {{ partial "partials/property-description" (dict "property" $property "required" $required) }} {{ end }} {{ else if (or .additionalProperties .patternProperties) }} {{ with $title }} {{ . }} {{ end }} Type Description {{ $property := partial "json-schema/resolve-allof" . }} {{ partial "partials/property-type" $property }} {{ partial "partials/property-description" (dict "property" $property) }} {{ end }} {{/* Computes the type to display for a property, given: * `type`: string or array of strings for the type(s) of the property * `title`: optional string for the title of the property * `oneOf`: optional array of dictionaries describing the different formats that the property can have * `additionalProperties`: optional dictionary for properties with undefined names * `patternProperties`: optional dictionary for properties with names adhering to a regex pattern * `items`: if the type is an array, array of dictionaries describing the format of the array's items * `anchor`: optional HTML element id for the target type, which will be used to link to it. */}} {{ define "partials/property-type" }} {{ $type := .type }} {{ if or (eq .type "object") (and .oneOf (reflect.IsSlice .oneOf)) }} {{ $type = partial "type-or-title" . }} {{ end }} {{/* If the property is an array, indicate this with square brackets, like `[type]`. */}} {{ if eq .type "array"}} {{ $items := .items }} {{ if .items }} {{ $items = partial "json-schema/resolve-allof" .items }} {{ end }} {{ $inner_type := partial "type-or-title" $items }} {{ $type = delimit (slice "[" $inner_type "]") "" }} {{ end }} {{ return $type }} {{ end }} {{/* Computes the type to display for a property's schema, given: * `type`: string or array of strings for the type(s) of the property * `title`: optional string for the title of the property * `oneOf`: optional array of dictionaries describing the different formats that the property can have * `additionalProperties`: optional dictionary for properties with undefined names * `patternProperties`: optional dictionary for properties with names adhering to a regex pattern * `anchor`: optional HTML element id for the target type, which will be used to link to it. The title has a higher priority than anything else. */}} {{ define "partials/type-or-title" }} {{ $type := "" }} {{ if .title }} {{/* If the property has a `title`, use that rather than `type`. This means we can write things like `EventFilter` rather than `object`. */}} {{ $type = .title }} {{ if .anchor }} {{ $type = printf "%s" (htmlEscape .anchor) (htmlEscape $type) | safeHTML }} {{ end }} {{ else if reflect.IsMap .additionalProperties }} {{/* If the property uses `additionalProperties` to describe its internal structure, handle this with a bit of recursion */}} {{ $additionalProperties := partial "json-schema/resolve-allof" .additionalProperties }} {{ $type = delimit (slice "{string: " (partial "property-type" $additionalProperties) "}" ) "" }} {{ else if reflect.IsMap .patternProperties }} {{/* If the property uses `patternProperties` to describe its internal structure, handle this with a bit of recursion. Note that we ignore the pattern as the current definitions always have a single pattern, but we might need to handle them later to differentiate schemas according to patterns. */}} {{ $types := slice }} {{ range $pattern, $schema := .patternProperties}} {{ $schema = partial "json-schema/resolve-allof" $schema }} {{ $types = $types | append (partial "property-type" $schema) }} {{ end }} {{ $type = delimit (slice "{string: " (delimit $types "|") "}" ) "" }} {{ else if reflect.IsSlice .type }} {{/* It's legal to specify an array of types. Join them together in that case */}} {{ $types := slice }} {{ range .type }} {{ $types = $types | append . }} {{ end }} {{ $type = delimit $types "|" }} {{ else if and .oneOf (reflect.IsSlice .oneOf) }} {{/* This is like an array of types except some of the types probably have a schema. Join them together too. */}} {{ $types := slice }} {{ range .oneOf }} {{ $types = $types | append (partial "type-or-title" .) }} {{ end }} {{ $type = delimit $types "|" }} {{ else }} {{ $type = .type }} {{ end }} {{ return $type }} {{ end }} {{/* Computes the description to display for a property, given: * `required`: boolean indicating whether this property is required. * `property`: dictionary describing the property's data, with these fields: * `description`: string describing the property * `enum`: optional array indicating the accepted values for the property * `x-addedInMatrixVersion`: optional string indicating in which Matrix spec version this property was added. * `x-changedInMatrixVersion`: optional string indicating in which Matrix spec version this property was last changed. */}} {{ define "partials/property-description" }} {{ if .required }}Required: {{end -}} {{ .property.description | markdownify -}} {{ if .property.enum }}

One of: [{{ delimit .property.enum ", " }}].

{{ end -}} {{ if (index .property "x-addedInMatrixVersion") }}{{ partial "added-in" (dict "v" (index .property "x-addedInMatrixVersion")) }}{{ end -}} {{ if (index .property "x-changedInMatrixVersion") }}{{ partial "changed-in" (dict "changes_dict" (index .property "x-changedInMatrixVersion")) }}{{ end -}} {{ end }}