src/Generator/Twig/json-schema/macros.twig
{#
Render schema block
Parameters:
schema - a SchemaDescriptor instance
compile_options - a compile_options instance
#}
{% macro draw_schema(schema, compile_options) %}
{% set fields = schema.inheritedFields|merge(schema.fields) %}
{
"id": "{{ compile_options.domain }}/json-schema/{{ schema.id.vendor }}/{{ schema.id.package }}/{% if schema.id.category %}{{ schema.id.category }}/{% endif %}{{ schema.id.message }}/{{ schema.id.version }}.json#",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
{% if not schema.isMixinSchema %}
"_schema": {
"type": "string",
"pattern": "^pbj:([a-z0-9-]+):([a-z0-9\\.-]+):([a-z0-9-]+)?:([a-z0-9-]+):([0-9]+-[0-9]+-[0-9]+)$",
"default": "{{ schema.id }}"
},
{% endif %}
{% for field in fields %}
{{ _self.draw_field(field) }}{% if not loop.last or schema.mixins|length %},{% endif %}
{% endfor %}
},
{% set required = [] %}
{% if not schema.isMixinSchema %}
{% set required = required|merge(['_schema']) %}
{% endif %}
{% for field in fields %}
{% if field.required %}
{% set required = required|merge([field.name]) %}
{% endif %}
{% endfor %}
{% if required|length %}
"required": [{% for field in required %}"{{ field }}"{% if not loop.last %}, {% endif %}{% endfor %}],
{% endif %}
{% set defs = [] %}
{% for field in fields %}
{% if field.anyOf %}
{% set defs = defs|merge(field.anyOf) %}
{% endif %}
{% endfor %}
{% if defs|length %}
"definitions": {
{% set shown = [] %}
{% for def in defs %}
{% if def.id not in shown %}
"{{ def.id.message|lower|slugify }}": {
"type": "object",
"anyOf": [
{% for s in get_all_versions(def) %}
{"$ref": "{{ compile_options.domain }}/json-schema/{{ s.id.vendor }}/{{ s.id.package }}/{% if s.id.category %}{{ s.id.category }}/{% endif %}{{ s.id.message }}/{{ s.id.version }}.json#" }{% if not loop.last %}, {% endif %}
{% endfor %}
]
}{% if not loop.last %}, {% endif %}
{% set shown = shown|merge([def.id]) %}
{% endif %}
{% endfor %}
},
{% endif %}
"additionalProperties": {% if schema.isMixinSchema %}true{% else %}false{% endif %}
}
{% endmacro %}
{#
Render field block
Parameters:
field - a FieldDescriptor instance
#}
{% macro draw_field(field) %}
"{{ field.name }}": {
{% if field.rule ~ '' == 'map' %}
"type": "object",
"patternProperties": {
"^[a-zA-Z_]{1}[\\w\\.:-]+$": {
{{ _self.draw_field_properties(field) }}
}
},
{% if field.required %}
"minProperties": 1,
{% endif %}
"additionalProperties": false,
{% elseif field.rule ~ '' in ['list', 'set'] %}
"type": "array",
"items": [
{% if field.anyOf %}
{% for schema in field.anyOf %}
{ "$ref": "#/definitions/{{ schema.id.message|lower|slugify }}" }{% if not loop.last %}, {% endif %}
{% endfor %}
{% else %}
{ {{ _self.draw_field_properties(field) }} }
{% endif %}
],
{% if field.rule ~ '' == 'set' %}
"uniqueItems": true,
{% endif %}
{% if field.required %}
"minItems": 1,
{% endif %}
"additionalProperties": false,
{% else %}
{{ _self.draw_field_properties(field) }}
{% endif %}
{% if field.description %}
"description": "{{ field.description|reduce_spaces|replace({'"': '\\"'}) }}",
{% endif %}
"pbj": {
"type": "{{ field.type.typeName }}",
{% if field.rule %}
"rule": "{{ field.rule }}",
{% endif %}
{% if field.format %}
"format": "{{ field.format }}",
{% endif %}
{% if field.precision %}
"precision": {{ field.precision }},
{% endif %}
{% if field.scale %}
"scale": {{ field.scale }},
{% endif %}
{% if not field.useTypeDefault %}
"useTypeDefault": false,
{% endif %}
{% if field.overridable %}
"overridable": true,
{% endif %}
}
}
{% endmacro %}
{#
Render field properties
Parameters:
field - a FieldDescriptor instance
#}
{% macro draw_field_properties(field) %}
{% if field.type.typeName ~ '' == 'message-ref' %}
{{ _self.draw_message_ref_properties() }}
{% elseif field.type.typeName ~ '' == 'geo-point' %}
{{ _self.draw_geo_point_properties() }}
{% elseif field.type.typeName ~ '' == 'dynamic-field' %}
{{ _self.draw_dynamic_field_properties() }}
{% elseif field.type.typeName ~ '' in ['decimal', 'float'] %}
"type": "number",
{% elseif field.type.typeName ~ '' in [
'big-int', 'int-enum', 'int', 'medium-int',
'signed-big-int', 'signed-big-int', 'signed-medium-int',
'signed-small-int', 'signed-tiny-int', 'small-int',
'timestamp', 'tiny-int', 'trinary'
] %}
"type": "integer",
{% elseif field.type.typeName ~ '' in ['boolean'] %}
"type": "boolean",
{% elseif field.type.typeName ~ '' in ['date', 'message'] %}
"type": "object",
{% else %}
"type": "string",
{% endif %}
{% if
field.default|default(field.type.default) is not empty
and field.type.typeName ~ '' not in ['microtime', 'timestamp', 'uuid', 'time-uuid']
%}
"default": {{ field.default|default(field.type.default)|json_encode }},
{% endif %}
{% if field.format ~ '' in ['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri'] %}
"format": "{{ field.format ~ '' }}",
{% elseif field.type.typeName ~ '' == 'date-time' %}
"format": "date-time",
{% endif %}
{% set hasPattern =
field.format ~ '' in ['date-time', 'email', 'hostname', 'ipv4', 'ipv6', 'uri']
or field.type.typeName ~ '' in ['date-time', 'message-ref', 'geo-point']
%}
{% if field.pattern %}
{% set hasPattern = true %}
"pattern": "{{ field.pattern|replace({'\\': '\\\\'}) }}",
{% elseif field.type.typeName ~ '' in ['uuid', 'time-uuid'] %}
{% set hasPattern = true %}
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
{% elseif field.type.typeName ~ '' == 'identifier' %}
{% set hasPattern = true %}
"pattern": "^[\\w\\/\\.:-]+$",
{% elseif field.type.typeName ~ '' == 'microtime' %}
{% set hasPattern = true %}
"pattern": "^[1-9]{1}[0-9]{12,15}$",
{% elseif field.type.typeName ~ '' == 'date' %}
{% set hasPattern = true %}
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
{% elseif field.format ~ '' == 'url' %}
{% set hasPattern = true %}
"pattern": "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$",
{% elseif field.format ~ '' == 'slug' %}
"pattern": "^([\\w\\/-]|[\\w-][\\w\\/-]*[\\w-])$",
{% endif %}
{% if field.enum %}
"enum": [
{% set uniqueValues = [] %}
{% for value in field.enum.values %}
{% if value not in uniqueValues %}
{{ value|json_encode }},
{% set uniqueValues = uniqueValues|merge([value]) %}
{% endif %}
{% endfor %}
],
{% endif %}
{% if not field.enum and not hasPattern %}
{% if field.type.typeName ~ '' in ['string', 'text', 'medium-text'] %}
{% set minLength = field.minLength|default(0) %}
{% if '' ~ minLength not in ['INF', 'NAN'] %}
"minLength": {{ minLength }},
{% endif %}
{% set maxLength = field.maxLength|default(field.type.maxBytes) %}
{% if '' ~ maxLength not in ['INF', 'NAN'] %}
"maxLength": {{ maxLength }},
{% endif %}
{% elseif field.type.typeName ~ '' not in ['boolean', 'date', 'decimal', 'dynamic-field', 'float', 'geo-point', 'message-ref', 'message'] %}
{% set min = field.min|default(field.type.min) %}
{% if '' ~ min not in ['INF', 'NAN'] %}
"minimum": {{ min }},
{% endif %}
{% set max = field.max|default(field.type.max) %}
{% if '' ~ max not in ['INF', 'NAN'] %}
"maximum": {{ max }},
{% endif %}
{% endif %}
{% endif %}
{% if field.anyOf %}
"anyOf": [
{% for schema in field.anyOf %}
{ "$ref": "#/definitions/{{ schema.id.message|lower|slugify }}" }{% if not loop.last %}, {% endif %}
{% endfor %}
],
{% endif %}
{% if field.language('json-schema').get('faker') %}
"faker": "{{ field.language('json-schema').get('faker') }}",
{% endif %}
{% endmacro %}
{% macro draw_message_ref_properties() %}
"type": "object",
"properties": {
"curie": {
"type": "string",
"pattern": "^([a-z0-9-]+):([a-z0-9\\.-]+):([a-z0-9-]+)?:([a-z0-9-]+)$",
"minLength": 0,
"maxLength": 146
},
"id": {
"type": "string",
"pattern": "^[A-Za-z0-9:_\\-]+$",
"minLength": 0,
"maxLength": 255
},
"tag": {
"type": "string",
"pattern": "^([\\w\\/-]|[\\w-][\\w\\/-]*[\\w-])$",
"minLength": 0,
"maxLength": 255
}
},
"required": ["curie", "id"],
"additionalProperties": false,
{% endmacro %}
{% macro draw_geo_point_properties() %}
"type": "object",
"properties": {
"type": {
"type": "string",
"pattern": "^Point$"
},
"coordinates": {
"type": "array",
"items": [
{
"required": true,
"type": "number",
"minimum": -180,
"maximum": 180
},
{
"required": true,
"type": "number",
"minimum": -90,
"maximum": 90
}
]
}
},
"required": ["type", "coordinates"],
"additionalProperties": false,
{% endmacro %}
{% macro draw_dynamic_field_properties() %}
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"bool_val": {
"type": "boolean",
"default": false
}
},
"required": [
"name", "bool_val"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"date_val": {
"type": "object",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
}
},
"required": [
"name", "date_val"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"float_val": {
"type": "number",
"default": 0.0
}
},
"required": [
"name", "float_val"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"int_val": {
"type": "integer",
"default": 0,
"minimum": 0,
"maximum": 4294967295
}
},
"required": [
"name", "int_val"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"string_val": {
"type": "string",
"minLength": 0,
"maxLength": 255
}
},
"required": [
"name", "string_val"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 127,
"pattern": "^[a-zA-Z_]{1}[a-zA-Z0-9_-]*$"
},
"text_val": {
"type": "string",
"minLength": 0,
"maxLength": 65535
}
},
"required": [
"name", "text_val"
],
"additionalProperties": false
}
],
{% endmacro %}