@sveltekit-i18n/base 3.0.0-next.2 → 3.0.0-next.4

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 CHANGED
@@ -40,7 +40,7 @@ You'll also need a parser:
40
40
 
41
41
  ```bash
42
42
  # Choose one:
43
- npm install @sveltekit-i18n/parser-default
43
+ npm install @sveltekit-i18n/parser-curly
44
44
  npm install @sveltekit-i18n/parser-icu
45
45
  # or create your own
46
46
  ```
@@ -62,11 +62,11 @@ npm install @sveltekit-i18n/parser-icu
62
62
  ```javascript
63
63
  // src/lib/translations/index.js
64
64
  import { I18n } from '@sveltekit-i18n/base';
65
- import parser from '@sveltekit-i18n/parser-default';
65
+ import parser from '@sveltekit-i18n/parser-curly';
66
66
 
67
67
  /** @type {import('@sveltekit-i18n/base').Config.T} */
68
68
  const config = {
69
- parser: parser({ /* parser options */ }),
69
+ parser: parser({ onReport: null, /* other parser options */ }),
70
70
  loaders: [
71
71
  {
72
72
  locale: 'en',
@@ -134,7 +134,7 @@ import i18n from '@sveltekit-i18n/base';
134
134
  import parser from '@sveltekit-i18n/parser-icu';
135
135
 
136
136
  const config = {
137
- parser: parser(),
137
+ parser: parser({ onReport: null }),
138
138
  loaders: [/* ... */],
139
139
  };
140
140
  ```
@@ -356,14 +356,14 @@ Full API documentation: [docs/README.md](./docs/README.md)
356
356
 
357
357
  ```typescript
358
358
  import { I18n, type Config } from '@sveltekit-i18n/base';
359
- import parser from '@sveltekit-i18n/parser-default';
359
+ import parser from '@sveltekit-i18n/parser-curly';
360
360
 
361
361
  // The parser's params – the rest parameters of `t`/`l`. Annotate only when the
362
362
  // config lives on its own; `new I18n({ ... })` infers them.
363
363
  type Params = [payload?: Record<string, unknown>];
364
364
 
365
365
  const config: Config.T<Params> = {
366
- parser: parser(),
366
+ parser: parser({ onReport: null }),
367
367
  loaders: [/* ... */],
368
368
  };
369
369
  ```
@@ -371,7 +371,7 @@ const config: Config.T<Params> = {
371
371
  Two more things are inferred from the config itself. [`schema`](#schema) types the keys and payloads of `t`/`l`, and every locale the config names — loader locales, `initLocale`, `fallbackLocale` and the keys of `translations` — completes the locale arguments and reads (`setLocale`, `loadTranslations`, `invalidate`, `l`, `locale`, `locales`):
372
372
 
373
373
  ```typescript
374
- const i18n = new I18n({ parser: parser(), initLocale: 'en', fallbackLocale: 'de' });
374
+ const i18n = new I18n({ parser: parser({ onReport: null }), initLocale: 'en', fallbackLocale: 'de' });
375
375
 
376
376
  i18n.setLocale('en'); // 'en' | 'de' autocomplete here
377
377
  i18n.setLocale('sv'); // still accepted — the union is a hint, not a constraint
@@ -381,8 +381,8 @@ The locales survive only when the config reaches the constructor as a literal
381
381
 
382
382
  ## Related Packages
383
383
 
384
- - [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) – Complete solution with default parser
385
- - [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) – Default message parser
384
+ - [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) – Complete solution, with the Curly Message Format parser included
385
+ - [@sveltekit-i18n/parser-curly](https://github.com/sveltekit-i18n/parsers/tree/master/parser-curly) – [Curly Message Format](https://github.com/curly-message/spec) parser
386
386
  - [@sveltekit-i18n/parser-icu](https://github.com/sveltekit-i18n/parsers/tree/master/parser-icu) – ICU message format parser
387
387
  - [Extensions](https://github.com/sveltekit-i18n/extensions) – Official extensions for the `config.extensions` pipe
388
388
 
package/dist/types.d.ts CHANGED
@@ -285,17 +285,33 @@ export declare namespace Parser {
285
285
  type Locale = Config.Locale;
286
286
  type Key = Loader.Key;
287
287
  type Output = any;
288
+ /**
289
+ * Called on the `t`/`l` path and nowhere else – never during loading,
290
+ * preprocessing, serialization or hydration. What it returns reaches the
291
+ * caller of `t`/`l` and nothing else: the core does not inspect, transform
292
+ * or serialize it.
293
+ */
288
294
  type Parse<P extends Parser.Params = Parser.Params, O = Output> = (
289
295
  /**
290
- * Translation value from the definitions.
291
- */
296
+ * Translation value from the definitions, read as an own property and
297
+ * already preprocessed. Arbitrary data – a string in the ordinary case and
298
+ * whatever a loader returned otherwise. Never `undefined`: a key resolving
299
+ * to no translation in the active locale nor in the fallback is answered
300
+ * by `fallbackValue`, and this is not called. Must not throw on whatever
301
+ * does arrive.
302
+ */
292
303
  value: Value,
293
304
  /**
294
- * Array of rest parameters given by user (e.g. payload variables etc...)
305
+ * The rest arguments of the `t`/`l` call. An argumentless call passes `[]`,
306
+ * never `undefined`; the core neither validates nor fills it in, and a
307
+ * `schema` narrows it at the type level only.
295
308
  */
296
309
  params: P,
297
310
  /**
298
- * Locale of translated message.
311
+ * Locale of translated message, normalized by `sanitizeLocales` where that
312
+ * yields one and as the caller spelled it otherwise. Never `undefined` –
313
+ * with no locale there is nothing to look up and this is not called at
314
+ * all.
299
315
  */
300
316
  locale: Locale,
301
317
  /**
@@ -304,8 +320,13 @@ export declare namespace Parser {
304
320
  key: Key) => O;
305
321
  type T<P extends Parser.Params = Parser.Params, O = Output> = {
306
322
  /**
307
- * Parse function deals with interpolation of user payload and returns interpolated message.
308
- */
323
+ * Parse function deals with interpolation of user payload and returns
324
+ * interpolated message. The message FORMAT is the parser's own – syntax,
325
+ * missing-parameter rendering, pluralization, formatting and escaping are
326
+ * out of the core's contract and differ between parsers. What the contract
327
+ * requires is that none of them throws: a parser is a public edge and this
328
+ * package fails soft at its edges.
329
+ */
309
330
  parse: Parse<P, O>;
310
331
  };
311
332
  /** The parser params carried by a config's `parser`; `any` when unknown. */
@@ -382,8 +403,8 @@ export declare namespace Parser {
382
403
  * Reports the parameters a message expects. This is the BUILD-TIME half of
383
404
  * the parser contract and is deliberately not a member of `T`: a message
384
405
  * 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.
406
+ * a browser bundle. A parser ships it as a separate export instead one a
407
+ * bundle that never reaches it drops – and the core never calls it.
387
408
  *
388
409
  * Values that are not messages the parser recognizes yield no parameters
389
410
  * rather than throwing – translation leaves are arbitrary data.
@@ -448,8 +469,15 @@ export declare namespace Schema {
448
469
  export declare namespace Translations {
449
470
  type Locales<T = string> = T[];
450
471
  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;
472
+ /**
473
+ * What `t`/`l` yield. The parser's output on the paths that reach the parser,
474
+ * and a plain string on the ones that cannot: an empty key, no locale, or a
475
+ * config carrying no parser. `O` is `string` for every parser that returns
476
+ * one, which collapses the union everywhere it is not needed.
477
+ */
478
+ type Translated<O> = O | string;
479
+ 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>) => Translated<O>;
480
+ 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>) => Translated<O>;
453
481
  type Input<V = any> = {
454
482
  [K in any]: Input<V> | V;
455
483
  };
package/dist/utils.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare const translate: <P extends Parser.Params = Parser.Params, O = Pa
9
9
  locale: Translations.Locales[number] | undefined;
10
10
  fallbackLocale?: Config.FallbackLocale;
11
11
  fallbackValue?: Config.FallbackValue;
12
- }) => O;
12
+ }) => Translations.Translated<O>;
13
13
  type Sanitizer = (...locales: any[]) => Config.Locale[];
14
14
  export declare const sanitizeLocales: Sanitizer;
15
15
  export declare const sanitizerFactory: (sanitize?: Config.SanitizeLocales) => Sanitizer;
package/dist/utils.js CHANGED
@@ -6,8 +6,6 @@ export const hasOwn = (obj, key) => obj != null && Object.prototype.hasOwnProper
6
6
  // Own-property read: returns the value only when `key` is the object's own
7
7
  // property, otherwise undefined. Centralizes the prototype-safe table lookup.
8
8
  export const read = (obj, key) => (hasOwn(obj, key) ? obj[key] : undefined);
9
- // The fail-soft paths return placeholder strings (`''`, the key itself) even
10
- // for a parser with a non-string output — hence the `as unknown as O` casts.
11
9
  export const translate = ({ parser, key, params, translations, locale, fallbackLocale, ...rest }) => {
12
10
  if (!key) {
13
11
  logger.warn(`No translation key provided ('${locale}' locale). Skipping translation...`);
@@ -30,14 +28,14 @@ export const translate = ({ parser, key, params, translations, locale, fallbackL
30
28
  return rest.fallbackValue;
31
29
  }
32
30
  logger.warn(`No translation nor fallback found for '${key}' .`);
31
+ // There is nothing to interpolate, so no parser is asked to. Echoing the
32
+ // key is what makes a missing translation visible instead of blank.
33
+ return key;
33
34
  }
34
35
  if (!parser || typeof parser.parse !== 'function') {
35
36
  // Reached on every call while no parser is set (e.g. before config loads),
36
37
  // so keep it at debug to avoid flooding logs on the render path.
37
38
  logger.debug(`No parser configured. Returning raw value for '${key}' key.`);
38
- // Mirror the missing-translation contract: fall back to the key itself.
39
- if (text === undefined)
40
- return key;
41
39
  return text;
42
40
  }
43
41
  // A key schema narrows the rest params to one key's payload — still a `P`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltekit-i18n/base",
3
- "version": "3.0.0-next.2",
3
+ "version": "3.0.0-next.4",
4
4
  "description": "Base functionality of sveltekit-i18n library with a support for external message parsers.",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",