{
  "$id": "https://hejj.net/schemas/manifest-1.json",
  "title": "hejj app manifest v1",
  "description": "Describes an app and the widgets it can ask a hejj user for. Host it at an https URL; that URL is the app's client_id. Host rules (same site, https) are checked by hejj on top of this schema. Spec: https://hejj.net/developers/widgets.md",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "hejj": { "type": "number", "const": 1 },
    "name": { "type": "string", "minLength": 1, "maxLength": 40 },
    "icon": { "type": "string", "maxLength": 2048, "format": "uri" },
    "homepage": { "type": "string", "maxLength": 2048, "format": "uri" },
    "redirect_uris": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": { "type": "string", "maxLength": 2048, "format": "uri" }
    },
    "device_secret_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
    "actions_url": { "type": "string", "maxLength": 2048, "format": "uri" },
    "widgets": {
      "type": "object",
      "propertyNames": { "type": "string", "pattern": "^[a-z0-9-]{1,32}$" },
      "additionalProperties": {
        "type": "object",
        "properties": {
          "title": { "type": "string", "minLength": 1, "maxLength": 40 },
          "description": { "type": "string", "minLength": 1, "maxLength": 160 },
          "size": {
            "type": "object",
            "properties": {
              "default": {
                "type": "object",
                "properties": {
                  "w": { "type": "integer", "minimum": 1, "maximum": 24 },
                  "h": { "type": "integer", "minimum": 1, "maximum": 40 }
                },
                "required": ["w", "h"],
                "additionalProperties": false
              },
              "min": {
                "type": "object",
                "properties": {
                  "w": { "type": "integer", "minimum": 1, "maximum": 24 },
                  "h": { "type": "integer", "minimum": 1, "maximum": 40 }
                },
                "required": ["w", "h"],
                "additionalProperties": false
              },
              "max": {
                "type": "object",
                "properties": {
                  "w": { "type": "integer", "minimum": 1, "maximum": 24 },
                  "h": { "type": "integer", "minimum": 1, "maximum": 40 }
                },
                "required": ["w", "h"],
                "additionalProperties": false
              }
            },
            "required": ["default", "min", "max"],
            "additionalProperties": false
          },
          "context": {
            "maxItems": 2,
            "type": "array",
            "items": { "type": "string", "enum": ["timezone", "locale"] }
          },
          "endpoints": {
            "minItems": 1,
            "maxItems": 8,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "string", "pattern": "^[a-z0-9-]{1,32}$" },
                "title": { "type": "string", "minLength": 1, "maxLength": 40 },
                "description": { "type": "string", "minLength": 1, "maxLength": 160 },
                "mode": { "type": "string", "enum": ["pull", "push"] },
                "url": { "type": "string", "maxLength": 2048, "format": "uri" },
                "ttl": { "type": "integer", "minimum": 60, "maximum": 86400 },
                "actions": {
                  "maxItems": 3,
                  "type": "array",
                  "items": { "type": "string", "pattern": "^[a-z0-9-]{1,32}$" }
                }
              },
              "required": ["id", "title", "mode"],
              "additionalProperties": false
            }
          }
        },
        "required": ["title", "endpoints"],
        "additionalProperties": false
      }
    }
  },
  "required": ["hejj", "name", "widgets"],
  "additionalProperties": false
}
