越界发现,记录于 #3576(修 packages/runner/README.md 的 /docs/runner 死链)期间。未在该 PR(#3602)中顺手修改 —— 该 PR 的文件面锁死在 packages/runner/README.md 一个文件,下面这 9 条在别的包里,属另一件事。
#3576 修的那一条不是孤例:同样的形状在包 README 里一共有 10 条,修掉 runner 之后还剩 9 条。
事实(均对 origin/main 复核)
把 packages/*/README.md 里所有 https://www.objectui.org/docs/... 链接逐条按 fumadocs 的候选拼写(x.mdx / x.md / x/index.mdx / x/index.md / 目录)去 content/docs 下找,以下 9 条一个候选都不存在:
| 位置 |
链接 |
为什么死 |
packages/auth/README.md:223 |
/docs/packages/auth |
content/docs/packages/ 这个目录根本不存在 |
packages/collaboration/README.md:132 |
/docs/packages/collaboration |
同上 |
packages/i18n/README.md:152 |
/docs/packages/i18n |
同上 |
packages/mobile/README.md:143 |
/docs/packages/mobile |
同上 |
packages/permissions/README.md:137 |
/docs/packages/permissions |
同上 |
packages/providers/README.md:82 |
/docs/packages/providers |
同上 |
packages/react/README.md:243 |
/docs/packages/react |
同上 |
packages/vscode-extension/README.md:188 |
/docs/protocol/overview |
content/docs/protocol/ 不存在 |
packages/vscode-extension/README.md:189 |
/docs/api/components |
content/docs/api/ 只有 index.md 与 schema-reference.md |
前 7 条是同一个成因:有一个不存在的 /docs/packages/* 命名空间被 7 个包的 README 当成了自己的文档主页。content/docs/meta.json 的 pages 是 guide / api / blocks / core / layout / fields / components / plugins / utilities,没有 packages,也没有 protocol。
这 9 条都长在各包 README 底部那个标准尾块的 ## Links 一节(📚 [Documentation](...)),也就是包在 npm 页面和 GitHub 上最显眼的那一行。
为什么门禁抓不到 —— 两层,缺一不可
-
扫描面:scripts/check-doc-links.mjs 的 SCAN_ROOTS 只有 content/docs / examples / 根 README.md(该文件 238-242 行),packages/**/README.md 不在里面。
-
就算加进去也抓不到:judgeHref() 在 check-doc-links.mjs:552 对任何带 scheme 的 href 直接 return null
if (EXTERNAL_HREF_RE.test(href)) return null;
唯一例外是它前面的 SELF_REPO_BLOB_RE(本仓 github.com/.../blob|tree/main/... 那一种)。站内绝对地址 https://www.objectui.org/docs/... 属于"带 scheme",从不做路由校验 —— 这一层对所有扫描面都成立,content/docs 自己也一样,只要有人在正文里写站内绝对 URL 而不是 /docs/... 相对路由,就同样不被校验。
所以这两层里只补一层没有用:只扩 SCAN_ROOTS 仍然全部漏过,只让脚本认站内绝对 URL 则包 README 还是没被扫。
建议
拆成两件,谁先做都行:
- 改链接(纯内容):9 条要么指到实际存在的页面(例如
packages/react 的文档实际在 content/docs/core/ 一带,需逐个查证),要么删掉这一行 —— 指向一个不存在的页面比不给链接更糟。
- 补门禁(纯脚本):让
judgeHref() 把 https://www.objectui.org/docs/... 解成站内路由再走 routeExists(),并把 packages/*/README.md 加进 SCAN_ROOTS(disk 还是 docs 规则需要斟酌:包 README 里的相对链接指的是磁盘路径,./CHANGELOG.md 那种,和 content/docs 的语义不同)。
与 #3572(check-doc-links 扫描面第三扩:CONTRIBUTING.md + ROADMAP.md + docs/)是兄弟但不重叠**:#3572 的完成范围是那三个根,不含 packages/**,而且它扩的是第 1 层,单独扩完也抓不到本 issue 这 9 条(卡在第 2 层)。所以独立开,不作为它的子 issue。
复核脚本(可直接重跑):
$ node -e '
const {execSync}=require("child_process"), fs=require("fs");
const out=execSync("git grep -n \"www.objectui.org/docs/\" -- packages/*/README.md",{encoding:"utf8"});
for(const line of out.split("\n").filter(Boolean)){
const m=line.match(/^(.*?):(\d+):.*?https:\/\/www\.objectui\.org(\/docs\/[A-Za-z0-9\-_\/\.]*)/);
if(!m) continue;
const r=m[3].replace(/[).,]+$/,"").split("#")[0].replace(/\/$/,"");
const rel=r.replace(/^\/docs/,"content/docs");
const ok=[rel+".mdx",rel+".md",rel+"/index.mdx",rel+"/index.md",rel].some(c=>fs.existsSync(c));
if(!ok) console.log(m[1]+":"+m[2]+" "+r);
}'
越界发现,记录于 #3576(修
packages/runner/README.md的/docs/runner死链)期间。未在该 PR(#3602)中顺手修改 —— 该 PR 的文件面锁死在packages/runner/README.md一个文件,下面这 9 条在别的包里,属另一件事。#3576 修的那一条不是孤例:同样的形状在包 README 里一共有 10 条,修掉 runner 之后还剩 9 条。
事实(均对
origin/main复核)把
packages/*/README.md里所有https://www.objectui.org/docs/...链接逐条按 fumadocs 的候选拼写(x.mdx/x.md/x/index.mdx/x/index.md/ 目录)去content/docs下找,以下 9 条一个候选都不存在:packages/auth/README.md:223/docs/packages/authcontent/docs/packages/这个目录根本不存在packages/collaboration/README.md:132/docs/packages/collaborationpackages/i18n/README.md:152/docs/packages/i18npackages/mobile/README.md:143/docs/packages/mobilepackages/permissions/README.md:137/docs/packages/permissionspackages/providers/README.md:82/docs/packages/providerspackages/react/README.md:243/docs/packages/reactpackages/vscode-extension/README.md:188/docs/protocol/overviewcontent/docs/protocol/不存在packages/vscode-extension/README.md:189/docs/api/componentscontent/docs/api/只有index.md与schema-reference.md前 7 条是同一个成因:有一个不存在的
/docs/packages/*命名空间被 7 个包的 README 当成了自己的文档主页。content/docs/meta.json的pages是guide / api / blocks / core / layout / fields / components / plugins / utilities,没有packages,也没有protocol。这 9 条都长在各包 README 底部那个标准尾块的
## Links一节(📚 [Documentation](...)),也就是包在 npm 页面和 GitHub 上最显眼的那一行。为什么门禁抓不到 —— 两层,缺一不可
扫描面:
scripts/check-doc-links.mjs的SCAN_ROOTS只有content/docs/examples/ 根README.md(该文件 238-242 行),packages/**/README.md不在里面。就算加进去也抓不到:
judgeHref()在check-doc-links.mjs:552对任何带 scheme 的 href 直接return null唯一例外是它前面的
SELF_REPO_BLOB_RE(本仓github.com/.../blob|tree/main/...那一种)。站内绝对地址https://www.objectui.org/docs/...属于"带 scheme",从不做路由校验 —— 这一层对所有扫描面都成立,content/docs自己也一样,只要有人在正文里写站内绝对 URL 而不是/docs/...相对路由,就同样不被校验。所以这两层里只补一层没有用:只扩
SCAN_ROOTS仍然全部漏过,只让脚本认站内绝对 URL 则包 README 还是没被扫。建议
拆成两件,谁先做都行:
packages/react的文档实际在content/docs/core/一带,需逐个查证),要么删掉这一行 —— 指向一个不存在的页面比不给链接更糟。judgeHref()把https://www.objectui.org/docs/...解成站内路由再走routeExists(),并把packages/*/README.md加进SCAN_ROOTS(disk还是docs规则需要斟酌:包 README 里的相对链接指的是磁盘路径,./CHANGELOG.md那种,和content/docs的语义不同)。与 #3572(check-doc-links 扫描面第三扩:CONTRIBUTING.md + ROADMAP.md + docs/)是兄弟但不重叠**:#3572 的完成范围是那三个根,不含
packages/**,而且它扩的是第 1 层,单独扩完也抓不到本 issue 这 9 条(卡在第 2 层)。所以独立开,不作为它的子 issue。复核脚本(可直接重跑):