path-rush 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/chunk-VBEFTPIV.mjs +517 -0
- package/dist/chunk-VBEFTPIV.mjs.map +1 -0
- package/dist/core.d.cts +2 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.js +553 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +7 -0
- package/dist/core.mjs.map +1 -0
- package/dist/plugin.d.cts +106 -0
- package/dist/plugin.d.ts +106 -0
- package/dist/plugin.js +551 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugin.mjs +7 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/react.d.cts +35 -0
- package/dist/react.d.ts +35 -0
- package/dist/react.js +111 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +74 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
// src/plugin.ts
|
|
2
|
+
import fs7 from "fs";
|
|
3
|
+
import path5 from "path";
|
|
4
|
+
|
|
5
|
+
// src/core/build-generator.ts
|
|
6
|
+
import fs4 from "fs";
|
|
7
|
+
import path3 from "path";
|
|
8
|
+
|
|
9
|
+
// src/core/metadata.ts
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
function extractMetadata(filePath) {
|
|
12
|
+
try {
|
|
13
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
14
|
+
const jsdocMetadata = extractJSDocMetadata(content);
|
|
15
|
+
if (jsdocMetadata) {
|
|
16
|
+
return jsdocMetadata;
|
|
17
|
+
}
|
|
18
|
+
const exportMetadata = extractExportMetadata(content);
|
|
19
|
+
if (exportMetadata) {
|
|
20
|
+
return exportMetadata;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.warn(
|
|
25
|
+
`[vite-plugin-file-router] Failed to extract metadata from ${filePath}:`,
|
|
26
|
+
error
|
|
27
|
+
);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function extractJSDocMetadata(content) {
|
|
32
|
+
const jsdocMatch = content.match(/\/\*\*([\s\S]*?)\*\//);
|
|
33
|
+
if (!jsdocMatch) return null;
|
|
34
|
+
const jsdoc = jsdocMatch[1];
|
|
35
|
+
const metadata = {};
|
|
36
|
+
const titleMatch = jsdoc.match(/@title\s+(.+)/);
|
|
37
|
+
if (titleMatch) metadata.title = titleMatch[1].trim();
|
|
38
|
+
const descMatch = jsdoc.match(/@description\s+(.+)/);
|
|
39
|
+
if (descMatch) metadata.description = descMatch[1].trim();
|
|
40
|
+
const keywordsMatch = jsdoc.match(/@keywords\s+(.+)/);
|
|
41
|
+
if (keywordsMatch) {
|
|
42
|
+
metadata.keywords = keywordsMatch[1].split(",").map((k) => k.trim());
|
|
43
|
+
}
|
|
44
|
+
const authorMatch = jsdoc.match(/@author\s+(.+)/);
|
|
45
|
+
if (authorMatch) metadata.author = authorMatch[1].trim();
|
|
46
|
+
const changefreqMatch = jsdoc.match(
|
|
47
|
+
/@changefreq\s+(always|hourly|daily|weekly|monthly|yearly|never)/
|
|
48
|
+
);
|
|
49
|
+
if (changefreqMatch) {
|
|
50
|
+
metadata.changefreq = changefreqMatch[1];
|
|
51
|
+
}
|
|
52
|
+
const priorityMatch = jsdoc.match(/@priority\s+([0-9.]+)/);
|
|
53
|
+
if (priorityMatch) {
|
|
54
|
+
metadata.priority = parseFloat(priorityMatch[1]);
|
|
55
|
+
}
|
|
56
|
+
return Object.keys(metadata).length > 0 ? metadata : null;
|
|
57
|
+
}
|
|
58
|
+
function extractExportMetadata(content) {
|
|
59
|
+
const metadataMatch = content.match(
|
|
60
|
+
/export\s+const\s+metadata\s*=\s*({[\s\S]*?});?/
|
|
61
|
+
);
|
|
62
|
+
if (!metadataMatch) return null;
|
|
63
|
+
try {
|
|
64
|
+
const metadataCode = metadataMatch[1];
|
|
65
|
+
const safeCode = metadataCode.replace(/import\s+.*?from\s+['"][^'"]*['"];?/g, "").replace(/require\s*\([^)]*\)/g, '""').replace(/process\.env\.[A-Z_]+/g, '""');
|
|
66
|
+
const func = new Function(`return ${safeCode}`);
|
|
67
|
+
return func();
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.warn(
|
|
70
|
+
`[vite-plugin-file-router] Failed to parse metadata export:`,
|
|
71
|
+
error
|
|
72
|
+
);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function generateSitemap(routes, baseUrl) {
|
|
77
|
+
const urls = routes.map((route) => {
|
|
78
|
+
const lastmod = (/* @__PURE__ */ new Date()).toISOString();
|
|
79
|
+
const changefreq = route.metadata?.changefreq || "monthly";
|
|
80
|
+
const priority = route.metadata?.priority || 0.8;
|
|
81
|
+
return ` <url>
|
|
82
|
+
<loc>${baseUrl}${route.path}</loc>
|
|
83
|
+
<lastmod>${lastmod}</lastmod>
|
|
84
|
+
<changefreq>${changefreq}</changefreq>
|
|
85
|
+
<priority>${priority}</priority>
|
|
86
|
+
</url>`;
|
|
87
|
+
}).join("\n");
|
|
88
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
89
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
90
|
+
${urls}
|
|
91
|
+
</urlset>`;
|
|
92
|
+
}
|
|
93
|
+
function generateRobots(baseUrl, disallowPaths = []) {
|
|
94
|
+
const disallowRules = disallowPaths.map((path6) => `Disallow: ${path6}`).join("\n");
|
|
95
|
+
return `User-agent: *
|
|
96
|
+
Allow: /
|
|
97
|
+
${disallowRules ? `
|
|
98
|
+
${disallowRules}` : ""}
|
|
99
|
+
|
|
100
|
+
Sitemap: ${baseUrl}/sitemap.xml`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/core/route-generator.ts
|
|
104
|
+
import path2 from "path";
|
|
105
|
+
|
|
106
|
+
// src/core/scanner.ts
|
|
107
|
+
import fg from "fast-glob";
|
|
108
|
+
import fs3 from "fs";
|
|
109
|
+
import path from "path";
|
|
110
|
+
|
|
111
|
+
// src/core/utils.ts
|
|
112
|
+
import fs2 from "fs";
|
|
113
|
+
var slash = (p) => p.replace(/\\/g, "/");
|
|
114
|
+
function detectExportType(filePath) {
|
|
115
|
+
try {
|
|
116
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
117
|
+
const hasDefaultExport = /export\s+default\s+/.test(content);
|
|
118
|
+
const hasNamedExport = /export\s+(const|function|class)\s+\w+\s*[=(]/.test(
|
|
119
|
+
content
|
|
120
|
+
);
|
|
121
|
+
if (hasDefaultExport) {
|
|
122
|
+
return "default";
|
|
123
|
+
} else if (hasNamedExport) {
|
|
124
|
+
return "named";
|
|
125
|
+
}
|
|
126
|
+
return "default";
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn(
|
|
129
|
+
`[vite-plugin-file-router] Failed to read file ${filePath}:`,
|
|
130
|
+
error
|
|
131
|
+
);
|
|
132
|
+
return "default";
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/core/scanner.ts
|
|
137
|
+
async function scanPages(resolvedPagesDir, opts) {
|
|
138
|
+
const exts = opts.extensions.join("|");
|
|
139
|
+
const pattern = `${slash(resolvedPagesDir)}/**/${opts.pageFileName}.+(${exts})`;
|
|
140
|
+
const files = await fg(pattern, { dot: true });
|
|
141
|
+
return files.map((f) => path.resolve(f));
|
|
142
|
+
}
|
|
143
|
+
function collectLayouts(filePath, resolvedPagesDir, opts) {
|
|
144
|
+
const rel = slash(path.relative(resolvedPagesDir, filePath));
|
|
145
|
+
const dir = path.dirname(rel);
|
|
146
|
+
const parts = dir === "." ? [] : dir.split("/").filter(Boolean);
|
|
147
|
+
const layouts = [];
|
|
148
|
+
for (let i = 0; i <= parts.length; i++) {
|
|
149
|
+
const p = parts.slice(0, i).join("/");
|
|
150
|
+
for (const ext of opts.extensions) {
|
|
151
|
+
const candidate = path.resolve(
|
|
152
|
+
resolvedPagesDir,
|
|
153
|
+
p || "",
|
|
154
|
+
`${opts.layoutFileName}.${ext}`
|
|
155
|
+
);
|
|
156
|
+
if (fs3.existsSync(candidate)) {
|
|
157
|
+
layouts.push(candidate);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return layouts;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/core/route-generator.ts
|
|
166
|
+
function segmentToRoute(seg) {
|
|
167
|
+
if (/^\[\.{3}.+\]$/.test(seg)) {
|
|
168
|
+
const name = seg.slice(4, -1);
|
|
169
|
+
return `:${name}(.*)`;
|
|
170
|
+
}
|
|
171
|
+
if (/^\[.+\]$/.test(seg)) {
|
|
172
|
+
const name = seg.slice(1, -1);
|
|
173
|
+
return `:${name}`;
|
|
174
|
+
}
|
|
175
|
+
return seg;
|
|
176
|
+
}
|
|
177
|
+
function filePathToRoute(filePath, resolvedPagesDir) {
|
|
178
|
+
const rel = slash(path2.relative(resolvedPagesDir, filePath));
|
|
179
|
+
const dir = path2.dirname(rel);
|
|
180
|
+
const parts = dir === "." ? [] : dir.split("/").filter(Boolean);
|
|
181
|
+
const filteredParts = parts.filter(
|
|
182
|
+
(part) => (!part.startsWith("(") || !part.endsWith(")")) && !part.startsWith("_")
|
|
183
|
+
);
|
|
184
|
+
const segments = filteredParts.map(segmentToRoute);
|
|
185
|
+
const route = "/" + segments.join("/");
|
|
186
|
+
return route === "/" ? "/" : route.replace(/\/+/g, "/");
|
|
187
|
+
}
|
|
188
|
+
function createRouteEntry(filePath, resolvedPagesDir, opts) {
|
|
189
|
+
const route = filePathToRoute(filePath, resolvedPagesDir);
|
|
190
|
+
const id = slash(path2.relative(resolvedPagesDir, filePath)).replace(/\//g, "_").replace(/\.[^.]+$/, "");
|
|
191
|
+
const exportType = detectExportType(filePath);
|
|
192
|
+
const loader = `() => import(${JSON.stringify(slash(filePath))})`;
|
|
193
|
+
const layouts = collectLayouts(filePath, resolvedPagesDir, opts).map(
|
|
194
|
+
(lp) => `() => import(${JSON.stringify(slash(lp))})`
|
|
195
|
+
);
|
|
196
|
+
return {
|
|
197
|
+
id,
|
|
198
|
+
path: route,
|
|
199
|
+
filePath: slash(filePath),
|
|
200
|
+
loader,
|
|
201
|
+
exportType,
|
|
202
|
+
layouts
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/core/type-generator.ts
|
|
207
|
+
function generateRouteTypes(routes) {
|
|
208
|
+
const routePaths = routes.map((route) => `'${route.path}'`).join(" | ");
|
|
209
|
+
const routeParams = {};
|
|
210
|
+
routes.forEach((route) => {
|
|
211
|
+
const params = {};
|
|
212
|
+
const idMatches = route.path.match(/\[([^\]]+)\]/g);
|
|
213
|
+
if (idMatches) {
|
|
214
|
+
idMatches.forEach((match) => {
|
|
215
|
+
const paramName = match.slice(1, -1);
|
|
216
|
+
if (paramName.startsWith("...")) {
|
|
217
|
+
params[paramName.slice(3)] = "string[]";
|
|
218
|
+
} else {
|
|
219
|
+
params[paramName] = "string";
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
if (Object.keys(params).length > 0) {
|
|
224
|
+
routeParams[route.path] = params;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
const routeParamsType = Object.keys(routeParams).length > 0 ? `export type RouteParams = {
|
|
228
|
+
${Object.entries(routeParams).map(([path6, params]) => {
|
|
229
|
+
const paramEntries = Object.entries(params).map(([key, type]) => `${key}: ${type}`).join(", ");
|
|
230
|
+
return ` '${path6}': { ${paramEntries} }`;
|
|
231
|
+
}).join("\n")}
|
|
232
|
+
}` : "export type RouteParams = Record<string, never>";
|
|
233
|
+
return `// \u0410\u0432\u0442\u043E\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0435 \u0442\u0438\u043F\u044B \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u043E\u0432
|
|
234
|
+
export type RoutePath = ${routePaths || "never"}
|
|
235
|
+
|
|
236
|
+
${routeParamsType}
|
|
237
|
+
|
|
238
|
+
export type PageProps<T extends RoutePath = RoutePath> = {
|
|
239
|
+
params: RouteParams[T]
|
|
240
|
+
searchParams?: Record<string, string>
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface LayoutProps {
|
|
244
|
+
children: React.ReactNode
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export interface RouteInfo {
|
|
248
|
+
id: string
|
|
249
|
+
path: string
|
|
250
|
+
filePath: string
|
|
251
|
+
exportType: 'default' | 'named'
|
|
252
|
+
layouts: string[]
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// \u0423\u0442\u0438\u043B\u0438\u0442\u044B \u0434\u043B\u044F \u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438
|
|
256
|
+
export function navigate<T extends RoutePath>(
|
|
257
|
+
path: T,
|
|
258
|
+
params?: RouteParams[T]
|
|
259
|
+
): void {
|
|
260
|
+
// \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438
|
|
261
|
+
window.location.href = path
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function useParams<T extends RoutePath>(): RouteParams[T] {
|
|
265
|
+
// \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0445\u0443\u043A\u0430 \u0434\u043B\u044F \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043E\u0432
|
|
266
|
+
return {} as RouteParams[T]
|
|
267
|
+
}
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
function generateMetadataTypes() {
|
|
271
|
+
return `// \u0422\u0438\u043F\u044B \u0434\u043B\u044F \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0442\u0440\u0430\u043D\u0438\u0446
|
|
272
|
+
export interface PageMetadata {
|
|
273
|
+
title?: string
|
|
274
|
+
description?: string
|
|
275
|
+
keywords?: string[]
|
|
276
|
+
author?: string
|
|
277
|
+
changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
|
|
278
|
+
priority?: number
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface SEOConfig {
|
|
282
|
+
baseUrl: string
|
|
283
|
+
defaultTitle?: string
|
|
284
|
+
defaultDescription?: string
|
|
285
|
+
disallowPaths?: string[]
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/core/build-generator.ts
|
|
291
|
+
async function generateTypes(resolvedPagesDir, opts) {
|
|
292
|
+
const pages = await scanPages(resolvedPagesDir, opts);
|
|
293
|
+
const routes = pages.map((fp) => createRouteEntry(fp, resolvedPagesDir, opts));
|
|
294
|
+
const routeTypes = generateRouteTypes(routes);
|
|
295
|
+
const metadataTypes = generateMetadataTypes();
|
|
296
|
+
const typesDir = path3.join(process.cwd(), "dist", "types");
|
|
297
|
+
if (!fs4.existsSync(typesDir)) {
|
|
298
|
+
fs4.mkdirSync(typesDir, { recursive: true });
|
|
299
|
+
}
|
|
300
|
+
fs4.writeFileSync(path3.join(typesDir, "routes.d.ts"), routeTypes);
|
|
301
|
+
fs4.writeFileSync(path3.join(typesDir, "metadata.d.ts"), metadataTypes);
|
|
302
|
+
}
|
|
303
|
+
async function generateSEOFiles(resolvedPagesDir, opts) {
|
|
304
|
+
const pages = await scanPages(resolvedPagesDir, opts);
|
|
305
|
+
const routesWithMetadata = pages.map((fp) => {
|
|
306
|
+
const entry = createRouteEntry(fp, resolvedPagesDir, opts);
|
|
307
|
+
const metadata = extractMetadata(fp);
|
|
308
|
+
return {
|
|
309
|
+
path: entry.path,
|
|
310
|
+
metadata: metadata || void 0
|
|
311
|
+
};
|
|
312
|
+
}).filter(
|
|
313
|
+
(route) => !opts.disallowPaths.some((disallow) => route.path.startsWith(disallow))
|
|
314
|
+
);
|
|
315
|
+
const sitemap = generateSitemap(routesWithMetadata, opts.baseUrl);
|
|
316
|
+
const robots = generateRobots(opts.baseUrl, opts.disallowPaths);
|
|
317
|
+
const distDir = path3.join(process.cwd(), "dist");
|
|
318
|
+
if (!fs4.existsSync(distDir)) {
|
|
319
|
+
fs4.mkdirSync(distDir, { recursive: true });
|
|
320
|
+
}
|
|
321
|
+
fs4.writeFileSync(path3.join(distDir, "sitemap.xml"), sitemap);
|
|
322
|
+
fs4.writeFileSync(path3.join(distDir, "robots.txt"), robots);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/core/hmr-handlers.ts
|
|
326
|
+
import fs5 from "fs";
|
|
327
|
+
function createHMRHandlers(resolvedPagesDir, resolvedVirtualId, root) {
|
|
328
|
+
const configureServer = (srv) => {
|
|
329
|
+
const invalidateVirtual = async () => {
|
|
330
|
+
const mod = srv.moduleGraph?.getModuleById?.(resolvedVirtualId);
|
|
331
|
+
if (mod) {
|
|
332
|
+
srv.moduleGraph?.invalidateModule?.(mod);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
const watchPath = fs5.existsSync(resolvedPagesDir) ? resolvedPagesDir : root;
|
|
336
|
+
srv.watcher?.add?.(watchPath);
|
|
337
|
+
srv.watcher?.on?.("add", (p) => {
|
|
338
|
+
if (p.startsWith(resolvedPagesDir)) invalidateVirtual();
|
|
339
|
+
});
|
|
340
|
+
srv.watcher?.on?.("unlink", (p) => {
|
|
341
|
+
if (p.startsWith(resolvedPagesDir)) invalidateVirtual();
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
const handleHotUpdate = (ctx) => {
|
|
345
|
+
const f = ctx.file;
|
|
346
|
+
if (!f?.startsWith(resolvedPagesDir)) return;
|
|
347
|
+
const mod = ctx.server.moduleGraph?.getModuleById?.(resolvedVirtualId);
|
|
348
|
+
if (mod) {
|
|
349
|
+
ctx.server.moduleGraph?.invalidateModule?.(mod);
|
|
350
|
+
return [mod];
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
return { configureServer, handleHotUpdate };
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/core/manifest-loader.ts
|
|
357
|
+
import fs6 from "fs";
|
|
358
|
+
import path4 from "path";
|
|
359
|
+
async function loadGeneratedManifest(root) {
|
|
360
|
+
const manifestPath = path4.join(root, "dist", "routes-manifest.js");
|
|
361
|
+
if (fs6.existsSync(manifestPath)) {
|
|
362
|
+
try {
|
|
363
|
+
const manifestContent = fs6.readFileSync(manifestPath, "utf-8");
|
|
364
|
+
const manifestRegex = /export const manifest = \[.*?\];/s;
|
|
365
|
+
const manifestMatch = manifestRegex.exec(manifestContent);
|
|
366
|
+
const basePathRegex = /export const basePath = ['"](.*?)['"];/;
|
|
367
|
+
const basePathMatch = basePathRegex.exec(manifestContent);
|
|
368
|
+
const basePath = basePathMatch ? basePathMatch[1] : "/";
|
|
369
|
+
if (manifestMatch) {
|
|
370
|
+
return `// virtual routes (production mode - using generated manifest)
|
|
371
|
+
${manifestMatch[0]}
|
|
372
|
+
export const basePath = ${JSON.stringify(basePath)};
|
|
373
|
+
export default manifest;
|
|
374
|
+
`;
|
|
375
|
+
}
|
|
376
|
+
} catch (error) {
|
|
377
|
+
console.warn(
|
|
378
|
+
"[vite-plugin-file-router] Failed to load generated manifest:",
|
|
379
|
+
error
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return `// virtual routes (production mode - empty manifest)
|
|
384
|
+
export const manifest = [];
|
|
385
|
+
export const basePath = '/';
|
|
386
|
+
export default manifest;
|
|
387
|
+
`;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/core/virtual-module.ts
|
|
391
|
+
async function generateVirtualModuleCode(resolvedPagesDir, opts) {
|
|
392
|
+
const pages = await scanPages(resolvedPagesDir, opts);
|
|
393
|
+
const entries = pages.map((fp) => {
|
|
394
|
+
const entry = createRouteEntry(fp, resolvedPagesDir, opts);
|
|
395
|
+
return `{
|
|
396
|
+
id: ${JSON.stringify(entry.id)},
|
|
397
|
+
path: ${JSON.stringify(entry.path)},
|
|
398
|
+
filePath: ${JSON.stringify(entry.filePath)},
|
|
399
|
+
loader: ${entry.loader},
|
|
400
|
+
exportType: ${JSON.stringify(entry.exportType)},
|
|
401
|
+
layouts: [${entry.layouts.join(",")}]
|
|
402
|
+
}`;
|
|
403
|
+
});
|
|
404
|
+
return `// Auto-generated routes manifest
|
|
405
|
+
const manifest = [${entries.join(",\n")}];
|
|
406
|
+
|
|
407
|
+
export const basePath = ${JSON.stringify(opts.basePath ?? "/")};
|
|
408
|
+
|
|
409
|
+
export { manifest };
|
|
410
|
+
export default manifest;
|
|
411
|
+
`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/plugin.ts
|
|
415
|
+
function pathRushRouting(rawOpts = {}) {
|
|
416
|
+
const opts = {
|
|
417
|
+
pagesDir: rawOpts.pagesDir ?? "src/pages",
|
|
418
|
+
pageFileName: rawOpts.pageFileName ?? "page",
|
|
419
|
+
layoutFileName: rawOpts.layoutFileName ?? "layout",
|
|
420
|
+
extensions: rawOpts.extensions ?? ["tsx"],
|
|
421
|
+
baseUrl: rawOpts.baseUrl ?? "http://localhost:5173",
|
|
422
|
+
basePath: rawOpts.basePath ?? "/",
|
|
423
|
+
disallowPaths: rawOpts.disallowPaths ?? [],
|
|
424
|
+
generateTypes: rawOpts.generateTypes ?? true,
|
|
425
|
+
enableSEO: rawOpts.enableSEO ?? true
|
|
426
|
+
};
|
|
427
|
+
const VIRTUAL_ID = "virtual:routes";
|
|
428
|
+
const RESOLVED_VIRTUAL_ID = "\0" + VIRTUAL_ID;
|
|
429
|
+
let root = process.cwd();
|
|
430
|
+
let resolvedPagesDir = path5.resolve(root, opts.pagesDir);
|
|
431
|
+
const plugin = {
|
|
432
|
+
name: "vite-plugin-file-router-mwv",
|
|
433
|
+
enforce: "pre",
|
|
434
|
+
// Автоматическая настройка Vite конфигурации
|
|
435
|
+
config(userConfig) {
|
|
436
|
+
const existingAlias = userConfig.resolve?.alias;
|
|
437
|
+
const existingExclude = userConfig.optimizeDeps?.exclude;
|
|
438
|
+
return {
|
|
439
|
+
optimizeDeps: {
|
|
440
|
+
exclude: [
|
|
441
|
+
...Array.isArray(existingExclude) ? existingExclude : [],
|
|
442
|
+
"virtual:routes"
|
|
443
|
+
]
|
|
444
|
+
},
|
|
445
|
+
resolve: {
|
|
446
|
+
alias: {
|
|
447
|
+
...typeof existingAlias === "object" ? existingAlias : {},
|
|
448
|
+
"virtual:routes": "virtual:routes"
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
},
|
|
453
|
+
resolveId(id) {
|
|
454
|
+
if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
|
|
455
|
+
return null;
|
|
456
|
+
},
|
|
457
|
+
async load(id) {
|
|
458
|
+
if (id === RESOLVED_VIRTUAL_ID) {
|
|
459
|
+
if (!fs7.existsSync(resolvedPagesDir)) {
|
|
460
|
+
return await loadGeneratedManifest(root);
|
|
461
|
+
}
|
|
462
|
+
return await generateVirtualModuleCode(resolvedPagesDir, opts);
|
|
463
|
+
}
|
|
464
|
+
return null;
|
|
465
|
+
},
|
|
466
|
+
async buildStart() {
|
|
467
|
+
root = process.cwd();
|
|
468
|
+
resolvedPagesDir = path5.resolve(root, opts.pagesDir);
|
|
469
|
+
if (!fs7.existsSync(resolvedPagesDir)) {
|
|
470
|
+
console.warn(
|
|
471
|
+
`[vite-plugin-file-router] pagesDir "${resolvedPagesDir}" not found.`
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
async generateBundle() {
|
|
476
|
+
if (!fs7.existsSync(resolvedPagesDir)) {
|
|
477
|
+
console.warn(
|
|
478
|
+
`[vite-plugin-file-router] pagesDir "${resolvedPagesDir}" not found in production build. Skipping route generation.`
|
|
479
|
+
);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
if (opts.generateTypes) {
|
|
483
|
+
try {
|
|
484
|
+
await generateTypes(resolvedPagesDir, opts);
|
|
485
|
+
} catch (error) {
|
|
486
|
+
console.warn(
|
|
487
|
+
`[vite-plugin-file-router] Failed to generate types: ${error}`
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (opts.enableSEO) {
|
|
492
|
+
try {
|
|
493
|
+
await generateSEOFiles(resolvedPagesDir, opts);
|
|
494
|
+
} catch (error) {
|
|
495
|
+
console.warn(
|
|
496
|
+
`[vite-plugin-file-router] Failed to generate SEO files: ${error}`
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
if (process.env.NODE_ENV !== "production") {
|
|
503
|
+
const { configureServer, handleHotUpdate } = createHMRHandlers(
|
|
504
|
+
resolvedPagesDir,
|
|
505
|
+
RESOLVED_VIRTUAL_ID,
|
|
506
|
+
root
|
|
507
|
+
);
|
|
508
|
+
plugin.configureServer = configureServer;
|
|
509
|
+
plugin.handleHotUpdate = handleHotUpdate;
|
|
510
|
+
}
|
|
511
|
+
return plugin;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export {
|
|
515
|
+
pathRushRouting
|
|
516
|
+
};
|
|
517
|
+
//# sourceMappingURL=chunk-VBEFTPIV.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/core/build-generator.ts","../src/core/metadata.ts","../src/core/route-generator.ts","../src/core/scanner.ts","../src/core/utils.ts","../src/core/type-generator.ts","../src/core/hmr-handlers.ts","../src/core/manifest-loader.ts","../src/core/virtual-module.ts"],"sourcesContent":["import fs from 'node:fs'\r\nimport path from 'node:path'\r\nimport type { Plugin, UserConfig } from 'vite'\r\nimport { generateSEOFiles, generateTypes } from './core/build-generator'\r\nimport { createHMRHandlers } from './core/hmr-handlers'\r\nimport { loadGeneratedManifest } from './core/manifest-loader'\r\nimport type { Options } from './core/types/types'\r\nimport { generateVirtualModuleCode } from './core/virtual-module'\r\n\r\nexport type { Options } from './core/types/types'\r\n\r\nexport function pathRushRouting(rawOpts: Options = {}): Plugin {\r\n\tconst opts: Required<Options> = {\r\n\t\tpagesDir: rawOpts.pagesDir ?? 'src/pages',\r\n\t\tpageFileName: rawOpts.pageFileName ?? 'page',\r\n\t\tlayoutFileName: rawOpts.layoutFileName ?? 'layout',\r\n\t\textensions: rawOpts.extensions ?? ['tsx'],\r\n\t\tbaseUrl: rawOpts.baseUrl ?? 'http://localhost:5173',\r\n\t\tbasePath: rawOpts.basePath ?? '/',\r\n\t\tdisallowPaths: rawOpts.disallowPaths ?? [],\r\n\t\tgenerateTypes: rawOpts.generateTypes ?? true,\r\n\t\tenableSEO: rawOpts.enableSEO ?? true,\r\n\t}\r\n\r\n\tconst VIRTUAL_ID = 'virtual:routes'\r\n\tconst RESOLVED_VIRTUAL_ID = '\\0' + VIRTUAL_ID\r\n\tlet root = process.cwd()\r\n\tlet resolvedPagesDir = path.resolve(root, opts.pagesDir)\r\n\r\n\tconst plugin: Plugin = {\r\n\t\tname: 'vite-plugin-file-router-mwv',\r\n\t\tenforce: 'pre',\r\n\r\n\t\t// Автоматическая настройка Vite конфигурации\r\n\t\tconfig(userConfig: UserConfig): UserConfig {\r\n\t\t\tconst existingAlias = userConfig.resolve?.alias\r\n\t\t\tconst existingExclude = userConfig.optimizeDeps?.exclude\r\n\r\n\t\t\t// Безопасно мерджим с существующей конфигурацией\r\n\t\t\treturn {\r\n\t\t\t\toptimizeDeps: {\r\n\t\t\t\t\texclude: [\r\n\t\t\t\t\t\t...(Array.isArray(existingExclude) ? existingExclude : []),\r\n\t\t\t\t\t\t'virtual:routes',\r\n\t\t\t\t\t],\r\n\t\t\t\t},\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\talias: {\r\n\t\t\t\t\t\t...(typeof existingAlias === 'object' ? existingAlias : {}),\r\n\t\t\t\t\t\t'virtual:routes': 'virtual:routes',\r\n\t\t\t\t\t},\r\n\t\t\t\t},\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tresolveId(id: string) {\r\n\t\t\tif (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID\r\n\t\t\treturn null\r\n\t\t},\r\n\r\n\t\tasync load(id: string) {\r\n\t\t\tif (id === RESOLVED_VIRTUAL_ID) {\r\n\t\t\t\t// В production режиме проверяем существование директории pages\r\n\t\t\t\tif (!fs.existsSync(resolvedPagesDir)) {\r\n\t\t\t\t\t// В production пытаемся загрузить сгенерированный манифест\r\n\t\t\t\t\treturn await loadGeneratedManifest(root)\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn await generateVirtualModuleCode(resolvedPagesDir, opts)\r\n\t\t\t}\r\n\t\t\treturn null\r\n\t\t},\r\n\r\n\t\tasync buildStart() {\r\n\t\t\troot = process.cwd()\r\n\t\t\tresolvedPagesDir = path.resolve(root, opts.pagesDir)\r\n\r\n\t\t\tif (!fs.existsSync(resolvedPagesDir)) {\r\n\t\t\t\tconsole.warn(\r\n\t\t\t\t\t`[vite-plugin-file-router] pagesDir \"${resolvedPagesDir}\" not found.`\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tasync generateBundle() {\r\n\t\t\t// Проверяем существование директории pages\r\n\t\t\tif (!fs.existsSync(resolvedPagesDir)) {\r\n\t\t\t\tconsole.warn(\r\n\t\t\t\t\t`[vite-plugin-file-router] pagesDir \"${resolvedPagesDir}\" not found in production build. Skipping route generation.`\r\n\t\t\t\t)\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\r\n\t\t\t// Генерируем TypeScript типы\r\n\t\t\tif (opts.generateTypes) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait generateTypes(resolvedPagesDir, opts)\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tconsole.warn(\r\n\t\t\t\t\t\t`[vite-plugin-file-router] Failed to generate types: ${error}`\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Генерируем SEO файлы\r\n\t\t\tif (opts.enableSEO) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tawait generateSEOFiles(resolvedPagesDir, opts)\r\n\t\t\t\t} catch (error) {\r\n\t\t\t\t\tconsole.warn(\r\n\t\t\t\t\t\t`[vite-plugin-file-router] Failed to generate SEO files: ${error}`\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t}\r\n\r\n\t// Добавляем HMR только если в development режиме\r\n\tif (process.env.NODE_ENV !== 'production') {\r\n\t\tconst { configureServer, handleHotUpdate } = createHMRHandlers(\r\n\t\t\tresolvedPagesDir,\r\n\t\t\tRESOLVED_VIRTUAL_ID,\r\n\t\t\troot\r\n\t\t)\r\n\t\tplugin.configureServer = configureServer\r\n\t\tplugin.handleHotUpdate = handleHotUpdate\r\n\t}\r\n\r\n\treturn plugin\r\n}\r\n","import fs from 'node:fs'\r\nimport path from 'node:path'\r\nimport { extractMetadata, generateRobots, generateSitemap } from './metadata'\r\nimport { createRouteEntry } from './route-generator'\r\nimport { scanPages } from './scanner'\r\nimport { generateMetadataTypes, generateRouteTypes } from './type-generator'\r\nimport type { Options } from './types/types'\r\n\r\nexport async function generateTypes(\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n) {\r\n\tconst pages = await scanPages(resolvedPagesDir, opts)\r\n\tconst routes = pages.map(fp => createRouteEntry(fp, resolvedPagesDir, opts))\r\n\r\n\tconst routeTypes = generateRouteTypes(routes)\r\n\tconst metadataTypes = generateMetadataTypes()\r\n\r\n\t// Создаем директорию для типов\r\n\tconst typesDir = path.join(process.cwd(), 'dist', 'types')\r\n\tif (!fs.existsSync(typesDir)) {\r\n\t\tfs.mkdirSync(typesDir, { recursive: true })\r\n\t}\r\n\r\n\tfs.writeFileSync(path.join(typesDir, 'routes.d.ts'), routeTypes)\r\n\tfs.writeFileSync(path.join(typesDir, 'metadata.d.ts'), metadataTypes)\r\n}\r\n\r\nexport async function generateSEOFiles(\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n) {\r\n\tconst pages = await scanPages(resolvedPagesDir, opts)\r\n\tconst routesWithMetadata = pages\r\n\t\t.map(fp => {\r\n\t\t\tconst entry = createRouteEntry(fp, resolvedPagesDir, opts)\r\n\t\t\tconst metadata = extractMetadata(fp)\r\n\t\t\treturn {\r\n\t\t\t\tpath: entry.path,\r\n\t\t\t\tmetadata: metadata || undefined,\r\n\t\t\t}\r\n\t\t})\r\n\t\t.filter(\r\n\t\t\troute =>\r\n\t\t\t\t!opts.disallowPaths.some(disallow => route.path.startsWith(disallow))\r\n\t\t)\r\n\r\n\t// Генерируем sitemap.xml и robots.txt\r\n\tconst sitemap = generateSitemap(routesWithMetadata, opts.baseUrl)\r\n\tconst robots = generateRobots(opts.baseUrl, opts.disallowPaths)\r\n\r\n\tconst distDir = path.join(process.cwd(), 'dist')\r\n\tif (!fs.existsSync(distDir)) {\r\n\t\tfs.mkdirSync(distDir, { recursive: true })\r\n\t}\r\n\r\n\tfs.writeFileSync(path.join(distDir, 'sitemap.xml'), sitemap)\r\n\tfs.writeFileSync(path.join(distDir, 'robots.txt'), robots)\r\n}\r\n","import fs from 'node:fs'\r\nimport type { PageMetadata } from './types/types'\r\n\r\nexport function extractMetadata(filePath: string): PageMetadata | null {\r\n\ttry {\r\n\t\tconst content = fs.readFileSync(filePath, 'utf-8')\r\n\r\n\t\t// Парсинг JSDoc комментариев\r\n\t\tconst jsdocMetadata = extractJSDocMetadata(content)\r\n\t\tif (jsdocMetadata) {\r\n\t\t\treturn jsdocMetadata\r\n\t\t}\r\n\r\n\t\t// Парсинг экспорта metadata\r\n\t\tconst exportMetadata = extractExportMetadata(content)\r\n\t\tif (exportMetadata) {\r\n\t\t\treturn exportMetadata\r\n\t\t}\r\n\r\n\t\treturn null\r\n\t} catch (error) {\r\n\t\tconsole.warn(\r\n\t\t\t`[vite-plugin-file-router] Failed to extract metadata from ${filePath}:`,\r\n\t\t\terror\r\n\t\t)\r\n\t\treturn null\r\n\t}\r\n}\r\n\r\nfunction extractJSDocMetadata(content: string): PageMetadata | null {\r\n\tconst jsdocMatch = content.match(/\\/\\*\\*([\\s\\S]*?)\\*\\//)\r\n\tif (!jsdocMatch) return null\r\n\r\n\tconst jsdoc = jsdocMatch[1]\r\n\tconst metadata: PageMetadata = {}\r\n\r\n\t// Парсинг JSDoc тегов\r\n\tconst titleMatch = jsdoc.match(/@title\\s+(.+)/)\r\n\tif (titleMatch) metadata.title = titleMatch[1].trim()\r\n\r\n\tconst descMatch = jsdoc.match(/@description\\s+(.+)/)\r\n\tif (descMatch) metadata.description = descMatch[1].trim()\r\n\r\n\tconst keywordsMatch = jsdoc.match(/@keywords\\s+(.+)/)\r\n\tif (keywordsMatch) {\r\n\t\tmetadata.keywords = keywordsMatch[1].split(',').map(k => k.trim())\r\n\t}\r\n\r\n\tconst authorMatch = jsdoc.match(/@author\\s+(.+)/)\r\n\tif (authorMatch) metadata.author = authorMatch[1].trim()\r\n\r\n\tconst changefreqMatch = jsdoc.match(\r\n\t\t/@changefreq\\s+(always|hourly|daily|weekly|monthly|yearly|never)/\r\n\t)\r\n\tif (changefreqMatch) {\r\n\t\tmetadata.changefreq = changefreqMatch[1] as PageMetadata['changefreq']\r\n\t}\r\n\r\n\tconst priorityMatch = jsdoc.match(/@priority\\s+([0-9.]+)/)\r\n\tif (priorityMatch) {\r\n\t\tmetadata.priority = parseFloat(priorityMatch[1])\r\n\t}\r\n\r\n\treturn Object.keys(metadata).length > 0 ? metadata : null\r\n}\r\n\r\nfunction extractExportMetadata(content: string): PageMetadata | null {\r\n\t// Ищем экспорт const metadata = { ... }\r\n\tconst metadataMatch = content.match(\r\n\t\t/export\\s+const\\s+metadata\\s*=\\s*({[\\s\\S]*?});?/\r\n\t)\r\n\tif (!metadataMatch) return null\r\n\r\n\ttry {\r\n\t\t// Безопасное выполнение кода для извлечения объекта\r\n\t\tconst metadataCode = metadataMatch[1]\r\n\t\t// Заменяем возможные импорты и функции на безопасные значения\r\n\t\tconst safeCode = metadataCode\r\n\t\t\t.replace(/import\\s+.*?from\\s+['\"][^'\"]*['\"];?/g, '')\r\n\t\t\t.replace(/require\\s*\\([^)]*\\)/g, '\"\"')\r\n\t\t\t.replace(/process\\.env\\.[A-Z_]+/g, '\"\"')\r\n\r\n\t\t// Создаем функцию для безопасного выполнения\r\n\t\tconst func = new Function(`return ${safeCode}`)\r\n\t\treturn func()\r\n\t} catch (error) {\r\n\t\tconsole.warn(\r\n\t\t\t`[vite-plugin-file-router] Failed to parse metadata export:`,\r\n\t\t\terror\r\n\t\t)\r\n\t\treturn null\r\n\t}\r\n}\r\n\r\nexport function generateSitemap(\r\n\troutes: Array<{ path: string; metadata?: PageMetadata }>,\r\n\tbaseUrl: string\r\n): string {\r\n\tconst urls = routes\r\n\t\t.map(route => {\r\n\t\t\tconst lastmod = new Date().toISOString()\r\n\t\t\tconst changefreq = route.metadata?.changefreq || 'monthly'\r\n\t\t\tconst priority = route.metadata?.priority || 0.8\r\n\r\n\t\t\treturn ` <url>\r\n <loc>${baseUrl}${route.path}</loc>\r\n <lastmod>${lastmod}</lastmod>\r\n <changefreq>${changefreq}</changefreq>\r\n <priority>${priority}</priority>\r\n </url>`\r\n\t\t})\r\n\t\t.join('\\n')\r\n\r\n\treturn `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\r\n${urls}\r\n</urlset>`\r\n}\r\n\r\nexport function generateRobots(\r\n\tbaseUrl: string,\r\n\tdisallowPaths: string[] = []\r\n): string {\r\n\tconst disallowRules = disallowPaths\r\n\t\t.map(path => `Disallow: ${path}`)\r\n\t\t.join('\\n')\r\n\r\n\treturn `User-agent: *\r\nAllow: /\r\n${disallowRules ? `\\n${disallowRules}` : ''}\r\n\r\nSitemap: ${baseUrl}/sitemap.xml`\r\n}\r\n","import path from 'node:path'\r\nimport { collectLayouts } from './scanner'\r\nimport type { Options, RouteEntry } from './types/types'\r\nimport { detectExportType, slash } from './utils'\r\n\r\nexport function segmentToRoute(seg: string): string {\r\n\tif (/^\\[\\.{3}.+\\]$/.test(seg)) {\r\n\t\tconst name = seg.slice(4, -1)\r\n\t\treturn `:${name}(.*)`\r\n\t}\r\n\tif (/^\\[.+\\]$/.test(seg)) {\r\n\t\tconst name = seg.slice(1, -1)\r\n\t\treturn `:${name}`\r\n\t}\r\n\treturn seg\r\n}\r\n\r\nexport function filePathToRoute(\r\n\tfilePath: string,\r\n\tresolvedPagesDir: string\r\n): string {\r\n\tconst rel = slash(path.relative(resolvedPagesDir, filePath))\r\n\tconst dir = path.dirname(rel)\r\n\tconst parts = dir === '.' ? [] : dir.split('/').filter(Boolean)\r\n\t// 1. Выбрасываем группы маршрутов (auth), (shop) …\r\n\t// 2. Добавляем фильтр папок, начинающихся с _\r\n\tconst filteredParts = parts.filter(\r\n\t\tpart =>\r\n\t\t\t(!part.startsWith('(') || !part.endsWith(')')) && !part.startsWith('_')\r\n\t)\r\n\tconst segments = filteredParts.map(segmentToRoute)\r\n\tconst route = '/' + segments.join('/')\r\n\treturn route === '/' ? '/' : route.replace(/\\/+/g, '/')\r\n}\r\n\r\nexport function createRouteEntry(\r\n\tfilePath: string,\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n): RouteEntry {\r\n\tconst route = filePathToRoute(filePath, resolvedPagesDir)\r\n\tconst id = slash(path.relative(resolvedPagesDir, filePath))\r\n\t\t.replace(/\\//g, '_')\r\n\t\t.replace(/\\.[^.]+$/, '')\r\n\tconst exportType = detectExportType(filePath)\r\n\tconst loader = `() => import(${JSON.stringify(slash(filePath))})`\r\n\tconst layouts = collectLayouts(filePath, resolvedPagesDir, opts).map(\r\n\t\tlp => `() => import(${JSON.stringify(slash(lp))})`\r\n\t)\r\n\r\n\treturn {\r\n\t\tid,\r\n\t\tpath: route,\r\n\t\tfilePath: slash(filePath),\r\n\t\tloader,\r\n\t\texportType,\r\n\t\tlayouts,\r\n\t}\r\n}\r\n","import fg from 'fast-glob'\r\nimport fs from 'node:fs'\r\nimport path from 'node:path'\r\nimport type { Options } from './types/types'\r\nimport { slash } from './utils'\r\n\r\nexport async function scanPages(\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n): Promise<string[]> {\r\n\t// pattern like /abs/path/**/page.tsx\r\n\tconst exts = opts.extensions.join('|')\r\n\tconst pattern = `${slash(resolvedPagesDir)}/**/${\r\n\t\topts.pageFileName\r\n\t}.+(${exts})`\r\n\tconst files = await fg(pattern, { dot: true })\r\n\t// return absolute normalized paths\r\n\treturn files.map((f: string) => path.resolve(f))\r\n}\r\n\r\nexport function collectLayouts(\r\n\tfilePath: string,\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n): string[] {\r\n\tconst rel = slash(path.relative(resolvedPagesDir, filePath))\r\n\tconst dir = path.dirname(rel)\r\n\tconst parts = dir === '.' ? [] : dir.split('/').filter(Boolean)\r\n\r\n\tconst layouts: string[] = []\r\n\t// for each level from 0..parts.length include layout if exists\r\n\t// НЕ фильтруем группы маршрутов при поиске layout файлов\r\n\tfor (let i = 0; i <= parts.length; i++) {\r\n\t\tconst p = parts.slice(0, i).join('/')\r\n\t\tfor (const ext of opts.extensions) {\r\n\t\t\tconst candidate = path.resolve(\r\n\t\t\t\tresolvedPagesDir,\r\n\t\t\t\tp || '',\r\n\t\t\t\t`${opts.layoutFileName}.${ext}`\r\n\t\t\t)\r\n\t\t\tif (fs.existsSync(candidate)) {\r\n\t\t\t\tlayouts.push(candidate)\r\n\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn layouts\r\n}\r\n","import fs from 'node:fs'\r\nimport type { ExportType } from './types/types'\r\n\r\nexport const slash = (p: string) => p.replace(/\\\\/g, '/')\r\n\r\nexport function detectExportType(filePath: string): ExportType {\r\n\ttry {\r\n\t\tconst content = fs.readFileSync(filePath, 'utf-8')\r\n\r\n\t\t// Проверяем наличие default экспорта\r\n\t\tconst hasDefaultExport = /export\\s+default\\s+/.test(content)\r\n\r\n\t\t// Проверяем наличие любого именованного экспорта (функция, константа или класс)\r\n\t\tconst hasNamedExport = /export\\s+(const|function|class)\\s+\\w+\\s*[=(]/.test(\r\n\t\t\tcontent\r\n\t\t)\r\n\r\n\t\tif (hasDefaultExport) {\r\n\t\t\treturn 'default'\r\n\t\t} else if (hasNamedExport) {\r\n\t\t\treturn 'named'\r\n\t\t}\r\n\r\n\t\t// По умолчанию предполагаем default экспорт для обратной совместимости\r\n\t\treturn 'default'\r\n\t} catch (error) {\r\n\t\t// В случае ошибки чтения файла, предполагаем default экспорт\r\n\t\tconsole.warn(\r\n\t\t\t`[vite-plugin-file-router] Failed to read file ${filePath}:`,\r\n\t\t\terror\r\n\t\t)\r\n\t\treturn 'default'\r\n\t}\r\n}\r\n","import type { RouteEntry } from './types/types'\r\n\r\nexport function generateRouteTypes(routes: RouteEntry[]): string {\r\n\tconst routePaths = routes.map(route => `'${route.path}'`).join(' | ')\r\n\r\n\t// Извлекаем параметры из динамических маршрутов\r\n\tconst routeParams: Record<string, Record<string, string>> = {}\r\n\troutes.forEach(route => {\r\n\t\tconst params: Record<string, string> = {}\r\n\r\n\t\t// Парсим [id] параметры\r\n\t\tconst idMatches = route.path.match(/\\[([^\\]]+)\\]/g)\r\n\t\tif (idMatches) {\r\n\t\t\tidMatches.forEach(match => {\r\n\t\t\t\tconst paramName = match.slice(1, -1)\r\n\t\t\t\tif (paramName.startsWith('...')) {\r\n\t\t\t\t\t// Catch-all параметр\r\n\t\t\t\t\tparams[paramName.slice(3)] = 'string[]'\r\n\t\t\t\t} else {\r\n\t\t\t\t\tparams[paramName] = 'string'\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tif (Object.keys(params).length > 0) {\r\n\t\t\trouteParams[route.path] = params\r\n\t\t}\r\n\t})\r\n\r\n\tconst routeParamsType =\r\n\t\tObject.keys(routeParams).length > 0\r\n\t\t\t? `export type RouteParams = {\r\n${Object.entries(routeParams)\r\n\t.map(([path, params]) => {\r\n\t\tconst paramEntries = Object.entries(params)\r\n\t\t\t.map(([key, type]) => `${key}: ${type}`)\r\n\t\t\t.join(', ')\r\n\t\treturn ` '${path}': { ${paramEntries} }`\r\n\t})\r\n\t.join('\\n')}\r\n}`\r\n\t\t\t: 'export type RouteParams = Record<string, never>'\r\n\r\n\treturn `// Автогенерированные типы маршрутов\r\nexport type RoutePath = ${routePaths || 'never'}\r\n\r\n${routeParamsType}\r\n\r\nexport type PageProps<T extends RoutePath = RoutePath> = {\r\n params: RouteParams[T]\r\n searchParams?: Record<string, string>\r\n}\r\n\r\nexport interface LayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nexport interface RouteInfo {\r\n id: string\r\n path: string\r\n filePath: string\r\n exportType: 'default' | 'named'\r\n layouts: string[]\r\n}\r\n\r\n// Утилиты для навигации\r\nexport function navigate<T extends RoutePath>(\r\n path: T, \r\n params?: RouteParams[T]\r\n): void {\r\n // Реализация навигации\r\n window.location.href = path\r\n}\r\n\r\nexport function useParams<T extends RoutePath>(): RouteParams[T] {\r\n // Реализация хука для получения параметров\r\n return {} as RouteParams[T]\r\n}\r\n`\r\n}\r\n\r\nexport function generateMetadataTypes(): string {\r\n\treturn `// Типы для метаданных страниц\r\nexport interface PageMetadata {\r\n title?: string\r\n description?: string\r\n keywords?: string[]\r\n author?: string\r\n changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\r\n priority?: number\r\n}\r\n\r\nexport interface SEOConfig {\r\n baseUrl: string\r\n defaultTitle?: string\r\n defaultDescription?: string\r\n disallowPaths?: string[]\r\n}\r\n`\r\n}\r\n","import fs from 'node:fs'\r\n\r\nexport function createHMRHandlers(\r\n\tresolvedPagesDir: string,\r\n\tresolvedVirtualId: string,\r\n\troot: string\r\n) {\r\n\tconst configureServer = (srv: any) => {\r\n\t\tconst invalidateVirtual = async () => {\r\n\t\t\tconst mod = srv.moduleGraph?.getModuleById?.(resolvedVirtualId)\r\n\t\t\tif (mod) {\r\n\t\t\t\tsrv.moduleGraph?.invalidateModule?.(mod)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst watchPath = fs.existsSync(resolvedPagesDir) ? resolvedPagesDir : root\r\n\t\tsrv.watcher?.add?.(watchPath)\r\n\r\n\t\tsrv.watcher?.on?.('add', (p: string) => {\r\n\t\t\tif (p.startsWith(resolvedPagesDir)) invalidateVirtual()\r\n\t\t})\r\n\t\tsrv.watcher?.on?.('unlink', (p: string) => {\r\n\t\t\tif (p.startsWith(resolvedPagesDir)) invalidateVirtual()\r\n\t\t})\r\n\t}\r\n\r\n\tconst handleHotUpdate = (ctx: any) => {\r\n\t\tconst f = ctx.file\r\n\t\tif (!f?.startsWith(resolvedPagesDir)) return\r\n\r\n\t\tconst mod = ctx.server.moduleGraph?.getModuleById?.(resolvedVirtualId)\r\n\t\tif (mod) {\r\n\t\t\tctx.server.moduleGraph?.invalidateModule?.(mod)\r\n\t\t\treturn [mod]\r\n\t\t}\r\n\t}\r\n\r\n\treturn { configureServer, handleHotUpdate }\r\n}\r\n","import fs from 'node:fs'\r\nimport path from 'node:path'\r\n\r\nexport async function loadGeneratedManifest(root: string): Promise<string> {\r\n\tconst manifestPath = path.join(root, 'dist', 'routes-manifest.js')\r\n\tif (fs.existsSync(manifestPath)) {\r\n\t\ttry {\r\n\t\t\tconst manifestContent = fs.readFileSync(manifestPath, 'utf-8')\r\n\t\t\tconst manifestRegex = /export const manifest = \\[.*?\\];/s\r\n\t\t\tconst manifestMatch = manifestRegex.exec(manifestContent)\r\n\t\t\tconst basePathRegex = /export const basePath = ['\"](.*?)['\"];/\r\n\t\t\tconst basePathMatch = basePathRegex.exec(manifestContent)\r\n\t\t\tconst basePath = basePathMatch ? basePathMatch[1] : '/'\r\n\t\t\t\r\n\t\t\tif (manifestMatch) {\r\n\t\t\t\treturn `// virtual routes (production mode - using generated manifest)\r\n${manifestMatch[0]}\r\nexport const basePath = ${JSON.stringify(basePath)};\r\nexport default manifest;\r\n`\r\n\t\t\t}\r\n\t\t} catch (error) {\r\n\t\t\tconsole.warn(\r\n\t\t\t\t'[vite-plugin-file-router] Failed to load generated manifest:',\r\n\t\t\t\terror\r\n\t\t\t)\r\n\t\t}\r\n\t}\r\n\r\n\t// Fallback - пустой манифест\r\n\treturn `// virtual routes (production mode - empty manifest)\r\nexport const manifest = [];\r\nexport const basePath = '/';\r\nexport default manifest;\r\n`\r\n}\r\n","import { createRouteEntry } from './route-generator'\r\nimport { scanPages } from './scanner'\r\nimport type { Options } from './types/types'\r\n\r\nexport async function generateVirtualModuleCode(\r\n\tresolvedPagesDir: string,\r\n\topts: Required<Options>\r\n): Promise<string> {\r\n\tconst pages = await scanPages(resolvedPagesDir, opts)\r\n\tconst entries = pages.map(fp => {\r\n\t\tconst entry = createRouteEntry(fp, resolvedPagesDir, opts)\r\n\t\treturn `{\r\n id: ${JSON.stringify(entry.id)},\r\n path: ${JSON.stringify(entry.path)},\r\n filePath: ${JSON.stringify(entry.filePath)},\r\n loader: ${entry.loader},\r\n exportType: ${JSON.stringify(entry.exportType)},\r\n layouts: [${entry.layouts.join(',')}]\r\n }`\r\n\t})\r\n\r\n\treturn `// Auto-generated routes manifest\r\nconst manifest = [${entries.join(',\\n')}];\r\n\r\nexport const basePath = ${JSON.stringify(opts.basePath ?? '/')};\r\n\r\nexport { manifest };\r\nexport default manifest;\r\n`\r\n}\r\n"],"mappings":"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","names":["fs","path","fs","path","path","path","fs","fs","fs","path","path","path","fs","fs","fs","path","path","fs"]}
|
package/dist/core.d.cts
ADDED
package/dist/core.d.ts
ADDED