gdbots/pbjc-php

View on GitHub
src/Generator/Twig/json-schema/macros.twig

Summary

Maintainability
Test Coverage
{#
    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 %}