@stacksjs/bun-router 0.0.6 → 0.0.8
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/cli.js +1 -1
- package/dist/index.js +72 -22
- package/dist/router/index.d.ts +1 -0
- package/dist/router/router.d.ts +18 -0
- package/dist/types.d.ts +6 -0
- package/package.json +1 -1
- package/src/router/index.ts +3 -1
- package/src/router/router.ts +79 -6
- package/src/router/server.ts +45 -22
- package/src/types.ts +6 -0
package/dist/cli.js
CHANGED
|
@@ -1879,7 +1879,7 @@ var prefix = getPrefix();
|
|
|
1879
1879
|
var color18 = __toESM(require_picocolors(), 1);
|
|
1880
1880
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
1881
1881
|
// package.json
|
|
1882
|
-
var version = "0.0.
|
|
1882
|
+
var version = "0.0.8";
|
|
1883
1883
|
|
|
1884
1884
|
// src/cli/middleware.ts
|
|
1885
1885
|
import fs from "fs/promises";
|
package/dist/index.js
CHANGED
|
@@ -8847,7 +8847,12 @@ class Router {
|
|
|
8847
8847
|
const allowedMethods = this.getAllowedMethods(url2.pathname, hostname);
|
|
8848
8848
|
if (allowedMethods.length > 0) {
|
|
8849
8849
|
const methodNotAllowedHandler = async (_req, _next) => {
|
|
8850
|
-
return new Response(JSON.stringify({
|
|
8850
|
+
return new Response(JSON.stringify({
|
|
8851
|
+
error: "Method Not Allowed",
|
|
8852
|
+
path: url2.pathname,
|
|
8853
|
+
method: req.method,
|
|
8854
|
+
allowed: allowedMethods
|
|
8855
|
+
}), {
|
|
8851
8856
|
status: 405,
|
|
8852
8857
|
headers: {
|
|
8853
8858
|
"Content-Type": "application/json",
|
|
@@ -8869,7 +8874,11 @@ class Router {
|
|
|
8869
8874
|
if (this.fallbackHandler) {
|
|
8870
8875
|
return await this.resolveHandler(this.fallbackHandler, enhancedReq);
|
|
8871
8876
|
}
|
|
8872
|
-
return new Response(JSON.stringify({
|
|
8877
|
+
return new Response(JSON.stringify({
|
|
8878
|
+
error: "Not Found",
|
|
8879
|
+
path: url2.pathname,
|
|
8880
|
+
method: req.method
|
|
8881
|
+
}), {
|
|
8873
8882
|
status: 404,
|
|
8874
8883
|
headers: { "Content-Type": "application/json" }
|
|
8875
8884
|
});
|
|
@@ -8884,7 +8893,11 @@ class Router {
|
|
|
8884
8893
|
const response2 = await this.resolveHandler(this.fallbackHandler, enhancedReq);
|
|
8885
8894
|
return this.applyModifiedCookies(response2, enhancedReq);
|
|
8886
8895
|
}
|
|
8887
|
-
return new Response(JSON.stringify({
|
|
8896
|
+
return new Response(JSON.stringify({
|
|
8897
|
+
error: "Not Found",
|
|
8898
|
+
path: url2.pathname,
|
|
8899
|
+
method: req.method
|
|
8900
|
+
}), {
|
|
8888
8901
|
status: 404,
|
|
8889
8902
|
headers: { "Content-Type": "application/json" }
|
|
8890
8903
|
});
|
|
@@ -9263,6 +9276,10 @@ class Router {
|
|
|
9263
9276
|
enhancedReq.header = (name) => {
|
|
9264
9277
|
return req.headers.get(name) || req.headers.get(name.toLowerCase()) || null;
|
|
9265
9278
|
};
|
|
9279
|
+
enhancedReq.cookie = (name, defaultValue) => {
|
|
9280
|
+
const value = getCookies()[name];
|
|
9281
|
+
return value !== undefined ? value : defaultValue ?? null;
|
|
9282
|
+
};
|
|
9266
9283
|
enhancedReq.getParam = (name, defaultValue) => {
|
|
9267
9284
|
const value = params?.[name];
|
|
9268
9285
|
return value !== undefined ? value : defaultValue;
|
|
@@ -9517,6 +9534,17 @@ class RouteGroupBuilder2 {
|
|
|
9517
9534
|
return this;
|
|
9518
9535
|
}
|
|
9519
9536
|
}
|
|
9537
|
+
var _enhancementHost = null;
|
|
9538
|
+
function getEnhancementHost() {
|
|
9539
|
+
if (_enhancementHost === null)
|
|
9540
|
+
_enhancementHost = new Router;
|
|
9541
|
+
return _enhancementHost;
|
|
9542
|
+
}
|
|
9543
|
+
function applyRequestEnhancements(req, params = {}) {
|
|
9544
|
+
if (typeof req.bearerToken === "function")
|
|
9545
|
+
return req;
|
|
9546
|
+
return getEnhancementHost().enhanceRequest(req, params);
|
|
9547
|
+
}
|
|
9520
9548
|
|
|
9521
9549
|
// src/router/server.ts
|
|
9522
9550
|
function registerServerHandling(RouterClass) {
|
|
@@ -9637,31 +9665,52 @@ function registerServerHandling(RouterClass) {
|
|
|
9637
9665
|
return new Response("No response from middleware chain", { status: 500 });
|
|
9638
9666
|
}
|
|
9639
9667
|
const allowedMethods = this.getAllowedMethods(url2.pathname, hostname);
|
|
9668
|
+
const corsHeaders = {
|
|
9669
|
+
"Content-Type": "application/json",
|
|
9670
|
+
"Access-Control-Allow-Origin": "*",
|
|
9671
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
9672
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, Accept, Origin"
|
|
9673
|
+
};
|
|
9640
9674
|
if (allowedMethods.length > 0) {
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9675
|
+
const methodNotAllowedHandler = async (_req, _next) => {
|
|
9676
|
+
return new Response(JSON.stringify({
|
|
9677
|
+
success: false,
|
|
9678
|
+
message: "Method Not Allowed",
|
|
9679
|
+
path: url2.pathname,
|
|
9680
|
+
method: req.method,
|
|
9681
|
+
allowed: allowedMethods
|
|
9682
|
+
}), {
|
|
9683
|
+
status: 405,
|
|
9684
|
+
headers: { ...corsHeaders, Allow: allowedMethods.join(", ") }
|
|
9685
|
+
});
|
|
9686
|
+
};
|
|
9687
|
+
if (this.globalMiddleware.length > 0) {
|
|
9688
|
+
const stack = [...this.globalMiddleware, methodNotAllowedHandler];
|
|
9689
|
+
const response2 = await this.runMiddleware(enhancedReq, stack);
|
|
9690
|
+
if (response2)
|
|
9691
|
+
return this.applyModifiedCookies(response2, enhancedReq);
|
|
9692
|
+
}
|
|
9693
|
+
return await methodNotAllowedHandler(enhancedReq, async () => null);
|
|
9651
9694
|
}
|
|
9652
9695
|
if (this.fallbackHandler) {
|
|
9653
9696
|
const response2 = await this.resolveHandler(this.fallbackHandler, enhancedReq);
|
|
9654
9697
|
return this.applyModifiedCookies(response2, enhancedReq);
|
|
9655
9698
|
}
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
9699
|
+
const notFoundHandler = async (_req, _next) => {
|
|
9700
|
+
return new Response(JSON.stringify({
|
|
9701
|
+
success: false,
|
|
9702
|
+
message: "Not Found",
|
|
9703
|
+
path: url2.pathname,
|
|
9704
|
+
method: req.method
|
|
9705
|
+
}), { status: 404, headers: corsHeaders });
|
|
9706
|
+
};
|
|
9707
|
+
if (this.globalMiddleware.length > 0) {
|
|
9708
|
+
const stack = [...this.globalMiddleware, notFoundHandler];
|
|
9709
|
+
const response2 = await this.runMiddleware(enhancedReq, stack);
|
|
9710
|
+
if (response2)
|
|
9711
|
+
return this.applyModifiedCookies(response2, enhancedReq);
|
|
9712
|
+
}
|
|
9713
|
+
return await notFoundHandler(enhancedReq, async () => null);
|
|
9665
9714
|
} catch (error) {
|
|
9666
9715
|
console.error("Error handling request:", error);
|
|
9667
9716
|
if (this.errorHandler) {
|
|
@@ -13781,6 +13830,7 @@ export {
|
|
|
13781
13830
|
authMocks,
|
|
13782
13831
|
authHelpers,
|
|
13783
13832
|
auth,
|
|
13833
|
+
applyRequestEnhancements,
|
|
13784
13834
|
apiKeyAuth,
|
|
13785
13835
|
WebSocketTester,
|
|
13786
13836
|
ValidationMiddlewareBuilder,
|
package/dist/router/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { FluentRouteBuilder, FluentRouter, RouteFactory, router, RouterUtils } f
|
|
|
4
4
|
import { Router } from './router';
|
|
5
5
|
import '../types';
|
|
6
6
|
export { Router };
|
|
7
|
+
export { applyRequestEnhancements } from './router';
|
|
7
8
|
declare module './router' {
|
|
8
9
|
interface Router {
|
|
9
10
|
stream: (callback: () => Generator<string | Uint8Array, void, unknown> | AsyncGenerator<string | Uint8Array, void, unknown>, status?: number, headers?: Record<string, string>) => Response;
|
package/dist/router/router.d.ts
CHANGED
|
@@ -274,3 +274,21 @@ export declare class RouteGroupBuilder {
|
|
|
274
274
|
put(_path: string, _handler: RouteHandler): this;
|
|
275
275
|
delete(_path: string, _handler: RouteHandler): this;
|
|
276
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Attach bun-router's request macros (`bearerToken`, `getParam`, `cookie`,
|
|
279
|
+
* `cookies`, `header`, `params`, plus the Laravel-style input helpers
|
|
280
|
+
* `get`, `input`, `string`, `integer`, `float`, `boolean`, `array`, `has`,
|
|
281
|
+
* `filled`, etc.) to a request.
|
|
282
|
+
*
|
|
283
|
+
* Idempotent: calling on an already-enhanced request returns it unchanged.
|
|
284
|
+
* We sniff `req.bearerToken` as the marker — cheap and reliable since no
|
|
285
|
+
* native Request has it.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* import { applyRequestEnhancements } from '@stacksjs/bun-router'
|
|
289
|
+
*
|
|
290
|
+
* const enhanced = applyRequestEnhancements(req, { id: '42' })
|
|
291
|
+
* enhanced.bearerToken() // → string | null
|
|
292
|
+
* enhanced.getParam('id') // → '42'
|
|
293
|
+
*/
|
|
294
|
+
export declare function applyRequestEnhancements(req: Request | EnhancedRequest, params?: Record<string, string>): EnhancedRequest;
|
package/dist/types.d.ts
CHANGED
|
@@ -688,6 +688,12 @@ export interface EnhancedRequest extends Request, Omit<RequestMacroMethods, 'ip'
|
|
|
688
688
|
* Route parameters extracted from the URL
|
|
689
689
|
*/
|
|
690
690
|
params: Record<string, string>;
|
|
691
|
+
/**
|
|
692
|
+
* Lookup a single route param. Equivalent to `request.params[name]` but
|
|
693
|
+
* with optional default-value handling, matching the Laravel-style
|
|
694
|
+
* `$request->route('name')` ergonomics.
|
|
695
|
+
*/
|
|
696
|
+
getParam: <T = string>(name: string, defaultValue?: T) => T | undefined;
|
|
691
697
|
/**
|
|
692
698
|
* Query parameters from the URL
|
|
693
699
|
*/
|
package/package.json
CHANGED
package/src/router/index.ts
CHANGED
|
@@ -33,8 +33,10 @@ registerModelBinding(Router)
|
|
|
33
33
|
registerFileBasedRouting(Router)
|
|
34
34
|
registerApiRoutes(Router)
|
|
35
35
|
|
|
36
|
-
// Export the Router class
|
|
36
|
+
// Export the Router class, the standalone request-enhancement helper, and
|
|
37
|
+
// fluent routing features.
|
|
37
38
|
export { Router }
|
|
39
|
+
export { applyRequestEnhancements } from './router'
|
|
38
40
|
|
|
39
41
|
// Type augmentation for Laravel-style methods
|
|
40
42
|
declare module './router' {
|
package/src/router/router.ts
CHANGED
|
@@ -611,13 +611,21 @@ export class Router {
|
|
|
611
611
|
return new Response('No response from middleware chain', { status: 500 })
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
-
// No route found - check if the path exists with a different method (405 vs 404)
|
|
614
|
+
// No route found - check if the path exists with a different method (405 vs 404).
|
|
615
|
+
// 404/405 bodies now include path + method so client-side debugging (typo'd
|
|
616
|
+
// endpoint, stale SPA cache, missing route registration) is one grep away.
|
|
617
|
+
// Both responses still flow through globalMiddleware so user middleware
|
|
618
|
+
// (X-Request-ID, audit, custom CORS) sees them.
|
|
615
619
|
const allowedMethods = this.getAllowedMethods(url.pathname, hostname)
|
|
616
620
|
|
|
617
|
-
// If there are allowed methods, return 405 Method Not Allowed
|
|
618
621
|
if (allowedMethods.length > 0) {
|
|
619
622
|
const methodNotAllowedHandler = async (_req: EnhancedRequest, _next: NextFunction) => {
|
|
620
|
-
return new Response(JSON.stringify({
|
|
623
|
+
return new Response(JSON.stringify({
|
|
624
|
+
error: 'Method Not Allowed',
|
|
625
|
+
path: url.pathname,
|
|
626
|
+
method: req.method,
|
|
627
|
+
allowed: allowedMethods,
|
|
628
|
+
}), {
|
|
621
629
|
status: 405,
|
|
622
630
|
headers: {
|
|
623
631
|
'Content-Type': 'application/json',
|
|
@@ -643,7 +651,11 @@ export class Router {
|
|
|
643
651
|
if (this.fallbackHandler) {
|
|
644
652
|
return await this.resolveHandler(this.fallbackHandler, enhancedReq)
|
|
645
653
|
}
|
|
646
|
-
return new Response(JSON.stringify({
|
|
654
|
+
return new Response(JSON.stringify({
|
|
655
|
+
error: 'Not Found',
|
|
656
|
+
path: url.pathname,
|
|
657
|
+
method: req.method,
|
|
658
|
+
}), {
|
|
647
659
|
status: 404,
|
|
648
660
|
headers: { 'Content-Type': 'application/json' },
|
|
649
661
|
})
|
|
@@ -661,8 +673,12 @@ export class Router {
|
|
|
661
673
|
return this.applyModifiedCookies(response, enhancedReq)
|
|
662
674
|
}
|
|
663
675
|
|
|
664
|
-
// No fallback handler, return a 404
|
|
665
|
-
return new Response(JSON.stringify({
|
|
676
|
+
// No fallback handler, return a 404 with path context
|
|
677
|
+
return new Response(JSON.stringify({
|
|
678
|
+
error: 'Not Found',
|
|
679
|
+
path: url.pathname,
|
|
680
|
+
method: req.method,
|
|
681
|
+
}), {
|
|
666
682
|
status: 404,
|
|
667
683
|
headers: { 'Content-Type': 'application/json' },
|
|
668
684
|
})
|
|
@@ -1131,6 +1147,15 @@ export class Router {
|
|
|
1131
1147
|
return req.headers.get(name) || req.headers.get(name.toLowerCase()) || null
|
|
1132
1148
|
}
|
|
1133
1149
|
|
|
1150
|
+
// Convenience cookie reader. The full `enhancedReq.cookies.get(name)` API
|
|
1151
|
+
// is also available below — `cookie(name)` is the shorter form callers
|
|
1152
|
+
// (and the Laravel-style macros) reach for first, so it deserves a
|
|
1153
|
+
// direct method on the enhanced request, not just on the macros class.
|
|
1154
|
+
;(enhancedReq as any).cookie = (name: string, defaultValue?: string): string | null => {
|
|
1155
|
+
const value = getCookies()[name]
|
|
1156
|
+
return value !== undefined ? value : (defaultValue ?? null)
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1134
1159
|
;(enhancedReq as any).getParam = <T = string>(name: string, defaultValue?: T): T | undefined => {
|
|
1135
1160
|
const value = params?.[name] as T | undefined
|
|
1136
1161
|
return value !== undefined ? value : defaultValue
|
|
@@ -1506,3 +1531,51 @@ export class RouteGroupBuilder {
|
|
|
1506
1531
|
return this
|
|
1507
1532
|
}
|
|
1508
1533
|
}
|
|
1534
|
+
|
|
1535
|
+
// ---------------------------------------------------------------------------
|
|
1536
|
+
// Standalone enhancement helper
|
|
1537
|
+
// ---------------------------------------------------------------------------
|
|
1538
|
+
|
|
1539
|
+
// Singleton scratch Router used to expose `enhanceRequest` as a standalone
|
|
1540
|
+
// function. Downstream consumers (frameworks layered on bun-router) often
|
|
1541
|
+
// need to attach the request macros to a request that was created outside
|
|
1542
|
+
// of `route.serve()` — for instance, when a higher-level router wraps
|
|
1543
|
+
// each handler with its own middleware chain. Without an exported function,
|
|
1544
|
+
// those consumers either spin up their own `new Router()` per call or
|
|
1545
|
+
// duplicate the attachment logic in user code.
|
|
1546
|
+
//
|
|
1547
|
+
// We share one instance because `enhanceRequest` does not depend on any
|
|
1548
|
+
// per-router state (route table, middleware groups, etc.) — it only reads
|
|
1549
|
+
// from the request and the supplied params.
|
|
1550
|
+
let _enhancementHost: Router | null = null
|
|
1551
|
+
|
|
1552
|
+
function getEnhancementHost(): Router {
|
|
1553
|
+
if (_enhancementHost === null) _enhancementHost = new Router()
|
|
1554
|
+
return _enhancementHost
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* Attach bun-router's request macros (`bearerToken`, `getParam`, `cookie`,
|
|
1559
|
+
* `cookies`, `header`, `params`, plus the Laravel-style input helpers
|
|
1560
|
+
* `get`, `input`, `string`, `integer`, `float`, `boolean`, `array`, `has`,
|
|
1561
|
+
* `filled`, etc.) to a request.
|
|
1562
|
+
*
|
|
1563
|
+
* Idempotent: calling on an already-enhanced request returns it unchanged.
|
|
1564
|
+
* We sniff `req.bearerToken` as the marker — cheap and reliable since no
|
|
1565
|
+
* native Request has it.
|
|
1566
|
+
*
|
|
1567
|
+
* @example
|
|
1568
|
+
* import { applyRequestEnhancements } from '@stacksjs/bun-router'
|
|
1569
|
+
*
|
|
1570
|
+
* const enhanced = applyRequestEnhancements(req, { id: '42' })
|
|
1571
|
+
* enhanced.bearerToken() // → string | null
|
|
1572
|
+
* enhanced.getParam('id') // → '42'
|
|
1573
|
+
*/
|
|
1574
|
+
export function applyRequestEnhancements(
|
|
1575
|
+
req: Request | EnhancedRequest,
|
|
1576
|
+
params: Record<string, string> = {},
|
|
1577
|
+
): EnhancedRequest {
|
|
1578
|
+
if (typeof (req as any).bearerToken === 'function')
|
|
1579
|
+
return req as EnhancedRequest
|
|
1580
|
+
return getEnhancementHost().enhanceRequest(req as Request, params)
|
|
1581
|
+
}
|
package/src/router/server.ts
CHANGED
|
@@ -195,21 +195,38 @@ export function registerServerHandling(RouterClass: typeof Router): void {
|
|
|
195
195
|
return new Response('No response from middleware chain', { status: 500 })
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
// No route found - check if the path exists with a different method (405 vs 404)
|
|
198
|
+
// No route found - check if the path exists with a different method (405 vs 404).
|
|
199
|
+
// The 404/405 responses below now (a) include path + method in the body so client
|
|
200
|
+
// debugging is one grep away, and (b) flow through globalMiddleware so cross-cutting
|
|
201
|
+
// concerns (X-Request-ID, Server-Timing, audit logging, custom CORS) can observe
|
|
202
|
+
// them. Previously these paths short-circuited entirely.
|
|
199
203
|
const allowedMethods = this.getAllowedMethods(url.pathname, hostname)
|
|
204
|
+
const corsHeaders = {
|
|
205
|
+
'Content-Type': 'application/json',
|
|
206
|
+
'Access-Control-Allow-Origin': '*',
|
|
207
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
208
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, Accept, Origin',
|
|
209
|
+
}
|
|
200
210
|
|
|
201
|
-
// If there are allowed methods, return 405 Method Not Allowed
|
|
202
211
|
if (allowedMethods.length > 0) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
212
|
+
const methodNotAllowedHandler = async (_req: EnhancedRequest, _next: any) => {
|
|
213
|
+
return new Response(JSON.stringify({
|
|
214
|
+
success: false,
|
|
215
|
+
message: 'Method Not Allowed',
|
|
216
|
+
path: url.pathname,
|
|
217
|
+
method: req.method,
|
|
218
|
+
allowed: allowedMethods,
|
|
219
|
+
}), {
|
|
220
|
+
status: 405,
|
|
221
|
+
headers: { ...corsHeaders, Allow: allowedMethods.join(', ') },
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
if (this.globalMiddleware.length > 0) {
|
|
225
|
+
const stack = [...this.globalMiddleware, methodNotAllowedHandler]
|
|
226
|
+
const response = await this.runMiddleware(enhancedReq, stack)
|
|
227
|
+
if (response) return this.applyModifiedCookies(response, enhancedReq)
|
|
228
|
+
}
|
|
229
|
+
return await methodNotAllowedHandler(enhancedReq, async () => null as any)
|
|
213
230
|
}
|
|
214
231
|
|
|
215
232
|
// No route found, try the fallback handler
|
|
@@ -218,16 +235,22 @@ export function registerServerHandling(RouterClass: typeof Router): void {
|
|
|
218
235
|
return this.applyModifiedCookies(response, enhancedReq)
|
|
219
236
|
}
|
|
220
237
|
|
|
221
|
-
// No fallback
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
},
|
|
230
|
-
}
|
|
238
|
+
// No fallback — emit a 404 enriched with path + method, also through
|
|
239
|
+
// globalMiddleware so user middleware sees it.
|
|
240
|
+
const notFoundHandler = async (_req: EnhancedRequest, _next: any) => {
|
|
241
|
+
return new Response(JSON.stringify({
|
|
242
|
+
success: false,
|
|
243
|
+
message: 'Not Found',
|
|
244
|
+
path: url.pathname,
|
|
245
|
+
method: req.method,
|
|
246
|
+
}), { status: 404, headers: corsHeaders })
|
|
247
|
+
}
|
|
248
|
+
if (this.globalMiddleware.length > 0) {
|
|
249
|
+
const stack = [...this.globalMiddleware, notFoundHandler]
|
|
250
|
+
const response = await this.runMiddleware(enhancedReq, stack)
|
|
251
|
+
if (response) return this.applyModifiedCookies(response, enhancedReq)
|
|
252
|
+
}
|
|
253
|
+
return await notFoundHandler(enhancedReq, async () => null as any)
|
|
231
254
|
}
|
|
232
255
|
catch (error) {
|
|
233
256
|
console.error('Error handling request:', error)
|
package/src/types.ts
CHANGED
|
@@ -793,6 +793,12 @@ export interface EnhancedRequest extends Request, Omit<RequestMacroMethods, 'ip'
|
|
|
793
793
|
* Route parameters extracted from the URL
|
|
794
794
|
*/
|
|
795
795
|
params: Record<string, string>
|
|
796
|
+
/**
|
|
797
|
+
* Lookup a single route param. Equivalent to `request.params[name]` but
|
|
798
|
+
* with optional default-value handling, matching the Laravel-style
|
|
799
|
+
* `$request->route('name')` ergonomics.
|
|
800
|
+
*/
|
|
801
|
+
getParam: <T = string>(name: string, defaultValue?: T) => T | undefined
|
|
796
802
|
/**
|
|
797
803
|
* Query parameters from the URL
|
|
798
804
|
*/
|