bxo 0.0.5-dev.35 → 0.0.5-dev.37

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 (3) hide show
  1. package/index.ts +166 -10
  2. package/package.json +2 -2
  3. package/example.ts +0 -33
package/index.ts CHANGED
@@ -319,13 +319,22 @@ export default class BXO {
319
319
  const params: Record<string, string> = {};
320
320
  let isMatch = true;
321
321
 
322
- // Handle wildcard at the end (catch-all)
322
+ // Check for double wildcard (**) in the route
323
+ const hasDoubleWildcard = routeSegments.some(segment => segment === '**');
324
+
325
+ // Handle double wildcard at the end (catch-all with slashes)
326
+ const hasDoubleWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '**';
327
+
328
+ // Handle single wildcard at the end (catch-all)
323
329
  const hasWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '*';
324
330
 
325
- if (hasWildcardAtEnd) {
326
- // For catch-all wildcard, path must have at least as many segments as route (minus the wildcard)
331
+ if (hasDoubleWildcardAtEnd) {
332
+ // For double wildcard at end, path must have at least as many segments as route (minus the double wildcard)
327
333
  if (pathSegments.length < routeSegments.length - 1) continue;
328
- } else {
334
+ } else if (hasWildcardAtEnd) {
335
+ // For single wildcard at end, path must have at least as many segments as route (minus the wildcard)
336
+ if (pathSegments.length < routeSegments.length - 1) continue;
337
+ } else if (!hasDoubleWildcard) {
329
338
  // For exact matching (with possible single-segment wildcards), lengths must match
330
339
  if (routeSegments.length !== pathSegments.length) continue;
331
340
  }
@@ -339,7 +348,14 @@ export default class BXO {
339
348
  break;
340
349
  }
341
350
 
342
- // Handle catch-all wildcard at the end
351
+ // Handle double wildcard at the end (matches everything including slashes)
352
+ if (routeSegment === '**' && i === routeSegments.length - 1) {
353
+ const remainingPath = pathSegments.slice(i).join('/');
354
+ params['**'] = remainingPath;
355
+ break;
356
+ }
357
+
358
+ // Handle single wildcard at the end (catch-all)
343
359
  if (routeSegment === '*' && i === routeSegments.length - 1) {
344
360
  // Wildcard at end matches remaining path segments
345
361
  const remainingPath = pathSegments.slice(i).join('/');
@@ -347,6 +363,68 @@ export default class BXO {
347
363
  break;
348
364
  }
349
365
 
366
+ // Handle double wildcard in the middle (matches everything including slashes)
367
+ if (routeSegment === '**') {
368
+ // Find the next non-wildcard segment to match against
369
+ let nextNonWildcardIndex = i + 1;
370
+ while (nextNonWildcardIndex < routeSegments.length &&
371
+ (routeSegments[nextNonWildcardIndex] === '*' || routeSegments[nextNonWildcardIndex] === '**')) {
372
+ nextNonWildcardIndex++;
373
+ }
374
+
375
+ if (nextNonWildcardIndex >= routeSegments.length) {
376
+ // Double wildcard is at the end or followed by other wildcards
377
+ const remainingPath = pathSegments.slice(i).join('/');
378
+ params['**'] = remainingPath;
379
+ break;
380
+ }
381
+
382
+ // Find the next matching segment in the path
383
+ const nextRouteSegment = routeSegments[nextNonWildcardIndex];
384
+ if (!nextRouteSegment) {
385
+ isMatch = false;
386
+ break;
387
+ }
388
+
389
+ let foundMatch = false;
390
+ let matchedPath = '';
391
+
392
+ for (let j = i; j < pathSegments.length; j++) {
393
+ const currentPathSegment = pathSegments[j];
394
+
395
+ // Check if this path segment matches the next route segment
396
+ if (nextRouteSegment.startsWith(':')) {
397
+ // Param segment - always matches
398
+ matchedPath = pathSegments.slice(i, j).join('/');
399
+ params['**'] = matchedPath;
400
+ i = j - 1; // Adjust index for the next iteration
401
+ foundMatch = true;
402
+ break;
403
+ } else if (nextRouteSegment === '*') {
404
+ // Single wildcard - always matches
405
+ matchedPath = pathSegments.slice(i, j).join('/');
406
+ params['**'] = matchedPath;
407
+ i = j - 1; // Adjust index for the next iteration
408
+ foundMatch = true;
409
+ break;
410
+ } else if (nextRouteSegment === currentPathSegment) {
411
+ // Exact match
412
+ matchedPath = pathSegments.slice(i, j).join('/');
413
+ params['**'] = matchedPath;
414
+ i = j - 1; // Adjust index for the next iteration
415
+ foundMatch = true;
416
+ break;
417
+ }
418
+ }
419
+
420
+ if (!foundMatch) {
421
+ isMatch = false;
422
+ break;
423
+ }
424
+
425
+ continue;
426
+ }
427
+
350
428
  if (!pathSegment) {
351
429
  isMatch = false;
352
430
  break;
@@ -383,13 +461,22 @@ export default class BXO {
383
461
  const params: Record<string, string> = {};
384
462
  let isMatch = true;
385
463
 
386
- // Handle wildcard at the end (catch-all)
464
+ // Check for double wildcard (**) in the route
465
+ const hasDoubleWildcard = routeSegments.some(segment => segment === '**');
466
+
467
+ // Handle double wildcard at the end (catch-all with slashes)
468
+ const hasDoubleWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '**';
469
+
470
+ // Handle single wildcard at the end (catch-all)
387
471
  const hasWildcardAtEnd = routeSegments.length > 0 && routeSegments[routeSegments.length - 1] === '*';
388
472
 
389
- if (hasWildcardAtEnd) {
390
- // For catch-all wildcard, path must have at least as many segments as route (minus the wildcard)
473
+ if (hasDoubleWildcardAtEnd) {
474
+ // For double wildcard at end, path must have at least as many segments as route (minus the double wildcard)
391
475
  if (pathSegments.length < routeSegments.length - 1) continue;
392
- } else {
476
+ } else if (hasWildcardAtEnd) {
477
+ // For single wildcard at end, path must have at least as many segments as route (minus the wildcard)
478
+ if (pathSegments.length < routeSegments.length - 1) continue;
479
+ } else if (!hasDoubleWildcard) {
393
480
  // For exact matching (with possible single-segment wildcards), lengths must match
394
481
  if (routeSegments.length !== pathSegments.length) continue;
395
482
  }
@@ -403,7 +490,14 @@ export default class BXO {
403
490
  break;
404
491
  }
405
492
 
406
- // Handle catch-all wildcard at the end
493
+ // Handle double wildcard at the end (matches everything including slashes)
494
+ if (routeSegment === '**' && i === routeSegments.length - 1) {
495
+ const remainingPath = pathSegments.slice(i).join('/');
496
+ params['**'] = remainingPath;
497
+ break;
498
+ }
499
+
500
+ // Handle single wildcard at the end (catch-all)
407
501
  if (routeSegment === '*' && i === routeSegments.length - 1) {
408
502
  // Wildcard at end matches remaining path segments
409
503
  const remainingPath = pathSegments.slice(i).join('/');
@@ -411,6 +505,68 @@ export default class BXO {
411
505
  break;
412
506
  }
413
507
 
508
+ // Handle double wildcard in the middle (matches everything including slashes)
509
+ if (routeSegment === '**') {
510
+ // Find the next non-wildcard segment to match against
511
+ let nextNonWildcardIndex = i + 1;
512
+ while (nextNonWildcardIndex < routeSegments.length &&
513
+ (routeSegments[nextNonWildcardIndex] === '*' || routeSegments[nextNonWildcardIndex] === '**')) {
514
+ nextNonWildcardIndex++;
515
+ }
516
+
517
+ if (nextNonWildcardIndex >= routeSegments.length) {
518
+ // Double wildcard is at the end or followed by other wildcards
519
+ const remainingPath = pathSegments.slice(i).join('/');
520
+ params['**'] = remainingPath;
521
+ break;
522
+ }
523
+
524
+ // Find the next matching segment in the path
525
+ const nextRouteSegment = routeSegments[nextNonWildcardIndex];
526
+ if (!nextRouteSegment) {
527
+ isMatch = false;
528
+ break;
529
+ }
530
+
531
+ let foundMatch = false;
532
+ let matchedPath = '';
533
+
534
+ for (let j = i; j < pathSegments.length; j++) {
535
+ const currentPathSegment = pathSegments[j];
536
+
537
+ // Check if this path segment matches the next route segment
538
+ if (nextRouteSegment.startsWith(':')) {
539
+ // Param segment - always matches
540
+ matchedPath = pathSegments.slice(i, j).join('/');
541
+ params['**'] = matchedPath;
542
+ i = j - 1; // Adjust index for the next iteration
543
+ foundMatch = true;
544
+ break;
545
+ } else if (nextRouteSegment === '*') {
546
+ // Single wildcard - always matches
547
+ matchedPath = pathSegments.slice(i, j).join('/');
548
+ params['**'] = matchedPath;
549
+ i = j - 1; // Adjust index for the next iteration
550
+ foundMatch = true;
551
+ break;
552
+ } else if (nextRouteSegment === currentPathSegment) {
553
+ // Exact match
554
+ matchedPath = pathSegments.slice(i, j).join('/');
555
+ params['**'] = matchedPath;
556
+ i = j - 1; // Adjust index for the next iteration
557
+ foundMatch = true;
558
+ break;
559
+ }
560
+ }
561
+
562
+ if (!foundMatch) {
563
+ isMatch = false;
564
+ break;
565
+ }
566
+
567
+ continue;
568
+ }
569
+
414
570
  if (!pathSegment) {
415
571
  isMatch = false;
416
572
  break;
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.35",
4
+ "version": "0.0.5-dev.37",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "devDependencies": {
@@ -15,6 +15,6 @@
15
15
  "typescript": "^5"
16
16
  },
17
17
  "dependencies": {
18
- "zod": "^4.0.5"
18
+ "zod": "^3.25.76"
19
19
  }
20
20
  }
package/example.ts DELETED
@@ -1,33 +0,0 @@
1
- import BXO, { createCookie, redirect } from 'bxo';
2
-
3
- const app = new BXO();
4
-
5
- // 1) Explicit return redirect (302 default)
6
- app.get('/old', ({ redirect }) => {
7
- return redirect('/new');
8
- });
9
-
10
- // 2) Implicit redirect (no return needed)
11
- app.get('/implicit', (ctx) => {
12
- ctx.redirect('/new');
13
- });
14
-
15
- // 3) Custom status (303 after POST)
16
- app.post('/submit', (ctx) => {
17
- // ...handle form...
18
- return ctx.redirect('/thanks', 303);
19
- });
20
-
21
- // 4) Redirect with cookie
22
- app.get('/login', (ctx) => {
23
- ctx.set.cookies = [
24
- createCookie('sid', 'abc123', { httpOnly: true, path: '/' })
25
- ];
26
- ctx.redirect('/dashboard'); // no return required
27
- });
28
-
29
- // 5) Using top-level helper (outside ctx)
30
- app.get('/go-external', () => redirect('https://example.com', 307));
31
-
32
- await app.start(3000);
33
- console.log('Server running at http://localhost:3000');