@loozo/angular-router 0.0.1 → 0.0.2
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.
- package/README.md +38 -9
- package/fesm2022/loozo-angular-router-_core.mjs +68 -0
- package/fesm2022/loozo-angular-router-_core.mjs.map +1 -1
- package/fesm2022/loozo-angular-router-_generated.mjs.map +1 -1
- package/fesm2022/loozo-angular-router.mjs +13 -0
- package/fesm2022/loozo-angular-router.mjs.map +1 -1
- package/node/src/builders/options.js +29 -3
- package/node/src/builders/serve.js +2 -2
- package/node/src/generation/emit.js +26 -1
- package/node/src/generation/files.js +28 -7
- package/node/src/generation/filesystem.js +343 -0
- package/node/src/generation/generate.js +14 -3
- package/node/src/generation/overlay.js +84 -0
- package/node/src/generation/sources.js +64 -23
- package/node/src/generation/validate.js +16 -1
- package/package.json +1 -1
- package/schemas/application.json +23 -0
- package/schemas/serve.json +23 -0
- package/types/loozo-angular-router-_core.d.ts +299 -0
- package/types/loozo-angular-router-_generated.d.ts +115 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loozo/angular-router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Typed route declarations, URLs, navigation and route handles for Angular's native router.",
|
|
5
5
|
"bugs": "https://github.com/theo-matzavinos/loozo/issues",
|
|
6
6
|
"license": "MIT",
|
package/schemas/application.json
CHANGED
|
@@ -8,8 +8,31 @@
|
|
|
8
8
|
"scanDirectories": {
|
|
9
9
|
"type": "array",
|
|
10
10
|
"minItems": 1,
|
|
11
|
+
"maxItems": 1,
|
|
11
12
|
"items": { "type": "string", "minLength": 1 }
|
|
12
13
|
},
|
|
14
|
+
"autoDefineRoutes": {
|
|
15
|
+
"$comment": "Conditional validation prevents Angular addUndefinedDefaults from creating an omitted opt-in object.",
|
|
16
|
+
"if": true,
|
|
17
|
+
"then": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"additionalProperties": false,
|
|
20
|
+
"properties": {
|
|
21
|
+
"filename": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"pattern": "^[A-Za-z0-9_$][A-Za-z0-9_$.-]*\\.ts$",
|
|
24
|
+
"not": {
|
|
25
|
+
"anyOf": [
|
|
26
|
+
{ "pattern": "\\.d\\.ts$" },
|
|
27
|
+
{
|
|
28
|
+
"enum": ["route.generated.ts", "routes.generated.ts", "destinations.generated.ts"]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
13
36
|
"outDirectory": { "type": "string", "minLength": 1 },
|
|
14
37
|
"delegateTarget": { "type": "string", "minLength": 1 },
|
|
15
38
|
"check": { "type": "boolean", "default": false }
|
package/schemas/serve.json
CHANGED
|
@@ -8,8 +8,31 @@
|
|
|
8
8
|
"scanDirectories": {
|
|
9
9
|
"type": "array",
|
|
10
10
|
"minItems": 1,
|
|
11
|
+
"maxItems": 1,
|
|
11
12
|
"items": { "type": "string", "minLength": 1 }
|
|
12
13
|
},
|
|
14
|
+
"autoDefineRoutes": {
|
|
15
|
+
"$comment": "Conditional validation prevents Angular addUndefinedDefaults from creating an omitted opt-in object.",
|
|
16
|
+
"if": true,
|
|
17
|
+
"then": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"additionalProperties": false,
|
|
20
|
+
"properties": {
|
|
21
|
+
"filename": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"pattern": "^[A-Za-z0-9_$][A-Za-z0-9_$.-]*\\.ts$",
|
|
24
|
+
"not": {
|
|
25
|
+
"anyOf": [
|
|
26
|
+
{ "pattern": "\\.d\\.ts$" },
|
|
27
|
+
{
|
|
28
|
+
"enum": ["route.generated.ts", "routes.generated.ts", "destinations.generated.ts"]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
13
36
|
"outDirectory": { "type": "string", "minLength": 1 },
|
|
14
37
|
"delegateTarget": { "type": "string", "minLength": 1 }
|
|
15
38
|
}
|
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
import { RedirectCommand, RunGuardsAndResolvers, ActivatedRouteSnapshot, RouterStateSnapshot, MaybeAsync, GuardResult, Route as Route$1, UrlSegment, PartialMatchRouteSnapshot } from '@angular/router';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Converts one decoded path or search value to and from an application value.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Parsing may be asynchronous; stringification must be synchronous. Neither
|
|
9
|
+
* method performs URL encoding. Codecs have no Angular injection-context
|
|
10
|
+
* guarantee, and their returned objects are not recursively frozen.
|
|
11
|
+
* For a terminal `$name[]` path, this codec applies to each element separately.
|
|
12
|
+
*
|
|
13
|
+
* @typeParam Value - The logical value, not a promise of that value.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const dateParam: ParamCodec<Date> = {
|
|
18
|
+
* parse: (raw) => new Date(raw),
|
|
19
|
+
* stringify: (value) => value.toISOString(),
|
|
20
|
+
* };
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
4
23
|
interface ParamCodec<Value> {
|
|
24
|
+
/**
|
|
25
|
+
* Parses one already percent-decoded value; do not decode it again.
|
|
26
|
+
*
|
|
27
|
+
* @param raw - A single logical string from Angular's URL inputs.
|
|
28
|
+
* @returns The logical value or a promise for it.
|
|
29
|
+
* @throws An application error for invalid input; generated input parsing
|
|
30
|
+
* reports throws and rejections as invalid path/search values with a cause.
|
|
31
|
+
*/
|
|
5
32
|
parse(raw: string): Value | Promise<Value>;
|
|
33
|
+
/**
|
|
34
|
+
* Serializes one logical value without percent-encoding it.
|
|
35
|
+
*
|
|
36
|
+
* @param value - The application value to serialize.
|
|
37
|
+
* @returns An unencoded string. Path output must not be empty, `.` or `..`.
|
|
38
|
+
* @throws An application error when the value cannot be serialized.
|
|
39
|
+
*/
|
|
6
40
|
stringify(value: Value): string;
|
|
7
41
|
}
|
|
8
42
|
declare const searchPresence: unique symbol;
|
|
43
|
+
/** A search-only codec whose key may be omitted or supplied as `undefined`. */
|
|
9
44
|
type OptionalCodec<Value> = ParamCodec<Value | undefined> & {
|
|
10
45
|
readonly [searchPresence]: "optional";
|
|
11
46
|
};
|
|
47
|
+
/** A search-only codec that represents explicit `null` as the text `"null"`. */
|
|
12
48
|
type NullableCodec<Value> = ParamCodec<Value | null> & {
|
|
13
49
|
readonly [searchPresence]: "nullable";
|
|
14
50
|
};
|
|
@@ -20,11 +56,79 @@ type IsOptional<Codec> = Codec extends {
|
|
|
20
56
|
readonly [searchPresence]: "optional";
|
|
21
57
|
} ? true : false;
|
|
22
58
|
declare function codecPresence(codec: object): "optional" | "nullable" | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Preserves strings verbatim, including empty strings and literal percent text.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* Empty, dot and dotdot values are valid codec values but cannot be serialized
|
|
64
|
+
* into path segments by URL creation. Search values may contain them.
|
|
65
|
+
*/
|
|
23
66
|
declare const stringParam: ParamCodec<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Parses nonblank text with JavaScript `Number` and requires a finite result.
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* Whitespace around numbers, exponent notation and hexadecimal text are accepted.
|
|
72
|
+
* Blank text, NaN and infinities throw. Stringification requires a finite number
|
|
73
|
+
* and uses its JavaScript string representation (including `-0` becoming `"0"`).
|
|
74
|
+
*/
|
|
24
75
|
declare const numberParam: ParamCodec<number>;
|
|
76
|
+
/**
|
|
77
|
+
* Parses only lowercase `"true"` and `"false"`, and emits those same strings.
|
|
78
|
+
* Other representations and nonboolean values throw.
|
|
79
|
+
*/
|
|
25
80
|
declare const booleanParam: ParamCodec<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Creates a case-sensitive string codec from a snapshotted list of members.
|
|
83
|
+
*
|
|
84
|
+
* @typeParam Values - The literal list from which the value union is inferred.
|
|
85
|
+
* @param values - Allowed decoded strings; an empty string is valid when listed.
|
|
86
|
+
* @returns A codec whose parser and stringifier reject nonmembers.
|
|
87
|
+
* @throws TypeError if the list or its entries are malformed.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const tab = enumParam(["details", "reviews"]);
|
|
92
|
+
* tab.parse("reviews"); // "reviews"
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
26
95
|
declare function enumParam<const Values extends readonly string[]>(values: Values): ParamCodec<Values[number]>;
|
|
96
|
+
/**
|
|
97
|
+
* Makes a search key optional without changing the handling of present values.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* Generated parsing omits absent keys; URL creation omits absent or `undefined`
|
|
101
|
+
* values. The wrapper's parser delegates present strings unchanged, preserving
|
|
102
|
+
* promises and failures. Its stringifier cannot serialize `undefined` directly.
|
|
103
|
+
* This wrapper is not a path codec. For optional nullable values, wrap
|
|
104
|
+
* {@link nullableSearchParam} with this function, not the other way around.
|
|
105
|
+
*
|
|
106
|
+
* @typeParam Value - The wrapped codec's logical value.
|
|
107
|
+
* @param codec - The codec used for present search values.
|
|
108
|
+
* @returns A search-only codec allowing omission.
|
|
109
|
+
* @throws TypeError if the codec lacks callable parse/stringify methods.
|
|
110
|
+
*/
|
|
27
111
|
declare function optionalSearchParam<Value>(codec: ParamCodec<Value>): OptionalCodec<Value>;
|
|
112
|
+
/**
|
|
113
|
+
* Adds explicit null to a search codec, represented by the decoded text `"null"`.
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* The key remains required unless wrapped with {@link optionalSearchParam}.
|
|
117
|
+
* Non-null values delegate unchanged, including promise/failure identity. The
|
|
118
|
+
* text `"null"` is reserved by this wrapper even if the inner codec accepts it.
|
|
119
|
+
* This wrapper is not a path codec and cannot wrap an optional search codec.
|
|
120
|
+
*
|
|
121
|
+
* @typeParam Value - The wrapped codec's non-null logical value.
|
|
122
|
+
* @param codec - The codec used for values other than null.
|
|
123
|
+
* @returns A search-only codec accepting and serializing null.
|
|
124
|
+
* @throws TypeError if the codec is malformed or is an optional search wrapper.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const score = optionalSearchParam(nullableSearchParam(numberParam));
|
|
129
|
+
* // Omission, null, and a present number remain distinct.
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
28
132
|
declare function nullableSearchParam<Value>(codec: ParamCodec<Value> & {
|
|
29
133
|
readonly [searchPresence]?: "nullable";
|
|
30
134
|
}): NullableCodec<Value>;
|
|
@@ -46,25 +150,51 @@ type Segment = {
|
|
|
46
150
|
};
|
|
47
151
|
|
|
48
152
|
declare const routeBrand: unique symbol;
|
|
153
|
+
/**
|
|
154
|
+
* A nominal route declaration created by `defineRoute`, not a native Angular Route.
|
|
155
|
+
*
|
|
156
|
+
* @remarks
|
|
157
|
+
* Prefer inference from `defineRoute` over explicit generic arguments. The
|
|
158
|
+
* optional `__params`, `__search` and `__data` members are type witnesses only;
|
|
159
|
+
* they are not populated runtime properties. Parent/codec/effective-path metadata
|
|
160
|
+
* is private. Spreading a declaration does not produce another valid route.
|
|
161
|
+
*
|
|
162
|
+
* @typeParam Path - The local authored path literal, not the effective URL path.
|
|
163
|
+
* @typeParam Params - Effective inherited and local logical path values.
|
|
164
|
+
* @typeParam Search - Effective inherited and local logical search values.
|
|
165
|
+
* @typeParam Resolvers - Local resolver callbacks; data unwraps Promise/Observable
|
|
166
|
+
* results and excludes Angular RedirectCommand values.
|
|
167
|
+
* @typeParam Fragments - This declaration's own allowed fragment-name union.
|
|
168
|
+
* @typeParam Catchall - Whether the declaration is a terminal catchall leaf.
|
|
169
|
+
*/
|
|
49
170
|
interface Route<Path extends string, Params, Search, Resolvers = {}, Fragments extends string = string, Catchall extends boolean = CatchallName<Path> extends never ? false : true> {
|
|
50
171
|
readonly [routeBrand]: {
|
|
51
172
|
readonly fragments: Fragments;
|
|
52
173
|
readonly catchall: Catchall;
|
|
53
174
|
};
|
|
175
|
+
/** The exact local authored path supplied to `defineRoute`. */
|
|
54
176
|
readonly path: Path;
|
|
177
|
+
/** Type-only witness for effective path values; not populated at runtime. */
|
|
55
178
|
readonly __params?: Params;
|
|
179
|
+
/** Type-only witness for effective search values; not populated at runtime. */
|
|
56
180
|
readonly __search?: Search;
|
|
181
|
+
/** Type-only witness for unwrapped local resolver data, excluding redirects. */
|
|
57
182
|
readonly __data?: {
|
|
58
183
|
readonly [Key in keyof Resolvers]: Resolved<Resolvers[Key]>;
|
|
59
184
|
};
|
|
185
|
+
/** The snapshotted local resolver map, retaining original callback identities. */
|
|
60
186
|
readonly resolve?: Readonly<Resolvers>;
|
|
187
|
+
/** The original native rerun policy; omission preserves Angular's default. */
|
|
61
188
|
readonly runGuardsAndResolvers?: RunGuardsAndResolvers;
|
|
62
189
|
}
|
|
63
190
|
type Unwrap<Value> = Value extends Promise<infer Inner> | Observable<infer Inner> ? Unwrap<Inner> : Value;
|
|
64
191
|
type Resolved<Callback> = Callback extends (...args: any[]) => infer Value ? Exclude<Unwrap<Value>, RedirectCommand> : never;
|
|
65
192
|
type AnyRoute = Route<string, any, any, any, any, boolean>;
|
|
193
|
+
/** Extracts a declaration's effective inherited and local path-value types. */
|
|
66
194
|
type ParamsOf<Target> = Target extends Route<string, infer Params, any, any, any, boolean> ? Params : {};
|
|
195
|
+
/** Extracts effective search-value types, retaining optional/nullable modifiers. */
|
|
67
196
|
type SearchOf<Target> = Target extends Route<string, any, infer Search, any, any, boolean> ? Search : {};
|
|
197
|
+
/** Extracts only the selected declaration's own allowed fragment-name union. */
|
|
68
198
|
type FragmentsOf<Target> = Target extends Route<string, any, any, any, infer Fragments, boolean> ? Fragments : never;
|
|
69
199
|
type CodecMap = Record<string, ParamCodec<any>>;
|
|
70
200
|
type LocalParams<Path extends string, Codecs> = {
|
|
@@ -77,30 +207,83 @@ type SearchValues<Codecs> = {
|
|
|
77
207
|
};
|
|
78
208
|
type EffectiveParams<Path extends string, Codecs, Parent> = ParamsOf<Parent> & LocalParams<Path, Codecs>;
|
|
79
209
|
type EffectiveSearch<Codecs, Parent> = SearchOf<Parent> & SearchValues<Codecs>;
|
|
210
|
+
/**
|
|
211
|
+
* Shared parsed inputs supplied to typed guards and resolvers.
|
|
212
|
+
* The container and maps are shallow-frozen; nested codec values remain opaque.
|
|
213
|
+
*/
|
|
80
214
|
type Inputs<Params, Search> = {
|
|
215
|
+
/** Logical positional path values, not Angular's matrix-merged params. */
|
|
81
216
|
readonly params: Readonly<Params>;
|
|
217
|
+
/** Logical declared search values; absent optional keys are omitted. */
|
|
82
218
|
readonly search: Readonly<Search>;
|
|
83
219
|
};
|
|
220
|
+
/**
|
|
221
|
+
* A local resolver invoked after successful effective input parsing.
|
|
222
|
+
* Callback entry has Angular's injection context; later awaits do not inherit it.
|
|
223
|
+
* Angular owns first-emission, empty, redirect, error and teardown behavior.
|
|
224
|
+
*
|
|
225
|
+
* @param inputs - Effective inherited and local parsed values.
|
|
226
|
+
* @param snapshot - The declaring route's native snapshot.
|
|
227
|
+
* @param state - The native router state being resolved.
|
|
228
|
+
* @returns A scalar, Promise, Observable or RedirectCommand result.
|
|
229
|
+
*/
|
|
84
230
|
type Resolver<Params, Search> = (inputs: Inputs<Params, Search>, snapshot: ActivatedRouteSnapshot, state: RouterStateSnapshot) => unknown;
|
|
231
|
+
/**
|
|
232
|
+
* An activation callback entered in Angular's injection context after parsing.
|
|
233
|
+
* Parse failures prevent entry and propagate as navigation errors, not false.
|
|
234
|
+
*
|
|
235
|
+
* @param inputs - The declaring route's effective parsed params/search.
|
|
236
|
+
* @param snapshot - The native route snapshot, or the child snapshot for
|
|
237
|
+
* canActivateChild (whose inputs still belong to the declaring parent).
|
|
238
|
+
* @param state - The native target router state.
|
|
239
|
+
* @returns A native guard result, synchronously or via Promise/Observable.
|
|
240
|
+
*/
|
|
85
241
|
type ActivationGuard<Params, Search> = (inputs: Inputs<Params, Search>, snapshot: ActivatedRouteSnapshot, state: RouterStateSnapshot) => MaybeAsync<GuardResult>;
|
|
242
|
+
/**
|
|
243
|
+
* A candidate matching callback entered in Angular's injection context after parsing.
|
|
244
|
+
* Unlike activation callbacks, it has no ancestor positional path values.
|
|
245
|
+
*
|
|
246
|
+
* @param inputs - Local positional params plus effective inherited/local search.
|
|
247
|
+
* @param routeConfig - Angular's native candidate configuration.
|
|
248
|
+
* @param segments - Angular's candidate URL segments.
|
|
249
|
+
* @param partialSnapshot - Angular's native partial matching snapshot.
|
|
250
|
+
* @returns A native guard result; false permits Angular's next candidate.
|
|
251
|
+
*/
|
|
86
252
|
type MatchingGuard<Params, Search> = (inputs: Inputs<Params, Search>, routeConfig: Route$1, segments: UrlSegment[], partialSnapshot: PartialMatchRouteSnapshot) => MaybeAsync<GuardResult>;
|
|
87
253
|
type RequiredKeys<Value> = {
|
|
88
254
|
[Key in keyof Value]-?: Pick<Value, Key> extends Required<Pick<Value, Key>> ? Key : never;
|
|
89
255
|
}[keyof Value];
|
|
90
256
|
type SearchInput<Schema, Keys extends keyof Schema> = keyof Schema extends never ? Record<string, never> : Pick<Schema, RequiredKeys<Schema> | Keys>;
|
|
257
|
+
/**
|
|
258
|
+
* Explicit values for URL creation and generated link/navigation calls.
|
|
259
|
+
* Effective path and required search keys must be present; optional search may
|
|
260
|
+
* be omitted. Paramless/searchless routes forbid those fields. Fragment names
|
|
261
|
+
* come only from the destination's own declaration.
|
|
262
|
+
*
|
|
263
|
+
* @typeParam Target - The selected route declaration.
|
|
264
|
+
* @typeParam SearchKeys - Supplied search keys inferred by each call to preserve
|
|
265
|
+
* optional-key typing, including keys that coincide with Object members.
|
|
266
|
+
*/
|
|
91
267
|
type UrlValues<Target extends AnyRoute, SearchKeys extends keyof SearchOf<Target> = keyof SearchOf<Target>> = (keyof ParamsOf<Target> extends never ? {
|
|
268
|
+
/** Forbidden when the destination has no effective path params. */
|
|
92
269
|
params?: never;
|
|
93
270
|
} : {
|
|
271
|
+
/** All effective path values; catchalls are readonly element-value arrays. */
|
|
94
272
|
params: ParamsOf<Target>;
|
|
95
273
|
}) & (keyof SearchOf<Target> extends never ? {
|
|
274
|
+
/** Forbidden when the destination has no search declarations. */
|
|
96
275
|
search?: never;
|
|
97
276
|
} : RequiredKeys<SearchOf<Target>> extends never ? {
|
|
277
|
+
/** Optional-only search; absent or undefined optional values are omitted. */
|
|
98
278
|
search?: SearchInput<SearchOf<Target>, SearchKeys>;
|
|
99
279
|
} : {
|
|
280
|
+
/** All required search values plus any supplied optional values. */
|
|
100
281
|
search: SearchInput<SearchOf<Target>, SearchKeys>;
|
|
101
282
|
}) & (FragmentsOf<Target> extends never ? {
|
|
283
|
+
/** Forbidden when this declaration has no fragment names. */
|
|
102
284
|
fragment?: never;
|
|
103
285
|
} : {
|
|
286
|
+
/** An optional logical name declared by this exact destination, without `#`. */
|
|
104
287
|
fragment?: FragmentsOf<Target>;
|
|
105
288
|
});
|
|
106
289
|
type CompatibleKeys<Source, Value> = {
|
|
@@ -115,53 +298,96 @@ type Forwardable<Source, Destination> = {
|
|
|
115
298
|
type Preservable<Source, Destination> = {
|
|
116
299
|
[Key in RequiredKeys<Destination>]: Key extends RequiredKeys<Source> ? Source[Key & keyof Source] extends Destination[Key] ? never : Key : Key;
|
|
117
300
|
}[RequiredKeys<Destination>] extends never ? true : false;
|
|
301
|
+
/**
|
|
302
|
+
* A typed redirect to a genuine authored declaration, not a concrete URL.
|
|
303
|
+
*
|
|
304
|
+
* @remarks
|
|
305
|
+
* Params map destination keys to compatible effective source path keys. Omission
|
|
306
|
+
* forwards by name only when all target keys are compatible. Search and fragment
|
|
307
|
+
* policies are mandatory. Search preserve validates destination-declared values
|
|
308
|
+
* but retains original query text and unknown keys; drop requires no required
|
|
309
|
+
* target search keys; replace uses explicit target-typed values (`{}` is allowed
|
|
310
|
+
* for searchless targets). Fragment preserve retains the incoming raw name,
|
|
311
|
+
* whereas replace requires a target-declared name. Angular executes the redirect.
|
|
312
|
+
*/
|
|
118
313
|
type Redirect<SourceParams, SourceSearch, Target extends AnyRoute, SearchKeys extends keyof SearchOf<Target>> = {
|
|
314
|
+
/** The already constructed target; generation requires a direct default import. */
|
|
119
315
|
to: Target;
|
|
316
|
+
/** Explicit query policy: preserve incoming text, drop it, or replace with values. */
|
|
120
317
|
search: {
|
|
318
|
+
/** Discard incoming queries and serialize explicit target-typed values. */
|
|
121
319
|
mode: "replace";
|
|
320
|
+
/** Required target search keys plus selected optional keys; unknown keys fail. */
|
|
122
321
|
values: SearchInput<SearchOf<NoInfer<Target>>, SearchKeys>;
|
|
123
322
|
} | (RequiredKeys<SearchOf<Target>> extends never ? {
|
|
323
|
+
/** Remove all incoming query values; target required keys are forbidden. */
|
|
124
324
|
mode: "drop";
|
|
125
325
|
} : never) | (Preservable<SourceSearch, SearchOf<Target>> extends true ? {
|
|
326
|
+
/** Keep original query text, validating destination-declared cardinality/values. */
|
|
126
327
|
mode: "preserve";
|
|
127
328
|
} : never);
|
|
329
|
+
/** Explicit hash policy; preserved incoming names need not be declared. */
|
|
128
330
|
fragment: {
|
|
331
|
+
/** Keep the raw incoming hash, or remove it entirely. */
|
|
129
332
|
mode: "preserve" | "drop";
|
|
130
333
|
} | (FragmentsOf<Target> extends never ? never : {
|
|
334
|
+
/** Replace the incoming hash with an explicitly declared target name. */
|
|
131
335
|
mode: "replace";
|
|
336
|
+
/** A logical target fragment name without the `#` delimiter. */
|
|
132
337
|
value: FragmentsOf<Target>;
|
|
133
338
|
});
|
|
134
339
|
} & (Forwardable<SourceParams, ParamsOf<Target>> extends true ? {
|
|
340
|
+
/** Optional destination-key to source-key mapping; otherwise forward by name. */
|
|
135
341
|
params?: Mapping<SourceParams, ParamsOf<Target>>;
|
|
136
342
|
} : {
|
|
343
|
+
/** Required mapping of every destination path key to a compatible source key. */
|
|
137
344
|
params: Mapping<SourceParams, ParamsOf<Target>>;
|
|
138
345
|
});
|
|
346
|
+
/**
|
|
347
|
+
* Options inferred by `defineRoute`; Angular's structural route fields are excluded.
|
|
348
|
+
* Local params/search cannot redeclare keys inherited from the parent.
|
|
349
|
+
*/
|
|
139
350
|
type RouteConfig<Path extends string, Parent extends AnyRoute | undefined, Params extends Record<string, PathCodec>, Search extends CodecMap, Resolvers, Fragments extends readonly string[], Target extends AnyRoute | undefined, ReplacementKeys extends keyof SearchOf<Target>> = {
|
|
351
|
+
/** Genuine authored parent; pathless nodes retain inherited input ownership. */
|
|
140
352
|
parent?: Parent & (Parent extends Route<string, any, any, any, any, true> ? never : unknown);
|
|
353
|
+
/** Local search codecs; keys are required unless wrapped with optionalSearchParam. */
|
|
141
354
|
search?: Search & Record<Extract<keyof Search, keyof SearchOf<Parent>>, never>;
|
|
355
|
+
/** Local parsed-input resolvers; not snapshot-first native ResolveFn callbacks. */
|
|
142
356
|
resolve?: Resolvers & Record<PropertyKey, Resolver<EffectiveParams<Path, Params, Parent>, EffectiveSearch<Search, Parent>>> & {
|
|
143
357
|
__loozoAngularRouterRouteId?: never;
|
|
144
358
|
};
|
|
359
|
+
/** Local logical anchor names, never inherited; this does not enable scrolling. */
|
|
145
360
|
fragments?: Fragments;
|
|
361
|
+
/** Native rerun policy. Use paramsOrQueryParamsChange for query-dependent data. */
|
|
146
362
|
runGuardsAndResolvers?: RunGuardsAndResolvers;
|
|
363
|
+
/** Guards with declaring-parent inputs and Angular's native child snapshot. */
|
|
147
364
|
canActivateChild?: readonly ActivationGuard<EffectiveParams<Path, Params, Parent>, EffectiveSearch<Search, Parent>>[];
|
|
365
|
+
/** Native component-first guard functions/tokens, without automatic input parsing. */
|
|
148
366
|
canDeactivate?: Route$1["canDeactivate"];
|
|
367
|
+
/** Native route-scoped providers; provider factories are not run at declaration. */
|
|
149
368
|
providers?: Route$1["providers"];
|
|
369
|
+
/** Native static title or title resolver, not a parsed-input callback. */
|
|
150
370
|
title?: Route$1["title"];
|
|
371
|
+
/** Native static data; cannot set the reserved __loozoAngularRouterRouteId key. */
|
|
151
372
|
data?: Route$1["data"] & {
|
|
152
373
|
__loozoAngularRouterRouteId?: never;
|
|
153
374
|
};
|
|
154
375
|
} & (PathNames<Path> extends never ? {
|
|
376
|
+
/** Paths without local placeholders cannot declare a params map. */
|
|
155
377
|
params?: never;
|
|
156
378
|
} : {
|
|
379
|
+
/** Exactly the local placeholder names; catchall codecs apply per element. */
|
|
157
380
|
params: Params & Record<PathNames<Path>, PathCodec> & Record<Exclude<keyof Params, PathNames<Path>> | Extract<keyof Params, keyof ParamsOf<Parent>>, never>;
|
|
158
381
|
}) & (Target extends AnyRoute ? {
|
|
382
|
+
/** Typed native redirect, incompatible with own canActivate/canMatch fields. */
|
|
159
383
|
redirect: Redirect<EffectiveParams<Path, Params, Parent>, EffectiveSearch<Search, Parent>, Target, ReplacementKeys>;
|
|
160
384
|
canActivate?: never;
|
|
161
385
|
canMatch?: never;
|
|
162
386
|
} : {
|
|
163
387
|
redirect?: never;
|
|
388
|
+
/** Activation guards with effective inherited and local parsed inputs. */
|
|
164
389
|
canActivate?: readonly ActivationGuard<EffectiveParams<Path, Params, Parent>, EffectiveSearch<Search, Parent>>[];
|
|
390
|
+
/** Matching guards with local path params and effective search only. */
|
|
165
391
|
canMatch?: readonly MatchingGuard<LocalParams<Path, Params>, EffectiveSearch<Search, Parent>>[];
|
|
166
392
|
});
|
|
167
393
|
|
|
@@ -177,8 +403,81 @@ interface RouteMetadata {
|
|
|
177
403
|
readonly config: Readonly<Record<string, unknown>>;
|
|
178
404
|
}
|
|
179
405
|
declare function routeMetadata(route: unknown): RouteMetadata;
|
|
406
|
+
/**
|
|
407
|
+
* Declares a nominal typed route without executing codecs or native callbacks.
|
|
408
|
+
*
|
|
409
|
+
* @remarks
|
|
410
|
+
* Paths are decoded authored text, not URLs: use `""` for root/pathless nodes,
|
|
411
|
+
* `$name` for a scalar segment and terminal `$name[]` for a zero-or-more
|
|
412
|
+
* catchall. Repeated local scalar names reuse one value. Leading/trailing or
|
|
413
|
+
* repeated slashes, dot segments and Angular `:name`/wildcard notation are invalid.
|
|
414
|
+
*
|
|
415
|
+
* Parents compose effective params/search transitively, including through
|
|
416
|
+
* pathless nodes. Children cannot redeclare ancestor-owned keys or have a
|
|
417
|
+
* catchall parent. Fragment names belong only to this declaration.
|
|
418
|
+
* The route and copied containers are shallow-frozen; application codecs,
|
|
419
|
+
* callbacks, providers and opaque values retain identity and are not deep-frozen.
|
|
420
|
+
*
|
|
421
|
+
* For generation, author a direct default export of this call with a literal
|
|
422
|
+
* path and inline config. Parent and redirect targets must be direct default
|
|
423
|
+
* imports of admitted declarations. Angular owns activation and navigation;
|
|
424
|
+
* declaration alone does not register a route with Angular.
|
|
425
|
+
*
|
|
426
|
+
* @param path - The literal local path, relative to the authored parent.
|
|
427
|
+
* @param config - Local codecs, parent, fragments and supported native behavior.
|
|
428
|
+
* Structural Angular options such as children, component and matcher are
|
|
429
|
+
* generator-owned and cannot be overridden.
|
|
430
|
+
* @returns A frozen route preserving inferred effective input and local data types.
|
|
431
|
+
* @throws TypeError for invalid paths/configuration, missing or extra local
|
|
432
|
+
* codecs, inherited key conflicts, or nongenuine parent/redirect routes.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```ts
|
|
436
|
+
* const product = defineRoute("products/$productId", {
|
|
437
|
+
* params: { productId: numberParam },
|
|
438
|
+
* search: { tab: optionalSearchParam(enumParam(["details", "reviews"])) },
|
|
439
|
+
* fragments: ["summary", "reviews"],
|
|
440
|
+
* });
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
180
443
|
declare function defineRoute<const Path extends string, Parent extends AnyRoute | undefined = undefined, Params extends Record<string, PathCodec> = {}, Search extends CodecMap = {}, Resolvers extends Record<string, (...args: any[]) => unknown> = {}, const Fragments extends readonly string[] = [], Target extends AnyRoute | undefined = undefined, ReplacementKeys extends keyof SearchOf<NoInfer<Target>> = never>(path: Path & ValidPath<Path>, config: RouteConfig<Path, Parent, Params, Search, Resolvers, Fragments, Target, ReplacementKeys>): Route<Path, EffectiveParams<Path, Params, Parent>, EffectiveSearch<Search, Parent>, Resolvers, Fragments[number], CatchallName<Path> extends never ? false : true>;
|
|
181
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Synchronously serializes a route's explicit values into a root-relative URL.
|
|
447
|
+
*
|
|
448
|
+
* @remarks
|
|
449
|
+
* Includes inherited path/search declarations, but only this route's fragment
|
|
450
|
+
* names. Every effective path value and required search key must be supplied.
|
|
451
|
+
* Optional-only search may be omitted; searchless/paramless routes forbid those
|
|
452
|
+
* records. Catchalls require readonly arrays, including a valid empty array.
|
|
453
|
+
* Values are never taken from a current navigation.
|
|
454
|
+
*
|
|
455
|
+
* Stringifies without calling parsers, guards, resolvers or redirects. Static
|
|
456
|
+
* segments and logical values are component-encoded (also escaping parentheses),
|
|
457
|
+
* so a dynamic slash becomes `%2F`. Search keys are globally sorted; optional
|
|
458
|
+
* `undefined` values are omitted. An empty effective path produces `/`.
|
|
459
|
+
* Redirect declarations serialize their source URL, not their redirect target.
|
|
460
|
+
*
|
|
461
|
+
* @param route - A genuine declaration from this physical package instance,
|
|
462
|
+
* not a generated destination, spread/copy or structural lookalike.
|
|
463
|
+
* @param values - Explicit destination-typed params, search and optional fragment.
|
|
464
|
+
* Pass an empty object when the route needs no values.
|
|
465
|
+
* @returns A root-relative URL string; this does not navigate or return a UrlTree.
|
|
466
|
+
* @throws TypeError for invalid routes/records, missing or unknown keys,
|
|
467
|
+
* undeclared fragments, nonarray catchalls, nonstring codec output, or empty/dot
|
|
468
|
+
* path output. Application stringifier failures propagate unchanged.
|
|
469
|
+
* @throws URIError for ill-formed Unicode in a serialized value.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```ts
|
|
473
|
+
* const product = defineRoute("products/$productId", {
|
|
474
|
+
* params: { productId: numberParam },
|
|
475
|
+
* fragments: ["summary"],
|
|
476
|
+
* });
|
|
477
|
+
* createUrl(product, { params: { productId: 42 }, fragment: "summary" });
|
|
478
|
+
* // /products/42#summary
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
182
481
|
declare function createUrl<Target extends AnyRoute, SearchKeys extends keyof SearchOf<NoInfer<Target>> = never>(route: Target, values: UrlValues<NoInfer<Target>, SearchKeys>): string;
|
|
183
482
|
|
|
184
483
|
export { booleanParam, codecPresence, createUrl, defineRoute, enumParam, nullableSearchParam, numberParam, optionalSearchParam, routeMetadata, stringParam };
|
|
@@ -23,6 +23,20 @@ declare function callbacks(set: RouteSet, id: string): Pick<Route, "canActivate"
|
|
|
23
23
|
declare function redirect(definition: () => AnyRoute): RedirectFunction;
|
|
24
24
|
|
|
25
25
|
declare const destinationBrand: unique symbol;
|
|
26
|
+
/**
|
|
27
|
+
* An inert nominal reference exported as `destination` by a route-local facade.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* Use the exported object with a handle's link/navigate methods; no injection
|
|
31
|
+
* context or target activation is needed. It selects its exact declaration,
|
|
32
|
+
* not a canonical pathless winner. Only references from the caller's generated
|
|
33
|
+
* set are accepted. Copies, spreads, fakes and authored routes are not references.
|
|
34
|
+
* Do not construct this type or pass it to the root createUrl function.
|
|
35
|
+
*
|
|
36
|
+
* @typeParam Target - The referenced route's input and fragment schema.
|
|
37
|
+
* @typeParam Set - The generator's nominal route-set identity.
|
|
38
|
+
* @typeParam Id - The exact generated declaration identity.
|
|
39
|
+
*/
|
|
26
40
|
declare class Destination<Target extends AnyRoute, Set = unknown, Id extends string = string> {
|
|
27
41
|
#private;
|
|
28
42
|
readonly [destinationBrand]: {
|
|
@@ -36,17 +50,118 @@ type DataOf<Target> = Target extends {
|
|
|
36
50
|
readonly __data?: infer Data;
|
|
37
51
|
} ? Readonly<Data> : never;
|
|
38
52
|
type IsUnion<Value, Whole = Value> = Value extends unknown ? [Whole] extends [Value] ? false : true : never;
|
|
53
|
+
/**
|
|
54
|
+
* The noncallable typed handle returned by a colocated `injectRoute()` facade.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* Obtain it in an Angular injection context for the exact generated activated
|
|
58
|
+
* record. Params/search parse together; data contains only local resolver results,
|
|
59
|
+
* not static/ancestor data or title. Resources are native readonly Angular
|
|
60
|
+
* Resources: use hasValue before value access; error-state value reads throw.
|
|
61
|
+
*
|
|
62
|
+
* Navigation hides old values. Cancellation/same-URL skip restores the survivor
|
|
63
|
+
* without reparsing; obsolete work cannot publish. Relevant parsing participates
|
|
64
|
+
* in Angular stability until publication, error, replacement or destruction.
|
|
65
|
+
* Codecs are not abortable and there is no package timeout or resolved-data cache.
|
|
66
|
+
*
|
|
67
|
+
* Selectors are single known authored literals, not concrete URLs or string
|
|
68
|
+
* unions. `.` is exact-current; other absolute/relative selections use generated
|
|
69
|
+
* canonical targets. Relative climbs count URL-template segments, not parent
|
|
70
|
+
* edges. Catchall origins permit exact-current, absolute and reference targets,
|
|
71
|
+
* not depth-dependent relative traversal. Every call supplies all target values;
|
|
72
|
+
* there is no current-value reuse, extras argument or implicit query merge.
|
|
73
|
+
*
|
|
74
|
+
* @typeParam Target - The bound declaration's schema.
|
|
75
|
+
* @typeParam Selected - Statically admitted literal selectors and target schemas.
|
|
76
|
+
* @typeParam Set - The generator's nominal route-set identity.
|
|
77
|
+
* @typeParam References - Exact declarations addressable by same-set references.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* import { injectRoute } from "./route.generated.js";
|
|
82
|
+
* import { destination as report } from "../report/route.generated.js";
|
|
83
|
+
*
|
|
84
|
+
* const route = injectRoute(); // Inside an Angular injection context.
|
|
85
|
+
* const link = route.link(report, { params: { reportId: 42 } });
|
|
86
|
+
* // Bind link to Angular RouterLink, or call route.navigate with the same values.
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
39
89
|
interface Handle<Target extends AnyRoute, Selected extends Record<string, AnyRoute> = {}, Set = unknown, References extends Record<string, AnyRoute> = {}> {
|
|
90
|
+
/** Effective positional params; undefined while pending or without a value. */
|
|
40
91
|
readonly params: Resource<Readonly<ParamsOf<Target>> | undefined>;
|
|
92
|
+
/** Effective declared search; paired with params from the same parse operation. */
|
|
41
93
|
readonly search: Resource<Readonly<SearchOf<Target>> | undefined>;
|
|
94
|
+
/** Own native resolver results only; settles independently of paired inputs. */
|
|
42
95
|
readonly data: Resource<DataOf<Target> | undefined>;
|
|
96
|
+
/**
|
|
97
|
+
* Creates a native UrlTree for this exact declaration without navigating.
|
|
98
|
+
*
|
|
99
|
+
* @param values - Explicit effective params/search and optional own fragment.
|
|
100
|
+
* @returns Router.parseUrl's result, suitable for Angular RouterLink.
|
|
101
|
+
* @throws Synchronous URL validation, encoding or stringifier failures before Angular.
|
|
102
|
+
*/
|
|
43
103
|
link<Keys extends keyof SearchOf<Target> = never>(values: UrlValues<Target, Keys>): UrlTree;
|
|
104
|
+
/**
|
|
105
|
+
* Creates a UrlTree for the exact bound declaration, not its pathless winner.
|
|
106
|
+
*
|
|
107
|
+
* @param selector - The exact-current literal `.`.
|
|
108
|
+
* @param values - Explicit values for this declaration, with no current-input reuse.
|
|
109
|
+
* @returns Router.parseUrl's result without navigating.
|
|
110
|
+
* @throws Synchronous URL validation, encoding or stringifier failures before Angular.
|
|
111
|
+
*/
|
|
44
112
|
link<Keys extends keyof SearchOf<Target> = never>(selector: ".", values: UrlValues<Target, Keys>): UrlTree;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a UrlTree for a statically admitted absolute/relative authored selector.
|
|
115
|
+
*
|
|
116
|
+
* @param selector - A single known template literal, never a concrete URL.
|
|
117
|
+
* @param values - The selected target's complete explicit values.
|
|
118
|
+
* @returns Router.parseUrl's result without navigating.
|
|
119
|
+
* @throws Synchronously for unknown selectors or invalid URL values.
|
|
120
|
+
*/
|
|
45
121
|
link<const Selector extends keyof Selected & string, Keys extends keyof SearchOf<NoInfer<Selected[Selector]>> = never>(selector: Selector & (IsUnion<Selector> extends true ? never : unknown), values: UrlValues<NoInfer<Selected[Selector]>, Keys>): UrlTree;
|
|
122
|
+
/**
|
|
123
|
+
* Creates a UrlTree for a generated reference's own exact declaration.
|
|
124
|
+
*
|
|
125
|
+
* @param selector - A genuine destination exported by a facade in this route set.
|
|
126
|
+
* @param values - The referenced declaration's complete explicit values.
|
|
127
|
+
* @returns Router.parseUrl's result without navigating.
|
|
128
|
+
* @throws Synchronously for foreign/fake references or invalid URL values.
|
|
129
|
+
*/
|
|
46
130
|
link<const Id extends keyof References & string, Keys extends keyof SearchOf<NoInfer<References[Id]>> = never>(selector: Destination<NoInfer<References[Id]>, Set, Id> & (IsUnion<Id> extends true ? never : unknown), values: UrlValues<NoInfer<References[Id]>, Keys>): UrlTree;
|
|
131
|
+
/**
|
|
132
|
+
* Navigates to this exact declaration via Router.navigateByUrl.
|
|
133
|
+
*
|
|
134
|
+
* @param values - Explicit effective params/search and optional own fragment.
|
|
135
|
+
* @returns Angular's identical Promise; Angular owns skips, redirects and failures.
|
|
136
|
+
* @throws Synchronous URL validation, encoding or stringifier failures before Angular.
|
|
137
|
+
*/
|
|
47
138
|
navigate<Keys extends keyof SearchOf<Target> = never>(values: UrlValues<Target, Keys>): Promise<boolean>;
|
|
139
|
+
/**
|
|
140
|
+
* Navigates to the exact bound declaration, not its pathless winner.
|
|
141
|
+
*
|
|
142
|
+
* @param selector - The exact-current literal `.`.
|
|
143
|
+
* @param values - Explicit values for this declaration, with no current-input reuse.
|
|
144
|
+
* @returns Angular's identical Router.navigateByUrl Promise.
|
|
145
|
+
* @throws Synchronous URL validation, encoding or stringifier failures before Angular.
|
|
146
|
+
*/
|
|
48
147
|
navigate<Keys extends keyof SearchOf<Target> = never>(selector: ".", values: UrlValues<Target, Keys>): Promise<boolean>;
|
|
148
|
+
/**
|
|
149
|
+
* Navigates to a statically admitted absolute/relative authored selector.
|
|
150
|
+
*
|
|
151
|
+
* @param selector - A single known template literal, never a concrete URL.
|
|
152
|
+
* @param values - The selected target's complete explicit values.
|
|
153
|
+
* @returns Angular's identical Router.navigateByUrl Promise.
|
|
154
|
+
* @throws Synchronously for unknown selectors or invalid URL values.
|
|
155
|
+
*/
|
|
49
156
|
navigate<const Selector extends keyof Selected & string, Keys extends keyof SearchOf<NoInfer<Selected[Selector]>> = never>(selector: Selector & (IsUnion<Selector> extends true ? never : unknown), values: UrlValues<NoInfer<Selected[Selector]>, Keys>): Promise<boolean>;
|
|
157
|
+
/**
|
|
158
|
+
* Navigates to a generated reference's own exact declaration.
|
|
159
|
+
*
|
|
160
|
+
* @param selector - A genuine destination exported by a facade in this route set.
|
|
161
|
+
* @param values - The referenced declaration's complete explicit values.
|
|
162
|
+
* @returns Angular's identical Router.navigateByUrl Promise.
|
|
163
|
+
* @throws Synchronously for foreign/fake references or invalid URL values.
|
|
164
|
+
*/
|
|
50
165
|
navigate<const Id extends keyof References & string, Keys extends keyof SearchOf<NoInfer<References[Id]>> = never>(selector: Destination<NoInfer<References[Id]>, Set, Id> & (IsUnion<Id> extends true ? never : unknown), values: UrlValues<NoInfer<References[Id]>, Keys>): Promise<boolean>;
|
|
51
166
|
}
|
|
52
167
|
declare function nativeOptions(definition: AnyRoute): Record<string, unknown>;
|