@sveltekit-i18n/base 1.3.7 → 3.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,461 @@
1
+ export declare namespace DotNotation {
2
+ type Input = any;
3
+ type Output<V = any, K extends keyof V = keyof V> = {
4
+ [P in K]?: V[K];
5
+ } | null | V;
6
+ type T = <I = Input>(input: I, preserveArrays?: boolean, parentKey?: string) => Output<I>;
7
+ }
8
+ export declare namespace Logger {
9
+ type Level = 'error' | 'warn' | 'debug';
10
+ type Prefix = string;
11
+ type T = {
12
+ [key in Logger.Level]: (message: string, error?: unknown) => void;
13
+ };
14
+ type FactoryProps = {
15
+ /**
16
+ * You can setup your custom logger using this property.
17
+ *
18
+ * @default console
19
+ */
20
+ logger?: Logger.T;
21
+ /**
22
+ * You can manage log level using this property.
23
+ *
24
+ * @default 'warn'
25
+ */
26
+ level?: Logger.Level;
27
+ /**
28
+ * You can prefix output logs using this property.
29
+ *
30
+ * @default '[i18n]: '
31
+ */
32
+ prefix?: Logger.Prefix;
33
+ };
34
+ }
35
+ export declare namespace Config {
36
+ export type Locale = Translations.Locales[number];
37
+ /**
38
+ * A locale as the public surface takes and reports it: the locales the config
39
+ * spells, plus any other string. The set is a completion hint, never a
40
+ * constraint — a locale can arrive from a URL, a cookie or an
41
+ * `Accept-Language` header, and a custom `sanitizeLocales` may map an
42
+ * arbitrary input onto a known one.
43
+ */
44
+ export type LocaleInput<L extends string = string> = L | (string & {});
45
+ /** A locale-valued config property; `never` unless it carries a literal. */
46
+ type LocaleProp<C, K extends string> = C extends {
47
+ [P in K]: infer L extends string;
48
+ } ? L : never;
49
+ type LocaleSources<C> = (C extends {
50
+ loaders: readonly {
51
+ locale: infer L extends string;
52
+ }[];
53
+ } ? L : never) | (C extends {
54
+ translations: infer T;
55
+ } ? keyof T & string : never) | LocaleProp<C, 'initLocale'> | LocaleProp<C, 'fallbackLocale'>;
56
+ type ResolveLocales<L> = L extends string ? L : never;
57
+ /**
58
+ * The locales a config type spells – loader locales, `initLocale`,
59
+ * `fallbackLocale` and the keys of `translations`. Plain `Locale` when it
60
+ * spells none, and plain `Locale` as soon as ONE source is dynamic: a
61
+ * half-known set would complete some locales while silently hiding the rest.
62
+ */
63
+ export type LocalesFromConfig<C> = [LocaleSources<C>] extends [never] ? Locale : ResolveLocales<LocaleSources<C>>;
64
+ export type InitLocale = Locale | undefined;
65
+ export type FallbackLocale = Locale | undefined;
66
+ export type FallbackValue = any;
67
+ export type SanitizeLocales = boolean | ((locale: Locale) => Locale);
68
+ export type T<P extends Parser.Params = Parser.Params, O = Parser.Output, S = any> = {
69
+ /**
70
+ * You can use loaders to define your asyncronous translation load. All loaded data are stored so loader is triggered only once – in case there is no previous version of the translation. It can get triggered again once the `config.cache` window elapses, or after `invalidate()` is called.
71
+ */
72
+ loaders?: readonly Loader.LoaderModule[];
73
+ /**
74
+ * Locale-indexed translations, which should be in place before loaders will trigger. It's useful for static pages and synchronous translations – for example locally defined language names which are the same for all of the language mutations.
75
+ *
76
+ * @example {
77
+ * "en": {"lang": {"en": "English", "cs": "Česky"}}
78
+ * "cs": {"lang": {"en": "English", "cs": "Česky"}}
79
+ * }
80
+ */
81
+ translations?: Translations.T;
82
+ /**
83
+ * If you set this property, translations will be initialized immediately using this locale.
84
+ */
85
+ initLocale?: InitLocale;
86
+ /**
87
+ * If you set this property, translations are automatically loaded not for current `locale` only, but for this locale as well. In case there is no translation for current `locale`, fallback locale translation is used instead of translation key placeholder. This is also used as a fallback when unknown locale is set.
88
+ */
89
+ fallbackLocale?: FallbackLocale;
90
+ /**
91
+ * By default, translation key is returned in case no translation is found for given translation key. For example, `t('unknown.key')` will result in `'unknown.key'` output. You can set this output value using this config prop.
92
+ */
93
+ fallbackValue?: FallbackValue;
94
+ /**
95
+ * Defines how locale identifiers are normalized before they key anything – `config.translations`, loaders, the translation tables, `locale`, `fallbackLocale` and every locale you pass in. `true` normalizes to the ISO form, `false` keeps each locale exactly as it was authored, and a function normalizes it your way.
96
+ *
97
+ * @default true
98
+ *
99
+ * @example true
100
+ * 'en-us' => 'en-US'
101
+ *
102
+ * @example false
103
+ * 'en-us' => 'en-us'
104
+ *
105
+ * @example (locale) => locale.toLowerCase()
106
+ * 'en-US' => 'en-us'
107
+ */
108
+ sanitizeLocales?: SanitizeLocales;
109
+ /**
110
+ * Preprocessor strategy or a custom function. Defines, how to transform the translation data immediately after the load. Note that a custom function (like `'none'`) bypasses the dot-notation flattening entirely – its return value is stored as-is, so keys are then looked up exactly as the function produced them.
111
+ * @default 'full'
112
+ *
113
+ * @example 'full'
114
+ * {a: {b: [{c: {d: 1}}, {c: {d: 2}}]}} => {"a.b.0.c.d": 1, "a.b.1.c.d": 2}
115
+ *
116
+ * @example 'preserveArrays'
117
+ * {a: {b: [{c: {d: 1}}, {c: {d: 2}}]}} => {"a.b": [{"c.d": 1}, {"c.d": 2}]}
118
+ *
119
+ * @example 'none'
120
+ * {a: {b: [{c: {d: 1}}, {c: {d: 2}}]}} => {a: {b: [{c: {d: 1}}, {c: {d: 2}}]}}
121
+ */
122
+ preprocess?: 'full' | 'preserveArrays' | 'none' | ((input: Translations.Input) => Translations.Input);
123
+ /**
124
+ * This property defines translation syntax you want to use.
125
+ */
126
+ parser: Parser.T<P, O>;
127
+ /**
128
+ * A key schema — a map of translation key to the payload its message
129
+ * expects (`never` for a message without parameters). Supplying it types
130
+ * `t`/`l`: keys autocomplete and a wrong payload is a type error. Only its
131
+ * TYPE is read, so a generated artifact may export a value that is empty
132
+ * at runtime — as long as that value is TYPED, e.g.
133
+ * `export const schema = {} as TranslationSchema`. A schema whose keys are not a
134
+ * closed set (an open index signature, or no keys at all) is ignored and
135
+ * keys stay plain strings. Read at construction time only: a later
136
+ * `loadConfig()` cannot retype the instance, and `config.extensions`
137
+ * erases the instance's type parameters entirely.
138
+ *
139
+ * @example
140
+ * import { schema } from './generated/i18n-schema.js';
141
+ *
142
+ * const i18n = new I18n({ ...config, schema });
143
+ */
144
+ schema?: S;
145
+ /**
146
+ * Time in milliseconds the loaded translations stay fresh for. Once a locale's translations are older, the next load trigger runs its loaders again. By default, loaded translations never expire – call `invalidate()` (or set a finite `cache`) when your translation source can change at runtime, e.g. a CMS.
147
+ *
148
+ * @default Number.POSITIVE_INFINITY
149
+ *
150
+ * @tip Set to `0` to treat translations as always stale (refetch on every load trigger).
151
+ */
152
+ cache?: number;
153
+ /**
154
+ * Extensions the constructed instance is piped through, left to right.
155
+ * Each extension receives the surface produced so far — the raw `I18n`
156
+ * instance for the first one, the previous extension's output for the
157
+ * next — and returns the surface handed on, so `new I18n(config)`
158
+ * evaluates to the LAST extension's output. Applied by the constructor
159
+ * only; a later `loadConfig()` ignores this property.
160
+ *
161
+ * @example
162
+ * import stores from '@sveltekit-i18n/extension-stores';
163
+ *
164
+ * const { t, locale, loading } = new I18n({ ...config, extensions: [stores] });
165
+ */
166
+ extensions?: readonly Extension.T[];
167
+ /**
168
+ * Custom logger configuration.
169
+ */
170
+ log?: Logger.FactoryProps;
171
+ };
172
+ export {};
173
+ }
174
+ declare const operator: unique symbol;
175
+ export declare namespace Extension {
176
+ type Input = any;
177
+ type Output = any;
178
+ /**
179
+ * An extension is a plain function over the constructed surface. It may
180
+ * augment its input in place and return it, or return a brand-new surface —
181
+ * the constructor just folds the instance through the configured extensions.
182
+ */
183
+ type T<I = Input, O = Output> = (input: I) => O;
184
+ /**
185
+ * The build-time half of an extension whose output shape depends on the
186
+ * surface it receives. Extend it and express the result through `this`:
187
+ *
188
+ * ```ts
189
+ * interface WithStores extends Extension.Operator {
190
+ * readonly output: this['input'] & { subscribe(): void };
191
+ * }
192
+ * ```
193
+ *
194
+ * A plain `(input: I) => O` pair cannot carry that dependency. Reading a
195
+ * generic signature instantiates its type parameters at their constraints,
196
+ * so the pipe would fold the constraint rather than the instance and the
197
+ * surface it was handed would be erased.
198
+ */
199
+ interface Operator {
200
+ readonly input: unknown;
201
+ readonly output: unknown;
202
+ }
203
+ /** Applies an `Operator` to the surface reaching it. */
204
+ type Apply<O extends Operator, Instance> = (O & {
205
+ readonly input: Instance;
206
+ })['output'];
207
+ /**
208
+ * An extension typed by an `Operator` instead of by a fixed return type.
209
+ * The brand is type-only and optional, so the function is written as usual:
210
+ *
211
+ * ```ts
212
+ * const withStores: Extension.Generic<WithStores> = (i18n) => ...;
213
+ * ```
214
+ */
215
+ type Generic<O extends Operator> = T & {
216
+ readonly [operator]?: O;
217
+ };
218
+ /** The `extensions` tuple carried by a config; `[]` when absent. */
219
+ type FromConfig<C> = C extends {
220
+ extensions: infer E extends readonly T[];
221
+ } ? E : [];
222
+ /**
223
+ * Folds a surface type through an extension tuple, left to right — the
224
+ * construction-time type of `new I18n(config)`. An `Operator`-branded
225
+ * extension is applied to the surface reaching it; a plain one contributes
226
+ * its declared return type, erasing what came before. A non-tuple
227
+ * `extensions` array (or none at all) degrades to the plain instance type.
228
+ */
229
+ type Piped<Instance, Extensions> = Extensions extends readonly [infer Head, ...infer Rest] ? Piped<Head extends {
230
+ readonly [operator]?: infer O extends Operator;
231
+ } ? Apply<O, Instance> : Head extends T<any, infer Out> ? Out : Instance, Rest> : Instance;
232
+ }
233
+ export declare namespace Loader {
234
+ type Key = string;
235
+ type Locale = Config.Locale;
236
+ /**
237
+ * Anything with a `test` method can act as a route matcher. It receives the
238
+ * bare route path (e.g. `/products/123`), so a matcher built around a full
239
+ * URL has to be wrapped in a predicate that supplies the origin itself.
240
+ */
241
+ type RouteMatcher = {
242
+ test: (route: string) => boolean;
243
+ };
244
+ type Route = string | RegExp | RouteMatcher;
245
+ /** The load context every loader is called with. */
246
+ type Props = {
247
+ /**
248
+ * Sanitized locale this loader run fetches translations for.
249
+ */
250
+ locale: Locale;
251
+ /**
252
+ * Route the load was triggered for.
253
+ */
254
+ route: string;
255
+ };
256
+ type LoaderModule = {
257
+ /**
258
+ * Represents the translation namespace. This key is used as a translation prefix so it should be module-unique. You can access your translation later using `t('key.yourTranslation')`. It shouldn't include `.` (dot) character.
259
+ */
260
+ key: Key;
261
+ /**
262
+ * Locale (e.g. `en`, `de`) which is this loader for.
263
+ */
264
+ locale: Locale;
265
+ /**
266
+ * Function returning a `Promise` with translation data. You can use it to load files locally, fetch it from your API etc...
267
+ */
268
+ loader: T;
269
+ /**
270
+ * Define routes this loader should be triggered for. You can use Regular expressions or any object with a `test` method too. For example `[/\/.ome/]` will be triggered for `/home` and `/rome` route as well (but still only once). Leave this `undefined` in case you want to load this module with any route (useful for common translations).
271
+ *
272
+ * Named capture groups in a route `RegExp` are reserved: today they match exactly as any other group does, but a future minor may read their matches as load parameters and re-run the loader when those change. Use a non-capturing group (`(?:...)`) where you only need grouping.
273
+ */
274
+ routes?: readonly Route[];
275
+ };
276
+ /**
277
+ * Loads translation data. Receives the load context (`locale`, `route`) –
278
+ * loaders that don't need it can simply take no parameters.
279
+ */
280
+ type T = (props: Props) => Promise<Translations.Input>;
281
+ }
282
+ export declare namespace Parser {
283
+ type Value = any;
284
+ type Params = Array<unknown>;
285
+ type Locale = Config.Locale;
286
+ type Key = Loader.Key;
287
+ type Output = any;
288
+ type Parse<P extends Parser.Params = Parser.Params, O = Output> = (
289
+ /**
290
+ * Translation value from the definitions.
291
+ */
292
+ value: Value,
293
+ /**
294
+ * Array of rest parameters given by user (e.g. payload variables etc...)
295
+ */
296
+ params: P,
297
+ /**
298
+ * Locale of translated message.
299
+ */
300
+ locale: Locale,
301
+ /**
302
+ * This key is serialized path to translation (e.g., `home.content.title`)
303
+ */
304
+ key: Key) => O;
305
+ type T<P extends Parser.Params = Parser.Params, O = Output> = {
306
+ /**
307
+ * Parse function deals with interpolation of user payload and returns interpolated message.
308
+ */
309
+ parse: Parse<P, O>;
310
+ };
311
+ /** The parser params carried by a config's `parser`; `any` when unknown. */
312
+ type FromConfig<C> = C extends {
313
+ parser: T<infer P>;
314
+ } ? P : any;
315
+ /**
316
+ * The parser output carried by a config's `parser`; `string` when unknown.
317
+ * `[unknown] extends [O]` catches both `any` and `unknown` – the former from
318
+ * a parser without a declared output (the `Output` default), the latter from
319
+ * an untyped `parser` value, where inference has no return type to read. A
320
+ * parser producing anything richer must declare its output explicitly (e.g.
321
+ * `Parser.T<Params, HtmlOutput>`).
322
+ */
323
+ type OutputFromConfig<C> = C extends {
324
+ parser: T<any, infer O>;
325
+ } ? ([unknown] extends [O] ? string : O) : string;
326
+ /**
327
+ * What a message parameter accepts, as far as a message can say.
328
+ *
329
+ * `'unknown'` is the top of this lattice, not a conflict marker: merging it
330
+ * with anything yields the other kind. `'date'` covers both date and time
331
+ * formatting and means `Date | number`. `'function'` is a rich-text callback,
332
+ * the shape ICU tags require. `'boolean'` is here for parsers that can prove
333
+ * it – neither official parser can, since both compare stringified values.
334
+ */
335
+ type ParamKind = 'unknown' | 'string' | 'number' | 'boolean' | 'date' | 'function';
336
+ /**
337
+ * One parameter a message expects. Produced by a parser's build-time
338
+ * extractor and consumed by a schema generator, never by the core.
339
+ */
340
+ type ParamSpec = {
341
+ /**
342
+ * Name the payload is keyed by, already unescaped. It is not necessarily a
343
+ * valid identifier, so a generator has to quote it.
344
+ */
345
+ name: string;
346
+ /**
347
+ * What the parameter accepts; defaults to `'unknown'`. Several kinds mean
348
+ * the message uses the parameter in several ways and any of them is valid.
349
+ */
350
+ kind?: ParamKind | readonly ParamKind[];
351
+ /**
352
+ * Values the message names explicitly – a hint for authoring tools, never
353
+ * an exhaustive set. Both official parsers fall back to a default branch
354
+ * for anything unlisted, so this must not be used to close a union. Omit it
355
+ * where the listed values are not values at all (numeric thresholds, plural
356
+ * categories) or mean the opposite (an inequality's operands).
357
+ */
358
+ values?: readonly string[];
359
+ /**
360
+ * Whether the message renders without it; defaults to `false`. A parameter
361
+ * that only some selector branches use is optional – over-approximating
362
+ * here trades a missed error for never demanding a parameter the caller's
363
+ * branch has no use for.
364
+ */
365
+ optional?: boolean;
366
+ /**
367
+ * Selector branches this parameter lives under, outermost first. Lets a
368
+ * generator emit a discriminated payload instead of the flat
369
+ * `optional: true` approximation; a generator that doesn't care can ignore it.
370
+ */
371
+ when?: readonly {
372
+ param: string;
373
+ branch: string;
374
+ }[];
375
+ };
376
+ /** Diagnostic context for an extractor. Neither official parser needs it to extract. */
377
+ type ExtractContext = {
378
+ key?: Key;
379
+ locale?: Locale;
380
+ };
381
+ /**
382
+ * Reports the parameters a message expects. This is the BUILD-TIME half of
383
+ * the parser contract and is deliberately not a member of `T`: a message
384
+ * scanner attached to the runtime parser object could never be shaken out of
385
+ * a browser bundle. A parser ships it from its own subpath instead, and the
386
+ * core never calls it.
387
+ *
388
+ * Values that are not messages the parser recognizes yield no parameters
389
+ * rather than throwing – translation leaves are arbitrary data.
390
+ */
391
+ type ExtractParams = (message: Value, context?: ExtractContext) => readonly ParamSpec[];
392
+ /**
393
+ * Builds an `ExtractParams` from the same options the runtime parser takes.
394
+ * Options decide what a message means – a custom modifier or a disabled tag
395
+ * syntax changes which parameters exist – so a generator has to construct the
396
+ * extractor the way the app constructs its parser.
397
+ */
398
+ type ExtractParamsFactory<O = unknown> = (options?: O) => ExtractParams;
399
+ }
400
+ export declare namespace Schema {
401
+ /**
402
+ * A schema types calls only when its keys form a specific, closed set. An
403
+ * untyped value, an empty object or an open index signature would otherwise
404
+ * reject every key or demand a payload for keys it knows nothing about, so
405
+ * they degrade to no schema at all.
406
+ */
407
+ type HasClosedKeys<S> = [keyof S & string] extends [never] ? false : string extends keyof S ? false : true;
408
+ /** The key schema carried by a config; `never` when there is none to use. */
409
+ export type FromConfig<C> = C extends {
410
+ schema?: infer S extends object;
411
+ } ? (HasClosedKeys<S> extends true ? S : never) : never;
412
+ /** The keys a schema allows; any string when there is no schema. */
413
+ export type Key<S> = [S] extends [never] ? string : keyof S & string;
414
+ type IsAny<T> = 0 extends 1 & T ? true : false;
415
+ /**
416
+ * What satisfies every key in `K` — see `Params`. The fold runs over the
417
+ * KEYS, so each key's own payload reaches the intersection whole; folding
418
+ * over the payloads instead would collapse a single key's discriminated
419
+ * union to `never` and type the message as parameterless. A key that carries
420
+ * no payload contributes nothing rather than erasing the others, and an
421
+ * empty union stays `never`: no member means no payload, not an
422
+ * unconstrained one.
423
+ */
424
+ type BoxedPayload<S, K extends string> = K extends keyof S ? [Exclude<S[K], undefined>] extends [never] ? never : (payload: Exclude<S[K], undefined>) => void : never;
425
+ type PayloadOf<S, K extends string> = [BoxedPayload<S, K>] extends [never] ? never : BoxedPayload<S, K> extends (payload: infer V) => void ? V : never;
426
+ /**
427
+ * The parser's own params minus the payload slot the schema takes over. A
428
+ * params tuple that is unknown or open-ended contributes no trailing slots –
429
+ * keeping its rest open would let any number of junk arguments through.
430
+ */
431
+ type Trailing<P extends Parser.Params> = number extends P['length'] ? [] : P extends readonly [unknown?, ...infer R] ? R : [];
432
+ /**
433
+ * The payload argument, spliced into slot 0 of the parser's params so the
434
+ * parser's trailing slots (ICU `formats`, for instance) survive. A payload
435
+ * that carries no value marks a message without parameters; one with no
436
+ * REQUIRED property, or one the schema marks `Optional`, may be omitted.
437
+ * A schema value of `any` keeps the slot unchecked rather than forbidding it.
438
+ */
439
+ export type Payload<P extends Parser.Params, V, Optional extends boolean = false> = IsAny<V> extends true ? [payload?: any, ...Trailing<P>] : [V] extends [void | null] ? [payload?: undefined, ...Trailing<P>] : true extends Optional | ({} extends V ? true : never) ? [payload?: V, ...Trailing<P>] : [payload: V, ...Trailing<P>];
440
+ /**
441
+ * Rest params for `key` — the parser's own params when there is no schema.
442
+ * A union of keys takes the INTERSECTION of their payloads, since one call
443
+ * has to satisfy every key it might be.
444
+ */
445
+ export type Params<S, K extends string, P extends Parser.Params> = [S] extends [never] ? P : [K] extends [keyof S] ? Payload<P, PayloadOf<S, K>, undefined extends S[K & keyof S] ? true : false> : P;
446
+ export {};
447
+ }
448
+ export declare namespace Translations {
449
+ type Locales<T = string> = T[];
450
+ type SerializedTranslations = LocaleIndexed<DotNotation.Input>;
451
+ type TranslationFunction<P extends Parser.Params = Parser.Params, O = string, S = never> = <K extends Schema.Key<S>>(key: K, ...restParams: Schema.Params<S, K, P>) => O;
452
+ type LocalTranslationFunction<P extends Parser.Params = Parser.Params, O = string, S = never, L extends string = string> = <K extends Schema.Key<S>>(locale: Config.LocaleInput<L>, key: K, ...restParams: Schema.Params<S, K, P>) => O;
453
+ type Input<V = any> = {
454
+ [K in any]: Input<V> | V;
455
+ };
456
+ type LocaleIndexed<V> = {
457
+ [locale: string]: V;
458
+ };
459
+ type T<V = any> = LocaleIndexed<Input<V>>;
460
+ }
461
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { Config, DotNotation, Translations, Loader, Parser } from './types.js';
2
+ export declare const hasOwn: (obj: any, key: PropertyKey) => boolean;
3
+ export declare const read: <T = any>(obj: any, key: PropertyKey) => T | undefined;
4
+ export declare const translate: <P extends Parser.Params = Parser.Params, O = Parser.Output>({ parser, key, params, translations, locale, fallbackLocale, ...rest }: {
5
+ parser: Parser.T<P, O>;
6
+ key: string;
7
+ params: Parser.Params;
8
+ translations: Translations.SerializedTranslations;
9
+ locale: Translations.Locales[number] | undefined;
10
+ fallbackLocale?: Config.FallbackLocale;
11
+ fallbackValue?: Config.FallbackValue;
12
+ }) => O;
13
+ type Sanitizer = (...locales: any[]) => Config.Locale[];
14
+ export declare const sanitizeLocales: Sanitizer;
15
+ export declare const sanitizerFactory: (sanitize?: Config.SanitizeLocales) => Sanitizer;
16
+ export declare const sanitizeTranslationLocales: (input: Translations.SerializedTranslations, sanitize: Sanitizer) => Translations.SerializedTranslations;
17
+ export declare const toDotNotation: DotNotation.T;
18
+ export declare const resolveLoaders: (input?: readonly Loader.LoaderModule[]) => Loader.LoaderModule[];
19
+ export declare const mergeTranslations: (target: any, source: any, path: string, onConflict?: (path: string) => void) => any;
20
+ export declare const serialize: (input: Array<Loader.LoaderModule & {
21
+ data: any;
22
+ }>) => Translations.SerializedTranslations;
23
+ export declare const fetchTranslations: (loaders: Loader.LoaderModule[], route: string) => Promise<Translations.SerializedTranslations>;
24
+ export declare const testRoute: (route: string) => (input: Loader.Route) => boolean;
25
+ export {};