prev-cli 0.5.0 → 0.6.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/dist/cli.js +72 -14
- package/dist/vite/pages.d.ts +14 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -71,13 +71,50 @@ async function ensureCacheDir(rootDir) {
|
|
|
71
71
|
import fg from "fast-glob";
|
|
72
72
|
import { readFile } from "fs/promises";
|
|
73
73
|
import path2 from "path";
|
|
74
|
+
function parseFrontmatter(content) {
|
|
75
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
76
|
+
const match = content.match(frontmatterRegex);
|
|
77
|
+
if (!match) {
|
|
78
|
+
return { frontmatter: {}, content };
|
|
79
|
+
}
|
|
80
|
+
const frontmatterStr = match[1];
|
|
81
|
+
const restContent = content.slice(match[0].length);
|
|
82
|
+
const frontmatter = {};
|
|
83
|
+
for (const line of frontmatterStr.split(`
|
|
84
|
+
`)) {
|
|
85
|
+
const colonIndex = line.indexOf(":");
|
|
86
|
+
if (colonIndex === -1)
|
|
87
|
+
continue;
|
|
88
|
+
const key = line.slice(0, colonIndex).trim();
|
|
89
|
+
let value = line.slice(colonIndex + 1).trim();
|
|
90
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
91
|
+
value = value.slice(1, -1);
|
|
92
|
+
}
|
|
93
|
+
if (value === "true")
|
|
94
|
+
value = true;
|
|
95
|
+
else if (value === "false")
|
|
96
|
+
value = false;
|
|
97
|
+
else if (!isNaN(Number(value)) && value !== "")
|
|
98
|
+
value = Number(value);
|
|
99
|
+
if (key) {
|
|
100
|
+
frontmatter[key] = value;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { frontmatter, content: restContent };
|
|
104
|
+
}
|
|
105
|
+
function isIndexFile(basename) {
|
|
106
|
+
const lower = basename.toLowerCase();
|
|
107
|
+
return lower === "index" || lower === "readme";
|
|
108
|
+
}
|
|
74
109
|
function fileToRoute(file) {
|
|
75
110
|
const withoutExt = file.replace(/\.mdx?$/, "");
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
const basename = path2.basename(withoutExt).toLowerCase();
|
|
112
|
+
if (basename === "index" || basename === "readme") {
|
|
113
|
+
const dir = path2.dirname(withoutExt);
|
|
114
|
+
if (dir === ".") {
|
|
115
|
+
return "/";
|
|
116
|
+
}
|
|
117
|
+
return "/" + dir;
|
|
81
118
|
}
|
|
82
119
|
return "/" + withoutExt;
|
|
83
120
|
}
|
|
@@ -86,30 +123,51 @@ async function scanPages(rootDir) {
|
|
|
86
123
|
cwd: rootDir,
|
|
87
124
|
ignore: ["node_modules/**", "dist/**", ".cache/**"]
|
|
88
125
|
});
|
|
89
|
-
const
|
|
126
|
+
const routeMap = new Map;
|
|
90
127
|
for (const file of files) {
|
|
128
|
+
const route = fileToRoute(file);
|
|
129
|
+
const basename = path2.basename(file, path2.extname(file)).toLowerCase();
|
|
130
|
+
const priority = basename === "index" ? 1 : basename === "readme" ? 2 : 0;
|
|
131
|
+
const existing = routeMap.get(route);
|
|
132
|
+
if (!existing || priority > 0 && priority < existing.priority) {
|
|
133
|
+
routeMap.set(route, { file, priority });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const pages = [];
|
|
137
|
+
for (const { file } of routeMap.values()) {
|
|
91
138
|
const fullPath = path2.join(rootDir, file);
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
139
|
+
const rawContent = await readFile(fullPath, "utf-8");
|
|
140
|
+
const { frontmatter, content } = parseFrontmatter(rawContent);
|
|
141
|
+
const title = extractTitle(content, file, frontmatter);
|
|
142
|
+
const page = {
|
|
95
143
|
route: fileToRoute(file),
|
|
96
144
|
title,
|
|
97
145
|
file
|
|
98
|
-
}
|
|
146
|
+
};
|
|
147
|
+
if (frontmatter.description) {
|
|
148
|
+
page.description = frontmatter.description;
|
|
149
|
+
}
|
|
150
|
+
if (Object.keys(frontmatter).length > 0) {
|
|
151
|
+
page.frontmatter = frontmatter;
|
|
152
|
+
}
|
|
153
|
+
pages.push(page);
|
|
99
154
|
}
|
|
100
155
|
return pages.sort((a, b) => a.route.localeCompare(b.route));
|
|
101
156
|
}
|
|
102
|
-
function extractTitle(content, file) {
|
|
157
|
+
function extractTitle(content, file, frontmatter) {
|
|
158
|
+
if (frontmatter?.title && typeof frontmatter.title === "string") {
|
|
159
|
+
return frontmatter.title;
|
|
160
|
+
}
|
|
103
161
|
const match = content.match(/^#\s+(.+)$/m);
|
|
104
162
|
if (match) {
|
|
105
163
|
return match[1].trim();
|
|
106
164
|
}
|
|
107
|
-
const basename = path2.basename(file, path2.extname(file));
|
|
108
|
-
if (basename
|
|
165
|
+
const basename = path2.basename(file, path2.extname(file)).toLowerCase();
|
|
166
|
+
if (isIndexFile(basename)) {
|
|
109
167
|
const dirname = path2.dirname(file);
|
|
110
168
|
return dirname === "." ? "Home" : capitalize(path2.basename(dirname));
|
|
111
169
|
}
|
|
112
|
-
return capitalize(basename);
|
|
170
|
+
return capitalize(path2.basename(file, path2.extname(file)));
|
|
113
171
|
}
|
|
114
172
|
function capitalize(str) {
|
|
115
173
|
return str.charAt(0).toUpperCase() + str.slice(1).replace(/-/g, " ");
|
package/dist/vite/pages.d.ts
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
|
+
export interface Frontmatter {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
1
6
|
export interface Page {
|
|
2
7
|
route: string;
|
|
3
8
|
title: string;
|
|
4
9
|
file: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
frontmatter?: Frontmatter;
|
|
5
12
|
}
|
|
6
13
|
export interface SidebarItem {
|
|
7
14
|
title: string;
|
|
8
15
|
route?: string;
|
|
9
16
|
children?: SidebarItem[];
|
|
10
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse YAML frontmatter from markdown content
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseFrontmatter(content: string): {
|
|
22
|
+
frontmatter: Frontmatter;
|
|
23
|
+
content: string;
|
|
24
|
+
};
|
|
11
25
|
export declare function fileToRoute(file: string): string;
|
|
12
26
|
export declare function scanPages(rootDir: string): Promise<Page[]>;
|
|
13
27
|
export declare function buildSidebarTree(pages: Page[]): SidebarItem[];
|