Skip to content

Commit e890961

Browse files
committed
refactor(config-generator): merge configuration details into the preview
Replace the separate generate and detail tabs with one page that has a selection region and a preview region. The preview renders the live generated configuration in the config-details style, matching each line to the config-desc descriptions in Rust, and keeps the generator's validity, error list, and copy and download actions. Retain the parsed config-desc tree and add render_annotated for YAML, TOML, and JSON. Generated members match by name, and duplicate branch members are chosen by their example value while records reuse the sole documented member as a template. Snapshot now exposes preview_lines instead of the raw config description, and outputs without a documented entry fall back to plain serialized lines. Reconcile the TUIC DNS server description with its output and rewrite the reuse example description to document its actual outputs. Drop the mode query switch, add PreviewDocument, and update the Rust tests, both browser regressions, the agent guides, and the TUIC docs. Assisted-by: opencode:deepseek-v4-flash
1 parent 74e4ca9 commit e890961

23 files changed

Lines changed: 564 additions & 349 deletions

‎AGENTS.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ npm ci --prefix config-generator
1818
npm run dev --prefix config-generator
1919
```
2020

21-
Open `http://127.0.0.1:8080/`. No Python or Zensical server is needed. Its application-schema selector currently provides independent TUIC server and client generators, covering multiple users, three certificate modes, SOCKS5 authentication, logging, connections, TCP/UDP forwarding, Quinn/quiche backends, outbound and ACL routing, DNS/GeoData, RESTful management, and HTTP/3 masquerading; "configuration details" browses structured YAML or TOML by enum branch and shows per-field explanations on hover or keyboard focus.
21+
Open `http://127.0.0.1:8080/`. No Python or Zensical server is needed. Its application-schema selector currently provides independent TUIC server and client generators, covering multiple users, three certificate modes, SOCKS5 authentication, logging, connections, TCP/UDP forwarding, Quinn/quiche backends, outbound and ACL routing, DNS/GeoData, RESTful management, and HTTP/3 masquerading. The page has two regions: a selection region with the generator form, and a preview region that renders the live generated config with syntax highlighting, per-line XML explanations on hover or keyboard focus, validation, and copy/download.
2222

2323
When [just](https://just.systems/) is installed, the repository root provides shortcuts:
2424

@@ -46,7 +46,7 @@ Artifacts live in `config-generator/dist/`. Hand the entire directory to a stati
4646

4747
Credentials are generated with the browser Crypto API. All input, validation, and serialization happen locally in WASM; no third-party analytics scripts are loaded, inputs, themes, and credentials are not saved, and configuration is never submitted over the network. Copy and download include plaintext passwords, while the preview hides passwords by default.
4848

49-
The page accepts `schema` and `mode` query parameters for direct links. `schema` is an application-schema ID from `schema/schemas.txt` (currently `tuic-server` or `tuic-client`); `mode` is `generate` or `detail`. The selector and page tabs keep these parameters synchronized without discarding unrelated query parameters or the URL fragment. Unknown schemas safely fall back to the first registered schema.
49+
The page accepts a `schema` query parameter for direct links; it is an application-schema ID from `schema/schemas.txt` (currently `tuic-server` or `tuic-client`). The selector keeps this parameter synchronized without discarding unrelated query parameters or the URL fragment. The legacy `mode` parameter is still read but no longer switches views. Unknown schemas safely fall back to the first registered schema.
5050

5151
## Running the documentation locally
5252

@@ -121,7 +121,7 @@ BROWSER_CHANNEL=chromium node tests/config-generator/browser.mjs
121121

122122
[Config DSL v4](config-generator/AGENTS.md) uses independent XML files to statically describe inputs, defaults, enums, conditions, lists, mappings, and sensitive fields, deserialized with quick-xml + Serde; configuration descriptions are not written with Rust macros or closures. `schema/schemas.txt` registers the XML files embedded in the production selector. The Rust session produces the form view, and Svelte renders it; generic projection and redaction live in `dsl.rs`, generic validation and field linkage in `dsl/rules.rs`, and basic address checks in `validation.rs`. TUIC branding, page sections, hints, cross-field rules, random-value generation declarations, and export commands are also entirely provided by XML. Adding a target application requires a new XML file and one manifest entry; `schema/example.xml` provides a reuse example with no TUIC fields.
123123

124-
Configuration state is modified only by the Rust `Session`. Svelte submits generic field/collection operations and reads field display values, visibility, errors, and previews from `Snapshot`; it does not parse XML, evaluate conditions, or keep a second mutable copy of the configuration. JSON strings cross the WASM boundary, and both field display values and stable row identities are strings, avoiding JavaScript number precision loss. `ui/types.ts` corresponds to the display contract in `session/view.rs`; when changing the contract, update both sides and run the session tests plus both browser test suites. Copy and download obtain the original text through a separate `export` operation rather than reading the redacted preview.
124+
Configuration state is modified only by the Rust `Session`. Svelte submits generic field/collection operations and reads field display values, visibility, errors, and previews from `Snapshot`; per-line preview explanations are matched from `config-desc` in Rust (`Snapshot.preview_lines`), so the frontend only highlights and displays them. It does not parse XML, evaluate conditions, or keep a second mutable copy of the configuration. JSON strings cross the WASM boundary, and both field display values and stable row identities are strings, avoiding JavaScript number precision loss. `ui/types.ts` corresponds to the display contract in `session/view.rs`; when changing the contract, update both sides and run the session tests plus both browser test suites. Copy and download obtain the original text through a separate `export` operation rather than reading the redacted preview.
125125

126126
| Path | Contents |
127127
| --- | --- |

‎config-generator/AGENTS.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@ Svelte 通过 WASM `Engine` 提交 `set`、`set-row`、`add`、`remove`、`gener
5353

5454
## 配置详解
5555

56-
可选的 `config-desc` 区块为独立的“配置详解”视图提供结构化示例和逐项说明。它不读取表单状态,也不参与配置投影、校验或导出;产品字段、示例值和说明仍全部留在 XML 中。页面左侧先选择 `config`、YAML/TOML 格式和该配置声明的任意 `selector`;右侧只显示 `when` 匹配的配置项。每行可用鼠标悬浮或键盘聚焦查看 `description`。前端 `ui/prism.ts` 用 Prism 仅注册 YAML/TOML 语法逐行高亮,颜色由 `--tok-*` 变量在明暗主题下定义;高亮只影响展示,XML 与 Rust 契约不变。右侧头部提供“复制配置”,复制当前 config、格式与 selector 过滤后可见的纯文本。
56+
可选的 `config-desc` 区块为“预览区”提供逐行说明。合并后的页面只有“选择配置区”(表单)和“预览区”两个区域,没有独立的“配置详解”视图或页签;预览区按配置详解的样式显示**表单实时生成**的配置:行号、Prism 逐行高亮、悬浮或键盘聚焦查看 `description`,并叠加生成器的校验结果(可导出状态、错误列表、复制与下载)。`ui/prism.ts` 注册 YAML/TOML/JSON 语法,颜色由 `--tok-*` 变量在明暗主题下定义;高亮只影响展示。
5757

58-
页面级方案来自 `schema/schemas.txt`,与单份 XML 内的输出和 `config-desc/config` 名称无关。页面可通过 `?schema=<schema-id>&mode=generate|detail` 直接选择应用 schema 和生成/详解视图;选择器与页签会同步这些参数并保留其他查询参数和片段。切换 schema 会创建全新会话,不复用上一应用的输入或凭据。
58+
`config-desc` 的 `config` 按 `name` 与顶层输出对应,没有对应说明的输出回退为无说明的纯文本行。生成配置与说明模板按成员名匹配:同名成员互斥时用示例 `value` 选择,记录等动态键(如 `users`、具名 `outbound`)复用对象中唯一的成员作为模板,数组按位置复用元素模板。因此 `config-desc` 的结构应与 `outputs` 保持一致;分支由表单控制,`selector` 不再驱动界面,仅保留用于解析与静态校验。
59+
60+
页面级方案来自 `schema/schemas.txt`,与单份 XML 内的输出和 `config-desc/config` 名称无关。页面可通过 `?schema=<schema-id>` 直接选择应用方案,并保留其他查询参数和片段;`?mode=generate|detail` 兼容读取但不再切换视图。切换 schema 会创建全新会话,不复用上一应用的输入或凭据。
5961

6062
```xml
61-
<config-desc title="配置项详解" description="选择分支并查看字段说明。">
63+
<config-desc title="配置项详解" description="逐行说明生成的配置。">
6264
<config name="server" label="服务端配置" filename="server">
6365
<selector name="backend" label="后端" default="quinn">
6466
<choice value="quinn" label="Quinn"/>
@@ -72,7 +74,7 @@ Svelte 通过 WASM `Engine` 提交 `set`、`set-row`、`add`、`remove`、`gener
7274
</config-desc>
7375
```
7476

75-
`config-desc` 至少包含一个 `config`,每个配置至少有一个结构节点。`config` 的 `name`、`label`、`filename` 必填;`filename` 是不含扩展名的安全文件名,界面根据所选格式追加 `.yaml` 或 `.toml`。`selector` 的 `name`、`label`、`default` 必填,且默认值必须属于其非空 `choice` 列表。
77+
`config-desc` 至少包含一个 `config`,每个配置至少有一个结构节点。`config` 的 `name`、`label`、`filename` 必填;`filename` 是不含扩展名的安全文件名。`selector` 的 `name`、`label`、`default` 必填,且默认值必须属于其非空 `choice` 列表。
7678

7779
结构节点包括 `object`、`array`、`string`、`integer` 和 `boolean`。对象成员必须声明 `name`;数组元素不能声明 `name`。标量使用 `value` 表达显式类型,所有可见配置项使用 `description` 提供说明。`array` 可以包含同类标量或 `object`,不能混合两种形态。可选 `when` 可用于任意层级,使用逗号分隔的 `selector=value` 条件;子节点继承父节点条件。相同对象中的同名成员只有在选择器条件互斥时才合法。渲染器统一处理 YAML 缩进、TOML table、对象数组和标量数组,XML 不含格式专用空格或标点。
7880

‎config-generator/schema/example.xml‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,22 @@
3838
<assert key="last" when="range" message="结束数量不能小于起始数量。"><compare op="gte"><source from="/last" transform="integer"/><source from="/first" transform="integer"/></compare></assert>
3939
<unique collection="entries" key="id" message="项目名称重复。"><source from="id" transform="trim lowercase"/></unique>
4040
</rules>
41-
<config-desc title="清单格式详解" description="此说明同样完全来自替换后的 XML。">
41+
<config-desc title="清单格式详解" description="预览区按当前填写内容生成配置,并逐行显示字段说明。">
4242
<config name="snapshot" label="完整清单" filename="snapshot">
43-
<selector name="visibility" label="可见性" default="team"><choice value="team" label="团队"/><choice value="private" label="私有"/></selector>
44-
<object name="metadata" description="清单元数据。">
45-
<string name="project" value="example" description="清单所属项目的名称。" />
46-
<string name="visibility" value="team" description="团队成员可以读取这份清单。" when="visibility=team" />
47-
<string name="visibility" value="private" description="只有清单所有者可以读取。" when="visibility=private" />
48-
</object>
43+
<string name="title" value="example" description="清单所属项目的名称。" />
44+
<array name="items" description="清单项目列表,按填写顺序输出。">
45+
<object description="单个清单项目。">
46+
<string name="name" value="item" description="项目名称,必须唯一。" />
47+
<boolean name="enabled" value="true" description="项目是否启用。" />
48+
<string name="secret" value="change-this-token" description="项目密钥,属于敏感信息,预览默认脱敏。" />
49+
</object>
50+
</array>
51+
</config>
52+
<config name="selected" label="单项清单" filename="selected">
53+
<string name="item" value="item" description="当前选中项目的名称。" />
54+
</config>
55+
<config name="audit" label="审计信息" filename="audit">
56+
<boolean name="confirmed" value="true" description="清单是否已确认。" />
4957
</config>
5058
</config-desc>
5159
<outputs>

‎config-generator/schema/tuic-server.xml‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,7 @@
425425
<object name="dns" description="DNS 解析配置;未启用时使用操作系统解析器。" when="dns=custom">
426426
<string name="mode" value="custom" description="DNS 模式:system、cloudflare、google、quad9、custom 及对应的 DoT/DoH 变体。" when="dns=custom" />
427427
<array name="servers" description="自定义 DNS 服务器列表,仅在 custom 模式输出。" when="dns=custom">
428-
<object description="自定义 DNS 服务器列表,仅在 custom 模式输出。" when="dns=custom">
429-
<string name="tls" value="//1.1.1.1#cloudflare-dns.com" description="服务器 URL,支持 1.1.1.1、udp://、tcp://、tls:// 与 https://。" />
430-
</object>
428+
<string value="tls://1.1.1.1#cloudflare-dns.com" description="服务器 URL,支持 1.1.1.1、udp://、tcp://、tls:// 与 https://。" />
431429
</array>
432430
<string name="timeout" value="5s" description="可选:单次查询超时;留空使用库默认值。" when="dns=custom" />
433431
<integer name="attempts" value="2" description="可选:单次查询的重试次数;留空使用库默认值。" when="dns=custom" />

0 commit comments

Comments
 (0)