Skip to content

Commit 9802e0f

Browse files
authored
Merge pull request #83 from DogeLakeDev/cursor/bc-ab200964-a3a7-4c09-9460-7867c64478bc-cc3a
fix(docs): 相对链接不得逃出 docs_dir(OCP 契约)
2 parents c4a7134 + 3405dcf commit 9802e0f

5 files changed

Lines changed: 47 additions & 25 deletions

File tree

docs/CONTRIBUTING-DOCS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ npm run docs -- build # TypeDoc + mkdocs build → site/
5454
2. 写入该目录 `.pages``nav` 列表
5555
3. 从章节 `index.md` 加链接
5656

57+
### 链接约定(契约)
58+
59+
- **站内页**:用相对 `docs/` 的路径(`./guide/``../dev/`),**不要**写成仓根的 `./docs/...`
60+
- **仓外目标**(源码、workflow、LICENSE、`configs/` 等):用 GitHub 绝对 URL(`https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/...`)。相对 `../../sfmc/...` 在 Pages 上会 404。
61+
- `npm run docs:build` / `docs:serve` 会解析手写 `.md` 相对链接;逃出 `docs/` 即失败。
62+
5763
## 扩展 TypeDoc 入口
5864

5965
在根目录 `typedoc.json``entryPoints` 追加 SDK 公开入口(与 `package.json#exports` 对齐)。

docs/dev/npm-publish.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
| `@sfmc-bds/tools` | `tools/` | 开发/安装工具脚本 |
2020
| `@sfmc-bds/sfmc` | `sfmc-meta/` | **聚合包**:一条命令装齐平台 |
2121

22-
可发包清单权威来源:[`tools/lib/npm-publish-packages.mjs`](../../tools/lib/npm-publish-packages.mjs)
22+
可发包清单权威来源:[`tools/lib/npm-publish-packages.mjs`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/tools/lib/npm-publish-packages.mjs)
2323

2424
`@sfmc-bds/remote-controller` 为内部实验包,**不发布**(已在 `.changeset/config.json#ignore`)。
2525

@@ -36,7 +36,7 @@
3636
## 日常开发流程
3737

3838
1. 改可发包代码后:`npm run changeset`,选包 + type,写中文摘要。
39-
2. PR 合入 `main` 后,[changeset-release.yml](../../.github/workflows/changeset-release.yml) 会开/更新 **Version Packages** PR。
39+
2. PR 合入 `main` 后,[changeset-release.yml](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/.github/workflows/changeset-release.yml) 会开/更新 **Version Packages** PR。
4040
3. 维护者审查并合并 Version PR → CI 跑 `ci-release-packages`(publish + tag + GitHub Release;pre mode → npm **`beta`**)。
4141

4242
### Version PR 权限(必读)
@@ -73,7 +73,7 @@ npm run prerelease-packages
7373

7474
## Beta-only(硬约束)
7575

76-
- 仓库含 [`.changeset/pre.json`](../../.changeset/pre.json)`mode: pre`, `tag: beta`
76+
- 仓库含 [`.changeset/pre.json`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/.changeset/pre.json)`mode: pre`, `tag: beta`
7777
- 安装文档与脚手架一律写 `@beta`
7878
- 已存在的 `latest` 上的 `0.1.0` **保留不动**;稳定通道未开放。
7979
- **退出 beta → latest 门槛(全部满足才 `changeset pre exit`**
@@ -92,7 +92,7 @@ npx changeset publish # → latest
9292

9393
## 应急单包补发
9494

95-
[npm-publish.yml](../../.github/workflows/npm-publish.yml)`workflow_dispatch`
95+
[npm-publish.yml](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/.github/workflows/npm-publish.yml)`workflow_dispatch`
9696

9797
- 默认 `dist_tag=beta`
9898
- 若仍处于 pre mode,选择 `latest` 会被 workflow 拒绝

docs/guide/config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
首次启动时,**各服务用代码内默认值 ensure 生成**缺失配置文件,并写入 `$schema` ,使用 IDE 时便可查看**详细的悬停说明**
44

5-
> IDE:工作区 [`.vscode/settings.json`](../../.vscode/settings.json) 已按文件名绑定 schema;也可用文件内 `$schema` 指向 `@sfmc-bds/sdk/schemas/*.schema.json`
5+
> IDE:工作区 [`.vscode/settings.json`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/.vscode/settings.json) 已按文件名绑定 schema;也可用文件内 `$schema` 指向 `@sfmc-bds/sdk/schemas/*.schema.json`
66
77
## 平台配置
88

docs/guide/pack-update.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
| 路径 | 职责 |
88
|------|------|
9-
| [`sfmc/src/pack-update/`](../../sfmc/src/pack-update/) | 配置、绑定、CF Provider、探测/检查/应用 |
10-
| [`sfmc/src/world-packs.ts`](../../sfmc/src/world-packs.ts) | CLI 接线、安装后探测钩子 |
11-
| [`sfmc/src/services.ts`](../../sfmc/src/services.ts) | BDS `beforeStart` 检查/应用 |
12-
| [`bds-tools/src/world-packs.ts`](../../bds-tools/src/world-packs.ts) | 安装/enable/抬版权威实现 |
13-
| [`modules/sdk/@sfmc-sdk/src/logs/terminal-progress.ts`](../../modules/sdk/@sfmc-sdk/src/logs/terminal-progress.ts) | 进度条与日志共存 |
14-
| [`configs/pack-update.json`](../../configs/pack-update.json) | 运行时配置(首次由 sfmc ensure 写入内置 DEFAULTS) |
9+
| [`sfmc/src/pack-update/`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/tree/main/sfmc/src/pack-update) | 配置、绑定、CF Provider、探测/检查/应用 |
10+
| [`sfmc/src/world-packs.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/sfmc/src/world-packs.ts) | CLI 接线、安装后探测钩子 |
11+
| [`sfmc/src/services.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/sfmc/src/services.ts) | BDS `beforeStart` 检查/应用 |
12+
| [`bds-tools/src/world-packs.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/bds-tools/src/world-packs.ts) | 安装/enable/抬版权威实现 |
13+
| [`modules/sdk/@sfmc-sdk/src/logs/terminal-progress.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/modules/sdk/@sfmc-sdk/src/logs/terminal-progress.ts) | 进度条与日志共存 |
14+
| `configs/pack-update.json` | 运行时配置(gitignore;首次由 sfmc ensure 写入内置 DEFAULTS,见 [`config.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/sfmc/src/pack-update/config.ts)|
1515

1616
通用收件箱安装见 [资源包管理](./world-packs.md)
1717

@@ -71,7 +71,7 @@ flowchart TD
7171

7272
不再从 `configs-default` 拷贝。`createServices()` / `ensurePackUpdateConfigFile()` 在文件缺失时写入代码内 `DEFAULTS`,并附带 `$schema`(见 `@sfmc-bds/sdk/schemas/pack_update.schema.json`)。
7373

74-
权威实现:[`sfmc/src/pack-update/config.ts`](../../sfmc/src/pack-update/config.ts)`ensurePackUpdateConfigFile`
74+
权威实现:[`sfmc/src/pack-update/config.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/sfmc/src/pack-update/config.ts)`ensurePackUpdateConfigFile`
7575

7676
### 3.3 `pack-update.json` 关键字段
7777

@@ -189,7 +189,7 @@ JSON 中 `$` **无需**加倍;仅当把 key 放进 **shell / docker-compose
189189
| `GET /v1/mods/search?...` | **部分 key 恒 403**`Forbidden: API Key missing or invalid`|
190190
| `GET https://api.curse.tools/v1/cf/mods/search?...` | 200(社区镜像,路径约定与官方类似) |
191191

192-
实现策略([`providers/curseforge.ts`](../../sfmc/src/pack-update/providers/curseforge.ts)):
192+
实现策略([`providers/curseforge.ts`](https://github.com/DogeLakeDev/ScriptsForMinecraftServer/blob/main/sfmc/src/pack-update/providers/curseforge.ts)):
193193

194194
1. 先打官方 `baseUrl` + `/v1/mods/search`
195195
2. 若返回 403 → 静默改打 `searchBaseUrl`(默认 `https://api.curse.tools/v1/cf`)的 `/mods/search`

tools/docs-mkdocs.mjs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,60 @@ if (!["serve", "build"].includes(mode)) {
1818
}
1919

2020
/**
21-
* MkDocs docs_dir=docs:页面内相对链接不应再带 ./docs/ 前缀。
22-
* 把 README(仓根路径)原样贴进 docs/*.md 会导致站内导航全断,且默认
23-
* unrecognized_links=ignore 时 CI 不会拦。在此做契约检查。
21+
* MkDocs docs_dir=docs:手写页相对链接解析后必须落在 docs/ 内。
22+
* 同时拦住两类误用(单一权威规则,避免再为每种前缀打洞):
23+
* 1) README 仓根路径误贴:](./docs/guide/…) → 站内变成双重 docs/
24+
* 2) 指向仓内其它目录:](../../sfmc/…) → Pages 上 404;应改 GitHub 绝对 URL
25+
* TypeDoc 生成目录跳过;mkdocs exclude(plan/archive/reviews)仍检查,防草稿误贴。
2426
*/
25-
function assertNoRepoRootDocsLinks(docsDir) {
27+
function assertDocsRelativeLinksStayInDocs(docsDir) {
2628
const bad = [];
29+
const linkRe = /\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
2730
const stack = [docsDir];
2831
while (stack.length) {
2932
const dir = stack.pop();
3033
for (const ent of readdirSync(dir, { withFileTypes: true })) {
3134
const full = path.join(dir, ent.name);
3235
if (ent.isDirectory()) {
33-
// TypeDoc 输出目录跳过;plan/archive 由 mkdocs exclude
3436
const rel = path.relative(docsDir, full).replace(/\\/g, "/");
35-
if (rel === "reference/sdk" || ent.name === "plan" || ent.name === "archive") continue;
37+
// 仅跳过 TypeDoc 输出(生成物,非手写契约)
38+
if (rel === "reference/sdk") continue;
3639
stack.push(full);
3740
continue;
3841
}
3942
if (!ent.name.endsWith(".md")) continue;
4043
const text = readFileSync(full, "utf8");
41-
// Markdown 链接目标:](./docs/...) 或 ](docs/...)
42-
if (/\]\(\.?\/?docs\//.test(text)) {
43-
bad.push(path.relative(root, full));
44+
const fileRel = path.relative(root, full).replace(/\\/g, "/");
45+
let m;
46+
linkRe.lastIndex = 0;
47+
while ((m = linkRe.exec(text))) {
48+
const raw = m[1].replace(/^<|>$/g, "");
49+
// 锚点 / 协议链接 / 协议相对 URL 不参与 docs_dir 解析
50+
if (!raw || raw.startsWith("#") || /^[a-z][a-z0-9+.-]*:/i.test(raw) || raw.startsWith("//")) {
51+
continue;
52+
}
53+
const targetPath = raw.split("#")[0].split("?")[0];
54+
if (!targetPath) continue;
55+
const resolved = path.resolve(path.dirname(full), targetPath);
56+
const relToDocs = path.relative(docsDir, resolved);
57+
if (relToDocs.startsWith("..") || path.isAbsolute(relToDocs)) {
58+
bad.push(`${fileRel}: ](${raw})`);
59+
}
4460
}
4561
}
4662
}
4763
if (bad.length) {
4864
console.error(
4965
[
50-
"[docs-mkdocs] 发现仓根相对路径 docs/…(MkDocs 下应写成 ./guide/、./dev/ 等):",
51-
...bad.map((f) => ` - ${f}`),
66+
"[docs-mkdocs] 相对链接逃出 docs/(站内应写 ./guide/ 等;仓外目标用 GitHub 绝对 URL):",
67+
...bad.map((line) => ` - ${line}`),
5268
].join("\n")
5369
);
5470
process.exit(1);
5571
}
5672
}
5773

58-
assertNoRepoRootDocsLinks(path.join(root, "docs"));
74+
assertDocsRelativeLinksStayInDocs(path.join(root, "docs"));
5975

6076
// 先生成 API 文档
6177
const gen = spawnSync(process.execPath, [path.join(root, "tools", "docs-typedoc.mjs")], {

0 commit comments

Comments
 (0)