bxo 0.0.5-dev.7 → 0.0.5-dev.9

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.
Files changed (2) hide show
  1. package/index.ts +58 -6
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -31,6 +31,7 @@ export type Context<TConfig extends RouteConfig = {}> = {
31
31
  query: TConfig['query'] extends z.ZodSchema<any> ? InferZodType<TConfig['query']> : Record<string, string | undefined>;
32
32
  body: TConfig['body'] extends z.ZodSchema<any> ? InferZodType<TConfig['body']> : unknown;
33
33
  headers: TConfig['headers'] extends z.ZodSchema<any> ? InferZodType<TConfig['headers']> : Record<string, string>;
34
+ path: string;
34
35
  request: Request;
35
36
  set: {
36
37
  status?: number;
@@ -251,16 +252,38 @@ export default class BXO {
251
252
  const routeSegments = route.path.split('/').filter(Boolean);
252
253
  const pathSegments = pathname.split('/').filter(Boolean);
253
254
 
254
- if (routeSegments.length !== pathSegments.length) continue;
255
-
256
255
  const params: Record<string, string> = {};
257
256
  let isMatch = true;
258
257
 
258
+ // Handle wildcard at the end (catch-all)
259
+ const hasWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '*';
260
+
261
+ if (hasWildcardAtEnd) {
262
+ // For catch-all wildcard, path must have at least as many segments as route (minus the wildcard)
263
+ if (pathSegments.length < routeSegments.length - 1) continue;
264
+ } else {
265
+ // For exact matching (with possible single-segment wildcards), lengths must match
266
+ if (routeSegments.length !== pathSegments.length) continue;
267
+ }
268
+
259
269
  for (let i = 0; i < routeSegments.length; i++) {
260
270
  const routeSegment = routeSegments[i];
261
271
  const pathSegment = pathSegments[i];
262
272
 
263
- if (!routeSegment || !pathSegment) {
273
+ if (!routeSegment) {
274
+ isMatch = false;
275
+ break;
276
+ }
277
+
278
+ // Handle catch-all wildcard at the end
279
+ if (routeSegment === '*' && i === routeSegments.length - 1) {
280
+ // Wildcard at end matches remaining path segments
281
+ const remainingPath = pathSegments.slice(i).join('/');
282
+ params['*'] = remainingPath;
283
+ break;
284
+ }
285
+
286
+ if (!pathSegment) {
264
287
  isMatch = false;
265
288
  break;
266
289
  }
@@ -268,6 +291,9 @@ export default class BXO {
268
291
  if (routeSegment.startsWith(':')) {
269
292
  const paramName = routeSegment.slice(1);
270
293
  params[paramName] = decodeURIComponent(pathSegment);
294
+ } else if (routeSegment === '*') {
295
+ // Single segment wildcard
296
+ params['*'] = decodeURIComponent(pathSegment);
271
297
  } else if (routeSegment !== pathSegment) {
272
298
  isMatch = false;
273
299
  break;
@@ -288,16 +314,38 @@ export default class BXO {
288
314
  const routeSegments = route.path.split('/').filter(Boolean);
289
315
  const pathSegments = pathname.split('/').filter(Boolean);
290
316
 
291
- if (routeSegments.length !== pathSegments.length) continue;
292
-
293
317
  const params: Record<string, string> = {};
294
318
  let isMatch = true;
295
319
 
320
+ // Handle wildcard at the end (catch-all)
321
+ const hasWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '*';
322
+
323
+ if (hasWildcardAtEnd) {
324
+ // For catch-all wildcard, path must have at least as many segments as route (minus the wildcard)
325
+ if (pathSegments.length < routeSegments.length - 1) continue;
326
+ } else {
327
+ // For exact matching (with possible single-segment wildcards), lengths must match
328
+ if (routeSegments.length !== pathSegments.length) continue;
329
+ }
330
+
296
331
  for (let i = 0; i < routeSegments.length; i++) {
297
332
  const routeSegment = routeSegments[i];
298
333
  const pathSegment = pathSegments[i];
299
334
 
300
- if (!routeSegment || !pathSegment) {
335
+ if (!routeSegment) {
336
+ isMatch = false;
337
+ break;
338
+ }
339
+
340
+ // Handle catch-all wildcard at the end
341
+ if (routeSegment === '*' && i === routeSegments.length - 1) {
342
+ // Wildcard at end matches remaining path segments
343
+ const remainingPath = pathSegments.slice(i).join('/');
344
+ params['*'] = remainingPath;
345
+ break;
346
+ }
347
+
348
+ if (!pathSegment) {
301
349
  isMatch = false;
302
350
  break;
303
351
  }
@@ -305,6 +353,9 @@ export default class BXO {
305
353
  if (routeSegment.startsWith(':')) {
306
354
  const paramName = routeSegment.slice(1);
307
355
  params[paramName] = decodeURIComponent(pathSegment);
356
+ } else if (routeSegment === '*') {
357
+ // Single segment wildcard
358
+ params['*'] = decodeURIComponent(pathSegment);
308
359
  } else if (routeSegment !== pathSegment) {
309
360
  isMatch = false;
310
361
  break;
@@ -400,6 +451,7 @@ export default class BXO {
400
451
  query: route.config?.query ? this.validateData(route.config.query, query) : query,
401
452
  body: route.config?.body ? this.validateData(route.config.body, body) : body,
402
453
  headers: route.config?.headers ? this.validateData(route.config.headers, headers) : headers,
454
+ path: pathname,
403
455
  request,
404
456
  set: {}
405
457
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bxo",
3
3
  "module": "index.ts",
4
- "version": "0.0.5-dev.7",
4
+ "version": "0.0.5-dev.9",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "devDependencies": {