aaex-file-router 1.2.1 → 1.3.1
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/README.md +100 -29
- package/dist/core/FileScanner.d.ts +2 -10
- package/dist/core/FileScanner.d.ts.map +1 -1
- package/dist/core/FileScanner.js +17 -58
- package/dist/core/FileScanner.js.map +1 -1
- package/dist/core/RouteGenerator.d.ts +17 -15
- package/dist/core/RouteGenerator.d.ts.map +1 -1
- package/dist/core/RouteGenerator.js +77 -139
- package/dist/core/RouteGenerator.js.map +1 -1
- package/dist/core/index.d.ts +0 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +1 -1
- package/dist/pages/test/ba/baka/boo.d.ts +2 -0
- package/dist/pages/test/ba/baka/boo.d.ts.map +1 -0
- package/dist/pages/test/ba/baka/boo.js +5 -0
- package/dist/pages/test/ba/baka/boo.js.map +1 -0
- package/dist/plugin/index.d.ts +3 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +2 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/plugin.d.ts +11 -0
- package/dist/plugin/plugin.d.ts.map +1 -0
- package/dist/plugin/plugin.js +48 -0
- package/dist/plugin/plugin.js.map +1 -0
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/test/index.js +10 -4
- package/dist/test/index.js.map +1 -1
- package/dist/test/output.d.ts +4 -0
- package/dist/test/output.d.ts.map +1 -0
- package/dist/test/output.js +42 -0
- package/dist/test/output.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,9 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
A file-based routing system for React projects that automatically generates routes from your file structure. Similar to Next.js App Router or Remix file conventions.
|
|
4
4
|
|
|
5
|
-
## V. 1.
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
## V. 1.3.1
|
|
6
|
+
|
|
7
|
+
Routes are now able to be infinitely nested
|
|
8
|
+
|
|
9
|
+
**Notice** Only tested 3 levels deep but there is no reason i shouldnt work further
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Features](#features)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Quick Start](#quick-start)
|
|
16
|
+
- [1. Create your pages structure](#1-create-your-pages-structure)
|
|
17
|
+
- [2. Configure Vite](#2-configure-vite)
|
|
18
|
+
- [3. Use in your app](#3-use-in-your-app)
|
|
19
|
+
- [Using createBrowserRouter](#1-using-createbrowserrouter-recommended-for-most-users)
|
|
20
|
+
- [Using nested Route elements](#2-using-nested-route-elements)
|
|
21
|
+
- [File Conventions](#file-conventions)
|
|
22
|
+
- [Generated Routes File](#generated-routes-file)
|
|
23
|
+
- [Route Resolution Examples](#route-resolution-examples)
|
|
24
|
+
- [Layouts](#layouts)
|
|
25
|
+
- [FileLink component](#filelink-component)
|
|
26
|
+
- [Usage](#usage)
|
|
27
|
+
- [API Reference](#api-reference)
|
|
28
|
+
- [How It Works](#how-it-works)
|
|
29
|
+
- [Performance Considerations](#performance-considerations)
|
|
30
|
+
- [Common Patterns](#common-patterns)
|
|
31
|
+
- [Troubleshooting](#troubleshooting)
|
|
32
|
+
- [License](#license)
|
|
8
33
|
|
|
9
34
|
## Features
|
|
10
35
|
|
|
@@ -43,7 +68,7 @@ src/pages/
|
|
|
43
68
|
// vite.config.ts
|
|
44
69
|
import { defineConfig } from "vite";
|
|
45
70
|
import react from "@vitejs/plugin-react";
|
|
46
|
-
import { aaexFileRouter } from "aaex-file-router";
|
|
71
|
+
import { aaexFileRouter } from "aaex-file-router/plugin";
|
|
47
72
|
|
|
48
73
|
export default defineConfig({
|
|
49
74
|
plugins: [
|
|
@@ -58,20 +83,66 @@ export default defineConfig({
|
|
|
58
83
|
|
|
59
84
|
### 3. Use in your app
|
|
60
85
|
|
|
86
|
+
#### 1. Using createBrowserRouter (recommended for most users)
|
|
87
|
+
|
|
61
88
|
```typescript
|
|
62
|
-
// src/
|
|
63
|
-
import
|
|
64
|
-
import ReactDOM from "react-dom/client";
|
|
65
|
-
import { RouterProvider, createBrowserRouter } from "react-router-dom";
|
|
89
|
+
// src/App.tsx
|
|
90
|
+
import "./App.css";
|
|
66
91
|
import routes from "./routes";
|
|
92
|
+
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
|
93
|
+
import { Suspense } from "react";
|
|
94
|
+
|
|
95
|
+
function App() {
|
|
96
|
+
const router = createBrowserRouter(routes);
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
100
|
+
<RouterProvider router={router} />
|
|
101
|
+
</Suspense>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default App;
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## **OR**
|
|
109
|
+
|
|
110
|
+
### 2. using nested Route elements
|
|
67
111
|
|
|
68
|
-
|
|
112
|
+
**Note** I will probably create a custom route provider using this version later since this is the only solution that works with VITE-SSR if you wrap client in `<BrowserRouter/>` and server in `<StaticRouter/>`
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
//src/App.tsx
|
|
116
|
+
import {
|
|
117
|
+
BrowserRouter,
|
|
118
|
+
Routes,
|
|
119
|
+
Route,
|
|
120
|
+
type RouteObject,
|
|
121
|
+
} from "react-router-dom";
|
|
122
|
+
import routes from "./routes";
|
|
123
|
+
import { Suspense } from "react";
|
|
124
|
+
import "./App.css";
|
|
125
|
+
|
|
126
|
+
//recursivly creates nested routes
|
|
127
|
+
function createRoutes(route: RouteObject) {
|
|
128
|
+
return (
|
|
129
|
+
<Route key={route.path} path={route.path} element={route.element}>
|
|
130
|
+
{route.children?.map((child) => createRoutes(child))}
|
|
131
|
+
</Route>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function App() {
|
|
136
|
+
return (
|
|
137
|
+
<BrowserRouter>
|
|
138
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
139
|
+
<Routes>{routes.map((route) => createRoutes(route))}</Routes>
|
|
140
|
+
</Suspense>
|
|
141
|
+
</BrowserRouter>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
69
144
|
|
|
70
|
-
|
|
71
|
-
<React.StrictMode>
|
|
72
|
-
<RouterProvider router={router} />
|
|
73
|
-
</React.StrictMode>
|
|
74
|
-
);
|
|
145
|
+
export default App;
|
|
75
146
|
```
|
|
76
147
|
|
|
77
148
|
## File Conventions
|
|
@@ -105,14 +176,14 @@ export default function AdminLayout() {
|
|
|
105
176
|
|
|
106
177
|
### Slug files
|
|
107
178
|
|
|
108
|
-
Filenames wrapper in
|
|
179
|
+
Filenames wrapper in square brackets `[filename]` will resolve to a dynamic route
|
|
109
180
|
|
|
110
181
|
```
|
|
111
|
-
pages/test/[<filename>].tsx → "/test/:<filename>"
|
|
182
|
+
src/pages/test/[<filename>].tsx → "/test/:<filename>"
|
|
112
183
|
```
|
|
113
184
|
|
|
114
185
|
```tsx
|
|
115
|
-
//pages/test/[slug].tsx
|
|
186
|
+
// src/pages/test/[slug].tsx
|
|
116
187
|
|
|
117
188
|
import { useParams } from "react-router-dom";
|
|
118
189
|
|
|
@@ -164,20 +235,20 @@ export default routes;
|
|
|
164
235
|
|
|
165
236
|
## Route Resolution Examples
|
|
166
237
|
|
|
167
|
-
| File Structure
|
|
168
|
-
|
|
|
169
|
-
| `pages/index.tsx` | `/` |
|
|
170
|
-
| `pages/about.tsx` | `/about` |
|
|
171
|
-
| `pages/blog/index.tsx` | `/blog` |
|
|
172
|
-
| `pages/blog/post.tsx` | `/blog/post` |
|
|
173
|
-
| `pages/admin/layout.tsx` + children | `/admin/*` (grouped) |
|
|
238
|
+
| File Structure | Route Path |
|
|
239
|
+
| --------------------------------------- | -------------------- |
|
|
240
|
+
| `src/pages/index.tsx` | `/` |
|
|
241
|
+
| `src/pages/about.tsx` | `/about` |
|
|
242
|
+
| `src/pages/blog/index.tsx` | `/blog` |
|
|
243
|
+
| `src/pages/blog/post.tsx` | `/blog/post` |
|
|
244
|
+
| `src/pages/admin/layout.tsx` + children | `/admin/*` (grouped) |
|
|
174
245
|
|
|
175
246
|
## Layouts
|
|
176
247
|
|
|
177
248
|
Layouts wrap their child routes and provide shared UI:
|
|
178
249
|
|
|
179
250
|
```typescript
|
|
180
|
-
// pages/dashboard/layout.tsx
|
|
251
|
+
// src/pages/dashboard/layout.tsx
|
|
181
252
|
import { Outlet } from "react-router-dom";
|
|
182
253
|
|
|
183
254
|
export default function DashboardLayout() {
|
|
@@ -192,7 +263,7 @@ export default function DashboardLayout() {
|
|
|
192
263
|
}
|
|
193
264
|
```
|
|
194
265
|
|
|
195
|
-
All routes in `pages/dashboard/*` will render inside this layout.
|
|
266
|
+
All routes in `src/pages/dashboard/*` will render inside this layout.
|
|
196
267
|
|
|
197
268
|
## FileLink component
|
|
198
269
|
|
|
@@ -214,7 +285,7 @@ export type FileRoutes = "/" | "test";
|
|
|
214
285
|
```
|
|
215
286
|
|
|
216
287
|
```tsx
|
|
217
|
-
//src/pages/index.tsx
|
|
288
|
+
// src/pages/index.tsx
|
|
218
289
|
import { FileLink } from "aaex-file-router";
|
|
219
290
|
import type { FileRoutes } from "../routeTypes";
|
|
220
291
|
|
|
@@ -224,7 +295,7 @@ export default function Home() {
|
|
|
224
295
|
Hello Home!
|
|
225
296
|
{/* FileRoutes is optional and not required it will work fine with any string if not passed */}
|
|
226
297
|
<FileLink<FileRoutes> to="test">Test safe</FileLink>
|
|
227
|
-
|
|
298
|
+
{/* or without type safety */}
|
|
228
299
|
<FileLink to="some-route">Non safe</FileLink>
|
|
229
300
|
</>
|
|
230
301
|
);
|
|
@@ -260,7 +331,7 @@ const routesCode = await generator.generateComponentsMap(fileData);
|
|
|
260
331
|
Automatically watches for file changes and regenerates routes.
|
|
261
332
|
|
|
262
333
|
```typescript
|
|
263
|
-
import { aaexFileRouter } from "aaex-file-router/
|
|
334
|
+
import { aaexFileRouter } from "aaex-file-router/plugin";
|
|
264
335
|
|
|
265
336
|
export default defineConfig({
|
|
266
337
|
plugins: [
|
|
@@ -7,21 +7,13 @@ export interface FileData {
|
|
|
7
7
|
}
|
|
8
8
|
export declare class FileScanner {
|
|
9
9
|
page_dir: string;
|
|
10
|
-
topLevelImports: string[];
|
|
11
10
|
constructor(pages_dir: string);
|
|
12
11
|
/**
|
|
13
|
-
* Recursively scan directory and
|
|
14
|
-
* Adds a parentPath property to each entry to track hierarchy
|
|
12
|
+
* Recursively scan directory and return nested FileData
|
|
15
13
|
*/
|
|
16
14
|
private scan_files;
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
19
|
-
* Rebuilds directory hierarchy and filters children by parent path
|
|
20
|
-
*/
|
|
21
|
-
private build_file_data;
|
|
22
|
-
/**
|
|
23
|
-
* Public entry point: scans pages directory and returns nested FileData structure
|
|
24
|
-
* Handles both flat scanning and hierarchical rebuilding
|
|
16
|
+
* Public entry point: returns nested FileData structure
|
|
25
17
|
*/
|
|
26
18
|
get_file_data(): Promise<FileData[]>;
|
|
27
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileScanner.d.ts","sourceRoot":"","sources":["../../src/core/FileScanner.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,qBAAa,WAAW;IACtB,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"FileScanner.d.ts","sourceRoot":"","sources":["../../src/core/FileScanner.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,qBAAa,WAAW;IACtB,QAAQ,EAAE,MAAM,CAAC;gBAEL,SAAS,EAAE,MAAM;IAI7B;;OAEG;YACW,UAAU;IA0BxB;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;CAKlD"}
|
package/dist/core/FileScanner.js
CHANGED
|
@@ -2,80 +2,39 @@ import { promises as fs } from "node:fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
export class FileScanner {
|
|
4
4
|
page_dir;
|
|
5
|
-
topLevelImports = [];
|
|
6
5
|
constructor(pages_dir) {
|
|
7
6
|
this.page_dir = pages_dir;
|
|
8
7
|
}
|
|
9
8
|
/**
|
|
10
|
-
* Recursively scan directory and
|
|
11
|
-
* Adds a parentPath property to each entry to track hierarchy
|
|
9
|
+
* Recursively scan directory and return nested FileData
|
|
12
10
|
*/
|
|
13
11
|
async scan_files(dir) {
|
|
14
12
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
15
|
-
|
|
13
|
+
const result = [];
|
|
16
14
|
for (const entry of entries) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const fullPath = path.join(dir, entry.name);
|
|
16
|
+
const relativePath = path.relative(process.cwd(), fullPath).replace(/\\/g, "/");
|
|
17
|
+
const parentPath = path.relative(process.cwd(), dir).replace(/\\/g, "/") + "/";
|
|
18
|
+
const fileData = {
|
|
19
|
+
name: entry.name,
|
|
20
|
+
relative_path: relativePath,
|
|
21
|
+
parent_path: parentPath,
|
|
22
|
+
isDirectory: entry.isDirectory(),
|
|
23
|
+
};
|
|
21
24
|
if (entry.isDirectory()) {
|
|
22
|
-
|
|
23
|
-
result = result.concat(subFiles);
|
|
25
|
+
fileData.children = await this.scan_files(fullPath);
|
|
24
26
|
}
|
|
27
|
+
result.push(fileData);
|
|
25
28
|
}
|
|
26
29
|
return result;
|
|
27
30
|
}
|
|
28
31
|
/**
|
|
29
|
-
*
|
|
30
|
-
* Rebuilds directory hierarchy and filters children by parent path
|
|
31
|
-
*/
|
|
32
|
-
async build_file_data(files) {
|
|
33
|
-
const result = [];
|
|
34
|
-
for (const file of files) {
|
|
35
|
-
const fullpath = path.join(file.parentPath, file.name);
|
|
36
|
-
// Convert backslashes to forward slashes for cross-platform path consistency
|
|
37
|
-
const relative = path
|
|
38
|
-
.relative(process.cwd(), fullpath)
|
|
39
|
-
.replace(/\\/g, "/")
|
|
40
|
-
.trim();
|
|
41
|
-
if (file.isDirectory()) {
|
|
42
|
-
// Filter files to find only direct children of this directory
|
|
43
|
-
const children = files.filter((file) => file.parentPath === fullpath);
|
|
44
|
-
result.push({
|
|
45
|
-
name: file.name,
|
|
46
|
-
parent_path:
|
|
47
|
-
// Normalize parent path with forward slashes and trailing slash
|
|
48
|
-
path
|
|
49
|
-
.relative(process.cwd(), file.parentPath)
|
|
50
|
-
.replace(/\\/g, "/") + "/",
|
|
51
|
-
relative_path: relative,
|
|
52
|
-
isDirectory: true,
|
|
53
|
-
children: await this.build_file_data(children),
|
|
54
|
-
});
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
result.push({
|
|
58
|
-
name: file.name,
|
|
59
|
-
parent_path:
|
|
60
|
-
// Normalize parent path with forward slashes and trailing slash
|
|
61
|
-
path
|
|
62
|
-
.relative(process.cwd(), file.parentPath)
|
|
63
|
-
.replace(/\\/g, "/") + "/",
|
|
64
|
-
relative_path: relative,
|
|
65
|
-
isDirectory: false,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Public entry point: scans pages directory and returns nested FileData structure
|
|
72
|
-
* Handles both flat scanning and hierarchical rebuilding
|
|
32
|
+
* Public entry point: returns nested FileData structure
|
|
73
33
|
*/
|
|
74
34
|
async get_file_data() {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return result;
|
|
35
|
+
const fullDir = path.join(process.cwd(), this.page_dir);
|
|
36
|
+
const data = await this.scan_files(fullDir);
|
|
37
|
+
return data;
|
|
79
38
|
}
|
|
80
39
|
}
|
|
81
40
|
//# sourceMappingURL=FileScanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileScanner.js","sourceRoot":"","sources":["../../src/core/FileScanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB,MAAM,OAAO,WAAW;IACtB,QAAQ,CAAS;
|
|
1
|
+
{"version":3,"file":"FileScanner.js","sourceRoot":"","sources":["../../src/core/FileScanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,IAAI,MAAM,MAAM,CAAC;AAUxB,MAAM,OAAO,WAAW;IACtB,QAAQ,CAAS;IAEjB,YAAY,SAAiB;QAC3B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,GAAW;QAClC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAe,EAAE,CAAC;QAE9B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAChF,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;YAE/E,MAAM,QAAQ,GAAa;gBACzB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,aAAa,EAAE,YAAY;gBAC3B,WAAW,EAAE,UAAU;gBACvB,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE;aACjC,CAAC;YAEF,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,QAAQ,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
interface FileNode {
|
|
2
|
+
name: string;
|
|
3
|
+
relative_path: string;
|
|
4
|
+
parent_path: string;
|
|
5
|
+
isDirectory: boolean;
|
|
6
|
+
children?: FileNode[];
|
|
7
|
+
}
|
|
2
8
|
export declare class RouteGenerator {
|
|
3
9
|
private topLevelImports;
|
|
4
10
|
private importSet;
|
|
5
|
-
private processedFiles;
|
|
6
11
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @param
|
|
10
|
-
* @param parentPath - Current path context for nested routes (empty for root)
|
|
12
|
+
* Converts a FileData-like tree into React Router routes
|
|
13
|
+
* @param files - Array of file/folder objects passed externally
|
|
14
|
+
* @param parentPath - Current path for recursion
|
|
11
15
|
*/
|
|
12
16
|
private fileDataToRoutes;
|
|
13
17
|
/**
|
|
14
|
-
* Generates a
|
|
15
|
-
*
|
|
16
|
-
* @param fileData - FileData tree from FileScanner
|
|
17
|
-
* @returns Complete routes file content ready to be written to disk
|
|
18
|
+
* Generates a React Router routes file as a string
|
|
19
|
+
* @param fileData - FileData-like tree
|
|
18
20
|
*/
|
|
19
|
-
|
|
21
|
+
generateRoutesFile(fileData: FileNode[]): Promise<string>;
|
|
20
22
|
/**
|
|
21
|
-
* Generates
|
|
22
|
-
* @param fileData - FileData tree
|
|
23
|
-
* @returns Type definition file content as string
|
|
23
|
+
* Generates TypeScript type definition for all route paths
|
|
24
|
+
* @param fileData - FileData-like tree
|
|
24
25
|
*/
|
|
25
|
-
generateRoutesTypeDef(fileData:
|
|
26
|
+
generateRoutesTypeDef(fileData: FileNode[]): Promise<string>;
|
|
26
27
|
}
|
|
28
|
+
export {};
|
|
27
29
|
//# sourceMappingURL=RouteGenerator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../src/core/RouteGenerator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../src/core/RouteGenerator.ts"],"names":[],"mappings":"AAMA,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,SAAS,CAA0B;IAE3C;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAgGxB;;;OAGG;IACU,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBtE;;;OAGG;IACU,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA8B1E"}
|
|
@@ -1,145 +1,89 @@
|
|
|
1
1
|
export class RouteGenerator {
|
|
2
2
|
topLevelImports = [];
|
|
3
3
|
importSet = new Set();
|
|
4
|
-
processedFiles = new Set();
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @param
|
|
9
|
-
* @param parentPath - Current path context for nested routes (empty for root)
|
|
5
|
+
* Converts a FileData-like tree into React Router routes
|
|
6
|
+
* @param files - Array of file/folder objects passed externally
|
|
7
|
+
* @param parentPath - Current path for recursion
|
|
10
8
|
*/
|
|
11
|
-
fileDataToRoutes(
|
|
9
|
+
fileDataToRoutes(files, parentPath = "", isChild = false) {
|
|
12
10
|
const routes = [];
|
|
13
|
-
const
|
|
14
|
-
/** Converts `[slug]` → `:slug` */
|
|
15
|
-
const normalizeDynamicSegment = (name) => name.replace(/\[([^\]]+)\]/g, ":$1");
|
|
16
|
-
/**
|
|
17
|
-
* Utility function to safely join path segments
|
|
18
|
-
* - Filters out empty/falsy parts to avoid "///" in paths
|
|
19
|
-
* - Joins with "/" separator
|
|
20
|
-
* - Replaces all backslashes with forward slashes for cross-platform consistency
|
|
21
|
-
* Example: posixJoin("test", "", "hello") -> "test/hello"
|
|
22
|
-
* Example: posixJoin("pages\\test", "hello") -> "pages/test/hello"
|
|
23
|
-
*/
|
|
24
|
-
const posixJoin = (...parts) => parts.filter(Boolean).join("/").replace(/\\/g, "/");
|
|
25
|
-
/** Converts "user", "[id]" → "User", "Id" */
|
|
11
|
+
const normalizeSegment = (name) => name.replace(/\[([^\]]+)\]/g, ":$1").toLowerCase();
|
|
26
12
|
const toPascal = (str) => str
|
|
27
13
|
.replace(/\[|\]/g, "")
|
|
28
14
|
.replace(/(^\w|[-_]\w)/g, (m) => m.replace(/[-_]/, "").toUpperCase());
|
|
29
|
-
|
|
30
|
-
const getImportName = (file) => {
|
|
31
|
-
const segments = file.relative_path.replace(/^src[\/\\]/, "").split("/");
|
|
32
|
-
const parentFolder = segments.length > 1 ? segments[segments.length - 2] : "";
|
|
33
|
-
const parentName = parentFolder ? toPascal(parentFolder) : "";
|
|
15
|
+
const getImportName = (file, parentPath) => {
|
|
34
16
|
const nameWithoutExt = file.name.replace(/\.[jt]sx?$/, "");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const createRoute = (file, path, importName, lazy = false) => {
|
|
42
|
-
const filePath = file.relative_path.replace(/^src[\/\\]/, "./");
|
|
43
|
-
const element = lazy
|
|
44
|
-
? `React.createElement(React.lazy(() => import('${filePath}')))`
|
|
45
|
-
: `React.createElement(${importName})`;
|
|
46
|
-
return { path: normalizeDynamicSegment(path), element };
|
|
17
|
+
if (nameWithoutExt.toLowerCase() === "index" && parentPath) {
|
|
18
|
+
// Use parent folder prefix for nested index
|
|
19
|
+
const segments = parentPath.split("/").filter(Boolean);
|
|
20
|
+
return toPascal(segments.join("")) + "Index";
|
|
21
|
+
}
|
|
22
|
+
return toPascal(nameWithoutExt);
|
|
47
23
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const layoutImportName = file.name.charAt(0).toUpperCase() + file.name.slice(1) + "Layout";
|
|
61
|
-
const layoutPath = layoutFile.relative_path.replace(/^src[\/\\]/, "./");
|
|
62
|
-
this.topLevelImports.push(`import ${layoutImportName} from '${layoutPath}';`);
|
|
63
|
-
this.processedFiles.add(layoutFile.relative_path);
|
|
64
|
-
const childRoutes = [];
|
|
65
|
-
for (const child of file.children.filter((c) => !/^layout\.(tsx|jsx|ts|js)$/i.test(c.name))) {
|
|
66
|
-
if (child.isDirectory) {
|
|
67
|
-
processFile(child, posixJoin(currentParentPath, file.name), "", true);
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
if (file.isDirectory) {
|
|
26
|
+
const layout = file.children?.find((f) => !f.isDirectory && /^layout\.(tsx|jsx|ts|js)$/i.test(f.name));
|
|
27
|
+
const route = {
|
|
28
|
+
path: normalizeSegment(file.name),
|
|
29
|
+
};
|
|
30
|
+
if (layout) {
|
|
31
|
+
const importName = `${toPascal(file.name)}Layout`;
|
|
32
|
+
const importPath = `./${layout.relative_path.replace(/^src[\/\\]/, "")}`;
|
|
33
|
+
if (!this.importSet.has(layout.relative_path)) {
|
|
34
|
+
this.topLevelImports.push(`import ${importName} from '${importPath}';`);
|
|
35
|
+
this.importSet.add(layout.relative_path);
|
|
68
36
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.
|
|
37
|
+
route.element = `React.createElement(${importName})`;
|
|
38
|
+
}
|
|
39
|
+
if (file.children?.length) {
|
|
40
|
+
const children = file.children.filter((f) => !/^layout\.(tsx|jsx|ts|js)$/i.test(f.name));
|
|
41
|
+
if (children.length) {
|
|
42
|
+
// Pass true for isChild to make children paths relative
|
|
43
|
+
route.children = this.fileDataToRoutes(children, route.path, true);
|
|
76
44
|
}
|
|
77
45
|
}
|
|
78
|
-
routes.push(
|
|
79
|
-
path: normalizeDynamicSegment(file.name.toLowerCase()),
|
|
80
|
-
element: `React.createElement(${layoutImportName})`,
|
|
81
|
-
children: childRoutes.length ? childRoutes : undefined,
|
|
82
|
-
});
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
// ---------------- FILES ----------------
|
|
86
|
-
const nameWithoutExt = file.name.replace(/\.[jt]sx?$/, "");
|
|
87
|
-
const isIndex = nameWithoutExt.toLowerCase() === "index";
|
|
88
|
-
if (isIndex && processedIndexes.has(file.relative_path))
|
|
89
|
-
return;
|
|
90
|
-
if (fileData.some((f) => f.isDirectory &&
|
|
91
|
-
f.name.toLowerCase() === nameWithoutExt.toLowerCase()) ||
|
|
92
|
-
/^layout\.(tsx|jsx|ts|js)$/i.test(file.name)) {
|
|
93
|
-
this.processedFiles.add(file.relative_path);
|
|
94
|
-
return;
|
|
46
|
+
routes.push(route);
|
|
95
47
|
}
|
|
96
|
-
const rawSegment = isIndex ? "" : nameWithoutExt.toLowerCase();
|
|
97
|
-
const fileSegment = normalizeDynamicSegment(rawSegment);
|
|
98
|
-
let fullPath;
|
|
99
|
-
if (currentFlatten)
|
|
100
|
-
fullPath = posixJoin(currentFlatten, fileSegment);
|
|
101
|
-
else if (group)
|
|
102
|
-
fullPath = fileSegment;
|
|
103
|
-
else if (currentParentPath)
|
|
104
|
-
fullPath = posixJoin(currentParentPath, fileSegment);
|
|
105
|
-
else
|
|
106
|
-
fullPath = isIndex ? "/" : fileSegment;
|
|
107
|
-
const importName = getImportName(file);
|
|
108
|
-
if (group)
|
|
109
|
-
routes.push(createRoute(file, fullPath, undefined, true));
|
|
110
48
|
else {
|
|
49
|
+
const nameWithoutExt = file.name.replace(/\.[jt]sx?$/, "");
|
|
50
|
+
const isIndex = nameWithoutExt.toLowerCase() === "index";
|
|
51
|
+
// If child, path is relative; otherwise, top-level gets full path
|
|
52
|
+
let pathSegment = isIndex ? "" : normalizeSegment(nameWithoutExt);
|
|
53
|
+
if (isChild) {
|
|
54
|
+
// Children always use relative paths
|
|
55
|
+
pathSegment = pathSegment;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
pathSegment = parentPath
|
|
59
|
+
? `${parentPath}/${pathSegment}`
|
|
60
|
+
: pathSegment;
|
|
61
|
+
}
|
|
62
|
+
const importName = getImportName(file, parentPath);
|
|
63
|
+
;
|
|
64
|
+
const importPath = `./${file.relative_path.replace(/^src[\/\\]/, "")}`;
|
|
111
65
|
if (!this.importSet.has(file.relative_path)) {
|
|
112
|
-
this.topLevelImports.push(`import ${importName} from '
|
|
66
|
+
this.topLevelImports.push(`import ${importName} from '${importPath}';`);
|
|
113
67
|
this.importSet.add(file.relative_path);
|
|
114
68
|
}
|
|
115
|
-
routes.push(
|
|
69
|
+
routes.push({
|
|
70
|
+
path: pathSegment,
|
|
71
|
+
element: `React.createElement(${importName})`,
|
|
72
|
+
});
|
|
116
73
|
}
|
|
117
|
-
|
|
118
|
-
if (isIndex)
|
|
119
|
-
processedIndexes.add(file.relative_path);
|
|
120
|
-
};
|
|
121
|
-
for (const file of fileData)
|
|
122
|
-
processFile(file, parentPath, flattenPrefix, inGroup);
|
|
74
|
+
}
|
|
123
75
|
return routes;
|
|
124
76
|
}
|
|
125
77
|
/**
|
|
126
|
-
* Generates a
|
|
127
|
-
*
|
|
128
|
-
* @param fileData - FileData tree from FileScanner
|
|
129
|
-
* @returns Complete routes file content ready to be written to disk
|
|
78
|
+
* Generates a React Router routes file as a string
|
|
79
|
+
* @param fileData - FileData-like tree
|
|
130
80
|
*/
|
|
131
|
-
async
|
|
132
|
-
// reset import & processed tracking each generation to avoid duplication across regen
|
|
81
|
+
async generateRoutesFile(fileData) {
|
|
133
82
|
this.topLevelImports = [];
|
|
134
83
|
this.importSet = new Set();
|
|
135
|
-
this.processedFiles = new Set();
|
|
136
84
|
const routes = this.fileDataToRoutes(fileData);
|
|
137
|
-
const routesString = JSON.stringify(routes, null, 2)
|
|
138
|
-
|
|
139
|
-
.replace(/"React\.createElement\(React\.lazy\(\(\) => import\('(.*)'\)\)\)"/g, "React.createElement(React.lazy(() => import('$1')))")
|
|
140
|
-
// React.createElement(Component) serialized as string, unquote it
|
|
141
|
-
.replace(/"React\.createElement\((\w+)\)"/g, "React.createElement($1)");
|
|
142
|
-
const mapString = `//* AUTO GENERATED: DO NOT EDIT
|
|
85
|
+
const routesString = JSON.stringify(routes, null, 2).replace(/"React\.createElement\((\w+)\)"/g, "React.createElement($1)");
|
|
86
|
+
return `//* AUTO GENERATED: DO NOT EDIT
|
|
143
87
|
import React from 'react';
|
|
144
88
|
${this.topLevelImports.join("\n")}
|
|
145
89
|
import type { RouteObject } from 'react-router-dom';
|
|
@@ -148,37 +92,31 @@ const routes: RouteObject[] = ${routesString};
|
|
|
148
92
|
|
|
149
93
|
export default routes;
|
|
150
94
|
`;
|
|
151
|
-
return mapString;
|
|
152
95
|
}
|
|
153
96
|
/**
|
|
154
|
-
* Generates
|
|
155
|
-
* @param fileData - FileData tree
|
|
156
|
-
* @returns Type definition file content as string
|
|
97
|
+
* Generates TypeScript type definition for all route paths
|
|
98
|
+
* @param fileData - FileData-like tree
|
|
157
99
|
*/
|
|
158
100
|
async generateRoutesTypeDef(fileData) {
|
|
159
|
-
// Reset state
|
|
160
|
-
this.topLevelImports = [];
|
|
161
|
-
this.importSet = new Set();
|
|
162
|
-
this.processedFiles = new Set();
|
|
163
101
|
const routes = this.fileDataToRoutes(fileData);
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
102
|
+
const paths = [];
|
|
103
|
+
const collectPaths = (routes, parentPath = "") => {
|
|
104
|
+
for (const route of routes) {
|
|
105
|
+
const fullPath = parentPath
|
|
106
|
+
? `${parentPath}/${route.path}`.replace(/\/+/g, "/")
|
|
107
|
+
: route.path;
|
|
108
|
+
const tsPath = fullPath
|
|
109
|
+
.split("/")
|
|
110
|
+
.map((seg) => (seg.startsWith(":") ? "${string}" : seg))
|
|
111
|
+
.join("/");
|
|
112
|
+
paths.push(tsPath);
|
|
113
|
+
if (route.children)
|
|
114
|
+
collectPaths(route.children, fullPath);
|
|
177
115
|
}
|
|
178
116
|
};
|
|
179
|
-
routes
|
|
180
|
-
const uniquePaths = Array.from(new Set(
|
|
181
|
-
.map((p) => `\`${p}\``)
|
|
117
|
+
collectPaths(routes);
|
|
118
|
+
const uniquePaths = Array.from(new Set(paths))
|
|
119
|
+
.map((p) => `\`${p}\``)
|
|
182
120
|
.join(" | ");
|
|
183
121
|
return `// * AUTO GENERATED: DO NOT EDIT
|
|
184
122
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteGenerator.js","sourceRoot":"","sources":["../../src/core/RouteGenerator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RouteGenerator.js","sourceRoot":"","sources":["../../src/core/RouteGenerator.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/core/index.js
CHANGED
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,gDAAgD
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,gDAAgD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boo.d.ts","sourceRoot":"","sources":["../../../../../src/pages/test/ba/baka/boo.tsx"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,GAAG,4CAE1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boo.js","sourceRoot":"","sources":["../../../../../src/pages/test/ba/baka/boo.tsx"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,UAAU,GAAG;IACvB,OAAO,qCAAS,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
export interface VitePluginOptions {
|
|
3
|
+
pagesDir?: string;
|
|
4
|
+
outputFile?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Vite plugin that auto-generates routes when page files change
|
|
8
|
+
* Watches the pages directory and regenerates routes.ts on file create/delete
|
|
9
|
+
*/
|
|
10
|
+
export declare function aaexFileRouter(options?: VitePluginOptions): Plugin;
|
|
11
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAM9B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAmDtE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { FileScanner } from "../core/FileScanner.js";
|
|
4
|
+
import { RouteGenerator } from "../core/RouteGenerator.js";
|
|
5
|
+
/**
|
|
6
|
+
* Vite plugin that auto-generates routes when page files change
|
|
7
|
+
* Watches the pages directory and regenerates routes.ts on file create/delete
|
|
8
|
+
*/
|
|
9
|
+
export function aaexFileRouter(options = {}) {
|
|
10
|
+
const pagesDir = options.pagesDir || "./src/pages";
|
|
11
|
+
const outputFile = options.outputFile || "./src/routes.ts";
|
|
12
|
+
let scanner;
|
|
13
|
+
let generator;
|
|
14
|
+
return {
|
|
15
|
+
name: "aaex-file-router",
|
|
16
|
+
apply: "serve", // Only run in dev mode
|
|
17
|
+
configResolved() {
|
|
18
|
+
scanner = new FileScanner(pagesDir);
|
|
19
|
+
generator = new RouteGenerator();
|
|
20
|
+
},
|
|
21
|
+
async configureServer(server) {
|
|
22
|
+
// Watch the pages directory for changes
|
|
23
|
+
server.watcher.add(path.resolve(process.cwd(), pagesDir));
|
|
24
|
+
server.watcher.on("all", async (event, filePath) => {
|
|
25
|
+
// Only regenerate on file add/unlink events
|
|
26
|
+
if (event === "add" || event === "unlink") {
|
|
27
|
+
try {
|
|
28
|
+
console.log(`📄 [aaex-file-router] ${event}: ${filePath}`);
|
|
29
|
+
// Regenerate routes
|
|
30
|
+
scanner = new FileScanner(pagesDir);
|
|
31
|
+
generator = new RouteGenerator();
|
|
32
|
+
const fileData = await scanner.get_file_data();
|
|
33
|
+
const routesCode = await generator.generateRoutesFile(fileData);
|
|
34
|
+
const routesType = await generator.generateRoutesTypeDef(fileData);
|
|
35
|
+
// Write routes file
|
|
36
|
+
await fs.writeFile(outputFile, routesCode, "utf-8");
|
|
37
|
+
await fs.writeFile("src/routeTypes.ts", routesType, "utf-8");
|
|
38
|
+
console.log(`✅ [aaex-file-router] Routes regenerated at ${outputFile}`);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error("❌ [aaex-file-router] Error regenerating routes:", error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAO3D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAA6B,EAAE;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAE3D,IAAI,OAAoB,CAAC;IACzB,IAAI,SAAyB,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,OAAO,EAAE,uBAAuB;QAEvC,cAAc;YACZ,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;YACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;QACnC,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,wCAAwC;YACxC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;YAE1D,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBACjD,4CAA4C;gBAC5C,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC1C,IAAI,CAAC;wBACH,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,KAAK,QAAQ,EAAE,CAAC,CAAC;wBAE3D,oBAAoB;wBACpB,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;wBACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;wBAEjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC/C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;wBAChE,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;wBAEnE,oBAAoB;wBACpB,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;wBACpD,MAAM,EAAE,CAAC,SAAS,CAAC,mBAAmB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;wBAE7D,OAAO,CAAC,GAAG,CACT,8CAA8C,UAAU,EAAE,CAC3D,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CACX,iDAAiD,EACjD,KAAK,CACN,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -30,7 +30,7 @@ export function aaexFileRouter(options = {}) {
|
|
|
30
30
|
scanner = new FileScanner(pagesDir);
|
|
31
31
|
generator = new RouteGenerator();
|
|
32
32
|
const fileData = await scanner.get_file_data();
|
|
33
|
-
const routesCode = await generator.
|
|
33
|
+
const routesCode = await generator.generateRoutesFile(fileData);
|
|
34
34
|
const routesType = await generator.generateRoutesTypeDef(fileData);
|
|
35
35
|
// Write routes file
|
|
36
36
|
await fs.writeFile(outputFile, routesCode, "utf-8");
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAA6B,EAAE;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAE3D,IAAI,OAAoB,CAAC;IACzB,IAAI,SAAyB,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,OAAO,EAAE,uBAAuB;QAEvC,cAAc;YACZ,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;YACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;QACnC,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,wCAAwC;YACxC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;YAE1D,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBACjD,4CAA4C;gBAC5C,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC1C,IAAI,CAAC;wBACH,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,KAAK,QAAQ,EAAE,CAAC,CAAC;wBAE3D,oBAAoB;wBACpB,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;wBACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;wBAEjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC/C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAA6B,EAAE;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAE3D,IAAI,OAAoB,CAAC;IACzB,IAAI,SAAyB,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,OAAO,EAAE,uBAAuB;QAEvC,cAAc;YACZ,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;YACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;QACnC,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,wCAAwC;YACxC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;YAE1D,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBACjD,4CAA4C;gBAC5C,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC1C,IAAI,CAAC;wBACH,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,KAAK,QAAQ,EAAE,CAAC,CAAC;wBAE3D,oBAAoB;wBACpB,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;wBACpC,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;wBAEjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC/C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;wBAChE,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;wBAEnE,oBAAoB;wBACpB,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;wBACpD,MAAM,EAAE,CAAC,SAAS,CAAC,mBAAmB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;wBAE7D,OAAO,CAAC,GAAG,CACT,8CAA8C,UAAU,EAAE,CAC3D,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CACX,iDAAiD,EACjD,KAAK,CACN,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/test/index.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { fileURLToPath } from "url";
|
|
2
2
|
import { FileScanner } from "../core/FileScanner.js";
|
|
3
3
|
import { RouteGenerator } from "../core/RouteGenerator.js";
|
|
4
|
+
import fs from "fs";
|
|
4
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
5
6
|
const pagesDir = "/src/pages";
|
|
6
7
|
async function generateRoutes() {
|
|
7
8
|
try {
|
|
8
9
|
const scanner = new FileScanner(pagesDir);
|
|
9
10
|
const fileData = await scanner.get_file_data();
|
|
10
|
-
console.log(fileData);
|
|
11
11
|
// console.log(fileData);
|
|
12
|
+
console.dir(fileData, { depth: null });
|
|
12
13
|
const generator = new RouteGenerator();
|
|
13
|
-
const routeMap = await generator.
|
|
14
|
+
const routeMap = await generator.generateRoutesFile(fileData);
|
|
14
15
|
// console.log("Route map: ", routeMap)
|
|
15
|
-
const routType = await generator.generateRoutesTypeDef(fileData);
|
|
16
|
-
console.log(routeMap);
|
|
16
|
+
// const routType = await generator.generateRoutesTypeDef(fileData);
|
|
17
|
+
// console.log(routeMap);
|
|
18
|
+
fs.writeFile("./src/test/output.ts", routeMap, "utf-8", (err) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
console.log(err);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
17
23
|
}
|
|
18
24
|
catch (error) {
|
|
19
25
|
console.error("Error generating routes:", error);
|
package/dist/test/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,KAAK,UAAU,cAAc;IAC3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;QAE/C,yBAAyB;QAEzB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAC,EAAC,KAAK,EAAC,IAAI,EAAC,CAAC,CAAC;QAEnC,MAAM,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE9D,uCAAuC;QAEvC,oEAAoE;QAEpE,yBAAyB;QAEzB,EAAE,CAAC,SAAS,CAAC,sBAAsB,EAAC,QAAQ,EAAC,OAAO,EAAC,CAAC,GAAG,EAAC,EAAE;YAC1D,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEnB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/test/output.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,QAAA,MAAM,MAAM,EAAE,WAAW,EAiCxB,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//* AUTO GENERATED: DO NOT EDIT
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Pages from './pages/index.tsx';
|
|
4
|
+
import TestLayout from './pages/test/layout.tsx';
|
|
5
|
+
import BaMoo from './pages/test/ba/moo.tsx';
|
|
6
|
+
import UsersLayout from './pages/users/layout.tsx';
|
|
7
|
+
const routes = [
|
|
8
|
+
{
|
|
9
|
+
"path": "/",
|
|
10
|
+
"element": React.createElement(Pages)
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": "test",
|
|
14
|
+
"element": React.createElement(TestLayout),
|
|
15
|
+
"children": [
|
|
16
|
+
{
|
|
17
|
+
"path": "about",
|
|
18
|
+
"element": React.createElement(React.lazy(() => import('./pages/test/about.tsx')))
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "",
|
|
22
|
+
"element": React.createElement(React.lazy(() => import('./pages/test/index.tsx')))
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "ba/moo",
|
|
28
|
+
"element": React.createElement(BaMoo)
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "users",
|
|
32
|
+
"element": React.createElement(UsersLayout),
|
|
33
|
+
"children": [
|
|
34
|
+
{
|
|
35
|
+
"path": ":id",
|
|
36
|
+
"element": React.createElement(React.lazy(() => import('./pages/users/[id].tsx')))
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
export default routes;
|
|
42
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/test/output.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AACtC,OAAO,UAAU,MAAM,yBAAyB,CAAC;AACjD,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAC5C,OAAO,WAAW,MAAM,0BAA0B,CAAC;AAGnD,MAAM,MAAM,GAAkB;IAC5B;QACE,MAAM,EAAE,GAAG;QACX,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;KACtC;IACD;QACE,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC;QAC1C,UAAU,EAAE;YACV;gBACE,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;aACnF;YACD;gBACE,MAAM,EAAE,EAAE;gBACV,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;aACnF;SACF;KACF;IACD;QACE,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;KACtC;IACD;QACE,MAAM,EAAE,OAAO;QACf,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC;QAC3C,UAAU,EAAE;YACV;gBACE,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;aACnF;SACF;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aaex-file-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A file-based routing system for React projects that automatically generates routes from your file structure. Similar to Next.js App Router or Remix file conventions.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
"exports":{
|
|
18
18
|
".": "./dist/index.js",
|
|
19
|
-
"./core": "./dist/core/index.js"
|
|
19
|
+
"./core": "./dist/core/index.js",
|
|
20
|
+
"./plugin": "./dist/plugin/index.js"
|
|
20
21
|
},
|
|
21
22
|
"author": "TmRAaEx",
|
|
22
23
|
"license": "MIT",
|