You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
6.1 KiB
HTML
153 lines
6.1 KiB
HTML
{{/*
|
|
|
|
Finds and returns all nested objects, given a dict containing:
|
|
* `schema`: a JSON schema object
|
|
* `anchor_base`: a prefix to add to the HTML anchors generated for each object. If nil, no anchors are generated.
|
|
* `name`: optionally, a name to use for this object in error/warning messages. If left unset,
|
|
the object's `title` property is used (if present).
|
|
|
|
This template finds all nested objects inside `schema`.
|
|
|
|
Assumes that "resolve-refs" and "resolve-allof" has already been called on the
|
|
input schema.
|
|
|
|
Returns a pair [$updated_definition, $additional_objects], where:
|
|
|
|
$updated_definition: Largely the same as the provided `schema`, except for the addition of an `anchor` property
|
|
for any objects we decided to generate anchors for.
|
|
|
|
For objects, this is the same as the first entry in `$additional_objects`.
|
|
|
|
$additional_objects is an array of all the objects found. For each object, the following properties are returned:
|
|
* title
|
|
* properties
|
|
* required
|
|
* enum
|
|
* anchor: a string suitable for using as an html anchor for this object (if `anchor_base` was set, and the object has a title)
|
|
|
|
Note that the returned array may contain duplicate objects.
|
|
|
|
*/}}
|
|
|
|
{{ $this_object := .schema }}
|
|
{{ $anchor_base := .anchor_base }}
|
|
{{ $additional_objects := slice }}
|
|
{{ $name := .name | default $this_object.title | default "<untitled object>" }}
|
|
|
|
{{ if eq $this_object.type "object" }}
|
|
{{/* give this object an anchor, if it has a name */}}
|
|
{{ if (and $anchor_base $this_object.title) }}
|
|
{{ $this_object = merge $this_object (dict "anchor" (printf "%s_%s" $anchor_base (anchorize $this_object.title))) }}
|
|
{{ end }}
|
|
|
|
{{/*
|
|
Add any nested objects referenced in this object's `additionalProperties`
|
|
*/}}
|
|
{{ if $this_object.additionalProperties }}
|
|
{{ if reflect.IsMap $this_object.additionalProperties }}
|
|
{{ $res := partial "get-additional-objects" (dict
|
|
"this_object" $this_object.additionalProperties
|
|
"anchor_base" $anchor_base
|
|
"name" (printf "%s.additional" $name)
|
|
) }}
|
|
{{/* appending an empty slice messes up the types and confuses go, so only do the append if $more_objects is non-empty */}}
|
|
{{ with $more_objects := index $res 1 }}
|
|
{{ $additional_objects = $additional_objects | append $more_objects }}
|
|
{{ end }}
|
|
|
|
{{/* update the object definition with any updates from the additional properties */}}
|
|
{{ $this_object = merge $this_object (dict "additionalProperties" (index $res 0)) }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{/*
|
|
Add any nested objects referenced in this object's `properties`
|
|
*/}}
|
|
{{ $updated_properties := dict }}
|
|
{{ range $key, $property := $this_object.properties}}
|
|
{{ $res := partial "get-additional-objects" (dict
|
|
"this_object" $property
|
|
"anchor_base" $anchor_base
|
|
"name" (printf "%s.%s" $name $key)
|
|
) }}
|
|
{{ with $more_objects := index $res 1 }}
|
|
{{ $additional_objects = $additional_objects | append $more_objects }}
|
|
{{ end }}
|
|
{{ $updated_properties = merge $updated_properties (dict $key (index $res 0)) }}
|
|
{{ end }}
|
|
|
|
{{/* update the object definition with any updates from the properties */}}
|
|
{{ $this_object = merge $this_object (dict "properties" $updated_properties) }}
|
|
|
|
{{/*
|
|
Add the updated object to the front of the $additional_objects array
|
|
*/}}
|
|
{{ $res := slice (partial "clean-object" $this_object) }}
|
|
{{ if $additional_objects }}
|
|
{{ $res = $res | append $additional_objects }}
|
|
{{ end }}
|
|
{{ $additional_objects = $res }}
|
|
{{ end }}
|
|
|
|
{{ if eq $this_object.type "array" }}
|
|
{{/*
|
|
Add any nested objects referenced in this object's `items`
|
|
*/}}
|
|
{{ if reflect.IsSlice $this_object.items}}
|
|
{{ range $idx, $item := $this_object.items }}
|
|
{{ $res := partial "get-additional-objects" (dict
|
|
"this_object" $item
|
|
"anchor_base" $anchor_base
|
|
"name" (printf "%s.items[%d]" $name $idx)
|
|
) }}
|
|
{{ with $more_objects := index $res 1 }}
|
|
{{ $additional_objects = $additional_objects | append $more_objects }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ else if reflect.IsMap $this_object.items}}
|
|
{{ $res := partial "get-additional-objects" (dict
|
|
"this_object" $this_object.items
|
|
"anchor_base" $anchor_base
|
|
"name" (printf "%s.items" $name)
|
|
) }}
|
|
{{ with $more_objects := index $res 1 }}
|
|
{{ $additional_objects = $additional_objects | append $more_objects }}
|
|
{{ end }}
|
|
{{ $this_object = merge $this_object (dict "items" (index $res 0)) }}
|
|
{{ else }}
|
|
{{ errorf "%s is defined as an 'array' but lacks a valid 'items'" $name }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{ return slice $this_object $additional_objects }}
|
|
|
|
|
|
{{/*
|
|
This actually makes the recursive call, and returns the new objects
|
|
*/}}
|
|
{{ define "partials/get-additional-objects" }}
|
|
{{/* .name is the name of the object for logging purposes */}}
|
|
{{ $name := .name }}
|
|
|
|
{{ if not (reflect.IsMap .this_object) }}
|
|
{{ errorf "Invalid call to partials/get-additional-objects: %s is not a map" $name .this_object }}
|
|
{{ end }}
|
|
|
|
/* although we expect resolve-allof to be called on the input, resolve-allof does not recurse into
|
|
* nested objects, so we have to call it again.
|
|
*/
|
|
{{ $this_object := partial "json-schema/resolve-allof" .this_object }}
|
|
|
|
{{ $more_objects := partial "json-schema/resolve-additional-types" (dict "schema" $this_object "anchor_base" .anchor_base "name" $name) }}
|
|
{{ return $more_objects }}
|
|
{{ end }}
|
|
|
|
{{/*
|
|
Only copy the bits of the object that we actually care about.
|
|
This is needed for uniqify to work - otherwise objects that are the same
|
|
but with (for example) different examples will be considered different.
|
|
*/}}
|
|
{{ define "partials/clean-object" }}
|
|
{{ return (dict "title" .title "properties" .properties "required" .required "enum" .enum "anchor" .anchor) }}
|
|
{{ end }}
|