czon 0.9.8 → 0.9.9

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.
@@ -16,6 +16,7 @@ const path_1 = __importDefault(require("path"));
16
16
  const findEntries_1 = require("../findEntries");
17
17
  const paths_1 = require("../paths");
18
18
  const isExists_1 = require("../utils/isExists");
19
+ const isFile_1 = require("../utils/isFile");
19
20
  /**
20
21
  * 递归遍历 marked token 树,收集所有真实的 link 和 image token。
21
22
  * 自动跳过 code(代码块)和 codespan(行内代码)中的内容。
@@ -192,7 +193,9 @@ async function checkLinks() {
192
193
  }
193
194
  // 再检查文件系统
194
195
  const resolvedFullPath = path_1.default.join(paths_1.INPUT_DIR, resolvedRelative);
195
- if (!(await (0, isExists_1.isExists)(resolvedFullPath))) {
196
+ const targetExists = await (0, isExists_1.isExists)(resolvedFullPath);
197
+ const targetIsFile = targetExists ? await (0, isFile_1.isFile)(resolvedFullPath) : false;
198
+ if (!targetExists || !targetIsFile) {
196
199
  // 通过 basename 模糊匹配,生成候选建议(最多 3 个)
197
200
  const suggestions = [];
198
201
  const targetBasename = path_1.default.basename(hrefWithoutHash);
@@ -209,7 +212,7 @@ async function checkLinks() {
209
212
  raw: link.raw,
210
213
  href: link.href,
211
214
  type: 'dead-link',
212
- message: '目标文件不存在',
215
+ message: targetExists ? '目标是目录,不是文件' : '目标文件不存在',
213
216
  suggestions,
214
217
  });
215
218
  }
@@ -9,6 +9,8 @@ const path_1 = __importDefault(require("path"));
9
9
  const findEntries_1 = require("../findEntries");
10
10
  const metadata_1 = require("../metadata");
11
11
  const paths_1 = require("../paths");
12
+ const isExists_1 = require("../utils/isExists");
13
+ const isFile_1 = require("../utils/isFile");
12
14
  const extractLinksFromMarkdown = (content) => {
13
15
  const linkRegex = /\[.*?\]\((.*?)\)/g;
14
16
  const links = [];
@@ -43,11 +45,14 @@ async function scanSourceFiles() {
43
45
  if (isVisited.has(fullPath))
44
46
  continue;
45
47
  isVisited.add(fullPath);
46
- const isExists = await (0, promises_1.access)(fullPath).then(() => true, () => false);
47
- if (!isExists) {
48
+ if (!(await (0, isExists_1.isExists)(fullPath))) {
48
49
  console.warn(`⚠️ File does not exist: ${fullPath}, skipping.`);
49
50
  continue;
50
51
  }
52
+ if (!(await (0, isFile_1.isFile)(fullPath))) {
53
+ console.warn(`⚠️ Path is not a file: ${fullPath}, skipping.`);
54
+ continue;
55
+ }
51
56
  const contentBuffer = await (0, promises_1.readFile)(fullPath);
52
57
  paths.add(relativePath);
53
58
  let meta = metadata_1.MetaData.files.find(f => f.path === relativePath);
@@ -65,10 +70,21 @@ async function scanSourceFiles() {
65
70
  for (const link of links) {
66
71
  if (URL.canParse(link))
67
72
  continue;
68
- const resolvedPath = path_1.default.resolve(path_1.default.dirname(fullPath), link);
69
- const relativePath = path_1.default.relative(paths_1.INPUT_DIR, resolvedPath);
70
- if (!isVisited.has(relativePath)) {
71
- queue.push(relativePath);
73
+ const hrefWithoutHash = link.split('#')[0];
74
+ const hrefWithoutQuery = hrefWithoutHash.split('?')[0];
75
+ if (!hrefWithoutQuery)
76
+ continue;
77
+ const resolvedPath = path_1.default.resolve(path_1.default.dirname(fullPath), hrefWithoutQuery);
78
+ if ((await (0, isExists_1.isExists)(resolvedPath)) && !(await (0, isFile_1.isFile)(resolvedPath))) {
79
+ console.warn(`⚠️ Link target is a directory: ${link} in ${relativePath}, skipping.`);
80
+ continue;
81
+ }
82
+ const resolvedRelativePath = path_1.default.relative(paths_1.INPUT_DIR, resolvedPath);
83
+ if (resolvedRelativePath.startsWith('..') || path_1.default.isAbsolute(resolvedRelativePath))
84
+ continue;
85
+ const resolvedFullPath = path_1.default.join(paths_1.INPUT_DIR, resolvedRelativePath);
86
+ if (!isVisited.has(resolvedFullPath)) {
87
+ queue.push(resolvedRelativePath);
72
88
  }
73
89
  }
74
90
  }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFile = void 0;
4
+ const promises_1 = require("fs/promises");
5
+ /**
6
+ * 检查路径是否为文件
7
+ * @param path 要检查的路径
8
+ * @returns Promise<boolean> 路径是否是文件
9
+ */
10
+ const isFile = async (path) => {
11
+ return (0, promises_1.stat)(path)
12
+ .then(stats => stats.isFile())
13
+ .catch(() => false);
14
+ };
15
+ exports.isFile = isFile;
16
+ //# sourceMappingURL=isFile.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "czon",
3
- "version": "0.9.8",
3
+ "version": "0.9.9",
4
4
  "description": "CZON - AI enhanced Markdown content engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",