{
  "$id": "https://hejj.net/schemas/blocks-1.json",
  "title": "hejj widget blocks v1",
  "description": "What an app sends to show in its widget: a pull answer, a push body or an action answer. Unknown block types are skipped by hejj. Spec: https://hejj.net/developers/widgets.md",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "v": { "type": "number", "const": 1 },
    "href": { "type": "string", "format": "uri" },
    "ttl": { "type": "integer", "minimum": 60, "maximum": 86400 },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
    },
    "blocks": {
      "minItems": 1,
      "maxItems": 12,
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "label": { "type": "string", "minLength": 1, "maxLength": 40 },
              "value": {
                "anyOf": [
                  { "type": "number" },
                  { "type": "string", "minLength": 1, "maxLength": 24 }
                ]
              },
              "unit": { "type": "string", "enum": ["money", "count", "percent", "text"] },
              "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
              "delta": {
                "type": "object",
                "properties": {
                  "value": { "type": "number" },
                  "percent": { "type": "boolean" },
                  "period": { "type": "string", "minLength": 1, "maxLength": 24 },
                  "good": { "type": "string", "enum": ["up", "down"] }
                },
                "required": ["value"],
                "additionalProperties": false
              },
              "period": { "type": "string", "minLength": 1, "maxLength": 24 },
              "type": { "type": "string", "const": "metric" }
            },
            "required": ["label", "value", "type"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "metrics" },
              "items": {
                "minItems": 1,
                "maxItems": 8,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": { "type": "string", "minLength": 1, "maxLength": 40 },
                    "value": {
                      "anyOf": [
                        { "type": "number" },
                        { "type": "string", "minLength": 1, "maxLength": 24 }
                      ]
                    },
                    "unit": { "type": "string", "enum": ["money", "count", "percent", "text"] },
                    "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
                    "delta": {
                      "type": "object",
                      "properties": {
                        "value": { "type": "number" },
                        "percent": { "type": "boolean" },
                        "period": { "type": "string", "minLength": 1, "maxLength": 24 },
                        "good": { "type": "string", "enum": ["up", "down"] }
                      },
                      "required": ["value"],
                      "additionalProperties": false
                    },
                    "period": { "type": "string", "minLength": 1, "maxLength": 24 }
                  },
                  "required": ["label", "value"],
                  "additionalProperties": false
                }
              }
            },
            "required": ["type", "items"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "sparkline" },
              "values": {
                "minItems": 2,
                "maxItems": 120,
                "type": "array",
                "items": { "type": "number" }
              },
              "label": { "type": "string", "minLength": 1, "maxLength": 40 },
              "color": {
                "type": "string",
                "enum": [
                  "stone",
                  "red",
                  "orange",
                  "amber",
                  "yellow",
                  "lime",
                  "green",
                  "teal",
                  "cyan",
                  "blue",
                  "indigo",
                  "violet",
                  "purple",
                  "pink",
                  "rose"
                ]
              }
            },
            "required": ["type", "values"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "list" },
              "items": {
                "minItems": 1,
                "maxItems": 30,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "title": { "type": "string", "minLength": 1, "maxLength": 80 },
                    "subtitle": { "type": "string", "minLength": 1, "maxLength": 120 },
                    "value": { "type": "string", "minLength": 1, "maxLength": 24 },
                    "emoji": { "type": "string", "minLength": 1, "maxLength": 16 },
                    "href": { "type": "string", "format": "uri" },
                    "color": {
                      "type": "string",
                      "enum": [
                        "stone",
                        "red",
                        "orange",
                        "amber",
                        "yellow",
                        "lime",
                        "green",
                        "teal",
                        "cyan",
                        "blue",
                        "indigo",
                        "violet",
                        "purple",
                        "pink",
                        "rose"
                      ]
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                    }
                  },
                  "required": ["title"],
                  "additionalProperties": false
                }
              }
            },
            "required": ["type", "items"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "table" },
              "columns": {
                "minItems": 1,
                "maxItems": 5,
                "type": "array",
                "items": { "type": "string", "minLength": 1, "maxLength": 24 }
              },
              "rows": {
                "maxItems": 20,
                "type": "array",
                "items": {
                  "minItems": 1,
                  "maxItems": 5,
                  "type": "array",
                  "items": {
                    "anyOf": [{ "type": "number" }, { "type": "string", "maxLength": 80 }]
                  }
                }
              }
            },
            "required": ["type", "columns", "rows"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "progress" },
              "label": { "type": "string", "minLength": 1, "maxLength": 40 },
              "value": { "type": "number", "minimum": 0 },
              "max": { "type": "number", "exclusiveMinimum": 0 },
              "color": {
                "type": "string",
                "enum": [
                  "stone",
                  "red",
                  "orange",
                  "amber",
                  "yellow",
                  "lime",
                  "green",
                  "teal",
                  "cyan",
                  "blue",
                  "indigo",
                  "violet",
                  "purple",
                  "pink",
                  "rose"
                ]
              }
            },
            "required": ["type", "label", "value", "max"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "status" },
              "state": { "type": "string", "enum": ["ok", "warn", "down", "unknown"] },
              "label": { "type": "string", "minLength": 1, "maxLength": 40 },
              "detail": { "type": "string", "minLength": 1, "maxLength": 120 }
            },
            "required": ["type", "state", "label"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "text" },
              "text": { "type": "string", "minLength": 1, "maxLength": 500 },
              "tone": { "type": "string", "enum": ["muted", "normal"] }
            },
            "required": ["type", "text"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "actions" },
              "buttons": {
                "minItems": 1,
                "maxItems": 3,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string", "pattern": "^[a-z0-9-]{1,32}$" },
                    "label": { "type": "string", "minLength": 1, "maxLength": 24 },
                    "style": { "type": "string", "enum": ["primary", "secondary", "danger"] },
                    "confirm": { "type": "string", "minLength": 1, "maxLength": 120 },
                    "value": { "type": "string", "maxLength": 256 }
                  },
                  "required": ["id", "label"],
                  "additionalProperties": false
                }
              }
            },
            "required": ["type", "buttons"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "const": "empty" },
              "title": { "type": "string", "minLength": 1, "maxLength": 60 },
              "hint": { "type": "string", "minLength": 1, "maxLength": 120 }
            },
            "required": ["type", "title"],
            "additionalProperties": false
          }
        ]
      }
    }
  },
  "required": ["v", "blocks"],
  "additionalProperties": false
}
