Skip to content

Commit 7b39f2d

Browse files
committed
Update mdx functions
1 parent cdbf4d5 commit 7b39f2d

File tree

3 files changed

+135
-123
lines changed

3 files changed

+135
-123
lines changed

src/app/(simple-mdx)/[...slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export async function generateStaticParams() {
2525
}
2626

2727
async function getFile(slug: string) {
28-
const file = loadMdxRouteFileAttributes({
28+
const file = await loadMdxRouteFileAttributes({
2929
slug: `content/simple-mdx-pages/${slug}`,
3030
});
3131
if (file) {

src/app/resources/[[...slug]]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export async function generateStaticParams() {
3838
}
3939

4040
async function getFile(slug: string) {
41-
const file = loadMdxRouteFileAttributes({
41+
const file = await loadMdxRouteFileAttributes({
4242
slug: `content/resources/${slug}`,
4343
});
4444
if (file) {

src/util/loadMdx.server.ts

Lines changed: 133 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -49,77 +49,86 @@ export const loadMdxDirectory = unstable_cache(
4949

5050
try {
5151
// Process directories and their children
52-
const directories = dirs.map((dir) => {
53-
// Get the index file's attributes for the current directory
54-
const index = loadMdxRouteFileAttributes({
55-
slug: join(baseDirectory, dir.name, 'index'),
56-
});
57-
58-
let children: MdxFile[] | null = null;
59-
60-
if (includeChildren) {
61-
// Read all files and subdirectories in the current directory
62-
children = readdirSync(join(basePath, dir.name), {
63-
withFileTypes: true,
64-
})
65-
.map((e) => {
66-
// Skip the index file
67-
if (e.name !== 'index.mdx') {
68-
if (e.isFile()) {
69-
// If it's a file, load its attributes
70-
return loadMdxRouteFileAttributes({
71-
slug: join(
72-
baseDirectory,
73-
dir.name,
74-
e.name.replace('.mdx', ''),
75-
),
76-
});
77-
} else if (e.isDirectory()) {
78-
// If it's a directory, recursively load its attributes
79-
const dirIndex = loadMdxRouteFileAttributes({
80-
slug: join(baseDirectory, dir.name, e.name, 'index'),
81-
});
82-
83-
if (dirIndex) {
84-
return {
85-
...dirIndex,
86-
children: loadMdxDirectory({
87-
baseDirectory: join(baseDirectory, dir.name, e.name),
88-
}),
89-
};
90-
}
91-
}
92-
}
93-
return null;
94-
})
95-
.filter((route): route is MdxFile => route !== null)
96-
.sort((a, b) => {
97-
return 'order' in a && 'order' in b && a.order && b.order
98-
? a.order - b.order
99-
: 0;
52+
const directories = await Promise.all(
53+
dirs.map(async (dir) => {
54+
// Get the index file's attributes for the current directory
55+
const index = await loadMdxRouteFileAttributes({
56+
slug: join(baseDirectory, dir.name, 'index'),
57+
});
58+
59+
let children: MdxFile[] | null = null;
60+
61+
if (includeChildren) {
62+
// Read all files and subdirectories in the current directory
63+
const dirs = readdirSync(join(basePath, dir.name), {
64+
withFileTypes: true,
10065
});
101-
}
10266

103-
return {
104-
...index,
105-
children,
106-
};
107-
});
67+
const mappedChildren = await Promise.all(
68+
dirs.map(async (e) => {
69+
// Skip the index file
70+
if (e.name !== 'index.mdx') {
71+
if (e.isFile()) {
72+
// If it's a file, load its attributes
73+
return await loadMdxRouteFileAttributes({
74+
slug: join(
75+
baseDirectory,
76+
dir.name,
77+
e.name.replace('.mdx', ''),
78+
),
79+
});
80+
} else if (e.isDirectory()) {
81+
// If it's a directory, recursively load its attributes
82+
const dirIndex = await loadMdxRouteFileAttributes({
83+
slug: join(baseDirectory, dir.name, e.name, 'index'),
84+
});
85+
86+
if (dirIndex) {
87+
return {
88+
...dirIndex,
89+
children: await loadMdxDirectory({
90+
baseDirectory: join(baseDirectory, dir.name, e.name),
91+
}),
92+
};
93+
}
94+
}
95+
}
96+
return null;
97+
}),
98+
);
99+
100+
children = mappedChildren
101+
.filter((route): route is MdxFile => route !== null)
102+
.sort((a, b) => {
103+
return 'order' in a && 'order' in b && a.order && b.order
104+
? a.order - b.order
105+
: 0;
106+
});
107+
}
108+
109+
return {
110+
...index,
111+
children,
112+
};
113+
}),
114+
);
108115

109116
// Process individual files in the base directory
110-
const entries = files.map((entry) => {
111-
// Skip index files
112-
if (entry.name === 'index.jsx' || entry.name === 'index.mdx') {
113-
return null;
114-
}
115-
116-
// Load attributes for the file
117-
const attributes = loadMdxRouteFileAttributes({
118-
slug: join(baseDirectory, entry.name.replace('.mdx', '')),
119-
});
120-
121-
return attributes;
122-
});
117+
const entries = await Promise.all(
118+
files.map(async (entry) => {
119+
// Skip index files
120+
if (entry.name === 'index.jsx' || entry.name === 'index.mdx') {
121+
return null;
122+
}
123+
124+
// Load attributes for the file
125+
const attributes = await loadMdxRouteFileAttributes({
126+
slug: join(baseDirectory, entry.name.replace('.mdx', '')),
127+
});
128+
129+
return attributes;
130+
}),
131+
);
123132

124133
// Combine directories and entries and filter out null values
125134
const allRoutes: MdxFile[] = [...entries, ...directories].filter(
@@ -150,57 +159,60 @@ export const loadMdxDirectory = unstable_cache(
150159
* @param slug - The slug representing the path to the MDX file.
151160
* @returns The MdxFile for the given slug, or null if not found.
152161
*/
153-
export function loadMdxRouteFileAttributes({
154-
slug,
155-
}: {
156-
slug: string;
157-
}): MdxFile | null {
158-
slug = join(...slug.split('/'));
159-
160-
// Generate the regular file name and index file name based on the slug
161-
const regularFileName = join(
162-
process.cwd(),
163-
'src',
164-
...`${slug}.mdx`.split('/').filter(Boolean),
165-
);
166-
167-
const indexFileName = join(
168-
process.cwd(),
169-
'src',
170-
...slug.split('/').filter(Boolean),
171-
'index.mdx',
172-
);
173-
174-
// Check if the regular file exists, otherwise, check if the index file exists
175-
const fileName = existsSync(regularFileName)
176-
? regularFileName
177-
: existsSync(indexFileName)
178-
? indexFileName
179-
: null;
180-
181-
// If the file doesn't exist, return null
182-
if (!fileName) {
183-
return null;
184-
}
185-
186-
// Read the contents of the file
187-
const fileContents = readFileSync(fileName, {
188-
encoding: 'utf-8',
189-
});
190-
191-
// Parse the front matter from the file contents using the front-matter library
192-
const contents = fm(fileContents);
193-
const attributes = contents.attributes as Omit<
194-
MdxFile,
195-
'slug' | 'requirePath'
196-
>;
197-
198-
// The attributes type is unknown, but we know it should match the MdxFile interface,
199-
// so we assert the type to MdxFile to resolve the TypeScript error.
200-
// Additionally, modify the slug to remove trailing "/index" and "__frontend/" if present.
201-
return {
202-
...attributes,
203-
isIndex: fileName === indexFileName,
204-
slug: slug.replace(/\/index$/g, '').replace(/^__frontend\//g, ''),
205-
};
206-
}
162+
export const loadMdxRouteFileAttributes = unstable_cache(
163+
async ({ slug }: { slug: string }): Promise<MdxFile | null> => {
164+
slug = join(...slug.split('/'));
165+
166+
// Generate the regular file name and index file name based on the slug
167+
const regularFileName = join(
168+
process.cwd(),
169+
'src',
170+
...`${slug}.mdx`.split('/').filter(Boolean),
171+
);
172+
173+
const indexFileName = join(
174+
process.cwd(),
175+
'src',
176+
...slug.split('/').filter(Boolean),
177+
'index.mdx',
178+
);
179+
180+
// Check if the regular file exists, otherwise, check if the index file exists
181+
const fileName = existsSync(regularFileName)
182+
? regularFileName
183+
: existsSync(indexFileName)
184+
? indexFileName
185+
: null;
186+
187+
// If the file doesn't exist, return null
188+
if (!fileName) {
189+
return null;
190+
}
191+
192+
// Read the contents of the file
193+
const fileContents = readFileSync(fileName, {
194+
encoding: 'utf-8',
195+
});
196+
197+
// Parse the front matter from the file contents using the front-matter library
198+
const contents = fm(fileContents);
199+
const attributes = contents.attributes as Omit<
200+
MdxFile,
201+
'slug' | 'requirePath'
202+
>;
203+
204+
// The attributes type is unknown, but we know it should match the MdxFile interface,
205+
// so we assert the type to MdxFile to resolve the TypeScript error.
206+
// Additionally, modify the slug to remove trailing "/index" and "__frontend/" if present.
207+
return {
208+
...attributes,
209+
isIndex: fileName === indexFileName,
210+
slug: slug.replace(/\/index$/g, '').replace(/^__frontend\//g, ''),
211+
};
212+
},
213+
[],
214+
{
215+
revalidate: 86400,
216+
tags: ['mdx-routes'],
217+
},
218+
);

0 commit comments

Comments
 (0)