文档目录

插件开发

Manifest 参考

manifest.json 全部字段、设置项 widget 矩阵、URL pattern 规则。

manifest.json 放在插件文件夹根部。所有键名用 camelCase。未知键会被拒绝——写错字段名会让整份 manifest 校验失败,而不是被静默忽略。

顶层字段

字段必填类型规则
identitystring^[a-z0-9_-]+@[a-z0-9_-]+$——小写名字、@、作者。禁止点号。永久 ID:设置、存储、安装目录都以它为键。
namestring显示名,不能为空。
versionstring主.次.补丁 三段整数。
descriptionstring显示在插件列表里。
homepagestring项目或作者主页。
iconstring相对插件文件夹的路径。禁止 ..、绝对路径、盘符、以 /\ 开头。
minAppVersionstring三段版本号。运行中的 FluxDown 比它旧时,插件在加载阶段被跳过(记日志,不算错误)。
resolversarrayv1 至多一个。见下。
hooksobject见下。
permissionsarray能力授权。v1 接受 "ffmpeg""ytdlp",未知值一律拒绝。
settingsarray声明式设置项。见下。

插件可以只声明 resolver、只声明 hooks,或两者都有。两者都没有的 manifest 合法,只是什么也不做。

resolvers[0]

{
  "resolvers": [
    {
      "match": { "urls": ["*://host.com/share/*", "*://cdn.host.com/*"] },
      "entry": "resolver.js",
      "timeoutMs": 15000
    }
  ]
}
字段必填规则
match.urls非空的 URL pattern 列表(规则见下)。
entry脚本文件,安全相对路径。必须定义 globalThis.resolve
timeoutMs单次调用超时(毫秒),不能是 0。它替换默认的 10 秒,但无论写多大都被 30 秒硬顶封住。

hooks

{
  "hooks": {
    "entry": "hooks.js",
    "events": ["onStart", "onDone", "onError"],
    "match": { "urls": ["*://host.com/*"] }
  }
}
字段必填规则
entry脚本文件,安全相对路径。按订阅的事件各定义一个全局函数。
events非空,只能取 onStartonErroronDoneonMetaProbed,其余一律拒绝。
match可选的 URL 过滤器,pattern 规则同上;存在时 urls 不能为空。省略 = 所有任务都触发。

注意:同一插件如果还声明了 resolver,onMetaProbed 对它的任务永远不触发——带 resolver 的任务直接跳过元数据探测。你照订阅的话,FluxDown 会记一条警告日志。

permissions

插件主动申请的额外宿主能力。为空或省略 = 基础沙箱(flux.fetch 网络、flux.storage、日志)。v1 识别两个值:

授予
ffmpegflux.ffmpeg 接口——对下载完成的文件运行解析到的 ffmpeg(见 API 参考)。
ytdlpflux.ytdlp 接口——在 resolve 或任意 hook 里运行解析到的 yt-dlp(见 API 参考)。
{ "permissions": ["ffmpeg", "ytdlp"] }

未知值会让整份 manifest 失败——这样不认识某权限的旧版 FluxDown 会拒绝该插件,而不是悄悄忽略;新增权限时请一并抬高 minAppVersion

settings[]

每一项描述一个字段,应用据此生成表单。key 必须唯一且非空。

{
  "settings": [
    { "key": "apiToken", "title": "API token", "type": "string", "widget": "password", "required": true },
    { "key": "quality",  "title": "偏好画质", "type": "string", "widget": "select",
      "options": [ { "value": "hd", "label": "高清" }, { "value": "sd", "label": "标清" } ],
      "default": "hd" },
    { "key": "maxRetries", "title": "最大重试次数", "type": "number", "min": 0, "max": 10, "default": "3" },
    { "key": "verbose", "title": "详细日志", "type": "boolean", "default": "false" }
  ]
}
字段必填说明
key插件内唯一。脚本里用 flux.settings.<key> 读回。
title表单标签。
description字段下方的说明文字。
typestringnumberboolean
widget缺省按 type 推导:string→text,number→number,boolean→toggle
options仅 select非空的 {value, label} 列表。
default一律写成字符串,number 也是("3"),boolean 只能是 "true"/"false"。select 的 default 必须是某个 option 的 value;number 的 default 必须能解析且落在 min/max 区间内。
required表单拒绝保存空值。
min / max仅 number有限数、闭区间、min ≤ max
pattern仅 stringJavaScript RegExp 语法(不是 Rust regex),保存时对值做校验。
helperScript仅 string一段脚本,宿主会在该字段旁渲染一个复制按钮。宿主只把脚本文本复制到剪贴板,绝不执行。用户把它粘贴到目标站点的浏览器开发者工具 Console 中运行(典型用途:读取 document.cookie 并把登录 Cookie 复制回该字段)。须非空、≤ 4 KB。
helperLabelhelperScript 同时出现按钮文案(≤ 60 字符)。只能与 helperScript 一起使用;省略时用通用文案「复制获取脚本」。

widget × type 合法矩阵

只有这些组合合法,其余组合校验失败:

widget允许的 type
textpasswordtextareafolderselectstring
toggleboolean
numbernumber

URL pattern 规则

pattern 不是正则,也不是浏览器扩展的 match pattern。完整规则:

  • *唯一通配符,匹配任意长度的字符(包括 /:)。
  • 各个 * 之间的文本必须按顺序作为子串出现。
  • pattern 不以 * 开头时,首段必须是 URL 的前缀
  • 不以 * 结尾时,末段必须是后缀
  • 匹配不区分大小写(两侧整体转小写后比较,路径也一样)。
  • 单独一个 * 匹配一切。

例子:

patternhttps://www.youtube.com/watch?v=abc
*://www.youtube.com/watch*匹配
https://x.com/a(无通配符)只做精确匹配
*://x.com/*https://y.com/a不匹配——找不到 ://x.com/
youtube.com/*不匹配——首段前缀锚定,URL 以 https:// 开头

校验总结

manifest 在安装时和每次加载时都会校验;失败则跳过该插件,原因写进日志。检查顺序:identity 格式 → name 非空 → version 格式 → minAppVersion 格式 → icon 路径安全 → resolver 至多一个 → resolver 的 entry 路径 / match.urls 非空 / timeoutMs ≠ 0 → hooks 的 entry 路径 / events 非空且合法 / match.urls(如有)非空 → settings 的 key 唯一性和上面的逐字段规则 → permissions 全为已知值。

两个入口脚本在安装时还会做编译检查——语法错误当场拒绝,而不是等到第一次下载才发现。

这页文档有问题?