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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 575 - (hide 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 rakinar2 575 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