Skip to content

andybp85/hatcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STATUS

Just getting started!

Working on getting the tokenizer and grammer creating a proper-looking struct.


Hatcher

A JSON Schema generator.

Goals

JSON Schema is extremely verbose and repetative, which makes writing it by hand cumbersome, error-prone, and trying (at best) for a human. Hatcher aims to make it... well, at least bearable. It is implemented in Racket.

Hatcher's design is guided by the following principles:

  1. Abstraction - Why write a nested block when one (or no) word will do.
  2. Inheritance - DRY it out.
  3. Organization - Trivially import pieces of schema into each other.
  4. Completeness - Support all features of JSON Schema 7.0.

README Formatting

  • Italics indicate a word that is a concept in the language, but isn't a keyword.
  • Code indicates a language keyword or example.
  • Italic code indicates JSON Schema (except in blocks, which are labeled). See the docs linked above if needed.

Language

Defintions

The basic form is the defintion, which consists of a name and key: value fields. The name must start with a capital letter.

 SomeDefinition
    properties:
        field: "value"

A basic defintion can have any fields legal in JSON Schema, and can be imported into any other definition of the same type. Definitions in the same file must be seperated by a blank line.

Also important to note, additionalProperties and additionalItems are set to false by default, but can be enabled by specifically setting them to true.

Qualifiers

Qualifiers can be used to create qualified defintions. A qualified defintion may have specific required fields, or may render a certain way. They start with a lower-case letter and are written before the name in a definition: main ConfigSchema. These qualifiers are included:

main

An object that defines the top-level configuration. There must be exactly one main defintion, and all imports must be relative to and either next to or below it in the file structure. These fields are required, all of which correspond to JSON Schema:

  • $id
  • $schema
  • title
  • properties

category

Categories will turn into groups of the things extending them in the schema using anyOf. These can be any type and contain any fields. Definitions in a category will inherit all fields from the category and can override any of them. Nested overrides will be merged with the child's fields overriding anything in the parent's.

We haven't seen inheritance yet, but this should be pretty clear:

 category Address
     properties:
         street:
             type: "string"

 HomeAddress /Addresses
     addressType: "home"

JSON Schema:

{
    "definitions": {
         "Address": {
             "anyOf": [
                 {
                     "$ref": "#/definitions/HomeAddress"
                 }
             ]
         },
         "HomeAddress": {
             "additionalProperties": false,
             "properties": {
                 "addressType": {
                     "const": "home"
                 },
                 "street": {
                     "type": "string"
                 }
             },
             "type": "object"
         }
    }
}

Types

A defintion must have a type that matches with the types in JSON Schema. Types are written after the qualifier, if present, and before the defintion name. The type can be ommitted if it is object.

array ToDoItems
    items:
        type: "string"

JSON Schema:

{
    "definitions": {
        "ToDoItems": {
            "additionalItems": false,
            "items": {
                "type": "string"
            },
            "type": "array",
        }
    }
}

Fields

Fields in a definition are seperated by new lines, and indentation is used to defined nesting. Field values that are strings must be "double quoted".

Attributes

Fields can have one or more of the following attributes that denote something specific about the field. These are written after the field name and bfore the colon: field*: value.

  • *: required
  • !: immutable
    • any definitions that inhert this field cannot change it.
  • +: abstract
    • These take a JSON-Schema like type field describing the field.
    • Abstract fields must be implemented on any definitions that inherit them.
    • See example at the end.

Paths

Paths all begin with a /, ., or ... Path components beginning with lowercase letters indicate subfolders or files relative to the current file, and components with capitals letters indicate definitions. Dots are required for imports from other files. Paths starting with a slash indicate imports in the same file. Paths to imports in other files must specify the file and the definition, e.g. ../file/Parent.

Inheritance

Inheritance is accomplishe by putting one or more paths after the name, e.g. SomeDefinition: ../file/Parent. The only restriction on Inheritance is that a defintion may only inherit from another with the same type.

Full Example

./main

main Schema
    properties:
        $id: "http://hatcher-example.com/schema.json"
        $schema: "http://json-schema.org/draft-07/schema#"
        title: "Hatcher Example Schema"
        patternProperties: {
            /^.+$/: ./address/Address

./address

category Address
    properties:
        addressType+:
            enum: [
                "business"
                "home"
            ]
        zipCode: 55555

./homeAddress

HomeAddress ./address/Address
    properties:
        AddressType: "home"
        street:
            type: "string"
        owners: /Owners

array Owners
    items:
        type: "string"

JSON Schema:

{
    "$id": "http://hatcher-example.com/schema.json",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "additionalProperties": false,
    "patternProperties": {
        "^.+$": {
            "$ref": "/definitions/Address"
        }
    },
    "definitions": {
         "Address": {
             "anyOf": [
                 {
                     "$ref": "#/definitions/HomeAddress"
                 }
             ]
         },
         "HomeAddress": {
             "additionalProperties": false,
             "properties": {
                 "addressType": "home",
                 "street": {
                     "type": "string"
                 },
                 "owners": {
                     "$ref": "#/definitions/Owners"
                 },
                 "zipCode": 55555
             },
             "type": "object"
         },
         "Owners": {
             "additionalItems": false,
             "items": {
                 "type": "string"
             },
             "type": "array"
         }
    },
    "title": "Hatcher Example Schema"
}

About

A JSON Schema generator - WIP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages