Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/extractor/parser/generalMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,6 @@ export type GeneralTokenType =
| 'tag.closing'
| 'tag.attribute.name'
| 'expression.template.begin'
| 'expression.template.end';
| 'expression.template.end'
| 'trigger.global.t.function';
export type GeneralToken = Token<GeneralTokenType>;
12 changes: 7 additions & 5 deletions src/extractor/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import { ExtractOptions, ExtractedKey, Warning } from '../index.js';
import { stringMerger } from './tokenMergers/stringMerger.js';
import { templateStringMerger } from './tokenMergers/templateStringMerger.js';
import { closingTagMerger } from './tokenMergers/closingTagMerger.js';
import { typesAsMergerer } from './tokenMergers/typesAsMergerer.js';
import { typesCastMergerer } from './tokenMergers/typesCastMerger.js';
import { typesAsMerger } from './tokenMergers/typesAsMerger.js';
import { typesCastMerger } from './tokenMergers/typesCastMerger.js';
import { customTCallMerger } from './tokenMergers/customTCallMerger.js';

export const DEFAULT_BLOCKS = {
'block.begin': ['block.end'],
Expand All @@ -35,12 +36,13 @@ export const DEFAULT_BLOCKS = {
],
} satisfies BlocksType<GeneralTokenType>;

export const DEFAULT_MERGERERS = [
export const DEFAULT_MERGERS = [
stringMerger,
templateStringMerger,
closingTagMerger,
typesAsMergerer,
typesCastMergerer,
typesAsMerger,
typesCastMerger,
customTCallMerger(['tolgee.t']),
] as const;

type ParserOptions<T extends string = GeneralTokenType> = {
Expand Down
10 changes: 10 additions & 0 deletions src/extractor/parser/rules/globalTFunction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { tFunctionGeneral } from './tFunctionGeneral.js';
import { RuleType } from '../types.js';
import { GeneralTokenType } from '../generalMapper.js';

export const globalTFunction = {
trigger: 'trigger.global.t.function',
call(context) {
return tFunctionGeneral(context, false);
},
} satisfies RuleType<GeneralTokenType> as any;
25 changes: 25 additions & 0 deletions src/extractor/parser/tokenMergers/customTCallMerger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ReactMappedTokenType } from '../../parserReact/ParserReact.js';
import { MachineType } from '../mergerMachine.js';

export const customTCallMerger = (customExpressions: string[]) => {
return {
initial: '',
step: (state, t, end) => {
const type = t.customType;
const token = t.token;

if (type === 'variable' || type === 'function.call') {
if (customExpressions.find((e) => e.startsWith(state + token))) {
return state + token;
}
} else if (type === 'acessor.dot') {
return state + '.';
} else if (state !== '' && type === 'expression.begin') {
if (customExpressions.includes(state)) {
return end.MERGE_ALL;
}
}
},
customType: 'trigger.global.t.function',
} as const satisfies MachineType<ReactMappedTokenType, string>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ReactMappedTokenType } from '../../parserReact/ParserReact.js';
const INITIAL_DEPTH = -1;

// in ts files we want to ignore stuff after 'as' `[count as number]`
export const typesAsMergerer = {
export const typesAsMerger = {
initial: INITIAL_DEPTH,
step: (depth, token, end) => {
const type = token.customType;
Expand Down
2 changes: 1 addition & 1 deletion src/extractor/parser/tokenMergers/typesCastMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ReactMappedTokenType } from '../../parserReact/ParserReact.js';
const INITIAL_DEPTH = 0;

// in ts files we want to ignore type casting (<number> count)
export const typesCastMergerer = {
export const typesCastMerger = {
initial: INITIAL_DEPTH,
step: (depth, token, end) => {
const type = token.customType;
Expand Down
7 changes: 4 additions & 3 deletions src/extractor/parserNgx/ParserNgx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pipeMachines } from '../parser/mergerMachine.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERERS, Parser } from '../parser/parser.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERS, Parser } from '../parser/parser.js';
import { IterableItem, Token } from '../parser/types.js';

import { GeneralTokenType, generalMapper } from '../parser/generalMapper.js';
Expand All @@ -13,6 +13,7 @@ import { pipeMerger } from './tokenMergers/pipeMerger.js';
import { componentWithT } from './rules/componentWithT.js';
import { translatePipe } from './rules/translatePipe.js';
import { translateFunction } from './rules/translateFunction.js';
import { globalTFunction } from '../parser/rules/globalTFunction.js';

const ngxMappers = [ngxMapper, generalMapper];

Expand All @@ -21,7 +22,7 @@ export type NgxMappedTokenType = NonNullable<
>;

export const ngxMergers = pipeMachines([
...DEFAULT_MERGERERS,
...DEFAULT_MERGERS,
componentWithTMerger,
pipeMerger,
translateMerger,
Expand All @@ -39,7 +40,7 @@ export const ParserNgx = () => {
blocks: {
...DEFAULT_BLOCKS,
},
rules: [componentWithT, translatePipe, translateFunction],
rules: [globalTFunction, componentWithT, translatePipe, translateFunction],
merger: ngxMergers,
treeTransform: ngxTreeTransform,
});
Expand Down
13 changes: 10 additions & 3 deletions src/extractor/parserReact/ParserReact.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pipeMachines } from '../parser/mergerMachine.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERERS, Parser } from '../parser/parser.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERS, Parser } from '../parser/parser.js';
import { IterableItem, Token } from '../parser/types.js';

import { GeneralTokenType, generalMapper } from '../parser/generalMapper.js';
Expand All @@ -14,6 +14,7 @@ import { reactCreateElement } from './rules/createElement.js';
import { tComponent } from './rules/tComponent.js';
import { tFunction } from './rules/tFunction.js';
import { useTranslate } from './rules/useTranslate.js';
import { globalTFunction } from '../parser/rules/globalTFunction.js';

const reactMappers = [generalMapper, reactMapper];

Expand All @@ -22,7 +23,7 @@ export type ReactMappedTokenType = NonNullable<
>;

export const reactMergers = pipeMachines([
...DEFAULT_MERGERERS,
...DEFAULT_MERGERS,
createElementMerger,
useTranslateMerger,
tFunctionMerger,
Expand All @@ -41,7 +42,13 @@ export const ParserReact = () => {
blocks: {
...DEFAULT_BLOCKS,
},
rules: [reactCreateElement, tComponent, tFunction, useTranslate],
rules: [
globalTFunction,
reactCreateElement,
tComponent,
tFunction,
useTranslate,
],
merger: reactMergers,
});
};
7 changes: 4 additions & 3 deletions src/extractor/parserSvelte/ParserSvelte.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pipeMachines } from '../parser/mergerMachine.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERERS, Parser } from '../parser/parser.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERS, Parser } from '../parser/parser.js';
import { IterableItem, Token } from '../parser/types.js';
import { svelteMapper } from './svelteMapper.js';
import { GeneralTokenType, generalMapper } from '../parser/generalMapper.js';
Expand All @@ -15,6 +15,7 @@ import { tComponent } from './rules/tComponent.js';
import { scriptTag } from './rules/scriptTag.js';

import { svelteTreeTransform } from './svelteTreeTransform.js';
import { globalTFunction } from '../parser/rules/globalTFunction.js';

const svelteMappers = [generalMapper, svelteMapper];

Expand All @@ -23,7 +24,7 @@ export type SvelteMappedTokenType = NonNullable<
>;

export const svelteMergers = pipeMachines([
...DEFAULT_MERGERERS,
...DEFAULT_MERGERS,
tFunctionMerger,
getTranslateMerger,
tComponentMerger,
Expand All @@ -42,7 +43,7 @@ export const ParserSvelte = () => {
blocks: {
...DEFAULT_BLOCKS,
},
rules: [tFunction, getTranslate, tComponent, scriptTag],
rules: [globalTFunction, tFunction, getTranslate, tComponent, scriptTag],
treeTransform: svelteTreeTransform,
merger: svelteMergers,
});
Expand Down
10 changes: 5 additions & 5 deletions src/extractor/parserVue/ParserVue.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { pipeMachines } from '../parser/mergerMachine.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERERS, Parser } from '../parser/parser.js';
import { DEFAULT_BLOCKS, DEFAULT_MERGERS, Parser } from '../parser/parser.js';
import { IterableItem, Token } from '../parser/types.js';
import { GeneralTokenType, generalMapper } from '../parser/generalMapper.js';
import { vueMapper } from './vueMapper.js';
import { vueTreeTransform } from './vueTreeTransform.js';

import { globalTFunctionMerger } from './tokenMergers/globalTFunctionMerger.js';
import { tFunctionMerger } from './tokenMergers/tFunctionMerger.js';
import { useTranslateMerger } from './tokenMergers/useTranslateMerger.js';
import { exportDefaultObjectMerger } from './tokenMergers/exportDefaultObjectMerger.js';
import { scriptTagMerger } from './tokenMergers/scriptTagMerger.js';
import { tComponentMerger } from './tokenMergers/tComponentMerger.js';

import { globalTFunction } from './rules/globalTFunction.js';
import { globalTFunction } from '../parser/rules/globalTFunction.js';
import { tFunction } from './rules/tFunction.js';
import { useTranslate } from './rules/useTranslate.js';
import { tComponent } from './rules/tComponent.js';
import { scriptTag } from './rules/scriptTag.js';
import { exportDefaultObject } from './rules/exportDefaultObject.js';
import { hyphenPropsMerger } from './tokenMergers/hyphenPropsMerger.js';
import { customTCallMerger } from '../parser/tokenMergers/customTCallMerger.js';

const vueMappers = [generalMapper, vueMapper];

Expand All @@ -27,9 +27,9 @@ export type VueMappedTokenType = NonNullable<
>;

export const vueMergers = pipeMachines([
...DEFAULT_MERGERERS,
...DEFAULT_MERGERS,
hyphenPropsMerger,
globalTFunctionMerger,
customTCallMerger(['$t', 'this.$t']),
tFunctionMerger,
useTranslateMerger,
tComponentMerger,
Expand Down
10 changes: 0 additions & 10 deletions src/extractor/parserVue/rules/globalTFunction.ts

This file was deleted.

46 changes: 0 additions & 46 deletions src/extractor/parserVue/tokenMergers/globalTFunctionMerger.ts

This file was deleted.

13 changes: 13 additions & 0 deletions test/unit/extractor/ngx/translateService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,17 @@ describe('translate service', () => {
expect(extracted.warnings).toEqual(expectedWarnings);
});
});

describe('global tolgee.t function', () => {
it('detects global tolgee.t function', async () => {
const code = `
const tolgee = Tolgee()
tolgee.t('key_name')
`;

const extracted = await extractNgxKeys(code, 'test.ts');
expect(extracted.keys).toEqual([{ keyName: 'key_name', line: 3 }]);
expect(extracted.warnings).toEqual([]);
});
});
});
13 changes: 13 additions & 0 deletions test/unit/extractor/react/useTranslate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,4 +536,17 @@ describe.each(['js', 'ts', 'jsx', 'tsx'])('useTranslate (.%s)', (ext) => {
expect(extracted.keys).toEqual(expectedKeys);
});
});

describe('global tolgee.t function', () => {
it('detects global tolgee.t function', async () => {
const code = `
const tolgee = Tolgee()
tolgee.t('key_name')
`;

const extracted = await extractReactKeys(code, FILE_NAME);
expect(extracted.keys).toEqual([{ keyName: 'key_name', line: 3 }]);
expect(extracted.warnings).toEqual([]);
});
});
});
15 changes: 15 additions & 0 deletions test/unit/extractor/svelte/getTranslate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,19 @@ describe('getTranslate', () => {
expect(extracted.keys).toEqual(expectedKeys);
});
});

describe('global tolgee.t function', () => {
it('detects global tolgee.t function', async () => {
const code = `
<script>
const tolgee = Tolgee()
tolgee.t('key_name')
</script>
`;

const extracted = await extractSvelteKeys(code, 'App.svelte');
expect(extracted.keys).toEqual([{ keyName: 'key_name', line: 4 }]);
expect(extracted.warnings).toEqual([]);
});
});
});
18 changes: 17 additions & 1 deletion test/unit/extractor/vue/globalT.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ describe('$t', () => {
expect(extracted.keys).toEqual([{ keyName: 'key1', line: 3 }]);
});

it('extracts both this.$t and $t', async () => {
it('extracts both this.$t and $t but nothing else', async () => {
const code = `
<script>
export default {
methods: {
onClick () {
alert(this.$t('key1'))
alert($t('key2'))
alert(foo.$t('key3'))
}
}
}
Expand Down Expand Up @@ -273,4 +274,19 @@ describe('$t', () => {
expect(extracted.keys).toEqual([]);
});
});

describe('global tolgee.t function', () => {
it('detects global tolgee.t function', async () => {
const code = `
<script>
const tolgee = Tolgee()
tolgee.t('key_name')
</script>
`;

const extracted = await extractVueKeys(code, 'App.vue');
expect(extracted.keys).toEqual([{ keyName: 'key_name', line: 4 }]);
expect(extracted.warnings).toEqual([]);
});
});
});
Loading