@stacksjs/bun-router 0.0.6 → 0.0.7

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 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.6";
1882
+ var version = "0.0.7";
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({ error: "Method Not Allowed" }), {
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({ error: "Not Found" }), {
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({ error: "Not Found" }), {
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
  });
@@ -9637,31 +9650,52 @@ function registerServerHandling(RouterClass) {
9637
9650
  return new Response("No response from middleware chain", { status: 500 });
9638
9651
  }
9639
9652
  const allowedMethods = this.getAllowedMethods(url2.pathname, hostname);
9653
+ const corsHeaders = {
9654
+ "Content-Type": "application/json",
9655
+ "Access-Control-Allow-Origin": "*",
9656
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
9657
+ "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, Accept, Origin"
9658
+ };
9640
9659
  if (allowedMethods.length > 0) {
9641
- return new Response(JSON.stringify({ success: false, message: "Method Not Allowed" }), {
9642
- status: 405,
9643
- headers: {
9644
- "Content-Type": "application/json",
9645
- Allow: allowedMethods.join(", "),
9646
- "Access-Control-Allow-Origin": "*",
9647
- "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
9648
- "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, Accept, Origin"
9649
- }
9650
- });
9660
+ const methodNotAllowedHandler = async (_req, _next) => {
9661
+ return new Response(JSON.stringify({
9662
+ success: false,
9663
+ message: "Method Not Allowed",
9664
+ path: url2.pathname,
9665
+ method: req.method,
9666
+ allowed: allowedMethods
9667
+ }), {
9668
+ status: 405,
9669
+ headers: { ...corsHeaders, Allow: allowedMethods.join(", ") }
9670
+ });
9671
+ };
9672
+ if (this.globalMiddleware.length > 0) {
9673
+ const stack = [...this.globalMiddleware, methodNotAllowedHandler];
9674
+ const response2 = await this.runMiddleware(enhancedReq, stack);
9675
+ if (response2)
9676
+ return this.applyModifiedCookies(response2, enhancedReq);
9677
+ }
9678
+ return await methodNotAllowedHandler(enhancedReq, async () => null);
9651
9679
  }
9652
9680
  if (this.fallbackHandler) {
9653
9681
  const response2 = await this.resolveHandler(this.fallbackHandler, enhancedReq);
9654
9682
  return this.applyModifiedCookies(response2, enhancedReq);
9655
9683
  }
9656
- return new Response(JSON.stringify({ success: false, message: "Not Found" }), {
9657
- status: 404,
9658
- headers: {
9659
- "Content-Type": "application/json",
9660
- "Access-Control-Allow-Origin": "*",
9661
- "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
9662
- "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With, Accept, Origin"
9663
- }
9664
- });
9684
+ const notFoundHandler = async (_req, _next) => {
9685
+ return new Response(JSON.stringify({
9686
+ success: false,
9687
+ message: "Not Found",
9688
+ path: url2.pathname,
9689
+ method: req.method
9690
+ }), { status: 404, headers: corsHeaders });
9691
+ };
9692
+ if (this.globalMiddleware.length > 0) {
9693
+ const stack = [...this.globalMiddleware, notFoundHandler];
9694
+ const response2 = await this.runMiddleware(enhancedReq, stack);
9695
+ if (response2)
9696
+ return this.applyModifiedCookies(response2, enhancedReq);
9697
+ }
9698
+ return await notFoundHandler(enhancedReq, async () => null);
9665
9699
  } catch (error) {
9666
9700
  console.error("Error handling request:", error);
9667
9701
  if (this.errorHandler) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/bun-router",
3
3
  "type": "module",
4
- "version": "0.0.6",
4
+ "version": "0.0.7",
5
5
  "description": "A fast, type-safe router for Bun.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",
@@ -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({ error: 'Method Not Allowed' }), {
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({ error: 'Not Found' }), {
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({ error: 'Not Found' }), {
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
  })
@@ -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
- return new Response(JSON.stringify({ success: false, message: 'Method Not Allowed' }), {
204
- status: 405,
205
- headers: {
206
- 'Content-Type': 'application/json',
207
- 'Allow': allowedMethods.join(', '),
208
- 'Access-Control-Allow-Origin': '*',
209
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
210
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, Accept, Origin',
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 handler, return a 404 with CORS headers
222
- return new Response(JSON.stringify({ success: false, message: 'Not Found' }), {
223
- status: 404,
224
- headers: {
225
- 'Content-Type': 'application/json',
226
- 'Access-Control-Allow-Origin': '*',
227
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
228
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, Accept, Origin',
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)