@devp0nt/route0 1.0.0-next.64 → 1.0.0-next.66

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.
@@ -33,7 +33,7 @@ class Route0 {
33
33
  get origin() {
34
34
  if (!this._origin) {
35
35
  throw new Error(
36
- "origin for route " + this.definition + ' is not set, please provide it like Route0.create(route, {origin: "https://example.com"}) in config or set via overrides like routes._.override({origin: "https://example.com"})'
36
+ "origin for route " + this.definition + ' is not set, please provide it like Route0.create(route, {origin: "https://example.com"}) in config or set via clones like routes._.clone({origin: "https://example.com"})'
37
37
  );
38
38
  }
39
39
  return this._origin;
@@ -458,76 +458,171 @@ class Route0 {
458
458
  unmatched
459
459
  };
460
460
  }
461
- /**
462
- * Safe parser for flat input objects.
463
- *
464
- * Returns structured success/error result instead of throwing.
465
- */
466
- safeParseFlatInput(input, loose) {
467
- loose ??= this.hasLooseSearch;
461
+ _validateParamsInput(input) {
468
462
  const paramsKeys = this.getParamsKeys();
469
463
  if (input === void 0) {
470
464
  if (paramsKeys.length) {
471
465
  return {
472
- success: false,
473
- data: void 0,
474
- error: new Error(`Missing params: ${paramsKeys.map((k) => `"${k}"`).join(", ")}`)
466
+ issues: [
467
+ {
468
+ message: `Missing params: ${paramsKeys.map((k) => `"${k}"`).join(", ")}`
469
+ }
470
+ ]
475
471
  };
476
472
  }
477
473
  input = {};
478
474
  }
479
475
  if (typeof input !== "object" || input === null) {
480
476
  return {
481
- success: false,
482
- data: void 0,
483
- error: new Error("Invalid input: expected object")
477
+ issues: [{ message: "Invalid input: expected object" }]
484
478
  };
485
479
  }
486
- const inputKeys = Object.keys(input);
480
+ const inputObj = input;
481
+ const inputKeys = Object.keys(inputObj);
487
482
  const notDefinedKeys = paramsKeys.filter((k) => !inputKeys.includes(k));
488
483
  if (notDefinedKeys.length) {
489
484
  return {
490
- success: false,
491
- data: void 0,
492
- error: new Error(`Missing params: ${notDefinedKeys.map((k) => `"${k}"`).join(", ")}`)
485
+ issues: [
486
+ {
487
+ message: `Missing params: ${notDefinedKeys.map((k) => `"${k}"`).join(", ")}`
488
+ }
489
+ ]
493
490
  };
494
491
  }
495
492
  const data = {};
496
- const filterKeys = !loose ? [...paramsKeys, ...this.getSearchKeys()] : false;
497
- for (const [k, v] of Object.entries(input)) {
498
- if (filterKeys && !filterKeys.includes(k)) {
499
- continue;
493
+ for (const k of paramsKeys) {
494
+ const v = inputObj[k];
495
+ if (typeof v === "string") {
496
+ data[k] = v;
497
+ } else if (typeof v === "number") {
498
+ data[k] = String(v);
499
+ } else {
500
+ return {
501
+ issues: [{ message: `Invalid input: expected string, number, got ${typeof v} for "${k}"` }]
502
+ };
500
503
  }
504
+ }
505
+ return {
506
+ value: data
507
+ };
508
+ }
509
+ _validateSearchInput(input, loose) {
510
+ if (input === void 0) {
511
+ input = {};
512
+ }
513
+ if (typeof input !== "object" || input === null) {
514
+ return {
515
+ issues: [{ message: "Invalid input: expected object" }]
516
+ };
517
+ }
518
+ const inputObj = input;
519
+ const paramsKeys = this.getParamsKeys();
520
+ const searchKeys = this.getSearchKeys();
521
+ const data = {};
522
+ for (const [k, v] of Object.entries(inputObj)) {
523
+ if (k === "hash") continue;
524
+ if (paramsKeys.includes(k)) continue;
525
+ if (!loose && !searchKeys.includes(k)) continue;
526
+ if (v === void 0) continue;
501
527
  if (typeof v === "string") {
502
528
  data[k] = v;
503
529
  } else if (typeof v === "number") {
504
530
  data[k] = String(v);
505
531
  } else {
506
- const isParamKey = paramsKeys.includes(k);
507
532
  return {
508
- success: false,
509
- data: void 0,
510
- error: new Error(
511
- `Invalid input: expected string, number,${!isParamKey ? " or undefined," : ""} got ${typeof v} for "${k}"`
512
- )
533
+ issues: [{ message: `Invalid input: expected string, number, or undefined, got ${typeof v} for "${k}"` }]
513
534
  };
514
535
  }
515
536
  }
516
537
  return {
517
- success: true,
518
- data,
519
- error: void 0
538
+ value: data
539
+ };
540
+ }
541
+ _validateFlatInput(input, loose) {
542
+ const paramsResult = this._validateParamsInput(input);
543
+ if ("issues" in paramsResult) {
544
+ return {
545
+ issues: paramsResult.issues ?? []
546
+ };
547
+ }
548
+ const searchResult = this._validateSearchInput(input, loose);
549
+ if ("issues" in searchResult) {
550
+ return {
551
+ issues: searchResult.issues ?? []
552
+ };
553
+ }
554
+ return {
555
+ value: {
556
+ ...searchResult.value,
557
+ ...paramsResult.value
558
+ }
520
559
  };
521
560
  }
522
- /** Throwing variant of `safeParseFlatInput()`. */
523
- parseFlatInput(input, loose) {
524
- loose ??= this.hasLooseSearch;
525
- const result = this.safeParseFlatInput(input, loose);
526
- if (result.error) {
527
- throw result.error;
561
+ _safeParseSchemaResult(result) {
562
+ if ("issues" in result) {
563
+ return {
564
+ success: false,
565
+ data: void 0,
566
+ error: new Error(result.issues?.[0]?.message ?? "Invalid input")
567
+ };
528
568
  }
529
- return result.data;
569
+ return {
570
+ success: true,
571
+ data: result.value,
572
+ error: void 0
573
+ };
530
574
  }
575
+ _parseSchemaResult(result) {
576
+ const safeResult = this._safeParseSchemaResult(result);
577
+ if (safeResult.error) {
578
+ throw safeResult.error;
579
+ }
580
+ return safeResult.data;
581
+ }
582
+ /** Standard Schema for route params input. */
583
+ paramsInputSchema = {
584
+ "~standard": {
585
+ version: 1,
586
+ vendor: "route0",
587
+ validate: (value) => this._validateParamsInput(value),
588
+ types: void 0
589
+ },
590
+ parse: (value) => this._parseSchemaResult(this._validateParamsInput(value)),
591
+ safeParse: (value) => this._safeParseSchemaResult(this._validateParamsInput(value))
592
+ };
593
+ /** Standard Schema for strict search input. */
594
+ strictSearchInputSchema = {
595
+ "~standard": {
596
+ version: 1,
597
+ vendor: "route0",
598
+ validate: (value) => this._validateSearchInput(value, false),
599
+ types: void 0
600
+ },
601
+ parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, false)),
602
+ safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, false))
603
+ };
604
+ /** Standard Schema for loose search input. */
605
+ looseSearchInputSchema = {
606
+ "~standard": {
607
+ version: 1,
608
+ vendor: "route0",
609
+ validate: (value) => this._validateSearchInput(value, true),
610
+ types: void 0
611
+ },
612
+ parse: (value) => this._parseSchemaResult(this._validateSearchInput(value, true)),
613
+ safeParse: (value) => this._safeParseSchemaResult(this._validateSearchInput(value, true))
614
+ };
615
+ /** Standard Schema for route flat input (uses route default strict/loose mode). */
616
+ flatInputSchema = {
617
+ "~standard": {
618
+ version: 1,
619
+ vendor: "route0",
620
+ validate: (value) => this._validateFlatInput(value, this.hasLooseSearch),
621
+ types: void 0
622
+ },
623
+ parse: (value) => this._parseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch)),
624
+ safeParse: (value) => this._safeParseSchemaResult(this._validateFlatInput(value, this.hasLooseSearch))
625
+ };
531
626
  /** True when path structure is equal (param names are ignored). */
532
627
  isSame(other) {
533
628
  return this.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__") === other.pathDefinition.replace(/:([A-Za-z0-9_]+)/g, "__PARAM__");
@@ -655,7 +750,7 @@ class Routes {
655
750
  this._ = {
656
751
  routes: this._routes,
657
752
  getLocation: this._getLocation.bind(this),
658
- override: this._override.bind(this),
753
+ clone: this._clone.bind(this),
659
754
  pathsOrdering: this._pathsOrdering,
660
755
  keysOrdering: this._keysOrdering,
661
756
  ordered: this._ordered
@@ -667,7 +762,7 @@ class Routes {
667
762
  if (!override) {
668
763
  return result;
669
764
  }
670
- return result._.override(override);
765
+ return result._.clone(override);
671
766
  }
672
767
  static prettify(instance) {
673
768
  Object.setPrototypeOf(instance, Routes.prototype);
@@ -675,7 +770,7 @@ class Routes {
675
770
  value: "Routes"
676
771
  });
677
772
  Object.assign(instance, {
678
- override: instance._override.bind(instance)
773
+ clone: instance._clone.bind(instance)
679
774
  });
680
775
  Object.assign(instance, instance._routes);
681
776
  return instance;
@@ -724,7 +819,7 @@ class Routes {
724
819
  return { pathsOrdering, keysOrdering };
725
820
  }
726
821
  /** Returns a cloned routes collection with config applied to each route. */
727
- _override(config) {
822
+ _clone(config) {
728
823
  const newRoutes = {};
729
824
  for (const key in this._routes) {
730
825
  if (Object.hasOwn(this._routes, key)) {