Skip to content

Commit f5df986

Browse files
committed
[fix] Front Matter of Next.js MDX compatibility
[optimize] support non-Markdown files in Folder Traversing [optimize] some Koa Router details [optimize] upgrade to MobX-GitHub 0.5 & other latest Upstream packages
1 parent 9807f7a commit f5df986

6 files changed

Lines changed: 819 additions & 716 deletions

File tree

next.config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { NextConfig } from 'next';
33
import setPWA from 'next-pwa';
44
// @ts-expect-error no official types
55
import withLess from 'next-with-less';
6+
import remarkFrontmatter from 'remark-frontmatter';
7+
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
68

79
const { NODE_ENV, CI } = process.env;
810
const isDev = NODE_ENV === 'development';
911

1012
const withMDX = setMDX({
1113
options: {
12-
remarkPlugins: [],
14+
remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter],
1315
rehypePlugins: [],
1416
providerImportSource: '@mdx-js/react',
1517
},

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"marked": "^16.2.1",
2727
"mime": "^4.0.7",
2828
"mobx": "^6.13.7",
29-
"mobx-github": "^0.4.0",
29+
"mobx-github": "^0.5.1",
3030
"mobx-i18n": "^0.7.1",
3131
"mobx-lark": "^2.4.1",
3232
"mobx-react": "^9.2.0",
@@ -35,11 +35,13 @@
3535
"mobx-restful-table": "^2.5.3",
3636
"next": "^15.5.2",
3737
"next-pwa": "^5.6.0",
38-
"next-ssr-middleware": "^1.0.2",
38+
"next-ssr-middleware": "^1.0.3",
3939
"react": "^19.1.1",
4040
"react-bootstrap": "^2.10.10",
4141
"react-dom": "^19.1.1",
4242
"react-typed-component": "^1.0.6",
43+
"remark-frontmatter": "^5.0.0",
44+
"remark-mdx-frontmatter": "^5.2.0",
4345
"undici": "^7.15.0",
4446
"web-utility": "^4.5.3",
4547
"yaml": "^2.8.1"
@@ -49,18 +51,17 @@
4951
"@babel/plugin-transform-typescript": "^7.28.0",
5052
"@babel/preset-react": "^7.27.1",
5153
"@cspell/eslint-plugin": "^9.2.1",
52-
"@eslint/js": "^9.34.0",
54+
"@eslint/js": "^9.35.0",
5355
"@next/eslint-plugin-next": "^15.5.2",
5456
"@softonus/prettier-plugin-duplicate-remover": "^1.1.2",
5557
"@stylistic/eslint-plugin": "^5.3.1",
5658
"@types/eslint-config-prettier": "^6.11.3",
5759
"@types/koa": "^3.0.0",
58-
"@types/koa__router": "^12.0.4",
5960
"@types/next-pwa": "^5.6.9",
60-
"@types/node": "^22.18.0",
61+
"@types/node": "^22.18.1",
6162
"@types/react": "^19.1.12",
6263
"@types/react-dom": "^19.1.9",
63-
"eslint": "^9.34.0",
64+
"eslint": "^9.35.0",
6465
"eslint-config-next": "^15.5.2",
6566
"eslint-config-prettier": "^10.1.8",
6667
"eslint-plugin-react": "^7.37.5",
@@ -74,9 +75,9 @@
7475
"next-with-less": "^3.0.1",
7576
"prettier": "^3.6.2",
7677
"prettier-plugin-css-order": "^2.1.2",
77-
"sass": "^1.91.0",
78+
"sass": "^1.92.1",
7879
"typescript": "~5.9.2",
79-
"typescript-eslint": "^8.42.0"
80+
"typescript-eslint": "^8.43.0"
8081
},
8182
"resolutions": {
8283
"next": "$next"
Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1+
import { Context } from 'koa';
12
import { LarkPageData, TableRecord, TableRecordData } from 'mobx-lark';
23
import { DataObject } from 'mobx-restful';
3-
import { createKoaRouter } from 'next-ssr-middleware';
4+
import { createKoaRouter, withKoaRouter } from 'next-ssr-middleware';
45

5-
import { withSafeKoaRouter } from '../../../core';
6+
import { safeAPI } from '../../../core';
67
import { proxyLark, proxyLarkAll } from '../../core';
78

89
export const config = { api: { bodyParser: false } };
910

1011
const router = createKoaRouter(import.meta.url);
1112

1213
function filterData(fields: DataObject) {
13-
for (const key of Object.keys(fields))
14-
if (!/^\w+$/.test(key)) delete fields[key];
14+
for (const key of Object.keys(fields)) if (!/^\w+$/.test(key)) delete fields[key];
1515
}
1616

17-
router.get('/apps/:app/tables/:table/records/:record', async context => {
18-
const { status, body } =
19-
await proxyLark<TableRecordData<DataObject>>(context);
17+
router.get('/apps/:app/tables/:table/records/:record', safeAPI, async (context: Context) => {
18+
const { status, body } = await proxyLark<TableRecordData<DataObject>>(context);
2019

2120
const { fields } = body!.data!.record;
2221

@@ -26,9 +25,8 @@ router.get('/apps/:app/tables/:table/records/:record', async context => {
2625
context.body = body;
2726
});
2827

29-
router.get('/apps/:app/tables/:table/records', async context => {
30-
const { status, body } =
31-
await proxyLark<LarkPageData<TableRecord<DataObject>>>(context);
28+
router.get('/apps/:app/tables/:table/records', safeAPI, async (context: Context) => {
29+
const { status, body } = await proxyLark<LarkPageData<TableRecord<DataObject>>>(context);
3230

3331
const list = body!.data!.items || [];
3432

@@ -38,6 +36,6 @@ router.get('/apps/:app/tables/:table/records', async context => {
3836
context.body = body;
3937
});
4038

41-
router.all('/(.*)', proxyLarkAll);
39+
router.all('/(.*)', safeAPI, proxyLarkAll);
4240

43-
export default withSafeKoaRouter(router);
41+
export default withKoaRouter(router);

pages/api/Lark/file/[id]/[name].ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { fileTypeFromStream } from 'file-type';
2+
import { Middleware } from 'koa';
23
import MIME from 'mime';
3-
import { createKoaRouter } from 'next-ssr-middleware';
4+
import { createKoaRouter, withKoaRouter } from 'next-ssr-middleware';
45
import { Readable } from 'stream';
56

67
import { CACHE_HOST } from '../../../../../models/configuration';
7-
import { withSafeKoaRouter } from '../../../core';
8+
import { safeAPI } from '../../../core';
89
import { lark } from '../../core';
910

1011
const router = createKoaRouter(import.meta.url);
1112

12-
router.all('/:id/:name', async context => {
13+
const downloader: Middleware = async context => {
1314
const { method, url, params, query } = context;
1415
const { id, name } = params;
1516

@@ -21,10 +22,9 @@ router.all('/:id/:name', async context => {
2122

2223
const token = await lark.getAccessToken();
2324

24-
const response = await fetch(
25-
lark.client.baseURI + `drive/v1/medias/${id}/download`,
26-
{ headers: { Authorization: `Bearer ${token}` } },
27-
);
25+
const response = await fetch(lark.client.baseURI + `drive/v1/medias/${id}/download`, {
26+
headers: { Authorization: `Bearer ${token}` },
27+
});
2828
const { ok, status, headers, body } = response;
2929

3030
if (!ok) {
@@ -47,6 +47,8 @@ router.all('/:id/:name', async context => {
4747
if (method === 'GET')
4848
// @ts-expect-error Web type compatibility
4949
context.body = Readable.fromWeb(stream2);
50-
});
50+
};
5151

52-
export default withSafeKoaRouter(router);
52+
router.head('/:id/:name', safeAPI, downloader).get('/:id/:name', safeAPI, downloader);
53+
54+
export default withKoaRouter(router);

pages/api/core.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import 'core-js/full/array/from-async';
22

3-
import Router, { RouterParamContext } from '@koa/router';
43
import { Context, Middleware } from 'koa';
54
import { HTTPError } from 'koajax';
65
import { DataObject } from 'mobx-restful';
7-
import { KoaOption, withKoa, withKoaRouter } from 'next-ssr-middleware';
6+
import { KoaOption, withKoa } from 'next-ssr-middleware';
7+
import Path from 'path';
88
import { ProxyAgent, setGlobalDispatcher } from 'undici';
9-
import { parse } from 'yaml';
9+
import YAML from 'yaml';
1010

1111
const { HTTP_PROXY } = process.env;
1212

@@ -46,11 +46,6 @@ export const safeAPI: Middleware<any, any> = async (context: Context, next) => {
4646
export const withSafeKoa = <S, C>(...middlewares: Middleware<S, C>[]) =>
4747
withKoa<S, C>({} as KoaOption, safeAPI, ...middlewares);
4848

49-
export const withSafeKoaRouter = <S, C extends RouterParamContext<S>>(
50-
router: Router<S, C>,
51-
...middlewares: Middleware<S, C>[]
52-
) => withKoaRouter<S, C>({} as KoaOption, router, safeAPI, ...middlewares);
53-
5449
export interface ArticleMeta {
5550
name: string;
5651
path?: string;
@@ -68,7 +63,7 @@ export function splitFrontMatter(raw: string) {
6863
if (!frontMatter) return { markdown: raw };
6964

7065
try {
71-
const meta = parse(frontMatter) as DataObject;
66+
const meta = YAML.parse(frontMatter) as DataObject;
7267

7368
return { markdown, meta };
7469
} catch (error) {
@@ -90,25 +85,28 @@ export async function* pageListOf(path: string, prefix = 'pages'): AsyncGenerato
9085

9186
const isMDX = MDX_pattern.test(name);
9287

93-
name = name.replace(MDX_pattern, '');
88+
({ name } = Path.parse(name));
9489
path = `${path}/${name}`.replace(new RegExp(`^${prefix}`), '');
9590

96-
if (node.isFile() && isMDX) {
91+
if (node.isFile()) {
9792
const article: ArticleMeta = { name, path, subs: [] };
9893

99-
const file = await readFile(`${node.path}/${node.name}`, 'utf-8');
100-
101-
const { meta } = splitFrontMatter(file);
94+
if (isMDX)
95+
try {
96+
const rawFile = await readFile(`${node.path}/${node.name}`, { encoding: 'utf-8' });
10297

103-
if (meta) article.meta = meta;
98+
const { meta } = splitFrontMatter(rawFile);
10499

100+
if (meta) article.meta = meta;
101+
} catch (error) {
102+
console.error(`Error reading front matter for ${node.path}/${node.name}:`, error);
103+
}
105104
yield article;
106-
}
107-
if (!node.isDirectory()) continue;
105+
} else if (node.isDirectory()) {
106+
const subs = await Array.fromAsync(pageListOf(path, prefix));
108107

109-
const subs = await Array.fromAsync(pageListOf(path, prefix));
110-
111-
if (subs.length) yield { name, subs };
108+
if (subs[0]) yield { name, subs };
109+
}
112110
}
113111
}
114112

0 commit comments

Comments
 (0)