path-rush 1.4.1 → 1.5.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/react.mjs CHANGED
@@ -1,5 +1,13 @@
1
+ // src/components/link.tsx
2
+ import { Link as ReactRouterLink } from "react-router-dom";
3
+
4
+ // src/components/hooks/use-location.ts
5
+ import { useLocation as useRouterLocation } from "react-router-dom";
6
+ function useLocation() {
7
+ return useRouterLocation();
8
+ }
9
+
1
10
  // src/components/hooks/use-links.tsx
2
- import { useLocation } from "react-router-dom";
3
11
  function useLink(props) {
4
12
  const location = useLocation();
5
13
  const currentPath = location.pathname;
@@ -10,33 +18,89 @@ function useLink(props) {
10
18
  }
11
19
 
12
20
  // src/components/link.tsx
13
- import { Link as ReactRouterLink } from "react-router-dom";
14
21
  var Link = ReactRouterLink;
15
22
 
23
+ // src/components/nav-link.tsx
24
+ import { NavLink as ReactRouterNavLink } from "react-router-dom";
25
+ var NavLink = ReactRouterNavLink;
26
+
27
+ // src/components/navigate.tsx
28
+ import { Navigate as ReactRouterNavigate } from "react-router-dom";
29
+ var Navigate = ReactRouterNavigate;
30
+
16
31
  // src/components/router-provider.tsx
17
- import { manifest, basePath as configBasePath } from "virtual:routes";
32
+ import {
33
+ basePath as configBasePath,
34
+ globalNotFound,
35
+ manifest
36
+ } from "virtual:routes";
18
37
 
19
38
  // src/components/router-layout.tsx
20
- import React2 from "react";
39
+ import React3 from "react";
21
40
  import { BrowserRouter, Routes } from "react-router-dom";
22
41
 
23
42
  // src/components/router-utils.tsx
24
- import React from "react";
43
+ import React2 from "react";
25
44
  import { Route } from "react-router-dom";
26
- import { jsx } from "react/jsx-runtime";
45
+
46
+ // src/components/error-boundary.tsx
47
+ import React from "react";
48
+ import { jsx, jsxs } from "react/jsx-runtime";
49
+ var ErrorBoundary = class extends React.Component {
50
+ constructor(props) {
51
+ super(props);
52
+ this.state = { hasError: false, error: null };
53
+ }
54
+ static getDerivedStateFromError(error) {
55
+ return { hasError: true, error };
56
+ }
57
+ componentDidCatch(error, errorInfo) {
58
+ this.props.onError?.(error, errorInfo);
59
+ }
60
+ resetError = () => {
61
+ this.setState({ hasError: false, error: null });
62
+ };
63
+ render() {
64
+ if (this.state.hasError && this.state.error) {
65
+ if (this.props.fallback) {
66
+ const Fallback = this.props.fallback;
67
+ return /* @__PURE__ */ jsx(Fallback, { error: this.state.error, resetError: this.resetError });
68
+ }
69
+ return /* @__PURE__ */ jsxs("div", { style: { padding: "20px" }, children: [
70
+ /* @__PURE__ */ jsx("h2", { children: "Something went wrong" }),
71
+ /* @__PURE__ */ jsx("pre", { children: this.state.error.message }),
72
+ /* @__PURE__ */ jsx("button", { onClick: this.resetError, children: "Try again" })
73
+ ] });
74
+ }
75
+ return this.props.children;
76
+ }
77
+ };
78
+
79
+ // src/components/router-utils.tsx
80
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
27
81
  function wrapLayouts(layouts, pageEl) {
28
82
  if (!layouts || layouts.length === 0) return pageEl;
29
83
  return layouts.reduceRight((child, loader) => {
30
- const Layout = React.lazy(async () => {
84
+ const Layout = React2.lazy(async () => {
31
85
  const module = await loader();
32
86
  return "default" in module ? module : { default: module.Layout };
33
87
  });
34
- return /* @__PURE__ */ jsx(Layout, { children: child });
88
+ return /* @__PURE__ */ jsx2(Layout, { children: child });
35
89
  }, pageEl);
36
90
  }
37
- var renderManifestAsRoutes = (manifest2) => {
91
+ function createLoadingFallback(loadingLoader) {
92
+ if (!loadingLoader) return void 0;
93
+ const Loading = React2.lazy(loadingLoader);
94
+ return /* @__PURE__ */ jsx2(Loading, {});
95
+ }
96
+ function createErrorFallback(errorLoader) {
97
+ if (!errorLoader) return void 0;
98
+ const ErrorComponent = React2.lazy(errorLoader);
99
+ return (props) => /* @__PURE__ */ jsx2(ErrorComponent, { ...props });
100
+ }
101
+ var renderManifestAsRoutes = (manifest2, globalNotFound2) => {
38
102
  return manifest2.map((n) => {
39
- const Page = React.lazy(async () => {
103
+ const Page = React2.lazy(async () => {
40
104
  const module = await n.loader();
41
105
  if (module && typeof module === "object" && "default" in module && module.default) {
42
106
  return module;
@@ -59,47 +123,92 @@ var renderManifestAsRoutes = (manifest2) => {
59
123
  `No valid export found in module for route ${n.path}. Available exports: ${availableExports}`
60
124
  );
61
125
  });
62
- const element = wrapLayouts(n.layouts, /* @__PURE__ */ jsx(Page, {}));
63
- return /* @__PURE__ */ jsx(Route, { path: n.path, element }, n.id);
64
- });
126
+ const loadingFallback = createLoadingFallback(n.loading);
127
+ const errorFallback = createErrorFallback(n.error);
128
+ const pageElement = wrapLayouts(n.layouts, /* @__PURE__ */ jsx2(Page, {}));
129
+ const wrappedElement = errorFallback ? /* @__PURE__ */ jsx2(ErrorBoundary, { fallback: errorFallback, children: pageElement }) : pageElement;
130
+ const element = loadingFallback ? /* @__PURE__ */ jsx2(React2.Suspense, { fallback: loadingFallback, children: wrappedElement }) : /* @__PURE__ */ jsx2(React2.Suspense, { fallback: /* @__PURE__ */ jsx2("div", { children: "Loading..." }), children: wrappedElement });
131
+ return /* @__PURE__ */ jsx2(Route, { path: n.path, element }, n.id);
132
+ }).concat(
133
+ // Добавляем 404 маршрут в конец
134
+ globalNotFound2 ? /* @__PURE__ */ jsx2(
135
+ Route,
136
+ {
137
+ path: "*",
138
+ element: /* @__PURE__ */ jsx2(React2.Suspense, { fallback: /* @__PURE__ */ jsx2("div", { children: "Loading..." }), children: (() => {
139
+ const NotFound = React2.lazy(globalNotFound2);
140
+ return /* @__PURE__ */ jsx2(NotFound, {});
141
+ })() })
142
+ },
143
+ "__not_found__"
144
+ ) : /* @__PURE__ */ jsx2(
145
+ Route,
146
+ {
147
+ path: "*",
148
+ element: /* @__PURE__ */ jsxs2("div", { style: { padding: "20px", textAlign: "center" }, children: [
149
+ /* @__PURE__ */ jsx2("h1", { children: "404" }),
150
+ /* @__PURE__ */ jsx2("p", { children: "Page not found" })
151
+ ] })
152
+ },
153
+ "__not_found__"
154
+ )
155
+ );
65
156
  };
66
157
 
67
158
  // src/components/router-layout.tsx
68
- import { jsx as jsx2 } from "react/jsx-runtime";
159
+ import { jsx as jsx3 } from "react/jsx-runtime";
69
160
  var RouterLayout = ({
70
161
  manifest: manifest2,
71
162
  children,
72
163
  preloader,
73
- basePath = "/"
74
- }) => /* @__PURE__ */ jsx2(BrowserRouter, { basename: basePath, children: /* @__PURE__ */ jsx2(React2.Suspense, { fallback: children || preloader || /* @__PURE__ */ jsx2("div", { children: "Loading..." }), children: /* @__PURE__ */ jsx2(Routes, { children: renderManifestAsRoutes(manifest2) }) }) });
164
+ basePath = "/",
165
+ globalNotFound: globalNotFound2
166
+ }) => /* @__PURE__ */ jsx3(BrowserRouter, { basename: basePath, children: /* @__PURE__ */ jsx3(React3.Suspense, { fallback: children || preloader || /* @__PURE__ */ jsx3("div", { children: "Loading..." }), children: /* @__PURE__ */ jsx3(Routes, { children: renderManifestAsRoutes(manifest2, globalNotFound2) }) }) });
75
167
 
76
168
  // src/components/router-provider.tsx
77
- import { jsx as jsx3 } from "react/jsx-runtime";
169
+ import { jsx as jsx4 } from "react/jsx-runtime";
78
170
  function RouterProvider({
79
171
  children,
80
172
  preloader,
81
173
  basePath
82
174
  }) {
83
175
  const finalBasePath = basePath ?? configBasePath ?? "/";
84
- return /* @__PURE__ */ jsx3(RouterLayout, { manifest, preloader, basePath: finalBasePath, children });
176
+ return /* @__PURE__ */ jsx4(
177
+ RouterLayout,
178
+ {
179
+ manifest,
180
+ preloader,
181
+ basePath: finalBasePath,
182
+ globalNotFound,
183
+ children
184
+ }
185
+ );
85
186
  }
86
187
 
87
- // src/react.ts
88
- import {
89
- Navigate,
90
- NavLink,
91
- useLocation as useLocation2,
92
- useNavigate,
93
- useParams,
94
- useSearchParams
95
- } from "react-router-dom";
188
+ // src/components/hooks/use-navigate.ts
189
+ import { useNavigate as useRouterNavigate } from "react-router-dom";
190
+ function useNavigate() {
191
+ return useRouterNavigate();
192
+ }
193
+
194
+ // src/components/hooks/use-params.ts
195
+ import { useParams as useRouterParams } from "react-router-dom";
196
+ function useParams() {
197
+ return useRouterParams();
198
+ }
199
+
200
+ // src/components/hooks/use-search-params.ts
201
+ import { useSearchParams as useRouterSearchParams } from "react-router-dom";
202
+ function useSearchParams() {
203
+ return useRouterSearchParams();
204
+ }
96
205
  export {
97
206
  Link,
98
207
  NavLink,
99
208
  Navigate,
100
209
  RouterProvider,
101
210
  useLink,
102
- useLocation2 as useLocation,
211
+ useLocation,
103
212
  useNavigate,
104
213
  useParams,
105
214
  useSearchParams
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/hooks/use-links.tsx","../src/components/link.tsx","../src/components/router-provider.tsx","../src/components/router-layout.tsx","../src/components/router-utils.tsx","../src/react.ts"],"sourcesContent":["import { useLocation } from 'react-router-dom'\r\n\r\nexport function useLink(props: { href: string }) {\r\n const location = useLocation()\r\n const currentPath = location.pathname\r\n \r\n return {\r\n href: props.href,\r\n isActive: currentPath === props.href,\r\n }\r\n}","import type { LinkProps as ReactRouterLinkProps } from 'react-router-dom'\r\nimport { Link as ReactRouterLink } from 'react-router-dom'\r\n\r\nexport type LinkProps = ReactRouterLinkProps\r\n\r\nexport const Link = ReactRouterLink\r\n\r\nexport { useLink } from './hooks/use-links'\r\n","import { manifest, basePath as configBasePath } from 'virtual:routes'\r\nimport { RouterLayout } from './router-layout'\r\nimport type { RouterProviderProps } from './types/types'\r\n\r\nexport default function RouterProvider({\r\n\tchildren,\r\n\tpreloader,\r\n\tbasePath,\r\n}: Readonly<RouterProviderProps>) {\r\n\t// Используем basePath из пропсов, если указан, иначе из конфигурации\r\n\tconst finalBasePath = basePath ?? configBasePath ?? '/'\r\n\t\r\n\treturn (\r\n\t\t<RouterLayout manifest={manifest} preloader={preloader} basePath={finalBasePath}>\r\n\t\t\t{children}\r\n\t\t</RouterLayout>\r\n\t)\r\n}\r\n","import React from 'react'\r\nimport { BrowserRouter, Routes } from 'react-router-dom'\r\nimport { renderManifestAsRoutes } from './router-utils'\r\nimport type { RouterLayoutProps } from './types/types'\r\n\r\nexport const RouterLayout = ({\r\n\tmanifest,\r\n\tchildren,\r\n\tpreloader,\r\n\tbasePath = '/',\r\n}: RouterLayoutProps) => (\r\n\t<BrowserRouter basename={basePath}>\r\n\t\t<React.Suspense fallback={children || preloader || <div>Loading...</div>}>\r\n\t\t\t<Routes>{renderManifestAsRoutes(manifest)}</Routes>\r\n\t\t</React.Suspense>\r\n\t</BrowserRouter>\r\n)\r\n","import React from 'react'\r\nimport { Route } from 'react-router-dom'\r\nimport type { Node } from './types/types'\r\n\r\nfunction wrapLayouts(\r\n\tlayouts: Node['layouts'] | undefined,\r\n\tpageEl: React.ReactNode\r\n) {\r\n\tif (!layouts || layouts.length === 0) return pageEl\r\n\r\n\treturn layouts.reduceRight((child, loader) => {\r\n\t\tconst Layout = React.lazy(async () => {\r\n\t\t\tconst module = await loader()\r\n\t\t\t// Поддерживаем как default, так и именованный экспорт Layout\r\n\t\t\treturn 'default' in module ? module : { default: module.Layout }\r\n\t\t})\r\n\t\treturn <Layout>{child}</Layout>\r\n\t}, pageEl as React.ReactElement)\r\n}\r\n\r\nexport const renderManifestAsRoutes = (manifest: Node[]) => {\r\n\treturn manifest.map(n => {\r\n\t\tconst Page = React.lazy(async () => {\r\n\t\t\tconst module = await n.loader()\r\n\r\n\t\t\t// Если есть default экспорт, используем его\r\n\t\t\tif (\r\n\t\t\t\tmodule &&\r\n\t\t\t\ttypeof module === 'object' &&\r\n\t\t\t\t'default' in module &&\r\n\t\t\t\tmodule.default\r\n\t\t\t) {\r\n\t\t\t\treturn module as { default: React.ComponentType }\r\n\t\t\t}\r\n\r\n\t\t\t// Ищем любой именованный экспорт, который является функцией или компонентом\r\n\t\t\tif (module && typeof module === 'object') {\r\n\t\t\t\tconst namedExports = Object.keys(module).filter(\r\n\t\t\t\t\tkey => key !== 'default'\r\n\t\t\t\t)\r\n\t\t\t\tfor (const key of namedExports) {\r\n\t\t\t\t\tconst exportValue = module[key]\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\ttypeof exportValue === 'function' ||\r\n\t\t\t\t\t\t(typeof exportValue === 'object' && exportValue !== null)\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\tdefault: exportValue as React.ComponentType,\r\n\t\t\t\t\t\t}\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// Если ничего не найдено, возвращаем ошибку\r\n\t\t\tconst availableExports =\r\n\t\t\t\tmodule && typeof module === 'object'\r\n\t\t\t\t\t? Object.keys(module).join(', ')\r\n\t\t\t\t\t: 'unknown'\r\n\t\t\tthrow new Error(\r\n\t\t\t\t`No valid export found in module for route ${n.path}. Available exports: ${availableExports}`\r\n\t\t\t)\r\n\t\t})\r\n\r\n\t\tconst element = wrapLayouts(n.layouts, <Page />)\r\n\t\treturn <Route key={n.id} path={n.path} element={element} />\r\n\t})\r\n}\r\n","import { useLink } from './components/hooks/use-links'\r\nimport { Link } from './components/link'\r\nimport RouterProvider from './components/router-provider'\r\n\r\n// Реэкспорт всего необходимого из react-router-dom\r\nexport {\r\n\tNavigate,\r\n\t// Компоненты\r\n\tNavLink, useLocation,\r\n\t// Хуки\r\n\tuseNavigate, useParams,\r\n\tuseSearchParams,\r\n\t// Типы\r\n\ttype LinkProps, type Location, type NavigateOptions, type NavigateProps, type NavLinkProps, type Params, type To\r\n} from 'react-router-dom'\r\n\r\n// Основные экспорты плагина\r\nexport { Link, RouterProvider, useLink }\r\n\r\n// Собственные типы\r\nexport type { RouterProviderProps } from './components/types/types'\r\n"],"mappings":";AAAA,SAAS,mBAAmB;AAErB,SAAS,QAAQ,OAAyB;AAC/C,QAAM,WAAW,YAAY;AAC7B,QAAM,cAAc,SAAS;AAE7B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,UAAU,gBAAgB,MAAM;AAAA,EAClC;AACF;;;ACTA,SAAS,QAAQ,uBAAuB;AAIjC,IAAM,OAAO;;;ACLpB,SAAS,UAAU,YAAY,sBAAsB;;;ACArD,OAAOA,YAAW;AAClB,SAAS,eAAe,cAAc;;;ACDtC,OAAO,WAAW;AAClB,SAAS,aAAa;AAeb;AAZT,SAAS,YACR,SACA,QACC;AACD,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO;AAE7C,SAAO,QAAQ,YAAY,CAAC,OAAO,WAAW;AAC7C,UAAM,SAAS,MAAM,KAAK,YAAY;AACrC,YAAM,SAAS,MAAM,OAAO;AAE5B,aAAO,aAAa,SAAS,SAAS,EAAE,SAAS,OAAO,OAAO;AAAA,IAChE,CAAC;AACD,WAAO,oBAAC,UAAQ,iBAAM;AAAA,EACvB,GAAG,MAA4B;AAChC;AAEO,IAAM,yBAAyB,CAACC,cAAqB;AAC3D,SAAOA,UAAS,IAAI,OAAK;AACxB,UAAM,OAAO,MAAM,KAAK,YAAY;AACnC,YAAM,SAAS,MAAM,EAAE,OAAO;AAG9B,UACC,UACA,OAAO,WAAW,YAClB,aAAa,UACb,OAAO,SACN;AACD,eAAO;AAAA,MACR;AAGA,UAAI,UAAU,OAAO,WAAW,UAAU;AACzC,cAAM,eAAe,OAAO,KAAK,MAAM,EAAE;AAAA,UACxC,SAAO,QAAQ;AAAA,QAChB;AACA,mBAAW,OAAO,cAAc;AAC/B,gBAAM,cAAc,OAAO,GAAG;AAC9B,cACC,OAAO,gBAAgB,cACtB,OAAO,gBAAgB,YAAY,gBAAgB,MACnD;AACD,mBAAO;AAAA,cACN,SAAS;AAAA,YACV;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAGA,YAAM,mBACL,UAAU,OAAO,WAAW,WACzB,OAAO,KAAK,MAAM,EAAE,KAAK,IAAI,IAC7B;AACJ,YAAM,IAAI;AAAA,QACT,6CAA6C,EAAE,IAAI,wBAAwB,gBAAgB;AAAA,MAC5F;AAAA,IACD,CAAC;AAED,UAAM,UAAU,YAAY,EAAE,SAAS,oBAAC,QAAK,CAAE;AAC/C,WAAO,oBAAC,SAAiB,MAAM,EAAE,MAAM,WAApB,EAAE,EAAoC;AAAA,EAC1D,CAAC;AACF;;;ADtDqD,gBAAAC,YAAA;AAP9C,IAAM,eAAe,CAAC;AAAA,EAC5B,UAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACZ,MACC,gBAAAD,KAAC,iBAAc,UAAU,UACxB,0BAAAA,KAACE,OAAM,UAAN,EAAe,UAAU,YAAY,aAAa,gBAAAF,KAAC,SAAI,wBAAU,GACjE,0BAAAA,KAAC,UAAQ,iCAAuBC,SAAQ,GAAE,GAC3C,GACD;;;ADFC,gBAAAE,YAAA;AATa,SAAR,eAAgC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACD,GAAkC;AAEjC,QAAM,gBAAgB,YAAY,kBAAkB;AAEpD,SACC,gBAAAA,KAAC,gBAAa,UAAoB,WAAsB,UAAU,eAChE,UACF;AAEF;;;AGZA;AAAA,EACC;AAAA,EAEA;AAAA,EAAS,eAAAC;AAAA,EAET;AAAA,EAAa;AAAA,EACb;AAAA,OAGM;","names":["React","manifest","jsx","manifest","React","jsx","useLocation"]}
1
+ {"version":3,"sources":["../src/components/link.tsx","../src/components/hooks/use-location.ts","../src/components/hooks/use-links.tsx","../src/components/nav-link.tsx","../src/components/navigate.tsx","../src/components/router-provider.tsx","../src/components/router-layout.tsx","../src/components/router-utils.tsx","../src/components/error-boundary.tsx","../src/components/hooks/use-navigate.ts","../src/components/hooks/use-params.ts","../src/components/hooks/use-search-params.ts"],"sourcesContent":["import type { LinkProps as ReactRouterLinkProps } from 'react-router-dom'\r\nimport { Link as ReactRouterLink } from 'react-router-dom'\r\n\r\nexport type LinkProps = ReactRouterLinkProps\r\n\r\n/**\r\n * Компонент для навигационных ссылок\r\n * \r\n * Используется для клиентской навигации без перезагрузки страницы\r\n * \r\n * @example\r\n * ```tsx\r\n * <Link to=\"/about\">About</Link>\r\n * <Link to=\"/users/123\" state={{ from: 'home' }}>User Profile</Link>\r\n * ```\r\n */\r\nexport const Link = ReactRouterLink\r\n\r\nexport { useLink } from './hooks/use-links'\r\n","import { useLocation as useRouterLocation } from 'react-router-dom'\r\nimport type { Location as RouterLocation } from 'react-router-dom'\r\n\r\n/**\r\n * Тип локации с информацией о текущем маршруте\r\n */\r\nexport type Location = RouterLocation\r\n\r\n/**\r\n * Хук для получения текущей локации\r\n * \r\n * @returns Объект с информацией о текущем маршруте\r\n * \r\n * @example\r\n * ```tsx\r\n * const location = useLocation()\r\n * console.log(location.pathname) // '/about'\r\n * console.log(location.search) // '?id=123'\r\n * ```\r\n */\r\nexport function useLocation(): Location {\r\n\treturn useRouterLocation()\r\n}\r\n","import { useLocation } from './use-location'\r\n\r\nexport function useLink(props: { href: string }) {\r\n const location = useLocation()\r\n const currentPath = location.pathname\r\n \r\n return {\r\n href: props.href,\r\n isActive: currentPath === props.href,\r\n }\r\n}","import type { NavLinkProps as ReactRouterNavLinkProps } from 'react-router-dom'\r\nimport { NavLink as ReactRouterNavLink } from 'react-router-dom'\r\n\r\nexport type NavLinkProps = ReactRouterNavLinkProps\r\n\r\n/**\r\n * Компонент для навигационных ссылок с поддержкой активного состояния\r\n * \r\n * Автоматически добавляет класс 'active' когда маршрут активен\r\n * \r\n * @example\r\n * ```tsx\r\n * <NavLink to=\"/about\">About</NavLink>\r\n * <NavLink to=\"/users\" className={({ isActive }) => isActive ? 'active' : ''}>\r\n * Users\r\n * </NavLink>\r\n * ```\r\n */\r\nexport const NavLink = ReactRouterNavLink\r\n","import type { NavigateProps as ReactRouterNavigateProps } from 'react-router-dom'\r\nimport { Navigate as ReactRouterNavigate } from 'react-router-dom'\r\n\r\nexport type NavigateProps = ReactRouterNavigateProps\r\n\r\n/**\r\n * Компонент для программного редиректа\r\n * \r\n * @example\r\n * ```tsx\r\n * <Navigate to=\"/login\" replace />\r\n * <Navigate to=\"/dashboard\" state={{ from: location }} />\r\n * ```\r\n */\r\nexport const Navigate = ReactRouterNavigate\r\n","import {\r\n\tbasePath as configBasePath,\r\n\tglobalNotFound,\r\n\tmanifest,\r\n} from 'virtual:routes'\r\nimport { RouterLayout } from './router-layout'\r\nimport type { RouterProviderProps } from './types/types'\r\n\r\nexport default function RouterProvider({\r\n\tchildren,\r\n\tpreloader,\r\n\tbasePath,\r\n}: Readonly<RouterProviderProps>) {\r\n\t// Используем basePath из пропсов, если указан, иначе из конфигурации\r\n\tconst finalBasePath = basePath ?? configBasePath ?? '/'\r\n\t\r\n\treturn (\r\n\t\t<RouterLayout\r\n\t\t\tmanifest={manifest}\r\n\t\t\tpreloader={preloader}\r\n\t\t\tbasePath={finalBasePath}\r\n\t\t\tglobalNotFound={globalNotFound}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</RouterLayout>\r\n\t)\r\n}\r\n","import React from 'react'\r\nimport { BrowserRouter, Routes } from 'react-router-dom'\r\nimport { renderManifestAsRoutes } from './router-utils'\r\nimport type { RouterLayoutProps } from './types/types'\r\n\r\nexport const RouterLayout = ({\r\n\tmanifest,\r\n\tchildren,\r\n\tpreloader,\r\n\tbasePath = '/',\r\n\tglobalNotFound,\r\n}: RouterLayoutProps) => (\r\n\t<BrowserRouter basename={basePath}>\r\n\t\t<React.Suspense fallback={children || preloader || <div>Loading...</div>}>\r\n\t\t\t<Routes>{renderManifestAsRoutes(manifest, globalNotFound)}</Routes>\r\n\t\t</React.Suspense>\r\n\t</BrowserRouter>\r\n)\r\n","import React from 'react'\r\nimport { Route } from 'react-router-dom'\r\nimport { ErrorBoundary } from './error-boundary'\r\nimport type { Node } from './types/types'\r\n\r\nfunction wrapLayouts(\r\n\tlayouts: Node['layouts'] | undefined,\r\n\tpageEl: React.ReactNode\r\n) {\r\n\tif (!layouts || layouts.length === 0) return pageEl\r\n\r\n\treturn layouts.reduceRight((child, loader) => {\r\n\t\tconst Layout = React.lazy(async () => {\r\n\t\t\tconst module = await loader()\r\n\t\t\t// Поддерживаем как default, так и именованный экспорт Layout\r\n\t\t\treturn 'default' in module ? module : { default: module.Layout }\r\n\t\t})\r\n\t\treturn <Layout>{child}</Layout>\r\n\t}, pageEl as React.ReactElement)\r\n}\r\n\r\nfunction createLoadingFallback(loadingLoader?: () => Promise<{ default: React.ComponentType }>) {\r\n\tif (!loadingLoader) return undefined\r\n\t\r\n\t// Loading компонент lazy, но он используется как fallback в Suspense\r\n\tconst Loading = React.lazy(loadingLoader)\r\n\treturn <Loading />\r\n}\r\n\r\nfunction createErrorFallback(errorLoader?: () => Promise<{ default: React.ComponentType<{ error?: Error; resetError?: () => void }> }>) {\r\n\tif (!errorLoader) return undefined\r\n\t\r\n\tconst ErrorComponent = React.lazy(errorLoader)\r\n\treturn (props: { error?: Error; resetError?: () => void }) => <ErrorComponent {...props} />\r\n}\r\n\r\nexport const renderManifestAsRoutes = (\r\n\tmanifest: Node[],\r\n\tglobalNotFound?: () => Promise<{ default: React.ComponentType }>\r\n) => {\r\n\treturn manifest.map(n => {\r\n\t\tconst Page = React.lazy(async () => {\r\n\t\t\tconst module = await n.loader()\r\n\r\n\t\t\t// Если есть default экспорт, используем его\r\n\t\t\tif (\r\n\t\t\t\tmodule &&\r\n\t\t\t\ttypeof module === 'object' &&\r\n\t\t\t\t'default' in module &&\r\n\t\t\t\tmodule.default\r\n\t\t\t) {\r\n\t\t\t\treturn module as { default: React.ComponentType }\r\n\t\t\t}\r\n\r\n\t\t\t// Ищем любой именованный экспорт, который является функцией или компонентом\r\n\t\t\tif (module && typeof module === 'object') {\r\n\t\t\t\tconst namedExports = Object.keys(module).filter(\r\n\t\t\t\t\tkey => key !== 'default'\r\n\t\t\t\t)\r\n\t\t\t\tfor (const key of namedExports) {\r\n\t\t\t\t\tconst exportValue = module[key]\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\ttypeof exportValue === 'function' ||\r\n\t\t\t\t\t\t(typeof exportValue === 'object' && exportValue !== null)\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\tdefault: exportValue as React.ComponentType,\r\n\t\t\t\t\t\t}\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// Если ничего не найдено, возвращаем ошибку\r\n\t\t\tconst availableExports =\r\n\t\t\t\tmodule && typeof module === 'object'\r\n\t\t\t\t\t? Object.keys(module).join(', ')\r\n\t\t\t\t\t: 'unknown'\r\n\t\t\tthrow new Error(\r\n\t\t\t\t`No valid export found in module for route ${n.path}. Available exports: ${availableExports}`\r\n\t\t\t)\r\n\t\t})\r\n\r\n\t\tconst loadingFallback = createLoadingFallback(n.loading)\r\n\t\tconst errorFallback = createErrorFallback(n.error)\r\n\t\t\r\n\t\tconst pageElement = wrapLayouts(n.layouts, <Page />)\r\n\t\t\r\n\t\t// Оборачиваем в ErrorBoundary если есть error компонент\r\n\t\tconst wrappedElement = errorFallback ? (\r\n\t\t\t<ErrorBoundary fallback={errorFallback}>\r\n\t\t\t\t{pageElement}\r\n\t\t\t</ErrorBoundary>\r\n\t\t) : pageElement\r\n\r\n\t\t// Оборачиваем в Suspense с loading fallback\r\n\t\tconst element = loadingFallback ? (\r\n\t\t\t<React.Suspense fallback={loadingFallback}>\r\n\t\t\t\t{wrappedElement}\r\n\t\t\t</React.Suspense>\r\n\t\t) : (\r\n\t\t\t<React.Suspense fallback={<div>Loading...</div>}>\r\n\t\t\t\t{wrappedElement}\r\n\t\t\t</React.Suspense>\r\n\t\t)\r\n\r\n\t\treturn <Route key={n.id} path={n.path} element={element} />\r\n\t}).concat(\r\n\t\t// Добавляем 404 маршрут в конец\r\n\t\tglobalNotFound ? (\r\n\t\t\t<Route\r\n\t\t\t\tkey=\"__not_found__\"\r\n\t\t\t\tpath=\"*\"\r\n\t\t\t\telement={\r\n\t\t\t\t\t<React.Suspense fallback={<div>Loading...</div>}>\r\n\t\t\t\t\t\t{(() => {\r\n\t\t\t\t\t\t\tconst NotFound = React.lazy(globalNotFound)\r\n\t\t\t\t\t\t\treturn <NotFound />\r\n\t\t\t\t\t\t})()}\r\n\t\t\t\t\t</React.Suspense>\r\n\t\t\t\t}\r\n\t\t\t/>\r\n\t\t) : (\r\n\t\t\t<Route\r\n\t\t\t\tkey=\"__not_found__\"\r\n\t\t\t\tpath=\"*\"\r\n\t\t\t\telement={\r\n\t\t\t\t\t<div style={{ padding: '20px', textAlign: 'center' }}>\r\n\t\t\t\t\t\t<h1>404</h1>\r\n\t\t\t\t\t\t<p>Page not found</p>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t}\r\n\t\t\t/>\r\n\t\t)\r\n\t)\r\n}\r\n","import React from 'react'\r\n\r\nexport interface ErrorBoundaryProps {\r\n\tchildren: React.ReactNode\r\n\tfallback?: React.ComponentType<{ error?: Error; resetError?: () => void }>\r\n\tonError?: (error: Error, errorInfo: React.ErrorInfo) => void\r\n}\r\n\r\ninterface ErrorBoundaryState {\r\n\thasError: boolean\r\n\terror: Error | null\r\n}\r\n\r\n/**\r\n * ErrorBoundary компонент для обработки ошибок рендеринга\r\n */\r\nexport class ErrorBoundary extends React.Component<\r\n\tErrorBoundaryProps,\r\n\tErrorBoundaryState\r\n> {\r\n\tconstructor(props: ErrorBoundaryProps) {\r\n\t\tsuper(props)\r\n\t\tthis.state = { hasError: false, error: null }\r\n\t}\r\n\r\n\tstatic getDerivedStateFromError(error: Error): ErrorBoundaryState {\r\n\t\treturn { hasError: true, error }\r\n\t}\r\n\r\n\tcomponentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\r\n\t\tthis.props.onError?.(error, errorInfo)\r\n\t}\r\n\r\n\tresetError = () => {\r\n\t\tthis.setState({ hasError: false, error: null })\r\n\t}\r\n\r\n\trender() {\r\n\t\tif (this.state.hasError && this.state.error) {\r\n\t\t\tif (this.props.fallback) {\r\n\t\t\t\tconst Fallback = this.props.fallback\r\n\t\t\t\treturn <Fallback error={this.state.error} resetError={this.resetError} />\r\n\t\t\t}\r\n\t\t\treturn (\r\n\t\t\t\t<div style={{ padding: '20px' }}>\r\n\t\t\t\t\t<h2>Something went wrong</h2>\r\n\t\t\t\t\t<pre>{this.state.error.message}</pre>\r\n\t\t\t\t\t<button onClick={this.resetError}>Try again</button>\r\n\t\t\t\t</div>\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\treturn this.props.children\r\n\t}\r\n}\r\n","import { useNavigate as useRouterNavigate } from 'react-router-dom'\r\n\r\nexport type NavigateOptions = {\r\n\treplace?: boolean\r\n\tstate?: unknown\r\n\trelative?: 'route' | 'path'\r\n}\r\n\r\nexport type To = string | number | { pathname?: string; search?: string; hash?: string }\r\n\r\n/**\r\n * Хук для программной навигации\r\n * \r\n * @returns Функция для навигации\r\n * \r\n * @example\r\n * ```tsx\r\n * const navigate = useNavigate()\r\n * navigate('/about')\r\n * navigate('/users', { replace: true })\r\n * navigate(-1) // назад\r\n * ```\r\n */\r\nexport function useNavigate() {\r\n\treturn useRouterNavigate()\r\n}\r\n","import { useParams as useRouterParams } from 'react-router-dom'\r\n\r\nexport type Params = Record<string, string | undefined>\r\n\r\n/**\r\n * Хук для получения параметров маршрута\r\n * \r\n * @returns Объект с параметрами текущего маршрута\r\n * \r\n * @example\r\n * ```tsx\r\n * // Для маршрута /users/:id\r\n * const { id } = useParams()\r\n * ```\r\n */\r\nexport function useParams<T extends Params = Params>(): T {\r\n\treturn useRouterParams() as T\r\n}\r\n","import { useSearchParams as useRouterSearchParams } from 'react-router-dom'\r\n\r\n/**\r\n * Хук для работы с query параметрами URL\r\n * \r\n * @returns Кортеж из [searchParams, setSearchParams]\r\n * \r\n * @example\r\n * ```tsx\r\n * const [searchParams, setSearchParams] = useSearchParams()\r\n * const id = searchParams.get('id')\r\n * setSearchParams({ id: '123' })\r\n * ```\r\n */\r\nexport function useSearchParams() {\r\n\treturn useRouterSearchParams()\r\n}\r\n"],"mappings":"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","names":["React","React","jsx","jsxs","React","manifest","globalNotFound","jsx","manifest","globalNotFound","React","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "path-rush",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "A simple and powerful plugin for Vite with file-based routing",
5
5
  "main": "dist/plugin.js",
6
6
  "module": "dist/plugin.mjs",
@@ -1 +0,0 @@
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"]}