{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "https://tabris.com/api-schema.json",
    "title": "Tabris.js API Definition JSON Schema",
    "definitions": {
        "api": {
            "type": "object",
            "properties": {
                "category": {
                    "enum": [
                        "core",
                        "service",
                        "widget",
                        "popup",
                        "net",
                        "data"
                    ]
                },
                "title": {
                    "description": "The title of the document. Will default to object or type name.",
                    "type": "string"
                },
                "description": {
                    "type": "string"
                },
                "namespace": {
                    "enum": [
                        "global",
                        "tabris",
                        false
                    ]
                },
                "module": {
                    "enum": [
                        "tabris",
                        "tabris-decorators"
                    ]
                },
                "markdown_only": {
                    "type": "boolean"
                },
                "type": {
                    "description": "Name of the class/interface",
                    "type": "string"
                },
                "jsxChildren": {
                    "items": {
                        "type": "string"
                    }
                },
                "interface": {
                    "description": "Makes this type an interface. Will be rendered inline where referenced in documentation.",
                    "type": "boolean",
                    "default": false
                },
                "object": {
                    "description": "Name of the instance (for singletons)",
                    "type": "string"
                },
                "extends": {
                    "$ref": "#/definitions/typeReference"
                },
                "generics": {
                    "$ref": "#/definitions/genericsDef"
                },
                "constructor": {
                    "properties": {
                        "access": {
                            "enum": [
                                "public",
                                "protected",
                                "private"
                            ]
                        },
                        "parameters": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/parameter"
                            }
                        }
                    },
                    "required": [
                        "access"
                    ],
                    "additionalProperties": false
                },
                "properties": {
                    "description": "Change events will be generated automatically if type extends NativeObject",
                    "type": "object",
                    "patternProperties": {
                        "(^[_\\$]?[a-z]\\w+$)|(^\\[.*\\]$)": {
                            "$ref": "#/definitions/property"
                        }
                    },
                    "additionalProperties": false
                },
                "methods": {
                    "type": "object",
                    "patternProperties": {
                        "(^[_\\$]?[a-z]\\w+$)|(^\\[.*\\]$|^\\$$)": {
                            "anyOf": [
                                {
                                    "$ref": "#/definitions/method"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/definitions/method"
                                    }
                                }
                            ]
                        }
                    },
                    "additionalProperties": false
                },
                "events": {
                    "type": "object",
                    "patternProperties": {
                        "^[a-z]\\w+$": {
                            "$ref": "#/definitions/event"
                        }
                    },
                    "additionalProperties": false
                },
                "statics": {
                    "$ref": "#/definitions/statics"
                },
                "links": {
                    "$ref": "#/definitions/links"
                }
            },
            "dependencies": {
                "extends": [
                    "type"
                ],
                "object": [
                    "type"
                ],
                "generics": [
                    "type"
                ],
                "constructor": [
                    "type"
                ],
                "events": [
                    "type"
                ]
            },
            "allOf": [
                {
                    "$comment": "Where is the API located?",
                    "anyOf": [
                        {
                            "required": [
                                "type"
                            ]
                        },
                        {
                            "required": [
                                "object"
                            ]
                        },
                        {
                            "required": [
                                "namespace"
                            ]
                        }
                    ]
                },
                {
                    "$comment": "What is the document named?",
                    "anyOf": [
                        {
                            "required": [
                                "title"
                            ]
                        },
                        {
                            "required": [
                                "object"
                            ]
                        },
                        {
                            "required": [
                                "type"
                            ]
                        }
                    ]
                }
            ],
            "not": {
                "$comment": "Interfaces do not support constructor or statics",
                "properties": {
                    "interface": {
                        "enum": [
                            true
                        ]
                    }
                },
                "required": [
                    "interface"
                ],
                "anyOf": [
                    {
                        "required": [
                            "constructor"
                        ]
                    },
                    {
                        "required": [
                            "statics"
                        ]
                    }
                ]
            },
            "required": [
                "category"
            ],
            "additionalProperties": false
        },
        "typeReference": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "object",
                    "properties": {
                        "interface": {
                            "type": "string"
                        },
                        "generics": {
                            "$ref": "#/definitions/generics"
                        }
                    },
                    "required": [
                        "interface",
                        "generics"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "union": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/typeReference"
                            }
                        }
                    },
                    "required": [
                        "union"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "tuple": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/typeReference"
                            }
                        }
                    },
                    "required": [
                        "tuple"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "map": {
                            "type": "object",
                            "patternProperties": {
                                "^[a-zA-Z]*$": {
                                    "$ref": "#/definitions/property"
                                }
                            },
                            "minProperties": 1,
                            "additionalProperties": false
                        }
                    },
                    "required": [
                        "map"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "map": {
                            "type": "object",
                            "patternProperties": {
                                "^[a-z]\\w+$": {
                                    "$ref": "#/definitions/typeReference"
                                }
                            },
                            "minProperties": 1,
                            "maxProperties": 1,
                            "additionalProperties": false
                        },
                        "indexType": {
                            "enum": [
                                "string",
                                "number",
                                "SelectorString"
                            ]
                        }
                    },
                    "required": [
                        "map",
                        "indexType"
                    ],
                    "additionalProperties": false
                },
                {
                    "type": "object",
                    "properties": {
                        "callback": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "$ref": "#/definitions/typeReference"
                                    },
                                    "name": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "type",
                                    "name"
                                ],
                                "additionalProperties": false
                            }
                        },
                        "returns": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "$ref": "#/definitions/typeReference"
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "type"
                            ],
                            "additionalProperties": false
                        }
                    },
                    "required": [
                        "callback"
                    ],
                    "additionalProperties": false
                }
            ]
        },
        "generics": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/typeReference"
            },
            "minItems": 1
        },
        "genericsDef": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "default": {
                        "$ref": "#/definitions/typeReference"
                    },
                    "extends": {
                        "$ref": "#/definitions/typeReference"
                    },
                    "description": {
                        "type": "string"
                    }
                },
                "required": [
                    "name"
                ],
                "additionalProperties": false
            },
            "minItems": 1
        },
        "statics": {
            "type": "object",
            "properties": {
                "properties": {
                    "type": "object",
                    "patternProperties": {
                        "(^_?[a-z]\\w+$)|(^\\[.*\\]$)": {
                            "$ref": "#/definitions/property"
                        }
                    },
                    "additionalProperties": false
                },
                "methods": {
                    "type": "object",
                    "patternProperties": {
                        "(^_?[a-z]\\w+$)|(^\\[.*\\]$)": {
                            "anyOf": [
                                {
                                    "$ref": "#/definitions/method"
                                },
                                {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/definitions/method"
                                    }
                                }
                            ]
                        }
                    },
                    "additionalProperties": false
                }
            }
        },
        "property": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "changeEventDescription": {
                    "type": "string"
                },
                "type": {
                    "$ref": "#/definitions/typeReference"
                },
                "ts_type": {
                    "description": "Overrides \"type\" for TypeScript declarations",
                    "$ref": "#/definitions/typeReference"
                },
                "ts_only": {
                    "description": "Exclude this property from documentation",
                    "type": "boolean"
                },
                "protected": {
                    "description": "Mark property as protected",
                    "type": "boolean"
                },
                "optional": {
                    "description": "Is the property optional?",
                    "type": "boolean",
                    "default": false
                },
                "private": {
                    "description": "Mark property as private",
                    "type": "boolean"
                },
                "jsxContentProperty": {
                    "description": "JSX child elements of the matching type are mapped to this property",
                    "type": "boolean"
                },
                "platforms": {
                    "$ref": "#/definitions/platforms"
                },
                "readonly": {
                    "description": "Indicates that this property can not be set. However, if the property is not a \"const\", it may change by itself. Defaults to false",
                    "type": "boolean"
                },
                "const": {
                    "description": "Indicates that this property can not change during the lifetime of this object. However, if there is a public constructor and the property is not \"readonly\", it can be set via constructor. No change events will be generated for this property. Defaults to false",
                    "type": "boolean"
                },
                "noChangeEvent": {
                    "type": "boolean",
                    "description": "This property does not produce change events. Implied by 'const'."
                },
                "default": {
                    "description": "Default value of this property"
                },
                "values": {
                    "description": "Limits the possible values of this property",
                    "type": "array",
                    "items": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            },
                            {
                                "type": "boolean"
                            }
                        ]
                    }
                },
                "links": {
                    "$ref": "#/definitions/links"
                }
            },
            "required": [
                "type"
            ],
            "additionalProperties": false
        },
        "event": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                },
                "eventObject": {
                    "type": "string",
                    "description": "The name of the generated event object interface for TypeScript declaration. Defaults to \"{TypeName}{EventName}Event\". Useful for merging multiple identical event interfaces."
                },
                "platforms": {
                    "$ref": "#/definitions/platforms"
                },
                "parameters": {
                    "type": "object",
                    "patternProperties": {
                        "^_?[a-z]\\w+$": {
                            "$ref": "#/definitions/property"
                        }
                    }
                },
                "links": {
                    "$ref": "#/definitions/links"
                }
            },
            "additionalProperties": false
        },
        "method": {
            "type": "object",
            "properties": {
                "parameters": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/parameter"
                    }
                },
                "returns": {
                    "$ref": "#/definitions/typeReference"
                },
                "docs_only": {
                    "type": "boolean"
                },
                "ts_only": {
                    "type": "boolean"
                },
                "ts_returns": {
                    "description": "Overrides \"returns\" for TypeScript declarations",
                    "$ref": "#/definitions/typeReference"
                },
                "description": {
                    "type": "string"
                },
                "generics": {
                    "$ref": "#/definitions/genericsDef"
                },
                "platforms": {
                    "$ref": "#/definitions/platforms"
                },
                "protected": {
                    "type": "boolean"
                },
                "private": {
                    "type": "boolean"
                },
                "provisional": {
                    "type": "boolean"
                },
                "links": {
                    "$ref": "#/definitions/links"
                }
            },
            "additionalProperties": false
        },
        "parameter": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                },
                "description": {
                    "type": "string"
                },
                "type": {
                    "$ref": "#/definitions/typeReference"
                },
                "ts_type": {
                    "description": "Overrides \"type\" for TypeScript declarations",
                    "$ref": "#/definitions/typeReference"
                },
                "optional": {
                    "description": "Defaults to false",
                    "type": "boolean"
                }
            },
            "required": [
                "name",
                "type"
            ],
            "additionalProperties": false
        },
        "platforms": {
            "type": "object",
            "properties": {
                "ios": {
                    "type": "boolean",
                    "description": "Defaults to true"
                },
                "android": {
                    "type": "boolean",
                    "description": "Defaults to true"
                }
            },
            "additionalProperties": false
        },
        "link": {
            "required": [
                "title",
                "path"
            ],
            "properties": {
                "title": {
                    "type": "string"
                },
                "path": {
                    "type": "string"
                }
            },
            "additionalProperties": false
        },
        "snippet": {
            "properties": {
                "title": {
                    "type": "string"
                },
                "snippet": {
                    "type": "string"
                },
                "repo": {
                    "enum": [
                        "tabris",
                        "tabris-decorators"
                    ]
                }
            },
            "required": [
                "snippet"
            ],
            "additionalProperties": false
        },
        "links": {
            "type": "array",
            "items": {
                "oneOf": [
                    {
                        "$ref": "#/definitions/link"
                    },
                    {
                        "$ref": "#/definitions/snippet"
                    }
                ]
            }
        }
    },
    "oneOf": [
        {
            "$ref": "#/definitions/api"
        }
    ]
}