/[sudobot]/trunk/docs/generate-page-index.js
ViewVC logotype

Contents of /trunk/docs/generate-page-index.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 575 - (show annotations)
Mon Jul 29 17:59:26 2024 UTC (8 months ago) by rakinar2
File MIME type: text/javascript
File size: 6291 byte(s)
chore: add trunk
1 const { lstatSync, read, readdirSync, existsSync } = require("fs");
2 const { readFile, writeFile, cp } = require("fs/promises");
3 const { glob } = require("glob");
4 const path = require("path");
5
6 (async () => {
7 const pages = await glob("app/**/page.{tsx,mdx,md}");
8 const index = [];
9
10 async function loadDocsIndex(
11 directory = path.resolve(__dirname, "app/(docs)"),
12 href = "/",
13 ) {
14 const data = [];
15 const files = readdirSync(directory);
16
17 for (const filename of files) {
18 console.log("INDEXING", filename, directory);
19 const file = path.resolve(directory, filename);
20 const stat = lstatSync(file);
21
22 if (stat.isDirectory()) {
23 const info = await loadDocsIndex(
24 file,
25 `${href}${href === "/" ? "" : "/"}${filename}`,
26 );
27 const i = info.children.findIndex(
28 c =>
29 c.name === "page.mdx" ||
30 c.name === "page.md" ||
31 c.name === "page.tsx",
32 );
33 const removed = i !== -1 ? info.children.splice(i, 1)[0] : null;
34
35 data.push(
36 i !== -1
37 ? {
38 ...info,
39 children: info.children,
40 type: "page",
41 data: info.data ?? removed.data,
42 }
43 : info,
44 );
45
46 continue;
47 }
48
49 if (
50 filename !== "page.tsx" &&
51 filename !== "page.md" &&
52 filename !== "page.mdx"
53 )
54 continue;
55
56 const isMDX = file.endsWith(".mdx") || file.endsWith(".md");
57 const info = isMDX
58 ? await generateIndexForMDXPage(file)
59 : await generateIndexForTSXPage(file);
60
61 data.push({
62 type: "page",
63 name: path.basename(filename),
64 url: file
65 .replace(/[\/\\]\([a-z0-9A-Z_-]+\)/gi, "")
66 .replace(/^app[\/\\]/gi, "")
67 .replace(/page\.(tsx|md|mdx)$/gi, "")
68 .replace(/\\/g, "/"),
69 path: file.replace(/\\/g, "/"),
70 data: {
71 title: info.title,
72 short_name: info.short_name,
73 },
74 });
75
76 console.log("NESTED INDEXED", file);
77 }
78
79 const name = path.basename(directory);
80
81 const dirdata = existsSync(path.join(directory, "metadata.json"))
82 ? JSON.parse(
83 await readFile(
84 path.join(directory, "metadata.json"),
85 "utf-8",
86 ),
87 )
88 : null;
89 const children = [...(dirdata?.entries ?? []), ...data];
90
91 children.sort((a, b) => {
92 if (dirdata?.sort_as) {
93 const aIndex = dirdata.sort_as.indexOf(a.name);
94 const bIndex = dirdata.sort_as.indexOf(b.name);
95
96 if (aIndex !== -1 && bIndex !== -1) {
97 return aIndex - bIndex;
98 } else if (aIndex !== -1) {
99 return -1;
100 } else if (bIndex !== -1) {
101 return 1;
102 }
103 }
104
105 return a.name.localeCompare(b.name);
106 });
107
108 return {
109 type: "directory",
110 name: name === "(docs)" ? "/" : name,
111 children: children,
112 href,
113 data: dirdata
114 ? {
115 title: dirdata.title,
116 short_name: dirdata.short_name,
117 }
118 : undefined,
119 };
120 }
121
122 for (const page of pages) {
123 const isMDX = page.endsWith(".mdx") || page.endsWith(".md");
124
125 index.push(
126 isMDX
127 ? await generateIndexForMDXPage(page)
128 : await generateIndexForTSXPage(page),
129 );
130
131 console.log("DONE ", page);
132 }
133
134 await writeFile(path.join(__dirname, "index.json"), JSON.stringify(index));
135
136 await writeFile(
137 path.join(__dirname, "docs_index.json"),
138 JSON.stringify(await loadDocsIndex(), null, 4),
139 );
140
141 try {
142 await cp(
143 path.join(__dirname, "index.json"),
144 path.join(__dirname, ".next/server/index.json"),
145 );
146 } catch (error) {
147 console.error(error);
148 }
149 })();
150
151 async function generateIndexForMDXPage(page) {
152 const contents = await readFile(page, {
153 encoding: "utf-8",
154 });
155 let [frontmatter, data] = contents
156 .substring(contents.startsWith("---") ? 3 : 0)
157 .split("\n---\n");
158
159 if (!contents.trimStart().startsWith("---")) {
160 data = frontmatter;
161 frontmatter = null;
162 }
163
164 const entries = frontmatter
165 ?.split("\n")
166 .filter(Boolean)
167 .map(entry =>
168 entry
169 .split(/:(.*)/s)
170 .filter(Boolean)
171 .map((a, i) => {
172 const trimmed = a.trim();
173 return i === 1 &&
174 trimmed.startsWith('"') &&
175 trimmed.endsWith('"')
176 ? trimmed.substring(1, trimmed.length - 1).trim()
177 : trimmed;
178 }),
179 );
180
181 const frontmatterData = entries ? Object.fromEntries(entries) : null;
182
183 return {
184 ...frontmatterData,
185 data: (data ?? "")
186 .replace(/^(([\s\r\n]*)import([^.]+);)+/gi, "")
187 .replace(/^(([\s\r\n]*)export([^.]+);)+/gi, "")
188 .replace(/([\s\r\n]*)export default ([^;]+);$/gi, "")
189 .replace(/<\/?[^>]+(>|$)/g, ""),
190 url:
191 "/" +
192 page
193 .replace(/[\/\\]\([a-z0-9A-Z_-]+\)/gi, "")
194 .replace(/^app[\/\\]/gi, "")
195 .replace(/page\.(tsx|md|mdx)$/gi, "")
196 .replace(/\\/g, "/"),
197 path: page.replace(/\\/g, "/"),
198 };
199 }
200
201 async function generateIndexForTSXPage(page) {
202 throw new Error("Not implemented");
203 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26