Skip to content

Commit 4858710

Browse files
committed
feat: add route documentation for languages and stats controllers
1 parent f256a96 commit 4858710

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

src/controllers/languages.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ export class LanguageController {
66
private static githubClient: GitHubClient;
77
private static cache: Map<string, { data: string; timestamp: number }>;
88
private static CACHE_DURATION: number;
9+
static routeDocs = {
10+
requiredParams: ['username'],
11+
optionalParams: [
12+
'theme',
13+
'show_info',
14+
'top',
15+
'variant',
16+
'type',
17+
'bgColor',
18+
'borderColor',
19+
'textColor',
20+
'titleColor',
21+
'format'
22+
],
23+
payload: null as null,
24+
example: '/languages?username=pphatdev&theme=default'
25+
};
926

1027
static initialize(githubClient: GitHubClient, cache: Map<string, { data: string; timestamp: number }>, cacheDuration: number) {
1128
this.githubClient = githubClient;

src/controllers/stats.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ export class StatsController {
88
private static CACHE_DURATION: number;
99
private static pendingRequests: Map<string, Promise<string>> = new Map();
1010
private static pngCache: Map<string, { data: Buffer; timestamp: number }> = new Map();
11+
static routeDocs = {
12+
requiredParams: ['username'],
13+
optionalParams: [
14+
'theme',
15+
'hide_title',
16+
'hide_border',
17+
'hide_rank',
18+
'show_icons',
19+
'avatar_mode',
20+
'show_avatar',
21+
'custom_title',
22+
'data_border_style',
23+
'data_border_frame',
24+
'bgColor',
25+
'borderColor',
26+
'textColor',
27+
'titleColor',
28+
'format'
29+
],
30+
payload: null as null,
31+
example: '/stats?username=pphatdev&theme=dark'
32+
};
1133

1234
static initialize(githubClient: GitHubClient, cache: Map<string, { data: string; timestamp: number }>, cacheDuration: number) {
1335
this.githubClient = githubClient;

src/index.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,63 @@ app.use(cors());
1717
app.use(express.static(publicDir));
1818
app.use('/public', express.static(publicDir));
1919

20+
const staticRoots = ['/', '/public'];
21+
22+
type RouteInfo = {
23+
method: string;
24+
path: string;
25+
requiredParams?: string[];
26+
optionalParams?: string[];
27+
payload?: string | null;
28+
example?: string;
29+
};
30+
31+
const routeDocs: Record<string, Omit<RouteInfo, 'method' | 'path'>> = {
32+
'GET /stats': StatsController.routeDocs,
33+
'GET /languages': LanguageController.routeDocs
34+
};
35+
36+
const getRoutes = (): RouteInfo[] => {
37+
const routes: RouteInfo[] = [];
38+
const router = (app as { _router?: { stack?: Array<{ route?: { path?: string; methods?: Record<string, boolean> } } | { name?: string; handle?: { stack?: Array<{ route?: { path?: string; methods?: Record<string, boolean> } }> } }> } })._router;
39+
const stack = router?.stack ?? [];
40+
41+
for (const layer of stack) {
42+
if ('route' in layer && layer.route) {
43+
const path = layer.route.path ?? '';
44+
const methods = Object.keys(layer.route.methods ?? {}).filter((method) => layer.route?.methods?.[method]);
45+
for (const method of methods) {
46+
const routeKey = `${method.toUpperCase()} ${path}`;
47+
routes.push({ method: method.toUpperCase(), path, ...routeDocs[routeKey] });
48+
}
49+
} else if ('name' in layer && layer.name === 'router' && layer.handle?.stack) {
50+
for (const nestedLayer of layer.handle.stack) {
51+
if (nestedLayer.route) {
52+
const path = nestedLayer.route.path ?? '';
53+
const methods = Object.keys(nestedLayer.route.methods ?? {}).filter((method) => nestedLayer.route?.methods?.[method]);
54+
for (const method of methods) {
55+
const routeKey = `${method.toUpperCase()} ${path}`;
56+
routes.push({ method: method.toUpperCase(), path, ...routeDocs[routeKey] });
57+
}
58+
}
59+
}
60+
}
61+
}
62+
63+
routes.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
64+
return routes;
65+
};
66+
67+
app.get('/', (_req, res) => {
68+
res.json({
69+
routes: getRoutes(),
70+
staticAssets: {
71+
roots: staticRoots,
72+
example: '/sitemap.xml'
73+
}
74+
});
75+
});
76+
2077
const PORT = process.env.PORT || 3000;
2178
const APP_ENV = process.env.APP_ENV || 'development';
2279
const PROTOCOL = APP_ENV === 'production' ? 'https' : 'http';

0 commit comments

Comments
 (0)