catpaw-drive-core 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,124 +1,249 @@
1
- # catpaw-drive-core
1
+ # catpaw-drive-core 1.0.0:Rex 外部模块开发接入指南
2
2
 
3
- 用于分享链接识别、网盘目录、影视文件匹配、转存、播放解析和转存清理的 JavaScript 核心。支持夸克、百度、UC、115、123、迅雷、光鸭、移动、天翼;各盘能力和权限要求不同,不代表所有网盘支持相同画质或下载方式。
3
+ 新模块使用 `catpaw-drive-core/rex-build`。npm 包在 Node.js 构建时生成网盘引擎表达式,嵌入最终 Rex 单文件;Rex 执行时直接使用宿主的词法 `Widget`,无需安装 npm、联网下载 core 或执行 eval。
4
4
 
5
- 首版 `0.1.0` 复用 CatPaw 当前正式 `2.2.4` 网盘引擎,发布 ESM、CommonJS、浏览器 IIFE 及 TypeScript 类型,无 npm 运行时依赖。公开包只提供混淆构建产物,不包含可读源码或 source map。混淆用于增加阅读成本,不能保证代码无法还原。
5
+ 开发者负责自己的资源来源:网站搜索、详情、分享地址和网站登录。引擎负责九盘分享解析、目录、分集匹配、取链、播放头、通用网盘账号与配置。**安装 core 不会自动获得某个网站的资源搜索接口。**
6
6
 
7
- ## 安装与构建
7
+ 适用版本:npm 包 **1.0.0**,内置 Rex 引擎标识 **2.2.4**。唯一代码入口为 `/rex-build`。旧 SDK 根入口、浏览器全局文件及 createDriveCore API 已删除;直接 import/require 包根路径会报不支持。包版本以 npm/package.json 为准,`engineVersion` 为引擎版本。
8
+
9
+ ## 1. 安装与构建
10
+
11
+ 需要 Node.js 18+;CatPaw 自身工程构建要求 Node.js 22+。请锁定版本并提交 lockfile:
8
12
 
9
13
  ```sh
10
- npm install catpaw-drive-core@0.1.0
14
+ npm install --save-dev --save-exact catpaw-drive-core@1.0.0
11
15
  ```
12
16
 
17
+ 构建脚本使用 ESM:
18
+
13
19
  ```js
14
- import { createDriveCore } from 'catpaw-drive-core';
15
-
16
- const core = createDriveCore({
17
- namespace: 'your-module.pan',
18
- http: Widget.http,
19
- storage: Widget.storage,
20
- // 该可选缓存仅用于当前模块自己的转存、令牌等状态,并按 namespace 隔离。
21
- sharedCache: Widget.sharedCache,
22
- // 共享账号入口由调用方选择,核心通过 getConfig 获取只读快照。
23
- getConfig() {
24
- try {
25
- const raw = Widget.sharedCache.get('catpaw.drive-accounts.v1', 'credentials');
26
- return typeof raw === 'string' ? JSON.parse(raw) : null;
27
- } catch { return null; }
28
- },
20
+ import {renderRexEngine, engineVersion} from 'catpaw-drive-core/rex-build';
21
+
22
+ const expression = renderRexEngine({
23
+ namespace: 'example.demo.pan',
24
+ linkPrefix: 'demopan:',
25
+ idPrefix: 'demo-pan-',
26
+ title: '我的网盘资源',
27
+ site: 'https://example.invalid', // 换成自己网站的实际 origin
29
28
  });
29
+ // expression 是 JavaScript 表达式字符串,构建时写入脚本,不要 JSON.stringify(expression)。
30
+ const output = 'var WidgetMetadata = ' + JSON.stringify(metadata) + ';\n'
31
+ + 'var DriveEngine = ' + expression + ';\n'
32
+ + runtimeSource;
33
+ ```
34
+
35
+ CommonJS 同样可用:
36
+
37
+ ```js
38
+ const {renderRexEngine} = require('catpaw-drive-core/rex-build');
39
+ ```
40
+
41
+ 配置约束:
42
+
43
+ | 字段 | 规则与作用 |
44
+ | --- | --- |
45
+ | namespace | 仅小写字母、数字、点;每个模块唯一,用于本模块原引擎的缓存命名空间 |
46
+ | linkPrefix | **七个小写字母加冒号,总长度 8**,例如 `demopan:`;每个模块唯一 |
47
+ | idPrefix | 仅小写字母和连字符,例如 `demo-pan-` |
48
+ | title | 模块显示标题;对外作者信息由外层 WidgetMetadata 设置 |
49
+ | site | 自己网站 origin;示例占位域名不能作为真实搜索服务 |
30
50
 
31
- // 每次业务入口先绑定本模块的有效配置;账号非空优先,留空继承 getConfig。
32
- core.bind({});
33
- const share = core.parseShare({ url: 'https://drive.uc.cn/s/SHARE_ID', password: '' });
34
- if (!share) throw new Error('无法识别分享链接');
35
- if (!core.enabled(share.provider)) throw new Error('该网盘未启用');
36
- const link = core.encode({ action: 'detail', title: '作品标题', shares: [share] });
37
- const detail = await core.loadDetail(link);
38
- const episode = detail && !Array.isArray(detail) && detail.episodeItems?.[0];
39
- if (episode) {
40
- const resources = await core.loadResource({ link: episode.link });
41
- // 使用 resources 中的 url 及 headers/customHeaders 交给宿主播放。
51
+ 对外发布后保持 metadata.id、namespace、linkPrefix、idPrefix 稳定,保留历史链接。外层只声明一份自己的 `WidgetMetadata`,不要再追加全盘模块元数据。生成引擎中的元数据在 IIFE 内部。不要把词法 `Widget` 改为依赖 `globalThis.Widget`。
52
+
53
+ npm 包随附完整示例 `examples/drive-core-module/`。复制到独立工程后执行 `npm install && npm run build`,产物是 `dist/demo.js`。示例由使用者输入片名、年份和分享地址,可搜索、展示分集及从 TMDB 匹配播放;它没有虚构的网站 API。接入实际网站时替换其 discovery。
54
+
55
+ ## 2. 必须注册 TMDB 资源入口
56
+
57
+ ```js
58
+ var WidgetMetadata = {
59
+ id: 'example.demo.pan', title: '我的网盘资源', author: 'YourName',
60
+ version: '1.0.0', requiredVersion: '0.0.1', detailCacheDuration: 1800,
61
+ globalParams: [],
62
+ search: {title: '搜索', functionName: 'search', params: [
63
+ {name: 'keyword', title: '关键词', type: 'input', value: ''}
64
+ ]},
65
+ modules: [{
66
+ id: 'loadResource', title: '加载网盘资源', functionName: 'loadResource',
67
+ type: 'stream', cacheDuration: 0, params: []
68
+ }]
69
+ };
70
+ ```
71
+
72
+ Rex 从 NightFrame / TMDB 进入影视时调用 `loadResource(params)`。只实现 `search`、`loadDetail` 或普通 list 入口,无法完成自动资源加载。模块必须启用;最终打包文件必须包含全局 `loadResource` 函数。
73
+
74
+ 典型输入(原样透传宿主其他字段及 signal):
75
+
76
+ ```js
77
+ {
78
+ title: '三体', seriesName: '三体', type: 'tv', year: 2023,
79
+ tmdbId: 204541, season: 1, episode: 15
80
+ }
81
+ ```
82
+
83
+ 电影使用 `type: 'movie'`;剧集必须有有效 episode,season 缺省为 1。不要补成其他剧集,也不要仅凭关键词接受年份冲突的资源。
84
+
85
+ ## 3. 运行时引擎 API
86
+
87
+ `DriveEngine` 为前述表达式的运行结果;它没有 npm import。以下为 1.0.0 的公开接入方法:
88
+
89
+ | 方法 | 作用 |
90
+ | --- | --- |
91
+ | bind(params) | **每个 search / loadDetail / loadResource 调用开始时执行**,绑定参数并读取当前账号;不要仅在初始化时调用 |
92
+ | parseShare({url, password?, note?}) | 有效时返回标准分享描述,无效返回 null;由引擎识别网盘及提取码 |
93
+ | enabled(provider) | 当前通用开关是否允许该盘 |
94
+ | encode(info) / decode(link) / isLink(link) | 生成、读取和识别本模块持久链接;不要自行拼接编码格式 |
95
+ | matchesSiteTitle(title, params) | 校验网站片名与本次目标 |
96
+ | prepareDirectoryIdentity(year, params) | **异步**年份/季度身份判断,返回 boolean;false 时舍弃该候选 |
97
+ | candidateLimit() | 当前每盘候选数量配置 |
98
+ | loadDetail(link) | detail 链接返回详情及 episodeItems;play 链接返回带 videoUrl/headers 的播放项数组 |
99
+ | loadResource(params, discovery?) | 资源匹配和取链,返回包含 url 的资源数组;原样返回以保留头、画质和字幕等字段 |
100
+ | owner() | 当前资源匹配任务的取消/截止时间上下文 |
101
+ | request(spec, requestFn, owner) | 在该上下文内调度网站请求,限制 timeoutMs 并检查失效 |
102
+ | clear() | 原引擎目录/相关缓存清理入口;网站自身缓存需开发者一起清理 |
103
+
104
+ provider 为 `quark`、`baidu`、`115`、`uc`、`123`、`xunlei`、`guangya`、`yidong`、`tianyi`。
105
+
106
+ 详情跳转应保留引擎生成的分集 link,播放时重新解析为新鲜 URL;不要把临时下载地址当永久历史链接,不要丢弃 `headers` / `customHeaders`。分集封面可由网站适配器补齐 coverUrl、posterPath、backdropPath。
107
+
108
+ ### 网站 discovery 契约
109
+
110
+ `engine.isLink(params.link)` 为 true 时走已有网盘链接;其余 TMDB 调用**必须传入 discovery**。遗漏时会进入引擎原全盘搜索路径,不能将自己的网站 origin 当作该协议接口。
111
+
112
+ ```js
113
+ async function loadResource(params = {}) {
114
+ DriveEngine.bind(params);
115
+ if (DriveEngine.isLink(params.link)) return DriveEngine.loadResource(params);
116
+ const discovery = {
117
+ identity: 'my-site:v1:public', // 域名/站点账户身份改变时也要改变;不要放明文凭据
118
+ async search(query) {
119
+ // 由你实现 websiteSearch;网站请求在 engine.owner() 的预算中执行。
120
+ const titles = await websiteSearch(query.keyword, DriveEngine.owner());
121
+ const rows = [];
122
+ for (const item of titles) {
123
+ if (!DriveEngine.matchesSiteTitle(item.title, query)) continue;
124
+ if (!await DriveEngine.prepareDirectoryIdentity(item.year, query)) continue;
125
+ for (const ref of item.shareReferences) {
126
+ if (!DriveEngine.enabled(ref.provider)) continue;
127
+ rows.push({
128
+ id: item.id + ':' + ref.id, cpSiteCardId: item.id,
129
+ type: 'url', title: item.title, provider: ref.provider,
130
+ link: DriveEngine.encode({action:'detail', title:item.title,
131
+ site:origin, shares:[], siteRef:ref.id})
132
+ });
133
+ }
134
+ }
135
+ return rows;
136
+ },
137
+ async read(row) {
138
+ const info = DriveEngine.decode(row.link);
139
+ const url = await websiteShareUrl(info.siteRef, DriveEngine.owner());
140
+ const share = DriveEngine.parseShare({url});
141
+ if (!share || share.provider !== row.provider) return null;
142
+ return {action:'detail', title:info.title, site:origin, shares:[share]};
143
+ }
144
+ };
145
+ return DriveEngine.loadResource(params, discovery);
42
146
  }
43
147
  ```
44
148
 
45
- CommonJS 使用 `require('catpaw-drive-core')`。浏览器脚本 `dist/drive-core.global.js` 提供 `DriveCore` 全局对象。Rex 模块需要在构建阶段将 npm 包打入单文件,再使用原模块加密发布流程;仅安装 npm 包不会让 Rex 在运行时支持 npm import。
149
+ 上面 `websiteSearch`、`websiteShareUrl`、`origin` 由具体网站实现,不能直接运行;包内分享示例无需这些占位函数。`cpSiteCardId` 标识同一个网站影视条目,`id` 区分分享。search 返回未取分享的候选,read 在引擎调度时再解引用;保持原网站顺序,不要先 Promise.all 获取所有分享、预先转存或预先取全部播放地址。
46
150
 
47
- ## 宿主接口
151
+ 网站请求形态:
48
152
 
49
- - `namespace`:必填,每个模块使用独立值,例如 `your-module.pan`,仅小写字母、数字、点和短横线,最多 96 字符。
50
- - `http.get(url, options)`、`http.post(url, body, options)`:必填,返回 Promise,结果含 `status`/`statusCode`、`data`、`headers`。请求配置沿用 Rex 风格的 `timeout`(通常按毫秒);可选 `http.request` 接收 Rex 原生请求参数,其中 `timeout` 按秒传递。宿主有差异时请自行适配。
51
- - `storage.get(key)`、`storage.set(key, value)`:必填同步字符串存储。核心自动在 key 前加模块 namespace。
52
- - `sharedCache.get(namespace, key)`、`set(namespace, key, value)`:可选同步共享字符串缓存。自动加模块 namespace;未提供时使用实例内存缓存。
53
- - `getConfig()`:可选同步函数,返回 schemaVersion 1 的账号配置对象或 null,不要返回 Promise。账号只通过本函数读取,核心不会直接访问宿主的全局共享账号记录。
54
- - `tmdb.get(path, options)`:可选,用于可信影视别名和年份信息;由调用方实现。
55
- - `site`:可选的调用方 HTTP(S) origin,不含结尾斜杠,默认 `https://drive-core.invalid`。仅作为来源身份,不会自动进行网站搜索。
153
+ ```js
154
+ const response = await DriveEngine.request(
155
+ {url, method:'GET', timeoutMs:10000},
156
+ spec => Widget.http.request(spec),
157
+ DriveEngine.owner()
158
+ );
159
+ ```
160
+
161
+ 此处需要宿主支持 `Widget.http.request` 且正确实现 timeoutMs。只有 get/post 的宿主需自己映射参数和响应,不能盲目替换为 fetch。网站请求默认不要携带网盘 Cookie。网站登录、验证码和站点限流属于网站适配器职责。
56
162
 
57
- 转存根目录为 `drive-core.<namespace>`;每个模块只扫描自己的转存目录,不扫描现有 Rex 的 `ftv-cache`。namespace 应保持稳定,改名后原目录需由用户自行处理。
163
+ ## 4. 直接使用 CatPaw 通用配置
58
164
 
59
- 同一业务调用内不要并行更换同一实例的账号。多个模块、独立账号和并行 session 使用独立实例及 namespace。
165
+ 正式通用域:
60
166
 
61
- ## 账号配置
167
+ ```js
168
+ const raw = Widget.sharedCache.get('catpaw.drive-accounts.v1', 'credentials');
169
+ ```
62
170
 
63
- `getConfig()` 对象至少包含:
171
+ 返回值为**同步 JSON 字符串**,未保存或宿主不支持时可能缺失或抛错。它不是对象,也不是 Promise。完整示例字符串解析后的内容如下(所有凭据都是占位值):
64
172
 
65
173
  ```json
66
174
  {
67
175
  "schemaVersion": 1,
68
176
  "revision": 1,
69
- "quarkCookie": "",
70
- "baiduCookie": "",
71
- "cookie115": "",
72
- "guangyaAuth": "{\"accessToken\":\"ACCESS\",\"refreshToken\":\"REFRESH\",\"deviceId\":\"DEVICE\"}",
73
- "xunleiAuth": "",
74
- "tianyiCookie": "",
75
- "driveGuangyaEnabled": "enabled"
177
+ "quarkCookie": "QUARK_COOKIE",
178
+ "baiduCookie": "BDUSS=BAIDU_COOKIE",
179
+ "cookie115": "UID=115_COOKIE",
180
+ "xunleiAuth": "{\"accessToken\":\"XUNLEI_ACCESS\",\"refreshToken\":\"XUNLEI_REFRESH\",\"deviceId\":\"XUNLEI_DEVICE\"}",
181
+ "guangyaAuth": "{\"accessToken\":\"GUANGYA_ACCESS\",\"refreshToken\":\"GUANGYA_REFRESH\",\"deviceId\":\"GUANGYA_DEVICE\"}",
182
+ "tianyiCookie": "TIANYI_COOKIE",
183
+ "quarkQuality": "auto",
184
+ "resourceCategory": "",
185
+ "maxShareCandidates": "2",
186
+ "indexTimeoutSeconds": "10",
187
+ "driveQuarkEnabled": "enabled",
188
+ "driveBaiduEnabled": "enabled",
189
+ "driveUcEnabled": "enabled",
190
+ "drive115Enabled": "enabled",
191
+ "drive123Enabled": "enabled",
192
+ "driveXunleiEnabled": "disabled",
193
+ "driveGuangyaEnabled": "disabled",
194
+ "driveYidongEnabled": "disabled",
195
+ "driveTianyiEnabled": "disabled",
196
+ "transferAutoCleanup": "disabled",
197
+ "candidateFailureFallback": "enabled"
76
198
  }
77
199
  ```
78
200
 
79
- 光鸭、迅雷界面虽可分三个输入框,共享快照仍分别使用 `guangyaAuth`、`xunleiAuth` 字符串;值可以是访问令牌或整套 JSON。核心沿用现有凭证别名、迅雷 Web/App 识别和续期逻辑。
201
+ 即 `raw === JSON.stringify(上面对象)`。**光鸭、迅雷 UI 各有三个独立输入字段,但共享快照仍分别只用 guangyaAuth / xunleiAuth 一个字符串承载整套凭据。** 不是六个顶层字段,也不是两个对象。只填访问令牌时可为原始令牌字符串;历史 JSON 凭据可能含其他字段,应原样保留。外层 JSON.parse 一次后,只有要查看套内字段时才尝试再次解析 Auth 字符串。
80
202
 
81
- `core.bind(params)` 接受本模块的 `quarkCookie`、`baiduCookie`、`cookie115`、`tianyiCookie`,以及 `guangyaAuth / guangyaRefreshToken / guangyaDeviceId`、`xunleiAuth / xunleiRefreshToken / xunleiDeviceId`。Cookie 非空优先,留空继承共享配置。光鸭、迅雷任一输入非空时使用本模块整套凭证,三项全空才继承;不会混用两个账号的令牌和设备号。`credentialSource: 'local'` 可停用共享账号继承。
203
+ | 配置 | 值与默认行为 |
204
+ | --- | --- |
205
+ | schemaVersion / revision | 数字 1 / 正安全整数;revision 随发布共享配置更新,不作为时间戳 |
206
+ | 六个账号字段 | 字符串;空字符串表示未配置。UC、123、移动当前使用免登录路径,没有对应 Cookie 输入 |
207
+ | 九盘 Enabled | 字符串 `enabled` / `disabled`;夸克、百度、115、UC、123 默认开,其余默认关 |
208
+ | quarkQuality | `auto` / `origin` / `transcode`,默认 auto |
209
+ | resourceCategory | `''` / `8k` / `4k` / `1080p` / `other`,仅控制展示分类,不提升视频分辨率 |
210
+ | maxShareCandidates | 字符串 `1` / `2` / `3` / `5`,默认 `2` |
211
+ | indexTimeoutSeconds | 5~30 的整数字符串,默认 `10`;保留10秒预算,不通过重构自动延长 |
212
+ | candidateFailureFallback | enabled / disabled,默认 enabled;提取失败时每盘最多候补一次 |
213
+ | transferAutoCleanup | enabled / disabled,默认 disabled;开启会清理夸克、迅雷、光鸭超2小时未用的转存文件,并清空对应账号整个回收站 |
82
214
 
83
- 共享快照还可包含 `driveQuarkEnabled / driveBaiduEnabled / driveUcEnabled / drive115Enabled / drive123Enabled / driveXunleiEnabled / driveGuangyaEnabled / driveYidongEnabled / driveTianyiEnabled`,值为 `enabled` 或 `disabled`。迅雷、光鸭、移动、天翼默认关闭,其他五盘默认开启。配置本地账号不会自动启用关闭的网盘。
215
+ `renderRexEngine` 已包含读取、校验、继承及失效处理,通常只需 `bind(params)`;**不要再手动 JSON.parse 后覆盖 params 所有字段**,否则容易破坏本地覆盖规则及配置变更检查。
84
216
 
85
- `quarkQuality`、`maxShareCandidates`、`indexTimeoutSeconds` 等现有共享设置继续适用;配置变更需更新 revision,并在下次操作前重新 bind。令牌轮换保存到模块自己的会话存储,不回写共享账号配置。
217
+ 需要仅接入共享配置、继续用自己网盘实现的模块,可以只读此 JSON,但必须自己实现字段校验、缺失处理、账号变更导致的缓存/在途任务失效和全部网盘协议。诊断时只展示“已配置/未配置”与 revision,不打印 raw、Cookie、令牌或带提取码的内部链接。读取后验证 schemaVersion、revision;不支持的 schema 应报不支持,不能当作其他账号格式继续取链。
86
218
 
87
- ## API
219
+ 使用者步骤:安装正式“猫 · 通用配置”→填写账号和开关→执行“保存/更新共享配置”,或搜索 **“保存账号”**。仅保存输入表单不代表已发布共享快照。共享范围是当前 Rex 宿主环境;不保证自动跨设备同步。外部模块不能覆盖作者的共享配置,只读继承即可。
88
220
 
89
- | 方法 | 用途 |
90
- |---|---|
91
- | `bind(params)` | 绑定当前模块配置和账号 |
92
- | `enabled(provider)` | 查询网盘开关 |
93
- | `parseShare({url,password?,note?})` | 识别分享;失败返回 null |
94
- | `encode(descriptor)` / `decode(link)` | 编解码当前引擎资源描述 |
95
- | `isLink(link)` | 判断是否当前资源链接前缀 |
96
- | `loadDetail(link)` | 读取分享目录和分集;播放描述可能返回资源数组 |
97
- | `loadResource(params, discovery?)` | 解析播放资源;自动选集可传 seriesName、type、year、season、episode |
98
- | `clear()` | 清理当前模块的目录缓存 |
99
- | `candidateLimit()` | 查询当前候选档位 |
100
- | `matchesSiteTitle(title, params)` | 使用共享标题匹配规则 |
101
- | `prepareDirectoryIdentity(year, params)` | 准备可信年份信息 |
102
- | `owner()` / `request(spec, request, owner?)` | 网站适配器共享当前预算与取消检查 |
221
+ ### 本地覆盖与 Beta 隔离
103
222
 
104
- 目录、转存和播放操作可能改变已登录网盘中的文件。`transferAutoCleanup` 默认关闭;启用后,夸克、迅雷和光鸭按两小时未使用时间清理本模块转存文件,并沿用来源引擎的**账号整个回收站清空行为**,其中包括其他模块或用户删除的内容。调用方应明确告知用户这一行为,谨慎启用。账号、播放地址和带认证信息的请求不得写入公开日志。
223
+ 示例默认只使用共享账号。若需要本模块覆盖,在 metadata 添加 `credentialSource`(shared/local)及与通用配置同名的输入项,原样传给 `bind(params)`。
105
224
 
106
- ## 网站发现由调用方提供
225
+ - `shared`:普通 Cookie 本地非空优先,空值继承共享。
226
+ - 光鸭本地三项 `guangyaAuth` / `guangyaRefreshToken` / `guangyaDeviceId`,迅雷本地三项 `xunleiAuth` / `xunleiRefreshToken` / `xunleiDeviceId`:任一非空就以**整套本地值**为准,不能与共享字段逐项混合;三项全空才继承共享。
227
+ - `credentialSource:'local'`:不继承共享账号,但通用网盘开关仍生效,不应据此承诺所有配置隔离。
228
+ - Beta 共享域是 `catpaw.beta.drive-accounts.v1`,与正式域分开。1.0.0 通用 renderer 默认正式域;CatPaw 的 Beta 构建另有整体身份/命名空间变换。仅改 namespace 不会自动切换共享账号域,外部模块不要擅自同时读取两域或静默回退。
107
229
 
108
- core 不内置全盘或其他资源站点的搜索后端。已有模块自行完成搜索、详情和分享地址提取,再将标准化分享传入 core。需要复用自动匹配调度时,可传入 `discovery`:
230
+ ## 5. 行为保持与迁移范围
109
231
 
110
- - `identity`:网站账号/来源的稳定身份,账号变化时更新。
111
- - `search(params)`:返回含 `title`、`provider` 和 `link` 的候选条目;link 可用 `core.encode(descriptor)` 生成。
112
- - `read(row, params)`:返回包含 title、shares 的 `action: 'detail'` 描述或 null。
232
+ 1.0.0 的 `/rex-build` 来自原 Rex 引擎,保留词法 Widget、原缓存语义、账号读取、链接、转存目录、取消检查及资源匹配预算。仅按作者要求移除固定日历使用期限;令牌和临时播放地址的自然过期仍有效。
113
233
 
114
- 没有 discovery、也没有直接资源 link 时返回空结果,不向任何默认搜索网站请求。
234
+ 引擎继续使用原转存目录策略(含 `ftv-cache`),不承诺每个 namespace 都独占远端文件夹。namespace 隔离模块本地键,通用账号跨模块共享。不要随意修改输出字符串里的存储键、目录、并发、排序和函数位置。
115
235
 
116
- ## 版本与有效期
236
+ `renderDriveModule(siteId, template)` 供 CatPaw 已有站点的固定槽位迁移,接受的布局限定于包内快照;**它不是外部新网站注册接口**。外部新开发使用 renderRexEngine。将旧模块改为新引擎时,需迁移其旧 link/缓存契约;不能假设任意旧模块的 id、链接和行为会自动兼容。
117
237
 
118
- `version` 为 npm 包版本,`engineVersion` 为来源引擎版本。npm 核心包没有日历使用期限;构建时移除了来源引擎的到期检查。网盘令牌和播放地址自身的过期、续期与刷新规则继续正常执行。
238
+ 已有17个 CatPaw Beta 的整文件输出与冻结原版逐字节比对通过(仅移除日历期限)。同一引擎已在 NightFrame → TMDB《嫁金钗》S1E15 展示资源卡片并播放验证。该证据覆盖这些模块和当时网络条件;外部网站适配器仍需验证自己的搜索、账号和真实播放。
119
239
 
120
- 发布前验证以离线协议回放、混淆产物和 npm tarball 消费端检查为主,不保证真实账号、网盘权限、接口变化及宿主差异下所有播放均可用。pansoo、pioz 等模块需要其作者实际接入和验证,安装本包不会自动修改已有模块。
240
+ ## 6. 发布前检查
121
241
 
122
- ## 使用授权
242
+ 1. 独立目录安装锁定的公共 npm 包,构建单文件;不要依赖 CatPaw 私有源码或工作区路径。
243
+ 2. Rex 中启用模块并保存正式通用配置;先用 UC 免登录分享验证目录,再验证自己的网盘账号。
244
+ 3. 验证搜索→详情→分集→播放;重新进入运行环境后旧分集 link 仍能取新 URL,播放头保留。
245
+ 4. 从 NightFrame / TMDB 进入同名同年份影视,验证电影及剧集季集,确认真正调用 stream loadResource;错误片名、年份、季集不出错误资源。
246
+ 5. 验证10秒预算、取消、切账号、禁用网盘、改通用配置、清缓存、冷/热目录、分享失效等场景;不得把全部异常吞成空数组。
247
+ 6. 保留既有模块身份和资源下载地址,原安装项更新。以后升级 core 时重新生成并比较产物;npm 升级本身不会修改已安装的 Rex 单文件。
123
248
 
124
- 包当前标记为 `UNLICENSED`,公开下载不授予开源许可证;集成和分发授权请联系作者 balge2019。
249
+ 包以混淆产物公开分发,无 source map;混淆不等同于加密,也不应用来隐藏凭据。当前 package.json 沿用 `UNLICENSED`,公开下载不等同于授予开源许可,外部分发授权请与作者确认。