@marlinjai/clearify 1.9.0 → 1.11.0
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.
- package/README.md +9 -0
- package/dist/node/{chunk-QIAMD2Q6.js → chunk-3CW4MOO4.js} +23 -0
- package/dist/node/chunk-AJBCHKBP.js +105 -0
- package/dist/node/{chunk-GGUDZD4K.js → chunk-JU53JE4P.js} +28 -9
- package/dist/node/chunk-NGWAMBXS.js +264 -0
- package/dist/node/{chunk-IF6GI4WU.js → chunk-PFX7LHRZ.js} +19 -10
- package/dist/node/{chunk-PQMKRFBQ.js → chunk-PVTUVUBK.js} +100 -29
- package/dist/node/{chunk-QNC5QRIO.js → chunk-QTGT76RY.js} +35 -14
- package/dist/node/cli/index.js +19 -3
- package/dist/node/core/config.d.ts +1 -1
- package/dist/node/core/config.js +2 -1
- package/dist/node/core/navigation.d.ts +1 -1
- package/dist/node/core/navigation.js +1 -1
- package/dist/node/core/remote.d.ts +18 -0
- package/dist/node/core/remote.js +8 -0
- package/dist/node/core/search.d.ts +6 -2
- package/dist/node/node/build.js +5 -4
- package/dist/node/node/check.d.ts +9 -2
- package/dist/node/node/check.js +6 -3
- package/dist/node/node/index.d.ts +1 -1
- package/dist/node/node/index.js +28 -9
- package/dist/node/node/init.js +1 -1
- package/dist/node/types/index.d.ts +19 -1
- package/dist/node/vite-plugin/index.js +4 -3
- package/package.json +10 -2
- package/src/theme/Sidebar.tsx +13 -11
- package/dist/node/chunk-77VHQV7W.js +0 -136
package/src/theme/Sidebar.tsx
CHANGED
|
@@ -449,25 +449,26 @@ function NavItem({ item, depth, onNavigate, expandedGroups, onToggleGroup, group
|
|
|
449
449
|
display: 'flex',
|
|
450
450
|
alignItems: 'center',
|
|
451
451
|
width: '100%',
|
|
452
|
-
padding: '0.4rem 0.75rem',
|
|
452
|
+
padding: depth === 0 ? '0.4rem 0.75rem' : '0.35rem 0.75rem',
|
|
453
|
+
paddingLeft: `${0.75 + depth * 0.75}rem`,
|
|
453
454
|
background: 'none',
|
|
454
455
|
border: 'none',
|
|
455
456
|
cursor: 'pointer',
|
|
456
|
-
fontSize: '0.6875rem',
|
|
457
|
-
fontWeight: 600,
|
|
458
|
-
textTransform: 'uppercase',
|
|
459
|
-
letterSpacing: '0.06em',
|
|
460
|
-
color: 'var(--clearify-text-tertiary)',
|
|
461
|
-
marginTop: depth === 0 ? '1.25rem' : 0,
|
|
457
|
+
fontSize: depth === 0 ? '0.6875rem' : '0.75rem',
|
|
458
|
+
fontWeight: depth === 0 ? 600 : 500,
|
|
459
|
+
textTransform: depth === 0 ? 'uppercase' : 'none',
|
|
460
|
+
letterSpacing: depth === 0 ? '0.06em' : '0.01em',
|
|
461
|
+
color: depth === 0 ? 'var(--clearify-text-tertiary)' : 'var(--clearify-text-secondary)',
|
|
462
|
+
marginTop: depth === 0 ? '1.25rem' : '0.375rem',
|
|
462
463
|
borderRadius: 'var(--clearify-radius-sm)',
|
|
463
464
|
transition: 'color 0.15s',
|
|
464
465
|
}}
|
|
465
|
-
onMouseEnter={(e) => (e.currentTarget.style.color = 'var(--clearify-text-secondary)')}
|
|
466
|
-
onMouseLeave={(e) => (e.currentTarget.style.color = 'var(--clearify-text-tertiary)')}
|
|
466
|
+
onMouseEnter={(e) => (e.currentTarget.style.color = depth === 0 ? 'var(--clearify-text-secondary)' : 'var(--clearify-text)')}
|
|
467
|
+
onMouseLeave={(e) => (e.currentTarget.style.color = depth === 0 ? 'var(--clearify-text-tertiary)' : 'var(--clearify-text-secondary)')}
|
|
467
468
|
>
|
|
468
469
|
<svg
|
|
469
|
-
width=
|
|
470
|
-
height=
|
|
470
|
+
width={depth === 0 ? '12' : '10'}
|
|
471
|
+
height={depth === 0 ? '12' : '10'}
|
|
471
472
|
viewBox="0 0 24 24"
|
|
472
473
|
fill="none"
|
|
473
474
|
stroke="currentColor"
|
|
@@ -479,6 +480,7 @@ function NavItem({ item, depth, onNavigate, expandedGroups, onToggleGroup, group
|
|
|
479
480
|
transition: 'transform 0.2s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
480
481
|
transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)',
|
|
481
482
|
flexShrink: 0,
|
|
483
|
+
opacity: depth === 0 ? 1 : 0.7,
|
|
482
484
|
}}
|
|
483
485
|
>
|
|
484
486
|
<polyline points="9 18 15 12 9 6" />
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadUserConfig,
|
|
3
|
-
resolveConfig,
|
|
4
|
-
resolveSections
|
|
5
|
-
} from "./chunk-PQMKRFBQ.js";
|
|
6
|
-
import {
|
|
7
|
-
scanDocs
|
|
8
|
-
} from "./chunk-QNC5QRIO.js";
|
|
9
|
-
|
|
10
|
-
// src/node/check.ts
|
|
11
|
-
import { resolve } from "path";
|
|
12
|
-
import { readFileSync, existsSync } from "fs";
|
|
13
|
-
async function checkLinks() {
|
|
14
|
-
const userRoot = process.cwd();
|
|
15
|
-
const userConfig = await loadUserConfig(userRoot);
|
|
16
|
-
const config = resolveConfig(userConfig, userRoot);
|
|
17
|
-
const sections = resolveSections(config, userRoot);
|
|
18
|
-
const validRoutes = /* @__PURE__ */ new Set();
|
|
19
|
-
const allDocs = [];
|
|
20
|
-
for (const section of sections) {
|
|
21
|
-
const docs = scanDocs(section.docsDir, section.exclude, section.basePath);
|
|
22
|
-
for (const doc of docs) {
|
|
23
|
-
validRoutes.add(doc.routePath);
|
|
24
|
-
allDocs.push(doc);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
validRoutes.add("/");
|
|
28
|
-
const changelogPath = resolve(userRoot, "CHANGELOG.md");
|
|
29
|
-
if (existsSync(changelogPath)) {
|
|
30
|
-
validRoutes.add("/changelog");
|
|
31
|
-
}
|
|
32
|
-
const expandedRoutes = new Set(validRoutes);
|
|
33
|
-
for (const route of validRoutes) {
|
|
34
|
-
expandedRoutes.add(route.replace(/\/$/, ""));
|
|
35
|
-
if (route !== "/") expandedRoutes.add(route + "/");
|
|
36
|
-
}
|
|
37
|
-
const mdLinkRegex = /\[(?:[^\]]*)\]\(([^)]+)\)/g;
|
|
38
|
-
const hrefRegex = /href=["']([^"']+)["']/g;
|
|
39
|
-
const brokenLinks = [];
|
|
40
|
-
for (const doc of allDocs) {
|
|
41
|
-
if (!existsSync(doc.filePath)) continue;
|
|
42
|
-
const content = readFileSync(doc.filePath, "utf-8");
|
|
43
|
-
const lines = content.split("\n");
|
|
44
|
-
for (let i = 0; i < lines.length; i++) {
|
|
45
|
-
const line = lines[i];
|
|
46
|
-
const lineNum = i + 1;
|
|
47
|
-
if (line.trimStart().startsWith("```")) continue;
|
|
48
|
-
for (const regex of [mdLinkRegex, hrefRegex]) {
|
|
49
|
-
regex.lastIndex = 0;
|
|
50
|
-
let match;
|
|
51
|
-
while ((match = regex.exec(line)) !== null) {
|
|
52
|
-
const rawLink = match[1].split(/[\s"'#]/)[0];
|
|
53
|
-
if (!rawLink || rawLink.startsWith("http://") || rawLink.startsWith("https://") || rawLink.startsWith("#") || rawLink.startsWith("mailto:") || rawLink.startsWith("tel:") || rawLink.startsWith("//") || rawLink.startsWith("{") || rawLink.startsWith("data:")) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (/\.(png|jpe?g|gif|svg|webp|ico|pdf|zip|tar|gz)$/i.test(rawLink)) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
let normalized = rawLink;
|
|
60
|
-
normalized = normalized.replace(/\.(mdx?|html?)$/, "");
|
|
61
|
-
if (!normalized.startsWith("/")) {
|
|
62
|
-
const docDir = doc.routePath.substring(0, doc.routePath.lastIndexOf("/")) || "/";
|
|
63
|
-
normalized = docDir === "/" ? "/" + normalized : docDir + "/" + normalized;
|
|
64
|
-
}
|
|
65
|
-
const check = normalized === "/" ? "/" : normalized.replace(/\/$/, "");
|
|
66
|
-
const checkNoIndex = check.replace(/\/index$/, "") || "/";
|
|
67
|
-
if (!expandedRoutes.has(check) && !expandedRoutes.has(checkNoIndex)) {
|
|
68
|
-
const suggestion = findClosest(check, validRoutes);
|
|
69
|
-
brokenLinks.push({
|
|
70
|
-
file: doc.filePath,
|
|
71
|
-
line: lineNum,
|
|
72
|
-
link: rawLink,
|
|
73
|
-
...suggestion ? { suggestion } : {}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (brokenLinks.length === 0) {
|
|
81
|
-
console.log("\n No broken links found.\n");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
console.log(`
|
|
85
|
-
Found ${brokenLinks.length} broken link${brokenLinks.length === 1 ? "" : "s"}:
|
|
86
|
-
`);
|
|
87
|
-
const byFile = /* @__PURE__ */ new Map();
|
|
88
|
-
for (const bl of brokenLinks) {
|
|
89
|
-
const relative = bl.file.replace(userRoot + "/", "");
|
|
90
|
-
if (!byFile.has(relative)) byFile.set(relative, []);
|
|
91
|
-
byFile.get(relative).push(bl);
|
|
92
|
-
}
|
|
93
|
-
for (const [file, links] of byFile) {
|
|
94
|
-
console.log(` ${file}`);
|
|
95
|
-
for (const link of links) {
|
|
96
|
-
const suggestion = link.suggestion ? ` (did you mean ${link.suggestion}?)` : "";
|
|
97
|
-
console.log(` line ${link.line}: ${link.link}${suggestion}`);
|
|
98
|
-
}
|
|
99
|
-
console.log();
|
|
100
|
-
}
|
|
101
|
-
process.exitCode = 1;
|
|
102
|
-
}
|
|
103
|
-
function findClosest(target, routes) {
|
|
104
|
-
let best;
|
|
105
|
-
let bestScore = Infinity;
|
|
106
|
-
const targetSegments = target.split("/").filter(Boolean);
|
|
107
|
-
for (const route of routes) {
|
|
108
|
-
const routeSegments = route.split("/").filter(Boolean);
|
|
109
|
-
const dist = levenshtein(target, route);
|
|
110
|
-
const common = targetSegments.filter((s) => routeSegments.includes(s)).length;
|
|
111
|
-
const score = dist - common * 2;
|
|
112
|
-
if (score < bestScore) {
|
|
113
|
-
bestScore = score;
|
|
114
|
-
best = route;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (best && bestScore < target.length * 0.6) return best;
|
|
118
|
-
return void 0;
|
|
119
|
-
}
|
|
120
|
-
function levenshtein(a, b) {
|
|
121
|
-
const m = a.length;
|
|
122
|
-
const n = b.length;
|
|
123
|
-
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
124
|
-
for (let i = 0; i <= m; i++) dp[i][0] = i;
|
|
125
|
-
for (let j = 0; j <= n; j++) dp[0][j] = j;
|
|
126
|
-
for (let i = 1; i <= m; i++) {
|
|
127
|
-
for (let j = 1; j <= n; j++) {
|
|
128
|
-
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return dp[m][n];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export {
|
|
135
|
-
checkLinks
|
|
136
|
-
};
|