{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://modpacks.ch/schemas/github-release-v1.json",
  "title": "Modpacks.ch GitHub release metadata",
  "description": "Creator-controlled metadata for one or more playable files in a GitHub release.",
  "$defs": {
    "dependencyRelation": {
      "enum": ["required", "optional", "incompatible"],
      "default": "required"
    },
    "dependency": {
      "description": "One outgoing edge from a playable file. Resolution selects or verifies a compatible file from the referenced project, then follows that file's own dependency edges.",
      "oneOf": [
        {
          "title": "CurseForge project dependency",
          "type": "object",
          "additionalProperties": false,
          "required": ["provider", "projectId"],
          "properties": {
            "provider": {
              "const": "curseforge"
            },
            "projectId": {
              "description": "The numeric CurseForge project ID.",
              "oneOf": [
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 999999999999
                },
                {
                  "type": "string",
                  "pattern": "^[1-9][0-9]{0,11}$"
                }
              ]
            },
            "fileId": {
              "description": "An optional exact CurseForge file ID. Exact files still have to match the requested game version, loader and install side.",
              "oneOf": [
                {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 999999999999
                },
                {
                  "type": "string",
                  "pattern": "^[1-9][0-9]{0,11}$"
                }
              ]
            },
            "relation": {
              "$ref": "#/$defs/dependencyRelation"
            }
          }
        },
        {
          "title": "Modrinth project dependency",
          "type": "object",
          "additionalProperties": false,
          "required": ["provider", "projectId"],
          "properties": {
            "provider": {
              "const": "modrinth"
            },
            "projectId": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]{3,64}$",
              "description": "The Modrinth project ID."
            },
            "versionId": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]{3,64}$",
              "description": "An optional exact Modrinth version ID. Exact versions still have to match the requested game version, loader and install side."
            },
            "relation": {
              "$ref": "#/$defs/dependencyRelation"
            }
          }
        },
        {
          "title": "GitHub project dependency",
          "type": "object",
          "additionalProperties": false,
          "required": ["provider", "projectId"],
          "properties": {
            "provider": {
              "const": "github"
            },
            "projectId": {
              "type": "string",
              "pattern": "^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?/[A-Za-z0-9._-]{1,100}$",
              "description": "The verified GitHub repository as owner/repository."
            },
            "versionId": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120,
              "description": "An optional exact GitHub Release tag."
            },
            "asset": {
              "type": "string",
              "pattern": "^[^/\\\\]{1,180}\\.(jar|zip)$",
              "description": "An optional exact JAR or ZIP on the selected GitHub Release. The asset's file metadata still has to match the requested game version, loader and install side."
            },
            "relation": {
              "$ref": "#/$defs/dependencyRelation"
            }
          }
        },
        {
          "title": "Legacy provider dependency",
          "description": "Compatibility shape for manifests published before project-first dependency references.",
          "type": "object",
          "additionalProperties": false,
          "required": ["provider", "id"],
          "properties": {
            "provider": {
              "enum": ["curseforge", "modrinth"]
            },
            "id": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]{1,64}$"
            },
            "relation": {
              "$ref": "#/$defs/dependencyRelation"
            }
          }
        }
      ]
    },
    "file": {
      "description": "One playable artifact and one dependency-resolution node. targets and environment define when the node is compatible; dependencies are outgoing edges from this exact artifact.",
      "type": "object",
      "required": ["name", "asset", "targets"],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "asset": {
          "type": "string",
          "pattern": "^[^/\\\\]{1,180}\\.(jar|zip)$"
        },
        "providers": {
          "description": "Optional exact copies of this artifact on verified provider projects. These IDs enable preferred-source ordering and alternate exact release pages; they are never turned into raw CDN links.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "curseforgeFile": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,11}$",
              "description": "The exact file ID inside projects.curseforge from the verified repository config."
            },
            "modrinthVersion": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]{3,64}$",
              "description": "The exact version ID inside projects.modrinth from the verified repository config."
            }
          }
        },
        "targets": {
          "description": "Every game version and loader combination this exact artifact supports.",
          "type": "object",
          "additionalProperties": false,
          "required": ["gameVersions", "loaders"],
          "properties": {
            "gameVersions": {
              "type": "array",
              "maxItems": 16,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 32
              }
            },
            "loaders": {
              "type": "array",
              "maxItems": 8,
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 24
              }
            }
          }
        },
        "environment": {
          "description": "Whether this exact artifact belongs on the client, dedicated server or both. Dependency resolution evaluates the side being installed rather than treating all files as universal.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "client": {
              "enum": ["required", "optional", "unsupported", "unknown"]
            },
            "server": {
              "enum": ["required", "optional", "unsupported", "unknown"]
            }
          }
        },
        "dependencies": {
          "description": "Dependencies declared by this exact playable file. Required and optional edges are resolved transitively through the selected dependency file's own targets, environment and dependencies. Incompatible edges are constraints and are never installed.",
          "type": "array",
          "maxItems": 32,
          "items": {
            "$ref": "#/$defs/dependency"
          }
        }
      }
    }
  },
  "oneOf": [
    {
      "type": "object",
      "additionalProperties": false,
      "required": ["$schema", "version", "files"],
      "properties": {
        "$schema": {
          "const": "https://modpacks.ch/schemas/github-release-v1.json"
        },
        "version": {
          "const": 1
        },
        "files": {
          "description": "Playable artifacts published by this GitHub Release. Multi-loader releases use separate entries so each loader can declare its own compatibility and dependency edges.",
          "type": "array",
          "minItems": 1,
          "maxItems": 8,
          "items": {
            "allOf": [{ "$ref": "#/$defs/file" }],
            "unevaluatedProperties": false
          }
        }
      }
    },
    {
      "allOf": [
        {
          "$ref": "#/$defs/file"
        },
        {
          "type": "object",
          "required": ["$schema", "version"],
          "properties": {
            "$schema": {
              "const": "https://modpacks.ch/schemas/github-release-v1.json"
            },
            "version": {
              "const": 1
            }
          }
        }
      ],
      "unevaluatedProperties": false
    }
  ]
}
