Skip to content

Support keyPrefix #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 6 additions & 0 deletions src/extractors/getFixedTFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ export default function extractGetFixedTFunction(
const tBinding = id.scope.bindings[id.node.name];
if (!tBinding) return [];

const keyPrefixArgument = path.get('arguments')[2];
const keyPrefix: string | null = getFirstOrNull(
evaluateIfConfident(keyPrefixArgument),
)

let keys = Array<ExtractedKey>();
for (const reference of tBinding.referencePaths) {
if (
Expand Down Expand Up @@ -94,6 +99,7 @@ export default function extractGetFixedTFunction(

return keys.map((k) => ({
...k,
keyPrefix: keyPrefix || undefined,
sourceNodes: [path.node, ...k.sourceNodes],
extractorName: extractGetFixedTFunction.name,
}));
Expand Down
10 changes: 10 additions & 0 deletions src/extractors/useTranslationHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ export default function extractUseTranslationHook(
const tBinding = id.scope.bindings['t'];
if (!tBinding) return [];

let keyPrefix: string | undefined;

const optionsArgument = path.get('arguments')[1];
const options = getFirstOrNull(evaluateIfConfident(optionsArgument))

if (options) {
keyPrefix = options.keyPrefix || keyPrefix
}

let keys = Array<ExtractedKey>();
for (const reference of tBinding.referencePaths) {
if (
Expand Down Expand Up @@ -86,6 +95,7 @@ export default function extractUseTranslationHook(

return keys.map((k) => ({
...k,
keyPrefix: keyPrefix,
sourceNodes: [path.node, ...k.sourceNodes],
extractorName: extractUseTranslationHook.name,
}));
Expand Down
15 changes: 14 additions & 1 deletion src/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface I18NextParsedOptions {
*/
export interface ExtractedKey {
key: string;
keyPrefix?: string;
parsedOptions: I18NextParsedOptions;

// Nodes (not node paths) from which the key was extracted.
Expand Down Expand Up @@ -54,15 +55,27 @@ function parseExtractedKey(key: ExtractedKey, config: Config): TranslationKey {
const nsSeparatorPos = cleanKey.indexOf(config.nsSeparator);

if (nsSeparatorPos !== -1) {
if (key.keyPrefix) {
throw new Error(
`Do not use the keyPrefix option if you want to use keys with prefixed namespace notation.
key: ${cleanKey}
keyPrefix: ${key.keyPrefix}`,
)
}

ns = cleanKey.slice(0, nsSeparatorPos);
cleanKey = cleanKey.slice(nsSeparatorPos + 1);
}
}

let keyPath = Array<string>();
if (config.keySeparator) {
if (key.keyPrefix) {
keyPath = key.keyPrefix.split(config.keySeparator);
}

const fullPath = cleanKey.split(config.keySeparator);
keyPath = fullPath.slice(0, fullPath.length - 1);
keyPath = [...keyPath, ...fullPath.slice(0, fullPath.length - 1)];
cleanKey = fullPath[fullPath.length - 1];
}

Expand Down
18 changes: 18 additions & 0 deletions tests/__fixtures__/testGetFixedTFunction/keyPrefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import i18next from "i18next";

export function anyJSFunction1() {
const t = i18next.getFixedT(null, 'ns0', 'deep0');
t('key0');
}

export function anyJSFunction2() {
const t = i18next.getFixedT(null, 'ns1', 'deep1.deep2');

t('key1');
}

export function anyJSFunction3() {
const t = i18next.getFixedT(null, 'ns2', 'deep3.deep4');

t('key2.key3');
}
9 changes: 9 additions & 0 deletions tests/__fixtures__/testGetFixedTFunction/keyPrefix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"description": "test keyPrefix usage of getFixedT TFunction",
"pluginOptions": {},
"expectValues": [
[{"deep0": { "key0": "" }}, {"ns": "ns0"}],
[{"deep1": { "deep2": { "key1": "" }}}, {"ns": "ns1"}],
[{"deep3": { "deep4": { "key2": { "key3": "" } }}}, {"ns": "ns2"}]
]
}
21 changes: 21 additions & 0 deletions tests/__fixtures__/testUseTranslationHook/keyPrefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useTranslation } from 'react-i18next';

export function MyComponent1() {
const [t] = useTranslation('ns0', { keyPrefix: 'deep0' });
return <p>{t('key0')}{t('key1')}</p>
}

export function MyComponent2() {
const [t] = useTranslation('ns1', { keyPrefix: 'deep1.deep2' });
return <p>{t('key2')}{t('key3')}</p>
}

export function MyComponent3() {
const [t] = useTranslation('ns2', { keyPrefix: 'deep3.deep4' });
return <p>{t('key4.key5')}{t('key4.key6')}</p>
}

export function MyComponent4() {
const [t] = useTranslation('ns3', { keyPrefix: 'deep5.deep6' });
return <p>{t('key7.key8')}{t('key9.key10')}</p>
}
10 changes: 10 additions & 0 deletions tests/__fixtures__/testUseTranslationHook/keyPrefix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"description": "test keyPrefix extraction of useTranslation hook",
"pluginOptions": {},
"expectValues": [
[{ "deep0": {"key0": "", "key1": ""}}, {"ns": "ns0"}],
[{ "deep1": {"deep2": {"key2": "", "key3": ""}}}, {"ns": "ns1"}],
[{ "deep3": {"deep4": {"key4": { "key5": "", "key6": "" }}}}, {"ns": "ns2"}],
[{ "deep5": {"deep6": {"key7": { "key8": "" }, "key9": {"key10": ""}}}}, {"ns": "ns3"}]
]
}
9 changes: 7 additions & 2 deletions tests/__fixtures__/testUseTranslationHook/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ const MyComponent2 = () => {
return <p>{t('key2')}</p>
}

export function MyComponent3() {
const MyComponent3 = () => {
const { t, i18n } = useTranslation();
return <p>{t('key3.key4')}</p>
}

export function MyComponent4() {
const {i18n} = useTranslation();
return <p>Shouldn't crash</p>
}

export function MyComponent4() {
export function MyComponent5() {
const { t } = ReactI18Next.useTranslation();
t('from wildcard import');
}
1 change: 1 addition & 0 deletions tests/__fixtures__/testUseTranslationHook/simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"key0": "",
"key1": "",
"key2": "",
"key3": { "key4": "" },
"from wildcard import": ""
}
}