Skip to content

Commit ca36e2e

Browse files
authored
refactor: move the RoutePath logic to RoutePage class (#2334)
1 parent 9b04ba5 commit ca36e2e

File tree

6 files changed

+128
-104
lines changed

6 files changed

+128
-104
lines changed

packages/core/src/node/auto-nav-sidebar/normalize.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
slash,
1010
} from '@rspress/shared';
1111
import { logger } from '@rspress/shared/logger';
12-
import { absolutePathToLink, addRoutePrefix } from '../utils/normalizePath';
12+
import { absolutePathToRoutePath, addRoutePrefix } from '../route/RoutePage';
1313
import type {
1414
CustomLinkMeta,
1515
DividerSideMeta,
@@ -271,7 +271,7 @@ async function metaFileItemToSidebarItem(
271271
);
272272
}
273273

274-
const link = absolutePathToLink(absolutePathWithExt, docsDir);
274+
const link = absolutePathToRoutePath(absolutePathWithExt, docsDir);
275275
const info = await extractInfoFromFrontmatterWithAbsolutePath(
276276
absolutePathWithExt,
277277
docsDir,

packages/core/src/node/auto-nav-sidebar/walk.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import path from 'node:path';
33
import { type NavItem, type Sidebar, isExternalUrl } from '@rspress/shared';
44
import { logger } from '@rspress/shared/logger';
55
import { hintNavJsonChangeThenPanic } from '../logger/hint';
6-
import { addRoutePrefix, pathExists } from '../utils';
6+
import { addRoutePrefix } from '../route/RoutePage';
7+
import { pathExists } from '../utils';
78
import { scanSideMeta } from './normalize';
89
import { readJson } from './utils';
910

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,110 @@
1+
import path from 'node:path';
12
import type { RouteMeta } from '@rspress/shared';
3+
import { getPageKey } from '../utils/getPageKey';
4+
import { normalizePath, slash } from '../utils/normalizePath';
5+
import { RouteService } from './RouteService';
26

37
export class RoutePage {
48
routeMeta: RouteMeta;
9+
// @ts-ignore use this field in the future
10+
#docDir: string;
11+
512
// TODO: add pageIndexInfo
613
// pageIndexInfo: PageIndexInfo;
714

8-
static create(routeMeta: RouteMeta) {
9-
return new RoutePage(routeMeta);
15+
static create(absolutePath: string, docsDir: string): RoutePage {
16+
const routeMeta = absolutePathToRouteMeta(absolutePath, docsDir);
17+
return new RoutePage(routeMeta, docsDir);
18+
}
19+
20+
static createFromExternal(
21+
routePath: string,
22+
filepath: string,
23+
docDir: string,
24+
): RoutePage {
25+
const routeMeta = RoutePage.generateRouteMeta(routePath, filepath, docDir);
26+
return new RoutePage(routeMeta, path.dirname(filepath));
1027
}
1128

12-
constructor(routeMeta: RouteMeta) {
29+
private constructor(routeMeta: RouteMeta, docDir: string) {
1330
this.routeMeta = routeMeta;
31+
this.#docDir = docDir;
1432
}
33+
34+
static generateRouteMeta(
35+
routePath: string,
36+
filepath: string,
37+
docDir: string,
38+
): RouteMeta {
39+
const routeService = RouteService.getInstance();
40+
const {
41+
routePath: normalizedPath,
42+
lang,
43+
version,
44+
} = routeService.normalizeRoutePath(routePath);
45+
return {
46+
routePath: normalizedPath,
47+
absolutePath: normalizePath(filepath),
48+
relativePath: normalizePath(path.relative(docDir, filepath)),
49+
pageName: getPageKey(routePath),
50+
lang,
51+
version,
52+
};
53+
}
54+
}
55+
56+
function absolutePathToRouteMeta(
57+
absolutePath: string,
58+
docsDir: string,
59+
): RouteMeta {
60+
const relativePath = slash(path.relative(docsDir, absolutePath));
61+
const routeService = RouteService.getInstance();
62+
63+
const { lang, routePath, version } = routeService.normalizeRoutePath(
64+
relativePath.replace(path.extname(relativePath), ''),
65+
);
66+
return {
67+
pageName: getPageKey(relativePath),
68+
absolutePath,
69+
lang,
70+
version,
71+
routePath,
72+
relativePath,
73+
};
74+
}
75+
76+
/**
77+
*
78+
* @returns runtime cleanUrl like "/api/guide"
79+
*/
80+
export function absolutePathToRoutePath(
81+
absolutePath: string,
82+
docsDir: string,
83+
): string {
84+
return absolutePathToRouteMeta(absolutePath, docsDir).routePath;
85+
}
86+
87+
function absolutePathToRoutePrefix(
88+
absolutePath: string,
89+
docsDir: string,
90+
): string {
91+
const relativePath = slash(
92+
path.relative(
93+
docsDir,
94+
absolutePath.replace(path.extname(absolutePath), ''),
95+
),
96+
);
97+
const routeService = RouteService.getInstance();
98+
const [versionPrefix, langPrefix] =
99+
routeService.getRoutePathParts(relativePath);
100+
return `${versionPrefix ? `/${versionPrefix}` : ''}${langPrefix ? `/${langPrefix}` : ''}`;
101+
}
102+
103+
export function addRoutePrefix(
104+
workDir: string,
105+
docsDir: string,
106+
link: string,
107+
): string {
108+
const routePrefix = absolutePathToRoutePrefix(workDir, docsDir);
109+
return `${routePrefix.replace(/\/$/, '')}/${link.replace(/^\//, '')}`;
15110
}

packages/core/src/node/route/RouteService.ts

Lines changed: 21 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type { ComponentType } from 'react';
66
import { glob } from 'tinyglobby';
77
import type { PluginDriver } from '../PluginDriver';
88
import { PUBLIC_DIR } from '../constants';
9-
import { getPageKey, normalizePath } from '../utils';
109
import { RoutePage } from './RoutePage';
1110
import { getRoutePathParts, normalizeRoutePath } from './normalizeRoutePath';
1211

@@ -69,13 +68,13 @@ export class RouteService {
6968
runtimeTempDir,
7069
pluginDriver,
7170
);
71+
RouteService.__instance__ = routeService;
7272
await routeService.#init();
7373
await pluginDriver.routeServiceGenerated(routeService);
74-
RouteService.__instance__ = routeService;
7574
return routeService;
7675
}
7776

78-
constructor(
77+
private constructor(
7978
scanDir: string,
8079
userConfig: UserConfig,
8180
tempDir: string,
@@ -127,23 +126,10 @@ export class RouteService {
127126
).sort();
128127

129128
files.forEach(filePath => {
130-
const fileRelativePath = normalizePath(
131-
path.relative(this.#scanDir, filePath),
132-
);
133-
const { routePath, lang, version } =
134-
this.normalizeRoutePath(fileRelativePath);
135-
const absolutePath = path.join(this.#scanDir, fileRelativePath);
136-
137-
const routeMeta = {
138-
routePath,
139-
absolutePath: normalizePath(absolutePath),
140-
relativePath: fileRelativePath,
141-
pageName: getPageKey(fileRelativePath),
142-
lang,
143-
version,
144-
};
145-
this.addRoute(routeMeta);
129+
const routePage = RoutePage.create(filePath, this.#scanDir);
130+
this.addRoute(routePage);
146131
});
132+
147133
// 2. external pages added by plugins
148134
const externalPages = await this.#pluginDriver.addPages();
149135

@@ -152,38 +138,40 @@ export class RouteService {
152138
const { routePath, content, filepath } = route;
153139
// case1: specify the filepath
154140
if (filepath) {
155-
const routeMeta = this.#generateRouteMeta(routePath, filepath);
156-
this.addRoute(routeMeta);
141+
const routePage = RoutePage.createFromExternal(
142+
routePath,
143+
filepath,
144+
this.#scanDir,
145+
);
146+
this.addRoute(routePage);
157147
return;
158148
}
159149
// case2: specify the content
160150
if (content) {
161151
const filepath = await this.#writeTempFile(index, content);
162-
const routeMeta = this.#generateRouteMeta(routePath, filepath);
163-
this.addRoute(routeMeta);
152+
const routePage = RoutePage.createFromExternal(
153+
routePath,
154+
filepath,
155+
this.#scanDir,
156+
);
157+
this.addRoute(routePage);
164158
}
165159
}),
166160
);
167161

168162
await this.#pluginDriver.routeGenerated(this.getRoutes());
169163
}
170164

171-
async addRoute(routeMeta: RouteMeta) {
172-
const { routePath } = routeMeta;
165+
async addRoute(routePage: RoutePage): Promise<void> {
166+
const {
167+
routeMeta: { routePath },
168+
} = routePage;
173169
if (this.routeData.has(routePath)) {
174170
throw new Error(`routePath ${routePath} has already been added`);
175171
}
176-
177-
const routePage = RoutePage.create(routeMeta);
178172
this.routeData.set(routePath, routePage);
179173
}
180174

181-
removeRoute(filePath: string): void {
182-
const fileRelativePath = path.relative(this.#scanDir, filePath);
183-
const { routePath } = this.normalizeRoutePath(fileRelativePath);
184-
this.routeData.delete(routePath);
185-
}
186-
187175
getRoutes(): RouteMeta[] {
188176
return Array.from(this.routeData.values()).map(i => i.routeMeta);
189177
}
@@ -260,22 +248,6 @@ ${routeMeta
260248
return tempFilePath;
261249
}
262250

263-
#generateRouteMeta(routePath: string, filepath: string): RouteMeta {
264-
const {
265-
routePath: normalizedPath,
266-
lang,
267-
version,
268-
} = this.normalizeRoutePath(routePath);
269-
return {
270-
routePath: normalizedPath,
271-
absolutePath: normalizePath(filepath),
272-
relativePath: normalizePath(path.relative(this.#scanDir, filepath)),
273-
pageName: getPageKey(routePath),
274-
lang,
275-
version,
276-
};
277-
}
278-
279251
getRoutePageByRoutePath(routePath: string) {
280252
return this.routeData.get(routePath);
281253
}

packages/core/src/node/route/normalizeRoutePath.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import { addLeadingSlash, addTrailingSlash } from '@rspress/shared';
22
import { DEFAULT_PAGE_EXTENSIONS } from '@rspress/shared/constants';
33

44
export const getRoutePathParts = (
5-
routePath: string,
5+
relativePath: string,
66
lang: string,
77
version: string,
88
langs: string[],
99
versions: string[],
1010
) => {
11-
const hasTrailSlash = routePath.endsWith('/');
11+
const hasTrailSlash = relativePath.endsWith('/');
1212

1313
let versionPart = '';
1414
let langPart = '';
1515
let purePathPart = '';
1616

17-
const parts: string[] = routePath.split('/').filter(Boolean);
17+
const parts: string[] = relativePath.split('/').filter(Boolean);
1818

1919
if (version) {
2020
const versionToMatch = parts[0];
@@ -47,15 +47,15 @@ export const getRoutePathParts = (
4747
};
4848

4949
export const normalizeRoutePath = (
50-
routePath: string,
50+
relativePath: string,
5151
lang: string,
5252
version: string,
5353
langs: string[],
5454
versions: string[],
5555
extensions: string[] = DEFAULT_PAGE_EXTENSIONS,
5656
) => {
5757
const [versionPart, langPart, purePathPart] = getRoutePathParts(
58-
routePath,
58+
relativePath,
5959
lang,
6060
version,
6161
langs,
Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os from 'node:os';
22
import path from 'node:path';
3-
import { RouteService } from '../route/RouteService';
43

54
export const isWindows = os.platform() === 'win32';
65

@@ -11,46 +10,3 @@ export function slash(p: string): string {
1110
export function normalizePath(id: string): string {
1211
return path.posix.normalize(isWindows ? slash(id) : id);
1312
}
14-
15-
/**
16-
*
17-
* @returns runtime cleanUrl like "/api/guide"
18-
*/
19-
export function absolutePathToLink(
20-
absolutePath: string,
21-
docsDir: string,
22-
): string {
23-
const relativePath = slash(
24-
path.relative(
25-
docsDir,
26-
absolutePath.replace(path.extname(absolutePath), ''),
27-
),
28-
);
29-
const routeService = RouteService.getInstance();
30-
return routeService.normalizeRoutePath(relativePath).routePath;
31-
}
32-
33-
function absolutePathToRoutePrefix(
34-
absolutePath: string,
35-
docsDir: string,
36-
): string {
37-
const relativePath = slash(
38-
path.relative(
39-
docsDir,
40-
absolutePath.replace(path.extname(absolutePath), ''),
41-
),
42-
);
43-
const routeService = RouteService.getInstance();
44-
const [versionPrefix, langPrefix] =
45-
routeService.getRoutePathParts(relativePath);
46-
return `${versionPrefix ? `/${versionPrefix}` : ''}${langPrefix ? `/${langPrefix}` : ''}`;
47-
}
48-
49-
export function addRoutePrefix(
50-
workDir: string,
51-
docsDir: string,
52-
link: string,
53-
): string {
54-
const routePrefix = absolutePathToRoutePrefix(workDir, docsDir);
55-
return `${routePrefix.replace(/\/$/, '')}/${link.replace(/^\//, '')}`;
56-
}

0 commit comments

Comments
 (0)