matrix-spec/layouts/partials/openapi/render-object-table.html
David Robertson c69ac3bb68
Present OpenAPI additionalProperties field
When looking at the "Authentication Data" type used in e.g. the account
deactivation endpoint

    https://spec.matrix.org/v1.3/client-server-api/#post_matrixclientv3accountdeactivate

it was not clear to me that clients and servers should expect additional
fields in this structure (the semantics of which are implied by the
`type` of the authentication, or that of the previously established
`session`.)

In the OpenAPI spec, We occasionally mark some ojects as allowing
arbitrary additional properties (`additionalProperties: true`, or
`additionalProperties: { description: "..."}`). In other places we are
more strict and provide a schema that additional properties must satisfy.
In this PR we aim to make the first kind of additional
properties (non-strict) more visible in the rendered spec.
2022-07-04 21:24:56 +01:00

123 lines
4.4 KiB
HTML

{{/*
Render a table listing the properties of an object, given:
* `caption`: optional caption for the table
* `properties`: dictionary of the properties to list, each given as:
`property_name` : `property_data`
* `required`: 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.
*/}}
{{ $caption := .caption }}
{{ $properties := .properties}}
{{ $required := .required}}
{{ $additionalProperties := .additionalProperties }}
{{ if $properties }}
<table class>
{{ with $caption }}
<caption>{{ . }}</caption>
{{ end }}
<thead>
<th class="col-name">Name</th>
<th class="col-type">Type</th>
<th class="col-description">Description</th>
</thead>
{{ range $property_name, $property := $properties }}
{{ $property := partial "json-schema/resolve-allof" $property }}
{{/*
If the property has a `title`, use that rather than `type`.
This means we can write things like `EventFilter` rather than `object`.
*/}}
{{ $type := $property.type}}
{{ if $property.title }}
{{ $type = $property.title }}
{{ end }}
{{/*
If the property is an array, indicate this with square brackets,
like `[type]`.
*/}}
{{ if eq $type "array"}}
{{ $items := $property.items }}
{{ if $property.items }}
{{ $items = partial "json-schema/resolve-allof" $property.items }}
{{ end }}
{{ $inner_type := $items.type }}
{{ if $items.title }}
{{ $inner_type = $items.title }}
{{ end }}
{{ $type = delimit (slice "[" $inner_type "]") "" }}
{{ end }}
{{/*
If the property is an enum, indicate this.
*/}}
{{ if (and (eq $type "string") ($property.enum)) }}
{{ $type = "enum" }}
{{ end }}
{{/*
If the property uses `additionalProperties` to describe its
internal structure, handle this.
*/}}
{{ if reflect.IsMap $property.additionalProperties }}
{{ if $property.additionalProperties.title }}
{{ $type = delimit (slice "{ string: " $property.additionalProperties.title "}" ) "" }}
{{ end }}
{{ end }}
{{/*
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 }}
<tr>
<td><code>{{ $property_name }}</code></td>
<td><code>{{ $type }}</code></td>
<td>
{{ if $required }}<strong>Required: </strong>{{end -}}
{{ $property.description | markdownify -}}
{{ if eq $type "enum"}}<p>One of: <code>{{ $property.enum }}</code>.</p>{{ 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 -}}
</td>
</tr>
{{ end }}
{{/* NB: the OpenAPI spec says "Consistent with JSON Schema, additionalProperties
defaults to true." Our schemas tend to omit additionalProperties; I think we
effectively assume it defaults to false. Therefore: we only output regarding
additionalProperties if it is explicitly set (i.e. is non-nil). */}}
{{ if (ne $additionalProperties nil )}}
<tr class="row-additional-properties">
<td colspan="3">
{{ if (and (reflect.IsMap $additionalProperties)) -}}
{{ if (index $additionalProperties "description") -}}
May have additional properties: {{ $additionalProperties.description }}
{{ end }}
{{/* TODO: should we handle the case where additional properties are permitted,
but must follow an explicit schema? */}}
{{ else if $additionalProperties -}}
May have additional properties.
{{ else if (not $additionalProperties) -}}
{{/* At present we don't have any schema with additionalProperties: false.
But if we ever do, let's support it. */}}
May **not** have additional properties.
{{ end }}
</td>
</tr>
{{ end }}
</table>
{{ end }}