/[sudobot]/trunk/docs/utils/pages.ts
ViewVC logotype

Annotation of /trunk/docs/utils/pages.ts

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: application/typescript
File size: 4708 byte(s)
chore: add trunk
1 rakinar2 575 import docsPageListJson from "@/docs_index.json";
2     import indexJson from "@/index.json";
3     import {
4     BOT_INVITE_REQUEST_URL,
5     DISCORD_URL,
6     DONATION_URL,
7     SUPPORT_EMAIL_ADDRESS,
8     } from "./links";
9     import { toTitleCase } from "./utils";
10    
11     export type OldDocsPage = {
12     name: string;
13     url?: string;
14     children?: DocsPageWithoutChildren[];
15     };
16    
17     export type DocsPageWithoutChildren = Omit<OldDocsPage, "children">;
18    
19     export type DocsPage = {
20     type: "directory" | "page";
21     name: string;
22     href: string;
23     children?: DocsPage[];
24     data?: {
25     title?: string;
26     short_name?: string;
27     };
28     };
29    
30     export const pages = [
31     {
32     name: "Home",
33     url: "/",
34     },
35     {
36     name: "FAQ",
37     url: "/faq",
38     },
39     {
40     name: "Invite",
41     url: BOT_INVITE_REQUEST_URL,
42     },
43     {
44     name: "Support",
45     url: SUPPORT_EMAIL_ADDRESS,
46     },
47     {
48     name: "Donate",
49     url: DONATION_URL,
50     },
51     {
52     name: "Discord",
53     url: DISCORD_URL,
54     },
55     ];
56    
57     export function resolveDocsURL(url: string) {
58     return url.startsWith("/") ? url : `/${url}`;
59     }
60    
61     export type Index = {
62     title?: string;
63     description?: string;
64     data: string;
65     };
66    
67     let index: Index[] | null = null,
68     lowercasedIndex: Index[] | null = null;
69    
70     function loadIndex() {
71     if (index !== null) {
72     return;
73     }
74    
75     index = indexJson;
76     lowercasedIndex =
77     index?.map(entry => ({
78     data: entry.data.toLowerCase(),
79     title: entry.title?.toLowerCase(),
80     description: entry.description?.toLowerCase(),
81     })) ?? null;
82     }
83    
84     export const getIndex = (lower = false) => {
85     if (!index) {
86     loadIndex();
87     }
88    
89     return lower ? lowercasedIndex! : index!;
90     };
91    
92     let docsPages: OldDocsPage[] | null = null;
93    
94     export const getDocsPages = () => {
95     if (!docsPages) {
96     loadDocsPages();
97     }
98    
99     return docsPages!;
100     };
101    
102     const excludedFromGrouping = ["features", "getting-started"];
103     const forceGrouping = ["extensions"];
104     const hoistedPages = [
105     "getting-started",
106     "features",
107     "features/screenshots",
108     ].map(a => `/${a}`);
109    
110     function loadDocsPages() {
111     if (docsPages) {
112     return;
113     }
114    
115     docsPages = [];
116    
117     const flattenedPages = indexJson.map(
118     page =>
119     ({
120     name: page.short_name ?? "Unnamed",
121     url: page.url,
122     } satisfies DocsPageWithoutChildren),
123     );
124     const pages: Record<string, DocsPageWithoutChildren[]> = {};
125    
126     for (const page of flattenedPages) {
127     const splitted = page.url.split("/");
128     const [, firstDirectory] = splitted;
129    
130     const key =
131     (forceGrouping.includes(firstDirectory) ||
132     (!excludedFromGrouping.includes(firstDirectory) &&
133     firstDirectory !== "")) &&
134     splitted.length > 3
135     ? toTitleCase(firstDirectory)
136     : "_";
137    
138     pages[key] ??= [];
139     pages[key].push({
140     name: page.name,
141     url:
142     page.url !== "/" && page.url.endsWith("/")
143     ? page.url.substring(0, page.url.length - 1)
144     : page.url,
145     });
146     }
147    
148     if (pages._) {
149     docsPages?.push(
150     ...pages._.sort(
151     (a, b) => a.name.charCodeAt(0) - b.name.charCodeAt(0),
152     ),
153     );
154     }
155    
156     for (const key in pages) {
157     if (key === "_") {
158     continue;
159     }
160    
161     docsPages?.push({
162     name: key,
163     children: pages[key].sort(
164     (a, b) => a.name.charCodeAt(0) - b.name.charCodeAt(0),
165     ),
166     });
167     }
168    
169     docsPages.sort((a, b) => {
170     const aIndex = hoistedPages.indexOf(a.url ?? "");
171     const bIndex = hoistedPages.indexOf(b.url ?? "");
172    
173     if (a.url === "/") {
174     return -1;
175     }
176    
177     if (b.url === "/") {
178     return 1;
179     }
180    
181     if (aIndex !== -1 && bIndex !== -1) {
182     return aIndex - bIndex;
183     }
184    
185     if (aIndex !== -1) {
186     return -1;
187     }
188    
189     if (bIndex !== -1) {
190     return 1;
191     }
192    
193     return a.name.localeCompare(b.name);
194     });
195     }
196    
197     export const getAllDocsPages = () => {
198     return docsPageListJson as unknown as {
199     type: "directory";
200     name: "/";
201     children: DocsPage[];
202     };
203     };
204    
205     export const flatten = (
206     pages: DocsPage[] = getAllDocsPages().children,
207     ): DocsPage[] => {
208     return pages.reduce<DocsPage[]>((acc, page) => {
209     if (page.children) {
210     acc.push(page, ...flatten(page.children));
211     } else {
212     acc.push(page);
213     }
214     return acc;
215     }, []);
216     };

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26