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/dist/plugin.js ADDED
@@ -0,0 +1,551 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/plugin.ts
31
+ var plugin_exports = {};
32
+ __export(plugin_exports, {
33
+ pathRushRouting: () => pathRushRouting
34
+ });
35
+ module.exports = __toCommonJS(plugin_exports);
36
+ var import_node_fs7 = __toESM(require("fs"), 1);
37
+ var import_node_path5 = __toESM(require("path"), 1);
38
+
39
+ // src/core/build-generator.ts
40
+ var import_node_fs4 = __toESM(require("fs"), 1);
41
+ var import_node_path3 = __toESM(require("path"), 1);
42
+
43
+ // src/core/metadata.ts
44
+ var import_node_fs = __toESM(require("fs"), 1);
45
+ function extractMetadata(filePath) {
46
+ try {
47
+ const content = import_node_fs.default.readFileSync(filePath, "utf-8");
48
+ const jsdocMetadata = extractJSDocMetadata(content);
49
+ if (jsdocMetadata) {
50
+ return jsdocMetadata;
51
+ }
52
+ const exportMetadata = extractExportMetadata(content);
53
+ if (exportMetadata) {
54
+ return exportMetadata;
55
+ }
56
+ return null;
57
+ } catch (error) {
58
+ console.warn(
59
+ `[vite-plugin-file-router] Failed to extract metadata from ${filePath}:`,
60
+ error
61
+ );
62
+ return null;
63
+ }
64
+ }
65
+ function extractJSDocMetadata(content) {
66
+ const jsdocMatch = content.match(/\/\*\*([\s\S]*?)\*\//);
67
+ if (!jsdocMatch) return null;
68
+ const jsdoc = jsdocMatch[1];
69
+ const metadata = {};
70
+ const titleMatch = jsdoc.match(/@title\s+(.+)/);
71
+ if (titleMatch) metadata.title = titleMatch[1].trim();
72
+ const descMatch = jsdoc.match(/@description\s+(.+)/);
73
+ if (descMatch) metadata.description = descMatch[1].trim();
74
+ const keywordsMatch = jsdoc.match(/@keywords\s+(.+)/);
75
+ if (keywordsMatch) {
76
+ metadata.keywords = keywordsMatch[1].split(",").map((k) => k.trim());
77
+ }
78
+ const authorMatch = jsdoc.match(/@author\s+(.+)/);
79
+ if (authorMatch) metadata.author = authorMatch[1].trim();
80
+ const changefreqMatch = jsdoc.match(
81
+ /@changefreq\s+(always|hourly|daily|weekly|monthly|yearly|never)/
82
+ );
83
+ if (changefreqMatch) {
84
+ metadata.changefreq = changefreqMatch[1];
85
+ }
86
+ const priorityMatch = jsdoc.match(/@priority\s+([0-9.]+)/);
87
+ if (priorityMatch) {
88
+ metadata.priority = parseFloat(priorityMatch[1]);
89
+ }
90
+ return Object.keys(metadata).length > 0 ? metadata : null;
91
+ }
92
+ function extractExportMetadata(content) {
93
+ const metadataMatch = content.match(
94
+ /export\s+const\s+metadata\s*=\s*({[\s\S]*?});?/
95
+ );
96
+ if (!metadataMatch) return null;
97
+ try {
98
+ const metadataCode = metadataMatch[1];
99
+ const safeCode = metadataCode.replace(/import\s+.*?from\s+['"][^'"]*['"];?/g, "").replace(/require\s*\([^)]*\)/g, '""').replace(/process\.env\.[A-Z_]+/g, '""');
100
+ const func = new Function(`return ${safeCode}`);
101
+ return func();
102
+ } catch (error) {
103
+ console.warn(
104
+ `[vite-plugin-file-router] Failed to parse metadata export:`,
105
+ error
106
+ );
107
+ return null;
108
+ }
109
+ }
110
+ function generateSitemap(routes, baseUrl) {
111
+ const urls = routes.map((route) => {
112
+ const lastmod = (/* @__PURE__ */ new Date()).toISOString();
113
+ const changefreq = route.metadata?.changefreq || "monthly";
114
+ const priority = route.metadata?.priority || 0.8;
115
+ return ` <url>
116
+ <loc>${baseUrl}${route.path}</loc>
117
+ <lastmod>${lastmod}</lastmod>
118
+ <changefreq>${changefreq}</changefreq>
119
+ <priority>${priority}</priority>
120
+ </url>`;
121
+ }).join("\n");
122
+ return `<?xml version="1.0" encoding="UTF-8"?>
123
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
124
+ ${urls}
125
+ </urlset>`;
126
+ }
127
+ function generateRobots(baseUrl, disallowPaths = []) {
128
+ const disallowRules = disallowPaths.map((path6) => `Disallow: ${path6}`).join("\n");
129
+ return `User-agent: *
130
+ Allow: /
131
+ ${disallowRules ? `
132
+ ${disallowRules}` : ""}
133
+
134
+ Sitemap: ${baseUrl}/sitemap.xml`;
135
+ }
136
+
137
+ // src/core/route-generator.ts
138
+ var import_node_path2 = __toESM(require("path"), 1);
139
+
140
+ // src/core/scanner.ts
141
+ var import_fast_glob = __toESM(require("fast-glob"), 1);
142
+ var import_node_fs3 = __toESM(require("fs"), 1);
143
+ var import_node_path = __toESM(require("path"), 1);
144
+
145
+ // src/core/utils.ts
146
+ var import_node_fs2 = __toESM(require("fs"), 1);
147
+ var slash = (p) => p.replace(/\\/g, "/");
148
+ function detectExportType(filePath) {
149
+ try {
150
+ const content = import_node_fs2.default.readFileSync(filePath, "utf-8");
151
+ const hasDefaultExport = /export\s+default\s+/.test(content);
152
+ const hasNamedExport = /export\s+(const|function|class)\s+\w+\s*[=(]/.test(
153
+ content
154
+ );
155
+ if (hasDefaultExport) {
156
+ return "default";
157
+ } else if (hasNamedExport) {
158
+ return "named";
159
+ }
160
+ return "default";
161
+ } catch (error) {
162
+ console.warn(
163
+ `[vite-plugin-file-router] Failed to read file ${filePath}:`,
164
+ error
165
+ );
166
+ return "default";
167
+ }
168
+ }
169
+
170
+ // src/core/scanner.ts
171
+ async function scanPages(resolvedPagesDir, opts) {
172
+ const exts = opts.extensions.join("|");
173
+ const pattern = `${slash(resolvedPagesDir)}/**/${opts.pageFileName}.+(${exts})`;
174
+ const files = await (0, import_fast_glob.default)(pattern, { dot: true });
175
+ return files.map((f) => import_node_path.default.resolve(f));
176
+ }
177
+ function collectLayouts(filePath, resolvedPagesDir, opts) {
178
+ const rel = slash(import_node_path.default.relative(resolvedPagesDir, filePath));
179
+ const dir = import_node_path.default.dirname(rel);
180
+ const parts = dir === "." ? [] : dir.split("/").filter(Boolean);
181
+ const layouts = [];
182
+ for (let i = 0; i <= parts.length; i++) {
183
+ const p = parts.slice(0, i).join("/");
184
+ for (const ext of opts.extensions) {
185
+ const candidate = import_node_path.default.resolve(
186
+ resolvedPagesDir,
187
+ p || "",
188
+ `${opts.layoutFileName}.${ext}`
189
+ );
190
+ if (import_node_fs3.default.existsSync(candidate)) {
191
+ layouts.push(candidate);
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ return layouts;
197
+ }
198
+
199
+ // src/core/route-generator.ts
200
+ function segmentToRoute(seg) {
201
+ if (/^\[\.{3}.+\]$/.test(seg)) {
202
+ const name = seg.slice(4, -1);
203
+ return `:${name}(.*)`;
204
+ }
205
+ if (/^\[.+\]$/.test(seg)) {
206
+ const name = seg.slice(1, -1);
207
+ return `:${name}`;
208
+ }
209
+ return seg;
210
+ }
211
+ function filePathToRoute(filePath, resolvedPagesDir) {
212
+ const rel = slash(import_node_path2.default.relative(resolvedPagesDir, filePath));
213
+ const dir = import_node_path2.default.dirname(rel);
214
+ const parts = dir === "." ? [] : dir.split("/").filter(Boolean);
215
+ const filteredParts = parts.filter(
216
+ (part) => (!part.startsWith("(") || !part.endsWith(")")) && !part.startsWith("_")
217
+ );
218
+ const segments = filteredParts.map(segmentToRoute);
219
+ const route = "/" + segments.join("/");
220
+ return route === "/" ? "/" : route.replace(/\/+/g, "/");
221
+ }
222
+ function createRouteEntry(filePath, resolvedPagesDir, opts) {
223
+ const route = filePathToRoute(filePath, resolvedPagesDir);
224
+ const id = slash(import_node_path2.default.relative(resolvedPagesDir, filePath)).replace(/\//g, "_").replace(/\.[^.]+$/, "");
225
+ const exportType = detectExportType(filePath);
226
+ const loader = `() => import(${JSON.stringify(slash(filePath))})`;
227
+ const layouts = collectLayouts(filePath, resolvedPagesDir, opts).map(
228
+ (lp) => `() => import(${JSON.stringify(slash(lp))})`
229
+ );
230
+ return {
231
+ id,
232
+ path: route,
233
+ filePath: slash(filePath),
234
+ loader,
235
+ exportType,
236
+ layouts
237
+ };
238
+ }
239
+
240
+ // src/core/type-generator.ts
241
+ function generateRouteTypes(routes) {
242
+ const routePaths = routes.map((route) => `'${route.path}'`).join(" | ");
243
+ const routeParams = {};
244
+ routes.forEach((route) => {
245
+ const params = {};
246
+ const idMatches = route.path.match(/\[([^\]]+)\]/g);
247
+ if (idMatches) {
248
+ idMatches.forEach((match) => {
249
+ const paramName = match.slice(1, -1);
250
+ if (paramName.startsWith("...")) {
251
+ params[paramName.slice(3)] = "string[]";
252
+ } else {
253
+ params[paramName] = "string";
254
+ }
255
+ });
256
+ }
257
+ if (Object.keys(params).length > 0) {
258
+ routeParams[route.path] = params;
259
+ }
260
+ });
261
+ const routeParamsType = Object.keys(routeParams).length > 0 ? `export type RouteParams = {
262
+ ${Object.entries(routeParams).map(([path6, params]) => {
263
+ const paramEntries = Object.entries(params).map(([key, type]) => `${key}: ${type}`).join(", ");
264
+ return ` '${path6}': { ${paramEntries} }`;
265
+ }).join("\n")}
266
+ }` : "export type RouteParams = Record<string, never>";
267
+ 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
268
+ export type RoutePath = ${routePaths || "never"}
269
+
270
+ ${routeParamsType}
271
+
272
+ export type PageProps<T extends RoutePath = RoutePath> = {
273
+ params: RouteParams[T]
274
+ searchParams?: Record<string, string>
275
+ }
276
+
277
+ export interface LayoutProps {
278
+ children: React.ReactNode
279
+ }
280
+
281
+ export interface RouteInfo {
282
+ id: string
283
+ path: string
284
+ filePath: string
285
+ exportType: 'default' | 'named'
286
+ layouts: string[]
287
+ }
288
+
289
+ // \u0423\u0442\u0438\u043B\u0438\u0442\u044B \u0434\u043B\u044F \u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438
290
+ export function navigate<T extends RoutePath>(
291
+ path: T,
292
+ params?: RouteParams[T]
293
+ ): void {
294
+ // \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438
295
+ window.location.href = path
296
+ }
297
+
298
+ export function useParams<T extends RoutePath>(): RouteParams[T] {
299
+ // \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
300
+ return {} as RouteParams[T]
301
+ }
302
+ `;
303
+ }
304
+ function generateMetadataTypes() {
305
+ 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
306
+ export interface PageMetadata {
307
+ title?: string
308
+ description?: string
309
+ keywords?: string[]
310
+ author?: string
311
+ changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
312
+ priority?: number
313
+ }
314
+
315
+ export interface SEOConfig {
316
+ baseUrl: string
317
+ defaultTitle?: string
318
+ defaultDescription?: string
319
+ disallowPaths?: string[]
320
+ }
321
+ `;
322
+ }
323
+
324
+ // src/core/build-generator.ts
325
+ async function generateTypes(resolvedPagesDir, opts) {
326
+ const pages = await scanPages(resolvedPagesDir, opts);
327
+ const routes = pages.map((fp) => createRouteEntry(fp, resolvedPagesDir, opts));
328
+ const routeTypes = generateRouteTypes(routes);
329
+ const metadataTypes = generateMetadataTypes();
330
+ const typesDir = import_node_path3.default.join(process.cwd(), "dist", "types");
331
+ if (!import_node_fs4.default.existsSync(typesDir)) {
332
+ import_node_fs4.default.mkdirSync(typesDir, { recursive: true });
333
+ }
334
+ import_node_fs4.default.writeFileSync(import_node_path3.default.join(typesDir, "routes.d.ts"), routeTypes);
335
+ import_node_fs4.default.writeFileSync(import_node_path3.default.join(typesDir, "metadata.d.ts"), metadataTypes);
336
+ }
337
+ async function generateSEOFiles(resolvedPagesDir, opts) {
338
+ const pages = await scanPages(resolvedPagesDir, opts);
339
+ const routesWithMetadata = pages.map((fp) => {
340
+ const entry = createRouteEntry(fp, resolvedPagesDir, opts);
341
+ const metadata = extractMetadata(fp);
342
+ return {
343
+ path: entry.path,
344
+ metadata: metadata || void 0
345
+ };
346
+ }).filter(
347
+ (route) => !opts.disallowPaths.some((disallow) => route.path.startsWith(disallow))
348
+ );
349
+ const sitemap = generateSitemap(routesWithMetadata, opts.baseUrl);
350
+ const robots = generateRobots(opts.baseUrl, opts.disallowPaths);
351
+ const distDir = import_node_path3.default.join(process.cwd(), "dist");
352
+ if (!import_node_fs4.default.existsSync(distDir)) {
353
+ import_node_fs4.default.mkdirSync(distDir, { recursive: true });
354
+ }
355
+ import_node_fs4.default.writeFileSync(import_node_path3.default.join(distDir, "sitemap.xml"), sitemap);
356
+ import_node_fs4.default.writeFileSync(import_node_path3.default.join(distDir, "robots.txt"), robots);
357
+ }
358
+
359
+ // src/core/hmr-handlers.ts
360
+ var import_node_fs5 = __toESM(require("fs"), 1);
361
+ function createHMRHandlers(resolvedPagesDir, resolvedVirtualId, root) {
362
+ const configureServer = (srv) => {
363
+ const invalidateVirtual = async () => {
364
+ const mod = srv.moduleGraph?.getModuleById?.(resolvedVirtualId);
365
+ if (mod) {
366
+ srv.moduleGraph?.invalidateModule?.(mod);
367
+ }
368
+ };
369
+ const watchPath = import_node_fs5.default.existsSync(resolvedPagesDir) ? resolvedPagesDir : root;
370
+ srv.watcher?.add?.(watchPath);
371
+ srv.watcher?.on?.("add", (p) => {
372
+ if (p.startsWith(resolvedPagesDir)) invalidateVirtual();
373
+ });
374
+ srv.watcher?.on?.("unlink", (p) => {
375
+ if (p.startsWith(resolvedPagesDir)) invalidateVirtual();
376
+ });
377
+ };
378
+ const handleHotUpdate = (ctx) => {
379
+ const f = ctx.file;
380
+ if (!f?.startsWith(resolvedPagesDir)) return;
381
+ const mod = ctx.server.moduleGraph?.getModuleById?.(resolvedVirtualId);
382
+ if (mod) {
383
+ ctx.server.moduleGraph?.invalidateModule?.(mod);
384
+ return [mod];
385
+ }
386
+ };
387
+ return { configureServer, handleHotUpdate };
388
+ }
389
+
390
+ // src/core/manifest-loader.ts
391
+ var import_node_fs6 = __toESM(require("fs"), 1);
392
+ var import_node_path4 = __toESM(require("path"), 1);
393
+ async function loadGeneratedManifest(root) {
394
+ const manifestPath = import_node_path4.default.join(root, "dist", "routes-manifest.js");
395
+ if (import_node_fs6.default.existsSync(manifestPath)) {
396
+ try {
397
+ const manifestContent = import_node_fs6.default.readFileSync(manifestPath, "utf-8");
398
+ const manifestRegex = /export const manifest = \[.*?\];/s;
399
+ const manifestMatch = manifestRegex.exec(manifestContent);
400
+ const basePathRegex = /export const basePath = ['"](.*?)['"];/;
401
+ const basePathMatch = basePathRegex.exec(manifestContent);
402
+ const basePath = basePathMatch ? basePathMatch[1] : "/";
403
+ if (manifestMatch) {
404
+ return `// virtual routes (production mode - using generated manifest)
405
+ ${manifestMatch[0]}
406
+ export const basePath = ${JSON.stringify(basePath)};
407
+ export default manifest;
408
+ `;
409
+ }
410
+ } catch (error) {
411
+ console.warn(
412
+ "[vite-plugin-file-router] Failed to load generated manifest:",
413
+ error
414
+ );
415
+ }
416
+ }
417
+ return `// virtual routes (production mode - empty manifest)
418
+ export const manifest = [];
419
+ export const basePath = '/';
420
+ export default manifest;
421
+ `;
422
+ }
423
+
424
+ // src/core/virtual-module.ts
425
+ async function generateVirtualModuleCode(resolvedPagesDir, opts) {
426
+ const pages = await scanPages(resolvedPagesDir, opts);
427
+ const entries = pages.map((fp) => {
428
+ const entry = createRouteEntry(fp, resolvedPagesDir, opts);
429
+ return `{
430
+ id: ${JSON.stringify(entry.id)},
431
+ path: ${JSON.stringify(entry.path)},
432
+ filePath: ${JSON.stringify(entry.filePath)},
433
+ loader: ${entry.loader},
434
+ exportType: ${JSON.stringify(entry.exportType)},
435
+ layouts: [${entry.layouts.join(",")}]
436
+ }`;
437
+ });
438
+ return `// Auto-generated routes manifest
439
+ const manifest = [${entries.join(",\n")}];
440
+
441
+ export const basePath = ${JSON.stringify(opts.basePath ?? "/")};
442
+
443
+ export { manifest };
444
+ export default manifest;
445
+ `;
446
+ }
447
+
448
+ // src/plugin.ts
449
+ function pathRushRouting(rawOpts = {}) {
450
+ const opts = {
451
+ pagesDir: rawOpts.pagesDir ?? "src/pages",
452
+ pageFileName: rawOpts.pageFileName ?? "page",
453
+ layoutFileName: rawOpts.layoutFileName ?? "layout",
454
+ extensions: rawOpts.extensions ?? ["tsx"],
455
+ baseUrl: rawOpts.baseUrl ?? "http://localhost:5173",
456
+ basePath: rawOpts.basePath ?? "/",
457
+ disallowPaths: rawOpts.disallowPaths ?? [],
458
+ generateTypes: rawOpts.generateTypes ?? true,
459
+ enableSEO: rawOpts.enableSEO ?? true
460
+ };
461
+ const VIRTUAL_ID = "virtual:routes";
462
+ const RESOLVED_VIRTUAL_ID = "\0" + VIRTUAL_ID;
463
+ let root = process.cwd();
464
+ let resolvedPagesDir = import_node_path5.default.resolve(root, opts.pagesDir);
465
+ const plugin = {
466
+ name: "vite-plugin-file-router-mwv",
467
+ enforce: "pre",
468
+ // Автоматическая настройка Vite конфигурации
469
+ config(userConfig) {
470
+ const existingAlias = userConfig.resolve?.alias;
471
+ const existingExclude = userConfig.optimizeDeps?.exclude;
472
+ return {
473
+ optimizeDeps: {
474
+ exclude: [
475
+ ...Array.isArray(existingExclude) ? existingExclude : [],
476
+ "virtual:routes"
477
+ ]
478
+ },
479
+ resolve: {
480
+ alias: {
481
+ ...typeof existingAlias === "object" ? existingAlias : {},
482
+ "virtual:routes": "virtual:routes"
483
+ }
484
+ }
485
+ };
486
+ },
487
+ resolveId(id) {
488
+ if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
489
+ return null;
490
+ },
491
+ async load(id) {
492
+ if (id === RESOLVED_VIRTUAL_ID) {
493
+ if (!import_node_fs7.default.existsSync(resolvedPagesDir)) {
494
+ return await loadGeneratedManifest(root);
495
+ }
496
+ return await generateVirtualModuleCode(resolvedPagesDir, opts);
497
+ }
498
+ return null;
499
+ },
500
+ async buildStart() {
501
+ root = process.cwd();
502
+ resolvedPagesDir = import_node_path5.default.resolve(root, opts.pagesDir);
503
+ if (!import_node_fs7.default.existsSync(resolvedPagesDir)) {
504
+ console.warn(
505
+ `[vite-plugin-file-router] pagesDir "${resolvedPagesDir}" not found.`
506
+ );
507
+ }
508
+ },
509
+ async generateBundle() {
510
+ if (!import_node_fs7.default.existsSync(resolvedPagesDir)) {
511
+ console.warn(
512
+ `[vite-plugin-file-router] pagesDir "${resolvedPagesDir}" not found in production build. Skipping route generation.`
513
+ );
514
+ return;
515
+ }
516
+ if (opts.generateTypes) {
517
+ try {
518
+ await generateTypes(resolvedPagesDir, opts);
519
+ } catch (error) {
520
+ console.warn(
521
+ `[vite-plugin-file-router] Failed to generate types: ${error}`
522
+ );
523
+ }
524
+ }
525
+ if (opts.enableSEO) {
526
+ try {
527
+ await generateSEOFiles(resolvedPagesDir, opts);
528
+ } catch (error) {
529
+ console.warn(
530
+ `[vite-plugin-file-router] Failed to generate SEO files: ${error}`
531
+ );
532
+ }
533
+ }
534
+ }
535
+ };
536
+ if (process.env.NODE_ENV !== "production") {
537
+ const { configureServer, handleHotUpdate } = createHMRHandlers(
538
+ resolvedPagesDir,
539
+ RESOLVED_VIRTUAL_ID,
540
+ root
541
+ );
542
+ plugin.configureServer = configureServer;
543
+ plugin.handleHotUpdate = handleHotUpdate;
544
+ }
545
+ return plugin;
546
+ }
547
+ // Annotate the CommonJS export names for ESM import in node:
548
+ 0 && (module.exports = {
549
+ pathRushRouting
550
+ });
551
+ //# sourceMappingURL=plugin.js.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":["import_node_fs","import_node_path","import_node_fs","import_node_path","fs","path","import_node_path","import_node_fs","import_node_fs","fs","fg","path","fs","path","path","path","fs","import_node_fs","fs","import_node_fs","import_node_path","path","fs","path","fs"]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ pathRushRouting
3
+ } from "./chunk-VBEFTPIV.mjs";
4
+ export {
5
+ pathRushRouting
6
+ };
7
+ //# sourceMappingURL=plugin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,35 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ type RouterProviderProps = {
5
+ /**
6
+ * ⏳ Кастомный индикатор загрузки
7
+ *
8
+ * ▸ Компонент который показывается во время загрузки
9
+ *
10
+ * ▸ Если не указан - используется стандартный прелоадер
11
+ *
12
+ * @default
13
+ * <div>Loading...</div>
14
+ */
15
+ preloader?: React.ReactNode;
16
+ /**
17
+ * 📍 Базовый путь для маршрутизации
18
+ *
19
+ * ▸ Используется для работы нескольких фронтендов на одном домене
20
+ *
21
+ * ▸ Переопределяет basePath из конфигурации плагина
22
+ *
23
+ * @example '/' - основной сайт
24
+ * @example '/admin' - админка на /admin/*
25
+ * @example '/app' - приложение на /app/*
26
+ *
27
+ * @default '/'
28
+ */
29
+ basePath?: string;
30
+ children?: React.ReactNode;
31
+ };
32
+
33
+ declare function RouterProvider({ children, preloader, basePath, }: Readonly<RouterProviderProps>): react_jsx_runtime.JSX.Element;
34
+
35
+ export { RouterProvider, type RouterProviderProps };