> ## Documentation Index
> Fetch the complete documentation index at: https://yumebox.oom-wg.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 覆写语法参考

> YAML 和 JavaScript 覆写的语义、脚本 API 与故障行为。

本页是覆写系统的语义参考。入门说明见 [覆写](/override/index)。

## 文件类型

| 后缀               | 处理方式                             |
| ---------------- | -------------------------------- |
| `.yaml` / `.yml` | 解析为补丁文档，并按覆写语义合并到当前配置            |
| `.js`            | 执行 `main(profile)`，使用返回对象作为下一版配置 |

空文件会被跳过并记录 warning。未知后缀会中断编译。

## YAML 补丁语义

| 写法                 | 行为                 |
| ------------------ | ------------------ |
| `key: value`       | 标量覆盖；对象递归合并；列表替换   |
| `key-start: [...]` | 插入到列表开头            |
| `key-end: [...]`   | 追加到列表末尾            |
| `key-merge: {...}` | 合并 Map             |
| `key-force: value` | 强制替换整个字段           |
| `<key-end>: value` | 将带修饰符样式的字段名按普通字段处理 |

### 对象合并

```yaml theme={null}
dns:
  enable: true
  enhanced-mode: fake-ip
```

对象默认递归合并。未写出的子字段会保留。

### 列表处理

```yaml theme={null}
rules-end:
  - DOMAIN-SUFFIX,example.com,DIRECT
```

不带修饰符的列表会替换原列表。需要保留原列表时使用 `-start` 或 `-end`。

对 `proxies`、`proxy-groups` 这类带 `name` 的列表，合并后会按 `name` 去重，后出现的同名项生效。

### Map 合并

```yaml theme={null}
hosts-merge:
  router.local: 192.168.1.1
  nas.local: 192.168.1.100
```

`-merge` 会保留已有键，并写入或覆盖指定键。

### 强制替换

```yaml theme={null}
dns-force:
  enable: true
  nameserver:
    - https://doh.pub/dns-query
```

`-force` 会替换整个字段。未写出的子字段不会保留。

## JavaScript 覆写

JS 覆写必须定义 `main(profile)`。函数可以同步返回，也可以返回 Promise。

```js theme={null}
function main(profile) {
  profile.mode = "rule";

  return deepMerge(profile, {
    "rules-end": ["DOMAIN-SUFFIX,example.com,DIRECT"],
  }, true);
}
```

返回值必须是对象。返回字符串、数字、数组或 `undefined` 都会被视为脚本失败。

### 可用 API

| API                                 | 说明                     |
| ----------------------------------- | ---------------------- |
| `yaml.parse(text)`                  | YAML 字符串转对象            |
| `yaml.stringify(value)`             | 对象转 YAML 字符串           |
| `deepMerge(target, patch, true)`    | 使用 JS helper 的覆写语义合并对象 |
| `fetch(url, init?)`                 | HTTP 请求，仅支持 `http://`  |
| `response.text()`                   | 读取响应文本                 |
| `response.json()`                   | 读取 JSON 响应             |
| `response.yaml()`                   | 读取 YAML 响应             |
| `console.log/info/warn/error/debug` | 写入同名 `.log` 文件         |
| `Buffer.from(...)`                  | 支持 `utf8` 与 `base64`   |
| `b64e(value)` / `b64d(value)`       | Base64 编码与解码           |

<Warning>
  嵌入式 `fetch` 只支持 `http://`，不支持 `https://`。
</Warning>

### JS helper 的列表写法

JS 内置 `deepMerge` 使用 `+key` 和 `key+` 处理列表：

```js theme={null}
function main(profile) {
  return deepMerge(profile, {
    "+rules": ["DOMAIN-SUFFIX,first.example,DIRECT"],
    "rules+": ["DOMAIN-SUFFIX,last.example,DIRECT"],
  }, true);
}
```

这和 YAML 的 `rules-start` / `rules-end` 作用相同。

## 日志与失败行为

| 场景       | 行为                             |
| -------- | ------------------------------ |
| JS 执行成功  | 写入开始、日志输出和成功记录                 |
| JS 执行失败  | 跳过当前 JS 覆写，保留执行前配置，并记录 warning |
| 空覆写文件    | 跳过并记录 warning                  |
| age 加密订阅 | warning 与 JS 日志隐藏敏感配置内容        |

JS 日志路径与脚本同名，例如 `example.js` 对应 `example.log`。

## 编译后补丁

覆写完成后，native 编译器还会应用运行时补丁：

* 清空 `interface-name`，设置 `routing-mark`。
* 补齐 `profile.store-selected` 与 `profile.store-fake-ip`。
* 在需要时补齐 DNS 默认配置。
* 清理不适用于 Android 运行态的 listener。
* 规范化 `proxy-providers` 与 `rule-providers` 的 `path`。

这些补丁属于 YumeBox 运行时约束，不需要在用户覆写中重复声明。
