{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "/schemas/manifest.json",
  "title": "JSON schema for Castopod Plugins's manifest.json files",
  "description": "The Castopod plugin manifest defines both metadata and behavior of a plugin",
  "type": "object",
  "properties": {
    "name": {
      "description": "The plugin name, including 'vendor-name/' prefix",
      "type": "string",
      "pattern": "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9]([_.-]?[a-z0-9]+)*$",
      "examples": ["acme/hello-world"]
    },
    "version": {
      "description": "The plugin's semantic version. See https://semver.org/",
      "type": "string",
      "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
      "examples": ["1.0.0"]
    },
    "description": {
      "description": "This helps people discover your plugin as it's listed in repositories",
      "type": "string"
    },
    "authors": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/person"
      }
    },
    "homepage": {
      "description": "The URL to the plugin homepage",
      "type": "string",
      "format": "uri"
    },
    "license": {
      "description": "You should specify a license for your plugin so that people know how they are permitted to use it, and any restrictions you're placing on it.",
      "default": "UNLICENSED",
      "anyOf": [
        {
          "type": "string"
        },
        {
          "enum": [
            "AGPL-3.0-only",
            "AGPL-3.0-or-later",
            "Apache-2.0",
            "BSL-1.0",
            "GPL-3.0-only",
            "GPL-3.0-or-later",
            "LGPL-3.0-only",
            "LGPL-3.0-or-later",
            "MIT",
            "MPL-2.0",
            "Unlicense",
            "UNLICENSED"
          ]
        }
      ]
    },
    "private": {
      "type": "boolean",
      "description": "If set to true, then repositories should refuse to publish it."
    },
    "keywords": {
      "description": "This helps people discover your plugin as it's listed in repositories",
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "accessibility",
              "analytics",
              "monetization",
              "podcasting2",
              "privacy",
              "seo"
            ]
          }
        ]
      },
      "uniqueItems": true
    },
    "hooks": {
      "description": "The hooks used by the plugin.",
      "type": "array",
      "items": {
        "enum": [
          "rssBeforeChannel",
          "rssAfterChannel",
          "rssBeforeItem",
          "rssAfterItem",
          "siteHead"
        ]
      },
      "uniqueItems": true
    },
    "settings": {
      "type": "object",
      "properties": {
        "general": {
          "$ref": "#/$defs/fields"
        },
        "podcast": {
          "$ref": "#/$defs/fields"
        },
        "episode": {
          "$ref": "#/$defs/fields"
        }
      }
    },
    "files": {
      "description": "List of files to include in your plugin package. If you include a folder in the array, all files inside it will also be included.",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "repository": {
      "description": "Specify the place where your plugin code lives. This is helpful for people who want to contribute.",
      "type": ["object", "string"],
      "properties": {
        "type": {
          "type": "string"
        },
        "url": {
          "type": "string"
        },
        "directory": {
          "type": "string"
        }
      }
    }
  },
  "required": ["name", "version"],
  "additionalProperties": false,
  "$defs": {
    "person": {
      "description": "A person who has been involved in creating or maintaining this plugin.",
      "type": ["object", "string"],
      "required": ["name"],
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email"
        },
        "url": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "fields": {
      "type": "object",
      "patternProperties": {
        "^[A-Za-z]+[\\w\\-\\:\\.]*$": { "$ref": "#/$defs/field" }
      },
      "additionalProperties": false
    },
    "field": {
      "type": "object",
      "properties": {
        "type": {
          "enum": [
            "checkbox",
            "datetime",
            "email",
            "markdown",
            "number",
            "radio-group",
            "select-multiple",
            "select",
            "text",
            "textarea",
            "toggler",
            "url"
          ],
          "default": "text"
        },
        "label": {
          "type": "string"
        },
        "hint": {
          "type": "string"
        },
        "helper": {
          "type": "string"
        },
        "optional": {
          "type": "boolean"
        },
        "options": {
          "type": "object",
          "patternProperties": {
            "^[A-Za-z0-9]+[\\w\\-\\:\\.]*$": { "$ref": "#/$defs/option" }
          },
          "additionalProperties": false
        }
      },
      "required": ["label"],
      "additionalProperties": false,
      "allOf": [
        { "$ref": "#/$defs/field-multiple-implies-options-is-required" }
      ]
    },
    "option": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string"
        },
        "hint": {
          "type": "string"
        }
      },
      "required": ["label"],
      "additionalProperties": false
    },
    "field-multiple-implies-options-is-required": {
      "anyOf": [
        {
          "not": {
            "properties": {
              "type": {
                "anyOf": [
                  { "const": "radio-group" },
                  { "const": "select" },
                  { "const": "select-multiple" }
                ]
              }
            },
            "required": ["type"]
          }
        },
        { "required": ["options"] }
      ]
    }
  }
}
