diff --git a/libs/transloco/src/lib/helpers.ts b/libs/transloco/src/lib/helpers.ts index 92032233..1fd3e1e4 100644 --- a/libs/transloco/src/lib/helpers.ts +++ b/libs/transloco/src/lib/helpers.ts @@ -86,11 +86,7 @@ export function coerceArray(value: T | T[]): T[] { * given: path-to_happiness => pathToHappiness * */ -export function toCamelCase(str: string, ignoreLowerUpperCase = false): string { - if (ignoreLowerUpperCase) { - return str.replace(/\s+|_|-|\//g, ''); - } - +export function toCamelCase(str: string): string { return str .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index == 0 ? word.toLowerCase() : word.toUpperCase(), diff --git a/libs/transloco/src/lib/scope-resolver.ts b/libs/transloco/src/lib/scope-resolver.ts index 05589c11..6ec6211f 100644 --- a/libs/transloco/src/lib/scope-resolver.ts +++ b/libs/transloco/src/lib/scope-resolver.ts @@ -1,11 +1,4 @@ -import { Inject } from '@angular/core'; - import { TranslocoScope, ProviderScope, OrArray } from './types'; -import { - TRANSLOCO_CONFIG, - TranslocoConfig, - PartialTranslocoConfig, -} from './transloco.config'; import { TranslocoService } from './transloco.service'; import { isScopeObject, toCamelCase } from './helpers'; @@ -15,14 +8,7 @@ type ScopeResolverParams = { }; export class ScopeResolver { - readonly config: TranslocoConfig; - - constructor( - private service: TranslocoService, - @Inject(TRANSLOCO_CONFIG) userConfig: PartialTranslocoConfig = {}, - ) { - this.config = JSON.parse(JSON.stringify(userConfig)); - } + constructor(private service: TranslocoService) {} // inline => provider resolve(params: ScopeResolverParams): string | undefined { @@ -35,7 +21,9 @@ export class ScopeResolver { if (isScopeObject(provider)) { const { scope, - alias = toCamelCase(scope, this.config.ignoreScopeCase), + alias = this.service.config.scope.keepNamespaceCasing + ? scope + : toCamelCase(scope), } = provider as ProviderScope; this.service._setScopeAlias(scope, alias); diff --git a/libs/transloco/src/lib/tests/scope-resolver.spec.ts b/libs/transloco/src/lib/tests/scope-resolver.spec.ts index 0a786cae..3425d525 100644 --- a/libs/transloco/src/lib/tests/scope-resolver.spec.ts +++ b/libs/transloco/src/lib/tests/scope-resolver.spec.ts @@ -1,4 +1,3 @@ -import { TranslocoConfig } from '../transloco.config'; import { ScopeResolver } from '../scope-resolver'; describe('ScopeResolver', () => { @@ -7,12 +6,9 @@ describe('ScopeResolver', () => { beforeEach(() => { spy = jasmine.createSpy('setScopeAlias'); - resolver = new ScopeResolver( - { - _setScopeAlias: spy, - } as any, - {} as TranslocoConfig, - ); + resolver = new ScopeResolver({ + _setScopeAlias: spy, + } as any); }); it('should return inline scope', () => { @@ -87,13 +83,15 @@ describe('ScopeResolver', () => { ); }); - it('should not alter the casing of the scope', () => { - resolver = new ScopeResolver( - { - _setScopeAlias: spy, - } as any, - { ignoreScopeCase: true } as TranslocoConfig, - ); + it('should not alter namespace of the scope', () => { + resolver = new ScopeResolver({ + _setScopeAlias: spy, + config: { + scope: { + keepNamespaceCasing: true, + }, + }, + } as any); expect( resolver.resolve({ @@ -102,9 +100,9 @@ describe('ScopeResolver', () => { scope: 'AdMiN-pAgE', }, }), - ).toEqual('AdMiNpAgE'); + ).toEqual('AdMiN-pAgE'); // one from before expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenCalledWith('AdMiN-pAgE', 'AdMiNpAgE'); + expect(spy).toHaveBeenCalledWith('AdMiN-pAgE', 'AdMiN-pAgE'); }); }); diff --git a/libs/transloco/src/lib/tests/service/setTranslation.spec.ts b/libs/transloco/src/lib/tests/service/setTranslation.spec.ts index 478cf605..6d4f79ac 100644 --- a/libs/transloco/src/lib/tests/service/setTranslation.spec.ts +++ b/libs/transloco/src/lib/tests/service/setTranslation.spec.ts @@ -15,14 +15,14 @@ describe('setTranslation', () => { service = createService(); setTranslationsSpy = spyOn( (service as any).translations, - 'set' + 'set', ).and.callThrough(); }); it('should add translation to the map after passing through the interceptor', () => { const interceptorSpy = spyOn( (service as any).interceptor, - 'preSaveTranslation' + 'preSaveTranslation', ).and.callThrough(); const lang = 'en'; const translation = flatten(mockLangs[lang]); @@ -102,5 +102,16 @@ describe('setTranslation', () => { }; expect(setTranslationsSpy).toHaveBeenCalledWith('en', merged); }); + + it("should not change scope's name given scope.keepNamespaceCasing is set to true", () => { + service.config.scope.keepNamespaceCasing = true; + service._setScopeAlias('LAZY-page', 'LAZY-page'); + service.setTranslation(translation, lang); + const merged = { + ...flatten(mockLangs.en), + ...flatten({ myScopeAlias: { ...translation } }), + }; + expect(setTranslationsSpy).toHaveBeenCalledWith('en', merged); + }); }); }); diff --git a/libs/transloco/src/lib/transloco.config.ts b/libs/transloco/src/lib/transloco.config.ts index de134f5c..888afd74 100644 --- a/libs/transloco/src/lib/transloco.config.ts +++ b/libs/transloco/src/lib/transloco.config.ts @@ -18,7 +18,9 @@ export interface TranslocoConfig { allowEmpty: boolean; }; interpolation: [string, string]; - ignoreScopeCase?: boolean; + scope: { + keepNamespaceCasing?: boolean; + }; } export const TRANSLOCO_CONFIG = new InjectionToken( @@ -45,7 +47,9 @@ export const defaultConfig: TranslocoConfig = { aot: false, }, interpolation: ['{{', '}}'], - ignoreScopeCase: false, + scope: { + keepNamespaceCasing: false, + }, }; type DeepPartial = @@ -71,5 +75,9 @@ export function translocoConfig( ...defaultConfig.flatten, ...config.flatten, }, + scope: { + ...defaultConfig.scope, + ...config.scope, + }, }; } diff --git a/libs/transloco/src/lib/transloco.service.ts b/libs/transloco/src/lib/transloco.service.ts index 4c573875..0c2d4029 100644 --- a/libs/transloco/src/lib/transloco.service.ts +++ b/libs/transloco/src/lib/transloco.service.ts @@ -791,7 +791,8 @@ export class TranslocoService implements OnDestroy { private getMappedScope(scope: string): string { const { scopeMapping = {} } = this.config; return ( - scopeMapping[scope] || toCamelCase(scope, this.config.ignoreScopeCase) + scopeMapping[scope] || + (this.config.scope.keepNamespaceCasing ? scope : toCamelCase(scope)) ); }