{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://mdbase.dev/connect/schemas/mdbase-app.v1.json",
  "title": "mdbase connect bundled application manifest v1",
  "type": "object",
  "additionalProperties": false,
  "required": ["manifest_version", "id", "name"],
  "properties": {
    "manifest_version": { "const": 1 },
    "distribution": {
      "enum": ["web", "portable"],
      "description": "Portable declarations use device authorization and do not claim a browser origin."
    },
    "id": {
      "type": "string",
      "minLength": 5,
      "maxLength": 150,
      "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*){2,}$",
      "description": "Stable reverse-domain application identifier. This is presentation metadata, not publisher authentication."
    },
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "homepage": { "type": "string", "format": "uri", "pattern": "^https://" },
    "project_url": { "type": "string", "format": "uri", "pattern": "^https://" },
    "icon": { "type": "string", "format": "uri", "pattern": "^https://" },
    "redirect_uris": {
      "type": "array",
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "format": "uri",
        "description": "An HTTPS URI on the homepage origin or a private-use scheme derived from the application ID."
      }
    },
    "requirements": { "$ref": "#/$defs/requirements" },
    "provisions": {
      "type": "object",
      "additionalProperties": false,
      "required": ["type_packs"],
      "properties": {
        "type_packs": {
          "type": "array",
          "maxItems": 20,
          "items": { "$ref": "#/$defs/typePackProvision" }
        }
      }
    },
    "notifications": {
      "type": "object",
      "additionalProperties": false,
      "required": ["criteria"],
      "properties": {
        "criteria": {
          "type": "array",
          "maxItems": 50,
          "items": { "$ref": "#/$defs/notificationCriterion" }
        },
        "native_delivery": { "$ref": "#/$defs/nativeNotificationDelivery" }
      }
    }
  },
  "oneOf": [
    {
      "required": ["homepage", "redirect_uris"],
      "properties": {
        "distribution": { "const": "web" },
        "homepage": true,
        "redirect_uris": true,
        "project_url": false
      }
    },
    {
      "required": ["distribution"],
      "properties": {
        "distribution": { "const": "portable" },
        "homepage": false,
        "redirect_uris": false
      }
    }
  ],
  "$defs": {
    "identifier": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
    },
    "duration": {
      "type": "string",
      "pattern": "^[0-9]+(ms|s|m|h|d)$"
    },
    "contract": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "version"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "version": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$"
        }
      }
    },
    "requirements": {
      "type": "object",
      "additionalProperties": false,
      "required": ["contracts"],
    "properties": {
      "access": {
        "enum": ["contract", "full_collection"],
        "description": "Access boundary requested after compatibility and provisioning checks."
      },
      "collection_kind": {
          "const": "hosted",
          "description": "Require a durable provider-backed collection with direct sync support."
        },
        "contracts": {
          "type": "array",
          "maxItems": 20,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/contract" }
        }
      }
    },
    "typePackProvision": {
      "type": "object",
      "additionalProperties": false,
      "required": ["manifest", "resources", "provides"],
      "properties": {
        "manifest": { "$ref": "#/$defs/typePackManifest" },
        "resources": {
          "type": "array",
          "minItems": 1,
          "maxItems": 100,
          "items": { "$ref": "#/$defs/typePackSourceResource" }
        },
        "provides": {
          "type": "array",
          "maxItems": 20,
          "uniqueItems": true,
          "items": { "$ref": "#/$defs/contract" }
        }
      }
    },
    "typePackManifest": {
      "type": "object",
      "required": ["kind", "id", "version", "resources"],
      "properties": {
        "kind": { "const": "mdbase.type-pack" },
        "id": { "$ref": "#/$defs/identifier" },
        "version": { "$ref": "#/$defs/contract/properties/version" },
        "name": { "type": "string", "minLength": 1, "maxLength": 100 },
        "description": { "type": "string", "maxLength": 500 },
        "resources": {
          "type": "array",
          "minItems": 1,
          "maxItems": 100,
          "items": { "$ref": "#/$defs/typePackManifestResource" }
        }
      },
      "patternProperties": { "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": true },
      "additionalProperties": false
    },
    "typePackManifestResource": {
      "type": "object",
      "additionalProperties": false,
      "required": ["kind", "source", "target", "digest"],
      "properties": {
        "kind": { "enum": ["contract", "type", "schema"] },
        "source": { "type": "string", "minLength": 1, "maxLength": 240 },
        "target": { "type": "string", "minLength": 1, "maxLength": 240 },
        "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
      }
    },
    "typePackSourceResource": {
      "type": "object",
      "additionalProperties": false,
      "required": ["source", "document"],
      "properties": {
        "source": { "type": "string", "minLength": 1, "maxLength": 240 },
        "document": { "type": "string", "maxLength": 262144 }
      }
    },
    "notificationCriterion": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "event", "presentation"],
      "properties": {
        "id": { "$ref": "#/$defs/identifier" },
        "event": { "$ref": "#/$defs/contract" },
        "if": {
          "type": "object",
          "additionalProperties": false,
          "required": ["$expr"],
          "properties": {
            "$expr": { "type": "string", "minLength": 1, "maxLength": 4096 }
          }
        },
        "debounce": { "$ref": "#/$defs/duration" },
        "minimum_interval": { "$ref": "#/$defs/duration" },
        "presentation": {
          "type": "object",
          "additionalProperties": false,
          "required": ["title"],
          "properties": {
            "title": { "type": "string", "minLength": 1, "maxLength": 80 },
            "body": { "type": "string", "maxLength": 160 },
            "tag": { "type": "string", "minLength": 1, "maxLength": 80 }
          }
        }
      }
    },
    "nativeNotificationDelivery": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["mode", "firebase_project_id"],
          "properties": {
            "mode": { "const": "managed_fcm" },
            "firebase_project_id": {
              "type": "string",
              "minLength": 6,
              "maxLength": 63,
              "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$"
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["mode", "url"],
          "properties": {
            "mode": { "const": "webhook" },
            "url": {
              "type": "string",
              "format": "uri",
              "pattern": "^https://"
            }
          }
        }
      ]
    }
  }
}
