coding-friend-cli 1.1.1 → 1.2.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 +15 -0
- package/dist/{chunk-KZT4AFDW.js → chunk-5HZJX47M.js} +1 -1
- package/dist/{chunk-AQXTNLQD.js → chunk-6OI37OZX.js} +9 -1
- package/dist/chunk-R6ZYK4UX.js +128 -0
- package/dist/dev-LZASFXZZ.js +243 -0
- package/dist/{host-JBTJCWM2.js → host-BK6DYFWF.js} +2 -2
- package/dist/index.js +26 -5
- package/dist/{init-E6CL3UZQ.js → init-2UKYE2KV.js} +2 -2
- package/dist/{mcp-MWESK6UX.js → mcp-CH4SKZSX.js} +2 -2
- package/dist/postinstall.js +1 -1
- package/dist/{statusline-7D6YU5YM.js → statusline-ARI7I5YM.js} +1 -1
- package/dist/{update-IH3G4SN5.js → update-5A2OP6EY.js} +58 -37
- package/lib/learn-host/.prettierignore +3 -0
- package/lib/learn-host/.prettierrc +8 -0
- package/lib/learn-host/CHANGELOG.md +9 -0
- package/lib/learn-host/eslint.config.mjs +6 -0
- package/lib/learn-host/next-env.d.ts +1 -1
- package/lib/learn-host/next.config.ts +1 -0
- package/lib/learn-host/package-lock.json +6039 -391
- package/lib/learn-host/package.json +30 -15
- package/lib/learn-host/public/_pagefind/fragment/en_1172b3c.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_118ad1c.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_32ab3d8.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_441f1e1.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_4452de4.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_4ae396d.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_58ee89d.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_6dd2225.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_765a297.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_7a4cc4a.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_8050261.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_83eaedf.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_925bc5f.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_95f3dd5.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_96d7a02.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_971f951.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_a446c32.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_a5ee367.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_b11c248.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_b13c52e.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_b5bd69b.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_b625d7d.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_bf63915.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_c52b25b.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_c9db556.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_d1537ee.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_d2e6412.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_d2f47a4.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_d361292.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_d727ec8.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_e11cd8f.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_e481f19.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_eee2805.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/fragment/en_f4de6c4.pf_fragment +0 -0
- package/lib/learn-host/public/_pagefind/index/en_1ecb9d5.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_37e362b.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_538eee7.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_5751dc8.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_67f794d.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_7458f81.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/index/en_e21f7e1.pf_index +0 -0
- package/lib/learn-host/public/_pagefind/pagefind-entry.json +1 -0
- package/lib/learn-host/public/_pagefind/pagefind-highlight.js +1064 -0
- package/lib/learn-host/public/_pagefind/pagefind-modular-ui.css +214 -0
- package/lib/learn-host/public/_pagefind/pagefind-modular-ui.js +8 -0
- package/lib/learn-host/public/_pagefind/pagefind-ui.css +1 -0
- package/lib/learn-host/public/_pagefind/pagefind-ui.js +2 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_104569cceb.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_1075df6f16.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_139f35f6e5.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_46bfc9f7e1.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_76b8937bbc.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_83cbfb0fd5.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.en_b1d168d536.pf_meta +0 -0
- package/lib/learn-host/public/_pagefind/pagefind.js +6 -0
- package/lib/learn-host/public/_pagefind/wasm.en.pagefind +0 -0
- package/lib/learn-host/public/_pagefind/wasm.unknown.pagefind +0 -0
- package/lib/learn-host/public/logo.svg +1 -0
- package/lib/learn-host/src/app/[category]/[slug]/page.tsx +36 -32
- package/lib/learn-host/src/app/[category]/page.tsx +2 -3
- package/lib/learn-host/src/app/apple-icon.svg +1 -0
- package/lib/learn-host/src/app/globals.css +74 -14
- package/lib/learn-host/src/app/icon.svg +1 -0
- package/lib/learn-host/src/app/layout.tsx +29 -9
- package/lib/learn-host/src/app/page.tsx +9 -11
- package/lib/learn-host/src/components/Breadcrumbs.tsx +12 -4
- package/lib/learn-host/src/components/DocCard.tsx +28 -10
- package/lib/learn-host/src/components/MarkdownRenderer.tsx +6 -2
- package/lib/learn-host/src/components/MobileNav.tsx +43 -35
- package/lib/learn-host/src/components/PagefindSearch.tsx +177 -54
- package/lib/learn-host/src/components/Sidebar.tsx +27 -29
- package/lib/learn-host/src/components/TableOfContents.tsx +62 -0
- package/lib/learn-host/src/components/TagBadge.tsx +1 -1
- package/lib/learn-host/src/components/ThemeToggle.tsx +36 -9
- package/lib/learn-host/src/components/layout/Footer.tsx +41 -0
- package/lib/learn-host/src/components/layout/Header.tsx +117 -0
- package/lib/learn-host/src/lib/docs.ts +98 -8
- package/lib/learn-host/src/lib/types.ts +7 -1
- package/lib/learn-host/tsconfig.json +8 -2
- package/lib/learn-host/tsconfig.tsbuildinfo +1 -0
- package/lib/learn-mcp/CHANGELOG.md +7 -0
- package/lib/learn-mcp/package.json +1 -1
- package/package.json +13 -5
- package/dist/chunk-VHZQ6KEU.js +0 -73
- package/lib/learn-host/src/app/search/page.tsx +0 -19
- package/lib/learn-host/src/components/SearchBar.tsx +0 -36
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Image from "next/image";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import type { CategoryInfo } from "@/lib/types";
|
|
7
|
+
import PagefindSearch from "@/components/PagefindSearch";
|
|
8
|
+
import ThemeToggle from "@/components/ThemeToggle";
|
|
9
|
+
|
|
10
|
+
export default function Header({ categories }: { categories: CategoryInfo[] }) {
|
|
11
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<header className="dark:bg-navy-900/80 sticky top-0 z-50 border-b border-slate-200 bg-white/80 px-4 backdrop-blur-lg md:px-6 dark:border-[#a0a0a01c]">
|
|
15
|
+
<div className="flex h-14 items-center justify-between">
|
|
16
|
+
{/* Left: Logo + Title */}
|
|
17
|
+
<Link href="/" className="flex shrink-0 items-center gap-2.5">
|
|
18
|
+
<Image src="/logo.svg" alt="Coding Friend" width={32} height={32} />
|
|
19
|
+
<span className="text-lg font-semibold text-slate-900 dark:text-white">
|
|
20
|
+
Learning Notes
|
|
21
|
+
</span>
|
|
22
|
+
</Link>
|
|
23
|
+
|
|
24
|
+
{/* Right */}
|
|
25
|
+
<div className="flex items-center gap-1 md:gap-3">
|
|
26
|
+
{/* Search */}
|
|
27
|
+
<PagefindSearch />
|
|
28
|
+
|
|
29
|
+
{/* Theme Toggle */}
|
|
30
|
+
<ThemeToggle />
|
|
31
|
+
|
|
32
|
+
{/* GitHub */}
|
|
33
|
+
<a
|
|
34
|
+
href="https://github.com/dinhanhthi/coding-friend"
|
|
35
|
+
target="_blank"
|
|
36
|
+
rel="noopener noreferrer"
|
|
37
|
+
className="hidden cursor-pointer rounded-lg p-2 text-slate-500 transition-colors duration-200 hover:text-slate-900 md:flex dark:text-slate-400 dark:hover:text-white"
|
|
38
|
+
aria-label="GitHub"
|
|
39
|
+
>
|
|
40
|
+
<svg className="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
|
|
41
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
|
42
|
+
</svg>
|
|
43
|
+
</a>
|
|
44
|
+
|
|
45
|
+
{/* Mobile Hamburger */}
|
|
46
|
+
<button
|
|
47
|
+
onClick={() => setMobileOpen(!mobileOpen)}
|
|
48
|
+
className="dark:hover:bg-navy-800 cursor-pointer rounded-lg p-2 transition-colors hover:bg-slate-100 md:hidden"
|
|
49
|
+
aria-label="Toggle menu"
|
|
50
|
+
>
|
|
51
|
+
{mobileOpen ? (
|
|
52
|
+
<svg
|
|
53
|
+
className="h-5 w-5"
|
|
54
|
+
fill="none"
|
|
55
|
+
viewBox="0 0 24 24"
|
|
56
|
+
stroke="currentColor"
|
|
57
|
+
>
|
|
58
|
+
<path
|
|
59
|
+
strokeLinecap="round"
|
|
60
|
+
strokeLinejoin="round"
|
|
61
|
+
strokeWidth={2}
|
|
62
|
+
d="M6 18L18 6M6 6l12 12"
|
|
63
|
+
/>
|
|
64
|
+
</svg>
|
|
65
|
+
) : (
|
|
66
|
+
<svg
|
|
67
|
+
className="h-5 w-5"
|
|
68
|
+
fill="none"
|
|
69
|
+
viewBox="0 0 24 24"
|
|
70
|
+
stroke="currentColor"
|
|
71
|
+
>
|
|
72
|
+
<path
|
|
73
|
+
strokeLinecap="round"
|
|
74
|
+
strokeLinejoin="round"
|
|
75
|
+
strokeWidth={2}
|
|
76
|
+
d="M4 6h16M4 12h16M4 18h16"
|
|
77
|
+
/>
|
|
78
|
+
</svg>
|
|
79
|
+
)}
|
|
80
|
+
</button>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
{/* Mobile Menu */}
|
|
85
|
+
{mobileOpen && (
|
|
86
|
+
<nav className="space-y-1 border-t border-slate-200 py-4 md:hidden dark:border-[#a0a0a01c]">
|
|
87
|
+
{categories.map((cat) => (
|
|
88
|
+
<Link
|
|
89
|
+
key={cat.name}
|
|
90
|
+
href={`/${cat.name}/`}
|
|
91
|
+
onClick={() => setMobileOpen(false)}
|
|
92
|
+
className="flex items-center justify-between px-3 py-2 text-sm font-medium text-slate-600 capitalize hover:text-violet-600 dark:text-slate-400 dark:hover:text-violet-400"
|
|
93
|
+
>
|
|
94
|
+
<span>{cat.name.replace(/[_-]/g, " ")}</span>
|
|
95
|
+
<span className="text-xs text-slate-400 dark:text-slate-500">
|
|
96
|
+
{cat.docCount}
|
|
97
|
+
</span>
|
|
98
|
+
</Link>
|
|
99
|
+
))}
|
|
100
|
+
<div className="flex items-center gap-3 px-3 pt-2">
|
|
101
|
+
<a
|
|
102
|
+
href="https://github.com/dinhanhthi/coding-friend"
|
|
103
|
+
target="_blank"
|
|
104
|
+
rel="noopener noreferrer"
|
|
105
|
+
className="flex cursor-pointer items-center gap-2 text-sm font-medium text-slate-500 hover:text-violet-600 dark:text-slate-400 dark:hover:text-violet-400"
|
|
106
|
+
>
|
|
107
|
+
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor">
|
|
108
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
|
109
|
+
</svg>
|
|
110
|
+
GitHub
|
|
111
|
+
</a>
|
|
112
|
+
</div>
|
|
113
|
+
</nav>
|
|
114
|
+
)}
|
|
115
|
+
</header>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -1,25 +1,102 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import matter from "gray-matter";
|
|
4
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
CategoryInfo,
|
|
7
|
+
Doc,
|
|
8
|
+
DocFrontmatter,
|
|
9
|
+
DocMeta,
|
|
10
|
+
TocItem,
|
|
11
|
+
} from "./types";
|
|
5
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the docs directory using the same logic as `cf host`:
|
|
15
|
+
* 1. DOCS_DIR env var (set by `cf host`)
|
|
16
|
+
* 2. Local .coding-friend/config.json → learn.outputDir
|
|
17
|
+
* 3. Global ~/.coding-friend/config.json → learn.outputDir
|
|
18
|
+
* 4. Default: docs/learn (relative to project root)
|
|
19
|
+
*/
|
|
6
20
|
function getDocsDir(): string {
|
|
7
|
-
|
|
8
|
-
|
|
21
|
+
if (process.env.DOCS_DIR) {
|
|
22
|
+
return path.resolve(process.env.DOCS_DIR);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Find project root by walking up from cwd looking for .coding-friend/
|
|
26
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
27
|
+
|
|
28
|
+
// Try local config
|
|
29
|
+
const localConfig = readJsonSafe(
|
|
30
|
+
path.join(projectRoot, ".coding-friend", "config.json"),
|
|
31
|
+
);
|
|
32
|
+
if (localConfig?.learn?.outputDir) {
|
|
33
|
+
return resolvePath(localConfig.learn.outputDir, projectRoot);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Try global config
|
|
37
|
+
const globalConfig = readJsonSafe(
|
|
38
|
+
path.join(homedir(), ".coding-friend", "config.json"),
|
|
39
|
+
);
|
|
40
|
+
if (globalConfig?.learn?.outputDir) {
|
|
41
|
+
return resolvePath(globalConfig.learn.outputDir, projectRoot);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Default
|
|
45
|
+
return path.join(projectRoot, "docs", "learn");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function findProjectRoot(from: string): string {
|
|
49
|
+
let dir = from;
|
|
50
|
+
while (dir !== path.dirname(dir)) {
|
|
51
|
+
if (fs.existsSync(path.join(dir, ".coding-friend"))) {
|
|
52
|
+
return dir;
|
|
53
|
+
}
|
|
54
|
+
dir = path.dirname(dir);
|
|
55
|
+
}
|
|
56
|
+
// Fallback: assume learn-host is at <root>/lib/learn-host
|
|
57
|
+
return path.resolve(from, "../..");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function resolvePath(p: string, base: string): string {
|
|
61
|
+
if (p.startsWith("/")) return p;
|
|
62
|
+
if (p.startsWith("~/")) return path.join(homedir(), p.slice(2));
|
|
63
|
+
return path.resolve(base, p);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface CfConfig {
|
|
67
|
+
learn?: { outputDir?: string };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function readJsonSafe(filePath: string): CfConfig | null {
|
|
71
|
+
try {
|
|
72
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
73
|
+
return JSON.parse(content) as CfConfig;
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
9
77
|
}
|
|
10
78
|
|
|
11
79
|
function isMarkdownDoc(fileName: string): boolean {
|
|
12
80
|
return fileName.endsWith(".md") && fileName !== "README.md";
|
|
13
81
|
}
|
|
14
82
|
|
|
83
|
+
function formatDate(value: unknown): string {
|
|
84
|
+
if (!value) return "";
|
|
85
|
+
if (value instanceof Date) return value.toISOString().slice(0, 10);
|
|
86
|
+
const str = String(value);
|
|
87
|
+
const parsed = new Date(str);
|
|
88
|
+
if (!Number.isNaN(parsed.getTime())) return parsed.toISOString().slice(0, 10);
|
|
89
|
+
return str;
|
|
90
|
+
}
|
|
91
|
+
|
|
15
92
|
function parseFrontmatter(raw: matter.GrayMatterFile<string>): DocFrontmatter {
|
|
16
93
|
const d = raw.data;
|
|
17
94
|
return {
|
|
18
95
|
title: String(d.title ?? "Untitled"),
|
|
19
96
|
category: String(d.category ?? ""),
|
|
20
97
|
tags: Array.isArray(d.tags) ? d.tags.map(String) : [],
|
|
21
|
-
created:
|
|
22
|
-
updated:
|
|
98
|
+
created: formatDate(d.created),
|
|
99
|
+
updated: formatDate(d.updated),
|
|
23
100
|
};
|
|
24
101
|
}
|
|
25
102
|
|
|
@@ -41,9 +118,7 @@ export function getAllCategories(): CategoryInfo[] {
|
|
|
41
118
|
.filter((d) => d.isDirectory() && !d.name.startsWith("."))
|
|
42
119
|
.map((d) => {
|
|
43
120
|
const catPath = path.join(docsDir, d.name);
|
|
44
|
-
const count = fs
|
|
45
|
-
.readdirSync(catPath)
|
|
46
|
-
.filter(isMarkdownDoc).length;
|
|
121
|
+
const count = fs.readdirSync(catPath).filter(isMarkdownDoc).length;
|
|
47
122
|
return { name: d.name, docCount: count };
|
|
48
123
|
})
|
|
49
124
|
.filter((c) => c.docCount > 0);
|
|
@@ -100,6 +175,21 @@ export function getDocBySlug(category: string, slug: string): Doc | null {
|
|
|
100
175
|
};
|
|
101
176
|
}
|
|
102
177
|
|
|
178
|
+
export function extractHeadings(content: string): TocItem[] {
|
|
179
|
+
const headings: TocItem[] = [];
|
|
180
|
+
const regex = /^(#{2,3})\s+(.+)$/gm;
|
|
181
|
+
let match;
|
|
182
|
+
while ((match = regex.exec(content)) !== null) {
|
|
183
|
+
const text = match[2].trim();
|
|
184
|
+
const id = text
|
|
185
|
+
.toLowerCase()
|
|
186
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
187
|
+
.replace(/(^-|-$)/g, "");
|
|
188
|
+
headings.push({ id, text, level: match[1].length });
|
|
189
|
+
}
|
|
190
|
+
return headings;
|
|
191
|
+
}
|
|
192
|
+
|
|
103
193
|
export function getAllTags(): { tag: string; count: number }[] {
|
|
104
194
|
const tagMap = new Map<string, number>();
|
|
105
195
|
for (const doc of getAllDocs()) {
|
|
@@ -11,11 +11,17 @@
|
|
|
11
11
|
"moduleResolution": "bundler",
|
|
12
12
|
"resolveJsonModule": true,
|
|
13
13
|
"isolatedModules": true,
|
|
14
|
-
"jsx": "
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
15
|
"incremental": true,
|
|
16
16
|
"plugins": [{ "name": "next" }],
|
|
17
17
|
"paths": { "@/*": ["./src/*"] }
|
|
18
18
|
},
|
|
19
|
-
"include": [
|
|
19
|
+
"include": [
|
|
20
|
+
"next-env.d.ts",
|
|
21
|
+
"**/*.ts",
|
|
22
|
+
"**/*.tsx",
|
|
23
|
+
".next/types/**/*.ts",
|
|
24
|
+
".next/dev/types/**/*.ts"
|
|
25
|
+
],
|
|
20
26
|
"exclude": ["node_modules"]
|
|
21
27
|
}
|