@avstantso/react-router-utils 0.1.2 → 0.2.1

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.
@@ -1,4 +1,3 @@
1
- import TS = AVStantso.TS;
2
1
  import type React from 'react';
3
2
  import type { NavigateFunction, NavigateOptions, NavigateProps } from 'react-router-dom';
4
3
  import type { BindedPath, BindProps } from '../core';
@@ -33,20 +32,23 @@ export declare namespace NavigatesTree {
33
32
  /**
34
33
  * @summary Navigate node component
35
34
  */
36
- type Leaf<P extends object = undefined> = React.FC<BindedNavigate.Props & ([
37
- keyof P
38
- ] extends [never] ? unknown : {
39
- params: P;
40
- })>;
35
+ type Leaf<TTypeMap extends UrlsTree.TypeMap> = React.FC<BindedNavigate.Props & UrlsTree.ResolveParams<TTypeMap, 'field'>>;
41
36
  /**
42
37
  * @summary Navigate component node based on url tree
43
38
  */
44
- type Node<TTree extends UrlsTree, TNode extends object, TParams extends object = {}, P extends TS.Keys = []> = (TNode extends UrlsTree.Node ? Leaf<TParams> : unknown) & {
45
- [K in UrlsTree.Key<TTree, TNode> as UrlsTree.ResolveKey<TTree, TParams, TNode, K>]: Node<TTree, Extract<TNode[K], UrlsTree.Node>, UrlsTree.ResolveParam<TTree, TParams, TNode, K>, [
46
- K,
47
- ...P
48
- ]>;
39
+ type Node<TTypeMap extends UrlsTree.TypeMap, F extends UrlsTree.IsFind<TTypeMap> = UrlsTree.IsFind<TTypeMap>> = F extends 'found' ? Node<Omit<TTypeMap, 'Find'>> : F extends 'not-found' ? {
40
+ [K in UrlsTree.Key<TTypeMap>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
41
+ }[UrlsTree.Key<TTypeMap>] : (TTypeMap extends {
42
+ Node: UrlsTree.Node;
43
+ } ? Leaf<TTypeMap> : unknown) & {
44
+ [K in UrlsTree.Key<TTypeMap> as UrlsTree.ResolveKey<TTypeMap, K>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
49
45
  };
46
+ namespace Node {
47
+ type Root<TTree extends UrlsTree, TFind extends string | UrlsTree.Node = undefined> = Node<UrlsTree.TypeMap.Init<TTree, TFind, {
48
+ ParamReplacePrefix: '$';
49
+ Casing: 'p';
50
+ }>>;
51
+ }
50
52
  }
51
53
  /**
52
54
  * `useNavigate` tree
@@ -55,19 +57,29 @@ export declare namespace NavigatesTree {
55
57
  /**
56
58
  * @summary Navigate hook node function
57
59
  */
58
- type Leaf<P extends object = undefined> = BindedNavigate.UseFunction<P>;
60
+ type Leaf<TTypeMap extends UrlsTree.TypeMap> = BindedNavigate.UseFunction<UrlsTree.ResolveParam<TTypeMap>>;
59
61
  /**
60
62
  * @summary Navigate hook node based on url tree
61
63
  */
62
- type Node<TTree extends UrlsTree, TNode extends object, TParams extends object = {}, P extends TS.Keys = []> = (TNode extends UrlsTree.Node ? Leaf<TParams> : unknown) & {
63
- [K in UrlsTree.Key<TTree, TNode> as UrlsTree.ResolveKey<TTree, TParams, TNode, K>]: Node<TTree, Extract<TNode[K], UrlsTree.Node>, UrlsTree.ResolveParam<TTree, TParams, TNode, K>, [
64
- K,
65
- ...P
66
- ]>;
64
+ type Node<TTypeMap extends UrlsTree.TypeMap, F extends UrlsTree.IsFind<TTypeMap> = UrlsTree.IsFind<TTypeMap>> = F extends 'found' ? Node<Omit<TTypeMap, 'Find'>> : F extends 'not-found' ? {
65
+ [K in UrlsTree.Key<TTypeMap>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
66
+ }[UrlsTree.Key<TTypeMap>] : (TTypeMap extends {
67
+ Node: UrlsTree.Node;
68
+ } ? Leaf<TTypeMap> : unknown) & {
69
+ [K in UrlsTree.Key<TTypeMap> as UrlsTree.ResolveKey<TTypeMap, K>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
67
70
  };
71
+ namespace Node {
72
+ type Root<TTree extends UrlsTree, TFind extends string | UrlsTree.Node = undefined> = Node<UrlsTree.TypeMap.Init<TTree, TFind, {
73
+ ParamReplacePrefix: '$';
74
+ Casing: 'p';
75
+ }>>;
76
+ }
68
77
  }
69
78
  }
70
- export type NavigatesTree<TTree extends UrlsTree> = NavigatesTree.Component.Node<TTree, TTree & object> & {
71
- useNavigate(): NavigateFunction & NavigatesTree.Hook.Node<TTree, TTree & object>;
79
+ export type NavigatesTree<TTree extends UrlsTree> = NavigatesTree.Component.Node.Root<TTree> & {
80
+ AT<TNode extends UrlsTree.Node>(node: TNode): NavigatesTree.Component.Node.Root<TTree, TNode>;
81
+ useNavigate(): NavigateFunction & NavigatesTree.Hook.Node.Root<TTree> & {
82
+ AT<TNode extends UrlsTree.Node>(node: TNode): NavigatesTree.Hook.Node.Root<TTree, TNode>;
83
+ };
72
84
  };
73
85
  export {};
@@ -8,18 +8,29 @@ type BRO = RouteCreator.BindedRouteObject;
8
8
  export declare namespace RouteCreator {
9
9
  type Type = 'url' | 'name';
10
10
  type BindedRouteObject = Omit<RouteObject, 'path'>;
11
- type Method = (routeObject: BRO) => RouteObject;
12
11
  /**
13
12
  * @summary Create node route function
14
13
  */
15
- type Leaf = Method;
14
+ type Leaf<TNode> = {
15
+ (routeObject: BRO): RouteObject;
16
+ (makeRouteObjectCallback: (node: TNode) => BRO): RouteObject;
17
+ };
16
18
  /**
17
19
  * @summary Component node based on url tree
18
20
  */
19
- type Node<TTree extends UrlsTree, TNode extends object> = (TNode extends UrlsTree.Node ? Leaf : unknown) & {
20
- [K in UrlsTree.Key<TTree, TNode> as UrlsTree.ResolveKey<TTree, undefined, TNode, K>]: Node<TTree, Extract<TNode[K], UrlsTree.Node>>;
21
- };
21
+ type Node<TTypeMap extends UrlsTree.TypeMap, F extends UrlsTree.IsFind<TTypeMap> = UrlsTree.IsFind<TTypeMap>> = F extends 'found' ? Node<Omit<TTypeMap, 'Find'>> : F extends 'not-found' ? {
22
+ [K in UrlsTree.Key<TTypeMap>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
23
+ }[UrlsTree.Key<TTypeMap>] : {
24
+ [K in UrlsTree.Key<TTypeMap> as UrlsTree.ResolveKey<TTypeMap, K>]: Node<UrlsTree.TypeMap.Next<TTypeMap, K>>;
25
+ } extends infer Children ? (TTypeMap extends {
26
+ Node: UrlsTree.Node;
27
+ } ? Leaf<Children> : unknown) & Children : never;
28
+ namespace Node {
29
+ type Root<TTree extends UrlsTree, TFind extends string | UrlsTree.Node = undefined> = Node<UrlsTree.TypeMap.Init<TTree, TFind, {
30
+ Casing: 'p';
31
+ }>>;
32
+ }
22
33
  type Factory = <TTree extends UrlsTree>(urlsTree: TTree) => RouteCreator<TTree>;
23
34
  }
24
- export type RouteCreator<TTree extends UrlsTree> = (type: CRT, commonProps?: BRO) => RouteCreator.Node<TTree, TTree & object>;
35
+ export type RouteCreator<TTree extends UrlsTree> = (type: CRT, commonProps?: BRO) => RouteCreator.Node.Root<TTree>;
25
36
  export {};
@@ -1,5 +1,6 @@
1
1
  import TS = AVStantso.TS;
2
2
  import { NamesTree } from '@avstantso/utils-names-tree';
3
+ type _Casing = 'c' | 'p' | 's' | 'S' | 'k';
3
4
  /**
4
5
  * @summary Routes url tree
5
6
  */
@@ -8,21 +9,140 @@ export declare namespace UrlsTree {
8
9
  * @summary One route url tree node
9
10
  */
10
11
  type Node = NamesTree.Presets.Urls.Constraint;
12
+ namespace Node {
13
+ type _Params<TParts extends readonly string[], R extends TS.Key[] = []> = TParts extends readonly [infer C extends string, ...infer Rest extends readonly string[]] ? _Params<Rest, C extends `:${infer P extends string}` ? [...R, P] : R> : R;
14
+ /**
15
+ * @summary Get node params names array
16
+ */
17
+ export type Params<TNode extends Node> = _Params<TS.String.Split<TNode['_path'], '/'>>;
18
+ export {};
19
+ }
11
20
  /**
12
21
  * @summary Urls tree `rootAlias` type
13
22
  */
14
23
  type RootAlias<TTree extends UrlsTree> = TTree[Extract<typeof NamesTree.symbolRootAlias, keyof TTree>];
15
24
  /**
16
- * @summary Tree node url key for components generation
25
+ * @summary Typemap for complex generic
17
26
  */
18
- type Key<TTree extends UrlsTree, N extends object, K extends keyof N = keyof N> = K extends string ? K extends UrlsTree.RootAlias<TTree> ? K : K extends (N[K] extends Function ? TS.Func.RestrictionsForExt : never) | `${'_' | '$' | TS.Letter.Upper}${string}` ? never : N[K] extends UrlsTree.Node ? K : never : never;
27
+ type TypeMap = {
28
+ /**
29
+ * @summary Initial tree type
30
+ */
31
+ Tree: UrlsTree;
32
+ /**
33
+ * @summary Initial tree current node type
34
+ */
35
+ Node?: Node;
36
+ /**
37
+ * @summary Params keys array
38
+ */
39
+ Params?: TS.Keys;
40
+ /**
41
+ * @summary Params is required
42
+ */
43
+ ParamsIsRequired?: boolean;
44
+ /**
45
+ * @summary Find criteria `_url` or `Node`
46
+ */
47
+ Find?: string | Node;
48
+ /**
49
+ * @summary Param replace prefix
50
+ */
51
+ ParamReplacePrefix?: string;
52
+ /**
53
+ * @summary Param replace casing
54
+ */
55
+ Casing?: _Casing;
56
+ };
57
+ namespace TypeMap {
58
+ /**
59
+ * @summary Init typemap for complex generic
60
+ */
61
+ type Init<TTree extends UrlsTree, TFind extends string | UrlsTree.Node = undefined, TExtends extends object = {}> = {
62
+ Tree: TTree;
63
+ } & (TFind extends undefined ? unknown : {
64
+ Find: TFind;
65
+ }) & TExtends;
66
+ /**
67
+ * @summary Next node typemap for complex generic
68
+ */
69
+ type Next<TTypeMap extends TypeMap, TKey extends TypeMap.Key<TTypeMap>> = (TTypeMap extends {
70
+ Node: infer TParentNode extends Node;
71
+ } ? TParentNode[Extract<TKey, keyof TParentNode>] : TTypeMap['Tree'][Extract<TKey, keyof TTypeMap['Tree']>]) extends infer TNode extends Node ? TTypeMap extends {
72
+ Tree: infer TTree extends UrlsTree;
73
+ } ? {
74
+ Tree: TTree;
75
+ Node: TNode;
76
+ } & ((TNode extends {
77
+ _name: `:${infer TParam extends string}`;
78
+ } ? [TParam] : []) extends infer TParams extends TS.Keys ? TTypeMap extends {
79
+ Params: infer TParentParams extends TS.Keys;
80
+ } ? {
81
+ Params: [...TParentParams, ...TParams];
82
+ } : {
83
+ Params: TParams;
84
+ } : never) & (TTypeMap extends {
85
+ ParamsIsRequired: infer PIR extends boolean;
86
+ } ? {
87
+ ParamsIsRequired: PIR;
88
+ } : unknown) & (TTypeMap extends {
89
+ Find: infer TFind extends string | Node;
90
+ } ? {
91
+ Find: TFind;
92
+ } : unknown) & (TTypeMap extends {
93
+ ParamReplacePrefix: infer PRP extends string;
94
+ } ? {
95
+ ParamReplacePrefix: PRP;
96
+ } : unknown) & (TTypeMap extends {
97
+ Casing: infer C extends _Casing;
98
+ } ? {
99
+ Casing: C;
100
+ } : unknown) : never : never;
101
+ /**
102
+ * @summary Typemap curent node key union
103
+ */
104
+ type Key<TTypeMap extends TypeMap> = TTypeMap extends {
105
+ Node: infer TNode extends Node;
106
+ } ? keyof TNode : keyof TTypeMap['Tree'];
107
+ /**
108
+ * @summary Typemap based casing
109
+ */
110
+ type Casing<TTypeMap extends TypeMap, S extends string> = TTypeMap extends {
111
+ Casing: infer C extends _Casing;
112
+ } ? TS.String.Case<C, S> : S;
113
+ }
114
+ /**
115
+ * @summary Filtered tree node url key for components generation
116
+ */
117
+ type Key<TTypeMap extends TypeMap, K extends TypeMap.Key<TTypeMap> = TypeMap.Key<TTypeMap>> = K extends string ? K extends UrlsTree.RootAlias<TTypeMap['Tree']> ? K : K extends (TTypeMap['Node'][K] extends Function ? TS.Func.RestrictionsForExt : never) | `${'_' | '$' | TS.Letter.Upper}${string}` ? never : K : never;
19
118
  /**
20
119
  * @summary Component node key resolving
21
120
  */
22
- type ResolveKey<TTree extends UrlsTree, P extends object, N extends object, K extends UrlsTree.Key<TTree, N>> = K extends `:${infer C extends string}` ? P extends undefined ? K : `$${TS.String.Case.Pascal<C>}` : TS.String.Case.Pascal<K>;
121
+ type ResolveKey<TTypeMap extends TypeMap, K extends Key<TTypeMap> = Key<TTypeMap>> = K extends `:${infer C extends string}` ? TTypeMap extends {
122
+ ParamReplacePrefix: infer PRP extends string;
123
+ } ? `${PRP}${TypeMap.Casing<TTypeMap, C>}` : K : TypeMap.Casing<TTypeMap, K>;
23
124
  /**
24
125
  * @summary Component node params resolving
25
126
  */
26
- type ResolveParam<TTree extends UrlsTree, P extends object, N extends object, K extends UrlsTree.Key<TTree, N>, Required extends boolean = false> = K extends `:${infer C extends string}` ? Record<C, string> extends infer X ? P & (Required extends true ? X : Partial<X>) : never : P;
127
+ type ResolveParam<TTypeMap extends TypeMap> = ((TTypeMap extends {
128
+ Params: infer P extends TS.Keys;
129
+ } ? P : [])) extends infer P extends TS.Keys ? TTypeMap extends {
130
+ ParamsIsRequired: true;
131
+ } ? Record<P[number], string> : Partial<Record<P[number], string>> : never;
132
+ /**
133
+ * @summary Component node params resolving to:
134
+ * - `optional` — `[params?: P]` / `[]`
135
+ * - `required` — `[params: P]` / `[]`
136
+ * - `field` — `{ [K in Field]: P }` / `{}`
137
+ */
138
+ type ResolveParams<TTypeMap extends TypeMap, Kind extends 'optional' | 'required' | 'field', Field extends Kind extends 'field' ? string : never = Kind extends 'field' ? 'params' : never, P extends ResolveParam<TTypeMap> = ResolveParam<TTypeMap>> = [keyof P] extends [never] ? Kind extends 'optional' | 'required' ? [] : unknown : Kind extends 'optional' ? [params?: P] : Kind extends 'required' ? [params: P] : {
139
+ [K in Field]: P;
140
+ };
141
+ type IsFind<TTypeMap extends UrlsTree.TypeMap> = TTypeMap extends {
142
+ Find: infer F extends string | Node;
143
+ } ? TTypeMap extends {
144
+ Node: infer N extends Node;
145
+ } ? (F extends Node ? F['_url'] : F) extends N['_url'] ? 'found' : 'not-found' : 'not-found' : 'node';
27
146
  }
28
147
  export type UrlsTree<T extends NamesTree.Source.Root = any, O extends NamesTree.Options = any> = NamesTree.Presets.Urls.Tree<T, O>;
148
+ export {};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@avstantso/react-router-utils",
3
3
  "license": "MIT",
4
4
  "author": "avstantso",
5
- "version": "0.1.2",
5
+ "version": "0.2.1",
6
6
  "description": "AVStantso react-router-dom enhancement package",
7
7
  "keywords": [
8
8
  "react-router-dom",
@@ -24,8 +24,8 @@
24
24
  "test": "NODE_ENV=test jest --coverage"
25
25
  },
26
26
  "dependencies": {
27
- "@avstantso/utils-misc": "^1.2.4",
28
- "@avstantso/utils-names-tree": "^1.3.2",
27
+ "@avstantso/utils-misc": "^1.2.5",
28
+ "@avstantso/utils-names-tree": "^1.3.3",
29
29
  "react": "^18.3.1",
30
30
  "react-dom": "^18.3.1",
31
31
  "react-router-dom": "^7.12.0"