@nsnanocat/preference-panes 0.5.0 → 0.7.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 +31 -124
- package/dist/module/app.mjs +1030 -0
- package/dist/module/index.html +14 -0
- package/dist/preference-panes.config.js +842 -0
- package/dist/preference-panes.mjs +935 -825
- package/dist/preference-panes.proxy.js +1726 -2121
- package/package.json +62 -66
- package/src/BoxJS.mjs +86 -0
- package/src/Store.mjs +127 -0
- package/src/browser/app.mjs +24 -148
- package/src/browser/client.d.mts +150 -0
- package/src/browser/client.mjs +191 -212
- package/src/browser/components.mjs +59 -0
- package/src/browser/index.d.ts +19 -152
- package/src/browser/index.mjs +60 -5
- package/src/browser/module.html +14 -0
- package/src/browser/panel.css +221 -221
- package/src/browser/panel.mjs +455 -514
- package/src/build.mjs +31 -0
- package/src/index.d.ts +227 -133
- package/src/index.mjs +3 -6
- package/src/lib/boxjs.mjs +77 -99
- package/src/lib/response.mjs +16 -0
- package/src/lib/settings-path.mjs +10 -23
- package/src/proxy/config.mjs +14 -0
- package/src/proxy/handler.mjs +40 -27
- package/src/proxy/response.mjs +16 -0
- package/dist/preference-panes.request.js +0 -2124
- package/dist/settings/app.mjs +0 -1044
- package/dist/settings/home.css +0 -134
- package/dist/settings/index.html +0 -15
- package/dist/settings/panel.css +0 -325
- package/src/PreferencesHandler.mjs +0 -50
- package/src/SettingsHandler.mjs +0 -142
- package/src/browser/home.css +0 -134
- package/src/browser/site.html +0 -15
- package/src/proxy/request.mjs +0 -5
package/README.md
CHANGED
|
@@ -1,146 +1,53 @@
|
|
|
1
1
|
# @nsnanocat/preference-panes
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PreferencePanes **只负责具体模块的设置页**。外部输入为这个模块的 BoxJS JSON 和可选 CSS;省略 CSS 使用默认样式。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
项目定制主页由 github.io 等调用方独立维护。主页只探测各模块的 JSON 是否可访问,并提供入口;它的布局、品牌、按钮目录不属于 PreferencePanes。本包不生成主页、模块选择目录或安装选择器。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
| --- | --- |
|
|
9
|
-
| src/SettingsHandler.mjs | 模块存储桥接 class |
|
|
10
|
-
| src/PreferencesHandler.mjs | 存储桥接与声明式静态资源响应 |
|
|
11
|
-
| src/browser/ | WebView 控件、内存会话和样式 |
|
|
12
|
-
| src/lib/ | 前端 BoxJS 与通用路径解析 |
|
|
13
|
-
| src/proxy/ | 代理宿主打包入口 |
|
|
14
|
-
| test/ | 类型与行为回归测试 |
|
|
15
|
-
| examples/ | BoxJS、HTML 和 Surge 集成示例 |
|
|
16
|
-
| apifox/ | 接口说明、原生 JSON 与生成器 |
|
|
17
|
-
| .github/ | CI、双平台发布工作流 |
|
|
18
|
-
| dist/ | 构建产物,不提交 Git |
|
|
7
|
+
## 导入一个模块
|
|
19
8
|
|
|
20
|
-
|
|
9
|
+
```js
|
|
10
|
+
import { mount } from "@nsnanocat/preference-panes/browser";
|
|
11
|
+
import boxjs from "./Module.boxjs.json" with { type: "json" };
|
|
21
12
|
|
|
22
|
-
|
|
13
|
+
const page = mount(boxjs, ".pp-panel { --pp-accent: #16866a; }");
|
|
14
|
+
// 离开模块页时释放视图、样式、监听器和会话。
|
|
15
|
+
// Release the view, styles, listeners and session when leaving the module page.
|
|
16
|
+
page.destroy();
|
|
17
|
+
```
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
import { SettingsHandler } from "@nsnanocat/preference-panes";
|
|
19
|
+
调用后直接显示该 JSON 对应的模块设置,不先显示入口页,也不按当前 URL 选择其它模块。一次输入必须恰好包含一个可推导模块;多模块文件会报错,不会生成菜单。支持字段数组、单 app 和只包含该模块的 apps 订阅。
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
origin: "https://example.org",
|
|
29
|
-
storageKey: "Root",
|
|
30
|
-
module: "Module"
|
|
31
|
-
});
|
|
32
|
-
const response = await handler.handle($request);
|
|
33
|
-
// 使用现有代理宿主的 done 适配。
|
|
34
|
-
// Adapt the response with the existing proxy host's done function.
|
|
35
|
-
~~~
|
|
21
|
+
`@Root.Module.Settings.key` 推导根、模块和字段路径;app 的 id/name 不替代存储映射。模块名、标题、说明、图标和选项来自 BoxJS。CSS 是正文字符串,作用于该模块文档;嵌入项目主页时应使用独立模块页面或 iframe,避免样式作用到宿主。
|
|
36
22
|
|
|
37
|
-
|
|
23
|
+
## 构建模块产物
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
| HEAD /api/Module/… | 确认路由可达,不读取存储 |
|
|
42
|
-
| GET /api/Module/Settings/key | 返回原值,缺失返回 404 |
|
|
43
|
-
| POST /api/Module/Settings/key | 以任意 JSON 值替换该位置,成功 200 |
|
|
44
|
-
| DELETE /api/Module/Settings/key | 删除键或子树,不存在也成功 |
|
|
45
|
-
| GET /api/Module/Caches | 返回所有 Caches |
|
|
46
|
-
| DELETE /api/Module/Caches | 清空缓存,保留 Settings |
|
|
47
|
-
| DELETE /api/Module/ | 重置模块全部数据,保留 Root 下其它模块 |
|
|
25
|
+
```js
|
|
26
|
+
import { build } from "@nsnanocat/preference-panes";
|
|
48
27
|
|
|
49
|
-
|
|
28
|
+
const files = await build(boxjs, css);
|
|
29
|
+
```
|
|
50
30
|
|
|
51
|
-
|
|
31
|
+
返回相对路径到正文的映射,调用方写出并托管即可。每次只生成该模块的 HTML、CSS、BoxJS、读写脚本、配置 Mock 和公共启动 JS。模块文件名独立,可以合并不同模块的产物;不会输出或覆盖项目的 `settings/index.html`。
|
|
52
32
|
|
|
53
|
-
|
|
54
|
-
import { mountPreferencePanes } from "@nsnanocat/preference-panes/browser";
|
|
55
|
-
import "@nsnanocat/preference-panes/browser/panel.css";
|
|
33
|
+
直接访问 `/settings/{module}` 时,启动器先导入 `/configs/{module}` JSON 与该模块 CSS,再调用 mount。JSON 缺失或与 URL 不符时不生成表单。项目主页可自行 HEAD `/configs/{module}` 判断入口可用性;PreferencePanes 不接管主页探测逻辑。
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
// 卸载时调用 panel.destroy()。
|
|
59
|
-
// Call panel.destroy() when unmounting.
|
|
60
|
-
~~~
|
|
35
|
+
## 模块页行为
|
|
61
36
|
|
|
62
|
-
|
|
37
|
+
渲染器使用已导入的 JSON 创建控件,只 GET 一次设置子树;不会再次请求配置或探测其它模块。打开/刷新模块文档重新导入,再读取设置。单选为下拉框,多选为二级选项页;二级返回不刷新设置值。
|
|
63
38
|
|
|
64
|
-
|
|
39
|
+
修改立即串行 POST,200 后更新当前内存并通知;失败恢复已保存值。保留 Caches 查看/清空和模块重置,不展示逐字段保存或删除按钮。API 按 BoxJS 根和模块用 util 读写任意 JSON 路径,不重复校验控件或枚举。
|
|
65
40
|
|
|
66
|
-
|
|
41
|
+
## 文件导入测试台
|
|
67
42
|
|
|
68
|
-
|
|
43
|
+
```sh
|
|
44
|
+
npm run preview
|
|
45
|
+
```
|
|
69
46
|
|
|
70
|
-
|
|
47
|
+
浏览器中选择一个模块的 JSON、可选 CSS,点击“生成”,在独立 iframe 查看模块页。不会自动装入示例,不会生成项目主页。CSS 隔离在预览文档内;测试数据只保存在内存,不访问用户代理存储。
|
|
71
48
|
|
|
72
|
-
##
|
|
49
|
+
## 维护
|
|
73
50
|
|
|
74
|
-
|
|
51
|
+
遵循 AGENTS.md 与通用 Biome 配置。运行 `npm run check` 和 `npm run apifox:check` 验证代码、类型、行为与文档。0.7.0 采用单模块双输入接口,运行时无额外 npm 依赖;旧的主页生成和安装对象接口不再提供。
|
|
75
52
|
|
|
76
|
-
|
|
77
|
-
{
|
|
78
|
-
"name": "Example",
|
|
79
|
-
"icon": "/assets/logo.png",
|
|
80
|
-
"sectionTitle": "模块",
|
|
81
|
-
"apps": [{ "module": "Module", "name": "Example Module", "icon": "/assets/module.png" }]
|
|
82
|
-
}
|
|
83
|
-
~~~
|
|
84
|
-
|
|
85
|
-
`apps[].module` 明确对应 `/settings/{module}`、`/configs/{module}` 和 `/api/{module}/`,不从名称推断。这个菜单 JSON 只声明入口;实际字段仍从配置 Mock 返回的 BoxJS 生成。菜单可选 `desc`、`iconDark` 和 `stylesheets`;`iconDark` 是显式暗色图标扩展,不能把 BoxJS 的透明/彩色 icons 当成亮暗版本。stylesheets 仅加载接入方指定的 HTTP(S) 样式,不加载业务 JS。
|
|
86
|
-
|
|
87
|
-
根页面每次进入重新 HEAD 探测,菜单 JSON 在当前文档只读取一次;模块页直接打开时无需先读菜单。图片与额外样式由托管站点提供。
|
|
88
|
-
|
|
89
|
-
代理优先使用原生 Mock 提供配置和页面。存储 API 和没有原生 Mock 的资源请求,由独立代理脚本处理。托管站点维护 installation JSON(origin/storageKey/module/resources),并用包内已经构建好的代理运行时生成安装文件:
|
|
90
|
-
|
|
91
|
-
~~~js
|
|
92
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
93
|
-
|
|
94
|
-
const runtime = await readFile(new URL(import.meta.resolve("@nsnanocat/preference-panes/dist/preference-panes.proxy.js")), "utf8");
|
|
95
|
-
const installation = JSON.parse(await readFile("installation.json", "utf8"));
|
|
96
|
-
await writeFile("Module.request.js", `${runtime}\nPreferencePanes.runPreferences(${JSON.stringify(installation)});\n`);
|
|
97
|
-
~~~
|
|
98
|
-
|
|
99
|
-
业务插件的代理规则直接引用托管站点的 Module.request.js;无需 npm 依赖、业务 Request 接入代码或额外构建脚本。生成文件把可信安装映射与通用执行端放在一起,不依赖平台是否支持 $argument,Quantumult X 也使用同一文件。所有代理平台判断、done 适配、异常响应、资源下载和读写都由本包完成。API 不下载安装 JSON 或 BoxJS。
|
|
100
|
-
|
|
101
|
-
以下是包内部处理器接受的安装映射形状;也可供需要手动集成的宿主使用:
|
|
102
|
-
|
|
103
|
-
~~~js
|
|
104
|
-
import { PreferencesHandler } from "@nsnanocat/preference-panes";
|
|
105
|
-
|
|
106
|
-
const handler = new PreferencesHandler({
|
|
107
|
-
origin: "https://example.org",
|
|
108
|
-
storageKey: "Root",
|
|
109
|
-
module: "Module",
|
|
110
|
-
resources: [
|
|
111
|
-
{ pattern: "^/configs/Module$", source: "https://example.org/settings/assets/Module.boxjs.json", contentType: "application/json" },
|
|
112
|
-
{ pattern: "^/settings/(?:[a-zA-Z0-9_-]+/?)?$", source: "https://example.org/settings/assets/index.html", contentType: "text/html" }
|
|
113
|
-
]
|
|
114
|
-
});
|
|
115
|
-
const response = await handler.handle($request);
|
|
116
|
-
~~~
|
|
117
|
-
|
|
118
|
-
资源 pattern 匹配 pathname,下载源必须避开拦截路径。只有命中静态资源的 GET/HEAD 才下载文件;API 由 SettingsHandler 直接处理,读写不会下载 BoxJS。业务插件只保留安装规则和配置 Mock;其业务请求脚本不负责设置接口。
|
|
119
|
-
|
|
120
|
-
## BoxJS 兼容
|
|
121
|
-
|
|
122
|
-
前端接受字段数组、单 app 和 apps 订阅。字段 ID 为 @根.模块.子路径.键;模块归属来自字段 ID,不能用 app 名称推断。
|
|
123
|
-
|
|
124
|
-
- name/val/type/desc/items:控件标题、默认值、类型、说明和选项。
|
|
125
|
-
- boolean/selects/checkboxes/text/textarea/number:支持的控件类型。
|
|
126
|
-
- placeholder/rows/autoGrow:输入提示、多行基础行数和自动高度。
|
|
127
|
-
- app name/author/desc/descs/repo:纯文本标题、作者、说明和项目链接。
|
|
128
|
-
- icon/icons:显式图标优先,原版 icons 为透明/彩色顺序,不是亮暗顺序。
|
|
129
|
-
- script:仅保留元数据,不下载或执行。
|
|
130
|
-
|
|
131
|
-
不执行 BoxJS HTML、脚本、动态字符串 items,不通过 keys 推导额外字段。WebView 使用原生网络与对象访问,不打入 util 的网络、存储或 Lodash polyfill。代理安装的 storageKey/module 应由接入方与 BoxJS 路径保持一致。
|
|
132
|
-
|
|
133
|
-
## 构建与发布
|
|
134
|
-
|
|
135
|
-
~~~sh
|
|
136
|
-
npm ci --registry=https://registry.npmjs.org/ --@nsnanocat:registry=https://registry.npmjs.org/
|
|
137
|
-
npm run build
|
|
138
|
-
npm run check
|
|
139
|
-
npm run apifox:generate
|
|
140
|
-
npm run apifox:check
|
|
141
|
-
npm pack --dry-run
|
|
142
|
-
~~~
|
|
143
|
-
|
|
144
|
-
构建生成 dist/preference-panes.mjs、读取宿主参数的 dist/preference-panes.request.js、供托管站点配置的 dist/preference-panes.proxy.js,以及可直接部署的 dist/settings/{index.html,app.mjs,panel.css,home.css}。托管仓库直接从依赖包复制,不读取业务插件的前端构建目录。0.5.0 将独立代理执行入口也交给本包,保留既有存储契约与页面交互。
|
|
145
|
-
|
|
146
|
-
[完整接口说明](apifox/guide.md) · [Apifox JSON](apifox/preference-panes.apifox.json) · [同步方式](apifox/README.md) · [发布工作流](.github/RELEASING.md)
|
|
53
|
+
[接口规范](apifox/Specification.md) · [Apifox JSON](apifox/preference-panes.apifox.json)
|