@xmachines/play-router 2.0.0 → 2.1.0

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 (58) hide show
  1. package/README.md +93 -76
  2. package/dist/base-route-map.d.ts +63 -57
  3. package/dist/base-route-map.d.ts.map +1 -1
  4. package/dist/base-route-map.js +65 -59
  5. package/dist/base-route-map.js.map +1 -1
  6. package/dist/build-tree.d.ts +13 -12
  7. package/dist/build-tree.d.ts.map +1 -1
  8. package/dist/build-tree.js +30 -28
  9. package/dist/build-tree.js.map +1 -1
  10. package/dist/create-route-map-from-tree.d.ts +15 -15
  11. package/dist/create-route-map-from-tree.js +15 -15
  12. package/dist/create-route-map.d.ts +18 -16
  13. package/dist/create-route-map.d.ts.map +1 -1
  14. package/dist/create-route-map.js +10 -9
  15. package/dist/create-route-map.js.map +1 -1
  16. package/dist/errors.d.ts +40 -38
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +40 -38
  19. package/dist/errors.js.map +1 -1
  20. package/dist/extract-routes.d.ts +8 -7
  21. package/dist/extract-routes.d.ts.map +1 -1
  22. package/dist/extract-routes.js +31 -27
  23. package/dist/extract-routes.js.map +1 -1
  24. package/dist/find-route.d.ts +18 -15
  25. package/dist/find-route.d.ts.map +1 -1
  26. package/dist/find-route.js +42 -38
  27. package/dist/find-route.js.map +1 -1
  28. package/dist/index.d.ts +6 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +11 -10
  31. package/dist/index.js.map +1 -1
  32. package/dist/machine-to-graph.d.ts +3 -2
  33. package/dist/machine-to-graph.d.ts.map +1 -1
  34. package/dist/machine-to-graph.js +20 -19
  35. package/dist/machine-to-graph.js.map +1 -1
  36. package/dist/query.d.ts +39 -37
  37. package/dist/query.d.ts.map +1 -1
  38. package/dist/query.js +62 -57
  39. package/dist/query.js.map +1 -1
  40. package/dist/router-bridge-base.d.ts +208 -190
  41. package/dist/router-bridge-base.d.ts.map +1 -1
  42. package/dist/router-bridge-base.js +235 -211
  43. package/dist/router-bridge-base.js.map +1 -1
  44. package/dist/router-sync.d.ts +41 -35
  45. package/dist/router-sync.d.ts.map +1 -1
  46. package/dist/router-sync.js +53 -45
  47. package/dist/router-sync.js.map +1 -1
  48. package/dist/types.d.ts +165 -147
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/url-pattern-utils.d.ts +53 -47
  51. package/dist/url-pattern-utils.d.ts.map +1 -1
  52. package/dist/url-pattern-utils.js +61 -55
  53. package/dist/url-pattern-utils.js.map +1 -1
  54. package/dist/validate-routes.d.ts +32 -31
  55. package/dist/validate-routes.d.ts.map +1 -1
  56. package/dist/validate-routes.js +30 -29
  57. package/dist/validate-routes.js.map +1 -1
  58. package/package.json +6 -5
@@ -1,20 +1,21 @@
1
1
  /**
2
- * Shared URLPattern utilities — internal module, NOT exported from index.ts
2
+ * The shared URLPattern utilities — an internal module. index.ts does not export it
3
3
  *
4
- * Provides the common URLPattern plumbing shared by:
4
+ * This module holds the common URLPattern work of four files:
5
5
  * - `create-route-map.ts`
6
6
  * - `base-route-map.ts`
7
7
  * - `find-route.ts`
8
8
  * - `router-bridge-base.ts`
9
9
  *
10
- * URLPattern is accessed via globalThis consumers must load a polyfill on
11
- * environments without native support (Node < 24, older browsers).
10
+ * The module reads URLPattern from globalThis. A consumer must load a polyfill in an
11
+ * environment without the native API: Node < 24, and an older browser.
12
12
  *
13
13
  * @internal
14
14
  */
15
15
  /**
16
- * Minimal structural type for the subset of URLPattern we use.
17
- * Avoids a hard dependency on the full URLPattern type declaration.
16
+ * The minimal structural type of the part of URLPattern that this package uses.
17
+ * The package therefore needs no hard dependency on the complete type declaration of
18
+ * URLPattern.
18
19
  */
19
20
  export type URLPatternLike = {
20
21
  exec(input: {
@@ -28,39 +29,42 @@ export type URLPatternLike = {
28
29
  pathname: string;
29
30
  }): boolean;
30
31
  };
31
- /** Constructor type for URLPatternLike instances. */
32
+ /** The constructor type of a URLPatternLike instance. */
32
33
  export type URLPatternCtor = new (init: {
33
34
  pathname: string;
34
35
  }) => URLPatternLike;
35
36
  /**
36
- * Retrieve the URLPattern constructor from `globalThis`, or `undefined` if
37
- * it is not available (Node < 24, older browsers without a polyfill).
37
+ * Returns the URLPattern constructor of `globalThis`, or `undefined` when it is
38
+ * absent: in Node < 24, and in an older browser without a polyfill.
38
39
  */
39
40
  export declare function getURLPatternCtor(): URLPatternCtor | undefined;
40
41
  /**
41
- * Check whether a route path is a parameterized pattern rather than a concrete URL.
42
+ * Tells you if a route path is a parameterized pattern, and not a concrete URL.
42
43
  *
43
- * A pattern contains `:param` segments (required or optional) and/or the `*`
44
- * wildcard both require URLPattern matching and carry no concrete values, so
45
- * they can never be pushed to a browser URL verbatim.
44
+ * A pattern holds a `:param` segment, which is necessary or optional, or the `*`
45
+ * wildcard, or both. Each of them needs a URLPattern match, and each of them carries
46
+ * no concrete value. Therefore the code can push such a path to a browser URL
47
+ * never.
46
48
  *
47
- * This is THE single source of truth for "is this path a pattern?" — used by
48
- * `RouteMap` to decide static-map vs pattern-bucket indexing and by
49
- * `RouterBridgeBase.resolveNavigationPath` to skip non-navigable routes, so the
50
- * two checks can never drift apart.
49
+ * This function is THE single source of truth of the question "is this path a
50
+ * pattern?". `RouteMap` uses it for its decision between the static map and the
51
+ * index of the pattern buckets, and `RouterBridgeBase.resolveNavigationPath` uses it
52
+ * to skip a route of no navigation. The two tests therefore cannot move apart.
51
53
  *
52
- * @param path - URL path or route pattern string (e.g. `/profile/:userId`, `/docs/*`)
53
- * @returns `true` if the path contains `:param` or `*` pattern syntax
54
+ * @param path - The string of a URL path or of a route pattern, for example `/profile/:userId` or `/docs/*`
55
+ * @returns `true` when the path holds a `:param` or a `*` pattern syntax
54
56
  */
55
57
  export declare function isParameterizedPattern(path: string): boolean;
56
58
  /**
57
- * Normalize a route path so its parameter names are valid URLPattern identifiers.
59
+ * Normalizes a route path, so that each of its parameter names is a valid URLPattern
60
+ * identifier.
58
61
  *
59
- * URLPattern requires parameter names to be valid JS identifiers (no hyphens).
60
- * Hyphenated names like `:cat-id` are replaced with underscored equivalents
61
- * (`:cat_id`) for the URLPattern compilation step. Callers that need the captured
62
- * group values (not just a match test) must map the normalized group names back to
63
- * the original param names via {@link getNormalizedParamNameMap}.
62
+ * URLPattern requires a valid JS identifier as a parameter name, and such an
63
+ * identifier holds no hyphen. Therefore the function replaces a name with a hyphen,
64
+ * for example `:cat-id`, with the equivalent name with an underscore (`:cat_id`),
65
+ * for the compilation step of URLPattern. A caller that needs the values of the
66
+ * captured groups, and not a test of the match alone, must map each normalized group
67
+ * name back to the original param name with {@link getNormalizedParamNameMap}.
64
68
  *
65
69
  * @example
66
70
  * normalizeParamNames("/docs/:cat-id/:page-num?")
@@ -68,11 +72,11 @@ export declare function isParameterizedPattern(path: string): boolean;
68
72
  */
69
73
  export declare function normalizeParamNames(path: string): string;
70
74
  /**
71
- * Build a map from normalized URLPattern group names back to the original
72
- * (hyphenated) param names for a route pattern.
75
+ * Builds the map from each normalized URLPattern group name back to the original
76
+ * param name, which holds a hyphen, of a route pattern.
73
77
  *
74
- * Only params rewritten by {@link normalizeParamNames} appear in the map —
75
- * params that are already valid identifiers keep their own name and need no entry.
78
+ * The map holds only the params that {@link normalizeParamNames} rewrote. A param
79
+ * with a valid identifier keeps its own name, and it needs no entry.
76
80
  *
77
81
  * @example
78
82
  * getNormalizedParamNameMap("/docs/:cat-id/:plain")
@@ -80,36 +84,38 @@ export declare function normalizeParamNames(path: string): string;
80
84
  */
81
85
  export declare function getNormalizedParamNameMap(path: string): Map<string, string>;
82
86
  /**
83
- * Compile a route pattern to a `URLPattern`, reusing the module-level cache.
87
+ * Compiles a route pattern into a `URLPattern`, and it uses the cache of the module
88
+ * level again.
84
89
  *
85
- * The pattern is normalized with {@link normalizeParamNames} before compilation
86
- * so hyphenated param names (`:cat-id`) become valid URLPattern identifiers
87
- * (`:cat_id`). Callers that extract group values must map the normalized names
88
- * back via {@link getNormalizedParamNameMap}.
90
+ * {@link normalizeParamNames} normalizes the pattern before the compilation. A param
91
+ * name with a hyphen (`:cat-id`) therefore becomes a valid URLPattern identifier
92
+ * (`:cat_id`). A caller that reads the values of the groups must map each normalized
93
+ * name back with {@link getNormalizedParamNameMap}.
89
94
  *
90
- * Compilation errors from the URLPattern constructor propagate as-is callers
91
- * that need a typed error wrap this in `InvalidRoutePatternError`.
95
+ * An error of the compilation from the URLPattern constructor goes to the caller
96
+ * without a change. A caller that needs a typed error wraps this function in an
97
+ * `InvalidRoutePatternError`.
92
98
  *
93
- * @param pattern - Route pattern string (e.g. `/profile/:userId`)
94
- * @param Ctor - URLPattern constructor retrieved via {@link getURLPatternCtor}
99
+ * @param pattern - The string of the route pattern, for example `/profile/:userId`
100
+ * @param Ctor - The URLPattern constructor, from {@link getURLPatternCtor}
95
101
  */
96
102
  export declare function getCompiledPattern(pattern: string, Ctor: URLPatternCtor): URLPatternLike;
97
103
  /**
98
- * Compute the bucket index key for a given path or pattern.
104
+ * Computes the key of the bucket index of a path or of a pattern.
99
105
  *
100
- * The key is the first path segment (e.g. `"settings"` for `"/settings/:id"`).
101
- * Parameterised first segments (`:lang`) fall into the `"*"` wildcard bucket.
102
- * The root path `"/"` maps to the key `"/"`.
106
+ * The key is the first path segment, for example `"settings"` of `"/settings/:id"`.
107
+ * A first segment with a parameter (`:lang`) goes into the `"*"` wildcard bucket.
108
+ * The root path `"/"` gives the key `"/"`.
103
109
  *
104
- * @param path - URL path or route pattern string
110
+ * @param path - The string of a URL path or of a route pattern
105
111
  */
106
112
  export declare function getIndexKey(path: string): string;
107
113
  /**
108
- * Merge the named-segment bucket and the wildcard bucket for a given index key,
109
- * preserving insertion order (by `order` field).
114
+ * Joins the bucket of the named segment and the wildcard bucket of one index key.
115
+ * The order of the insertion stays, through the `order` field.
110
116
  *
111
- * @param patternBuckets - Map of bucket key ordered pattern entries
112
- * @param indexKey - First-segment key computed by `getIndexKey`
117
+ * @param patternBuckets - The map from a bucket key to its ordered pattern entries
118
+ * @param indexKey - The key of the first segment, from `getIndexKey`
113
119
  */
114
120
  export declare function getCandidates<T extends {
115
121
  order: number;
@@ -1 +1 @@
1
- {"version":3,"file":"url-pattern-utils.d.ts","sourceRoot":"","sources":["../src/url-pattern-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,IAAI,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAClC,QAAQ,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;SAAE,CAAC;KACzD,GAAG,IAAI,CAAC;IACT,IAAI,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;CAC3C,CAAC;AAEF,qDAAqD;AACrD,MAAM,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAAK,cAAc,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3E;AAeD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,cAAc,CAWxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EACxD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAChC,QAAQ,EAAE,MAAM,GACd,CAAC,EAAE,CA2BL"}
1
+ {"version":3,"file":"url-pattern-utils.d.ts","sourceRoot":"","sources":["../src/url-pattern-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,IAAI,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG;QAClC,QAAQ,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;SAAE,CAAC;KACzD,GAAG,IAAI,CAAC;IACT,IAAI,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;CAC3C,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAAK,cAAc,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAO3E;AAgBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,cAAc,CAWxF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EACxD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAChC,QAAQ,EAAE,MAAM,GACd,CAAC,EAAE,CA2BL"}
@@ -1,56 +1,59 @@
1
1
  /**
2
- * Shared URLPattern utilities — internal module, NOT exported from index.ts
2
+ * The shared URLPattern utilities — an internal module. index.ts does not export it
3
3
  *
4
- * Provides the common URLPattern plumbing shared by:
4
+ * This module holds the common URLPattern work of four files:
5
5
  * - `create-route-map.ts`
6
6
  * - `base-route-map.ts`
7
7
  * - `find-route.ts`
8
8
  * - `router-bridge-base.ts`
9
9
  *
10
- * URLPattern is accessed via globalThis consumers must load a polyfill on
11
- * environments without native support (Node < 24, older browsers).
10
+ * The module reads URLPattern from globalThis. A consumer must load a polyfill in an
11
+ * environment without the native API: Node < 24, and an older browser.
12
12
  *
13
13
  * @internal
14
14
  */
15
15
  /**
16
- * Retrieve the URLPattern constructor from `globalThis`, or `undefined` if
17
- * it is not available (Node < 24, older browsers without a polyfill).
16
+ * Returns the URLPattern constructor of `globalThis`, or `undefined` when it is
17
+ * absent: in Node < 24, and in an older browser without a polyfill.
18
18
  */
19
19
  export function getURLPatternCtor() {
20
20
  return globalThis["URLPattern"];
21
21
  }
22
22
  /**
23
- * Check whether a route path is a parameterized pattern rather than a concrete URL.
23
+ * Tells you if a route path is a parameterized pattern, and not a concrete URL.
24
24
  *
25
- * A pattern contains `:param` segments (required or optional) and/or the `*`
26
- * wildcard both require URLPattern matching and carry no concrete values, so
27
- * they can never be pushed to a browser URL verbatim.
25
+ * A pattern holds a `:param` segment, which is necessary or optional, or the `*`
26
+ * wildcard, or both. Each of them needs a URLPattern match, and each of them carries
27
+ * no concrete value. Therefore the code can push such a path to a browser URL
28
+ * never.
28
29
  *
29
- * This is THE single source of truth for "is this path a pattern?" — used by
30
- * `RouteMap` to decide static-map vs pattern-bucket indexing and by
31
- * `RouterBridgeBase.resolveNavigationPath` to skip non-navigable routes, so the
32
- * two checks can never drift apart.
30
+ * This function is THE single source of truth of the question "is this path a
31
+ * pattern?". `RouteMap` uses it for its decision between the static map and the
32
+ * index of the pattern buckets, and `RouterBridgeBase.resolveNavigationPath` uses it
33
+ * to skip a route of no navigation. The two tests therefore cannot move apart.
33
34
  *
34
- * @param path - URL path or route pattern string (e.g. `/profile/:userId`, `/docs/*`)
35
- * @returns `true` if the path contains `:param` or `*` pattern syntax
35
+ * @param path - The string of a URL path or of a route pattern, for example `/profile/:userId` or `/docs/*`
36
+ * @returns `true` when the path holds a `:param` or a `*` pattern syntax
36
37
  */
37
38
  export function isParameterizedPattern(path) {
38
39
  return path.includes(":") || path.includes("*");
39
40
  }
40
41
  /**
41
- * Matches hyphenated `:param` names (e.g. `:cat-id`, `:page-num?`).
42
- * URLPattern requires parameter names to be valid JS identifiers, so hyphenated
43
- * names must be rewritten before compilation.
42
+ * The expression matches a `:param` name with a hyphen, for example `:cat-id` or
43
+ * `:page-num?`. URLPattern requires a valid JS identifier as a parameter name.
44
+ * Therefore the code must rewrite a name with a hyphen before the compilation.
44
45
  */
45
46
  const HYPHENATED_PARAM_RE = /:([A-Za-z][A-Za-z0-9]*(?:-[A-Za-z0-9]+)+)(\??)/g;
46
47
  /**
47
- * Normalize a route path so its parameter names are valid URLPattern identifiers.
48
+ * Normalizes a route path, so that each of its parameter names is a valid URLPattern
49
+ * identifier.
48
50
  *
49
- * URLPattern requires parameter names to be valid JS identifiers (no hyphens).
50
- * Hyphenated names like `:cat-id` are replaced with underscored equivalents
51
- * (`:cat_id`) for the URLPattern compilation step. Callers that need the captured
52
- * group values (not just a match test) must map the normalized group names back to
53
- * the original param names via {@link getNormalizedParamNameMap}.
51
+ * URLPattern requires a valid JS identifier as a parameter name, and such an
52
+ * identifier holds no hyphen. Therefore the function replaces a name with a hyphen,
53
+ * for example `:cat-id`, with the equivalent name with an underscore (`:cat_id`),
54
+ * for the compilation step of URLPattern. A caller that needs the values of the
55
+ * captured groups, and not a test of the match alone, must map each normalized group
56
+ * name back to the original param name with {@link getNormalizedParamNameMap}.
54
57
  *
55
58
  * @example
56
59
  * normalizeParamNames("/docs/:cat-id/:page-num?")
@@ -62,11 +65,11 @@ export function normalizeParamNames(path) {
62
65
  });
63
66
  }
64
67
  /**
65
- * Build a map from normalized URLPattern group names back to the original
66
- * (hyphenated) param names for a route pattern.
68
+ * Builds the map from each normalized URLPattern group name back to the original
69
+ * param name, which holds a hyphen, of a route pattern.
67
70
  *
68
- * Only params rewritten by {@link normalizeParamNames} appear in the map —
69
- * params that are already valid identifiers keep their own name and need no entry.
71
+ * The map holds only the params that {@link normalizeParamNames} rewrote. A param
72
+ * with a valid identifier keeps its own name, and it needs no entry.
70
73
  *
71
74
  * @example
72
75
  * getNormalizedParamNameMap("/docs/:cat-id/:plain")
@@ -81,30 +84,33 @@ export function getNormalizedParamNameMap(path) {
81
84
  return nameMap;
82
85
  }
83
86
  /**
84
- * Module-level cache of compiled URLPattern instances keyed by pattern string.
85
- *
86
- * Route patterns are compiled on every navigation-time lookup path
87
- * (`extractRouteParams`, `findRouteByPath`) and once per `RouteMap`
88
- * construction; compiling the same route pattern each time is wasted work.
89
- * Growth is bounded by the number of distinct route patterns in the
90
- * application's route maps. The cache is invalidated when the URLPattern
91
- * constructor changes (tests swap `globalThis.URLPattern`).
87
+ * The cache of the compiled URLPattern instances at the module level. The key is the
88
+ * string of the pattern.
89
+ *
90
+ * The code compiles a route pattern on every lookup path of a navigation
91
+ * (`extractRouteParams` and `findRouteByPath`), and also one time for each
92
+ * `RouteMap` construction. A new compilation of the same route pattern each time is
93
+ * lost work. The number of the different route patterns of the route maps of the
94
+ * application limits the growth of the cache. The cache goes away when the
95
+ * URLPattern constructor changes, and a test changes `globalThis.URLPattern`.
92
96
  */
93
97
  const compiledPatternCache = new Map();
94
98
  let compiledPatternCtor;
95
99
  /**
96
- * Compile a route pattern to a `URLPattern`, reusing the module-level cache.
100
+ * Compiles a route pattern into a `URLPattern`, and it uses the cache of the module
101
+ * level again.
97
102
  *
98
- * The pattern is normalized with {@link normalizeParamNames} before compilation
99
- * so hyphenated param names (`:cat-id`) become valid URLPattern identifiers
100
- * (`:cat_id`). Callers that extract group values must map the normalized names
101
- * back via {@link getNormalizedParamNameMap}.
103
+ * {@link normalizeParamNames} normalizes the pattern before the compilation. A param
104
+ * name with a hyphen (`:cat-id`) therefore becomes a valid URLPattern identifier
105
+ * (`:cat_id`). A caller that reads the values of the groups must map each normalized
106
+ * name back with {@link getNormalizedParamNameMap}.
102
107
  *
103
- * Compilation errors from the URLPattern constructor propagate as-is callers
104
- * that need a typed error wrap this in `InvalidRoutePatternError`.
108
+ * An error of the compilation from the URLPattern constructor goes to the caller
109
+ * without a change. A caller that needs a typed error wraps this function in an
110
+ * `InvalidRoutePatternError`.
105
111
  *
106
- * @param pattern - Route pattern string (e.g. `/profile/:userId`)
107
- * @param Ctor - URLPattern constructor retrieved via {@link getURLPatternCtor}
112
+ * @param pattern - The string of the route pattern, for example `/profile/:userId`
113
+ * @param Ctor - The URLPattern constructor, from {@link getURLPatternCtor}
108
114
  */
109
115
  export function getCompiledPattern(pattern, Ctor) {
110
116
  if (Ctor !== compiledPatternCtor) {
@@ -119,13 +125,13 @@ export function getCompiledPattern(pattern, Ctor) {
119
125
  return compiled;
120
126
  }
121
127
  /**
122
- * Compute the bucket index key for a given path or pattern.
128
+ * Computes the key of the bucket index of a path or of a pattern.
123
129
  *
124
- * The key is the first path segment (e.g. `"settings"` for `"/settings/:id"`).
125
- * Parameterised first segments (`:lang`) fall into the `"*"` wildcard bucket.
126
- * The root path `"/"` maps to the key `"/"`.
130
+ * The key is the first path segment, for example `"settings"` of `"/settings/:id"`.
131
+ * A first segment with a parameter (`:lang`) goes into the `"*"` wildcard bucket.
132
+ * The root path `"/"` gives the key `"/"`.
127
133
  *
128
- * @param path - URL path or route pattern string
134
+ * @param path - The string of a URL path or of a route pattern
129
135
  */
130
136
  export function getIndexKey(path) {
131
137
  const trimmed = path.startsWith("/") ? path.slice(1) : path;
@@ -137,11 +143,11 @@ export function getIndexKey(path) {
137
143
  return segment;
138
144
  }
139
145
  /**
140
- * Merge the named-segment bucket and the wildcard bucket for a given index key,
141
- * preserving insertion order (by `order` field).
146
+ * Joins the bucket of the named segment and the wildcard bucket of one index key.
147
+ * The order of the insertion stays, through the `order` field.
142
148
  *
143
- * @param patternBuckets - Map of bucket key ordered pattern entries
144
- * @param indexKey - First-segment key computed by `getIndexKey`
149
+ * @param patternBuckets - The map from a bucket key to its ordered pattern entries
150
+ * @param indexKey - The key of the first segment, from `getIndexKey`
145
151
  */
146
152
  export function getCandidates(patternBuckets, indexKey) {
147
153
  const bucket = patternBuckets.get(indexKey) ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"url-pattern-utils.js","sourceRoot":"","sources":["../src/url-pattern-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAgBH;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAChC,OAAQ,UAAsC,CAAC,YAAY,CAA+B,CAAC;AAC5F,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,iDAAiD,CAAC;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,EAAE,EAAE,IAAY,EAAE,QAAgB,EAAE,EAAE;QAC/E,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACrD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA0B,CAAC;AAC/D,IAAI,mBAA+C,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,IAAoB;IACvE,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;QAClC,oBAAoB,CAAC,KAAK,EAAE,CAAC;QAC7B,mBAAmB,GAAG,IAAI,CAAC;IAC5B,CAAC;IACD,IAAI,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ,GAAG,IAAI,IAAI,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChE,oBAAoB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACjE,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC5B,cAAgC,EAChC,QAAgB;IAEhB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,cAAc,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAC/C,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAE/C,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC;QACvD,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC,IAAI,CAAC,CAAC;QACR,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC,IAAI,CAAC,CAAC;QACR,CAAC;IACF,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,IAAI,CAAC,CAAC;IACR,CAAC;IACD,OAAO,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC,IAAI,CAAC,CAAC;IACR,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"url-pattern-utils.js","sourceRoot":"","sources":["../src/url-pattern-utils.ts"],"names":[],"mappings":"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"}
@@ -1,57 +1,58 @@
1
1
  /**
2
- * A route entry with its RESOLVED full path the path after relative routes have
3
- * been prefixed with their parent's full path during tree construction.
2
+ * A route entry with its RESOLVED complete path, which is the path after the tree
3
+ * construction put the path of the parent before each relative route.
4
4
  *
5
5
  * `RouteNode` satisfies this shape structurally.
6
6
  */
7
7
  export interface ResolvedRoutePath {
8
- /** State identifier owning the route (e.g. `"app.dashboard.settings"`). */
8
+ /** The identifier of the state that owns the route, for example `"app.dashboard.settings"`. */
9
9
  stateId: string;
10
- /** Resolved absolute route path (e.g. `"/dashboard/settings"`). */
10
+ /** The resolved absolute route path, for example `"/dashboard/settings"`. */
11
11
  fullPath: string;
12
12
  }
13
13
  /**
14
- * Validate route path format
14
+ * Checks the format of a route path
15
15
  *
16
- * Ensures route paths are non-empty strings. Both absolute paths ("/foo")
17
- * and relative paths ("foo", "child/nested") are accepted. Relative routes
18
- * inherit their parent state's path prefix when the tree is built.
16
+ * The function requires a string that is not empty. It accepts an absolute path
17
+ * ("/foo") and also a relative path ("foo" or "child/nested"). A relative route
18
+ * receives the path prefix of its parent state during the construction of the tree.
19
19
  *
20
- * @param routePath - Route path to validate (absolute or relative)
21
- * @param stateId - State identifier for error messages
22
- * @throws {EmptyRoutePathError} If route path is empty
20
+ * @param routePath - The route path to check: absolute or relative
21
+ * @param stateId - The identifier of the state, for the error message
22
+ * @throws {EmptyRoutePathError} When the route path is empty
23
23
  */
24
24
  export declare const validateRouteFormat: (routePath: string, stateId: string) => void;
25
25
  /**
26
- * Validate state exists in state ID set
26
+ * Checks that the set of the state IDs holds a state
27
27
  *
28
- * Ensures referenced state IDs exist in the machine graph.
29
- * Build-time validation prevents broken route references.
28
+ * The function requires each state ID of a reference in the machine graph. This
29
+ * check at the build time therefore stops a broken route reference.
30
30
  *
31
- * @param stateId - State identifier to validate
32
- * @param stateIds - Set of all known state IDs from the machine graph
33
- * @throws {InvalidStateIdError} If state ID doesn't exist in set
31
+ * @param stateId - The identifier of the state to check
32
+ * @param stateIds - The set of every known state ID of the machine graph
33
+ * @throws {InvalidStateIdError} When the set does not hold the state ID
34
34
  */
35
35
  export declare const validateStateExists: (stateId: string, stateIds: Set<string>) => void;
36
36
  /**
37
- * Detect duplicate route paths
37
+ * Finds each duplicate route path
38
38
  *
39
- * THROWS ERROR when multiple states share the same RESOLVED full path.
39
+ * The function THROWS AN ERROR when more than one state holds the same RESOLVED
40
+ * complete path.
40
41
  *
41
- * Detection operates on resolved full paths (after relative routes have been
42
- * prefixed with their parent's path in `buildRouteTree`), not on raw route
43
- * strings: two relative `"settings"` routes under different parents resolve to
44
- * distinct full paths and are valid, while a relative route and an absolute
45
- * route resolving to the same URL genuinely collide and must be rejected.
46
- * Called from `buildRouteTree` once full paths are known.
42
+ * The detection works on the resolved complete paths, after `buildRouteTree` put the
43
+ * path of each parent before its relative routes. It does not work on the raw route
44
+ * strings: two relative `"settings"` routes below two different parents resolve to
45
+ * two different complete paths, and they are valid; a relative route and an absolute
46
+ * route that resolve to the same URL are a real collision, and the function refuses
47
+ * them. `buildRouteTree` calls this function when the complete paths are known.
47
48
  *
48
- * Rationale: URL-based routing requires one-to-one mapping between URLs and states.
49
- * Multiple states at the same path creates ambiguity for browser navigation (back button,
50
- * direct URL access). Use different paths for different states, or single state with
51
- * conditional rendering.
49
+ * The reason: a routing on the URL requires one state for each URL. Two states at
50
+ * the same path make the browser navigation ambiguous, for the BACK button and for a
51
+ * direct URL. Use a different path for each state, or use one state with a
52
+ * conditional render.
52
53
  *
53
- * @param routes - Array of route entries with resolved full paths (e.g. `RouteNode`s)
54
- * @throws {DuplicateRoutePathError} If duplicate resolved route paths are detected
54
+ * @param routes - The array of the route entries with their resolved complete paths, for example the `RouteNode` objects
55
+ * @throws {DuplicateRoutePathError} When the function finds two resolved route paths that are equal
55
56
  */
56
57
  export declare const detectDuplicateRoutes: (routes: ResolvedRoutePath[]) => void;
57
58
  //# sourceMappingURL=validate-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-routes.d.ts","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,IAIxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,GAAG,CAAC,MAAM,CAAC,KAAG,IAI5E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,iBAAiB,EAAE,KAAG,IAqBnE,CAAC"}
1
+ {"version":3,"file":"validate-routes.d.ts","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,IAIxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,GAAG,CAAC,MAAM,CAAC,KAAG,IAI5E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,iBAAiB,EAAE,KAAG,IAqBnE,CAAC"}
@@ -1,14 +1,14 @@
1
1
  import { EmptyRoutePathError, InvalidStateIdError, DuplicateRoutePathError } from "./errors.js";
2
2
  /**
3
- * Validate route path format
3
+ * Checks the format of a route path
4
4
  *
5
- * Ensures route paths are non-empty strings. Both absolute paths ("/foo")
6
- * and relative paths ("foo", "child/nested") are accepted. Relative routes
7
- * inherit their parent state's path prefix when the tree is built.
5
+ * The function requires a string that is not empty. It accepts an absolute path
6
+ * ("/foo") and also a relative path ("foo" or "child/nested"). A relative route
7
+ * receives the path prefix of its parent state during the construction of the tree.
8
8
  *
9
- * @param routePath - Route path to validate (absolute or relative)
10
- * @param stateId - State identifier for error messages
11
- * @throws {EmptyRoutePathError} If route path is empty
9
+ * @param routePath - The route path to check: absolute or relative
10
+ * @param stateId - The identifier of the state, for the error message
11
+ * @throws {EmptyRoutePathError} When the route path is empty
12
12
  */
13
13
  export const validateRouteFormat = (routePath, stateId) => {
14
14
  if (!routePath) {
@@ -16,14 +16,14 @@ export const validateRouteFormat = (routePath, stateId) => {
16
16
  }
17
17
  };
18
18
  /**
19
- * Validate state exists in state ID set
19
+ * Checks that the set of the state IDs holds a state
20
20
  *
21
- * Ensures referenced state IDs exist in the machine graph.
22
- * Build-time validation prevents broken route references.
21
+ * The function requires each state ID of a reference in the machine graph. This
22
+ * check at the build time therefore stops a broken route reference.
23
23
  *
24
- * @param stateId - State identifier to validate
25
- * @param stateIds - Set of all known state IDs from the machine graph
26
- * @throws {InvalidStateIdError} If state ID doesn't exist in set
24
+ * @param stateId - The identifier of the state to check
25
+ * @param stateIds - The set of every known state ID of the machine graph
26
+ * @throws {InvalidStateIdError} When the set does not hold the state ID
27
27
  */
28
28
  export const validateStateExists = (stateId, stateIds) => {
29
29
  if (!stateIds.has(stateId)) {
@@ -31,34 +31,35 @@ export const validateStateExists = (stateId, stateIds) => {
31
31
  }
32
32
  };
33
33
  /**
34
- * Detect duplicate route paths
34
+ * Finds each duplicate route path
35
35
  *
36
- * THROWS ERROR when multiple states share the same RESOLVED full path.
36
+ * The function THROWS AN ERROR when more than one state holds the same RESOLVED
37
+ * complete path.
37
38
  *
38
- * Detection operates on resolved full paths (after relative routes have been
39
- * prefixed with their parent's path in `buildRouteTree`), not on raw route
40
- * strings: two relative `"settings"` routes under different parents resolve to
41
- * distinct full paths and are valid, while a relative route and an absolute
42
- * route resolving to the same URL genuinely collide and must be rejected.
43
- * Called from `buildRouteTree` once full paths are known.
39
+ * The detection works on the resolved complete paths, after `buildRouteTree` put the
40
+ * path of each parent before its relative routes. It does not work on the raw route
41
+ * strings: two relative `"settings"` routes below two different parents resolve to
42
+ * two different complete paths, and they are valid; a relative route and an absolute
43
+ * route that resolve to the same URL are a real collision, and the function refuses
44
+ * them. `buildRouteTree` calls this function when the complete paths are known.
44
45
  *
45
- * Rationale: URL-based routing requires one-to-one mapping between URLs and states.
46
- * Multiple states at the same path creates ambiguity for browser navigation (back button,
47
- * direct URL access). Use different paths for different states, or single state with
48
- * conditional rendering.
46
+ * The reason: a routing on the URL requires one state for each URL. Two states at
47
+ * the same path make the browser navigation ambiguous, for the BACK button and for a
48
+ * direct URL. Use a different path for each state, or use one state with a
49
+ * conditional render.
49
50
  *
50
- * @param routes - Array of route entries with resolved full paths (e.g. `RouteNode`s)
51
- * @throws {DuplicateRoutePathError} If duplicate resolved route paths are detected
51
+ * @param routes - The array of the route entries with their resolved complete paths, for example the `RouteNode` objects
52
+ * @throws {DuplicateRoutePathError} When the function finds two resolved route paths that are equal
52
53
  */
53
54
  export const detectDuplicateRoutes = (routes) => {
54
55
  const routeMap = new Map();
55
- // Build map of resolved full paths to state IDs
56
+ // Build the map from each resolved complete path to its state IDs
56
57
  for (const route of routes) {
57
58
  const stateIds = routeMap.get(route.fullPath) || [];
58
59
  stateIds.push(route.stateId);
59
60
  routeMap.set(route.fullPath, stateIds);
60
61
  }
61
- // Check for duplicates and throw error
62
+ // Find each duplicate, and throw an error
62
63
  const duplicates = [];
63
64
  for (const [routePath, stateIds] of routeMap.entries()) {
64
65
  if (stateIds.length > 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"validate-routes.js","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAehG;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,OAAe,EAAQ,EAAE;IAC/E,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,QAAqB,EAAQ,EAAE;IACnF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAA2B,EAAQ,EAAE;IAC1E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,gDAAgD;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,uCAAuC;IACvC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,IAAI,CAAC,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"validate-routes.js","sourceRoot":"","sources":["../src/validate-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAehG;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,OAAe,EAAQ,EAAE;IAC/E,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,QAAqB,EAAQ,EAAE;IACnF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;AACF,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAA2B,EAAQ,EAAE;IAC1E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,kEAAkE;IAClE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACpD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,0CAA0C;IAC1C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,IAAI,CAAC,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;IACF,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;AACF,CAAC,CAAC"}