@intlayer/ngx-translate 9.5.10

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 (58) hide show
  1. package/README.md +329 -0
  2. package/dist/esm/esbuild/index.mjs +43 -0
  3. package/dist/esm/esbuild/index.mjs.map +1 -0
  4. package/dist/esm/handlers.mjs +116 -0
  5. package/dist/esm/handlers.mjs.map +1 -0
  6. package/dist/esm/index.mjs +11 -0
  7. package/dist/esm/partialDeclarations.mjs +0 -0
  8. package/dist/esm/plugin/index.mjs +49 -0
  9. package/dist/esm/plugin/index.mjs.map +1 -0
  10. package/dist/esm/providers.mjs +53 -0
  11. package/dist/esm/providers.mjs.map +1 -0
  12. package/dist/esm/registryLookup.mjs +52 -0
  13. package/dist/esm/registryLookup.mjs.map +1 -0
  14. package/dist/esm/standalone.mjs +27 -0
  15. package/dist/esm/standalone.mjs.map +1 -0
  16. package/dist/esm/translateBlockDirective.mjs +47 -0
  17. package/dist/esm/translateBlockDirective.mjs.map +1 -0
  18. package/dist/esm/translateDirective.mjs +66 -0
  19. package/dist/esm/translateDirective.mjs.map +1 -0
  20. package/dist/esm/translatePipe.mjs +60 -0
  21. package/dist/esm/translatePipe.mjs.map +1 -0
  22. package/dist/esm/translateService.mjs +224 -0
  23. package/dist/esm/translateService.mjs.map +1 -0
  24. package/dist/esm/translateStore.mjs +53 -0
  25. package/dist/esm/translateStore.mjs.map +1 -0
  26. package/dist/esm/types.mjs +0 -0
  27. package/dist/esm/util.mjs +44 -0
  28. package/dist/esm/util.mjs.map +1 -0
  29. package/dist/types/esbuild/index.d.ts +23 -0
  30. package/dist/types/esbuild/index.d.ts.map +1 -0
  31. package/dist/types/handlers.d.ts +52 -0
  32. package/dist/types/handlers.d.ts.map +1 -0
  33. package/dist/types/index.d.ts +11 -0
  34. package/dist/types/partialDeclarations.d.ts +18 -0
  35. package/dist/types/partialDeclarations.d.ts.map +1 -0
  36. package/dist/types/plugin/index.d.ts +25 -0
  37. package/dist/types/plugin/index.d.ts.map +1 -0
  38. package/dist/types/providers.d.ts +22 -0
  39. package/dist/types/providers.d.ts.map +1 -0
  40. package/dist/types/registryLookup.d.ts +13 -0
  41. package/dist/types/registryLookup.d.ts.map +1 -0
  42. package/dist/types/standalone.d.ts +24 -0
  43. package/dist/types/standalone.d.ts.map +1 -0
  44. package/dist/types/translateBlockDirective.d.ts +23 -0
  45. package/dist/types/translateBlockDirective.d.ts.map +1 -0
  46. package/dist/types/translateDirective.d.ts +33 -0
  47. package/dist/types/translateDirective.d.ts.map +1 -0
  48. package/dist/types/translatePipe.d.ts +21 -0
  49. package/dist/types/translatePipe.d.ts.map +1 -0
  50. package/dist/types/translateService.d.ts +106 -0
  51. package/dist/types/translateService.d.ts.map +1 -0
  52. package/dist/types/translateStore.d.ts +21 -0
  53. package/dist/types/translateStore.d.ts.map +1 -0
  54. package/dist/types/types.d.ts +56 -0
  55. package/dist/types/types.d.ts.map +1 -0
  56. package/dist/types/util.d.ts +22 -0
  57. package/dist/types/util.d.ts.map +1 -0
  58. package/package.json +115 -0
@@ -0,0 +1,53 @@
1
+ import { DefaultMissingTranslationHandler, MissingTranslationHandler, TranslateCompiler, TranslateDefaultParser, TranslateLoader, TranslateNoOpCompiler, TranslateNoOpLoader, TranslateParser } from "./handlers.mjs";
2
+ import { TranslateStore } from "./translateStore.mjs";
3
+ import { TRANSLATE_SERVICE_CONFIG, TranslateService } from "./translateService.mjs";
4
+
5
+ //#region src/providers.ts
6
+ /** Whether a function is a class constructor rather than a factory. */
7
+ const isClass = (value) => typeof value === "function" && /^class\s/.test(Function.prototype.toString.call(value));
8
+ const toProvider = (token, value) => isClass(value) ? {
9
+ provide: token,
10
+ useClass: value
11
+ } : {
12
+ provide: token,
13
+ useFactory: value
14
+ };
15
+ const provideTranslateLoader = (loader) => toProvider(TranslateLoader, loader);
16
+ const provideTranslateCompiler = (compiler) => toProvider(TranslateCompiler, compiler);
17
+ const provideTranslateParser = (parser) => toProvider(TranslateParser, parser);
18
+ const provideMissingTranslationHandler = (handler) => toProvider(MissingTranslationHandler, handler);
19
+ /**
20
+ * A plugin slot: the default class, a bare class / factory (wrapped), or a
21
+ * ready provider.
22
+ */
23
+ const resolvePluginProvider = (token, value, defaultClass) => {
24
+ if (value === void 0) return toProvider(token, defaultClass);
25
+ if (typeof value === "function") return toProvider(token, value);
26
+ return value;
27
+ };
28
+ const createProviders = (config) => [
29
+ resolvePluginProvider(TranslateLoader, config.loader, TranslateNoOpLoader),
30
+ resolvePluginProvider(TranslateCompiler, config.compiler, TranslateNoOpCompiler),
31
+ resolvePluginProvider(TranslateParser, config.parser, TranslateDefaultParser),
32
+ resolvePluginProvider(MissingTranslationHandler, config.missingTranslationHandler, DefaultMissingTranslationHandler),
33
+ TranslateStore,
34
+ {
35
+ provide: TRANSLATE_SERVICE_CONFIG,
36
+ useValue: config
37
+ },
38
+ TranslateService
39
+ ];
40
+ /**
41
+ * Root providers: `bootstrapApplication(App, { providers: [
42
+ * provideIntlayer(), provideTranslateService({ fallbackLang: 'en' })] })`.
43
+ */
44
+ const provideTranslateService = (config = {}) => createProviders(config);
45
+ /**
46
+ * Providers for a lazy route or component subtree. Every service shares
47
+ * intlayer's locale, so a child service only scopes runtime translations.
48
+ */
49
+ const provideChildTranslateService = (config = {}) => createProviders(config);
50
+
51
+ //#endregion
52
+ export { provideChildTranslateService, provideMissingTranslationHandler, provideTranslateCompiler, provideTranslateLoader, provideTranslateParser, provideTranslateService };
53
+ //# sourceMappingURL=providers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.mjs","names":[],"sources":["../../src/providers.ts"],"sourcesContent":["import type { Provider, Type } from '@angular/core';\nimport {\n DefaultMissingTranslationHandler,\n MissingTranslationHandler,\n TranslateCompiler,\n TranslateDefaultParser,\n TranslateLoader,\n TranslateNoOpCompiler,\n TranslateNoOpLoader,\n TranslateParser,\n} from './handlers';\nimport { TRANSLATE_SERVICE_CONFIG, TranslateService } from './translateService';\nimport { TranslateStore } from './translateStore';\nimport type {\n ChildTranslateServiceConfig,\n RootTranslateServiceConfig,\n TranslateProvider,\n} from './types';\n\n/** A class to instantiate, or a factory returning the instance. */\ntype ClassOrFactory<T> = Type<T> | (() => T);\n\n/** Whether a function is a class constructor rather than a factory. */\nconst isClass = (value: unknown): value is Type<unknown> =>\n typeof value === 'function' &&\n /^class\\s/.test(Function.prototype.toString.call(value));\n\nconst toProvider = <T>(\n token: abstract new (...args: never[]) => T,\n value: ClassOrFactory<T>\n): Provider =>\n isClass(value)\n ? { provide: token, useClass: value }\n : { provide: token, useFactory: value as () => T };\n\nexport const provideTranslateLoader = (\n loader: ClassOrFactory<TranslateLoader>\n): Provider => toProvider(TranslateLoader, loader);\n\nexport const provideTranslateCompiler = (\n compiler: ClassOrFactory<TranslateCompiler>\n): Provider => toProvider(TranslateCompiler, compiler);\n\nexport const provideTranslateParser = (\n parser: ClassOrFactory<TranslateParser>\n): Provider => toProvider(TranslateParser, parser);\n\nexport const provideMissingTranslationHandler = (\n handler: ClassOrFactory<MissingTranslationHandler>\n): Provider => toProvider(MissingTranslationHandler, handler);\n\n/**\n * A plugin slot: the default class, a bare class / factory (wrapped), or a\n * ready provider.\n */\nconst resolvePluginProvider = <T>(\n token: abstract new (...args: never[]) => T,\n value: TranslateProvider | ClassOrFactory<T> | undefined,\n defaultClass: Type<T>\n): Provider => {\n if (value === undefined) return toProvider(token, defaultClass);\n if (typeof value === 'function') {\n return toProvider(token, value as ClassOrFactory<T>);\n }\n return value;\n};\n\nconst createProviders = (\n config: RootTranslateServiceConfig & ChildTranslateServiceConfig\n): Provider[] => [\n resolvePluginProvider(TranslateLoader, config.loader, TranslateNoOpLoader),\n resolvePluginProvider(\n TranslateCompiler,\n config.compiler,\n TranslateNoOpCompiler\n ),\n resolvePluginProvider(TranslateParser, config.parser, TranslateDefaultParser),\n resolvePluginProvider(\n MissingTranslationHandler,\n config.missingTranslationHandler,\n DefaultMissingTranslationHandler\n ),\n TranslateStore,\n { provide: TRANSLATE_SERVICE_CONFIG, useValue: config },\n TranslateService,\n];\n\n/**\n * Root providers: `bootstrapApplication(App, { providers: [\n * provideIntlayer(), provideTranslateService({ fallbackLang: 'en' })] })`.\n */\nexport const provideTranslateService = (\n config: RootTranslateServiceConfig = {}\n): Provider[] => createProviders(config);\n\n/**\n * Providers for a lazy route or component subtree. Every service shares\n * intlayer's locale, so a child service only scopes runtime translations.\n */\nexport const provideChildTranslateService = (\n config: ChildTranslateServiceConfig = {}\n): Provider[] => createProviders(config);\n"],"mappings":";;;;;;AAuBA,MAAM,WAAW,UACf,OAAO,UAAU,cACjB,WAAW,KAAK,SAAS,UAAU,SAAS,KAAK,KAAK,CAAC;AAEzD,MAAM,cACJ,OACA,UAEA,QAAQ,KAAK,IACT;CAAE,SAAS;CAAO,UAAU;AAAM,IAClC;CAAE,SAAS;CAAO,YAAY;AAAiB;AAErD,MAAa,0BACX,WACa,WAAW,iBAAiB,MAAM;AAEjD,MAAa,4BACX,aACa,WAAW,mBAAmB,QAAQ;AAErD,MAAa,0BACX,WACa,WAAW,iBAAiB,MAAM;AAEjD,MAAa,oCACX,YACa,WAAW,2BAA2B,OAAO;;;;;AAM5D,MAAM,yBACJ,OACA,OACA,iBACa;CACb,IAAI,UAAU,QAAW,OAAO,WAAW,OAAO,YAAY;CAC9D,IAAI,OAAO,UAAU,YACnB,OAAO,WAAW,OAAO,KAA0B;CAErD,OAAO;AACT;AAEA,MAAM,mBACJ,WACe;CACf,sBAAsB,iBAAiB,OAAO,QAAQ,mBAAmB;CACzE,sBACE,mBACA,OAAO,UACP,qBACF;CACA,sBAAsB,iBAAiB,OAAO,QAAQ,sBAAsB;CAC5E,sBACE,2BACA,OAAO,2BACP,gCACF;CACA;CACA;EAAE,SAAS;EAA0B,UAAU;CAAO;CACtD;AACF;;;;;AAMA,MAAa,2BACX,SAAqC,CAAC,MACvB,gBAAgB,MAAM;;;;;AAMvC,MAAa,gCACX,SAAsC,CAAC,MACxB,gBAAgB,MAAM"}
@@ -0,0 +1,52 @@
1
+ import { navigatePath } from "@intlayer/core/messageFormat";
2
+ import { getIntlayer } from "@intlayer/core/interpreter";
3
+ import { getDictionaries } from "@intlayer/dictionaries-entry";
4
+
5
+ //#region src/registryLookup.ts
6
+ /**
7
+ * Registry-backed key resolution. The only module touching
8
+ * `@intlayer/dictionaries-entry`, which statically imports every dictionary.
9
+ */
10
+ /** Keys of every dictionary available at runtime; empty outside a bundle. */
11
+ const getDictionaryKeys = () => {
12
+ try {
13
+ return new Set(Object.keys(getDictionaries()));
14
+ } catch {
15
+ return /* @__PURE__ */ new Set();
16
+ }
17
+ };
18
+ const readDictionary = (key, locale) => {
19
+ try {
20
+ return getIntlayer(key, locale);
21
+ } catch {
22
+ return;
23
+ }
24
+ };
25
+ /**
26
+ * Looks up an ngx-translate key across the intlayer dictionaries:
27
+ *
28
+ * 1. `'home.title'` → dictionary `home`, field `title`;
29
+ * 2. `'home'` → the whole `home` dictionary;
30
+ * 3. the full key in every dictionary — a single migrated `en.json`.
31
+ *
32
+ * @returns The interpreted node (string, object or callable), or `undefined`.
33
+ */
34
+ const lookupRegistryTranslation = (key, locale) => {
35
+ const dictionaryKeys = getDictionaryKeys();
36
+ const dotPosition = key.indexOf(".");
37
+ if (dotPosition > 0) {
38
+ const dictionaryKey = key.slice(0, dotPosition);
39
+ if (dictionaryKeys.has(dictionaryKey)) {
40
+ const translation = navigatePath(readDictionary(dictionaryKey, locale), key.slice(dotPosition + 1));
41
+ if (translation !== void 0) return translation;
42
+ }
43
+ } else if (dictionaryKeys.has(key)) return readDictionary(key, locale);
44
+ for (const dictionaryKey of dictionaryKeys) {
45
+ const translation = navigatePath(readDictionary(dictionaryKey, locale), key);
46
+ if (translation !== void 0) return translation;
47
+ }
48
+ };
49
+
50
+ //#endregion
51
+ export { lookupRegistryTranslation };
52
+ //# sourceMappingURL=registryLookup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registryLookup.mjs","names":[],"sources":["../../src/registryLookup.ts"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport { navigatePath } from '@intlayer/core/messageFormat';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Registry-backed key resolution. The only module touching\n * `@intlayer/dictionaries-entry`, which statically imports every dictionary.\n */\n\n/** Keys of every dictionary available at runtime; empty outside a bundle. */\nconst getDictionaryKeys = (): Set<string> => {\n try {\n return new Set(Object.keys(getDictionaries()));\n } catch {\n return new Set();\n }\n};\n\nconst readDictionary = (key: string, locale: string): unknown => {\n try {\n return getIntlayer(key as DictionaryKeys, locale as LocalesValues);\n } catch {\n return undefined;\n }\n};\n\n/**\n * Looks up an ngx-translate key across the intlayer dictionaries:\n *\n * 1. `'home.title'` → dictionary `home`, field `title`;\n * 2. `'home'` → the whole `home` dictionary;\n * 3. the full key in every dictionary — a single migrated `en.json`.\n *\n * @returns The interpreted node (string, object or callable), or `undefined`.\n */\nexport const lookupRegistryTranslation = (\n key: string,\n locale: string\n): unknown => {\n const dictionaryKeys = getDictionaryKeys();\n const dotPosition = key.indexOf('.');\n\n if (dotPosition > 0) {\n const dictionaryKey = key.slice(0, dotPosition);\n\n if (dictionaryKeys.has(dictionaryKey)) {\n const translation = navigatePath(\n readDictionary(dictionaryKey, locale),\n key.slice(dotPosition + 1)\n );\n if (translation !== undefined) return translation;\n }\n } else if (dictionaryKeys.has(key)) {\n return readDictionary(key, locale);\n }\n\n for (const dictionaryKey of dictionaryKeys) {\n const translation = navigatePath(\n readDictionary(dictionaryKey, locale),\n key\n );\n if (translation !== undefined) return translation;\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;;AAcA,MAAM,0BAAuC;CAC3C,IAAI;EACF,OAAO,IAAI,IAAI,OAAO,KAAK,gBAAgB,CAAC,CAAC;CAC/C,QAAQ;EACN,uBAAO,IAAI,IAAI;CACjB;AACF;AAEA,MAAM,kBAAkB,KAAa,WAA4B;CAC/D,IAAI;EACF,OAAO,YAAY,KAAuB,MAAuB;CACnE,QAAQ;EACN;CACF;AACF;;;;;;;;;;AAWA,MAAa,6BACX,KACA,WACY;CACZ,MAAM,iBAAiB,kBAAkB;CACzC,MAAM,cAAc,IAAI,QAAQ,GAAG;CAEnC,IAAI,cAAc,GAAG;EACnB,MAAM,gBAAgB,IAAI,MAAM,GAAG,WAAW;EAE9C,IAAI,eAAe,IAAI,aAAa,GAAG;GACrC,MAAM,cAAc,aAClB,eAAe,eAAe,MAAM,GACpC,IAAI,MAAM,cAAc,CAAC,CAC3B;GACA,IAAI,gBAAgB,QAAW,OAAO;EACxC;CACF,OAAO,IAAI,eAAe,IAAI,GAAG,GAC/B,OAAO,eAAe,KAAK,MAAM;CAGnC,KAAK,MAAM,iBAAiB,gBAAgB;EAC1C,MAAM,cAAc,aAClB,eAAe,eAAe,MAAM,GACpC,GACF;EACA,IAAI,gBAAgB,QAAW,OAAO;CACxC;AAGF"}
@@ -0,0 +1,27 @@
1
+ import { TranslateService } from "./translateService.mjs";
2
+ import { inject } from "@angular/core";
3
+
4
+ //#region src/standalone.ts
5
+ /**
6
+ * Signal of a translation, updated on language change. Must run in an
7
+ * injection context.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * readonly title = translate('home.title');
12
+ * ```
13
+ */
14
+ const translate = (key, params, lang) => inject(TranslateService).translate(key, params, lang);
15
+ /**
16
+ * Marks a key for extraction tools; returns it unchanged.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const titleKey = _('home.title');
21
+ * ```
22
+ */
23
+ const _ = (key) => key;
24
+
25
+ //#endregion
26
+ export { _, translate };
27
+ //# sourceMappingURL=standalone.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.mjs","names":[],"sources":["../../src/standalone.ts"],"sourcesContent":["import { inject, type Signal } from '@angular/core';\nimport { TranslateService } from './translateService';\nimport type { InterpolationParameters, Language, Translation } from './types';\n\n/**\n * Signal of a translation, updated on language change. Must run in an\n * injection context.\n *\n * @example\n * ```ts\n * readonly title = translate('home.title');\n * ```\n */\nexport const translate = (\n key: string | string[] | (() => string | string[]),\n params?:\n | InterpolationParameters\n | (() => InterpolationParameters | undefined),\n lang?: Language | (() => Language | undefined)\n): Signal<Translation> => inject(TranslateService).translate(key, params, lang);\n\n/**\n * Marks a key for extraction tools; returns it unchanged.\n *\n * @example\n * ```ts\n * const titleKey = _('home.title');\n * ```\n */\nexport const _ = <T extends string | string[]>(key: T): T => key;\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,aACX,KACA,QAGA,SACwB,OAAO,gBAAgB,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI;;;;;;;;;AAU9E,MAAa,KAAkC,QAAc"}
@@ -0,0 +1,47 @@
1
+ import { TranslateService } from "./translateService.mjs";
2
+ import * as i0 from "@angular/core";
3
+ import { TemplateRef, ViewContainerRef, inject } from "@angular/core";
4
+
5
+ //#region src/translateBlockDirective.ts
6
+ /** Template context of `*translateBlock="let t"`. */
7
+ var TranslateBlockContext = class {
8
+ $implicit;
9
+ constructor($implicit) {
10
+ this.$implicit = $implicit;
11
+ }
12
+ };
13
+ /**
14
+ * `<div *translateBlock="let t">{{ t('home.title') }}</div>` — exposes
15
+ * `instant` to a template block.
16
+ */
17
+ var TranslateBlockDirective = class TranslateBlockDirective {
18
+ templateRef = inject(TemplateRef);
19
+ viewContainer = inject(ViewContainerRef);
20
+ translateService = inject(TranslateService);
21
+ ngOnInit() {
22
+ this.viewContainer.createEmbeddedView(this.templateRef, new TranslateBlockContext((key, params) => this.translateService.instant(key, params)));
23
+ }
24
+ static ngTemplateContextGuard(_directive, _context) {
25
+ return true;
26
+ }
27
+ static ɵfac = i0.ɵɵngDeclareFactory({
28
+ minVersion: "12.0.0",
29
+ version: "17.0.0",
30
+ ngImport: i0,
31
+ type: TranslateBlockDirective,
32
+ deps: [],
33
+ target: i0.ɵɵFactoryTarget.Directive
34
+ });
35
+ static ɵdir = i0.ɵɵngDeclareDirective({
36
+ minVersion: "14.0.0",
37
+ version: "17.0.0",
38
+ type: TranslateBlockDirective,
39
+ isStandalone: true,
40
+ selector: "[translateBlock]",
41
+ ngImport: i0
42
+ });
43
+ };
44
+
45
+ //#endregion
46
+ export { TranslateBlockContext, TranslateBlockDirective };
47
+ //# sourceMappingURL=translateBlockDirective.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translateBlockDirective.mjs","names":[],"sources":["../../src/translateBlockDirective.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { inject, TemplateRef, ViewContainerRef } from '@angular/core';\nimport type {\n DirectiveDeclaration,\n FactoryDeclaration,\n} from './partialDeclarations';\nimport { TranslateService } from './translateService';\nimport type { InterpolationParameters, Translation } from './types';\n\n/** Template context of `*translateBlock=\"let t\"`. */\nexport class TranslateBlockContext {\n constructor(\n public $implicit: (\n key: string,\n params?: InterpolationParameters\n ) => Translation\n ) {}\n}\n\n/**\n * `<div *translateBlock=\"let t\">{{ t('home.title') }}</div>` — exposes\n * `instant` to a template block.\n */\nexport class TranslateBlockDirective {\n private readonly templateRef =\n inject<TemplateRef<TranslateBlockContext>>(TemplateRef);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly translateService = inject(TranslateService);\n\n ngOnInit(): void {\n this.viewContainer.createEmbeddedView(\n this.templateRef,\n new TranslateBlockContext((key, params) =>\n this.translateService.instant(key, params)\n )\n );\n }\n\n static ngTemplateContextGuard(\n _directive: TranslateBlockDirective,\n _context: unknown\n ): _context is TranslateBlockContext {\n return true;\n }\n\n static ɵfac: i0.ɵɵFactoryDeclaration<TranslateBlockDirective, never> =\n i0.ɵɵngDeclareFactory({\n minVersion: '12.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslateBlockDirective,\n deps: [],\n target: i0.ɵɵFactoryTarget.Directive,\n } as FactoryDeclaration) as never;\n static ɵdir: i0.ɵɵDirectiveDeclaration<\n TranslateBlockDirective,\n '[translateBlock]',\n never,\n {},\n {},\n never,\n never,\n true,\n never\n > = i0.ɵɵngDeclareDirective({\n minVersion: '14.0.0',\n version: '17.0.0',\n type: TranslateBlockDirective,\n isStandalone: true,\n selector: '[translateBlock]',\n ngImport: i0,\n } as DirectiveDeclaration) as never;\n}\n"],"mappings":";;;;;;AAUA,IAAa,wBAAb,MAAmC;CAExB;CADT,YACE,AAAO,WAIP;EAJO;CAIN;AACL;;;;;AAMA,IAAa,0BAAb,MAAa,wBAAwB;CACnC,AAAiB,cACf,OAA2C,WAAW;CACxD,AAAiB,gBAAgB,OAAO,gBAAgB;CACxD,AAAiB,mBAAmB,OAAO,gBAAgB;CAE3D,WAAiB;EACf,KAAK,cAAc,mBACjB,KAAK,aACL,IAAI,uBAAuB,KAAK,WAC9B,KAAK,iBAAiB,QAAQ,KAAK,MAAM,CAC3C,CACF;CACF;CAEA,OAAO,uBACL,YACA,UACmC;EACnC,OAAO;CACT;CAEA,OAAO,OACL,GAAG,mBAAmB;EACpB,YAAY;EACZ,SAAS;EACT,UAAU;EACV,MAAM;EACN,MAAM,CAAC;EACP,QAAQ,GAAG,gBAAgB;CAC7B,CAAuB;CACzB,OAAO,OAUH,GAAG,qBAAqB;EAC1B,YAAY;EACZ,SAAS;EACT,MAAM;EACN,cAAc;EACd,UAAU;EACV,UAAU;CACZ,CAAyB;AAC3B"}
@@ -0,0 +1,66 @@
1
+ import { equals, isString } from "./util.mjs";
2
+ import { TranslateService } from "./translateService.mjs";
3
+ import * as i0 from "@angular/core";
4
+ import { ElementRef, Injector, effect, inject, signal } from "@angular/core";
5
+
6
+ //#region src/translateDirective.ts
7
+ /**
8
+ * `<p [translate]="'home.title'" [translateParams]="{ name }"></p>` or
9
+ * `<p translate>home.title</p>` — writes the translation as text content.
10
+ */
11
+ var TranslateDirective = class TranslateDirective {
12
+ translateService = inject(TranslateService);
13
+ element = inject(ElementRef);
14
+ injector = inject(Injector);
15
+ keySignal = signal(void 0);
16
+ paramsSignal = signal(void 0);
17
+ translation = null;
18
+ set translate(key) {
19
+ if (!key) return;
20
+ this.keySignal.set(key);
21
+ this.ensureRendering();
22
+ }
23
+ set translateParams(params) {
24
+ if (!equals(this.paramsSignal(), params)) this.paramsSignal.set(params);
25
+ }
26
+ /** Content-key form: the element's own text is the key. */
27
+ ngAfterViewInit() {
28
+ if (this.keySignal()) return;
29
+ const contentKey = this.element.nativeElement.textContent?.trim();
30
+ if (!contentKey) return;
31
+ this.keySignal.set(contentKey);
32
+ this.ensureRendering();
33
+ }
34
+ ensureRendering() {
35
+ if (this.translation) return;
36
+ this.translation = this.translateService.translate(() => this.keySignal() ?? "", () => this.paramsSignal());
37
+ effect(() => {
38
+ const value = this.translation?.();
39
+ this.element.nativeElement.textContent = isString(value) ? value : value === void 0 || value === null ? this.keySignal() ?? "" : JSON.stringify(value);
40
+ }, { injector: this.injector });
41
+ }
42
+ static ɵfac = i0.ɵɵngDeclareFactory({
43
+ minVersion: "12.0.0",
44
+ version: "17.0.0",
45
+ ngImport: i0,
46
+ type: TranslateDirective,
47
+ deps: [],
48
+ target: i0.ɵɵFactoryTarget.Directive
49
+ });
50
+ static ɵdir = i0.ɵɵngDeclareDirective({
51
+ minVersion: "14.0.0",
52
+ version: "17.0.0",
53
+ type: TranslateDirective,
54
+ isStandalone: true,
55
+ selector: "[translate],[ngx-translate]",
56
+ inputs: {
57
+ translate: "translate",
58
+ translateParams: "translateParams"
59
+ },
60
+ ngImport: i0
61
+ });
62
+ };
63
+
64
+ //#endregion
65
+ export { TranslateDirective };
66
+ //# sourceMappingURL=translateDirective.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translateDirective.mjs","names":[],"sources":["../../src/translateDirective.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport {\n ElementRef,\n effect,\n Injector,\n inject,\n type Signal,\n signal,\n type WritableSignal,\n} from '@angular/core';\nimport type {\n DirectiveDeclaration,\n FactoryDeclaration,\n} from './partialDeclarations';\nimport { TranslateService } from './translateService';\nimport type { InterpolationParameters, Translation } from './types';\nimport { equals, isString } from './util';\n\n/**\n * `<p [translate]=\"'home.title'\" [translateParams]=\"{ name }\"></p>` or\n * `<p translate>home.title</p>` — writes the translation as text content.\n */\nexport class TranslateDirective {\n private readonly translateService = inject(TranslateService);\n private readonly element = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n private readonly keySignal: WritableSignal<string | undefined> =\n signal(undefined);\n private readonly paramsSignal: WritableSignal<\n InterpolationParameters | undefined\n > = signal(undefined);\n private translation: Signal<Translation> | null = null;\n\n set translate(key: string) {\n if (!key) return;\n this.keySignal.set(key);\n this.ensureRendering();\n }\n\n set translateParams(params: InterpolationParameters) {\n if (!equals(this.paramsSignal(), params)) this.paramsSignal.set(params);\n }\n\n /** Content-key form: the element's own text is the key. */\n ngAfterViewInit(): void {\n if (this.keySignal()) return;\n\n const contentKey = this.element.nativeElement.textContent?.trim();\n if (!contentKey) return;\n\n this.keySignal.set(contentKey);\n this.ensureRendering();\n }\n\n private ensureRendering(): void {\n if (this.translation) return;\n\n this.translation = this.translateService.translate(\n () => this.keySignal() ?? '',\n () => this.paramsSignal()\n );\n\n effect(\n () => {\n const value = this.translation?.();\n this.element.nativeElement.textContent = isString(value)\n ? value\n : value === undefined || value === null\n ? (this.keySignal() ?? '')\n : JSON.stringify(value);\n },\n { injector: this.injector }\n );\n }\n\n static ɵfac: i0.ɵɵFactoryDeclaration<TranslateDirective, never> =\n i0.ɵɵngDeclareFactory({\n minVersion: '12.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslateDirective,\n deps: [],\n target: i0.ɵɵFactoryTarget.Directive,\n } as FactoryDeclaration) as never;\n static ɵdir: i0.ɵɵDirectiveDeclaration<\n TranslateDirective,\n '[translate],[ngx-translate]',\n never,\n {\n translate: { alias: 'translate'; required: false };\n translateParams: { alias: 'translateParams'; required: false };\n },\n {},\n never,\n never,\n true,\n never\n > = i0.ɵɵngDeclareDirective({\n minVersion: '14.0.0',\n version: '17.0.0',\n type: TranslateDirective,\n isStandalone: true,\n selector: '[translate],[ngx-translate]',\n inputs: {\n translate: 'translate',\n translateParams: 'translateParams',\n },\n ngImport: i0,\n } as DirectiveDeclaration) as never;\n}\n"],"mappings":";;;;;;;;;;AAsBA,IAAa,qBAAb,MAAa,mBAAmB;CAC9B,AAAiB,mBAAmB,OAAO,gBAAgB;CAC3D,AAAiB,UAAU,OAAgC,UAAU;CACrE,AAAiB,WAAW,OAAO,QAAQ;CAE3C,AAAiB,YACf,OAAO,MAAS;CAClB,AAAiB,eAEb,OAAO,MAAS;CACpB,AAAQ,cAA0C;CAElD,IAAI,UAAU,KAAa;EACzB,IAAI,CAAC,KAAK;EACV,KAAK,UAAU,IAAI,GAAG;EACtB,KAAK,gBAAgB;CACvB;CAEA,IAAI,gBAAgB,QAAiC;EACnD,IAAI,CAAC,OAAO,KAAK,aAAa,GAAG,MAAM,GAAG,KAAK,aAAa,IAAI,MAAM;CACxE;;CAGA,kBAAwB;EACtB,IAAI,KAAK,UAAU,GAAG;EAEtB,MAAM,aAAa,KAAK,QAAQ,cAAc,aAAa,KAAK;EAChE,IAAI,CAAC,YAAY;EAEjB,KAAK,UAAU,IAAI,UAAU;EAC7B,KAAK,gBAAgB;CACvB;CAEA,AAAQ,kBAAwB;EAC9B,IAAI,KAAK,aAAa;EAEtB,KAAK,cAAc,KAAK,iBAAiB,gBACjC,KAAK,UAAU,KAAK,UACpB,KAAK,aAAa,CAC1B;EAEA,aACQ;GACJ,MAAM,QAAQ,KAAK,cAAc;GACjC,KAAK,QAAQ,cAAc,cAAc,SAAS,KAAK,IACnD,QACA,UAAU,UAAa,UAAU,OAC9B,KAAK,UAAU,KAAK,KACrB,KAAK,UAAU,KAAK;EAC5B,GACA,EAAE,UAAU,KAAK,SAAS,CAC5B;CACF;CAEA,OAAO,OACL,GAAG,mBAAmB;EACpB,YAAY;EACZ,SAAS;EACT,UAAU;EACV,MAAM;EACN,MAAM,CAAC;EACP,QAAQ,GAAG,gBAAgB;CAC7B,CAAuB;CACzB,OAAO,OAaH,GAAG,qBAAqB;EAC1B,YAAY;EACZ,SAAS;EACT,MAAM;EACN,cAAc;EACd,UAAU;EACV,QAAQ;GACN,WAAW;GACX,iBAAiB;EACnB;EACA,UAAU;CACZ,CAAyB;AAC3B"}
@@ -0,0 +1,60 @@
1
+ import { equals, isDict, isString } from "./util.mjs";
2
+ import { TranslateService } from "./translateService.mjs";
3
+ import * as i0 from "@angular/core";
4
+ import { inject } from "@angular/core";
5
+
6
+ //#region src/translatePipe.ts
7
+ /**
8
+ * `{{ 'home.title' | translate: { name } }}` — impure pipe reading a
9
+ * translation signal, so the view refreshes on language change.
10
+ */
11
+ var TranslatePipe = class TranslatePipe {
12
+ translateService = inject(TranslateService);
13
+ cachedTranslation = null;
14
+ lastKey = null;
15
+ lastParams;
16
+ transform(query, ...args) {
17
+ if (!query?.length) return query;
18
+ const interpolateParams = this.parseArgs(args);
19
+ if (query !== this.lastKey || !equals(interpolateParams, this.lastParams)) {
20
+ this.cachedTranslation = this.translateService.translate(query, interpolateParams);
21
+ this.lastKey = query;
22
+ this.lastParams = interpolateParams;
23
+ }
24
+ return this.cachedTranslation?.();
25
+ }
26
+ /** Accepts an object, or an object literal written as a template string. */
27
+ parseArgs(args) {
28
+ const [firstArgument] = args;
29
+ if (isString(firstArgument) && firstArgument.length) {
30
+ const json = firstArgument.replace(/(')?([a-zA-Z0-9_]+)(')?(\s)?:/g, "\"$2\":").replace(/:(\s)?(')(.*?)(')/g, ":\"$3\"");
31
+ try {
32
+ return JSON.parse(json);
33
+ } catch {
34
+ throw new SyntaxError(`Wrong parameter in TranslatePipe. Expected a valid Object, received: ${firstArgument}`);
35
+ }
36
+ }
37
+ return isDict(firstArgument) ? firstArgument : void 0;
38
+ }
39
+ static ɵfac = i0.ɵɵngDeclareFactory({
40
+ minVersion: "12.0.0",
41
+ version: "17.0.0",
42
+ ngImport: i0,
43
+ type: TranslatePipe,
44
+ deps: [],
45
+ target: i0.ɵɵFactoryTarget.Pipe
46
+ });
47
+ static ɵpipe = i0.ɵɵngDeclarePipe({
48
+ minVersion: "14.0.0",
49
+ version: "17.0.0",
50
+ ngImport: i0,
51
+ type: TranslatePipe,
52
+ isStandalone: true,
53
+ name: "translate",
54
+ pure: false
55
+ });
56
+ };
57
+
58
+ //#endregion
59
+ export { TranslatePipe };
60
+ //# sourceMappingURL=translatePipe.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translatePipe.mjs","names":[],"sources":["../../src/translatePipe.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport { inject, type PipeTransform, type Signal } from '@angular/core';\nimport type {\n FactoryDeclaration,\n PipeDeclaration,\n} from './partialDeclarations';\nimport { TranslateService } from './translateService';\nimport type { InterpolationParameters, Translation } from './types';\nimport { equals, isDict, isString } from './util';\n\n/**\n * `{{ 'home.title' | translate: { name } }}` — impure pipe reading a\n * translation signal, so the view refreshes on language change.\n */\nexport class TranslatePipe implements PipeTransform {\n private readonly translateService = inject(TranslateService);\n private cachedTranslation: Signal<Translation> | null = null;\n private lastKey: string | null = null;\n private lastParams: InterpolationParameters | undefined;\n\n transform(\n query: string | undefined | null,\n ...args: unknown[]\n ): Translation | undefined | null {\n if (!query?.length) return query;\n\n const interpolateParams = this.parseArgs(args);\n\n if (query !== this.lastKey || !equals(interpolateParams, this.lastParams)) {\n this.cachedTranslation = this.translateService.translate(\n query,\n interpolateParams\n );\n this.lastKey = query;\n this.lastParams = interpolateParams;\n }\n\n return this.cachedTranslation?.();\n }\n\n /** Accepts an object, or an object literal written as a template string. */\n private parseArgs(args: unknown[]): InterpolationParameters | undefined {\n const [firstArgument] = args;\n\n if (isString(firstArgument) && firstArgument.length) {\n const json = firstArgument\n .replace(/(')?([a-zA-Z0-9_]+)(')?(\\s)?:/g, '\"$2\":')\n .replace(/:(\\s)?(')(.*?)(')/g, ':\"$3\"');\n try {\n return JSON.parse(json) as InterpolationParameters;\n } catch {\n throw new SyntaxError(\n `Wrong parameter in TranslatePipe. Expected a valid Object, received: ${firstArgument}`\n );\n }\n }\n\n return isDict(firstArgument) ? firstArgument : undefined;\n }\n\n static ɵfac: i0.ɵɵFactoryDeclaration<TranslatePipe, never> =\n i0.ɵɵngDeclareFactory({\n minVersion: '12.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslatePipe,\n deps: [],\n target: i0.ɵɵFactoryTarget.Pipe,\n } as FactoryDeclaration) as never;\n static ɵpipe: i0.ɵɵPipeDeclaration<TranslatePipe, 'translate', true> =\n i0.ɵɵngDeclarePipe({\n minVersion: '14.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslatePipe,\n isStandalone: true,\n name: 'translate',\n pure: false,\n } as PipeDeclaration) as never;\n}\n"],"mappings":";;;;;;;;;;AAcA,IAAa,gBAAb,MAAa,cAAuC;CAClD,AAAiB,mBAAmB,OAAO,gBAAgB;CAC3D,AAAQ,oBAAgD;CACxD,AAAQ,UAAyB;CACjC,AAAQ;CAER,UACE,OACA,GAAG,MAC6B;EAChC,IAAI,CAAC,OAAO,QAAQ,OAAO;EAE3B,MAAM,oBAAoB,KAAK,UAAU,IAAI;EAE7C,IAAI,UAAU,KAAK,WAAW,CAAC,OAAO,mBAAmB,KAAK,UAAU,GAAG;GACzE,KAAK,oBAAoB,KAAK,iBAAiB,UAC7C,OACA,iBACF;GACA,KAAK,UAAU;GACf,KAAK,aAAa;EACpB;EAEA,OAAO,KAAK,oBAAoB;CAClC;;CAGA,AAAQ,UAAU,MAAsD;EACtE,MAAM,CAAC,iBAAiB;EAExB,IAAI,SAAS,aAAa,KAAK,cAAc,QAAQ;GACnD,MAAM,OAAO,cACV,QAAQ,kCAAkC,SAAO,CAAC,CAClD,QAAQ,sBAAsB,SAAO;GACxC,IAAI;IACF,OAAO,KAAK,MAAM,IAAI;GACxB,QAAQ;IACN,MAAM,IAAI,YACR,wEAAwE,eAC1E;GACF;EACF;EAEA,OAAO,OAAO,aAAa,IAAI,gBAAgB;CACjD;CAEA,OAAO,OACL,GAAG,mBAAmB;EACpB,YAAY;EACZ,SAAS;EACT,UAAU;EACV,MAAM;EACN,MAAM,CAAC;EACP,QAAQ,GAAG,gBAAgB;CAC7B,CAAuB;CACzB,OAAO,QACL,GAAG,gBAAgB;EACjB,YAAY;EACZ,SAAS;EACT,UAAU;EACV,MAAM;EACN,cAAc;EACd,MAAM;EACN,MAAM;CACR,CAAoB;AACxB"}
@@ -0,0 +1,224 @@
1
+ import { insertValue, isDict, isString } from "./util.mjs";
2
+ import { MissingTranslationHandler, TranslateCompiler, TranslateLoader, TranslateNoOpLoader, TranslateParser } from "./handlers.mjs";
3
+ import { lookupRegistryTranslation } from "./registryLookup.mjs";
4
+ import { TranslateStore } from "./translateStore.mjs";
5
+ import * as i0 from "@angular/core";
6
+ import { InjectionToken, computed, inject, signal, untracked } from "@angular/core";
7
+ import { Subject, isObservable, map, merge, of, startWith } from "rxjs";
8
+ import { resolveMessageNodeToString } from "@intlayer/core/messageFormat";
9
+ import { internationalization } from "@intlayer/config/built";
10
+ import { createIntlayerClient } from "angular-intlayer";
11
+
12
+ //#region src/translateService.ts
13
+ /** Resolved `provideTranslateService()` options. */
14
+ const TRANSLATE_SERVICE_CONFIG = new InjectionToken("TRANSLATE_SERVICE_CONFIG");
15
+ /** Resolves a plain value or a function / signal returning it. */
16
+ const readInput = (input) => typeof input === "function" ? input() : input;
17
+ /** Abstract API of {@link TranslateService}, kept for type compatibility. */
18
+ var ITranslateService = class {};
19
+ /**
20
+ * ngx-translate's `TranslateService` over intlayer.
21
+ *
22
+ * - The active language is angular-intlayer's locale signal, so `use()`,
23
+ * `useLocale().setLocale()` and `useIntlayer()` share one locale.
24
+ * - Keys resolve against runtime translations (`setTranslation()`, a
25
+ * configured loader) first, then the intlayer dictionaries — the first key
26
+ * segment names the dictionary (`'home.title'` → `home`).
27
+ * - Everything is synchronous: dictionaries are bundled, so `get()` and
28
+ * `use()` emit immediately.
29
+ */
30
+ var TranslateService = class TranslateService extends ITranslateService {
31
+ intlayerClient = createIntlayerClient();
32
+ config = inject(TRANSLATE_SERVICE_CONFIG, { optional: true });
33
+ store = inject(TranslateStore);
34
+ currentLoader = inject(TranslateLoader);
35
+ compiler = inject(TranslateCompiler);
36
+ parser = inject(TranslateParser);
37
+ missingTranslationHandler = inject(MissingTranslationHandler);
38
+ fallbackLangSignal = signal(null);
39
+ isLoadingSignal = signal(false);
40
+ langChangeSubject = new Subject();
41
+ fallbackLangChangeSubject = new Subject();
42
+ /** The active language, shared with angular-intlayer. */
43
+ currentLang = computed(() => this.intlayerClient.locale());
44
+ fallbackLang = this.fallbackLangSignal.asReadonly();
45
+ isLoading = this.isLoadingSignal.asReadonly();
46
+ onLangChange = this.langChangeSubject.asObservable();
47
+ onFallbackLangChange = this.fallbackLangChangeSubject.asObservable();
48
+ /** @deprecated Use `onFallbackLangChange`. */
49
+ onDefaultLangChange = this.onFallbackLangChange;
50
+ onTranslationChange = this.store.translationChange$;
51
+ /** Emits whenever displayed translations may have changed. */
52
+ onTranslationRefresh = merge(this.onLangChange, this.onTranslationChange, this.onFallbackLangChange);
53
+ constructor() {
54
+ super();
55
+ const fallbackLang = this.config?.fallbackLang ?? this.config?.defaultLanguage;
56
+ if (fallbackLang) this.setFallbackLang(fallbackLang);
57
+ if (this.config?.lang) this.use(this.config.lang);
58
+ }
59
+ getCurrentLang() {
60
+ return untracked(this.currentLang);
61
+ }
62
+ getFallbackLang() {
63
+ return untracked(this.fallbackLang);
64
+ }
65
+ /** Sets the language whose translations fill the gaps of the active one. */
66
+ setFallbackLang(lang) {
67
+ this.fallbackLangSignal.set(lang);
68
+ this.fallbackLangChangeSubject.next({
69
+ lang,
70
+ translations: this.store.getTranslations(lang)
71
+ });
72
+ return this.loadTranslations(lang);
73
+ }
74
+ /** @deprecated Use `setFallbackLang`. */
75
+ setDefaultLang(lang) {
76
+ return this.setFallbackLang(lang);
77
+ }
78
+ /** @deprecated Use `getFallbackLang`. */
79
+ getDefaultLang() {
80
+ return this.getFallbackLang();
81
+ }
82
+ /** Activates a language, through angular-intlayer's locale. */
83
+ use(lang) {
84
+ const translations$ = this.loadTranslations(lang);
85
+ if (lang !== this.getCurrentLang()) {
86
+ this.intlayerClient.setLocale(lang);
87
+ this.langChangeSubject.next({
88
+ lang,
89
+ translations: this.store.getTranslations(lang)
90
+ });
91
+ }
92
+ return translations$;
93
+ }
94
+ /**
95
+ * Runs a configured loader once per language. Intlayer dictionaries need
96
+ * none, so the default no-op loader short-circuits.
97
+ */
98
+ loadTranslations(lang) {
99
+ if (this.currentLoader instanceof TranslateNoOpLoader || lang in this.store.translations()) return of(this.store.getTranslations(lang));
100
+ this.isLoadingSignal.set(true);
101
+ return this.currentLoader.getTranslation(lang).pipe(map((translations) => {
102
+ this.setTranslation(lang, translations, true);
103
+ this.isLoadingSignal.set(false);
104
+ return this.store.getTranslations(lang);
105
+ }));
106
+ }
107
+ reloadLang(lang) {
108
+ this.resetLang(lang);
109
+ return this.loadTranslations(lang);
110
+ }
111
+ resetLang(lang) {
112
+ this.store.deleteTranslations(lang);
113
+ }
114
+ /** Languages declared in intlayer plus any registered at runtime. */
115
+ getLangs() {
116
+ return [.../* @__PURE__ */ new Set([...internationalization?.locales ?? [], ...Object.keys(this.store.translations())])];
117
+ }
118
+ /** Kept for API parity: the intlayer configuration owns the locale list. */
119
+ addLangs(_languages) {}
120
+ getTranslations(lang) {
121
+ return this.store.getTranslations(lang);
122
+ }
123
+ getTranslation(lang) {
124
+ return this.loadTranslations(lang);
125
+ }
126
+ /** Registers runtime translations, compiled by the configured compiler. */
127
+ setTranslation(lang, translations, shouldMerge = false) {
128
+ this.store.setTranslations(lang, this.compiler.compileTranslations(translations, lang), shouldMerge);
129
+ }
130
+ /** Registers translations that are already compiled. */
131
+ setCompiledTranslation(lang, translations, shouldMerge = false) {
132
+ this.store.setTranslations(lang, translations, shouldMerge);
133
+ }
134
+ /** Sets one runtime translation. */
135
+ set(key, translation, lang = this.getCurrentLang()) {
136
+ this.store.setTranslations(lang, insertValue(this.store.getTranslations(lang), key, isString(translation) ? this.compiler.compile(translation, lang) : this.compiler.compileTranslations(translation, lang)), false);
137
+ }
138
+ /**
139
+ * Interpolates a raw translation, recursing into subtrees. Strings go
140
+ * through the configured parser (`{{ name }}`); functions are either
141
+ * compiled runtime translations (parser) or intlayer nodes (resolver).
142
+ */
143
+ interpolate(translation, params, lang, isDictionaryContent) {
144
+ if (Array.isArray(translation)) return translation.map((item) => this.interpolate(item, params, lang, isDictionaryContent));
145
+ if (isDict(translation)) return Object.fromEntries(Object.entries(translation).map(([key, value]) => [key, this.interpolate(value, params, lang, isDictionaryContent)]));
146
+ if (isDictionaryContent && typeof translation === "function") return resolveMessageNodeToString(translation, params, lang);
147
+ return this.parser.interpolate(translation, params) ?? "";
148
+ }
149
+ /** Interpolated translation of `key` in `lang`, or `undefined`. */
150
+ resolveKey(key, params, lang) {
151
+ const runtimeTranslation = this.store.getTranslationValue(lang, key);
152
+ if (runtimeTranslation !== void 0 && runtimeTranslation !== null) return this.interpolate(runtimeTranslation, params, lang, false);
153
+ const dictionaryContent = lookupRegistryTranslation(key, lang);
154
+ if (dictionaryContent !== void 0 && dictionaryContent !== null) return this.interpolate(dictionaryContent, params, lang, true);
155
+ }
156
+ /** Translation of a key, or of each key of a list. */
157
+ getParsedResult(key, interpolateParams, lang) {
158
+ if (Array.isArray(key)) return Object.fromEntries(key.map((singleKey) => [singleKey, this.instant(singleKey, interpolateParams, lang)]));
159
+ const targetLang = lang ?? this.currentLang();
160
+ const fallbackLang = this.fallbackLang();
161
+ for (const candidateLang of [targetLang, fallbackLang]) {
162
+ if (!candidateLang) continue;
163
+ const translation = this.resolveKey(key, interpolateParams ?? {}, candidateLang);
164
+ if (translation !== void 0) return translation;
165
+ }
166
+ return this.missingTranslationHandler.handle({
167
+ key,
168
+ translateService: this,
169
+ interpolateParams
170
+ }) ?? key;
171
+ }
172
+ /** Synchronous translation. Reads signals, so it is reactive in templates. */
173
+ instant(key, interpolateParams, lang) {
174
+ if (!key?.length) return "";
175
+ this.store.translations();
176
+ const result = this.getParsedResult(key, interpolateParams, lang);
177
+ return isObservable(result) ? key : result;
178
+ }
179
+ /** Emits the translation once. */
180
+ get(key, interpolateParams, lang) {
181
+ return of(this.instant(key, interpolateParams, lang));
182
+ }
183
+ /** Emits the translation now and after every language change. */
184
+ stream(key, interpolateParams, lang) {
185
+ return this.onTranslationRefresh.pipe(startWith(null), map(() => this.instant(key, interpolateParams, lang)));
186
+ }
187
+ /** Signal of the translation, updated on language or translation change. */
188
+ translate(key, params, lang) {
189
+ return computed(() => this.instant(readInput(key), readInput(params), readInput(lang)));
190
+ }
191
+ getBrowserLang() {
192
+ return TranslateService.getBrowserLang();
193
+ }
194
+ getBrowserCultureLang() {
195
+ return TranslateService.getBrowserCultureLang();
196
+ }
197
+ /** The browser's language without region, e.g. `"de"`. */
198
+ static getBrowserLang() {
199
+ return TranslateService.getBrowserCultureLang()?.split(/[-_]/)[0];
200
+ }
201
+ /** The browser's language with region, e.g. `"de-DE"`. */
202
+ static getBrowserCultureLang() {
203
+ if (typeof navigator === "undefined") return void 0;
204
+ return navigator.languages?.[0] ?? navigator.language;
205
+ }
206
+ static ɵfac = i0.ɵɵngDeclareFactory({
207
+ minVersion: "12.0.0",
208
+ version: "17.0.0",
209
+ ngImport: i0,
210
+ type: TranslateService,
211
+ deps: [],
212
+ target: i0.ɵɵFactoryTarget.Injectable
213
+ });
214
+ static ɵprov = i0.ɵɵngDeclareInjectable({
215
+ minVersion: "12.0.0",
216
+ version: "17.0.0",
217
+ ngImport: i0,
218
+ type: TranslateService
219
+ });
220
+ };
221
+
222
+ //#endregion
223
+ export { ITranslateService, TRANSLATE_SERVICE_CONFIG, TranslateService };
224
+ //# sourceMappingURL=translateService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translateService.mjs","names":[],"sources":["../../src/translateService.ts"],"sourcesContent":["import * as i0 from '@angular/core';\nimport {\n computed,\n InjectionToken,\n inject,\n type Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport { internationalization } from '@intlayer/config/built';\nimport { resolveMessageNodeToString } from '@intlayer/core/messageFormat';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { createIntlayerClient } from 'angular-intlayer';\nimport {\n isObservable,\n map,\n merge,\n type Observable,\n of,\n Subject,\n startWith,\n} from 'rxjs';\nimport {\n MissingTranslationHandler,\n TranslateCompiler,\n TranslateLoader,\n TranslateNoOpLoader,\n TranslateParser,\n} from './handlers';\nimport type {\n FactoryDeclaration,\n InjectableDeclaration,\n} from './partialDeclarations';\nimport { lookupRegistryTranslation } from './registryLookup';\nimport { TranslateStore } from './translateStore';\nimport type {\n FallbackLangChangeEvent,\n InterpolatableTranslation,\n InterpolatableTranslationObject,\n InterpolationParameters,\n LangChangeEvent,\n Language,\n RootTranslateServiceConfig,\n StrictTranslation,\n Translation,\n TranslationChangeEvent,\n TranslationObject,\n} from './types';\nimport { insertValue, isDict, isString } from './util';\n\n/** Resolved `provideTranslateService()` options. */\nexport const TRANSLATE_SERVICE_CONFIG =\n new InjectionToken<RootTranslateServiceConfig>('TRANSLATE_SERVICE_CONFIG');\n\n/** A key, a key list, or a reactive source of either. */\ntype KeyInput = string | string[] | (() => string | string[]);\n\n/** Resolves a plain value or a function / signal returning it. */\nconst readInput = <T>(input: T | (() => T)): T =>\n typeof input === 'function' ? (input as () => T)() : input;\n\n/** Abstract API of {@link TranslateService}, kept for type compatibility. */\nexport abstract class ITranslateService {}\n\n/**\n * ngx-translate's `TranslateService` over intlayer.\n *\n * - The active language is angular-intlayer's locale signal, so `use()`,\n * `useLocale().setLocale()` and `useIntlayer()` share one locale.\n * - Keys resolve against runtime translations (`setTranslation()`, a\n * configured loader) first, then the intlayer dictionaries — the first key\n * segment names the dictionary (`'home.title'` → `home`).\n * - Everything is synchronous: dictionaries are bundled, so `get()` and\n * `use()` emit immediately.\n */\nexport class TranslateService extends ITranslateService {\n private readonly intlayerClient = createIntlayerClient();\n private readonly config = inject(TRANSLATE_SERVICE_CONFIG, {\n optional: true,\n });\n\n readonly store = inject(TranslateStore);\n readonly currentLoader = inject(TranslateLoader);\n readonly compiler = inject(TranslateCompiler);\n readonly parser = inject(TranslateParser);\n readonly missingTranslationHandler = inject(MissingTranslationHandler);\n\n private readonly fallbackLangSignal = signal<Language | null>(null);\n private readonly isLoadingSignal = signal(false);\n private readonly langChangeSubject = new Subject<LangChangeEvent>();\n private readonly fallbackLangChangeSubject =\n new Subject<FallbackLangChangeEvent>();\n\n /** The active language, shared with angular-intlayer. */\n readonly currentLang: Signal<Language> = computed(\n () => this.intlayerClient.locale() as Language\n );\n readonly fallbackLang: Signal<Language | null> =\n this.fallbackLangSignal.asReadonly();\n readonly isLoading: Signal<boolean> = this.isLoadingSignal.asReadonly();\n\n readonly onLangChange: Observable<LangChangeEvent> =\n this.langChangeSubject.asObservable();\n readonly onFallbackLangChange: Observable<FallbackLangChangeEvent> =\n this.fallbackLangChangeSubject.asObservable();\n /** @deprecated Use `onFallbackLangChange`. */\n readonly onDefaultLangChange = this.onFallbackLangChange;\n readonly onTranslationChange: Observable<TranslationChangeEvent> =\n this.store.translationChange$;\n /** Emits whenever displayed translations may have changed. */\n readonly onTranslationRefresh: Observable<unknown> = merge(\n this.onLangChange,\n this.onTranslationChange,\n this.onFallbackLangChange\n );\n\n constructor() {\n super();\n\n const fallbackLang =\n this.config?.fallbackLang ?? this.config?.defaultLanguage;\n if (fallbackLang) this.setFallbackLang(fallbackLang);\n if (this.config?.lang) this.use(this.config.lang);\n }\n\n getCurrentLang(): Language {\n return untracked(this.currentLang);\n }\n\n getFallbackLang(): Language | null {\n return untracked(this.fallbackLang);\n }\n\n /** Sets the language whose translations fill the gaps of the active one. */\n setFallbackLang(lang: Language): Observable<InterpolatableTranslationObject> {\n this.fallbackLangSignal.set(lang);\n this.fallbackLangChangeSubject.next({\n lang,\n translations: this.store.getTranslations(lang),\n });\n return this.loadTranslations(lang);\n }\n\n /** @deprecated Use `setFallbackLang`. */\n setDefaultLang(lang: Language): Observable<InterpolatableTranslationObject> {\n return this.setFallbackLang(lang);\n }\n\n /** @deprecated Use `getFallbackLang`. */\n getDefaultLang(): Language | null {\n return this.getFallbackLang();\n }\n\n /** Activates a language, through angular-intlayer's locale. */\n use(lang: Language): Observable<InterpolatableTranslationObject> {\n const translations$ = this.loadTranslations(lang);\n\n if (lang !== this.getCurrentLang()) {\n this.intlayerClient.setLocale(lang as LocalesValues);\n this.langChangeSubject.next({\n lang,\n translations: this.store.getTranslations(lang),\n });\n }\n\n return translations$;\n }\n\n /**\n * Runs a configured loader once per language. Intlayer dictionaries need\n * none, so the default no-op loader short-circuits.\n */\n private loadTranslations(\n lang: Language\n ): Observable<InterpolatableTranslationObject> {\n if (\n this.currentLoader instanceof TranslateNoOpLoader ||\n lang in this.store.translations()\n ) {\n return of(this.store.getTranslations(lang));\n }\n\n this.isLoadingSignal.set(true);\n\n return this.currentLoader.getTranslation(lang).pipe(\n map((translations) => {\n this.setTranslation(lang, translations, true);\n this.isLoadingSignal.set(false);\n return this.store.getTranslations(lang);\n })\n );\n }\n\n reloadLang(lang: Language): Observable<InterpolatableTranslationObject> {\n this.resetLang(lang);\n return this.loadTranslations(lang);\n }\n\n resetLang(lang: Language): void {\n this.store.deleteTranslations(lang);\n }\n\n /** Languages declared in intlayer plus any registered at runtime. */\n getLangs(): readonly Language[] {\n return [\n ...new Set([\n ...((internationalization?.locales ?? []) as Language[]),\n ...Object.keys(this.store.translations()),\n ]),\n ];\n }\n\n /** Kept for API parity: the intlayer configuration owns the locale list. */\n addLangs(_languages: Language[]): void {}\n\n getTranslations(lang: Language): InterpolatableTranslationObject {\n return this.store.getTranslations(lang);\n }\n\n getTranslation(lang: Language): Observable<InterpolatableTranslationObject> {\n return this.loadTranslations(lang);\n }\n\n /** Registers runtime translations, compiled by the configured compiler. */\n setTranslation(\n lang: Language,\n translations: TranslationObject,\n shouldMerge = false\n ): void {\n this.store.setTranslations(\n lang,\n this.compiler.compileTranslations(translations, lang),\n shouldMerge\n );\n }\n\n /** Registers translations that are already compiled. */\n setCompiledTranslation(\n lang: Language,\n translations: InterpolatableTranslationObject,\n shouldMerge = false\n ): void {\n this.store.setTranslations(lang, translations, shouldMerge);\n }\n\n /** Sets one runtime translation. */\n set(\n key: string,\n translation: string | TranslationObject,\n lang: Language = this.getCurrentLang()\n ): void {\n this.store.setTranslations(\n lang,\n insertValue(\n this.store.getTranslations(lang),\n key,\n isString(translation)\n ? this.compiler.compile(translation, lang)\n : this.compiler.compileTranslations(translation, lang)\n ),\n false\n );\n }\n\n /**\n * Interpolates a raw translation, recursing into subtrees. Strings go\n * through the configured parser (`{{ name }}`); functions are either\n * compiled runtime translations (parser) or intlayer nodes (resolver).\n */\n private interpolate(\n translation: InterpolatableTranslation,\n params: InterpolationParameters,\n lang: Language,\n isDictionaryContent: boolean\n ): Translation {\n if (Array.isArray(translation)) {\n return translation.map((item) =>\n this.interpolate(item, params, lang, isDictionaryContent)\n );\n }\n if (isDict(translation)) {\n return Object.fromEntries(\n Object.entries(translation).map(([key, value]) => [\n key,\n this.interpolate(value, params, lang, isDictionaryContent),\n ])\n );\n }\n if (isDictionaryContent && typeof translation === 'function') {\n return resolveMessageNodeToString(\n translation,\n params,\n lang as LocalesValues\n );\n }\n return this.parser.interpolate(translation, params) ?? '';\n }\n\n /** Interpolated translation of `key` in `lang`, or `undefined`. */\n private resolveKey(\n key: string,\n params: InterpolationParameters,\n lang: Language\n ): Translation | undefined {\n const runtimeTranslation = this.store.getTranslationValue(lang, key);\n if (runtimeTranslation !== undefined && runtimeTranslation !== null) {\n return this.interpolate(\n runtimeTranslation as InterpolatableTranslation,\n params,\n lang,\n false\n );\n }\n\n const dictionaryContent = lookupRegistryTranslation(key, lang);\n if (dictionaryContent !== undefined && dictionaryContent !== null) {\n return this.interpolate(\n dictionaryContent as InterpolatableTranslation,\n params,\n lang,\n true\n );\n }\n\n return undefined;\n }\n\n /** Translation of a key, or of each key of a list. */\n getParsedResult(\n key: string | string[],\n interpolateParams?: InterpolationParameters,\n lang?: Language\n ): StrictTranslation | Observable<StrictTranslation> {\n if (Array.isArray(key)) {\n return Object.fromEntries(\n key.map((singleKey) => [\n singleKey,\n this.instant(singleKey, interpolateParams, lang),\n ])\n );\n }\n\n const targetLang = lang ?? this.currentLang();\n const fallbackLang = this.fallbackLang();\n\n for (const candidateLang of [targetLang, fallbackLang]) {\n if (!candidateLang) continue;\n\n const translation = this.resolveKey(\n key,\n interpolateParams ?? {},\n candidateLang\n );\n if (translation !== undefined) return translation as StrictTranslation;\n }\n\n return (\n this.missingTranslationHandler.handle({\n key,\n translateService: this,\n interpolateParams,\n }) ?? key\n );\n }\n\n /** Synchronous translation. Reads signals, so it is reactive in templates. */\n instant(\n key: string | string[],\n interpolateParams?: InterpolationParameters,\n lang?: Language\n ): Translation {\n if (!key?.length) return '';\n\n // Track runtime translation changes for signal consumers.\n this.store.translations();\n\n const result = this.getParsedResult(key, interpolateParams, lang);\n return isObservable(result) ? key : result;\n }\n\n /** Emits the translation once. */\n get(\n key: string | string[],\n interpolateParams?: InterpolationParameters,\n lang?: Language\n ): Observable<Translation> {\n return of(this.instant(key, interpolateParams, lang));\n }\n\n /** Emits the translation now and after every language change. */\n stream(\n key: string | string[],\n interpolateParams?: InterpolationParameters,\n lang?: Language\n ): Observable<Translation> {\n return this.onTranslationRefresh.pipe(\n startWith(null),\n map(() => this.instant(key, interpolateParams, lang))\n );\n }\n\n /** Signal of the translation, updated on language or translation change. */\n translate(\n key: KeyInput,\n params?:\n | InterpolationParameters\n | (() => InterpolationParameters | undefined),\n lang?: Language | (() => Language | undefined)\n ): Signal<Translation> {\n return computed(() =>\n this.instant(readInput(key), readInput(params), readInput(lang))\n );\n }\n\n getBrowserLang(): Language | undefined {\n return TranslateService.getBrowserLang();\n }\n\n getBrowserCultureLang(): Language | undefined {\n return TranslateService.getBrowserCultureLang();\n }\n\n /** The browser's language without region, e.g. `\"de\"`. */\n static getBrowserLang(): Language | undefined {\n return TranslateService.getBrowserCultureLang()?.split(/[-_]/)[0];\n }\n\n /** The browser's language with region, e.g. `\"de-DE\"`. */\n static getBrowserCultureLang(): Language | undefined {\n if (typeof navigator === 'undefined') return undefined;\n return navigator.languages?.[0] ?? navigator.language;\n }\n\n static ɵfac: i0.ɵɵFactoryDeclaration<TranslateService, never> =\n i0.ɵɵngDeclareFactory({\n minVersion: '12.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslateService,\n deps: [],\n target: i0.ɵɵFactoryTarget.Injectable,\n } as FactoryDeclaration) as never;\n static ɵprov: i0.ɵɵInjectableDeclaration<TranslateService> =\n i0.ɵɵngDeclareInjectable({\n minVersion: '12.0.0',\n version: '17.0.0',\n ngImport: i0,\n type: TranslateService,\n } as InjectableDeclaration) as never;\n}\n"],"mappings":"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"}