{
  "apiVersion": 1,
  "identityFields": ["baseUrl"],
  "id": "dandanplay",
  "name": "DanDanPlay",
  "locales": {
    "zh-CN": {
      "name": "弹弹play",
      "configSchema.properties.baseUrl.title": "基础地址",
      "configSchema.properties.baseUrl.description": "弹弹play（或兼容）API 的根地址。默认为官方 https://api.dandanplay.net。指向代理或自建服务器即可覆盖。",
      "configSchema.properties.appId.title": "应用 ID",
      "configSchema.properties.appId.description": "弹弹play 开放平台的 App ID。使用官方 API 时需填写；由代理在服务端签名时可留空。",
      "configSchema.properties.appSecret.title": "应用密钥",
      "configSchema.properties.appSecret.description": "弹弹play 开放平台的 App Secret，用于对官方 API 的请求进行签名。",
      "configSchema.properties.auth.title": "鉴权",
      "configSchema.properties.auth.description": "随每个请求发送的自定义请求头（如 token）。未设置 appId/appSecret 时用于替代签名，例如对接自建的兼容服务器。",
      "configSchema.properties.auth.properties.enabled.title": "启用鉴权请求头",
      "configSchema.properties.auth.properties.headers.title": "请求头",
      "configSchema.properties.auth.properties.headers.items.properties.key.title": "请求头名称",
      "configSchema.properties.auth.properties.headers.items.properties.value.title": "值",
      "configSchema.properties.chConvert.title": "中文转换",
      "configSchema.properties.chConvert.description": "0 = 不转换，1 = 转为简体，2 = 转为繁体"
    }
  },
  "version": "0.5.0",
  "hosts": ["*"],
  "configSchema": {
    "type": "object",
    "properties": {
      "baseUrl": {
        "type": "string",
        "title": "Base URL",
        "description": "Root of the DanDanPlay (or compatible) API. Defaults to the official https://api.dandanplay.net. Point this at a proxy or self-hosted server to override."
      },
      "appId": {
        "type": "string",
        "title": "App ID",
        "description": "DanDanPlay open-platform App ID. Required when using the official API; leave empty when a proxy signs requests server-side."
      },
      "appSecret": {
        "type": "string",
        "title": "App Secret",
        "description": "DanDanPlay open-platform App Secret. Used to sign requests to the official API."
      },
      "auth": {
        "type": "object",
        "title": "Authentication",
        "description": "Custom request headers (e.g. a token) sent on every request. Used instead of signing when appId/appSecret are absent, e.g. a self-hosted compatible server.",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": false,
            "title": "Enable auth headers"
          },
          "headers": {
            "type": "array",
            "title": "Headers",
            "items": {
              "type": "object",
              "required": ["key", "value"],
              "properties": {
                "key": { "type": "string", "title": "Header name" },
                "value": { "type": "string", "title": "Value" }
              }
            }
          }
        }
      },
      "chConvert": {
        "type": "integer",
        "enum": [0, 1, 2],
        "default": 0,
        "title": "Chinese conversion",
        "description": "0 = no conversion, 1 = convert to simplified, 2 = convert to traditional"
      }
    }
  },
  "search": {
    "inputs": ["q"],
    "steps": [
      {
        "type": "assign",
        "id": "prep",
        "values": {
          "req": "($base := baseUrl ? $replace(baseUrl, /\\/$/, '') : 'https://api.dandanplay.net'; $p := '/api/v2/search/anime'; $ts := $string($now()); $headers := (appId and appSecret) ? { 'X-AppId': appId, 'X-Timestamp': $ts, 'X-Signature': $sha256Base64(appId & $ts & $p & appSecret) } : ((auth.enabled and auth.headers) ? $merge(auth.headers.{ key: value }) : {}); { 'url': $base & $p, 'headers': $headers })"
        }
      },
      {
        "type": "http",
        "id": "search",
        "request": {
          "method": "GET",
          "url": "prep.req.url",
          "query": "{ 'keyword': q }",
          "headers": "prep.req.headers"
        }
      }
    ],
    "output": "[search.animes.{ 'providerIds': { 'animeId': animeId, 'bangumiId': bangumiId }, 'indexedId': $string(animeId), 'title': animeTitle, 'type': type, 'typeDescription': typeDescription, 'imageUrl': imageUrl, 'episodeCount': episodeCount, 'year': startDate and $contains(startDate, '-') ? $number($substringBefore(startDate, '-')) : undefined }]"
  },
  "episodes": {
    "inputs": ["bangumiId"],
    "steps": [
      {
        "type": "assign",
        "id": "prep",
        "values": {
          "req": "($base := baseUrl ? $replace(baseUrl, /\\/$/, '') : 'https://api.dandanplay.net'; $p := '/api/v2/bangumi/' & $string(bangumiId); $ts := $string($now()); $headers := (appId and appSecret) ? { 'X-AppId': appId, 'X-Timestamp': $ts, 'X-Signature': $sha256Base64(appId & $ts & $p & appSecret) } : ((auth.enabled and auth.headers) ? $merge(auth.headers.{ key: value }) : {}); { 'url': $base & $p, 'headers': $headers })"
        }
      },
      {
        "type": "http",
        "id": "bangumi",
        "request": {
          "method": "GET",
          "url": "prep.req.url",
          "headers": "prep.req.headers"
        }
      }
    ],
    "output": "[bangumi.bangumi.episodes.{ 'providerIds': { 'episodeId': episodeId, 'animeId': %.animeId, 'bangumiId': %.bangumiId }, 'indexedId': $string(episodeId), 'title': episodeTitle, 'episodeNumber': $match(episodeNumber, /^\\d+$/) ? $number(episodeNumber) : episodeNumber }]"
  },
  "danmaku": {
    "inputs": ["episodeId"],
    "steps": [
      {
        "type": "assign",
        "id": "prep",
        "values": {
          "req": "($base := baseUrl ? $replace(baseUrl, /\\/$/, '') : 'https://api.dandanplay.net'; $p := '/api/v2/comment/' & $string(episodeId); $ts := $string($now()); $headers := (appId and appSecret) ? { 'X-AppId': appId, 'X-Timestamp': $ts, 'X-Signature': $sha256Base64(appId & $ts & $p & appSecret) } : ((auth.enabled and auth.headers) ? $merge(auth.headers.{ key: value }) : {}); { 'url': $base & $p, 'headers': $headers })"
        }
      },
      {
        "type": "http",
        "id": "comments",
        "request": {
          "method": "GET",
          "url": "prep.req.url",
          "query": "{ 'withRelated': 'true', 'chConvert': chConvert ? $string(chConvert) : undefined }",
          "headers": "prep.req.headers"
        }
      }
    ],
    "output": "[comments.comments]"
  }
}
