clear-router 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/basic-BCxhZ1Wd.d.cts +24 -0
- package/dist/basic-POMY6a76.d.mts +24 -0
- package/dist/express/routes.cjs +249 -0
- package/dist/express/routes.d.cts +158 -0
- package/dist/express/routes.d.mts +159 -0
- package/dist/express/routes.mjs +248 -0
- package/dist/h3/routes.cjs +252 -0
- package/dist/h3/routes.d.cts +151 -0
- package/dist/h3/routes.d.mts +152 -0
- package/dist/h3/routes.mjs +251 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Refkinscallv
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# @refkinscallv/express-routing
|
|
2
|
+
|
|
3
|
+
Laravel-style routing system for Express.js in JavaScript. Clean route definitions, middleware support, and controller bindings with full TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @refkinscallv/express-routing
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Simple and clean route declarations (get, post, put, delete, patch, options, head)
|
|
14
|
+
- Grouped routes with prefix
|
|
15
|
+
- Middleware stack: per-route and group-level
|
|
16
|
+
- Controller-method pair as route handler
|
|
17
|
+
- Supports HttpContext style handlers: { req, res, next }
|
|
18
|
+
- Auto-binds controller methods
|
|
19
|
+
- Full CommonJS, ESM, and TypeScript support
|
|
20
|
+
- Error handling delegated to Express
|
|
21
|
+
- Route inspection with allRoutes method
|
|
22
|
+
- Fully Express-compatible
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### CommonJS
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
const express = require('express');
|
|
30
|
+
const Routes = require('@refkinscallv/express-routing');
|
|
31
|
+
|
|
32
|
+
const app = express();
|
|
33
|
+
const router = express.Router();
|
|
34
|
+
|
|
35
|
+
Routes.get('/hello', ({ res }) => {
|
|
36
|
+
res.send('Hello World');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
Routes.apply(router);
|
|
40
|
+
app.use(router);
|
|
41
|
+
|
|
42
|
+
app.listen(3000);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### ESM
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
import express from 'express';
|
|
49
|
+
import Routes from '@refkinscallv/express-routing';
|
|
50
|
+
|
|
51
|
+
const app = express();
|
|
52
|
+
const router = express.Router();
|
|
53
|
+
|
|
54
|
+
Routes.get('/hello', ({ res }) => {
|
|
55
|
+
res.send('Hello World');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await Routes.apply(router);
|
|
59
|
+
app.use(router);
|
|
60
|
+
|
|
61
|
+
app.listen(3000);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### TypeScript
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import express from 'express';
|
|
68
|
+
import Routes from '@refkinscallv/express-routing';
|
|
69
|
+
|
|
70
|
+
const app = express();
|
|
71
|
+
const router = express.Router();
|
|
72
|
+
|
|
73
|
+
Routes.get('/hello', ({ res }) => {
|
|
74
|
+
res.send('Hello World');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await Routes.apply(router);
|
|
78
|
+
app.use(router);
|
|
79
|
+
|
|
80
|
+
app.listen(3000);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Usage Examples
|
|
84
|
+
|
|
85
|
+
### Basic Route
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
Routes.get('/hello', ({ res }) => {
|
|
89
|
+
res.send('Hello World');
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### With Middleware
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const authMiddleware = (req, res, next) => {
|
|
97
|
+
// auth logic
|
|
98
|
+
next();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
Routes.post('/secure', ({ res }) => res.send('Protected'), [authMiddleware]);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Controller Binding
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
class UserController {
|
|
108
|
+
static index({ res }) {
|
|
109
|
+
res.send('User List');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Routes.get('/users', [UserController, 'index']);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Class-based handlers will auto-bind to static or instance methods.
|
|
117
|
+
|
|
118
|
+
### Grouped Routes
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
Routes.group('/admin', () => {
|
|
122
|
+
Routes.get('/dashboard', ({ res }) => res.send('Admin Panel'));
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
With middleware:
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
Routes.group('/secure', () => {
|
|
130
|
+
Routes.get('/data', ({ res }) => res.send('Secure Data'));
|
|
131
|
+
}, [authMiddleware]);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Global Middleware Scope
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
Routes.middleware([authMiddleware], () => {
|
|
138
|
+
Routes.get('/profile', ({ res }) => res.send('My Profile'));
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Multiple HTTP Methods
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
Routes.add(['get', 'post'], '/handle', ({ req, res }) => {
|
|
146
|
+
res.send(`Method: ${req.method}`);
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Inspecting Routes
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
Routes.get('/hello', ({ res }) => res.send('Hello'));
|
|
154
|
+
Routes.post('/world', ({ res }) => res.send('World'));
|
|
155
|
+
|
|
156
|
+
const allRoutes = Routes.allRoutes();
|
|
157
|
+
console.log(allRoutes);
|
|
158
|
+
// Output:
|
|
159
|
+
// [
|
|
160
|
+
// { methods: ['get'], path: '/hello', middlewareCount: 0, handlerType: 'function' },
|
|
161
|
+
// { methods: ['post'], path: '/world', middlewareCount: 0, handlerType: 'function' }
|
|
162
|
+
// ]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## API Reference
|
|
166
|
+
|
|
167
|
+
See [API.md](API.md) for complete API documentation.
|
|
168
|
+
|
|
169
|
+
## Error Handling
|
|
170
|
+
|
|
171
|
+
All errors during route execution are automatically passed to Express error handling middleware using `next(error)`. You can define your error handler:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
app.use((err, req, res, next) => {
|
|
175
|
+
console.error(err);
|
|
176
|
+
res.status(500).json({ error: err.message });
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Middleware Execution Order
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
[ Global Middleware ] → [ Group Middleware ] → [ Route Middleware ]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Handler Execution
|
|
187
|
+
|
|
188
|
+
- If function: executed directly
|
|
189
|
+
- If [Controller, 'method']: auto-instantiated (if needed), method is called
|
|
190
|
+
|
|
191
|
+
## Testing
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm test # Run all tests
|
|
195
|
+
npm run test:cjs # Test CommonJS
|
|
196
|
+
npm run test:esm # Test ESM
|
|
197
|
+
npm run test:ts # Test TypeScript
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
See [TESTING.md](TESTING.md) for detailed testing guide.
|
|
201
|
+
|
|
202
|
+
## Examples
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm run example # CommonJS example
|
|
206
|
+
npm run example:esm # ESM example
|
|
207
|
+
npm run example:ts # TypeScript example
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Check `example/` directory for full working demos.
|
|
211
|
+
|
|
212
|
+
## Changelog
|
|
213
|
+
|
|
214
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
215
|
+
|
|
216
|
+
## Requirements
|
|
217
|
+
|
|
218
|
+
- Node.js >= 14.0.0
|
|
219
|
+
- Express >= 5.0.0
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT License © 2026 Refkinscallv
|
|
224
|
+
|
|
225
|
+
## Author
|
|
226
|
+
|
|
227
|
+
Refkinscallv <refkinscallv@gmail.com>
|
|
228
|
+
|
|
229
|
+
## Repository
|
|
230
|
+
|
|
231
|
+
https://github.com/refkinscallv/express-routing
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region types/basic.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Controller method reference
|
|
4
|
+
*/
|
|
5
|
+
type ControllerHandler = [any, string];
|
|
6
|
+
/**
|
|
7
|
+
* HTTP methods supported by the router
|
|
8
|
+
*/
|
|
9
|
+
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
|
|
10
|
+
/**
|
|
11
|
+
* Route information object
|
|
12
|
+
*/
|
|
13
|
+
interface RouteInfo {
|
|
14
|
+
methods: HttpMethod[];
|
|
15
|
+
path: string;
|
|
16
|
+
middlewareCount: number;
|
|
17
|
+
handlerType: 'function' | 'controller';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Common controller action names
|
|
21
|
+
*/
|
|
22
|
+
type ControllerAction = 'index' | 'show' | 'create' | 'update' | 'destroy';
|
|
23
|
+
//#endregion
|
|
24
|
+
export { RouteInfo as i, ControllerHandler as n, HttpMethod as r, ControllerAction as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region types/basic.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Controller method reference
|
|
4
|
+
*/
|
|
5
|
+
type ControllerHandler = [any, string];
|
|
6
|
+
/**
|
|
7
|
+
* HTTP methods supported by the router
|
|
8
|
+
*/
|
|
9
|
+
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head';
|
|
10
|
+
/**
|
|
11
|
+
* Route information object
|
|
12
|
+
*/
|
|
13
|
+
interface RouteInfo {
|
|
14
|
+
methods: HttpMethod[];
|
|
15
|
+
path: string;
|
|
16
|
+
middlewareCount: number;
|
|
17
|
+
handlerType: 'function' | 'controller';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Common controller action names
|
|
21
|
+
*/
|
|
22
|
+
type ControllerAction = 'index' | 'show' | 'create' | 'update' | 'destroy';
|
|
23
|
+
//#endregion
|
|
24
|
+
export { RouteInfo as i, ControllerHandler as n, HttpMethod as r, ControllerAction as t };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/express/routes.ts
|
|
3
|
+
/**
|
|
4
|
+
* @class clear-router
|
|
5
|
+
* @description Laravel-style routing system for Express.js and H3 with support for CommonJS, ESM, and TypeScript
|
|
6
|
+
* @author Refkinscallv
|
|
7
|
+
* @author 3m1n3nc3
|
|
8
|
+
* @repository https://github.com/toneflix/clear-router
|
|
9
|
+
*/
|
|
10
|
+
var Routes = class {
|
|
11
|
+
/**
|
|
12
|
+
* All registered routes
|
|
13
|
+
*/
|
|
14
|
+
static routes = [];
|
|
15
|
+
/**
|
|
16
|
+
* Current route prefix
|
|
17
|
+
*/
|
|
18
|
+
static prefix = "";
|
|
19
|
+
/**
|
|
20
|
+
* Group-level middlewares
|
|
21
|
+
*/
|
|
22
|
+
static groupMiddlewares = [];
|
|
23
|
+
/**
|
|
24
|
+
* Global-level middlewares
|
|
25
|
+
*/
|
|
26
|
+
static globalMiddlewares = [];
|
|
27
|
+
/**
|
|
28
|
+
* Normalize path by removing duplicate slashes and ensuring leading slash
|
|
29
|
+
* @param path - Path to normalize
|
|
30
|
+
* @returns Normalized path
|
|
31
|
+
*/
|
|
32
|
+
static normalizePath(path) {
|
|
33
|
+
return "/" + path.split("/").filter(Boolean).join("/");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add a route with specified HTTP methods, path, handler, and middlewares
|
|
37
|
+
* @param methods - HTTP method(s) for the route
|
|
38
|
+
* @param path - Route path
|
|
39
|
+
* @param handler - Route handler function or controller reference
|
|
40
|
+
* @param middlewares - Array of middleware functions
|
|
41
|
+
*/
|
|
42
|
+
static add(methods, path, handler, middlewares) {
|
|
43
|
+
const methodArray = Array.isArray(methods) ? methods : [methods];
|
|
44
|
+
const fullPath = this.normalizePath(`${this.prefix}/${path}`);
|
|
45
|
+
this.routes.push({
|
|
46
|
+
methods: methodArray,
|
|
47
|
+
path: fullPath,
|
|
48
|
+
handler,
|
|
49
|
+
middlewares: [
|
|
50
|
+
...this.globalMiddlewares,
|
|
51
|
+
...this.groupMiddlewares,
|
|
52
|
+
...middlewares || []
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Register RESTful API resource routes for a controller with optional action filtering
|
|
58
|
+
*
|
|
59
|
+
* @param basePath - Base path for the resource
|
|
60
|
+
* @param controller - Controller object containing action methods
|
|
61
|
+
* @param options - Optional filtering options for actions
|
|
62
|
+
*/
|
|
63
|
+
static apiResource(basePath, controller, options) {
|
|
64
|
+
const actions = {
|
|
65
|
+
index: {
|
|
66
|
+
method: "get",
|
|
67
|
+
path: "/"
|
|
68
|
+
},
|
|
69
|
+
show: {
|
|
70
|
+
method: "get",
|
|
71
|
+
path: "/:id"
|
|
72
|
+
},
|
|
73
|
+
create: {
|
|
74
|
+
method: "post",
|
|
75
|
+
path: "/"
|
|
76
|
+
},
|
|
77
|
+
update: {
|
|
78
|
+
method: "put",
|
|
79
|
+
path: "/:id"
|
|
80
|
+
},
|
|
81
|
+
destroy: {
|
|
82
|
+
method: "delete",
|
|
83
|
+
path: "/:id"
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const only = options?.only || Object.keys(actions);
|
|
87
|
+
const except = options?.except || [];
|
|
88
|
+
for (const action of only) {
|
|
89
|
+
if (except.includes(action)) continue;
|
|
90
|
+
if (typeof controller[action] === "function") {
|
|
91
|
+
const { method, path } = actions[action];
|
|
92
|
+
this.add(method, `${basePath}${path}`, [controller, action]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Register a GET route
|
|
98
|
+
* @param path - Route path
|
|
99
|
+
* @param handler - Route handler
|
|
100
|
+
* @param middlewares - Middleware functions
|
|
101
|
+
*/
|
|
102
|
+
static get(path, handler, middlewares) {
|
|
103
|
+
this.add("get", path, handler, middlewares);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Register a POST route
|
|
107
|
+
* @param path - Route path
|
|
108
|
+
* @param handler - Route handler
|
|
109
|
+
* @param middlewares - Middleware functions
|
|
110
|
+
*/
|
|
111
|
+
static post(path, handler, middlewares) {
|
|
112
|
+
this.add("post", path, handler, middlewares);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Register a PUT route
|
|
116
|
+
* @param path - Route path
|
|
117
|
+
* @param handler - Route handler
|
|
118
|
+
* @param middlewares - Middleware functions
|
|
119
|
+
*/
|
|
120
|
+
static put(path, handler, middlewares) {
|
|
121
|
+
this.add("put", path, handler, middlewares);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Register a DELETE route
|
|
125
|
+
* @param path - Route path
|
|
126
|
+
* @param handler - Route handler
|
|
127
|
+
* @param middlewares - Middleware functions
|
|
128
|
+
*/
|
|
129
|
+
static delete(path, handler, middlewares) {
|
|
130
|
+
this.add("delete", path, handler, middlewares);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Register a PATCH route
|
|
134
|
+
* @param path - Route path
|
|
135
|
+
* @param handler - Route handler
|
|
136
|
+
* @param middlewares - Middleware functions
|
|
137
|
+
*/
|
|
138
|
+
static patch(path, handler, middlewares) {
|
|
139
|
+
this.add("patch", path, handler, middlewares);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Register an OPTIONS route
|
|
143
|
+
* @param path - Route path
|
|
144
|
+
* @param handler - Route handler
|
|
145
|
+
* @param middlewares - Middleware functions
|
|
146
|
+
*/
|
|
147
|
+
static options(path, handler, middlewares) {
|
|
148
|
+
this.add("options", path, handler, middlewares);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Register a HEAD route
|
|
152
|
+
* @param path - Route path
|
|
153
|
+
* @param handler - Route handler
|
|
154
|
+
* @param middlewares - Middleware functions
|
|
155
|
+
*/
|
|
156
|
+
static head(path, handler, middlewares) {
|
|
157
|
+
this.add("head", path, handler, middlewares);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Group routes with a common prefix and middlewares
|
|
161
|
+
* @param prefix - URL prefix for grouped routes
|
|
162
|
+
* @param callback - Function containing route definitions
|
|
163
|
+
* @param middlewares - Middleware functions applied to all routes in group
|
|
164
|
+
*/
|
|
165
|
+
static group(prefix, callback, middlewares) {
|
|
166
|
+
const previousPrefix = this.prefix;
|
|
167
|
+
const previousMiddlewares = this.groupMiddlewares;
|
|
168
|
+
const fullPrefix = [previousPrefix, prefix].filter(Boolean).join("/");
|
|
169
|
+
this.prefix = this.normalizePath(fullPrefix);
|
|
170
|
+
this.groupMiddlewares = [...previousMiddlewares, ...middlewares || []];
|
|
171
|
+
callback();
|
|
172
|
+
this.prefix = previousPrefix;
|
|
173
|
+
this.groupMiddlewares = previousMiddlewares;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Apply global middlewares for the duration of the callback
|
|
177
|
+
* @param middlewares - Middleware functions
|
|
178
|
+
* @param callback - Function containing route definitions
|
|
179
|
+
*/
|
|
180
|
+
static middleware(middlewares, callback) {
|
|
181
|
+
const prevMiddlewares = this.globalMiddlewares;
|
|
182
|
+
this.globalMiddlewares = [...prevMiddlewares, ...middlewares || []];
|
|
183
|
+
callback();
|
|
184
|
+
this.globalMiddlewares = prevMiddlewares;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get all registered routes with their information
|
|
188
|
+
* @returns Array of route information objects
|
|
189
|
+
*/
|
|
190
|
+
static allRoutes() {
|
|
191
|
+
return this.routes.map((route) => ({
|
|
192
|
+
methods: route.methods,
|
|
193
|
+
path: route.path,
|
|
194
|
+
middlewareCount: route.middlewares.length,
|
|
195
|
+
handlerType: typeof route.handler === "function" ? "function" : "controller"
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
static async apply(router) {
|
|
199
|
+
for (const route of this.routes) {
|
|
200
|
+
let handlerFunction = null;
|
|
201
|
+
try {
|
|
202
|
+
if (typeof route.handler === "function") handlerFunction = route.handler;
|
|
203
|
+
else if (Array.isArray(route.handler) && route.handler.length === 2) {
|
|
204
|
+
const [Controller, method] = route.handler;
|
|
205
|
+
if (typeof Controller === "function" && typeof Controller[method] === "function") handlerFunction = Controller[method].bind(Controller);
|
|
206
|
+
else if (typeof Controller === "function") {
|
|
207
|
+
const instance = new Controller();
|
|
208
|
+
if (typeof instance[method] === "function") handlerFunction = instance[method].bind(instance);
|
|
209
|
+
else throw new Error(`Method "${method}" not found in controller instance "${Controller.name}"`);
|
|
210
|
+
} else throw new Error(`Invalid controller type for route: ${route.path}`);
|
|
211
|
+
} else throw new Error(`Invalid handler format for route: ${route.path}`);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.error(`[ROUTES] Error setting up route ${route.path}:`, error.message);
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
if (!handlerFunction) continue;
|
|
217
|
+
for (const method of route.methods) {
|
|
218
|
+
if (![
|
|
219
|
+
"get",
|
|
220
|
+
"post",
|
|
221
|
+
"put",
|
|
222
|
+
"delete",
|
|
223
|
+
"patch",
|
|
224
|
+
"options",
|
|
225
|
+
"head"
|
|
226
|
+
].includes(method)) {
|
|
227
|
+
const error = /* @__PURE__ */ new Error(`Invalid HTTP method: ${method} for route: ${route.path}`);
|
|
228
|
+
console.error(`[ROUTES]`, error.message);
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
router[method](route.path, ...route.middlewares || [], async (req, res, next) => {
|
|
232
|
+
try {
|
|
233
|
+
const result = handlerFunction({
|
|
234
|
+
req,
|
|
235
|
+
res,
|
|
236
|
+
next
|
|
237
|
+
});
|
|
238
|
+
await Promise.resolve(result);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
next(error);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
//#endregion
|
|
249
|
+
module.exports = Routes;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { i as RouteInfo, n as ControllerHandler, r as HttpMethod, t as ControllerAction } from "../basic-BCxhZ1Wd.cjs";
|
|
2
|
+
import { NextFunction, Request, Response, Router } from "express";
|
|
3
|
+
|
|
4
|
+
//#region types/express.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* HTTP context passed to route handlers
|
|
7
|
+
*/
|
|
8
|
+
interface HttpContext {
|
|
9
|
+
req: Request;
|
|
10
|
+
res: Response;
|
|
11
|
+
next: NextFunction;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Route handler function type
|
|
15
|
+
*/
|
|
16
|
+
type RouteHandler = (ctx: HttpContext) => any | Promise<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Handler can be either a function or controller reference
|
|
19
|
+
*/
|
|
20
|
+
type Handler = RouteHandler | ControllerHandler;
|
|
21
|
+
/**
|
|
22
|
+
* Middleware function type
|
|
23
|
+
*/
|
|
24
|
+
type Middleware = (req: Request, res: Response, next: NextFunction) => any | Promise<any>;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/express/routes.d.ts
|
|
27
|
+
/**
|
|
28
|
+
* @class clear-router
|
|
29
|
+
* @description Laravel-style routing system for Express.js and H3 with support for CommonJS, ESM, and TypeScript
|
|
30
|
+
* @author Refkinscallv
|
|
31
|
+
* @author 3m1n3nc3
|
|
32
|
+
* @repository https://github.com/toneflix/clear-router
|
|
33
|
+
*/
|
|
34
|
+
declare class Routes {
|
|
35
|
+
/**
|
|
36
|
+
* All registered routes
|
|
37
|
+
*/
|
|
38
|
+
static routes: Array<{
|
|
39
|
+
methods: HttpMethod[];
|
|
40
|
+
path: string;
|
|
41
|
+
handler: Handler;
|
|
42
|
+
middlewares: Middleware[];
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Current route prefix
|
|
46
|
+
*/
|
|
47
|
+
static prefix: string;
|
|
48
|
+
/**
|
|
49
|
+
* Group-level middlewares
|
|
50
|
+
*/
|
|
51
|
+
static groupMiddlewares: Middleware[];
|
|
52
|
+
/**
|
|
53
|
+
* Global-level middlewares
|
|
54
|
+
*/
|
|
55
|
+
static globalMiddlewares: Middleware[];
|
|
56
|
+
/**
|
|
57
|
+
* Normalize path by removing duplicate slashes and ensuring leading slash
|
|
58
|
+
* @param path - Path to normalize
|
|
59
|
+
* @returns Normalized path
|
|
60
|
+
*/
|
|
61
|
+
static normalizePath(path: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Add a route with specified HTTP methods, path, handler, and middlewares
|
|
64
|
+
* @param methods - HTTP method(s) for the route
|
|
65
|
+
* @param path - Route path
|
|
66
|
+
* @param handler - Route handler function or controller reference
|
|
67
|
+
* @param middlewares - Array of middleware functions
|
|
68
|
+
*/
|
|
69
|
+
static add(methods: HttpMethod | HttpMethod[], path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
70
|
+
/**
|
|
71
|
+
* Register RESTful API resource routes for a controller with optional action filtering
|
|
72
|
+
*
|
|
73
|
+
* @param basePath - Base path for the resource
|
|
74
|
+
* @param controller - Controller object containing action methods
|
|
75
|
+
* @param options - Optional filtering options for actions
|
|
76
|
+
*/
|
|
77
|
+
static apiResource(basePath: string, controller: any, options?: {
|
|
78
|
+
only?: ControllerAction[];
|
|
79
|
+
except?: ControllerAction[];
|
|
80
|
+
}): void;
|
|
81
|
+
/**
|
|
82
|
+
* Register a GET route
|
|
83
|
+
* @param path - Route path
|
|
84
|
+
* @param handler - Route handler
|
|
85
|
+
* @param middlewares - Middleware functions
|
|
86
|
+
*/
|
|
87
|
+
static get(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
88
|
+
/**
|
|
89
|
+
* Register a POST route
|
|
90
|
+
* @param path - Route path
|
|
91
|
+
* @param handler - Route handler
|
|
92
|
+
* @param middlewares - Middleware functions
|
|
93
|
+
*/
|
|
94
|
+
static post(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
95
|
+
/**
|
|
96
|
+
* Register a PUT route
|
|
97
|
+
* @param path - Route path
|
|
98
|
+
* @param handler - Route handler
|
|
99
|
+
* @param middlewares - Middleware functions
|
|
100
|
+
*/
|
|
101
|
+
static put(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
102
|
+
/**
|
|
103
|
+
* Register a DELETE route
|
|
104
|
+
* @param path - Route path
|
|
105
|
+
* @param handler - Route handler
|
|
106
|
+
* @param middlewares - Middleware functions
|
|
107
|
+
*/
|
|
108
|
+
static delete(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
109
|
+
/**
|
|
110
|
+
* Register a PATCH route
|
|
111
|
+
* @param path - Route path
|
|
112
|
+
* @param handler - Route handler
|
|
113
|
+
* @param middlewares - Middleware functions
|
|
114
|
+
*/
|
|
115
|
+
static patch(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
116
|
+
/**
|
|
117
|
+
* Register an OPTIONS route
|
|
118
|
+
* @param path - Route path
|
|
119
|
+
* @param handler - Route handler
|
|
120
|
+
* @param middlewares - Middleware functions
|
|
121
|
+
*/
|
|
122
|
+
static options(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
123
|
+
/**
|
|
124
|
+
* Register a HEAD route
|
|
125
|
+
* @param path - Route path
|
|
126
|
+
* @param handler - Route handler
|
|
127
|
+
* @param middlewares - Middleware functions
|
|
128
|
+
*/
|
|
129
|
+
static head(path: string, handler: Handler, middlewares?: Middleware[]): void;
|
|
130
|
+
/**
|
|
131
|
+
* Group routes with a common prefix and middlewares
|
|
132
|
+
* @param prefix - URL prefix for grouped routes
|
|
133
|
+
* @param callback - Function containing route definitions
|
|
134
|
+
* @param middlewares - Middleware functions applied to all routes in group
|
|
135
|
+
*/
|
|
136
|
+
static group(prefix: string, callback: () => void, middlewares?: Middleware[]): void;
|
|
137
|
+
/**
|
|
138
|
+
* Apply global middlewares for the duration of the callback
|
|
139
|
+
* @param middlewares - Middleware functions
|
|
140
|
+
* @param callback - Function containing route definitions
|
|
141
|
+
*/
|
|
142
|
+
static middleware(middlewares: Middleware[], callback: () => void): void;
|
|
143
|
+
/**
|
|
144
|
+
* Get all registered routes with their information
|
|
145
|
+
* @returns Array of route information objects
|
|
146
|
+
*/
|
|
147
|
+
static allRoutes(): RouteInfo[];
|
|
148
|
+
/**
|
|
149
|
+
* Apply all registered routes to the provided Express Router instance
|
|
150
|
+
* Handles controller-method binding and middleware application
|
|
151
|
+
* All errors are thrown to Express error handling middleware
|
|
152
|
+
*
|
|
153
|
+
* @param router - Express Router instance
|
|
154
|
+
*/
|
|
155
|
+
static apply(router: Router): void;
|
|
156
|
+
static apply(router: Router): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
export = Routes;
|