@fedify/uri-template 2.0.0-pr.475.1 → 2.3.0-dev.1137
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/LICENSE +1 -1
- package/README.md +250 -44
- package/dist/mod.cjs +1901 -0
- package/dist/mod.d.cts +795 -0
- package/dist/mod.d.ts +795 -0
- package/dist/mod.js +1873 -0
- package/package.json +42 -29
- package/dist/_virtual/rolldown_runtime.cjs +0 -30
- package/dist/ast.d.cts +0 -39
- package/dist/ast.d.ts +0 -39
- package/dist/compile.cjs +0 -30
- package/dist/compile.d.cts +0 -80
- package/dist/compile.d.ts +0 -80
- package/dist/compile.js +0 -30
- package/dist/error.cjs +0 -29
- package/dist/error.js +0 -28
- package/dist/expand.cjs +0 -94
- package/dist/expand.d.cts +0 -72
- package/dist/expand.d.ts +0 -72
- package/dist/expand.js +0 -94
- package/dist/index.cjs +0 -9
- package/dist/index.d.cts +0 -6
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -6
- package/dist/match.cjs +0 -180
- package/dist/match.d.cts +0 -92
- package/dist/match.d.ts +0 -92
- package/dist/match.js +0 -180
- package/dist/match.spec.cjs +0 -109
- package/dist/match.spec.d.cts +0 -1
- package/dist/match.spec.d.ts +0 -1
- package/dist/match.spec.js +0 -108
- package/dist/parser.cjs +0 -102
- package/dist/parser.d.cts +0 -35
- package/dist/parser.d.ts +0 -35
- package/dist/parser.js +0 -102
- package/dist/rfc6570.spec.cjs +0 -419
- package/dist/rfc6570.spec.d.cts +0 -1
- package/dist/rfc6570.spec.d.ts +0 -1
- package/dist/rfc6570.spec.js +0 -418
- package/dist/spec.cjs +0 -112
- package/dist/spec.js +0 -108
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
//#region src/router/errors.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Common base class for router-level errors.
|
|
4
|
+
*/
|
|
5
|
+
declare class RouterError extends Error {
|
|
6
|
+
/**
|
|
7
|
+
* @param message Human-readable summary.
|
|
8
|
+
*/
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Raised when a route template is not a path template.
|
|
13
|
+
*/
|
|
14
|
+
declare class RouteTemplatePathError extends RouterError {
|
|
15
|
+
/**
|
|
16
|
+
* The route template that failed validation.
|
|
17
|
+
*/
|
|
18
|
+
readonly template: string;
|
|
19
|
+
constructor(
|
|
20
|
+
/**
|
|
21
|
+
* The route template that failed validation.
|
|
22
|
+
*/
|
|
23
|
+
template: string);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Raised when the same variable name appears in multiple variable
|
|
27
|
+
* specifications whose modifiers imply contradictory `multiple` semantics
|
|
28
|
+
* within a single route template (for example, `{x}` together with `{x*}`).
|
|
29
|
+
*/
|
|
30
|
+
declare class ConflictingVarSpecError extends RouterError {
|
|
31
|
+
/**
|
|
32
|
+
* The route template containing the conflicting variable specifications.
|
|
33
|
+
*/
|
|
34
|
+
readonly template: string;
|
|
35
|
+
/**
|
|
36
|
+
* The variable name with conflicting variable specifications.
|
|
37
|
+
*/
|
|
38
|
+
readonly variable: string;
|
|
39
|
+
constructor(
|
|
40
|
+
/**
|
|
41
|
+
* The route template containing the conflicting variable specifications.
|
|
42
|
+
*/
|
|
43
|
+
template: string,
|
|
44
|
+
/**
|
|
45
|
+
* The variable name with conflicting variable specifications.
|
|
46
|
+
*/
|
|
47
|
+
variable: string);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Raised under the default `exact` route option when the `variables` keys
|
|
51
|
+
* do not exactly match the route template's variables: the set of supplied
|
|
52
|
+
* keys must equal the set of template variables (no unknown keys, none
|
|
53
|
+
* missing). All mismatched names — both unknown and missing — are reported.
|
|
54
|
+
*/
|
|
55
|
+
declare class RouteTemplateOptionsNotMatchedError extends RouterError {
|
|
56
|
+
/**
|
|
57
|
+
* The route template whose variables were not matched exactly.
|
|
58
|
+
*/
|
|
59
|
+
readonly template: string;
|
|
60
|
+
/**
|
|
61
|
+
* The mismatched variable names: keys not declared by the template
|
|
62
|
+
* together with template variables absent from the options.
|
|
63
|
+
*/
|
|
64
|
+
readonly variable: readonly string[];
|
|
65
|
+
constructor(
|
|
66
|
+
/**
|
|
67
|
+
* The route template whose variables were not matched exactly.
|
|
68
|
+
*/
|
|
69
|
+
template: string,
|
|
70
|
+
/**
|
|
71
|
+
* The mismatched variable names: keys not declared by the template
|
|
72
|
+
* together with template variables absent from the options.
|
|
73
|
+
*/
|
|
74
|
+
variable: readonly string[]);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Raised when a variable appears more than once in a route template while
|
|
78
|
+
* its `duplicable` constraint is `false` (the default).
|
|
79
|
+
*/
|
|
80
|
+
declare class DuplicateRouteVariableError extends RouterError {
|
|
81
|
+
/**
|
|
82
|
+
* The route template containing the duplicated variable.
|
|
83
|
+
*/
|
|
84
|
+
readonly template: string;
|
|
85
|
+
/**
|
|
86
|
+
* The variable name that appears more than once.
|
|
87
|
+
*/
|
|
88
|
+
readonly variable: string;
|
|
89
|
+
constructor(
|
|
90
|
+
/**
|
|
91
|
+
* The route template containing the duplicated variable.
|
|
92
|
+
*/
|
|
93
|
+
template: string,
|
|
94
|
+
/**
|
|
95
|
+
* The variable name that appears more than once.
|
|
96
|
+
*/
|
|
97
|
+
variable: string);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Raised when a variable specification uses the explode (`*`) or prefix
|
|
101
|
+
* (`:N`) modifier while the corresponding `explodable`/`prefixable`
|
|
102
|
+
* constraint is `false` (the default).
|
|
103
|
+
*/
|
|
104
|
+
declare class DisallowedVarSpecModifierError extends RouterError {
|
|
105
|
+
/**
|
|
106
|
+
* The route template containing the disallowed modifier.
|
|
107
|
+
*/
|
|
108
|
+
readonly template: string;
|
|
109
|
+
/**
|
|
110
|
+
* The variable name whose specification uses the modifier.
|
|
111
|
+
*/
|
|
112
|
+
readonly variable: string;
|
|
113
|
+
/**
|
|
114
|
+
* The disallowed modifier.
|
|
115
|
+
*/
|
|
116
|
+
readonly modifier: "explode" | "prefix";
|
|
117
|
+
constructor(
|
|
118
|
+
/**
|
|
119
|
+
* The route template containing the disallowed modifier.
|
|
120
|
+
*/
|
|
121
|
+
template: string,
|
|
122
|
+
/**
|
|
123
|
+
* The variable name whose specification uses the modifier.
|
|
124
|
+
*/
|
|
125
|
+
variable: string,
|
|
126
|
+
/**
|
|
127
|
+
* The disallowed modifier.
|
|
128
|
+
*/
|
|
129
|
+
modifier: "explode" | "prefix");
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Raised when a variable is used with an expression operator that is not in
|
|
133
|
+
* its `operatables` allow-list.
|
|
134
|
+
*/
|
|
135
|
+
declare class DisallowedOperatorError extends RouterError {
|
|
136
|
+
/**
|
|
137
|
+
* The route template containing the disallowed operator.
|
|
138
|
+
*/
|
|
139
|
+
readonly template: string;
|
|
140
|
+
/**
|
|
141
|
+
* The variable name used with the disallowed operator.
|
|
142
|
+
*/
|
|
143
|
+
readonly variable: string;
|
|
144
|
+
/**
|
|
145
|
+
* The disallowed expression operator (`""`, `"+"`, `"#"`, `"."`, `"/"`,
|
|
146
|
+
* `";"`, `"?"`, or `"&"`).
|
|
147
|
+
*/
|
|
148
|
+
readonly operator: string;
|
|
149
|
+
constructor(
|
|
150
|
+
/**
|
|
151
|
+
* The route template containing the disallowed operator.
|
|
152
|
+
*/
|
|
153
|
+
template: string,
|
|
154
|
+
/**
|
|
155
|
+
* The variable name used with the disallowed operator.
|
|
156
|
+
*/
|
|
157
|
+
variable: string,
|
|
158
|
+
/**
|
|
159
|
+
* The disallowed expression operator (`""`, `"+"`, `"#"`, `"."`, `"/"`,
|
|
160
|
+
* `";"`, `"?"`, or `"&"`).
|
|
161
|
+
*/
|
|
162
|
+
operator: string);
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/const.d.ts
|
|
166
|
+
/**
|
|
167
|
+
* Operators implemented by this package, including `""` for simple string
|
|
168
|
+
* expansion with no explicit operator.
|
|
169
|
+
*/
|
|
170
|
+
declare const OPERATORS: readonly ["", "+", ".", "/", ";", "?", "&", "#"];
|
|
171
|
+
/**
|
|
172
|
+
* Union of supported URI Template operators.
|
|
173
|
+
*/
|
|
174
|
+
type Operator = typeof OPERATORS[number];
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/types.d.ts
|
|
177
|
+
/**
|
|
178
|
+
* Path-shaped URI Template accepted by the router.
|
|
179
|
+
*
|
|
180
|
+
* The empty path is accepted so trailing-slash-insensitive routing can retry
|
|
181
|
+
* the root path (`/`) as an empty path.
|
|
182
|
+
*/
|
|
183
|
+
type Path = "" | `/${string}` | `{/${string}}${string}`;
|
|
184
|
+
/**
|
|
185
|
+
* Primitive value accepted by {@link Template.expand}.
|
|
186
|
+
*/
|
|
187
|
+
type PrimitiveValue = string | number | boolean | null | undefined;
|
|
188
|
+
/**
|
|
189
|
+
* Associative composite value accepted by
|
|
190
|
+
* {@link Template.expand}.
|
|
191
|
+
*
|
|
192
|
+
* Keys are expanded as URI Template associative names. Values may be primitive
|
|
193
|
+
* values or primitive lists.
|
|
194
|
+
*/
|
|
195
|
+
type AssociativeValue = Record<string, PrimitiveValue | readonly PrimitiveValue[]>;
|
|
196
|
+
/**
|
|
197
|
+
* Any value shape accepted for one template variable during expansion.
|
|
198
|
+
*/
|
|
199
|
+
type ExpandValue = PrimitiveValue | readonly PrimitiveValue[] | AssociativeValue;
|
|
200
|
+
/**
|
|
201
|
+
* Context object accepted by {@link Template.expand}.
|
|
202
|
+
* Each variable resolves to a primitive, an ordered list of primitives,
|
|
203
|
+
* or an associative map.
|
|
204
|
+
*/
|
|
205
|
+
type ExpandContext = Record<string, ExpandValue>;
|
|
206
|
+
/**
|
|
207
|
+
* Parsed RFC 6570 variable specification inside an expression.
|
|
208
|
+
*
|
|
209
|
+
* Produced by the expression parser and consumed by the expansion module.
|
|
210
|
+
*/
|
|
211
|
+
interface VarSpec {
|
|
212
|
+
/** Variable name to look up in the expansion context. */
|
|
213
|
+
readonly name: string;
|
|
214
|
+
/** Whether the varspec uses the Level 4 explode modifier (`*`). */
|
|
215
|
+
readonly explode: boolean;
|
|
216
|
+
/** Prefix length from a Level 4 prefix modifier (`:N`), if present. */
|
|
217
|
+
readonly prefix?: number;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Token produced by parsing a URI Template.
|
|
221
|
+
*
|
|
222
|
+
* Literal tokens are copied directly. Expression tokens are expanded with a
|
|
223
|
+
* context object.
|
|
224
|
+
*/
|
|
225
|
+
type Token = {
|
|
226
|
+
readonly kind: "literal";
|
|
227
|
+
readonly text: string;
|
|
228
|
+
} | {
|
|
229
|
+
readonly kind: "expression";
|
|
230
|
+
readonly operator: Operator;
|
|
231
|
+
readonly vars: readonly VarSpec[];
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Options controlling URI Template parsing and expansion diagnostics.
|
|
235
|
+
*/
|
|
236
|
+
interface TemplateOptions {
|
|
237
|
+
/**
|
|
238
|
+
* If `true`, the first parse or expansion error will be automatically
|
|
239
|
+
* thrown after being reported. `true` is the default value. If `false`,
|
|
240
|
+
* errors will be reported to by the `report` function, but none will be
|
|
241
|
+
* thrown unless the `report` function itself throws.
|
|
242
|
+
*/
|
|
243
|
+
strict: boolean;
|
|
244
|
+
/**
|
|
245
|
+
* A function that will be called with any errors encountered while parsing
|
|
246
|
+
* or expanding. Defaults to a no-op; pass a callback (for example, one
|
|
247
|
+
* backed by your application's logger) to observe diagnostics. In strict
|
|
248
|
+
* mode, errors are still thrown after this reporter runs.
|
|
249
|
+
* @param error The error that was encountered while parsing or expanding the
|
|
250
|
+
* template.
|
|
251
|
+
*/
|
|
252
|
+
report: Reporter;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Callback used to report recoverable parse and expansion diagnostics.
|
|
256
|
+
*/
|
|
257
|
+
type Reporter = (error: Error) => void;
|
|
258
|
+
//#endregion
|
|
259
|
+
//#region src/template/errors.d.ts
|
|
260
|
+
/**
|
|
261
|
+
* Errors raised when an RFC 6570 URI template fails to parse or expand.
|
|
262
|
+
*
|
|
263
|
+
* Parse-time hierarchy:
|
|
264
|
+
*
|
|
265
|
+
* ~~~~
|
|
266
|
+
* TemplateParseError
|
|
267
|
+
* ├── UnclosedExpressionError
|
|
268
|
+
* ├── StrayClosingBraceError
|
|
269
|
+
* ├── NestedOpeningBraceError
|
|
270
|
+
* ├── EmptyExpressionError
|
|
271
|
+
* ├── ReservedOperatorError
|
|
272
|
+
* ├── UnknownOperatorError
|
|
273
|
+
* ├── InvalidLiteralError
|
|
274
|
+
* ├── InvalidVarSpecError
|
|
275
|
+
* │ ├── EmptyVarNameError
|
|
276
|
+
* │ ├── InvalidVarNameError
|
|
277
|
+
* │ ├── InvalidPrefixError
|
|
278
|
+
* │ └── TrailingCommaError
|
|
279
|
+
* └── UnexpectedCharacterError
|
|
280
|
+
* ~~~~
|
|
281
|
+
*
|
|
282
|
+
* Expansion-time hierarchy:
|
|
283
|
+
*
|
|
284
|
+
* ~~~~
|
|
285
|
+
* TemplateExpansionError
|
|
286
|
+
* └── PrefixModifierNotApplicableError
|
|
287
|
+
* ~~~~
|
|
288
|
+
*
|
|
289
|
+
* Parse errors carry the original `template` and the 0-based `position` where
|
|
290
|
+
* the offending input was located. Expansion errors carry the runtime variable
|
|
291
|
+
* name whose value cannot be expanded.
|
|
292
|
+
*
|
|
293
|
+
* @module
|
|
294
|
+
*/
|
|
295
|
+
/**
|
|
296
|
+
* Common base class for every parse-time error produced by the RFC 6570 parser.
|
|
297
|
+
*/
|
|
298
|
+
declare class TemplateParseError extends Error {
|
|
299
|
+
readonly template: string;
|
|
300
|
+
readonly position: number;
|
|
301
|
+
readonly hint: string;
|
|
302
|
+
/**
|
|
303
|
+
* @param template The full URI template string that was being parsed.
|
|
304
|
+
* @param position 0-based index into `template` where the problem was
|
|
305
|
+
* detected. When the offending input spans a range,
|
|
306
|
+
* this is the start of that range.
|
|
307
|
+
* @param hint Short, actionable instruction for the user.
|
|
308
|
+
* @param message Human-readable summary.
|
|
309
|
+
*/
|
|
310
|
+
constructor(template: string, position: number, hint: string, message: string);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Raised when an opening `{` has no matching `}` before the template ends.
|
|
314
|
+
*
|
|
315
|
+
* Fix: close the expression with `}` or pct-encode the literal `{` as `%7B`.
|
|
316
|
+
* RFC 6570 does not define an escape syntax.
|
|
317
|
+
*/
|
|
318
|
+
declare class UnclosedExpressionError extends TemplateParseError {
|
|
319
|
+
constructor(template: string, position: number);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Raised when a `}` appears outside of any expression.
|
|
323
|
+
*
|
|
324
|
+
* Fix: remove the stray `}` or precede it with a matching `{`.
|
|
325
|
+
*/
|
|
326
|
+
declare class StrayClosingBraceError extends TemplateParseError {
|
|
327
|
+
constructor(template: string, position: number);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Raised when a `{` appears inside another expression before that expression
|
|
331
|
+
* is closed. RFC 6570 expressions cannot nest.
|
|
332
|
+
*
|
|
333
|
+
* Fix: close the outer expression with `}` before opening a new one.
|
|
334
|
+
*/
|
|
335
|
+
declare class NestedOpeningBraceError extends TemplateParseError {
|
|
336
|
+
constructor(template: string, position: number);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Raised when a literal section of the template contains a character that is
|
|
340
|
+
* outside the RFC 6570 `literals` set: CTL, SP, `"`, `'`, lone `%`, `<`, `>`,
|
|
341
|
+
* `\\`, `^`, `` ` ``, `|`.
|
|
342
|
+
*
|
|
343
|
+
* Fix: pct-encode the offending character or remove it.
|
|
344
|
+
*/
|
|
345
|
+
declare class InvalidLiteralError extends TemplateParseError {
|
|
346
|
+
readonly char: string;
|
|
347
|
+
constructor(template: string, position: number, char: string);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Raised for `{}` — an expression that contains neither operator nor varspec.
|
|
351
|
+
*
|
|
352
|
+
* Fix: insert at least one varname between the braces, e.g. `{var}`.
|
|
353
|
+
*/
|
|
354
|
+
declare class EmptyExpressionError extends TemplateParseError {
|
|
355
|
+
constructor(template: string, position: number);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Raised when the operator slot holds one of the characters reserved by
|
|
359
|
+
* RFC 6570 §2.2 for future extensions: `=`, `,`, `!`, `@`, `|`.
|
|
360
|
+
*
|
|
361
|
+
* Fix: drop the reserved operator or replace it with one of the implemented
|
|
362
|
+
* operators (`+`, `#`, `.`, `/`, `;`, `?`, `&`).
|
|
363
|
+
*/
|
|
364
|
+
declare class ReservedOperatorError extends TemplateParseError {
|
|
365
|
+
readonly operator: string;
|
|
366
|
+
constructor(template: string, position: number, operator: string);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Raised when the operator slot holds a character that is neither a defined
|
|
370
|
+
* RFC 6570 operator nor part of the varname grammar.
|
|
371
|
+
*
|
|
372
|
+
* Fix: use one of the implemented operators (`+`, `#`, `.`, `/`, `;`, `?`,
|
|
373
|
+
* `&`) or remove the character.
|
|
374
|
+
*/
|
|
375
|
+
declare class UnknownOperatorError extends TemplateParseError {
|
|
376
|
+
readonly operator: string;
|
|
377
|
+
constructor(template: string, position: number, operator: string);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Common base for malformed varspec errors so users can `instanceof`-filter.
|
|
381
|
+
*/
|
|
382
|
+
declare class InvalidVarSpecError extends TemplateParseError {
|
|
383
|
+
readonly varSpec: string;
|
|
384
|
+
constructor(template: string, position: number, hint: string, message: string, varSpec: string);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Raised when a varspec contains no varname (e.g. `{,foo}` or `{foo,}`).
|
|
388
|
+
*/
|
|
389
|
+
declare class EmptyVarNameError extends InvalidVarSpecError {
|
|
390
|
+
constructor(template: string, position: number);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Raised when a varname contains characters outside the RFC 6570 varchar set
|
|
394
|
+
* (`ALPHA / DIGIT / "_" / pct-encoded`, optionally separated by `.`).
|
|
395
|
+
*/
|
|
396
|
+
declare class InvalidVarNameError extends InvalidVarSpecError {
|
|
397
|
+
readonly offendingChar: string;
|
|
398
|
+
constructor(template: string, position: number, varSpec: string, offendingChar: string);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Raised when a prefix modifier (`:N`) is malformed: missing digits, leading
|
|
402
|
+
* zero, or `N` outside the range `1..9999`.
|
|
403
|
+
*/
|
|
404
|
+
declare class InvalidPrefixError extends InvalidVarSpecError {
|
|
405
|
+
readonly prefix: string;
|
|
406
|
+
constructor(template: string, position: number, varSpec: string, prefix: string);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Raised when a varspec ends with a trailing comma followed by `}` or end of
|
|
410
|
+
* variable-list (e.g. `{a,b,}`).
|
|
411
|
+
*/
|
|
412
|
+
declare class TrailingCommaError extends InvalidVarSpecError {
|
|
413
|
+
constructor(template: string, position: number);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Raised when an unexpected character appears between a varspec and the next
|
|
417
|
+
* separator (`,` or `}`), e.g. `{a b}` or `{a:3x}`.
|
|
418
|
+
*/
|
|
419
|
+
declare class UnexpectedCharacterError extends TemplateParseError {
|
|
420
|
+
readonly char: string;
|
|
421
|
+
constructor(template: string, position: number, char: string);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Common base class for runtime expansion errors.
|
|
425
|
+
*/
|
|
426
|
+
declare class TemplateExpansionError extends Error {
|
|
427
|
+
readonly variableName: string;
|
|
428
|
+
readonly hint: string;
|
|
429
|
+
/**
|
|
430
|
+
* @param variableName The variable whose resolved value cannot be expanded.
|
|
431
|
+
* @param hint Short, actionable instruction for the user.
|
|
432
|
+
* @param message Human-readable summary.
|
|
433
|
+
*/
|
|
434
|
+
constructor(variableName: string, hint: string, message: string);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Raised when a prefix modifier is applied to a composite value.
|
|
438
|
+
*
|
|
439
|
+
* RFC 6570 §2.4.1 defines prefix modifiers for string values only; lists and
|
|
440
|
+
* associative arrays must use normal or explode expansion instead.
|
|
441
|
+
*/
|
|
442
|
+
declare class PrefixModifierNotApplicableError extends TemplateExpansionError {
|
|
443
|
+
readonly prefix: number;
|
|
444
|
+
readonly valueType: "list" | "associative";
|
|
445
|
+
constructor(variableName: string, prefix: number, valueType: "list" | "associative");
|
|
446
|
+
}
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/template/template.d.ts
|
|
449
|
+
/**
|
|
450
|
+
* Parsed RFC 6570 URI Template that can be expanded repeatedly.
|
|
451
|
+
*
|
|
452
|
+
* This class owns tokenization and delegates expression expansion to the
|
|
453
|
+
* expansion module. Instances are immutable after construction.
|
|
454
|
+
*/
|
|
455
|
+
declare class Template {
|
|
456
|
+
#private;
|
|
457
|
+
/**
|
|
458
|
+
* URI template string to parse. See [RFC 6570] for syntax details.
|
|
459
|
+
*
|
|
460
|
+
* [RFC 6570]: https://datatracker.ietf.org/doc/html/rfc6570
|
|
461
|
+
*/
|
|
462
|
+
readonly uriTemplate: string;
|
|
463
|
+
/**
|
|
464
|
+
* Options for parsing the template. By default, `strict` is `true` and
|
|
465
|
+
* `report` is a no-op. If `strict` is `true`, the first error encountered
|
|
466
|
+
* while parsing or expanding will be automatically thrown after being
|
|
467
|
+
* reported. If `strict` is `false`, errors will be reported but none will
|
|
468
|
+
* be thrown unless the `report` function itself throws. The rest of the
|
|
469
|
+
* part remains as literal text.
|
|
470
|
+
*/
|
|
471
|
+
readonly options: Partial<TemplateOptions>;
|
|
472
|
+
constructor(
|
|
473
|
+
/**
|
|
474
|
+
* URI template string to parse. See [RFC 6570] for syntax details.
|
|
475
|
+
*
|
|
476
|
+
* [RFC 6570]: https://datatracker.ietf.org/doc/html/rfc6570
|
|
477
|
+
*/
|
|
478
|
+
|
|
479
|
+
uriTemplate: string,
|
|
480
|
+
/**
|
|
481
|
+
* Options for parsing the template. By default, `strict` is `true` and
|
|
482
|
+
* `report` is a no-op. If `strict` is `true`, the first error encountered
|
|
483
|
+
* while parsing or expanding will be automatically thrown after being
|
|
484
|
+
* reported. If `strict` is `false`, errors will be reported but none will
|
|
485
|
+
* be thrown unless the `report` function itself throws. The rest of the
|
|
486
|
+
* part remains as literal text.
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
options?: Partial<TemplateOptions>);
|
|
490
|
+
/**
|
|
491
|
+
* Parses a URI Template using default strict parsing options.
|
|
492
|
+
*/
|
|
493
|
+
static parse(uriTemplate: string, options?: Partial<TemplateOptions>): Template;
|
|
494
|
+
/**
|
|
495
|
+
* Immutable parsed token stream for diagnostics and router integration.
|
|
496
|
+
*/
|
|
497
|
+
get tokens(): readonly Token[];
|
|
498
|
+
/**
|
|
499
|
+
* Expands this template against a variable context.
|
|
500
|
+
*/
|
|
501
|
+
readonly expand: (context: ExpandContext) => string;
|
|
502
|
+
/**
|
|
503
|
+
* Matches a URI against this template, returning the variable context if the
|
|
504
|
+
* URI matches or `null` if it does not.
|
|
505
|
+
*/
|
|
506
|
+
readonly match: (uri: string) => ExpandContext | null;
|
|
507
|
+
readonly toString: () => string;
|
|
508
|
+
}
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region src/router/types.d.ts
|
|
511
|
+
/**
|
|
512
|
+
* Options for the {@link Router}.
|
|
513
|
+
*/
|
|
514
|
+
interface RouterOptions {
|
|
515
|
+
/**
|
|
516
|
+
* Whether to ignore trailing slashes when matching paths.
|
|
517
|
+
*/
|
|
518
|
+
trailingSlashInsensitive?: boolean;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Fully-resolved per-variable matching constraint. Every template variable
|
|
522
|
+
* is constrained even when it is not listed in {@link RouteOptions.variables};
|
|
523
|
+
* the listed entries only override the defaults. All fields are required;
|
|
524
|
+
* call sites pass a {@link Partial} and {@link fillRouteOptions} fills the
|
|
525
|
+
* missing fields with their defaults.
|
|
526
|
+
*/
|
|
527
|
+
interface VariableConstraint {
|
|
528
|
+
/**
|
|
529
|
+
* When `true`, an unbound or empty binding still matches (opt-out of the
|
|
530
|
+
* non-empty requirement). Defaults to `false`.
|
|
531
|
+
*/
|
|
532
|
+
readonly nullable: boolean;
|
|
533
|
+
/**
|
|
534
|
+
* Whether the variable binds to a list of values rather than a single
|
|
535
|
+
* scalar. When omitted it is derived from the variable specification:
|
|
536
|
+
* explode (`*`) implies `true`, a prefix modifier (`:N`) implies `false`,
|
|
537
|
+
* and a plain variable defaults to `false` but may be set either way.
|
|
538
|
+
* Specifying a value that contradicts the derived one is a registration
|
|
539
|
+
* error.
|
|
540
|
+
*/
|
|
541
|
+
readonly multiple: boolean;
|
|
542
|
+
/**
|
|
543
|
+
* Whether the variable may appear more than once in the route template.
|
|
544
|
+
* Defaults to `false`: a variable that occurs in multiple variable
|
|
545
|
+
* specifications is a registration error (`DuplicateRouteVariableError`).
|
|
546
|
+
* Set to `true` to allow repeated occurrences (their bindings must still
|
|
547
|
+
* agree at match time).
|
|
548
|
+
*/
|
|
549
|
+
readonly duplicable: boolean;
|
|
550
|
+
/**
|
|
551
|
+
* Whether a variable specification may use the prefix modifier (`:N`).
|
|
552
|
+
* Defaults to `false`: a `{var:N}` specification is a registration error
|
|
553
|
+
* (`DisallowedVarSpecModifierError`). Incompatible with `multiple: true`
|
|
554
|
+
* (a prefix yields a single truncated scalar); that combination is
|
|
555
|
+
* already rejected by the `multiple` derivation.
|
|
556
|
+
*/
|
|
557
|
+
readonly prefixable: boolean;
|
|
558
|
+
/**
|
|
559
|
+
* Whether a variable specification may use the explode modifier (`*`).
|
|
560
|
+
* Defaults to `false`: a `{var*}` specification is a registration error
|
|
561
|
+
* (`DisallowedVarSpecModifierError`). Only meaningful with
|
|
562
|
+
* `multiple: true` (explode yields a list); the `multiple` derivation
|
|
563
|
+
* already forces and checks that coupling.
|
|
564
|
+
*/
|
|
565
|
+
readonly explodable: boolean;
|
|
566
|
+
/**
|
|
567
|
+
* Allow-list of expression operators the variable may be used with.
|
|
568
|
+
* Defaults to `[]`, which permits every operator. When non-empty, using
|
|
569
|
+
* the variable under an operator outside this list is a registration
|
|
570
|
+
* error (`DisallowedOperatorError`).
|
|
571
|
+
*/
|
|
572
|
+
readonly operatables: readonly Operator[];
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Fully-resolved options attached to a registered route. All fields are
|
|
576
|
+
* required; {@link fillRouteOptions} resolves a {@link Partial} input against
|
|
577
|
+
* a {@link RouterPathPattern} into this shape.
|
|
578
|
+
*/
|
|
579
|
+
interface RouteOptions {
|
|
580
|
+
/**
|
|
581
|
+
* Per-variable constraint, keyed by variable name. After resolution this
|
|
582
|
+
* contains an entry for every template variable, not just the overridden
|
|
583
|
+
* ones.
|
|
584
|
+
*/
|
|
585
|
+
readonly variables: Readonly<Record<string, VariableConstraint>>;
|
|
586
|
+
/**
|
|
587
|
+
* When `true` (the default), the `variables` keys must exactly match the
|
|
588
|
+
* template's variables: a key that is not an actual template variable is
|
|
589
|
+
* a registration error (typo guard). When `false`, such keys are
|
|
590
|
+
* silently ignored.
|
|
591
|
+
*/
|
|
592
|
+
readonly exact: boolean;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* The subset of a per-variable constraint that {@link ConstraintValue}
|
|
596
|
+
* inspects to compute a matched value's static type. Only `multiple` and
|
|
597
|
+
* `nullable` shape the value: `multiple: true` yields `readonly string[]`,
|
|
598
|
+
* `nullable: true` additionally admits `null`.
|
|
599
|
+
*
|
|
600
|
+
* `explodable` is a *registration permission* (it lets a varspec use the
|
|
601
|
+
* explode modifier `{var*}` without throwing) and deliberately does **not**
|
|
602
|
+
* affect the computed value type. An exploded route still resolves
|
|
603
|
+
* `multiple` to `true` via {@link fillMultiple}, so callers that want the
|
|
604
|
+
* matched value narrowed to `readonly string[]` must pass `multiple: true`
|
|
605
|
+
* in the {@link Router.route} type argument, not merely `explodable: true`.
|
|
606
|
+
*/
|
|
607
|
+
interface MinimalConstraint {
|
|
608
|
+
readonly multiple?: boolean;
|
|
609
|
+
readonly nullable?: boolean;
|
|
610
|
+
readonly explodable?: boolean;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Computes the value type of a single matched variable from its constraint:
|
|
614
|
+
* `multiple: true` yields `readonly string[]`, otherwise `string`;
|
|
615
|
+
* `nullable: true` additionally admits `null`.
|
|
616
|
+
*
|
|
617
|
+
* The trailing `extends infer R ? R : never` is an identity that forces
|
|
618
|
+
* TypeScript to evaluate the conditional union eagerly.
|
|
619
|
+
*/
|
|
620
|
+
type ConstraintValue<C extends MinimalConstraint> = ((C extends {
|
|
621
|
+
multiple: true;
|
|
622
|
+
} ? readonly string[] : string) | (C extends {
|
|
623
|
+
nullable: true;
|
|
624
|
+
} ? null : never)) extends infer R ? R : never;
|
|
625
|
+
/**
|
|
626
|
+
* Computes the `values` record type from a map of variable constraints. An
|
|
627
|
+
* empty map (the default) widens to `Record<string, string>` because the
|
|
628
|
+
* matched route is not known at the type level.
|
|
629
|
+
*/
|
|
630
|
+
type RouteValues<TConstraints extends Record<string, MinimalConstraint>> = [keyof TConstraints] extends [never] ? Record<string, ConstraintValue<{
|
|
631
|
+
multiple: false;
|
|
632
|
+
nullable: false;
|
|
633
|
+
}>> : { [K in keyof TConstraints]: ConstraintValue<TConstraints[K]> };
|
|
634
|
+
/**
|
|
635
|
+
* The result of {@link Router.route}. The type argument is the per-variable
|
|
636
|
+
* constraint map; pass it at the call site to narrow `values` (for example,
|
|
637
|
+
* `router.route<{ tags: { nullable: false; multiple: true } }>(...)`).
|
|
638
|
+
*/
|
|
639
|
+
interface RouterRouteResult<TConstraints extends Record<string, MinimalConstraint>> {
|
|
640
|
+
/**
|
|
641
|
+
* The matched route name.
|
|
642
|
+
*/
|
|
643
|
+
name: string;
|
|
644
|
+
/**
|
|
645
|
+
* The URI template of the matched route.
|
|
646
|
+
*/
|
|
647
|
+
template: Path;
|
|
648
|
+
/**
|
|
649
|
+
* The values extracted from the URI.
|
|
650
|
+
*/
|
|
651
|
+
values: RouteValues<TConstraints>;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Parsed path template ready to be registered in a {@link Router}.
|
|
655
|
+
*
|
|
656
|
+
* Instances returned by {@link Router.compile} are immutable and may be shared
|
|
657
|
+
* safely between routers and router clones.
|
|
658
|
+
*/
|
|
659
|
+
interface RouterPathPattern {
|
|
660
|
+
/**
|
|
661
|
+
* The original path template string.
|
|
662
|
+
*/
|
|
663
|
+
readonly path: Path;
|
|
664
|
+
/**
|
|
665
|
+
* Parsed URI Template.
|
|
666
|
+
*/
|
|
667
|
+
readonly template: Template;
|
|
668
|
+
/**
|
|
669
|
+
* Variable names found in the template.
|
|
670
|
+
*/
|
|
671
|
+
readonly variables: ReadonlySet<string>;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Resolved route definition produced internally and returned by
|
|
675
|
+
* {@link Router#clone} round-trips. Unlike {@link PartialRouterRoute}, the
|
|
676
|
+
* path is already compiled and the options are fully resolved.
|
|
677
|
+
*/
|
|
678
|
+
type RouterRoute = readonly [pathOrPattern: RouterPathPattern, name: string, options: RouteOptions];
|
|
679
|
+
/**
|
|
680
|
+
* Route definition accepted by {@link Router#register}, the {@link Router}
|
|
681
|
+
* constructor, and {@link Router.from}. The first element is either a path
|
|
682
|
+
* template string or a pre-parsed {@link RouterPathPattern} from
|
|
683
|
+
* {@link Router.compile}; the second element is the route name; the optional
|
|
684
|
+
* third element is the per-route options (missing fields are filled with
|
|
685
|
+
* their defaults).
|
|
686
|
+
*/
|
|
687
|
+
type PartialRouterRoute = readonly [pathOrPattern: Path | RouterPathPattern, name: string, options?: {
|
|
688
|
+
readonly variables?: Readonly<Record<string, Partial<VariableConstraint>>>;
|
|
689
|
+
readonly exact?: boolean;
|
|
690
|
+
}];
|
|
691
|
+
//#endregion
|
|
692
|
+
//#region src/router/router.d.ts
|
|
693
|
+
/**
|
|
694
|
+
* Router that resolves URIs against registered RFC 6570 templates.
|
|
695
|
+
*/
|
|
696
|
+
declare class Router {
|
|
697
|
+
#private;
|
|
698
|
+
/**
|
|
699
|
+
* Whether to ignore trailing slashes when matching paths.
|
|
700
|
+
*/
|
|
701
|
+
trailingSlashInsensitive: boolean;
|
|
702
|
+
/**
|
|
703
|
+
* Create a new {@link Router}.
|
|
704
|
+
*
|
|
705
|
+
* The first argument may be an iterable of routes, an options object, or
|
|
706
|
+
* omitted. When two arguments are passed, they are interpreted as
|
|
707
|
+
* `(routes, options)`.
|
|
708
|
+
*
|
|
709
|
+
* @param routes Routes to register on the new router.
|
|
710
|
+
* @param options Options for the router.
|
|
711
|
+
*/
|
|
712
|
+
constructor(routes: Iterable<PartialRouterRoute>, options?: RouterOptions);
|
|
713
|
+
constructor(options?: RouterOptions);
|
|
714
|
+
/**
|
|
715
|
+
* Creates a new {@link Router}. Mirrors the constructor argument
|
|
716
|
+
* interface and is provided for ergonomic call sites that prefer a
|
|
717
|
+
* static factory over `new`.
|
|
718
|
+
*/
|
|
719
|
+
static from(routes: Iterable<PartialRouterRoute>, options?: RouterOptions): Router;
|
|
720
|
+
static from(options?: RouterOptions): Router;
|
|
721
|
+
/**
|
|
722
|
+
* Compiles a path template without registering it in a router.
|
|
723
|
+
* @param path The path pattern.
|
|
724
|
+
* @returns A parsed path pattern.
|
|
725
|
+
*/
|
|
726
|
+
static compile(path: Path): RouterPathPattern;
|
|
727
|
+
/**
|
|
728
|
+
* Returns the variable names in a path template without registering it.
|
|
729
|
+
* @param path The path pattern.
|
|
730
|
+
* @returns The names of the variables in the path pattern.
|
|
731
|
+
*/
|
|
732
|
+
static variables: (path: Path) => Set<string>;
|
|
733
|
+
/**
|
|
734
|
+
* Checks if a path name exists in the router.
|
|
735
|
+
* @param name The name of the path.
|
|
736
|
+
* @returns `true` if the path name exists, otherwise `false`.
|
|
737
|
+
*/
|
|
738
|
+
has: (name: string) => boolean;
|
|
739
|
+
/**
|
|
740
|
+
* Adds a new path rule to the router.
|
|
741
|
+
* @param pathOrPattern The path template, or a pre-parsed
|
|
742
|
+
* {@link RouterPathPattern} produced by
|
|
743
|
+
* {@link Router.compile}.
|
|
744
|
+
* @param name The name of the path.
|
|
745
|
+
* @param options Per-route options, including per-variable constraints.
|
|
746
|
+
*/
|
|
747
|
+
add: (...args: PartialRouterRoute) => void;
|
|
748
|
+
/**
|
|
749
|
+
* Registers multiple path rules at once.
|
|
750
|
+
* @param routes Iterable of `[pathOrPattern, name]` pairs to register.
|
|
751
|
+
*/
|
|
752
|
+
register: (routes: Iterable<PartialRouterRoute>) => void;
|
|
753
|
+
/**
|
|
754
|
+
* Resolves a path name and values from a URI, if any match.
|
|
755
|
+
* @param url The URI to resolve.
|
|
756
|
+
* @returns The name of the path and its values, if any match. Otherwise,
|
|
757
|
+
* `null`.
|
|
758
|
+
*/
|
|
759
|
+
route: <TConstraints extends Record<string, MinimalConstraint> = Record<never, never>>(url: Path) => RouterRouteResult<TConstraints> | null;
|
|
760
|
+
/**
|
|
761
|
+
* Constructs a URL/path from a path name and values.
|
|
762
|
+
* @param name The name of the path.
|
|
763
|
+
* @param values The values to expand the path with.
|
|
764
|
+
* @returns The URL/path, if the name exists. Otherwise, `null`.
|
|
765
|
+
*/
|
|
766
|
+
build: <TConstraints extends Record<string, VariableConstraint> = Record<never, never>>(name: string, values: RouterRouteResult<TConstraints>["values"]) => Path | null;
|
|
767
|
+
/**
|
|
768
|
+
* Creates a shallow clone of the router. The clone shares immutable
|
|
769
|
+
* registered path patterns with the original, but changes to the route set
|
|
770
|
+
* (adding, removing, or re-registering routes) do not affect the other
|
|
771
|
+
* router.
|
|
772
|
+
* @returns A new router with the same routes and options as this one.
|
|
773
|
+
*/
|
|
774
|
+
clone: () => Router;
|
|
775
|
+
}
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region src/utils.d.ts
|
|
778
|
+
declare const isExpression: <T extends {
|
|
779
|
+
kind: string;
|
|
780
|
+
}>(token: T) => token is Extract<T, {
|
|
781
|
+
kind: "expression";
|
|
782
|
+
}>;
|
|
783
|
+
/**
|
|
784
|
+
* Returns whether `path` is a path-shaped URI Template accepted by the
|
|
785
|
+
* router.
|
|
786
|
+
*
|
|
787
|
+
* A path is either an empty string, a literal string starting with `/`, or a
|
|
788
|
+
* path-expansion expression (`{/var}`).
|
|
789
|
+
* Templates that fail to parse — and therefore could never be routed —
|
|
790
|
+
* return `false`.
|
|
791
|
+
*/
|
|
792
|
+
declare function isPath(path: string): path is Path;
|
|
793
|
+
declare function assertPath(path: string): asserts path is Path;
|
|
794
|
+
//#endregion
|
|
795
|
+
export { type AssociativeValue, ConflictingVarSpecError, type ConstraintValue, DisallowedOperatorError, DisallowedVarSpecModifierError, DuplicateRouteVariableError, EmptyExpressionError, EmptyVarNameError, type ExpandContext, type ExpandValue, InvalidLiteralError, InvalidPrefixError, InvalidVarNameError, InvalidVarSpecError, NestedOpeningBraceError, type Operator, type Path, PrefixModifierNotApplicableError, type PrimitiveValue, type Reporter, ReservedOperatorError, type RouteOptions, RouteTemplateOptionsNotMatchedError, RouteTemplatePathError, type RouteValues, Router, RouterError, type RouterOptions, type RouterPathPattern, type RouterRoute, type RouterRouteResult, StrayClosingBraceError, Template, TemplateExpansionError, type TemplateOptions, TemplateParseError, type Token, TrailingCommaError, UnclosedExpressionError, UnexpectedCharacterError, UnknownOperatorError, type VarSpec, type VariableConstraint, assertPath, isExpression, isPath };
|