i18next-cli 1.11.7 → 1.11.9
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.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/extractor/core/translation-manager.js +1 -1
- package/dist/cjs/extractor/parsers/call-expression-handler.js +1 -1
- package/dist/cjs/extractor/parsers/jsx-handler.js +1 -1
- package/dist/cjs/extractor/parsers/jsx-parser.js +1 -1
- package/dist/esm/cli.js +1 -1
- package/dist/esm/extractor/core/translation-manager.js +1 -1
- package/dist/esm/extractor/parsers/call-expression-handler.js +1 -1
- package/dist/esm/extractor/parsers/jsx-handler.js +1 -1
- package/dist/esm/extractor/parsers/jsx-parser.js +1 -1
- package/package.json +1 -1
- package/src/cli.ts +1 -1
- package/src/extractor/core/translation-manager.ts +10 -15
- package/src/extractor/parsers/call-expression-handler.ts +87 -11
- package/src/extractor/parsers/jsx-handler.ts +10 -5
- package/src/extractor/parsers/jsx-parser.ts +61 -4
- package/src/types.ts +3 -0
- package/types/extractor/core/translation-manager.d.ts.map +1 -1
- package/types/extractor/parsers/call-expression-handler.d.ts.map +1 -1
- package/types/extractor/parsers/jsx-handler.d.ts.map +1 -1
- package/types/extractor/parsers/jsx-parser.d.ts +2 -0
- package/types/extractor/parsers/jsx-parser.d.ts.map +1 -1
- package/types/types.d.ts +2 -0
- package/types/types.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.11.9](https://github.com/i18next/i18next-cli/compare/v1.11.8...v1.11.9) - 2025-10-20
|
|
9
|
+
|
|
10
|
+
- Fix: Make --sync-primary (syncPrimaryWithDefaults) smarter — only overwrite primary-language plural/context variants when the source actually provides an explicit default [#67](https://github.com/i18next/i18next-cli/issues/67)
|
|
11
|
+
- Fix: Detect shorthand object property "count" in t(...) calls (e.g. t('key', { count })) so plural keys are generated correctly. Adds handling for shorthand AST shapes and tests to cover the case. [#68](https://github.com/i18next/i18next-cli/issues/68)
|
|
12
|
+
|
|
13
|
+
## [1.11.8](https://github.com/i18next/i18next-cli/compare/v1.11.7...v1.11.8) - 2025-10-20
|
|
14
|
+
|
|
15
|
+
- Fix: Make `<Trans>` child indexing more robust by recognizing self-closing HTML tags (e.g. `<br/>`) and treating them as layout-only when appropriate. This prevents preserved HTML and surrounding formatting whitespace from shifting component placeholder indexes, so extracted default values now match react‑i18next runtime normalization. [#63](https://github.com/i18next/i18next-cli/issues/63)
|
|
16
|
+
|
|
8
17
|
## [1.11.7](https://github.com/i18next/i18next-cli/compare/v1.11.6...v1.11.7) - 2025-10-20
|
|
9
18
|
|
|
10
19
|
- improve: extractor --sync-primary (--syncPrimaryWithDefaults) incorrectly reset plural variants to empty strings, effectively removing existing plural translations [#67](https://github.com/i18next/i18next-cli/issues/67)
|
package/dist/cjs/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var e=require("commander"),t=require("chokidar"),n=require("glob"),o=require("chalk"),i=require("./config.js"),a=require("./heuristic-config.js"),r=require("./extractor/core/extractor.js");require("node:path"),require("node:fs/promises"),require("jiti");var c=require("./types-generator.js"),s=require("./syncer.js"),l=require("./migrator.js"),u=require("./init.js"),d=require("./linter.js"),g=require("./status.js"),p=require("./locize.js");const f=new e.Command;f.name("i18next-cli").description("A unified, high-performance i18next CLI.").version("1.11.
|
|
2
|
+
"use strict";var e=require("commander"),t=require("chokidar"),n=require("glob"),o=require("chalk"),i=require("./config.js"),a=require("./heuristic-config.js"),r=require("./extractor/core/extractor.js");require("node:path"),require("node:fs/promises"),require("jiti");var c=require("./types-generator.js"),s=require("./syncer.js"),l=require("./migrator.js"),u=require("./init.js"),d=require("./linter.js"),g=require("./status.js"),p=require("./locize.js");const f=new e.Command;f.name("i18next-cli").description("A unified, high-performance i18next CLI.").version("1.11.9"),f.command("extract").description("Extract translation keys from source files and update resource files.").option("-w, --watch","Watch for file changes and re-run the extractor.").option("--ci","Exit with a non-zero status code if any files are updated.").option("--dry-run","Run the extractor without writing any files to disk.").option("--sync-primary","Sync primary language values with default values from code.").action(async e=>{try{const o=await i.ensureConfig(),a=async()=>{const t=await r.runExtractor(o,{isWatchMode:!!e.watch,isDryRun:!!e.dryRun,syncPrimaryWithDefaults:!!e.syncPrimary});return e.ci&&!t?(console.log("✅ No files were updated."),process.exit(0)):e.ci&&t&&(console.error("❌ Some files were updated. This should not happen in CI mode."),process.exit(1)),t};if(await a(),e.watch){console.log("\nWatching for changes...");t.watch(await n.glob(o.extract.input),{ignored:/node_modules/,persistent:!0}).on("change",e=>{console.log(`\nFile changed: ${e}`),a()})}}catch(e){console.error("Error running extractor:",e),process.exit(1)}}),f.command("status [locale]").description("Display translation status. Provide a locale for a detailed key-by-key view.").option("-n, --namespace <ns>","Filter the status report by a specific namespace").action(async(e,t)=>{let n=await i.loadConfig();if(!n){console.log(o.blue("No config file found. Attempting to detect project structure..."));const e=await a.detectConfig();e||(console.error(o.red("Could not automatically detect your project structure.")),console.log(`Please create a config file first by running: ${o.cyan("npx i18next-cli init")}`),process.exit(1)),console.log(o.green("Project structure detected successfully!")),n=e}await g.runStatus(n,{detail:e,namespace:t.namespace})}),f.command("types").description("Generate TypeScript definitions from translation resource files.").option("-w, --watch","Watch for file changes and re-run the type generator.").action(async e=>{const o=await i.ensureConfig(),a=()=>c.runTypesGenerator(o);if(await a(),e.watch){console.log("\nWatching for changes...");t.watch(await n.glob(o.types?.input||[]),{persistent:!0}).on("change",e=>{console.log(`\nFile changed: ${e}`),a()})}}),f.command("sync").description("Synchronize secondary language files with the primary language file.").action(async()=>{const e=await i.ensureConfig();await s.runSyncer(e)}),f.command("migrate-config [configPath]").description("Migrate a legacy i18next-parser.config.js to the new format.").action(async e=>{await l.runMigrator(e)}),f.command("init").description("Create a new i18next.config.ts/js file with an interactive setup wizard.").action(u.runInit),f.command("lint").description("Find potential issues like hardcoded strings in your codebase.").option("-w, --watch","Watch for file changes and re-run the linter.").action(async e=>{const r=async()=>{let e=await i.loadConfig();if(!e){console.log(o.blue("No config file found. Attempting to detect project structure..."));const t=await a.detectConfig();t||(console.error(o.red("Could not automatically detect your project structure.")),console.log(`Please create a config file first by running: ${o.cyan("npx i18next-cli init")}`),process.exit(1)),console.log(o.green("Project structure detected successfully!")),e=t}await d.runLinter(e)};if(await r(),e.watch){console.log("\nWatching for changes...");const e=await i.loadConfig();if(e?.extract?.input){t.watch(await n.glob(e.extract.input),{ignored:/node_modules/,persistent:!0}).on("change",e=>{console.log(`\nFile changed: ${e}`),r()})}}}),f.command("locize-sync").description("Synchronize local translations with your locize project.").option("--update-values","Update values of existing translations on locize.").option("--src-lng-only","Check for changes in source language only.").option("--compare-mtime","Compare modification times when syncing.").option("--dry-run","Run the command without making any changes.").action(async e=>{const t=await i.ensureConfig();await p.runLocizeSync(t,e)}),f.command("locize-download").description("Download all translations from your locize project.").action(async e=>{const t=await i.ensureConfig();await p.runLocizeDownload(t,e)}),f.command("locize-migrate").description("Migrate local translation files to a new locize project.").action(async e=>{const t=await i.ensureConfig();await p.runLocizeMigrate(t,e)}),f.parse(process.argv);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("node:path"),t=require("glob"),s=require("../../utils/nested-object.js"),r=require("../../utils/file-utils.js"),n=require("../../utils/default-value.js");function a(e){const t=`^${e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")}$`;return new RegExp(t)}function o(e,t){if("object"!=typeof e||null===e||Array.isArray(e))return e;const s={},r=t?.extract?.pluralSeparator??"_",n=["zero","one","two","few","many","other"],a=n.map(e=>`ordinal${r}${e}`),l=Object.keys(e).sort((e,t)=>{const s=e=>{for(const t of a)if(e.endsWith(`${r}${t}`)){return{base:e.slice(0,-(r.length+t.length)),form:t,isOrdinal:!0,isPlural:!0,fullKey:e}}for(const t of n)if(e.endsWith(`${r}${t}`)){return{base:e.slice(0,-(r.length+t.length)),form:t,isOrdinal:!1,isPlural:!0,fullKey:e}}return{base:e,form:"",isOrdinal:!1,isPlural:!1,fullKey:e}},o=s(e),l=s(t);if(o.isPlural&&l.isPlural){const e=o.base.localeCompare(l.base,void 0,{sensitivity:"base"});if(0!==e)return e;if(o.isOrdinal!==l.isOrdinal)return o.isOrdinal?1:-1;const t=o.isOrdinal?a:n,s=t.indexOf(o.form),r=t.indexOf(l.form);return-1!==s&&-1!==r?s-r:o.form.localeCompare(l.form)}const i=e.localeCompare(t,void 0,{sensitivity:"base"});return 0===i?e.localeCompare(t,void 0,{sensitivity:"case"}):i});for(const r of l)s[r]=o(e[r],t);return s}function l(e,t,r,a,l,i,c,u=!1){const{keySeparator:f=".",sort:d=!0,removeUnusedKeys:p=!0,primaryLanguage:g,defaultValue:y="",pluralSeparator:h="_",contextSeparator:m="_"}=r.extract,
|
|
1
|
+
"use strict";var e=require("node:path"),t=require("glob"),s=require("../../utils/nested-object.js"),r=require("../../utils/file-utils.js"),n=require("../../utils/default-value.js");function a(e){const t=`^${e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")}$`;return new RegExp(t)}function o(e,t){if("object"!=typeof e||null===e||Array.isArray(e))return e;const s={},r=t?.extract?.pluralSeparator??"_",n=["zero","one","two","few","many","other"],a=n.map(e=>`ordinal${r}${e}`),l=Object.keys(e).sort((e,t)=>{const s=e=>{for(const t of a)if(e.endsWith(`${r}${t}`)){return{base:e.slice(0,-(r.length+t.length)),form:t,isOrdinal:!0,isPlural:!0,fullKey:e}}for(const t of n)if(e.endsWith(`${r}${t}`)){return{base:e.slice(0,-(r.length+t.length)),form:t,isOrdinal:!1,isPlural:!0,fullKey:e}}return{base:e,form:"",isOrdinal:!1,isPlural:!1,fullKey:e}},o=s(e),l=s(t);if(o.isPlural&&l.isPlural){const e=o.base.localeCompare(l.base,void 0,{sensitivity:"base"});if(0!==e)return e;if(o.isOrdinal!==l.isOrdinal)return o.isOrdinal?1:-1;const t=o.isOrdinal?a:n,s=t.indexOf(o.form),r=t.indexOf(l.form);return-1!==s&&-1!==r?s-r:o.form.localeCompare(l.form)}const i=e.localeCompare(t,void 0,{sensitivity:"base"});return 0===i?e.localeCompare(t,void 0,{sensitivity:"case"}):i});for(const r of l)s[r]=o(e[r],t);return s}function l(e,t,r,a,l,i,c,u=!1){const{keySeparator:f=".",sort:d=!0,removeUnusedKeys:p=!0,primaryLanguage:g,defaultValue:y="",pluralSeparator:h="_",contextSeparator:m="_"}=r.extract,x=new Set;try{const e=new Intl.PluralRules(a,{type:"cardinal"}),t=new Intl.PluralRules(a,{type:"ordinal"});e.resolvedOptions().pluralCategories.forEach(e=>x.add(e)),t.resolvedOptions().pluralCategories.forEach(e=>x.add(`ordinal_${e}`))}catch(e){const t=new Intl.PluralRules(g||"en",{type:"cardinal"}),s=new Intl.PluralRules(g||"en",{type:"ordinal"});t.resolvedOptions().pluralCategories.forEach(e=>x.add(e)),s.resolvedOptions().pluralCategories.forEach(e=>x.add(`ordinal_${e}`))}const O=e.filter(({key:e,hasCount:t,isOrdinal:s})=>{if(i.some(t=>t.test(e)))return!1;if(!t)return!0;const r=e.split(h);if(s&&r.includes("ordinal")){const e=r[r.length-1];return x.has(`ordinal_${e}`)}if(t){const e=r[r.length-1];return x.has(e)}return!0});let v=p?{}:JSON.parse(JSON.stringify(t));const w=s.getNestedKeys(t,f??".");for(const e of w)if(i.some(t=>t.test(e))){const r=s.getNestedValue(t,e,f??".");s.setNestedValue(v,e,r,f??".")}if(p){const e=s.getNestedKeys(t,f??".");for(const r of e){const e=r.split(h);if("zero"===e[e.length-1]){const n=e.slice(0,-1).join(h);if(O.some(({key:e})=>e.split(h).slice(0,-1).join(h)===n)){const e=s.getNestedValue(t,r,f??".");s.setNestedValue(v,r,e,f??".")}}}}for(const{key:e,defaultValue:r,explicitDefault:o}of O){const i=s.getNestedValue(t,e,f??"."),d=!O.some(t=>t.key.startsWith(`${e}${f}`)&&t.key!==e),p="object"==typeof i&&null!==i&&(c.has(e)||!r||r===e),x="object"==typeof i&&null!==i&&d&&!c.has(e)&&!p;if(p){s.setNestedValue(v,e,i,f??".");continue}let w;if(void 0===i||x)if(a===g)if(u){const t=r&&(r===e||e!==r&&(e.startsWith(r+h)||e.startsWith(r+m)));w=r&&!t?r:n.resolveDefaultValue(y,e,l,a)}else w=r||e;else w=n.resolveDefaultValue(y,e,l,a);else if(a===g&&u){const t=r&&(r===e||e!==r&&(e.startsWith(r+h)||e.startsWith(r+m)));w=(e.includes(h)||e.includes(m))&&!o?i:r&&!t?r:i}else w=i;s.setNestedValue(v,e,w,f??".")}if(!0===d)return o(v,r);if("function"==typeof d){const e={},t=Object.keys(v),s=new Map;for(const e of O){const t=!1===f?e.key:e.key.split(f)[0];s.has(t)||s.set(t,e)}t.sort((e,t)=>{if("function"==typeof d){const r=s.get(e),n=s.get(t);if(r&&n)return d(r,n)}return e.localeCompare(t,void 0,{sensitivity:"base"})});for(const s of t)e[s]=o(v[s],r);v=e}return v}exports.getTranslations=async function(s,n,o,{syncPrimaryWithDefaults:i=!1}={}){o.extract.primaryLanguage||=o.locales[0]||"en",o.extract.secondaryLanguages||=o.locales.filter(e=>e!==o?.extract?.primaryLanguage);const c=o.extract.defaultNS??"translation",u=[...o.extract.preservePatterns||[]],f=o.extract.indentation??2;for(const e of n)u.push(`${e}.*`);const d=u.map(a),p=new Map;for(const e of s.values()){const t=e.ns||c;p.has(t)||p.set(t,[]),p.get(t).push(e)}const g=[],y=Array.isArray(o.extract.ignore)?o.extract.ignore:o.extract.ignore?[o.extract.ignore]:[];for(const s of o.locales){if(o.extract.mergeNamespaces||!o.extract.output.includes("{{namespace}}")){const t={},a=r.getOutputPath(o.extract.output,s),c=e.resolve(process.cwd(),a),u=await r.loadTranslationFile(c)||{},y=new Set([...p.keys(),...Object.keys(u)]);for(const e of y){const r=p.get(e)||[],a=u[e]||{};t[e]=l(r,a,o,s,e,d,n,i)}const h=JSON.stringify(u,null,f),m=JSON.stringify(t,null,f);g.push({path:c,updated:m!==h,newTranslations:t,existingTranslations:u})}else{const a=new Set(p.keys()),c=r.getOutputPath(o.extract.output,s,"*"),u=await t.glob(c,{ignore:y});for(const t of u)a.add(e.basename(t,e.extname(t)));for(const t of a){const a=p.get(t)||[],c=r.getOutputPath(o.extract.output,s,t),u=e.resolve(process.cwd(),c),y=await r.loadTranslationFile(u)||{},h=l(a,y,o,s,t,d,n,i),m=JSON.stringify(y,null,f),x=JSON.stringify(h,null,f);g.push({path:u,updated:x!==m,newTranslations:h,existingTranslations:y})}}}return g};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("./ast-utils.js");exports.CallExpressionHandler=class{pluginContext;config;logger;expressionResolver;objectKeys=new Set;constructor(e,t,
|
|
1
|
+
"use strict";var e=require("./ast-utils.js");exports.CallExpressionHandler=class{pluginContext;config;logger;expressionResolver;objectKeys=new Set;constructor(e,t,r,n){this.config=e,this.pluginContext=t,this.logger=r,this.expressionResolver=n}handleCallExpression(t,r){const n=this.getFunctionName(t.callee);if(!n)return;const s=r(n),i=this.config.extract.functions||["t","*.t"];let o=void 0!==s;if(!o)for(const e of i)if(e.startsWith("*.")){if(n.endsWith(e.substring(1))){o=!0;break}}else if(e===n){o=!0;break}if(!o||0===t.arguments.length)return;const{keysToProcess:l,isSelectorAPI:a}=this.handleCallExpressionArgument(t,0);if(0===l.length)return;let u=!1;const p=this.config.extract.pluralSeparator??"_";for(let e=0;e<l.length;e++)l[e].endsWith(`${p}ordinal`)&&(u=!0,l[e]=l[e].slice(0,-8));let f,c;if(t.arguments.length>1){const e=t.arguments[1].expression;"ObjectExpression"===e.type?c=e:"StringLiteral"===e.type&&(f=e.value)}if(t.arguments.length>2){const e=t.arguments[2].expression;"ObjectExpression"===e.type&&(c=e)}const y=c?e.getObjectPropValue(c,"defaultValue"):void 0,g="string"==typeof y?y:f,h=e=>{if(!e||!Array.isArray(e.properties))return!1;for(const t of e.properties)if(t&&"KeyValueProperty"===t.type&&t.key){const e="Identifier"===t.key.type&&t.key.value||"StringLiteral"===t.key.type&&t.key.value;if("string"==typeof e&&e.startsWith("defaultValue"))return!0}return!1},d="string"==typeof g||h(c),x=h(c),k=Boolean(x||"string"==typeof g&&!("string"==typeof(v=g)&&/{{\s*count\s*}}/.test(v)));var v;for(let t=0;t<l.length;t++){let r,n=l[t];if(c){const t=e.getObjectPropValue(c,"ns");"string"==typeof t&&(r=t)}const i=this.config.extract.nsSeparator??":";if(!r&&i&&n.includes(i)){const e=n.split(i);if(r=e.shift(),n=e.join(i),!n||""===n.trim()){this.logger.warn(`Skipping key that became empty after namespace removal: '${r}${i}'`);continue}}!r&&s?.defaultNs&&(r=s.defaultNs),r||(r=this.config.extract.defaultNS);let o=n;if(s?.keyPrefix){const e=this.config.extract.keySeparator??".";if(o=!1!==e?s.keyPrefix.endsWith(e)?`${s.keyPrefix}${n}`:`${s.keyPrefix}${e}${n}`:`${s.keyPrefix}${n}`,!1!==e){if(o.split(e).some(e=>""===e.trim())){this.logger.warn(`Skipping key with empty segments: '${o}' (keyPrefix: '${s.keyPrefix}', key: '${n}')`);continue}}}const p=t===l.length-1&&g||n;if(c){const t=e.getObjectProperty(c,"context"),n=[];if("StringLiteral"===t?.value?.type||"NumericLiteral"===t?.value.type||"BooleanLiteral"===t?.value.type){const e=`${t.value.value}`,s=this.config.extract.contextSeparator??"_";""!==e&&n.push({key:`${o}${s}${e}`,ns:r,defaultValue:p,explicitDefault:d})}else if(t?.value){const e=this.expressionResolver.resolvePossibleContextStringValues(t.value),s=this.config.extract.contextSeparator??"_";e.length>0&&(e.forEach(e=>{n.push({key:`${o}${s}${e}`,ns:r,defaultValue:p,explicitDefault:d})}),n.push({key:o,ns:r,defaultValue:p,explicitDefault:d}))}const s=e=>{if(e){if("KeyValueProperty"===e.type&&e.key){if("Identifier"===e.key.type)return e.key.value;if("StringLiteral"===e.key.type)return e.key.value}return"KeyValueProperty"===e.type&&e.value&&"Identifier"===e.value.type?e.key&&"Identifier"===e.key.type?e.key.value:void 0:"ShorthandProperty"!==e.type&&"Identifier"!==e.type||!e.value?e.key&&"string"==typeof e.key?e.key:void 0:e.value}},i=(()=>{if(!c||!Array.isArray(c.properties))return!1;for(const e of c.properties){if("count"===s(e))return!0}return!1})(),l=(()=>{if(!c||!Array.isArray(c.properties))return!1;for(const e of c.properties){if("ordinal"===s(e))return!("KeyValueProperty"!==e.type||!e.value||"BooleanLiteral"!==e.value.type)&&Boolean(e.value.value)}return!1})();if(i||u){this.config.extract.disablePlurals?n.length>0?n.forEach(this.pluginContext.addKey):this.pluginContext.addKey({key:o,ns:r,defaultValue:p,explicitDefault:d}):this.handlePluralKeys(o,r,c,l||u,g,k);continue}if(n.length>0){n.forEach(this.pluginContext.addKey);continue}!0===e.getObjectPropValue(c,"returnObjects")&&this.objectKeys.add(o)}a&&this.objectKeys.add(o),this.pluginContext.addKey({key:o,ns:r,defaultValue:p,explicitDefault:d})}}handleCallExpressionArgument(e,t){const r=e.arguments[t].expression,n=[];let s=!1;if("ArrowFunctionExpression"===r.type){const e=this.extractKeyFromSelector(r);e&&(n.push(e),s=!0)}else if("ArrayExpression"===r.type)for(const e of r.elements)e?.expression&&n.push(...this.expressionResolver.resolvePossibleKeyStringValues(e.expression));else n.push(...this.expressionResolver.resolvePossibleKeyStringValues(r));return{keysToProcess:n.filter(e=>!!e),isSelectorAPI:s}}extractKeyFromSelector(e){let t=e.body;if("BlockStatement"===t.type){const e=t.stmts.find(e=>"ReturnStatement"===e.type);if("ReturnStatement"!==e?.type||!e.argument)return null;t=e.argument}let r=t;const n=[];for(;"MemberExpression"===r.type;){const e=r.property;if("Identifier"===e.type)n.unshift(e.value);else{if("Computed"!==e.type||"StringLiteral"!==e.expression.type)return null;n.unshift(e.expression.value)}r=r.object}if(n.length>0){const e=this.config.extract.keySeparator,t="string"==typeof e?e:".";return n.join(t)}return null}handlePluralKeys(t,r,n,s,i,o){try{const l=s?"ordinal":"cardinal",a=new Set;for(const e of this.config.locales)try{const t=new Intl.PluralRules(e,{type:l});t.resolvedOptions().pluralCategories.forEach(e=>a.add(e))}catch(e){const t=new Intl.PluralRules("en",{type:l});t.resolvedOptions().pluralCategories.forEach(e=>a.add(e))}const u=Array.from(a).sort(),p=this.config.extract.pluralSeparator??"_",f=e.getObjectPropValue(n,"defaultValue"),c=e.getObjectPropValue(n,`defaultValue${p}other`),y=e.getObjectPropValue(n,`defaultValue${p}ordinal${p}other`),g=e.getObjectProperty(n,"context"),h=[];if(g?.value){const e=this.expressionResolver.resolvePossibleContextStringValues(g.value);if(e.length>0)if("StringLiteral"===g.value.type)for(const r of e)r.length>0&&h.push({key:t,context:r});else{for(const r of e)r.length>0&&h.push({key:t,context:r});!1!==this.config.extract?.generateBasePluralForms&&h.push({key:t})}else h.push({key:t})}else h.push({key:t});for(const{key:t,context:l}of h)for(const a of u){const u=s?`defaultValue${p}ordinal${p}${a}`:`defaultValue${p}${a}`,g=e.getObjectPropValue(n,u);let h,d;if(h="string"==typeof g?g:"one"===a&&"string"==typeof f?f:"one"===a&&"string"==typeof i?i:s&&"string"==typeof y?y:s||"string"!=typeof c?"string"==typeof f?f:"string"==typeof i?i:t:c,l){const e=this.config.extract.contextSeparator??"_";d=s?`${t}${e}${l}${p}ordinal${p}${a}`:`${t}${e}${l}${p}${a}`}else d=s?`${t}${p}ordinal${p}${a}`:`${t}${p}${a}`;this.pluginContext.addKey({key:d,ns:r,defaultValue:h,hasCount:!0,isOrdinal:s,explicitDefault:Boolean(o||"string"==typeof g||"string"==typeof c)})}}catch(s){this.logger.warn(`Could not determine plural rules for language "${this.config.extract?.primaryLanguage}". Falling back to simple key extraction.`);const o=i||e.getObjectPropValue(n,"defaultValue");this.pluginContext.addKey({key:t,ns:r,defaultValue:"string"==typeof o?o:t})}}getFunctionName(e){if("Identifier"===e.type)return e.value;if("MemberExpression"===e.type){const t=[];let r=e;for(;"MemberExpression"===r.type;){if("Identifier"!==r.property.type)return null;t.unshift(r.property.value),r=r.object}if("ThisExpression"===r.type)t.unshift("this");else{if("Identifier"!==r.type)return null;t.unshift(r.value)}return t.join(".")}return null}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("./jsx-parser.js"),t=require("./ast-utils.js");exports.JSXHandler=class{config;pluginContext;expressionResolver;constructor(e,t,n){this.config=e,this.pluginContext=t,this.expressionResolver=n}handleJSXElement(t,n){const s=this.getElementName(t);if(s&&(this.config.extract.transComponents||["Trans"]).includes(s)){const s=e.extractFromTransComponent(t,this.config),a=[];if(s){if(s.keyExpression){const e=this.expressionResolver.resolvePossibleKeyStringValues(s.keyExpression);a.push(...e)}else a.push(s.serializedChildren);let e;const{contextExpression:l,optionsNode:i,defaultValue:o,hasCount:r,isOrdinal:u,serializedChildren:f}=s;if(s.ns){const{ns:t}=s;e=a.map(e=>({key:e,ns:t,defaultValue:o||f,hasCount:r,isOrdinal:u}))}else{e=a.map(e=>{const t=this.config.extract.nsSeparator??":";let n;if(t&&e.includes(t)){let s;[n,...s]=e.split(t),e=s.join(t)}return{key:e,ns:n,defaultValue:o||f,hasCount:r,isOrdinal:u}});const
|
|
1
|
+
"use strict";var e=require("./jsx-parser.js"),t=require("./ast-utils.js");exports.JSXHandler=class{config;pluginContext;expressionResolver;constructor(e,t,n){this.config=e,this.pluginContext=t,this.expressionResolver=n}handleJSXElement(t,n){const s=this.getElementName(t);if(s&&(this.config.extract.transComponents||["Trans"]).includes(s)){const s=e.extractFromTransComponent(t,this.config),a=[];if(s){if(s.keyExpression){const e=this.expressionResolver.resolvePossibleKeyStringValues(s.keyExpression);a.push(...e)}else a.push(s.serializedChildren);let e;const{contextExpression:l,optionsNode:i,defaultValue:o,hasCount:r,isOrdinal:u,serializedChildren:f}=s;if(s.ns){const{ns:t}=s;e=a.map(e=>({key:e,ns:t,defaultValue:o||f,hasCount:r,isOrdinal:u}))}else{e=a.map(e=>{const t=this.config.extract.nsSeparator??":";let n;if(t&&e.includes(t)){let s;[n,...s]=e.split(t),e=s.join(t)}return{key:e,ns:n,defaultValue:o||f,hasCount:r,isOrdinal:u,explicitDefault:s.explicitDefault}});const l=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"t"===e.name.value);if("JSXAttribute"===l?.type&&"JSXExpressionContainer"===l.value?.type&&"Identifier"===l.value.expression.type){const t=n(l.value.expression.value);t?.defaultNs&&e.forEach(e=>{e.ns||(e.ns=t.defaultNs)})}}if(e.forEach(e=>{e.ns||(e.ns=this.config.extract.defaultNS)}),l&&r)if(this.config.extract.disablePlurals){const t=this.expressionResolver.resolvePossibleContextStringValues(l),n=this.config.extract.contextSeparator??"_";if(t.length>0)if("StringLiteral"===l.type)for(const s of t)for(const t of e){const e=`${t.key}${n}${s}`;this.pluginContext.addKey({key:e,ns:t.ns,defaultValue:t.defaultValue})}else{e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})});for(const s of t)for(const t of e){const e=`${t.key}${n}${s}`;this.pluginContext.addKey({key:e,ns:t.ns,defaultValue:t.defaultValue})}}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else{const n=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),s=!!n,a=this.expressionResolver.resolvePossibleContextStringValues(l),o=this.config.extract.contextSeparator??"_";if(a.length>0){e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,i));for(const t of a)for(const n of e){const e=`${n.key}${o}${t}`;this.generatePluralKeysForTrans(e,n.defaultValue,n.ns,s,i,n.explicitDefault)}}else e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,i,e.explicitDefault))}else if(l){const t=this.expressionResolver.resolvePossibleContextStringValues(l),n=this.config.extract.contextSeparator??"_";if(t.length>0){for(const s of t)for(const{key:t,ns:a,defaultValue:l}of e)this.pluginContext.addKey({key:`${t}${n}${s}`,ns:a,defaultValue:l});"StringLiteral"!==l.type&&e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else if(r)if(this.config.extract.disablePlurals)e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})});else{const n=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),s=!!n;e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,i,e.explicitDefault))}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}}}generatePluralKeysForTrans(e,n,s,a,l,i){try{const o=a?"ordinal":"cardinal",r=new Intl.PluralRules(this.config.extract?.primaryLanguage,{type:o}).resolvedOptions().pluralCategories,u=this.config.extract.pluralSeparator??"_";let f,d;l&&(f=t.getObjectPropValue(l,`defaultValue${u}other`),d=t.getObjectPropValue(l,`defaultValue${u}ordinal${u}other`));for(const o of r){const r=a?`defaultValue${u}ordinal${u}${o}`:`defaultValue${u}${o}`,p=l?t.getObjectPropValue(l,r):void 0;let c;c="string"==typeof p?p:"one"===o&&"string"==typeof n?n:a&&"string"==typeof d?d:a||"string"!=typeof f?"string"==typeof n?n:e:f;const y=a?`${e}${u}ordinal${u}${o}`:`${e}${u}${o}`;this.pluginContext.addKey({key:y,ns:s,defaultValue:c,hasCount:!0,isOrdinal:a,explicitDefault:Boolean(i||"string"==typeof p||"string"==typeof f)})}}catch(t){this.pluginContext.addKey({key:e,ns:s,defaultValue:n})}}getElementName(e){if("Identifier"===e.opening.name.type)return e.opening.name.value;if("JSXMemberExpression"===e.opening.name.type){let t=e.opening.name;const n=[];for(;"JSXMemberExpression"===t.type;)"Identifier"===t.property.type&&n.unshift(t.property.value),t=t.object;return"Identifier"===t.type&&n.unshift(t.value),n.join(".")}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("./ast-utils.js");exports.extractFromTransComponent=function(t,n){const i=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"i18nKey"===e.name.value),r=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"defaults"===e.name.value),s=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"count"===e.name.value),p=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"values"===e.name.value);let o;s||"JSXAttribute"!==p?.type||"JSXExpressionContainer"!==p.value?.type||"ObjectExpression"!==p.value.expression.type||(o=e.getObjectProperty(p.value.expression,"count"));const
|
|
1
|
+
"use strict";var e=require("./ast-utils.js");exports.extractFromTransComponent=function(t,n){const i=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"i18nKey"===e.name.value),r=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"defaults"===e.name.value),s=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"count"===e.name.value),p=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"values"===e.name.value);let o;s||"JSXAttribute"!==p?.type||"JSXExpressionContainer"!==p.value?.type||"ObjectExpression"!==p.value.expression.type||(o=e.getObjectProperty(p.value.expression,"count"));const l=!!s||!!o,a=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"tOptions"===e.name.value),u="JSXAttribute"===a?.type&&"JSXExpressionContainer"===a.value?.type&&"ObjectExpression"===a.value.expression.type?a.value.expression:void 0,y=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),f=!!y,c=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"context"===e.name.value);let v="JSXAttribute"===c?.type&&"JSXExpressionContainer"===c.value?.type?c.value.expression:"JSXAttribute"===c?.type&&"StringLiteral"===c.value?.type?c.value:void 0;const S=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ns"===e.name.value);let g;if(g="JSXAttribute"===S?.type&&"StringLiteral"===S.value?.type?S.value.value:void 0,u&&(void 0===g&&(g=e.getObjectPropValue(u,"ns")),void 0===v)){const t=e.getObjectProperty(u,"context");t?.value&&(v=t.value)}const x=function(e,t){if(!e||0===e.length)return"";const n=new Set(t.extract.transKeepBasicHtmlNodesFor??["br","strong","i","p"]),i=e=>e&&"JSXText"===e.type&&/^\s*$/.test(e.value)&&e.value.includes("\n");function r(e,t,s=!1){if(!e||!e.length)return;let p=0,o=e.length-1;for(;p<=o&&i(e[p]);)p++;for(;o>=p&&i(e[o]);)o--;const l=p<=o?e.slice(p,o+1):[];for(let e=0;e<l.length;e++){const p=l[e];if(p)if("JSXText"!==p.type)if("JSXExpressionContainer"!==p.type){if("JSXElement"===p.type){const e=p.opening&&p.opening.name&&"Identifier"===p.opening.name.type?p.opening.name.value:void 0;if(e&&n.has(e)){!(!p.opening||!p.opening.selfClosing)&&t.push(p),r(p.children||[],t,!1)}else t.push(p),r(p.children||[],t,!0);continue}"JSXFragment"!==p.type||r(p.children||[],t,s)}else{if(s&&p.expression){const e=p.expression.type;if("ObjectExpression"===e){const e=p.expression.properties&&p.expression.properties[0];if(e&&"KeyValueProperty"===e.type)continue}if("StringLiteral"===e){const e=String(p.expression.value||"");if(!(/^\s*$/.test(e)&&!e.includes("\n")))continue}else if("Identifier"===e||"MemberExpression"===e||"CallExpression"===e)continue}if(p.expression&&"StringLiteral"===p.expression.type){const n=String(p.expression.value||""),r=/^\s*$/.test(n)&&!n.includes("\n"),s=l[e-1],o=l[e+1];if(r){const n=l[e+2];if(o&&"JSXText"===o.type&&i(o)&&n&&("JSXElement"===n.type||"JSXFragment"===n.type)){const t=l[e-1],n=l[e-2];if(!t||"JSXText"!==t.type&&n&&"JSXExpressionContainer"===n.type)continue}if(s&&("JSXElement"===s.type||"JSXFragment"===s.type)&&o&&"JSXText"===o.type&&i(o))continue;const r=!o||"JSXText"===o.type&&!i(o);if(s&&"JSXText"===s.type&&r){const e=t[t.length-1];if(e&&"JSXText"===e.type){e.value=String(e.value)+p.expression.value;continue}}if(s&&("JSXElement"===s.type||"JSXFragment"===s.type)&&o&&"JSXText"===o.type&&i(o))continue}}t.push(p)}else{if(s)continue;if(i(p)){const n=t[t.length-1],i=l[e-1];if(n){if(i&&"JSXExpressionContainer"===i.type)continue;if("JSXText"===n.type&&i&&"JSXText"===i.type){n.value=String(n.value)+p.value;continue}}}t.push(p)}}}const s=[];function p(e){if(!e||0===e.length)return"";let t="",r=!1;for(let o=0;o<e.length;o++){const l=e[o];if(l)if("JSXText"!==l.type){if("JSXExpressionContainer"===l.type){const e=l.expression;if(!e)continue;if("StringLiteral"===e.type)t+=e.value;else if("Identifier"===e.type)t+=`{{${e.value}}}`;else if("ObjectExpression"===e.type){const n=e.properties[0];n&&"KeyValueProperty"===n.type&&n.key&&"Identifier"===n.key.type?t+=`{{${n.key.value}}}`:n&&"Identifier"===n.type?t+=`{{${n.value}}}`:t+="{{value}}"}else"MemberExpression"===e.type&&e.property&&"Identifier"===e.property.type?t+=`{{${e.property.value}}}`:"CallExpression"===e.type&&"Identifier"===e.callee?.type?t+=`{{${e.callee.value}}}`:t+="{{value}}";r=!1;continue}if("JSXElement"===l.type){let i;if(l.opening&&l.opening.name&&"Identifier"===l.opening.name.type&&(i=l.opening.name.value),i&&n.has(i)){const n=p(l.children||[]),s=!(!l.opening||!l.opening.selfClosing),a=""!==String(n).trim();if(s||!a){const n=e[o-1];n&&"JSXText"===n.type&&/\n\s*$/.test(n.value)&&(t=t.replace(/\s+$/,"")),t+=`<${i}/>`,r=!0}else t+=`<${i}>${n}</${i}>`,r=!1}else{const e=s.indexOf(l);t+=`<${e}>${p(l.children||[])}</${e}>`,r=!1}continue}"JSXFragment"!==l.type||(t+=p(l.children||[]),r=!1)}else{if(i(l))continue;r?(t+=l.value.replace(/^\s+/,""),r=!1):t+=l.value}}return t}r(e,s,!1);const o=p(e);return String(o).replace(/\s+/g," ").trim()}(t.children,n);let d,J,X;if("JSXAttribute"===r?.type&&"StringLiteral"===r.value?.type)d=r.value.value;else{const e=n.extract.defaultValue;d="string"==typeof e?e:""}if("JSXAttribute"===i?.type){if("StringLiteral"===i.value?.type){if(J=i.value,X=J.value,!X||""===X.trim())return null;if(g&&"StringLiteral"===J.type){const e=n.extract.nsSeparator??":",t=J.value;if(e&&t.startsWith(`${g}${e}`)){if(X=t.slice(`${g}${e}`.length),!X||""===X.trim())return null;J={...J,value:X}}}}else"JSXExpressionContainer"===i.value?.type&&"JSXEmptyExpression"!==i.value.expression.type&&(J=i.value.expression);if(!J)return null}return r||!X||x.trim()?!r&&x.trim()&&(d=x):d=X,{keyExpression:J,serializedChildren:x,ns:g,defaultValue:d,hasCount:l,isOrdinal:f,contextExpression:v,optionsNode:u,explicitDefault:Boolean(r&&"JSXAttribute"===r.type&&"StringLiteral"===r.value?.type||(e=>{if(!e||!Array.isArray(e.properties))return!1;for(const t of e.properties)if(t&&"KeyValueProperty"===t.type&&t.key){const e="Identifier"===t.key.type&&t.key.value||"StringLiteral"===t.key.type&&t.key.value;if("string"==typeof e&&e.startsWith("defaultValue"))return!0}return!1})(u))}};
|
package/dist/esm/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as t}from"commander";import e from"chokidar";import{glob as o}from"glob";import n from"chalk";import{ensureConfig as i,loadConfig as a}from"./config.js";import{detectConfig as c}from"./heuristic-config.js";import{runExtractor as r}from"./extractor/core/extractor.js";import"node:path";import"node:fs/promises";import"jiti";import{runTypesGenerator as s}from"./types-generator.js";import{runSyncer as l}from"./syncer.js";import{runMigrator as p}from"./migrator.js";import{runInit as m}from"./init.js";import{runLinter as d}from"./linter.js";import{runStatus as u}from"./status.js";import{runLocizeSync as f,runLocizeDownload as g,runLocizeMigrate as h}from"./locize.js";const y=new t;y.name("i18next-cli").description("A unified, high-performance i18next CLI.").version("1.11.
|
|
2
|
+
import{Command as t}from"commander";import e from"chokidar";import{glob as o}from"glob";import n from"chalk";import{ensureConfig as i,loadConfig as a}from"./config.js";import{detectConfig as c}from"./heuristic-config.js";import{runExtractor as r}from"./extractor/core/extractor.js";import"node:path";import"node:fs/promises";import"jiti";import{runTypesGenerator as s}from"./types-generator.js";import{runSyncer as l}from"./syncer.js";import{runMigrator as p}from"./migrator.js";import{runInit as m}from"./init.js";import{runLinter as d}from"./linter.js";import{runStatus as u}from"./status.js";import{runLocizeSync as f,runLocizeDownload as g,runLocizeMigrate as h}from"./locize.js";const y=new t;y.name("i18next-cli").description("A unified, high-performance i18next CLI.").version("1.11.9"),y.command("extract").description("Extract translation keys from source files and update resource files.").option("-w, --watch","Watch for file changes and re-run the extractor.").option("--ci","Exit with a non-zero status code if any files are updated.").option("--dry-run","Run the extractor without writing any files to disk.").option("--sync-primary","Sync primary language values with default values from code.").action(async t=>{try{const n=await i(),a=async()=>{const e=await r(n,{isWatchMode:!!t.watch,isDryRun:!!t.dryRun,syncPrimaryWithDefaults:!!t.syncPrimary});return t.ci&&!e?(console.log("✅ No files were updated."),process.exit(0)):t.ci&&e&&(console.error("❌ Some files were updated. This should not happen in CI mode."),process.exit(1)),e};if(await a(),t.watch){console.log("\nWatching for changes...");e.watch(await o(n.extract.input),{ignored:/node_modules/,persistent:!0}).on("change",t=>{console.log(`\nFile changed: ${t}`),a()})}}catch(t){console.error("Error running extractor:",t),process.exit(1)}}),y.command("status [locale]").description("Display translation status. Provide a locale for a detailed key-by-key view.").option("-n, --namespace <ns>","Filter the status report by a specific namespace").action(async(t,e)=>{let o=await a();if(!o){console.log(n.blue("No config file found. Attempting to detect project structure..."));const t=await c();t||(console.error(n.red("Could not automatically detect your project structure.")),console.log(`Please create a config file first by running: ${n.cyan("npx i18next-cli init")}`),process.exit(1)),console.log(n.green("Project structure detected successfully!")),o=t}await u(o,{detail:t,namespace:e.namespace})}),y.command("types").description("Generate TypeScript definitions from translation resource files.").option("-w, --watch","Watch for file changes and re-run the type generator.").action(async t=>{const n=await i(),a=()=>s(n);if(await a(),t.watch){console.log("\nWatching for changes...");e.watch(await o(n.types?.input||[]),{persistent:!0}).on("change",t=>{console.log(`\nFile changed: ${t}`),a()})}}),y.command("sync").description("Synchronize secondary language files with the primary language file.").action(async()=>{const t=await i();await l(t)}),y.command("migrate-config [configPath]").description("Migrate a legacy i18next-parser.config.js to the new format.").action(async t=>{await p(t)}),y.command("init").description("Create a new i18next.config.ts/js file with an interactive setup wizard.").action(m),y.command("lint").description("Find potential issues like hardcoded strings in your codebase.").option("-w, --watch","Watch for file changes and re-run the linter.").action(async t=>{const i=async()=>{let t=await a();if(!t){console.log(n.blue("No config file found. Attempting to detect project structure..."));const e=await c();e||(console.error(n.red("Could not automatically detect your project structure.")),console.log(`Please create a config file first by running: ${n.cyan("npx i18next-cli init")}`),process.exit(1)),console.log(n.green("Project structure detected successfully!")),t=e}await d(t)};if(await i(),t.watch){console.log("\nWatching for changes...");const t=await a();if(t?.extract?.input){e.watch(await o(t.extract.input),{ignored:/node_modules/,persistent:!0}).on("change",t=>{console.log(`\nFile changed: ${t}`),i()})}}}),y.command("locize-sync").description("Synchronize local translations with your locize project.").option("--update-values","Update values of existing translations on locize.").option("--src-lng-only","Check for changes in source language only.").option("--compare-mtime","Compare modification times when syncing.").option("--dry-run","Run the command without making any changes.").action(async t=>{const e=await i();await f(e,t)}),y.command("locize-download").description("Download all translations from your locize project.").action(async t=>{const e=await i();await g(e,t)}),y.command("locize-migrate").description("Migrate local translation files to a new locize project.").action(async t=>{const e=await i();await h(e,t)}),y.parse(process.argv);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolve as t,basename as e,extname as r}from"node:path";import{glob as s}from"glob";import{getNestedKeys as
|
|
1
|
+
import{resolve as t,basename as e,extname as r}from"node:path";import{glob as s}from"glob";import{getNestedKeys as n,getNestedValue as o,setNestedValue as a}from"../../utils/nested-object.js";import{getOutputPath as i,loadTranslationFile as l}from"../../utils/file-utils.js";import{resolveDefaultValue as c}from"../../utils/default-value.js";function f(t){const e=`^${t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")}$`;return new RegExp(e)}function u(t,e){if("object"!=typeof t||null===t||Array.isArray(t))return t;const r={},s=e?.extract?.pluralSeparator??"_",n=["zero","one","two","few","many","other"],o=n.map(t=>`ordinal${s}${t}`),a=Object.keys(t).sort((t,e)=>{const r=t=>{for(const e of o)if(t.endsWith(`${s}${e}`)){return{base:t.slice(0,-(s.length+e.length)),form:e,isOrdinal:!0,isPlural:!0,fullKey:t}}for(const e of n)if(t.endsWith(`${s}${e}`)){return{base:t.slice(0,-(s.length+e.length)),form:e,isOrdinal:!1,isPlural:!0,fullKey:t}}return{base:t,form:"",isOrdinal:!1,isPlural:!1,fullKey:t}},a=r(t),i=r(e);if(a.isPlural&&i.isPlural){const t=a.base.localeCompare(i.base,void 0,{sensitivity:"base"});if(0!==t)return t;if(a.isOrdinal!==i.isOrdinal)return a.isOrdinal?1:-1;const e=a.isOrdinal?o:n,r=e.indexOf(a.form),s=e.indexOf(i.form);return-1!==r&&-1!==s?r-s:a.form.localeCompare(i.form)}const l=t.localeCompare(e,void 0,{sensitivity:"base"});return 0===l?t.localeCompare(e,void 0,{sensitivity:"case"}):l});for(const s of a)r[s]=u(t[s],e);return r}function p(t,e,r,s,i,l,f,p=!1){const{keySeparator:d=".",sort:y=!0,removeUnusedKeys:g=!0,primaryLanguage:m,defaultValue:h="",pluralSeparator:x="_",contextSeparator:O="_"}=r.extract,w=new Set;try{const t=new Intl.PluralRules(s,{type:"cardinal"}),e=new Intl.PluralRules(s,{type:"ordinal"});t.resolvedOptions().pluralCategories.forEach(t=>w.add(t)),e.resolvedOptions().pluralCategories.forEach(t=>w.add(`ordinal_${t}`))}catch(t){const e=new Intl.PluralRules(m||"en",{type:"cardinal"}),r=new Intl.PluralRules(m||"en",{type:"ordinal"});e.resolvedOptions().pluralCategories.forEach(t=>w.add(t)),r.resolvedOptions().pluralCategories.forEach(t=>w.add(`ordinal_${t}`))}const v=t.filter(({key:t,hasCount:e,isOrdinal:r})=>{if(l.some(e=>e.test(t)))return!1;if(!e)return!0;const s=t.split(x);if(r&&s.includes("ordinal")){const t=s[s.length-1];return w.has(`ordinal_${t}`)}if(e){const t=s[s.length-1];return w.has(t)}return!0});let b=g?{}:JSON.parse(JSON.stringify(e));const $=n(e,d??".");for(const t of $)if(l.some(e=>e.test(t))){const r=o(e,t,d??".");a(b,t,r,d??".")}if(g){const t=n(e,d??".");for(const r of t){const t=r.split(x);if("zero"===t[t.length-1]){const s=t.slice(0,-1).join(x);if(v.some(({key:t})=>t.split(x).slice(0,-1).join(x)===s)){const t=o(e,r,d??".");a(b,r,t,d??".")}}}}for(const{key:t,defaultValue:r,explicitDefault:n}of v){const l=o(e,t,d??"."),u=!v.some(e=>e.key.startsWith(`${t}${d}`)&&e.key!==t),y="object"==typeof l&&null!==l&&(f.has(t)||!r||r===t),g="object"==typeof l&&null!==l&&u&&!f.has(t)&&!y;if(y){a(b,t,l,d??".");continue}let w;if(void 0===l||g)if(s===m)if(p){const e=r&&(r===t||t!==r&&(t.startsWith(r+x)||t.startsWith(r+O)));w=r&&!e?r:c(h,t,i,s)}else w=r||t;else w=c(h,t,i,s);else if(s===m&&p){const e=r&&(r===t||t!==r&&(t.startsWith(r+x)||t.startsWith(r+O)));w=(t.includes(x)||t.includes(O))&&!n?l:r&&!e?r:l}else w=l;a(b,t,w,d??".")}if(!0===y)return u(b,r);if("function"==typeof y){const t={},e=Object.keys(b),s=new Map;for(const t of v){const e=!1===d?t.key:t.key.split(d)[0];s.has(e)||s.set(e,t)}e.sort((t,e)=>{if("function"==typeof y){const r=s.get(t),n=s.get(e);if(r&&n)return y(r,n)}return t.localeCompare(e,void 0,{sensitivity:"base"})});for(const s of e)t[s]=u(b[s],r);b=t}return b}async function d(n,o,a,{syncPrimaryWithDefaults:c=!1}={}){a.extract.primaryLanguage||=a.locales[0]||"en",a.extract.secondaryLanguages||=a.locales.filter(t=>t!==a?.extract?.primaryLanguage);const u=a.extract.defaultNS??"translation",d=[...a.extract.preservePatterns||[]],y=a.extract.indentation??2;for(const t of o)d.push(`${t}.*`);const g=d.map(f),m=new Map;for(const t of n.values()){const e=t.ns||u;m.has(e)||m.set(e,[]),m.get(e).push(t)}const h=[],x=Array.isArray(a.extract.ignore)?a.extract.ignore:a.extract.ignore?[a.extract.ignore]:[];for(const n of a.locales){if(a.extract.mergeNamespaces||!a.extract.output.includes("{{namespace}}")){const e={},r=i(a.extract.output,n),s=t(process.cwd(),r),f=await l(s)||{},u=new Set([...m.keys(),...Object.keys(f)]);for(const t of u){const r=m.get(t)||[],s=f[t]||{};e[t]=p(r,s,a,n,t,g,o,c)}const d=JSON.stringify(f,null,y),x=JSON.stringify(e,null,y);h.push({path:s,updated:x!==d,newTranslations:e,existingTranslations:f})}else{const f=new Set(m.keys()),u=i(a.extract.output,n,"*"),d=await s(u,{ignore:x});for(const t of d)f.add(e(t,r(t)));for(const e of f){const r=m.get(e)||[],s=i(a.extract.output,n,e),f=t(process.cwd(),s),u=await l(f)||{},d=p(r,u,a,n,e,g,o,c),x=JSON.stringify(u,null,y),O=JSON.stringify(d,null,y);h.push({path:f,updated:O!==x,newTranslations:d,existingTranslations:u})}}}return h}export{d as getTranslations};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getObjectPropValue as e,getObjectProperty as t}from"./ast-utils.js";class
|
|
1
|
+
import{getObjectPropValue as e,getObjectProperty as t}from"./ast-utils.js";class r{pluginContext;config;logger;expressionResolver;objectKeys=new Set;constructor(e,t,r,n){this.config=e,this.pluginContext=t,this.logger=r,this.expressionResolver=n}handleCallExpression(r,n){const i=this.getFunctionName(r.callee);if(!i)return;const s=n(i),o=this.config.extract.functions||["t","*.t"];let l=void 0!==s;if(!l)for(const e of o)if(e.startsWith("*.")){if(i.endsWith(e.substring(1))){l=!0;break}}else if(e===i){l=!0;break}if(!l||0===r.arguments.length)return;const{keysToProcess:a,isSelectorAPI:u}=this.handleCallExpressionArgument(r,0);if(0===a.length)return;let f=!1;const p=this.config.extract.pluralSeparator??"_";for(let e=0;e<a.length;e++)a[e].endsWith(`${p}ordinal`)&&(f=!0,a[e]=a[e].slice(0,-8));let y,c;if(r.arguments.length>1){const e=r.arguments[1].expression;"ObjectExpression"===e.type?c=e:"StringLiteral"===e.type&&(y=e.value)}if(r.arguments.length>2){const e=r.arguments[2].expression;"ObjectExpression"===e.type&&(c=e)}const g=c?e(c,"defaultValue"):void 0,h="string"==typeof g?g:y,d=e=>{if(!e||!Array.isArray(e.properties))return!1;for(const t of e.properties)if(t&&"KeyValueProperty"===t.type&&t.key){const e="Identifier"===t.key.type&&t.key.value||"StringLiteral"===t.key.type&&t.key.value;if("string"==typeof e&&e.startsWith("defaultValue"))return!0}return!1},x="string"==typeof h||d(c),k=d(c),v=Boolean(k||"string"==typeof h&&!("string"==typeof($=h)&&/{{\s*count\s*}}/.test($)));var $;for(let r=0;r<a.length;r++){let n,i=a[r];if(c){const t=e(c,"ns");"string"==typeof t&&(n=t)}const o=this.config.extract.nsSeparator??":";if(!n&&o&&i.includes(o)){const e=i.split(o);if(n=e.shift(),i=e.join(o),!i||""===i.trim()){this.logger.warn(`Skipping key that became empty after namespace removal: '${n}${o}'`);continue}}!n&&s?.defaultNs&&(n=s.defaultNs),n||(n=this.config.extract.defaultNS);let l=i;if(s?.keyPrefix){const e=this.config.extract.keySeparator??".";if(l=!1!==e?s.keyPrefix.endsWith(e)?`${s.keyPrefix}${i}`:`${s.keyPrefix}${e}${i}`:`${s.keyPrefix}${i}`,!1!==e){if(l.split(e).some(e=>""===e.trim())){this.logger.warn(`Skipping key with empty segments: '${l}' (keyPrefix: '${s.keyPrefix}', key: '${i}')`);continue}}}const p=r===a.length-1&&h||i;if(c){const r=t(c,"context"),i=[];if("StringLiteral"===r?.value?.type||"NumericLiteral"===r?.value.type||"BooleanLiteral"===r?.value.type){const e=`${r.value.value}`,t=this.config.extract.contextSeparator??"_";""!==e&&i.push({key:`${l}${t}${e}`,ns:n,defaultValue:p,explicitDefault:x})}else if(r?.value){const e=this.expressionResolver.resolvePossibleContextStringValues(r.value),t=this.config.extract.contextSeparator??"_";e.length>0&&(e.forEach(e=>{i.push({key:`${l}${t}${e}`,ns:n,defaultValue:p,explicitDefault:x})}),i.push({key:l,ns:n,defaultValue:p,explicitDefault:x}))}const s=e=>{if(e){if("KeyValueProperty"===e.type&&e.key){if("Identifier"===e.key.type)return e.key.value;if("StringLiteral"===e.key.type)return e.key.value}return"KeyValueProperty"===e.type&&e.value&&"Identifier"===e.value.type?e.key&&"Identifier"===e.key.type?e.key.value:void 0:"ShorthandProperty"!==e.type&&"Identifier"!==e.type||!e.value?e.key&&"string"==typeof e.key?e.key:void 0:e.value}},o=(()=>{if(!c||!Array.isArray(c.properties))return!1;for(const e of c.properties){if("count"===s(e))return!0}return!1})(),a=(()=>{if(!c||!Array.isArray(c.properties))return!1;for(const e of c.properties){if("ordinal"===s(e))return!("KeyValueProperty"!==e.type||!e.value||"BooleanLiteral"!==e.value.type)&&Boolean(e.value.value)}return!1})();if(o||f){this.config.extract.disablePlurals?i.length>0?i.forEach(this.pluginContext.addKey):this.pluginContext.addKey({key:l,ns:n,defaultValue:p,explicitDefault:x}):this.handlePluralKeys(l,n,c,a||f,h,v);continue}if(i.length>0){i.forEach(this.pluginContext.addKey);continue}!0===e(c,"returnObjects")&&this.objectKeys.add(l)}u&&this.objectKeys.add(l),this.pluginContext.addKey({key:l,ns:n,defaultValue:p,explicitDefault:x})}}handleCallExpressionArgument(e,t){const r=e.arguments[t].expression,n=[];let i=!1;if("ArrowFunctionExpression"===r.type){const e=this.extractKeyFromSelector(r);e&&(n.push(e),i=!0)}else if("ArrayExpression"===r.type)for(const e of r.elements)e?.expression&&n.push(...this.expressionResolver.resolvePossibleKeyStringValues(e.expression));else n.push(...this.expressionResolver.resolvePossibleKeyStringValues(r));return{keysToProcess:n.filter(e=>!!e),isSelectorAPI:i}}extractKeyFromSelector(e){let t=e.body;if("BlockStatement"===t.type){const e=t.stmts.find(e=>"ReturnStatement"===e.type);if("ReturnStatement"!==e?.type||!e.argument)return null;t=e.argument}let r=t;const n=[];for(;"MemberExpression"===r.type;){const e=r.property;if("Identifier"===e.type)n.unshift(e.value);else{if("Computed"!==e.type||"StringLiteral"!==e.expression.type)return null;n.unshift(e.expression.value)}r=r.object}if(n.length>0){const e=this.config.extract.keySeparator,t="string"==typeof e?e:".";return n.join(t)}return null}handlePluralKeys(r,n,i,s,o,l){try{const a=s?"ordinal":"cardinal",u=new Set;for(const e of this.config.locales)try{const t=new Intl.PluralRules(e,{type:a});t.resolvedOptions().pluralCategories.forEach(e=>u.add(e))}catch(e){const t=new Intl.PluralRules("en",{type:a});t.resolvedOptions().pluralCategories.forEach(e=>u.add(e))}const f=Array.from(u).sort(),p=this.config.extract.pluralSeparator??"_",y=e(i,"defaultValue"),c=e(i,`defaultValue${p}other`),g=e(i,`defaultValue${p}ordinal${p}other`),h=t(i,"context"),d=[];if(h?.value){const e=this.expressionResolver.resolvePossibleContextStringValues(h.value);if(e.length>0)if("StringLiteral"===h.value.type)for(const t of e)t.length>0&&d.push({key:r,context:t});else{for(const t of e)t.length>0&&d.push({key:r,context:t});!1!==this.config.extract?.generateBasePluralForms&&d.push({key:r})}else d.push({key:r})}else d.push({key:r});for(const{key:t,context:r}of d)for(const a of f){const u=e(i,s?`defaultValue${p}ordinal${p}${a}`:`defaultValue${p}${a}`);let f,h;if(f="string"==typeof u?u:"one"===a&&"string"==typeof y?y:"one"===a&&"string"==typeof o?o:s&&"string"==typeof g?g:s||"string"!=typeof c?"string"==typeof y?y:"string"==typeof o?o:t:c,r){const e=this.config.extract.contextSeparator??"_";h=s?`${t}${e}${r}${p}ordinal${p}${a}`:`${t}${e}${r}${p}${a}`}else h=s?`${t}${p}ordinal${p}${a}`:`${t}${p}${a}`;this.pluginContext.addKey({key:h,ns:n,defaultValue:f,hasCount:!0,isOrdinal:s,explicitDefault:Boolean(l||"string"==typeof u||"string"==typeof c)})}}catch(t){this.logger.warn(`Could not determine plural rules for language "${this.config.extract?.primaryLanguage}". Falling back to simple key extraction.`);const s=o||e(i,"defaultValue");this.pluginContext.addKey({key:r,ns:n,defaultValue:"string"==typeof s?s:r})}}getFunctionName(e){if("Identifier"===e.type)return e.value;if("MemberExpression"===e.type){const t=[];let r=e;for(;"MemberExpression"===r.type;){if("Identifier"!==r.property.type)return null;t.unshift(r.property.value),r=r.object}if("ThisExpression"===r.type)t.unshift("this");else{if("Identifier"!==r.type)return null;t.unshift(r.value)}return t.join(".")}return null}}export{r as CallExpressionHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{extractFromTransComponent as e}from"./jsx-parser.js";import{getObjectPropValue as t}from"./ast-utils.js";class n{config;pluginContext;expressionResolver;constructor(e,t,n){this.config=e,this.pluginContext=t,this.expressionResolver=n}handleJSXElement(t,n){const s=this.getElementName(t);if(s&&(this.config.extract.transComponents||["Trans"]).includes(s)){const s=e(t,this.config),a=[];if(s){if(s.keyExpression){const e=this.expressionResolver.resolvePossibleKeyStringValues(s.keyExpression);a.push(...e)}else a.push(s.serializedChildren);let e;const{contextExpression:i,optionsNode:l,defaultValue:o,hasCount:r,isOrdinal:u,serializedChildren:f}=s;if(s.ns){const{ns:t}=s;e=a.map(e=>({key:e,ns:t,defaultValue:o||f,hasCount:r,isOrdinal:u}))}else{e=a.map(e=>{const t=this.config.extract.nsSeparator??":";let n;if(t&&e.includes(t)){let s;[n,...s]=e.split(t),e=s.join(t)}return{key:e,ns:n,defaultValue:o||f,hasCount:r,isOrdinal:u}});const
|
|
1
|
+
import{extractFromTransComponent as e}from"./jsx-parser.js";import{getObjectPropValue as t}from"./ast-utils.js";class n{config;pluginContext;expressionResolver;constructor(e,t,n){this.config=e,this.pluginContext=t,this.expressionResolver=n}handleJSXElement(t,n){const s=this.getElementName(t);if(s&&(this.config.extract.transComponents||["Trans"]).includes(s)){const s=e(t,this.config),a=[];if(s){if(s.keyExpression){const e=this.expressionResolver.resolvePossibleKeyStringValues(s.keyExpression);a.push(...e)}else a.push(s.serializedChildren);let e;const{contextExpression:i,optionsNode:l,defaultValue:o,hasCount:r,isOrdinal:u,serializedChildren:f}=s;if(s.ns){const{ns:t}=s;e=a.map(e=>({key:e,ns:t,defaultValue:o||f,hasCount:r,isOrdinal:u}))}else{e=a.map(e=>{const t=this.config.extract.nsSeparator??":";let n;if(t&&e.includes(t)){let s;[n,...s]=e.split(t),e=s.join(t)}return{key:e,ns:n,defaultValue:o||f,hasCount:r,isOrdinal:u,explicitDefault:s.explicitDefault}});const i=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"t"===e.name.value);if("JSXAttribute"===i?.type&&"JSXExpressionContainer"===i.value?.type&&"Identifier"===i.value.expression.type){const t=n(i.value.expression.value);t?.defaultNs&&e.forEach(e=>{e.ns||(e.ns=t.defaultNs)})}}if(e.forEach(e=>{e.ns||(e.ns=this.config.extract.defaultNS)}),i&&r)if(this.config.extract.disablePlurals){const t=this.expressionResolver.resolvePossibleContextStringValues(i),n=this.config.extract.contextSeparator??"_";if(t.length>0)if("StringLiteral"===i.type)for(const s of t)for(const t of e){const e=`${t.key}${n}${s}`;this.pluginContext.addKey({key:e,ns:t.ns,defaultValue:t.defaultValue})}else{e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})});for(const s of t)for(const t of e){const e=`${t.key}${n}${s}`;this.pluginContext.addKey({key:e,ns:t.ns,defaultValue:t.defaultValue})}}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else{const n=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),s=!!n,a=this.expressionResolver.resolvePossibleContextStringValues(i),o=this.config.extract.contextSeparator??"_";if(a.length>0){e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,l));for(const t of a)for(const n of e){const e=`${n.key}${o}${t}`;this.generatePluralKeysForTrans(e,n.defaultValue,n.ns,s,l,n.explicitDefault)}}else e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,l,e.explicitDefault))}else if(i){const t=this.expressionResolver.resolvePossibleContextStringValues(i),n=this.config.extract.contextSeparator??"_";if(t.length>0){for(const s of t)for(const{key:t,ns:a,defaultValue:i}of e)this.pluginContext.addKey({key:`${t}${n}${s}`,ns:a,defaultValue:i});"StringLiteral"!==i.type&&e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}else if(r)if(this.config.extract.disablePlurals)e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})});else{const n=t.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),s=!!n;e.forEach(e=>this.generatePluralKeysForTrans(e.key,e.defaultValue,e.ns,s,l,e.explicitDefault))}else e.forEach(e=>{this.pluginContext.addKey({key:e.key,ns:e.ns,defaultValue:e.defaultValue})})}}}generatePluralKeysForTrans(e,n,s,a,i,l){try{const o=a?"ordinal":"cardinal",r=new Intl.PluralRules(this.config.extract?.primaryLanguage,{type:o}).resolvedOptions().pluralCategories,u=this.config.extract.pluralSeparator??"_";let f,d;i&&(f=t(i,`defaultValue${u}other`),d=t(i,`defaultValue${u}ordinal${u}other`));for(const o of r){const r=i?t(i,a?`defaultValue${u}ordinal${u}${o}`:`defaultValue${u}${o}`):void 0;let p;p="string"==typeof r?r:"one"===o&&"string"==typeof n?n:a&&"string"==typeof d?d:a||"string"!=typeof f?"string"==typeof n?n:e:f;const c=a?`${e}${u}ordinal${u}${o}`:`${e}${u}${o}`;this.pluginContext.addKey({key:c,ns:s,defaultValue:p,hasCount:!0,isOrdinal:a,explicitDefault:Boolean(l||"string"==typeof r||"string"==typeof f)})}}catch(t){this.pluginContext.addKey({key:e,ns:s,defaultValue:n})}}getElementName(e){if("Identifier"===e.opening.name.type)return e.opening.name.value;if("JSXMemberExpression"===e.opening.name.type){let t=e.opening.name;const n=[];for(;"JSXMemberExpression"===t.type;)"Identifier"===t.property.type&&n.unshift(t.property.value),t=t.object;return"Identifier"===t.type&&n.unshift(t.value),n.join(".")}}}export{n as JSXHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getObjectProperty as e,getObjectPropValue as t}from"./ast-utils.js";function n(n,i){const r=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"i18nKey"===e.name.value),s=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"defaults"===e.name.value),p=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"count"===e.name.value),o=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"values"===e.name.value);let l;p||"JSXAttribute"!==o?.type||"JSXExpressionContainer"!==o.value?.type||"ObjectExpression"!==o.value.expression.type||(l=e(o.value.expression,"count"));const a=!!p||!!l,u=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"tOptions"===e.name.value),y="JSXAttribute"===u?.type&&"JSXExpressionContainer"===u.value?.type&&"ObjectExpression"===u.value.expression.type?u.value.expression:void 0,f=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),c=!!f,v=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"context"===e.name.value);let S="JSXAttribute"===v?.type&&"JSXExpressionContainer"===v.value?.type?v.value.expression:"JSXAttribute"===v?.type&&"StringLiteral"===v.value?.type?v.value:void 0;const x=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ns"===e.name.value);let
|
|
1
|
+
import{getObjectProperty as e,getObjectPropValue as t}from"./ast-utils.js";function n(n,i){const r=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"i18nKey"===e.name.value),s=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"defaults"===e.name.value),p=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"count"===e.name.value),o=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"values"===e.name.value);let l;p||"JSXAttribute"!==o?.type||"JSXExpressionContainer"!==o.value?.type||"ObjectExpression"!==o.value.expression.type||(l=e(o.value.expression,"count"));const a=!!p||!!l,u=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"tOptions"===e.name.value),y="JSXAttribute"===u?.type&&"JSXExpressionContainer"===u.value?.type&&"ObjectExpression"===u.value.expression.type?u.value.expression:void 0,f=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ordinal"===e.name.value),c=!!f,v=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"context"===e.name.value);let S="JSXAttribute"===v?.type&&"JSXExpressionContainer"===v.value?.type?v.value.expression:"JSXAttribute"===v?.type&&"StringLiteral"===v.value?.type?v.value:void 0;const x=n.opening.attributes?.find(e=>"JSXAttribute"===e.type&&"Identifier"===e.name.type&&"ns"===e.name.value);let g;if(g="JSXAttribute"===x?.type&&"StringLiteral"===x.value?.type?x.value.value:void 0,y&&(void 0===g&&(g=t(y,"ns")),void 0===S)){const t=e(y,"context");t?.value&&(S=t.value)}const d=function(e,t){if(!e||0===e.length)return"";const n=new Set(t.extract.transKeepBasicHtmlNodesFor??["br","strong","i","p"]),i=e=>e&&"JSXText"===e.type&&/^\s*$/.test(e.value)&&e.value.includes("\n");function r(e,t,s=!1){if(!e||!e.length)return;let p=0,o=e.length-1;for(;p<=o&&i(e[p]);)p++;for(;o>=p&&i(e[o]);)o--;const l=p<=o?e.slice(p,o+1):[];for(let e=0;e<l.length;e++){const p=l[e];if(p)if("JSXText"!==p.type)if("JSXExpressionContainer"!==p.type){if("JSXElement"===p.type){const e=p.opening&&p.opening.name&&"Identifier"===p.opening.name.type?p.opening.name.value:void 0;if(e&&n.has(e)){!(!p.opening||!p.opening.selfClosing)&&t.push(p),r(p.children||[],t,!1)}else t.push(p),r(p.children||[],t,!0);continue}"JSXFragment"!==p.type||r(p.children||[],t,s)}else{if(s&&p.expression){const e=p.expression.type;if("ObjectExpression"===e){const e=p.expression.properties&&p.expression.properties[0];if(e&&"KeyValueProperty"===e.type)continue}if("StringLiteral"===e){const e=String(p.expression.value||"");if(!(/^\s*$/.test(e)&&!e.includes("\n")))continue}else if("Identifier"===e||"MemberExpression"===e||"CallExpression"===e)continue}if(p.expression&&"StringLiteral"===p.expression.type){const n=String(p.expression.value||""),r=/^\s*$/.test(n)&&!n.includes("\n"),s=l[e-1],o=l[e+1];if(r){const n=l[e+2];if(o&&"JSXText"===o.type&&i(o)&&n&&("JSXElement"===n.type||"JSXFragment"===n.type)){const t=l[e-1],n=l[e-2];if(!t||"JSXText"!==t.type&&n&&"JSXExpressionContainer"===n.type)continue}if(s&&("JSXElement"===s.type||"JSXFragment"===s.type)&&o&&"JSXText"===o.type&&i(o))continue;const r=!o||"JSXText"===o.type&&!i(o);if(s&&"JSXText"===s.type&&r){const e=t[t.length-1];if(e&&"JSXText"===e.type){e.value=String(e.value)+p.expression.value;continue}}if(s&&("JSXElement"===s.type||"JSXFragment"===s.type)&&o&&"JSXText"===o.type&&i(o))continue}}t.push(p)}else{if(s)continue;if(i(p)){const n=t[t.length-1],i=l[e-1];if(n){if(i&&"JSXExpressionContainer"===i.type)continue;if("JSXText"===n.type&&i&&"JSXText"===i.type){n.value=String(n.value)+p.value;continue}}}t.push(p)}}}const s=[];function p(e){if(!e||0===e.length)return"";let t="",r=!1;for(let o=0;o<e.length;o++){const l=e[o];if(l)if("JSXText"!==l.type){if("JSXExpressionContainer"===l.type){const e=l.expression;if(!e)continue;if("StringLiteral"===e.type)t+=e.value;else if("Identifier"===e.type)t+=`{{${e.value}}}`;else if("ObjectExpression"===e.type){const n=e.properties[0];n&&"KeyValueProperty"===n.type&&n.key&&"Identifier"===n.key.type?t+=`{{${n.key.value}}}`:n&&"Identifier"===n.type?t+=`{{${n.value}}}`:t+="{{value}}"}else"MemberExpression"===e.type&&e.property&&"Identifier"===e.property.type?t+=`{{${e.property.value}}}`:"CallExpression"===e.type&&"Identifier"===e.callee?.type?t+=`{{${e.callee.value}}}`:t+="{{value}}";r=!1;continue}if("JSXElement"===l.type){let i;if(l.opening&&l.opening.name&&"Identifier"===l.opening.name.type&&(i=l.opening.name.value),i&&n.has(i)){const n=p(l.children||[]),s=!(!l.opening||!l.opening.selfClosing),a=""!==String(n).trim();if(s||!a){const n=e[o-1];n&&"JSXText"===n.type&&/\n\s*$/.test(n.value)&&(t=t.replace(/\s+$/,"")),t+=`<${i}/>`,r=!0}else t+=`<${i}>${n}</${i}>`,r=!1}else{const e=s.indexOf(l);t+=`<${e}>${p(l.children||[])}</${e}>`,r=!1}continue}"JSXFragment"!==l.type||(t+=p(l.children||[]),r=!1)}else{if(i(l))continue;r?(t+=l.value.replace(/^\s+/,""),r=!1):t+=l.value}}return t}r(e,s,!1);const o=p(e);return String(o).replace(/\s+/g," ").trim()}(n.children,i);let J,X,m;if("JSXAttribute"===s?.type&&"StringLiteral"===s.value?.type)J=s.value.value;else{const e=i.extract.defaultValue;J="string"==typeof e?e:""}if("JSXAttribute"===r?.type){if("StringLiteral"===r.value?.type){if(X=r.value,m=X.value,!m||""===m.trim())return null;if(g&&"StringLiteral"===X.type){const e=i.extract.nsSeparator??":",t=X.value;if(e&&t.startsWith(`${g}${e}`)){if(m=t.slice(`${g}${e}`.length),!m||""===m.trim())return null;X={...X,value:m}}}}else"JSXExpressionContainer"===r.value?.type&&"JSXEmptyExpression"!==r.value.expression.type&&(X=r.value.expression);if(!X)return null}s||!m||d.trim()?!s&&d.trim()&&(J=d):J=m;return{keyExpression:X,serializedChildren:d,ns:g,defaultValue:J,hasCount:a,isOrdinal:c,contextExpression:S,optionsNode:y,explicitDefault:Boolean(s&&"JSXAttribute"===s.type&&"StringLiteral"===s.value?.type||(e=>{if(!e||!Array.isArray(e.properties))return!1;for(const t of e.properties)if(t&&"KeyValueProperty"===t.type&&t.key){const e="Identifier"===t.key.type&&t.key.value||"StringLiteral"===t.key.type&&t.key.value;if("string"==typeof e&&e.startsWith("defaultValue"))return!0}return!1})(y))}}export{n as extractFromTransComponent};
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -208,7 +208,7 @@ function buildNewTranslationsForNs (
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
// 1. Build the object first, without any sorting.
|
|
211
|
-
for (const { key, defaultValue } of filteredKeys) {
|
|
211
|
+
for (const { key, defaultValue, explicitDefault } of filteredKeys) {
|
|
212
212
|
const existingValue = getNestedValue(existingTranslations, key, keySeparator ?? '.')
|
|
213
213
|
const isLeafInNewKeys = !filteredKeys.some(otherKey => otherKey.key.startsWith(`${key}${keySeparator}`) && otherKey.key !== key)
|
|
214
214
|
|
|
@@ -255,8 +255,7 @@ function buildNewTranslationsForNs (
|
|
|
255
255
|
} else {
|
|
256
256
|
// Existing value exists - decide whether to preserve or sync
|
|
257
257
|
if (locale === primaryLanguage && syncPrimaryWithDefaults) {
|
|
258
|
-
//
|
|
259
|
-
// Only update if we have a meaningful defaultValue that's not derived from key pattern
|
|
258
|
+
// Only update when we have a meaningful defaultValue that's not derived from the key pattern.
|
|
260
259
|
const isDerivedDefault = defaultValue && (
|
|
261
260
|
defaultValue === key || // Exact match
|
|
262
261
|
// For variant keys (plural/context), check if defaultValue is the base
|
|
@@ -265,20 +264,16 @@ function buildNewTranslationsForNs (
|
|
|
265
264
|
key.startsWith(defaultValue + contextSeparator)))
|
|
266
265
|
)
|
|
267
266
|
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// This includes plural/context variant keys generated from a single explicit
|
|
276
|
-
// default (e.g. t('key', 'Default', { count })) — we should update all
|
|
277
|
-
// generated variant forms to that explicit default.
|
|
278
|
-
if (defaultValue && !isDerivedDefault) {
|
|
267
|
+
// If this key looks like a plural/context variant and the default
|
|
268
|
+
// wasn't explicitly provided in source code, preserve the existing value.
|
|
269
|
+
const isVariantKey = key.includes(pluralSeparator) || key.includes(contextSeparator)
|
|
270
|
+
if (isVariantKey && !explicitDefault) {
|
|
271
|
+
valueToSet = existingValue
|
|
272
|
+
} else if (defaultValue && !isDerivedDefault) {
|
|
273
|
+
// Otherwise, if we have a meaningful (non-derived) default, apply it.
|
|
279
274
|
valueToSet = defaultValue
|
|
280
275
|
} else {
|
|
281
|
-
//
|
|
276
|
+
// Fallback: preserve existing translation.
|
|
282
277
|
valueToSet = existingValue
|
|
283
278
|
}
|
|
284
279
|
} else {
|
|
@@ -98,6 +98,28 @@ export class CallExpressionHandler {
|
|
|
98
98
|
const defaultValueFromOptions = options ? getObjectPropValue(options, 'defaultValue') : undefined
|
|
99
99
|
const finalDefaultValue = (typeof defaultValueFromOptions === 'string' ? defaultValueFromOptions : defaultValue)
|
|
100
100
|
|
|
101
|
+
// Helper: detect if options object contains any defaultValue* properties
|
|
102
|
+
const optionsHasDefaultProps = (opts?: ObjectExpression) => {
|
|
103
|
+
if (!opts || !Array.isArray(opts.properties)) return false
|
|
104
|
+
for (const p of opts.properties as any[]) {
|
|
105
|
+
if (p && p.type === 'KeyValueProperty' && p.key) {
|
|
106
|
+
const keyName = (p.key.type === 'Identifier' && p.key.value) || (p.key.type === 'StringLiteral' && p.key.value)
|
|
107
|
+
if (typeof keyName === 'string' && keyName.startsWith('defaultValue')) return true
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// explicit for base key when a string default was provided OR explicit plural defaults are present
|
|
114
|
+
const explicitDefaultForBase = typeof finalDefaultValue === 'string' || optionsHasDefaultProps(options)
|
|
115
|
+
// detect if options contain plural-specific defaultValue_* props
|
|
116
|
+
const explicitPluralDefaultsInOptions = optionsHasDefaultProps(options)
|
|
117
|
+
// If a base default string exists, consider it explicit for plural VARIANTS only when
|
|
118
|
+
// it does NOT contain a count interpolation like '{{count}}' — templates with count
|
|
119
|
+
// are often the runtime interpolation form and should NOT overwrite existing variant forms.
|
|
120
|
+
const containsCountPlaceholder = (s?: string) => typeof s === 'string' && /{{\s*count\s*}}/.test(s)
|
|
121
|
+
const explicitPluralForVariants = Boolean(explicitPluralDefaultsInOptions || (typeof finalDefaultValue === 'string' && !containsCountPlaceholder(finalDefaultValue)))
|
|
122
|
+
|
|
101
123
|
// Loop through each key found (could be one or more) and process it
|
|
102
124
|
for (let i = 0; i < keysToProcess.length; i++) {
|
|
103
125
|
let key = keysToProcess[i]
|
|
@@ -172,7 +194,7 @@ export class CallExpressionHandler {
|
|
|
172
194
|
const contextSeparator = this.config.extract.contextSeparator ?? '_'
|
|
173
195
|
// Ignore context: ''
|
|
174
196
|
if (contextValue !== '') {
|
|
175
|
-
keysWithContext.push({ key: `${finalKey}${contextSeparator}${contextValue}`, ns, defaultValue: dv })
|
|
197
|
+
keysWithContext.push({ key: `${finalKey}${contextSeparator}${contextValue}`, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase })
|
|
176
198
|
}
|
|
177
199
|
} else if (contextProp?.value) {
|
|
178
200
|
const contextValues = this.expressionResolver.resolvePossibleContextStringValues(contextProp.value)
|
|
@@ -180,16 +202,62 @@ export class CallExpressionHandler {
|
|
|
180
202
|
|
|
181
203
|
if (contextValues.length > 0) {
|
|
182
204
|
contextValues.forEach(context => {
|
|
183
|
-
keysWithContext.push({ key: `${finalKey}${contextSeparator}${context}`, ns, defaultValue: dv })
|
|
205
|
+
keysWithContext.push({ key: `${finalKey}${contextSeparator}${context}`, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase })
|
|
184
206
|
})
|
|
185
207
|
// For dynamic context, also add the base key as a fallback
|
|
186
|
-
keysWithContext.push({ key: finalKey, ns, defaultValue: dv })
|
|
208
|
+
keysWithContext.push({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase })
|
|
187
209
|
}
|
|
188
210
|
}
|
|
189
211
|
|
|
190
212
|
// 2. Handle Plurals
|
|
191
|
-
|
|
192
|
-
|
|
213
|
+
// Robust detection for `{ count }`, `{ count: x }`, `{ 'count': x }` etc.
|
|
214
|
+
// Support KeyValueProperty and common shorthand forms that SWC may emit.
|
|
215
|
+
const propNameFromNode = (p: any): string | undefined => {
|
|
216
|
+
if (!p) return undefined
|
|
217
|
+
// Standard key:value property
|
|
218
|
+
if (p.type === 'KeyValueProperty' && p.key) {
|
|
219
|
+
if (p.key.type === 'Identifier') return p.key.value
|
|
220
|
+
if (p.key.type === 'StringLiteral') return p.key.value
|
|
221
|
+
}
|
|
222
|
+
// SWC may represent shorthand properties differently (no explicit key node).
|
|
223
|
+
// Try common shapes: property with `value` being an Identifier (shorthand).
|
|
224
|
+
if (p.type === 'KeyValueProperty' && p.value && p.value.type === 'Identifier') {
|
|
225
|
+
// e.g. { count: count } - already covered above, but keep safe fallback
|
|
226
|
+
return p.key && p.key.type === 'Identifier' ? p.key.value : undefined
|
|
227
|
+
}
|
|
228
|
+
// Some AST variants use 'ShorthandProperty' or keep the Identifier directly.
|
|
229
|
+
if ((p.type === 'ShorthandProperty' || p.type === 'Identifier') && (p as any).value) {
|
|
230
|
+
return (p as any).value
|
|
231
|
+
}
|
|
232
|
+
// Fallback: if node has an 'id' or 'key' string value
|
|
233
|
+
if (p.key && typeof p.key === 'string') return p.key
|
|
234
|
+
return undefined
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const hasCount = (() => {
|
|
238
|
+
if (!options || !Array.isArray(options.properties)) return false
|
|
239
|
+
for (const p of options.properties as any[]) {
|
|
240
|
+
const name = propNameFromNode(p)
|
|
241
|
+
if (name === 'count') return true
|
|
242
|
+
}
|
|
243
|
+
return false
|
|
244
|
+
})()
|
|
245
|
+
|
|
246
|
+
const isOrdinalByOption = (() => {
|
|
247
|
+
if (!options || !Array.isArray(options.properties)) return false
|
|
248
|
+
for (const p of options.properties as any[]) {
|
|
249
|
+
const name = propNameFromNode(p)
|
|
250
|
+
if (name === 'ordinal') {
|
|
251
|
+
// If it's a key:value pair with a BooleanLiteral true, respect it.
|
|
252
|
+
if (p.type === 'KeyValueProperty' && p.value && p.value.type === 'BooleanLiteral') {
|
|
253
|
+
return Boolean(p.value.value)
|
|
254
|
+
}
|
|
255
|
+
// shorthand `ordinal` without explicit true -> treat as false
|
|
256
|
+
return false
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return false
|
|
260
|
+
})()
|
|
193
261
|
if (hasCount || isOrdinalByKey) {
|
|
194
262
|
// Check if plurals are disabled
|
|
195
263
|
if (this.config.extract.disablePlurals) {
|
|
@@ -198,12 +266,15 @@ export class CallExpressionHandler {
|
|
|
198
266
|
if (keysWithContext.length > 0) {
|
|
199
267
|
keysWithContext.forEach(this.pluginContext.addKey)
|
|
200
268
|
} else {
|
|
201
|
-
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv })
|
|
269
|
+
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase })
|
|
202
270
|
}
|
|
203
271
|
} else {
|
|
204
272
|
// Original plural handling logic when plurals are enabled
|
|
205
|
-
// Always pass the base key to handlePluralKeys - it will handle context internally
|
|
206
|
-
|
|
273
|
+
// Always pass the base key to handlePluralKeys - it will handle context internally.
|
|
274
|
+
// Pass explicitDefaultForBase so that when a call-site provided an explicit
|
|
275
|
+
// base default (e.g. t('key', 'Default', { count })), plural variant keys
|
|
276
|
+
// are treated as explicit and may be synced to that default.
|
|
277
|
+
this.handlePluralKeys(finalKey, ns, options, isOrdinalByOption || isOrdinalByKey, finalDefaultValue, explicitPluralForVariants)
|
|
207
278
|
}
|
|
208
279
|
|
|
209
280
|
continue // This key is fully handled
|
|
@@ -229,7 +300,7 @@ export class CallExpressionHandler {
|
|
|
229
300
|
}
|
|
230
301
|
|
|
231
302
|
// 5. Default case: Add the simple key
|
|
232
|
-
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv })
|
|
303
|
+
this.pluginContext.addKey({ key: finalKey, ns, defaultValue: dv, explicitDefault: explicitDefaultForBase })
|
|
233
304
|
}
|
|
234
305
|
}
|
|
235
306
|
|
|
@@ -339,7 +410,7 @@ export class CallExpressionHandler {
|
|
|
339
410
|
* @param options - object expression options
|
|
340
411
|
* @param isOrdinal - isOrdinal flag
|
|
341
412
|
*/
|
|
342
|
-
private handlePluralKeys (key: string, ns: string | undefined, options: ObjectExpression, isOrdinal: boolean, defaultValueFromCall?: string): void {
|
|
413
|
+
private handlePluralKeys (key: string, ns: string | undefined, options: ObjectExpression, isOrdinal: boolean, defaultValueFromCall?: string, explicitDefaultFromSource?: boolean): void {
|
|
343
414
|
try {
|
|
344
415
|
const type = isOrdinal ? 'ordinal' : 'cardinal'
|
|
345
416
|
|
|
@@ -460,7 +531,12 @@ export class CallExpressionHandler {
|
|
|
460
531
|
ns,
|
|
461
532
|
defaultValue: finalDefaultValue,
|
|
462
533
|
hasCount: true,
|
|
463
|
-
isOrdinal
|
|
534
|
+
isOrdinal,
|
|
535
|
+
// Only treat plural/context variant as explicit when:
|
|
536
|
+
// - the extractor marked the source as explicitly providing plural defaults
|
|
537
|
+
// - OR a plural-specific default was provided in the options (specificDefault/otherDefault)
|
|
538
|
+
// Do NOT treat the presence of a general base defaultValueFromCall as making variants explicit.
|
|
539
|
+
explicitDefault: Boolean(explicitDefaultFromSource || typeof specificDefault === 'string' || typeof otherDefault === 'string')
|
|
464
540
|
})
|
|
465
541
|
}
|
|
466
542
|
}
|
|
@@ -70,6 +70,7 @@ export class JSXHandler {
|
|
|
70
70
|
defaultValue: defaultValue || serializedChildren,
|
|
71
71
|
hasCount,
|
|
72
72
|
isOrdinal,
|
|
73
|
+
explicitDefault: extractedAttributes.explicitDefault,
|
|
73
74
|
}
|
|
74
75
|
})
|
|
75
76
|
|
|
@@ -184,12 +185,12 @@ export class JSXHandler {
|
|
|
184
185
|
for (const context of contextValues) {
|
|
185
186
|
for (const extractedKey of extractedKeys) {
|
|
186
187
|
const contextKey = `${extractedKey.key}${contextSeparator}${context}`
|
|
187
|
-
this.generatePluralKeysForTrans(contextKey, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode)
|
|
188
|
+
this.generatePluralKeysForTrans(contextKey, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode, extractedKey.explicitDefault)
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
} else {
|
|
191
192
|
// Fallback to just plural forms if context resolution fails
|
|
192
|
-
extractedKeys.forEach(extractedKey => this.generatePluralKeysForTrans(extractedKey.key, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode))
|
|
193
|
+
extractedKeys.forEach(extractedKey => this.generatePluralKeysForTrans(extractedKey.key, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode, extractedKey.explicitDefault))
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
} else if (contextExpression) {
|
|
@@ -245,7 +246,7 @@ export class JSXHandler {
|
|
|
245
246
|
)
|
|
246
247
|
const isOrdinal = !!ordinalAttr
|
|
247
248
|
|
|
248
|
-
extractedKeys.forEach(extractedKey => this.generatePluralKeysForTrans(extractedKey.key, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode))
|
|
249
|
+
extractedKeys.forEach(extractedKey => this.generatePluralKeysForTrans(extractedKey.key, extractedKey.defaultValue, extractedKey.ns, isOrdinal, optionsNode, extractedKey.explicitDefault))
|
|
249
250
|
}
|
|
250
251
|
} else {
|
|
251
252
|
// No count or context - just add the base keys
|
|
@@ -270,7 +271,7 @@ export class JSXHandler {
|
|
|
270
271
|
* @param isOrdinal - Whether to generate ordinal plural forms
|
|
271
272
|
* @param optionsNode - Optional tOptions object expression for plural-specific defaults
|
|
272
273
|
*/
|
|
273
|
-
private generatePluralKeysForTrans (key: string, defaultValue: string | undefined, ns: string | undefined, isOrdinal: boolean, optionsNode?: ObjectExpression): void {
|
|
274
|
+
private generatePluralKeysForTrans (key: string, defaultValue: string | undefined, ns: string | undefined, isOrdinal: boolean, optionsNode?: ObjectExpression, explicitDefaultFromSource?: boolean): void {
|
|
274
275
|
try {
|
|
275
276
|
const type = isOrdinal ? 'ordinal' : 'cardinal'
|
|
276
277
|
const pluralCategories = new Intl.PluralRules(this.config.extract?.primaryLanguage, { type }).resolvedOptions().pluralCategories
|
|
@@ -321,7 +322,11 @@ export class JSXHandler {
|
|
|
321
322
|
ns,
|
|
322
323
|
defaultValue: finalDefaultValue,
|
|
323
324
|
hasCount: true,
|
|
324
|
-
isOrdinal
|
|
325
|
+
isOrdinal,
|
|
326
|
+
// Only treat plural/context variant as explicit when:
|
|
327
|
+
// - the extractor indicated the default was explicit on the source element
|
|
328
|
+
// - OR a plural-specific default was provided in tOptions (specificDefault/otherDefault)
|
|
329
|
+
explicitDefault: Boolean(explicitDefaultFromSource || typeof specificDefault === 'string' || typeof otherDefault === 'string')
|
|
325
330
|
})
|
|
326
331
|
}
|
|
327
332
|
} catch (e) {
|
|
@@ -26,6 +26,9 @@ export interface ExtractedJSXAttributes {
|
|
|
26
26
|
|
|
27
27
|
/** hold the raw context expression from the AST */
|
|
28
28
|
contextExpression?: Expression;
|
|
29
|
+
|
|
30
|
+
/** Whether the defaultValue was explicitly provided on the <Trans /> (defaults prop or tOptions defaultValue*) */
|
|
31
|
+
explicitDefault?: boolean;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
/**
|
|
@@ -224,6 +227,23 @@ export function extractFromTransComponent (node: JSXElement, config: I18nextTool
|
|
|
224
227
|
defaultValue = serialized
|
|
225
228
|
}
|
|
226
229
|
|
|
230
|
+
// Determine if tOptions contained explicit defaultValue* properties
|
|
231
|
+
const optionsHasDefaultProps = (opts?: ObjectExpression) => {
|
|
232
|
+
if (!opts || !Array.isArray((opts as any).properties)) return false
|
|
233
|
+
for (const p of (opts as any).properties) {
|
|
234
|
+
if (p && p.type === 'KeyValueProperty' && p.key) {
|
|
235
|
+
const keyName = (p.key.type === 'Identifier' && p.key.value) || (p.key.type === 'StringLiteral' && p.key.value)
|
|
236
|
+
if (typeof keyName === 'string' && keyName.startsWith('defaultValue')) return true
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return false
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const explicitDefault = Boolean(
|
|
243
|
+
(defaultsAttr && defaultsAttr.type === 'JSXAttribute' && defaultsAttr.value?.type === 'StringLiteral') ||
|
|
244
|
+
optionsHasDefaultProps(optionsNode)
|
|
245
|
+
)
|
|
246
|
+
|
|
227
247
|
return {
|
|
228
248
|
keyExpression,
|
|
229
249
|
serializedChildren: serialized,
|
|
@@ -233,6 +253,7 @@ export function extractFromTransComponent (node: JSXElement, config: I18nextTool
|
|
|
233
253
|
isOrdinal,
|
|
234
254
|
contextExpression,
|
|
235
255
|
optionsNode,
|
|
256
|
+
explicitDefault
|
|
236
257
|
}
|
|
237
258
|
}
|
|
238
259
|
|
|
@@ -439,7 +460,15 @@ function serializeJSXChildren (children: any[], config: I18nextToolkitConfig): s
|
|
|
439
460
|
? n.opening.name.value
|
|
440
461
|
: undefined
|
|
441
462
|
if (tagName && allowedTags.has(tagName)) {
|
|
442
|
-
// preserved
|
|
463
|
+
// Count preserved HTML element as a global slot only when the AST
|
|
464
|
+
// marks it self-closing (e.g. <br />). Self-closing preserved tags
|
|
465
|
+
// should influence placeholder indexes (they appear inline without
|
|
466
|
+
// children), while non-self-closing preserved tags (e.g. <strong>)
|
|
467
|
+
// should not.
|
|
468
|
+
const isAstSelfClosing = !!(n.opening && (n.opening as any).selfClosing)
|
|
469
|
+
if (isAstSelfClosing) {
|
|
470
|
+
slots.push(n)
|
|
471
|
+
}
|
|
443
472
|
collectSlots(n.children || [], slots, false)
|
|
444
473
|
} else {
|
|
445
474
|
// non-preserved element: the element itself is a single slot.
|
|
@@ -469,12 +498,20 @@ function serializeJSXChildren (children: any[], config: I18nextToolkitConfig): s
|
|
|
469
498
|
function visitNodes (nodes: any[]): string {
|
|
470
499
|
if (!nodes || nodes.length === 0) return ''
|
|
471
500
|
let out = ''
|
|
501
|
+
let lastWasSelfClosing = false
|
|
472
502
|
|
|
473
|
-
for (
|
|
503
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
504
|
+
const node = nodes[i]
|
|
474
505
|
if (!node) continue
|
|
475
506
|
|
|
476
507
|
if (node.type === 'JSXText') {
|
|
477
|
-
if (
|
|
508
|
+
if (isFormattingWhitespace(node)) continue
|
|
509
|
+
if (lastWasSelfClosing) {
|
|
510
|
+
out += node.value.replace(/^\s+/, '')
|
|
511
|
+
lastWasSelfClosing = false
|
|
512
|
+
} else {
|
|
513
|
+
out += node.value
|
|
514
|
+
}
|
|
478
515
|
continue
|
|
479
516
|
}
|
|
480
517
|
|
|
@@ -502,6 +539,7 @@ function serializeJSXChildren (children: any[], config: I18nextToolkitConfig): s
|
|
|
502
539
|
} else {
|
|
503
540
|
out += '{{value}}'
|
|
504
541
|
}
|
|
542
|
+
lastWasSelfClosing = false
|
|
505
543
|
continue
|
|
506
544
|
}
|
|
507
545
|
|
|
@@ -513,19 +551,38 @@ function serializeJSXChildren (children: any[], config: I18nextToolkitConfig): s
|
|
|
513
551
|
|
|
514
552
|
if (tag && allowedTags.has(tag)) {
|
|
515
553
|
const inner = visitNodes(node.children || [])
|
|
516
|
-
|
|
554
|
+
// consider element self-closing for rendering when AST marks it so or it has no meaningful children
|
|
555
|
+
const isAstSelfClosing = !!(node.opening && (node.opening as any).selfClosing)
|
|
556
|
+
const hasMeaningfulChildren = String(inner).trim() !== ''
|
|
557
|
+
if (isAstSelfClosing || !hasMeaningfulChildren) {
|
|
558
|
+
// If the previous original sibling is a JSXText that ends with a
|
|
559
|
+
// newline (the tag was placed on its own indented line), trim any
|
|
560
|
+
// trailing space we've accumulated so we don't leave " ... . <br/>".
|
|
561
|
+
// This targeted trimming avoids breaking other spacing-sensitive cases.
|
|
562
|
+
const prevOriginal = nodes[i - 1]
|
|
563
|
+
if (prevOriginal && prevOriginal.type === 'JSXText' && /\n\s*$/.test(prevOriginal.value)) {
|
|
564
|
+
out = out.replace(/\s+$/, '')
|
|
565
|
+
}
|
|
566
|
+
out += `<${tag}/>`
|
|
567
|
+
lastWasSelfClosing = true
|
|
568
|
+
} else {
|
|
569
|
+
out += `<${tag}>${inner}</${tag}>`
|
|
570
|
+
lastWasSelfClosing = false
|
|
571
|
+
}
|
|
517
572
|
} else {
|
|
518
573
|
// Use the pre-order globalSlots index so placeholder numbers reflect
|
|
519
574
|
// the global ordering (including nested slots collected earlier).
|
|
520
575
|
const idx = globalSlots.indexOf(node)
|
|
521
576
|
const inner = visitNodes(node.children || [])
|
|
522
577
|
out += `<${idx}>${inner}</${idx}>`
|
|
578
|
+
lastWasSelfClosing = false
|
|
523
579
|
}
|
|
524
580
|
continue
|
|
525
581
|
}
|
|
526
582
|
|
|
527
583
|
if (node.type === 'JSXFragment') {
|
|
528
584
|
out += visitNodes(node.children || [])
|
|
585
|
+
lastWasSelfClosing = false
|
|
529
586
|
continue
|
|
530
587
|
}
|
|
531
588
|
|
package/src/types.ts
CHANGED
|
@@ -306,6 +306,9 @@ export interface ExtractedKey {
|
|
|
306
306
|
|
|
307
307
|
/** hold the raw context expression from the AST */
|
|
308
308
|
contextExpression?: Expression;
|
|
309
|
+
|
|
310
|
+
/** Whether the defaultValue was explicitly provided in source code (vs derived from children/key) */
|
|
311
|
+
explicitDefault?: boolean;
|
|
309
312
|
}
|
|
310
313
|
|
|
311
314
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"translation-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/translation-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA2UnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,oBAAoB,EAC5B,EAAE,uBAA+B,EAAE,GAAE;IAAE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9E,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA8E9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,aAAa,CAAA;AACvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAG1D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;gBAGnC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB;IAQxC;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"call-expression-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/call-expression-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAgB,SAAS,EAAE,MAAM,aAAa,CAAA;AACvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAG1D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,kBAAkB,CAAoB;IACvC,UAAU,cAAoB;gBAGnC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB;IAQxC;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI;IA4QxG;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IA8BpC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,sBAAsB;IA2C9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IA0IxB;;;;;;;;;OASG;IACH,OAAO,CAAC,eAAe;CA2BxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,WAAW,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,aAAa,CAAA;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAI1D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;gBAG5C,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB;IAOxC;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"jsx-handler.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,WAAW,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAgB,MAAM,aAAa,CAAA;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAI1D,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAoB;gBAG5C,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,kBAAkB,EAAE,kBAAkB;IAOxC;;;;;;;;OAQG;IACH,gBAAgB,CAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IA0OjI;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B;IAgElC;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;CAevB"}
|
|
@@ -17,6 +17,8 @@ export interface ExtractedJSXAttributes {
|
|
|
17
17
|
optionsNode?: ObjectExpression;
|
|
18
18
|
/** hold the raw context expression from the AST */
|
|
19
19
|
contextExpression?: Expression;
|
|
20
|
+
/** Whether the defaultValue was explicitly provided on the <Trans /> (defaults prop or tOptions defaultValue*) */
|
|
21
|
+
explicitDefault?: boolean;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
24
|
* Extracts translation keys from JSX Trans components.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAY,MAAM,WAAW,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGvD,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAE/B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"jsx-parser.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/jsx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAY,MAAM,WAAW,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGvD,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,aAAa,CAAC,EAAE,UAAU,CAAC;IAE3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAE/B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAE/B,kHAAkH;IAClH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,yBAAyB,CAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,IAAI,CAgMxH"}
|
package/types/types.d.ts
CHANGED
|
@@ -251,6 +251,8 @@ export interface ExtractedKey {
|
|
|
251
251
|
optionsNode?: ObjectExpression;
|
|
252
252
|
/** hold the raw context expression from the AST */
|
|
253
253
|
contextExpression?: Expression;
|
|
254
|
+
/** Whether the defaultValue was explicitly provided in source code (vs derived from children/key) */
|
|
255
|
+
explicitDefault?: boolean;
|
|
254
256
|
}
|
|
255
257
|
/**
|
|
256
258
|
* Result of processing translation files for a specific locale and namespace.
|
package/types/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|