@vielzeug/lingua 2.4.0 → 3.0.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.
Files changed (52) hide show
  1. package/README.md +9 -28
  2. package/dist/_dev.cjs.map +1 -1
  3. package/dist/_dev.js.map +1 -1
  4. package/dist/_resources.cjs +1 -1
  5. package/dist/_resources.cjs.map +1 -1
  6. package/dist/_resources.d.ts +9 -3
  7. package/dist/_resources.d.ts.map +1 -1
  8. package/dist/_resources.js +19 -22
  9. package/dist/_resources.js.map +1 -1
  10. package/dist/_template.cjs +1 -1
  11. package/dist/_template.cjs.map +1 -1
  12. package/dist/_template.d.ts +2 -1
  13. package/dist/_template.d.ts.map +1 -1
  14. package/dist/_template.js +12 -3
  15. package/dist/_template.js.map +1 -1
  16. package/dist/catalog.cjs +1 -1
  17. package/dist/catalog.cjs.map +1 -1
  18. package/dist/catalog.d.ts +8 -8
  19. package/dist/catalog.d.ts.map +1 -1
  20. package/dist/catalog.js +10 -5
  21. package/dist/catalog.js.map +1 -1
  22. package/dist/errors.cjs +1 -1
  23. package/dist/errors.cjs.map +1 -1
  24. package/dist/errors.d.ts +4 -0
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +3 -3
  27. package/dist/errors.js.map +1 -1
  28. package/dist/i18n.cjs +1 -1
  29. package/dist/i18n.cjs.map +1 -1
  30. package/dist/i18n.d.ts +6 -7
  31. package/dist/i18n.d.ts.map +1 -1
  32. package/dist/i18n.js +68 -55
  33. package/dist/i18n.js.map +1 -1
  34. package/dist/index.cjs +1 -1
  35. package/dist/index.d.ts +4 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +5 -5
  38. package/dist/lingua.cjs +1 -1
  39. package/dist/lingua.cjs.map +1 -1
  40. package/dist/lingua.iife.js +1 -1
  41. package/dist/lingua.iife.js.map +1 -1
  42. package/dist/lingua.js +1 -1
  43. package/dist/lingua.js.map +1 -1
  44. package/dist/translator.cjs +1 -1
  45. package/dist/translator.cjs.map +1 -1
  46. package/dist/translator.d.ts +15 -10
  47. package/dist/translator.d.ts.map +1 -1
  48. package/dist/translator.js +41 -32
  49. package/dist/translator.js.map +1 -1
  50. package/dist/types.d.ts +38 -14
  51. package/dist/types.d.ts.map +1 -1
  52. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"translator.js","names":[],"sources":["../src/translator.ts"],"sourcesContent":["import { type CompiledCatalog, type CompiledMessage, compileCatalog } from './_catalog';\nimport { canonicalLocale, localeChain, pluralCategory } from './_locale';\nimport { renderSegments, renderText, type Template } from './_template';\nimport { LinguaInvalidPluralCountError } from './errors';\nimport type {\n Catalog,\n Catalogs,\n CatalogTranslatorOptions,\n Locale,\n PluralKey,\n PluralOptions,\n TextKey,\n TranslateOptions,\n TranslatorOptions,\n} from './types';\n\nexport type Translator<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n segments<V>(key: TextKey<C>, options: TranslateOptions & { values: Record<string, V> }): Array<string | V>;\n segments<V>(key: PluralKey<C>, options: PluralOptions & { values?: Record<string, V> }): Array<string | number | V>;\n segmentsDynamic<V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<string | number | V>;\n translate(key: TextKey<C>, options?: TranslateOptions): string;\n translate(key: PluralKey<C>, options: PluralOptions): string;\n translateDynamic(key: string, options?: TranslateOptions | PluralOptions): string;\n};\n\ntype ResolvedMessage = { readonly locale: Locale; readonly message: CompiledMessage };\n\nexport function createTranslatorFromCompiled<C extends Catalog>(\n catalogs: ReadonlyMap<Locale, CompiledCatalog>,\n options: TranslatorOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const fallback = (\n Array.isArray(options.fallback) ? options.fallback : options.fallback ? [options.fallback] : []\n ).map(canonicalLocale);\n const chain = localeChain(locale, fallback);\n const missingKey = options.onMissingKey ?? ((key: string) => key);\n const missingValue = options.onMissingValue ?? ((name: string) => `{${name}}`);\n\n const resolve = (key: string): ResolvedMessage | undefined => {\n for (const candidate of chain) {\n const message = catalogs.get(candidate)?.get(key);\n\n if (message) return { locale: candidate, message };\n }\n\n return undefined;\n };\n\n const templateFor = (\n key: string,\n options: TranslateOptions | PluralOptions,\n ): { key: string; template: Template } | undefined => {\n const found = resolve(key);\n\n if (!found) return undefined;\n\n if (found.message.kind === 'text') {\n if ('count' in options) return undefined;\n\n return { key, template: found.message.template };\n }\n\n if (!('count' in options) || !Number.isFinite(options.count)) {\n if ('count' in options) throw new LinguaInvalidPluralCountError('`count` must be a finite number.');\n\n return undefined;\n }\n\n const category =\n options.count === 0 && !options.ordinal\n ? 'zero'\n : pluralCategory(found.locale, options.count, options.ordinal ?? false);\n const template = found.message.forms.get(category) ?? found.message.forms.get('other');\n\n return template ? { key, template } : undefined;\n };\n\n const valuesFor = (options: TranslateOptions | PluralOptions): Record<string, unknown> =>\n 'count' in options ? { count: options.count, ...options.values } : (options.values ?? {});\n\n const segmentsDynamic = <V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<string | number | V> => {\n const found = templateFor(key, options);\n\n if (!found) return [missingKey(key, locale)];\n\n return renderSegments(found.template, valuesFor(options) as Record<string, V | number>, (name) =>\n missingValue(name, found.key, locale),\n );\n };\n\n const translateDynamic = (key: string, options: TranslateOptions | PluralOptions = {}): string => {\n const found = templateFor(key, options);\n\n if (!found) return missingKey(key, locale);\n\n return renderText(found.template, valuesFor(options), (name) => missingValue(name, found.key, locale));\n };\n\n return {\n locale,\n segments(key: string, options: (TranslateOptions | PluralOptions) & { values?: Record<string, unknown> }) {\n return segmentsDynamic(key, options);\n },\n segmentsDynamic,\n translate(key: string, options: TranslateOptions | PluralOptions = {}) {\n return translateDynamic(key, options);\n },\n translateDynamic,\n } as Translator<C>;\n}\n\n/** Creates a fixed-locale translator from one catalog. Lingua snapshots catalog messages during construction. */\nexport function createCatalogTranslator<C extends Catalog>(\n catalog: C,\n options: CatalogTranslatorOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const compiled = new Map<Locale, CompiledCatalog>([[locale, compileCatalog(catalog)]]);\n\n return createTranslatorFromCompiled<C>(compiled, { ...options, locale });\n}\n\nexport function createTranslator<C extends Catalog>(catalogs: Catalogs<C>, options?: TranslatorOptions): Translator<C> {\n const compiled = new Map<Locale, CompiledCatalog>();\n\n for (const [locale, catalog] of Object.entries(catalogs)) {\n compiled.set(canonicalLocale(locale), compileCatalog(catalog));\n }\n\n return createTranslatorFromCompiled<C>(compiled, options);\n}\n"],"mappings":";;;;;AA+BA,SAAgB,EACd,GACA,IAA6B,CAAC,GACf;CACf,IAAM,IAAS,EAAgB,EAAQ,UAAU,IAAI,GAC/C,KACJ,MAAM,QAAQ,EAAQ,QAAQ,IAAI,EAAQ,WAAW,EAAQ,WAAW,CAAC,EAAQ,QAAQ,IAAI,CAAC,EAAA,CAC9F,IAAI,CAAe,GACf,IAAQ,EAAY,GAAQ,CAAQ,GACpC,IAAa,EAAQ,kBAAkB,MAAgB,IACvD,IAAe,EAAQ,oBAAoB,MAAiB,IAAI,EAAK,KAErE,KAAW,MAA6C;EAC5D,KAAK,IAAM,KAAa,GAAO;GAC7B,IAAM,IAAU,EAAS,IAAI,CAAS,CAAC,EAAE,IAAI,CAAG;GAEhD,IAAI,GAAS,OAAO;IAAE,QAAQ;IAAW;GAAQ;EACnD;CAGF,GAEM,KACJ,GACA,MACoD;EACpD,IAAM,IAAQ,EAAQ,CAAG;EAEzB,IAAI,CAAC,GAAO;EAEZ,IAAI,EAAM,QAAQ,SAAS,QAGzB,OAFI,WAAW,IAAS,SAEjB;GAAE;GAAK,UAAU,EAAM,QAAQ;EAAS;EAGjD,IAAI,EAAE,WAAW,MAAY,CAAC,OAAO,SAAS,EAAQ,KAAK,GAAG;GAC5D,IAAI,WAAW,GAAS,MAAM,IAAI,EAA8B,kCAAkC;GAElG;EACF;EAEA,IAAM,IACJ,EAAQ,UAAU,KAAK,CAAC,EAAQ,UAC5B,SACA,EAAe,EAAM,QAAQ,EAAQ,OAAO,EAAQ,WAAW,EAAK,GACpE,IAAW,EAAM,QAAQ,MAAM,IAAI,CAAQ,KAAK,EAAM,QAAQ,MAAM,IAAI,OAAO;EAErF,OAAO,IAAW;GAAE;GAAK;EAAS,IAAI,KAAA;CACxC,GAEM,KAAa,MACjB,WAAW,IAAU;EAAE,OAAO,EAAQ;EAAO,GAAG,EAAQ;CAAO,IAAK,EAAQ,UAAU,CAAC,GAEnF,KACJ,GACA,MAC+B;EAC/B,IAAM,IAAQ,EAAY,GAAK,CAAO;EAItC,OAFK,IAEE,EAAe,EAAM,UAAU,EAAU,CAAO,IAAkC,MACvF,EAAa,GAAM,EAAM,KAAK,CAAM,CACtC,IAJmB,CAAC,EAAW,GAAK,CAAM,CAAC;CAK7C,GAEM,KAAoB,GAAa,IAA4C,CAAC,MAAc;EAChG,IAAM,IAAQ,EAAY,GAAK,CAAO;EAItC,OAFK,IAEE,EAAW,EAAM,UAAU,EAAU,CAAO,IAAI,MAAS,EAAa,GAAM,EAAM,KAAK,CAAM,CAAC,IAFlF,EAAW,GAAK,CAAM;CAG3C;CAEA,OAAO;EACL;EACA,SAAS,GAAa,GAAoF;GACxG,OAAO,EAAgB,GAAK,CAAO;EACrC;EACA;EACA,UAAU,GAAa,IAA4C,CAAC,GAAG;GACrE,OAAO,EAAiB,GAAK,CAAO;EACtC;EACA;CACF;AACF;AAGA,SAAgB,EACd,GACA,IAAoC,CAAC,GACtB;CACf,IAAM,IAAS,EAAgB,EAAQ,UAAU,IAAI;CAGrD,OAAO,kBAAgC,IAFlB,IAA6B,CAAC,CAAC,GAAQ,EAAe,CAAO,CAAC,CAAC,CAE7C,GAAU;EAAE,GAAG;EAAS;CAAO,CAAC;AACzE;AAEA,SAAgB,EAAoC,GAAuB,GAA4C;CACrH,IAAM,oBAAW,IAAI,IAA6B;CAElD,KAAK,IAAM,CAAC,GAAQ,MAAY,OAAO,QAAQ,CAAQ,GACrD,EAAS,IAAI,EAAgB,CAAM,GAAG,EAAe,CAAO,CAAC;CAG/D,OAAO,EAAgC,GAAU,CAAO;AAC1D"}
1
+ {"version":3,"file":"translator.js","names":[],"sources":["../src/translator.ts"],"sourcesContent":["import { type CompiledCatalog, type CompiledMessage, compileCatalog } from './_catalog';\nimport { warn } from './_dev';\nimport { canonicalLocale, localeChain, pluralCategory } from './_locale';\nimport { renderParts, renderText, type Template } from './_template';\nimport { LinguaInvalidPluralCountError, LinguaMissingKeyError, LinguaMissingValueError } from './errors';\nimport type {\n Catalog,\n Locale,\n MissingInfo,\n MissingStrategy,\n Part,\n PluralKey,\n PluralOptions,\n TextKey,\n TranslateOptions,\n TranslatorOptions,\n} from './types';\n\nexport type Translator<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n parts<V>(key: TextKey<C>, options: TranslateOptions & { values: Record<string, V> }): Array<Part<V>>;\n parts<V>(key: PluralKey<C>, options: PluralOptions & { values?: Record<string, V> }): Array<Part<number | V>>;\n partsDynamic<V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<Part<number | V>>;\n translate(key: TextKey<C>, options?: TranslateOptions): string;\n translate(key: PluralKey<C>, options: PluralOptions): string;\n translateDynamic(key: string, options?: TranslateOptions | PluralOptions): string;\n};\n\ntype InternalOptions = {\n readonly fallback?: Locale | readonly Locale[];\n readonly locale?: Locale;\n readonly missing?: MissingStrategy;\n};\n\nconst isDev = !(globalThis as { __LINGUA_PROD__?: boolean }).__LINGUA_PROD__;\n\nfunction resolveMissing(strategy: MissingStrategy | undefined, info: MissingInfo): string {\n if (strategy === 'throw') {\n throw info.name\n ? new LinguaMissingValueError(\n `Missing interpolation value \"${info.name}\" for key \"${info.key}\" in locale \"${info.locale}\".`,\n )\n : new LinguaMissingKeyError(`Missing translation key \"${info.key}\" in locale \"${info.locale}\".`);\n }\n\n if (typeof strategy === 'function') return strategy(info);\n\n // 'key' or undefined (default)\n if (strategy === undefined && isDev) {\n warn(\n info.name\n ? `Missing interpolation value \"${info.name}\" for key \"${info.key}\" in locale \"${info.locale}\".`\n : `Missing translation key \"${info.key}\" in locale \"${info.locale}\".`,\n );\n }\n\n return info.name ? `{${info.name}}` : info.key;\n}\n\ntype ResolvedMessage = { readonly locale: Locale; readonly message: CompiledMessage };\n\nexport function createTranslatorFromCompiled<C extends Catalog>(\n catalogs: ReadonlyMap<Locale, CompiledCatalog>,\n options: InternalOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const fallback = (\n Array.isArray(options.fallback) ? options.fallback : options.fallback ? [options.fallback] : []\n ).map(canonicalLocale);\n const chain = localeChain(locale, fallback);\n const missing = options.missing;\n\n const missingKey = (key: string): string => resolveMissing(missing, { key, locale });\n const missingValue = (name: string, key: string): string => resolveMissing(missing, { key, locale, name });\n\n const resolve = (key: string): ResolvedMessage | undefined => {\n for (const candidate of chain) {\n const message = catalogs.get(candidate)?.get(key);\n\n if (message) return { locale: candidate, message };\n }\n\n return undefined;\n };\n\n const templateFor = (\n key: string,\n options: TranslateOptions | PluralOptions,\n ): { key: string; template: Template } | undefined => {\n const found = resolve(key);\n\n if (!found) return undefined;\n\n if (found.message.kind === 'text') {\n if ('count' in options) return undefined;\n\n return { key, template: found.message.template };\n }\n\n if (!('count' in options) || !Number.isFinite(options.count)) {\n if ('count' in options) throw new LinguaInvalidPluralCountError('`count` must be a finite number.');\n\n return undefined;\n }\n\n const category =\n options.count === 0 && !options.ordinal\n ? 'zero'\n : pluralCategory(found.locale, options.count, options.ordinal ?? false);\n const template = found.message.forms.get(category) ?? found.message.forms.get('other');\n\n return template ? { key, template } : undefined;\n };\n\n const valuesFor = (options: TranslateOptions | PluralOptions): Record<string, unknown> =>\n 'count' in options ? { count: options.count, ...options.values } : (options.values ?? {});\n\n const partsDynamic = <V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<Part<number | V>> => {\n const found = templateFor(key, options);\n\n if (!found) return [{ type: 'text', value: missingKey(key) }];\n\n return renderParts(found.template, valuesFor(options) as Record<string, V | number>, (name) =>\n missingValue(name, found.key),\n );\n };\n\n const translateDynamic = (key: string, options: TranslateOptions | PluralOptions = {}): string => {\n const found = templateFor(key, options);\n\n if (!found) return missingKey(key);\n\n return renderText(found.template, valuesFor(options), (name) => missingValue(name, found.key));\n };\n\n return {\n locale,\n parts(key: string, options: (TranslateOptions | PluralOptions) & { values?: Record<string, unknown> }) {\n return partsDynamic(key, options);\n },\n partsDynamic,\n translate(key: string, options: TranslateOptions | PluralOptions = {}) {\n return translateDynamic(key, options);\n },\n translateDynamic,\n } as Translator<C>;\n}\n\n/** Creates a fixed-locale translator from one catalog. Lingua snapshots catalog messages during construction. */\nexport function createTranslator<C extends Catalog>(catalog: C, options?: TranslatorOptions): Translator<C> {\n const locale = canonicalLocale(options?.locale ?? 'en');\n const compiled = new Map<Locale, CompiledCatalog>([[locale, compileCatalog(catalog)]]);\n\n return createTranslatorFromCompiled<C>(compiled, { ...options, locale });\n}\n"],"mappings":";;;;;AAuCA,SAAS,EAAe,GAAuC,GAA2B;CACxF,IAAI,MAAa,SACf,MAAM,EAAK,OACP,IAAI,EACF,gCAAgC,EAAK,KAAK,aAAa,EAAK,IAAI,eAAe,EAAK,OAAO,GAC7F,IACA,IAAI,EAAsB,4BAA4B,EAAK,IAAI,eAAe,EAAK,OAAO,GAAG;CAcnG,OAXI,OAAO,KAAa,aAAmB,EAAS,CAAI,IAWjD,EAAK,OAAO,IAAI,EAAK,KAAK,KAAK,EAAK;AAC7C;AAIA,SAAgB,EACd,GACA,IAA2B,CAAC,GACb;CACf,IAAM,IAAS,EAAgB,EAAQ,UAAU,IAAI,GAC/C,KACJ,MAAM,QAAQ,EAAQ,QAAQ,IAAI,EAAQ,WAAW,EAAQ,WAAW,CAAC,EAAQ,QAAQ,IAAI,CAAC,EAAA,CAC9F,IAAI,CAAe,GACf,IAAQ,EAAY,GAAQ,CAAQ,GACpC,IAAU,EAAQ,SAElB,KAAc,MAAwB,EAAe,GAAS;EAAE;EAAK;CAAO,CAAC,GAC7E,KAAgB,GAAc,MAAwB,EAAe,GAAS;EAAE;EAAK;EAAQ;CAAK,CAAC,GAEnG,KAAW,MAA6C;EAC5D,KAAK,IAAM,KAAa,GAAO;GAC7B,IAAM,IAAU,EAAS,IAAI,CAAS,CAAC,EAAE,IAAI,CAAG;GAEhD,IAAI,GAAS,OAAO;IAAE,QAAQ;IAAW;GAAQ;EACnD;CAGF,GAEM,KACJ,GACA,MACoD;EACpD,IAAM,IAAQ,EAAQ,CAAG;EAEzB,IAAI,CAAC,GAAO;EAEZ,IAAI,EAAM,QAAQ,SAAS,QAGzB,OAFI,WAAW,IAAS,SAEjB;GAAE;GAAK,UAAU,EAAM,QAAQ;EAAS;EAGjD,IAAI,EAAE,WAAW,MAAY,CAAC,OAAO,SAAS,EAAQ,KAAK,GAAG;GAC5D,IAAI,WAAW,GAAS,MAAM,IAAI,EAA8B,kCAAkC;GAElG;EACF;EAEA,IAAM,IACJ,EAAQ,UAAU,KAAK,CAAC,EAAQ,UAC5B,SACA,EAAe,EAAM,QAAQ,EAAQ,OAAO,EAAQ,WAAW,EAAK,GACpE,IAAW,EAAM,QAAQ,MAAM,IAAI,CAAQ,KAAK,EAAM,QAAQ,MAAM,IAAI,OAAO;EAErF,OAAO,IAAW;GAAE;GAAK;EAAS,IAAI,KAAA;CACxC,GAEM,KAAa,MACjB,WAAW,IAAU;EAAE,OAAO,EAAQ;EAAO,GAAG,EAAQ;CAAO,IAAK,EAAQ,UAAU,CAAC,GAEnF,KACJ,GACA,MAC4B;EAC5B,IAAM,IAAQ,EAAY,GAAK,CAAO;EAItC,OAFK,IAEE,EAAY,EAAM,UAAU,EAAU,CAAO,IAAkC,MACpF,EAAa,GAAM,EAAM,GAAG,CAC9B,IAJmB,CAAC;GAAE,MAAM;GAAQ,OAAO,EAAW,CAAG;EAAE,CAAC;CAK9D,GAEM,KAAoB,GAAa,IAA4C,CAAC,MAAc;EAChG,IAAM,IAAQ,EAAY,GAAK,CAAO;EAItC,OAFK,IAEE,EAAW,EAAM,UAAU,EAAU,CAAO,IAAI,MAAS,EAAa,GAAM,EAAM,GAAG,CAAC,IAF1E,EAAW,CAAG;CAGnC;CAEA,OAAO;EACL;EACA,MAAM,GAAa,GAAoF;GACrG,OAAO,EAAa,GAAK,CAAO;EAClC;EACA;EACA,UAAU,GAAa,IAA4C,CAAC,GAAG;GACrE,OAAO,EAAiB,GAAK,CAAO;EACtC;EACA;CACF;AACF;AAGA,SAAgB,EAAoC,GAAY,GAA4C;CAC1G,IAAM,IAAS,EAAgB,GAAS,UAAU,IAAI;CAGtD,OAAO,kBAAgC,IAFlB,IAA6B,CAAC,CAAC,GAAQ,EAAe,CAAO,CAAC,CAAC,CAE7C,GAAU;EAAE,GAAG;EAAS;CAAO,CAAC;AACzE"}
package/dist/types.d.ts CHANGED
@@ -9,10 +9,6 @@ export type Catalog = {
9
9
  readonly [key: string]: CatalogNode;
10
10
  };
11
11
  export type Catalogs<C extends Catalog = Catalog> = Record<Locale, C>;
12
- export type CatalogLoader<C extends Catalog = Catalog> = () => Promise<C>;
13
- export type CatalogSource<C extends Catalog = Catalog> = C | CatalogLoader<C>;
14
- /** Locale declarations may contain static catalogs or lazy loaders. */
15
- export type CatalogSources<C extends Catalog = Catalog> = Record<Locale, CatalogSource<C>>;
16
12
  /** Traverses a catalog type and collects dotted paths to nodes matching `Leaf`. */
17
13
  type CatalogPaths<C, Leaf, Prefix extends string = '', Depth extends readonly unknown[] = readonly [1, 1, 1, 1, 1, 1]> = Depth extends readonly [unknown, ...infer Rest] ? C extends Leaf ? Prefix : C extends Catalog ? {
18
14
  [K in string & keyof C]: CatalogPaths<C[K], Leaf, Prefix extends '' ? K : `${Prefix}.${K}`, Rest>;
@@ -28,25 +24,53 @@ export type PluralOptions = TranslateOptions & {
28
24
  count: number;
29
25
  ordinal?: boolean;
30
26
  };
27
+ export type TextPart = {
28
+ readonly type: 'text';
29
+ readonly value: string;
30
+ };
31
+ export type ValuePart<V> = {
32
+ readonly type: 'value';
33
+ readonly value: V;
34
+ };
35
+ export type Part<V> = TextPart | ValuePart<V>;
36
+ export type MissingInfo = {
37
+ readonly key: string;
38
+ readonly locale: Locale;
39
+ readonly name?: string;
40
+ };
41
+ export type MissingHandler = (info: MissingInfo) => string;
42
+ export type MissingStrategy = 'throw' | 'key' | MissingHandler;
31
43
  export type TranslatorOptions = {
32
- fallback?: Locale | readonly Locale[];
33
- locale?: Locale;
34
- onMissingKey?: (key: string, locale: Locale) => string;
35
- onMissingValue?: (name: string, key: string, locale: Locale) => string;
44
+ readonly locale?: Locale;
45
+ readonly missing?: MissingStrategy;
36
46
  };
37
- /** Options for a translator built from one immutable locale catalog. */
38
- export type CatalogTranslatorOptions = Omit<TranslatorOptions, 'fallback'>;
47
+ type I18nCommonOptions = {
48
+ readonly fallback?: Locale | readonly Locale[];
49
+ readonly locale?: Locale;
50
+ readonly missing?: MissingStrategy;
51
+ };
52
+ type CatalogLoader<C extends Catalog> = (locale: Locale) => Promise<C> | C;
53
+ export type I18nOptions<C extends Catalog = Catalog> = I18nCommonOptions & ({
54
+ readonly catalogs: Catalogs<C>;
55
+ readonly loadCatalog?: CatalogLoader<C>;
56
+ readonly state?: never;
57
+ } | {
58
+ readonly catalogs?: never;
59
+ readonly loadCatalog?: CatalogLoader<C>;
60
+ readonly state: TranslationState<C>;
61
+ } | {
62
+ readonly catalogs?: never;
63
+ readonly loadCatalog: CatalogLoader<C>;
64
+ readonly state?: never;
65
+ });
39
66
  export type SubscribeOptions = {
40
67
  immediate?: boolean;
41
68
  signal?: AbortSignal;
42
69
  };
43
- export type TranslationStoreOptions<C extends Catalog = Catalog> = TranslatorOptions & {
44
- catalogs: CatalogSources<C>;
45
- };
46
70
  export type TranslationState<C extends Catalog = Catalog> = {
47
71
  readonly catalogs: Catalogs<C>;
48
72
  readonly locale: Locale;
49
- readonly version: 3;
73
+ readonly version: 4;
50
74
  };
51
75
  export {};
52
76
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vielzeug/lingua",
3
- "version": "2.4.0",
4
- "description": "Explicit typed localization with pluralization, lazy locale catalogs, and SSR hydration",
3
+ "version": "3.0.0",
4
+ "description": "Explicit typed localization with pluralization, lazy locale loading, and SSR hydration",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/helmuthdu/vielzeug",
@@ -50,21 +50,21 @@
50
50
  "registry": "https://registry.npmjs.org/"
51
51
  },
52
52
  "scripts": {
53
- "build": "pnpm run typecheck && vite build && pnpm run build:bundle && pnpm run build:types && pnpm run verify:exports",
53
+ "build": "pnpm --silent run typecheck && vite build && pnpm --silent run build:bundle && pnpm --silent run build:types && pnpm --silent run verify:exports",
54
54
  "build:bundle": "vite build --config vite.bundle.config.ts",
55
55
  "build:types": "tsc -p tsconfig.declarations.json",
56
56
  "fix": "biome check --write src",
57
57
  "lint": "biome ci src",
58
- "prepublishOnly": "pnpm run build",
58
+ "prepublishOnly": "pnpm --silent run build",
59
59
  "preview": "vite preview",
60
- "test": "pnpm run typecheck && vitest",
60
+ "test": "pnpm --silent run typecheck && vitest",
61
61
  "typecheck": "tsc -p tsconfig.json --noEmit",
62
62
  "verify:exports": "node ./scripts/verify-exports.mjs"
63
63
  },
64
64
  "devDependencies": {
65
- "@types/node": "^26.2.0",
65
+ "@types/node": "^26.4.1",
66
66
  "typescript": "^6.0.3",
67
- "vite": "^8.2.1",
68
- "vitest": "^4.1.10"
67
+ "vite": "^8.2.2",
68
+ "vitest": "^5.0.0"
69
69
  }
70
70
  }