{
  "title": "api-extractor documentation JSON file",
  "description": "Describes the public API types and documentation for a TypeScript project",

  "definitions": {
    //=============================================================================================
    // Documentation Elements
    //=============================================================================================

    //---------------------------------------------------------------------------------------------
    "textDocElement": {
      "description": "A documentation element representing a block of plain text",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of documentation element",
          "type": "string",
          "enum": [ "textDocElement" ]
        },
        "value": {
          "description": "The text",
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "value" ]
    },

    //---------------------------------------------------------------------------------------------
    "linkDocElement": {
      "description": "A documentation element representing a hyperlink",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of documentation element",
          "type": "string",
          "enum": [ "linkDocElement" ]
        },
        "referenceType": {
          "description": "The link can either refer to a API definition or href",
          "type": "string",
          "enum": [ "href", "code" ]
        },
        "targetUrl": {
          "description": "The target URL for the hyperlink",
          "type": "string"
        },
        "value": {
          "description": "An optional display name to show for a link",
          "type": "string"
        },
        "memberName": {
          "description": "An optional name that specifies the export item",
          "type": "string"
        },
        "exportName": {
          "description": "A name that is required if the referenceType is code",
          "type": "string"
        },
        "packageName": {
          "description": "An optional name of the package where an export is located",
          "type": "string"
        },
        "scopeName": {
          "description": "An optional name that scopes the package name",
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "referenceType" ]
    },

    //---------------------------------------------------------------------------------------------
    "seeDocElement": {
      "description": "A documentation element representing a see js doc tag",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of documentation element",
          "type": "string",
          "enum": [ "seeDocElement" ]
        },
        "seeElements": {
          "description": "The element collection that follows the see js dog tag.",
          "type": "array",
          "items": {
            "oneOf": [
              { "$ref": "#/definitions/textDocElement" },
              { "$ref": "#/definitions/linkDocElement" }
            ]
          }
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "seeElements" ]
    },

    //---------------------------------------------------------------------------------------------
    "docElementCollection": {
      "description": "A block of annotated text, represented as a list of documentation elements",
      "type": "array",
      "items": {
        "oneOf": [
          { "$ref": "#/definitions/textDocElement" },
          { "$ref": "#/definitions/linkDocElement" },
          { "$ref": "#/definitions/seeDocElement" }
        ]
      }
    },

    //=============================================================================================
    // API Items
    //=============================================================================================

    //---------------------------------------------------------------------------------------------
    "constructorApiItem": {
      "description": "A constructor of a TypeScript class",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of documentation element",
          "type": "string",
          "enum": [ "constructor" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },
        "signature": {
          "description": "A text summary of the method definition",
          "type": "string"
        },
        "parameters": {
          "description": "The list of function parameters",
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "type": "object",
              "properties": {
                "name": {
                  "description": "The parameter name",
                  "type": "string"
                },
                "description": {
                  "$ref": "#/definitions/docElementCollection"
                },
                "isOptional": {
                  "description": "Whether the parameter is optional",
                  "type": "boolean"
                },
                "isSpread": {
                  "description": "Whether the parameter has the '...' spread suffix",
                  "type": "boolean"
                },
                "type": {
                  "description": "The data type of the parameter",
                  "type": "string"
                }
              }
            }
          },
          "additionalProperties": false
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": ["summary"]
    },

    //---------------------------------------------------------------------------------------------

    //---------------------------------------------------------------------------------------------
    "propertyApiItem": {
      "description": "A property of a TypeScript class or interface",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "property" ]
        },
        "isOptional": {
          "description": "For an interface member, whether it is optional",
          "type": "boolean"
        },
        "isReadOnly": {
          "description": "Whether the property is read-only",
          "type": "boolean"
        },
        "isStatic": {
          "description": "For a class member, whether it is static",
          "type": "boolean"
        },
        "type": {
          "description": "The data type of this property",
          "type": "string"
        },
        "isBeta": {
          "description": "Whether the API property is beta",
          "type": "boolean"
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "isOptional", "isReadOnly", "isStatic", "type", "summary", "isBeta" ]
    },

    //---------------------------------------------------------------------------------------------
    "methodApiItem": {
      "description": "A member function of a TypeScript class or interface",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "method" ]
        },
        "signature": {
          "description": "A text summary of the method definition",
          "type": "string"
        },
        "accessModifier": {
          "description": "Whether the function is public, private, or protected",
          "type": "string",
          "enum": [ "public", "private", "protected", ""]
        },
        "isOptional": {
          "description": "For an interface member, whether it is optional",
          "type": "boolean"
        },
        "isStatic": {
          "description": "For a class member, whether it is static",
          "type": "boolean"
        },
        "isBeta": {
          "description": "Whether the API method is beta",
          "type": "boolean"
        },
        "parameters": {
          "description": "The list of function parameters",
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "type": "object",
              "properties": {
                "name": {
                  "description": "The parameter name",
                  "type": "string"
                },
                "description": {
                  "$ref": "#/definitions/docElementCollection"
                },
                "isOptional": {
                  "description": "Whether the parameter is optional",
                  "type": "boolean"
                },
                "isSpread": {
                  "description": "Whether the parameter has the '...' spread suffix",
                  "type": "boolean"
                },
                "type": {
                  "description": "The data type of the parameter",
                  "type": "string"
                }
              }
            }
          },
          "additionalProperties": false
        },
        "returnValue": {
          "description": "Information about the return value of this function",
          "type": "object",
          "properties": {
            "type": {
              "description": "The data type returned by the function",
              "type": "string"
            },
            "description": {
              "$ref": "#/definitions/docElementCollection"
            }
          },
          "additionalProperties": false,
          "required": [ "type", "description" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "isOptional", "isStatic", "parameters", "returnValue", "summary", "isBeta" ]
    },

    //---------------------------------------------------------------------------------------------
    "functionApiItem": {
      "description": "A Typescript function",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "function" ]
        },
        "parameters": {
          "description": "The list of function parameters",
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "type": "object",
              "properties": {
                "name": {
                  "description": "The parameter name",
                  "type": "string"
                },
                "description": {
                  "$ref": "#/definitions/docElementCollection"
                },
                "isOptional": {
                  "description": "Whether the parameter is optional",
                  "type": "boolean"
                },
                "isSpread": {
                  "description": "Whether the parameter has the '...' spread suffix",
                  "type": "boolean"
                },
                "type": {
                  "description": "The data type of the parameter",
                  "type": "string"
                }
              }
            }
          },
          "additionalProperties": false
        },
        "returnValue": {
          "description": "Information about the return value of this function",
          "type": "object",
          "properties": {
            "type": {
              "description": "The data type returned by the function",
              "type": "string"
            },
            "description": {
              "$ref": "#/definitions/docElementCollection"
            }
          },
          "additionalProperties": false,
          "required": [ "type", "description" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },
        "isBeta": {
          "description": "Whether the API method is beta",
          "type": "boolean"
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "parameters", "returnValue", "summary", "isBeta" ]
    },


    //---------------------------------------------------------------------------------------------
    "classApiItem": {
      "description": "A TypeScript class definition",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "class" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },
        "members": {
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "oneOf": [
                { "$ref": "#/definitions/propertyApiItem" },
                { "$ref": "#/definitions/constructorApiItem" },
                { "$ref": "#/definitions/methodApiItem" }
              ]
            }
          },
          "additionalProperties": false
        },

        "implements": {
          "description": "Interfaces implemented by this class",
          "type": "string"
        },
        "extends": {
          "description": "The base class for this class",
          "type": "string"
        },
        "typeParameters": {
          "description": "Generic type parameters for this class",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "isBeta": {
          "description": "Whether the API class is beta",
          "type": "boolean"
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "summary", "isBeta" ]
    },

    //---------------------------------------------------------------------------------------------
    "enumApiItem": {
      "description": "A TypeScript enum definition",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "enum" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },
        "isBeta": {
          "description": "Whether the API enum is beta",
          "type": "boolean"
        },
        "values": {
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "type": "object",
              "properties": {
                "value": {
                  "description": "The initializer to the enum value",
                  "type": "string"
                },
                "deprecatedMessage": {
                  "$ref": "#/definitions/docElementCollection"
                },
                "summary": {
                  "$ref": "#/definitions/docElementCollection"
                },
                "remarks": {
                  "$ref": "#/definitions/docElementCollection"
                }
              }
            }
          },
          "additionalProperties": false
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "summary", "values", "isBeta" ]
    },

    //---------------------------------------------------------------------------------------------
    "interfaceApiItem": {
      "description": "A TypeScript interface definition",
      "type": "object",

      "properties": {
        "kind": {
          "description": "The kind of API definition",
          "type": "string",
          "enum": [ "interface" ]
        },
        "summary": {
          "$ref": "#/definitions/docElementCollection"
        },
        "members": {
          "type": "object",
          "patternProperties": {
            "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
              "oneOf": [
                { "$ref": "#/definitions/propertyApiItem" },
                { "$ref": "#/definitions/methodApiItem" }
              ]
            }
          },
          "additionalProperties": false
        },

        "implements": {
          "description": "Interfaces implemented by this interface",
          "type": "string"
        },
        "extends": {
          "description": "The base interface for this interface",
          "type": "string"
        },
        "typeParameters": {
          "description": "Generic type parameters for this interface",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "isBeta": {
          "description": "Whether the API interface is beta",
          "type": "boolean"
        },

        // Optional properties:
        "remarks": {
          "$ref": "#/definitions/docElementCollection"
        },
        "deprecatedMessage": {
          "$ref": "#/definitions/docElementCollection"
        }
      },
      "additionalProperties": false,
      "required": [ "kind", "summary", "isBeta" ]
    }
  },

  //===============================================================================================
  // Package
  //===============================================================================================
  "type": "object",
  "properties": {
    "$schema": {
      "description": "The metadata to indicate the JSON schema, required by some editors such as VS2015",
      "type": "string"
    },
    "kind": {
      "description": "The kind of API definition",
      "type": "string",
      "enum": [ "package" ]
    },
    "summary": {
          "$ref": "#/definitions/docElementCollection"
    },
    "remarks": {
          "$ref": "#/definitions/docElementCollection"
    },
    "exports": {
      "description": "The exported definitions for this API package",
      "type": "object",

      "patternProperties": {
         "^[a-zA-Z_]+[a-zA-Z_0-9]*$": {
           "oneOf": [
             { "$ref": "#/definitions/classApiItem" },
             { "$ref": "#/definitions/interfaceApiItem" },
             { "$ref": "#/definitions/enumApiItem" },
             { "$ref": "#/definitions/functionApiItem" }
           ]
         }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false,
  "required": [ "kind", "exports" ]
}
