<commit_before>$schema: http://json-schema.org/draft-06/schema#
$id: idl_schema_v1
title: API engine IDL schema
description: Schema validating the API engine's IDL
type: object
required: [engine, models]
properties:
  # Versioning
  engine:
    type: string
    pattern: '^api-engine [0-9]+\.[0-9]+\.[0-9]+$'
  # Model definitions
  models:
    additionalProperties:
      $ref: '#/definitions/model'
    # Check models names
    propertyNames:
      $ref: '#/definitions/validModelName'
  # Custom functions that can be used in IDL functions
  helpers:
    oneOf:
    - type: array
      items:
        $ref: '#/definitions/helpers'
    - not:
        type: array
      $ref: '#/definitions/helpers'
  # Functions that modifies IDL definition
  plugins:
    $ref: '#/definitions/plugins'
  # Custom validation keywords
  validation:
    $ref: '#/definitions/validation'
  # Automatically generated, and used to validate `type`
  modelTypes:
    type: array
    items:
      type: string
  # Automatically generated, and used to validate custom validation keywords
  customValidationNames:
    type: array
    items:
      type: string
# Users can only define custom properties prefixed with x-*
additionalProperties: false
patternProperties:
  '^x-': true
definitions:
  # idl.models.MODEL
  model:
    type: object
    # Users can only define custom properties prefixed with x-*
    additionalProperties: false
    patternProperties:
      '^x-': true
    required: [attributes]
    properties:
      model:
        $ref: '#/definitions/validModelName'
      description:
        $ref: '#/definitions/description'
      commands:
        $ref: '#/definitions/commands'
      attributes:
        type: object
        additionalProperties:
          $ref: '#/definitions/attribute'
        propertyNames:
          $ref: '#/definitions/validAttributeName'
        properties:
          id:
            $ref: '#/definitions/idAttribute'
  # MODEL.id
  idAttribute:
    properties:
      # `model.id` can only be a string:
      #  - it should be able to be assigned by the API (as opposed to the
      #    database), so serial integers cannot be used
      #  - it cannot be targetting another model.
      type:
        const: string
      # `MODEL.id` cannot be optional
      validate:
        properties:
          required:
            not:
              const: false
    # `MODEL.id` cannot use transform|value|readonly
    allOf:
    - not:
        required: [transform]
    - not:
        required: [value]
    - not:
        required: [readonly]
  # MODEL.attributes
  attribute:
    type: object
    # Users can only define custom properties prefixed with x-*
    additionalProperties: false
    patternProperties:
      '^x-': true
    properties:
      alias:
        oneOf:
        - type: string
          $ref: '#/definitions/validAttributeName'
        - type: array
          items:
            type: string
            $ref: '#/definitions/validAttributeName'
      readonly:
        type: boolean
      transform:
        $ref: '#/definitions/transformValue'
      value:
        $ref: '#/definitions/transformValue'
      # General data validation
      validate:
        $ref: '#/definitions/validate'
      # Like JSON schema, but is used for more than validation,
      # e.g. in GraphQL schema
      type:
        $ref: '#/definitions/type'
      # For array types
      multiple:
        type: boolean
      # Indicate an attribute is deprecated, and why
      deprecation_reason:
        $ref: '#/definitions/description'
      # Used in automatically generated documentation
      description:
        $ref: '#/definitions/description'
      # Used in automatically generated documentation
      examples:
        type: array
        items:
          type: string
      # Default value
      default:
        $ref: '#/definitions/idlFuncOrValue'
    allOf:
    # Cannot both be required and have a default value
    - if:
        required: [validate]
        properties:
          validate:
            required: [required]
            properties:
              required:
                const: true
      then:
        not:
          required: [default]
  # model.commands
  # E.g. `commands: [find, create]`
  # This property restricts which commands a specific model can perform
  commands:
    type: array
    uniqueItems: true
    items:
      type: string
      enum:
      - find
      - create
      - replace
      - delete
  # idl.helpers
  helpers:
    typeof: [object, function]
    # system-defined helpers use $THIS_CASE, so we forbid it for user-defined
    # helpers for forward compatibility
    propertyNames:
      not:
        pattern: '^\$[A-Z_]+$'
    # Helpers can either be an options object, or the options.value directly
    additionalProperties:
      if:
        type: object
        required: [value]
      then:
        properties:
          useVars:
            type: boolean
  # idl.plugins
  plugins:
    type: array
    items:
      typeof: object
      not:
        type: array
      properties:
        plugin:
          typeof: [function, string]
        enabled:
          typeof: boolean
        opts: {}
      additionalProperties: false
  # idl.validation
  validation:
    type: object
    additionalProperties:
      type: object
      properties:
        test:
          $ref: '#/definitions/idlFuncString'
        # Error messages can either be a string, or IDL functions
        message:
          $ref: '#/definitions/idlFuncString'
          # Convention: error message must start with "must"
          if:
            type: string
          then:
            anyOf:
            - pattern: ^must\s
            - pattern: ^\("must\s.*"\)$
            - pattern: ^\('must\s.*'\)$
            - pattern: ^\(`must\s.*`\)$
        type:
          $ref: '#/definitions/jsonSchemaType'
      additionalProperties: false
    # Must start with uppercase letter to avoid naming conflict with other
    # attributes, and ensure forward compatibility
    propertyNames:
      pattern: '^[A-Z][a-zA-Z0-9]*$'
  # attr.type
  type:
    oneOf:
    - $ref: '#/definitions/singleType'
    # Cannot specify models when using an array of types
    - type: array
      # Must choose between multiple and non-multiple types, when using an array
      oneOf:
      - items:
          $ref: '#/definitions/nonModelSimpleType'
      - items:
          $ref: '#/definitions/nonModelMultipleType'
      minItems: 1
      uniqueItems: true
  singleType:
    type: string
    oneOf:
    - $ref: '#/definitions/modelType'
    - $ref: '#/definitions/nonModelType'
  modelType:
    enum:
      $data: '/modelTypes'
  nonModelType:
    oneOf:
    - $ref: '#/definitions/nonModelSimpleType'
    - $ref: '#/definitions/nonModelMultipleType'
  nonModelSimpleType:
    enum:
    - string
    - number
    - integer
    - boolean
    # Not allowed: should use models instead
    # - object
    # Not allowed: should use [] notation instead
    # - array
  nonModelMultipleType:
    enum:
    - string[]
    - number[]
    - integer[]
    - boolean[]
  # attr.transform or attr.value
  transformValue:
    $ref: '#/definitions/idlFuncOrValue'
  # model.description or attr.description
  description:
    type: string
  # TODO: validate that if this is not IDL function, it should be of same
  # type as the attribute.type
  idlFuncOrValue:
    anyOf:
    - $ref: '#/definitions/idlFunc'
    - not:
        $ref: '#/definitions/idlFunc'
  idlFuncString:
    anyOf:
    - $ref: '#/definitions/idlFunc'
    - not:
        $ref: '#/definitions/idlFunc'
      type: string
  # IDL functions can either be external (function) or inline (a string '(...)')
  idlFunc:
    anyOf:
    - typeof: function
    - type: string
      pattern: '^\s*\(.*\)\s*$'
  # Keys of idl.models.*, and model.model
  validModelName:
    type: string
    # Valid GraphQL identifier name, regular expression taken from spec
    # Additional restriction: lowercase-only
    pattern: '^[_a-z][_0-9a-z]*$'
    # Should not start with __ as it is reserved for GraphQL introspection types
    not:
      pattern: '^__'
  # Keys of MODEL.attributes.*
  validAttributeName:
    allOf:
    # Attributes follow same naming convention as models
    - $ref: '#/definitions/validModelName'
    # 'all' is a special attribute name, used to query all attributes
    - not:
        const: all
  # attr.validate
  validate:
    type: object
    $ref: '#/definitions/jsonSchema'
  # Value of schema.type from JSON schema
  jsonSchemaType:
    oneOf:
    - type: string
      enum: [string, number, integer, boolean, null, object, array]
    - type: array
      items:
        $ref: '#/definitions/jsonSchemaType'
  # Reuse standard JSON schema as a base
  # This is JSON schema v6, as YAML
  # The spec is currently in draft (only v4 is currently official)
  jsonSchema:
    definitions:
      schemaArray:
        type: array
        minItems: 1
        items:
          $ref: '#/definitions/jsonSchema'
      nonNegativeInteger:
        type: integer
        minimum: 0
      nonNegativeIntegerDefault0:
        allOf:
          - $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
          - default: 0
      simpleTypes:
        enum:
          - array
          - boolean
          - integer
          - 'null'
          - number
          - object
          - string
      stringArray:
        type: array
        items:
          type: string
        uniqueItems: true
        default: []
    type:
    - object
    # JSON schemas can be booleans
    - boolean
    properties:
      # The following properties are not available, because a property on
      # attributes should be used instead:
      #  - type
      #  - description
      #  - examples
      #  - default
      #  - title
      # The following properties are not available, because attributes cannot
      # be objects.
      #  - maxProperties
      #  - minProperties
      #  - additionalProperties
      #  - properties
      #  - patternProperties
      #  - propertyNames
      # We are using a different syntax for the following attributes:
      #  - format
      #  - required
      #  - dependencies
      # The following properties are not available, because not directly
      # validation-related:
      #  - $id
      #  - $schema
      #  - $ref
      #  - definitions
      multipleOf:
        type: number
        exclusiveMinimum: 0
      maximum:
        type: number
      exclusiveMaximum:
        type: number
      minimum:
        type: number
      exclusiveMinimum:
        type: number
      maxLength:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
      minLength:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeIntegerDefault0'
      pattern:
        type: string
        format: regex
      additionalItems:
        $ref: '#/definitions/jsonSchema'
      items:
        anyOf:
          - $ref: '#/definitions/jsonSchema'
          - $ref: '#/definitions/jsonSchema/definitions/schemaArray'
        default: {}
      maxItems:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
      minItems:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeIntegerDefault0'
      uniqueItems:
        type: boolean
        default: false
      contains:
        $ref: '#/definitions/jsonSchema'
      const: {}
      enum:
        type: array
        minItems: 1
        uniqueItems: true
      allOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      anyOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      oneOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      not:
        $ref: '#/definitions/jsonSchema'
      # Future JSON standard
      formatMaximum:
        type: string
      formatMinimum:
        type: string
      formatExclusiveMaximum:
        type: boolean
      formatExclusiveMinimum:
        type: boolean
      if:
        $ref: '#/definitions/jsonSchema'
      then:
        $ref: '#/definitions/jsonSchema'
      else:
        $ref: '#/definitions/jsonSchema'
      # Our additions to JSON schema
      # All spec-defined formats are allowed. We are stricter than the spec,
      # as custom formats are forbidden.
      format:
        type: string
        enum:
        - regex
        - date-time
        - date
        - time
        - email
        - hostname
        - ipv4
        - ipv6
        - uri
        - uri-reference
        - json-pointer
        - relative-json-pointer
      # Instead of being an array on the model,
      # like in standard JSON schema.
      # More intuitive
      required:
        type: boolean
      # Same as JSON schema, but directly on the attribute
      dependencies:
        anyOf:
        - $ref: '#/definitions/jsonSchema'
        - $ref: '#/definitions/jsonSchema/definitions/stringArray'
    default: {}
    # Future JSON standard
    dependencies:
      formatExclusiveMinimum: [formatMinimum]
      formatExclusiveMaximum: [formatMaximum]
      if: [then]
      then: [if]
      else: [then]
    # Do not allow custom properties, except the ones from idl.validation
    propertyNames:
      oneOf:
      - enum:
          $data: '/customValidationNames'
      - enum:
        # Numbers validation
        - multipleOf
        - maximum
        - exclusiveMaximum
        - minimum
        - exclusiveMinimum
        # String validation
        - maxLength
        - minLength
        - pattern
        - format
        - formatMaximum
        - formatMinimum
        - formatExclusiveMaximum
        - formatExclusiveMinimum
        # Array validation
        - additionalItems
        - items
        - maxItems
        - minItems
        - uniqueItems
        - contains
        # Any type validation
        - const
        - enum
        - required
        - dependencies
        # Combinators
        - allOf
        - anyOf
        - oneOf
        - not
        - if
        - then
        - else
<commit_msg>attr.default and attr.required are not exclusive<commit_after>$schema: http://json-schema.org/draft-06/schema#
$id: idl_schema_v1
title: API engine IDL schema
description: Schema validating the API engine's IDL
type: object
required: [engine, models]
properties:
  # Versioning
  engine:
    type: string
    pattern: '^api-engine [0-9]+\.[0-9]+\.[0-9]+$'
  # Model definitions
  models:
    additionalProperties:
      $ref: '#/definitions/model'
    # Check models names
    propertyNames:
      $ref: '#/definitions/validModelName'
  # Custom functions that can be used in IDL functions
  helpers:
    oneOf:
    - type: array
      items:
        $ref: '#/definitions/helpers'
    - not:
        type: array
      $ref: '#/definitions/helpers'
  # Functions that modifies IDL definition
  plugins:
    $ref: '#/definitions/plugins'
  # Custom validation keywords
  validation:
    $ref: '#/definitions/validation'
  # Automatically generated, and used to validate `type`
  modelTypes:
    type: array
    items:
      type: string
  # Automatically generated, and used to validate custom validation keywords
  customValidationNames:
    type: array
    items:
      type: string
# Users can only define custom properties prefixed with x-*
additionalProperties: false
patternProperties:
  '^x-': true
definitions:
  # idl.models.MODEL
  model:
    type: object
    # Users can only define custom properties prefixed with x-*
    additionalProperties: false
    patternProperties:
      '^x-': true
    required: [attributes]
    properties:
      model:
        $ref: '#/definitions/validModelName'
      description:
        $ref: '#/definitions/description'
      commands:
        $ref: '#/definitions/commands'
      attributes:
        type: object
        additionalProperties:
          $ref: '#/definitions/attribute'
        propertyNames:
          $ref: '#/definitions/validAttributeName'
        properties:
          id:
            $ref: '#/definitions/idAttribute'
  # MODEL.id
  idAttribute:
    properties:
      # `model.id` can only be a string:
      #  - it should be able to be assigned by the API (as opposed to the
      #    database), so serial integers cannot be used
      #  - it cannot be targetting another model.
      type:
        const: string
      # `MODEL.id` cannot be optional
      validate:
        properties:
          required:
            not:
              const: false
    # `MODEL.id` cannot use transform|value|readonly
    allOf:
    - not:
        required: [transform]
    - not:
        required: [value]
    - not:
        required: [readonly]
  # MODEL.attributes
  attribute:
    type: object
    # Users can only define custom properties prefixed with x-*
    additionalProperties: false
    patternProperties:
      '^x-': true
    properties:
      alias:
        oneOf:
        - type: string
          $ref: '#/definitions/validAttributeName'
        - type: array
          items:
            type: string
            $ref: '#/definitions/validAttributeName'
      readonly:
        type: boolean
      transform:
        $ref: '#/definitions/transformValue'
      value:
        $ref: '#/definitions/transformValue'
      # General data validation
      validate:
        $ref: '#/definitions/validate'
      # Like JSON schema, but is used for more than validation,
      # e.g. in GraphQL schema
      type:
        $ref: '#/definitions/type'
      # For array types
      multiple:
        type: boolean
      # Indicate an attribute is deprecated, and why
      deprecation_reason:
        $ref: '#/definitions/description'
      # Used in automatically generated documentation
      description:
        $ref: '#/definitions/description'
      # Used in automatically generated documentation
      examples:
        type: array
        items:
          type: string
      # Default value
      default:
        $ref: '#/definitions/idlFuncOrValue'
  # model.commands
  # E.g. `commands: [find, create]`
  # This property restricts which commands a specific model can perform
  commands:
    type: array
    uniqueItems: true
    items:
      type: string
      enum:
      - find
      - create
      - replace
      - delete
  # idl.helpers
  helpers:
    typeof: [object, function]
    # system-defined helpers use $THIS_CASE, so we forbid it for user-defined
    # helpers for forward compatibility
    propertyNames:
      not:
        pattern: '^\$[A-Z_]+$'
    # Helpers can either be an options object, or the options.value directly
    additionalProperties:
      if:
        type: object
        required: [value]
      then:
        properties:
          useVars:
            type: boolean
  # idl.plugins
  plugins:
    type: array
    items:
      typeof: object
      not:
        type: array
      properties:
        plugin:
          typeof: [function, string]
        enabled:
          typeof: boolean
        opts: {}
      additionalProperties: false
  # idl.validation
  validation:
    type: object
    additionalProperties:
      type: object
      properties:
        test:
          $ref: '#/definitions/idlFuncString'
        # Error messages can either be a string, or IDL functions
        message:
          $ref: '#/definitions/idlFuncString'
          # Convention: error message must start with "must"
          if:
            type: string
          then:
            anyOf:
            - pattern: ^must\s
            - pattern: ^\("must\s.*"\)$
            - pattern: ^\('must\s.*'\)$
            - pattern: ^\(`must\s.*`\)$
        type:
          $ref: '#/definitions/jsonSchemaType'
      additionalProperties: false
    # Must start with uppercase letter to avoid naming conflict with other
    # attributes, and ensure forward compatibility
    propertyNames:
      pattern: '^[A-Z][a-zA-Z0-9]*$'
  # attr.type
  type:
    oneOf:
    - $ref: '#/definitions/singleType'
    # Cannot specify models when using an array of types
    - type: array
      # Must choose between multiple and non-multiple types, when using an array
      oneOf:
      - items:
          $ref: '#/definitions/nonModelSimpleType'
      - items:
          $ref: '#/definitions/nonModelMultipleType'
      minItems: 1
      uniqueItems: true
  singleType:
    type: string
    oneOf:
    - $ref: '#/definitions/modelType'
    - $ref: '#/definitions/nonModelType'
  modelType:
    enum:
      $data: '/modelTypes'
  nonModelType:
    oneOf:
    - $ref: '#/definitions/nonModelSimpleType'
    - $ref: '#/definitions/nonModelMultipleType'
  nonModelSimpleType:
    enum:
    - string
    - number
    - integer
    - boolean
    # Not allowed: should use models instead
    # - object
    # Not allowed: should use [] notation instead
    # - array
  nonModelMultipleType:
    enum:
    - string[]
    - number[]
    - integer[]
    - boolean[]
  # attr.transform or attr.value
  transformValue:
    $ref: '#/definitions/idlFuncOrValue'
  # model.description or attr.description
  description:
    type: string
  # TODO: validate that if this is not IDL function, it should be of same
  # type as the attribute.type
  idlFuncOrValue:
    anyOf:
    - $ref: '#/definitions/idlFunc'
    - not:
        $ref: '#/definitions/idlFunc'
  idlFuncString:
    anyOf:
    - $ref: '#/definitions/idlFunc'
    - not:
        $ref: '#/definitions/idlFunc'
      type: string
  # IDL functions can either be external (function) or inline (a string '(...)')
  idlFunc:
    anyOf:
    - typeof: function
    - type: string
      pattern: '^\s*\(.*\)\s*$'
  # Keys of idl.models.*, and model.model
  validModelName:
    type: string
    # Valid GraphQL identifier name, regular expression taken from spec
    # Additional restriction: lowercase-only
    pattern: '^[_a-z][_0-9a-z]*$'
    # Should not start with __ as it is reserved for GraphQL introspection types
    not:
      pattern: '^__'
  # Keys of MODEL.attributes.*
  validAttributeName:
    allOf:
    # Attributes follow same naming convention as models
    - $ref: '#/definitions/validModelName'
    # 'all' is a special attribute name, used to query all attributes
    - not:
        const: all
  # attr.validate
  validate:
    type: object
    $ref: '#/definitions/jsonSchema'
  # Value of schema.type from JSON schema
  jsonSchemaType:
    oneOf:
    - type: string
      enum: [string, number, integer, boolean, null, object, array]
    - type: array
      items:
        $ref: '#/definitions/jsonSchemaType'
  # Reuse standard JSON schema as a base
  # This is JSON schema v6, as YAML
  # The spec is currently in draft (only v4 is currently official)
  jsonSchema:
    definitions:
      schemaArray:
        type: array
        minItems: 1
        items:
          $ref: '#/definitions/jsonSchema'
      nonNegativeInteger:
        type: integer
        minimum: 0
      nonNegativeIntegerDefault0:
        allOf:
          - $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
          - default: 0
      simpleTypes:
        enum:
          - array
          - boolean
          - integer
          - 'null'
          - number
          - object
          - string
      stringArray:
        type: array
        items:
          type: string
        uniqueItems: true
        default: []
    type:
    - object
    # JSON schemas can be booleans
    - boolean
    properties:
      # The following properties are not available, because a property on
      # attributes should be used instead:
      #  - type
      #  - description
      #  - examples
      #  - default
      #  - title
      # The following properties are not available, because attributes cannot
      # be objects.
      #  - maxProperties
      #  - minProperties
      #  - additionalProperties
      #  - properties
      #  - patternProperties
      #  - propertyNames
      # We are using a different syntax for the following attributes:
      #  - format
      #  - required
      #  - dependencies
      # The following properties are not available, because not directly
      # validation-related:
      #  - $id
      #  - $schema
      #  - $ref
      #  - definitions
      multipleOf:
        type: number
        exclusiveMinimum: 0
      maximum:
        type: number
      exclusiveMaximum:
        type: number
      minimum:
        type: number
      exclusiveMinimum:
        type: number
      maxLength:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
      minLength:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeIntegerDefault0'
      pattern:
        type: string
        format: regex
      additionalItems:
        $ref: '#/definitions/jsonSchema'
      items:
        anyOf:
          - $ref: '#/definitions/jsonSchema'
          - $ref: '#/definitions/jsonSchema/definitions/schemaArray'
        default: {}
      maxItems:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeInteger'
      minItems:
        $ref: '#/definitions/jsonSchema/definitions/nonNegativeIntegerDefault0'
      uniqueItems:
        type: boolean
        default: false
      contains:
        $ref: '#/definitions/jsonSchema'
      const: {}
      enum:
        type: array
        minItems: 1
        uniqueItems: true
      allOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      anyOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      oneOf:
        $ref: '#/definitions/jsonSchema/definitions/schemaArray'
      not:
        $ref: '#/definitions/jsonSchema'
      # Future JSON standard
      formatMaximum:
        type: string
      formatMinimum:
        type: string
      formatExclusiveMaximum:
        type: boolean
      formatExclusiveMinimum:
        type: boolean
      if:
        $ref: '#/definitions/jsonSchema'
      then:
        $ref: '#/definitions/jsonSchema'
      else:
        $ref: '#/definitions/jsonSchema'
      # Our additions to JSON schema
      # All spec-defined formats are allowed. We are stricter than the spec,
      # as custom formats are forbidden.
      format:
        type: string
        enum:
        - regex
        - date-time
        - date
        - time
        - email
        - hostname
        - ipv4
        - ipv6
        - uri
        - uri-reference
        - json-pointer
        - relative-json-pointer
      # Instead of being an array on the model,
      # like in standard JSON schema.
      # More intuitive
      required:
        type: boolean
      # Same as JSON schema, but directly on the attribute
      dependencies:
        anyOf:
        - $ref: '#/definitions/jsonSchema'
        - $ref: '#/definitions/jsonSchema/definitions/stringArray'
    default: {}
    # Future JSON standard
    dependencies:
      formatExclusiveMinimum: [formatMinimum]
      formatExclusiveMaximum: [formatMaximum]
      if: [then]
      then: [if]
      else: [then]
    # Do not allow custom properties, except the ones from idl.validation
    propertyNames:
      oneOf:
      - enum:
          $data: '/customValidationNames'
      - enum:
        # Numbers validation
        - multipleOf
        - maximum
        - exclusiveMaximum
        - minimum
        - exclusiveMinimum
        # String validation
        - maxLength
        - minLength
        - pattern
        - format
        - formatMaximum
        - formatMinimum
        - formatExclusiveMaximum
        - formatExclusiveMinimum
        # Array validation
        - additionalItems
        - items
        - maxItems
        - minItems
        - uniqueItems
        - contains
        # Any type validation
        - const
        - enum
        - required
        - dependencies
        # Combinators
        - allOf
        - anyOf
        - oneOf
        - not
        - if
        - then
        - else

{'fraction_non_alphanumeric': 0.09172066234701223, 'fraction_numerical': 0.0018718502519798417, 'mean_word_length': 1.8902413649604661, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1994407', 'n_tokens_mistral': 7828, 'n_tokens_neox': 7705, 'n_words': 2253}