From 557f4ae15ad7544bc3eae6d191816ee868cfaf92 Mon Sep 17 00:00:00 2001 From: Tzvi Melamed Date: Fri, 1 Nov 2024 14:38:25 -0400 Subject: [PATCH] feat(react-i18n): add support for custom useTranslation function aliases --- locales/en.json | 1 + package.json | 7 +++++++ src/core/Config.ts | 10 ++++++++++ src/frameworks/react-i18next.ts | 8 +++++--- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/locales/en.json b/locales/en.json index 6f9c8b38..4f3e66dd 100644 --- a/locales/en.json +++ b/locales/en.json @@ -52,6 +52,7 @@ "config.editor_prefer_editor": "Prefer to use webview editor for locale editing.", "config.enabled_frameworks": "Specify the supported framework(s) to enable. If no value is set, the extension will detect frameworks automatically.", "config.enabled_parsers": "Locale file format parsers. By default, It will be handled by activated frameworks", + "config.use_translation_functions": "Aliases for a useTranslation function that can set a scoped namespace. By default, It will use \"useTranslation\".", "config.encoding": "File encoding for reading and writing locale files", "config.full_reload_on_changed": "Perform a full reload on locale file changes. (for .js/.ts dynamic import)", "config.google_api_key": "API key for Google Translate (Optional)", diff --git a/package.json b/package.json index 154b2439..aa86a790 100644 --- a/package.json +++ b/package.json @@ -859,6 +859,13 @@ }, "description": "%config.enabled_parsers%" }, + "i18n-ally.useTranslationFunctions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "%config.use_translation_functions%" + }, "i18n-ally.keysInUse": { "type": "array", "items": { diff --git a/src/core/Config.ts b/src/core/Config.ts index 3eedd1c5..a94f2cea 100644 --- a/src/core/Config.ts +++ b/src/core/Config.ts @@ -18,6 +18,7 @@ export class Config { 'includeSubfolders', 'enabledFrameworks', 'enabledParsers', + 'useTranslationFunctions', 'dirStructure', 'encoding', 'namespace', @@ -155,6 +156,15 @@ export class Config { return ids } + static get useTranslationFunctions(): string[] | undefined { + let ids = this.getConfig('useTranslationFunctions') + if (!ids || !ids.length) + return undefined + if (typeof ids === 'string') + ids = [ids] + return ids + } + static get enabledParsers(): string[] | undefined { let ids = this.getConfig('enabledParsers') if (!ids || !ids.length) diff --git a/src/frameworks/react-i18next.ts b/src/frameworks/react-i18next.ts index 12ccc293..499f575e 100644 --- a/src/frameworks/react-i18next.ts +++ b/src/frameworks/react-i18next.ts @@ -162,7 +162,9 @@ class ReactI18nextFramework extends Framework { // Add first namespace as a global scope resetting on each occurrence // useTranslation(ns1) and useTranslation(['ns1', ...]) - const regUse = /useTranslation\(\s*\[?\s*['"`](.*?)['"`]/g + // we support alternate naming of useTranslation via config + const useTranslationFunctions = Config.useTranslationFunctions ?? ['useTranslation']; + const regUse = new RegExp(`(${useTranslationFunctions.join('|')})\\(\\s*\\[?\\s*['"\`](?.*?)['"\`]`, 'g'); let prevGlobalScope = false for (const match of text.matchAll(regUse)) { if (typeof match.index !== 'number') @@ -173,12 +175,12 @@ class ReactI18nextFramework extends Framework { ranges[ranges.length - 1].end = match.index // start a new scope if namespace is provided - if (match[1]) { + if (match.groups?.namespace) { prevGlobalScope = true ranges.push({ start: match.index, end: text.length, - namespace: match[1], + namespace: match.groups.namespace, }) } }