From 2cba018779f132ea0473d204f28ab847e3554d92 Mon Sep 17 00:00:00 2001 From: wa Date: Tue, 26 May 2026 14:24:50 +0500 Subject: [PATCH 1/3] fix(cli): improve locale list parsing in init command --- .changeset/config.json | 23 ++++++++------ .changeset/wicked-baboons-bake.md | 5 +++ .../public/translations/de.json | 26 ++++++++-------- .../public/translations/es.json | 26 ++++++++-------- .../public/translations/fr.json | 26 ++++++++-------- packages/cli/src/cli/cmd/init.ts | 31 ++++++++++++------- 6 files changed, 77 insertions(+), 60 deletions(-) create mode 100644 .changeset/wicked-baboons-bake.md diff --git a/.changeset/config.json b/.changeset/config.json index 500af1667..68200943a 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,10 +1,15 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "lingodotdev/lingo.dev" }], - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch" -} + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": [ + "@changesets/changelog-github", + { + "repo": "lingodotdev/lingo.dev" + } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch" +} \ No newline at end of file diff --git a/.changeset/wicked-baboons-bake.md b/.changeset/wicked-baboons-bake.md new file mode 100644 index 000000000..576f8d42e --- /dev/null +++ b/.changeset/wicked-baboons-bake.md @@ -0,0 +1,5 @@ +--- +"lingo.dev": patch +--- + +Fix parsing of comma-separated locale inputs with spaces and quotes during init diff --git a/demo/new-compiler-vite-react-spa/public/translations/de.json b/demo/new-compiler-vite-react-spa/public/translations/de.json index fc47c06b9..7de6ecef2 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/de.json +++ b/demo/new-compiler-vite-react-spa/public/translations/de.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "de", "entries": { + "02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.", + "07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!", + "0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.", + "2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen", + "44a3311c3a4a": "Wie es funktioniert", + "52ed9ee761d8": "Hallo Welt", + "556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo", + "5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen", "8492c53cfbaf": "Über Lingo.dev", "8aa4fe3f0590": "Dies ist eine Demo-Anwendung, die den Lingo.dev-Compiler für automatische Übersetzungen in React-Anwendungen präsentiert.", - "af76f667703b": "Hauptfunktionen", + "93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}", "999a96fc5866": "Automatische Extraktion übersetzbarer Texte aus JSX", - "b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead", "ab0450919701": "Unterstützung für mehrere Bundler (Vite, Webpack, Next.js)", - "2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen", "aca12d550fe2": "Unterstützung für Server- und Client-Komponenten", - "44a3311c3a4a": "Wie es funktioniert", - "0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.", - "07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!", + "af76f667703b": "Hauptfunktionen", + "b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead", + "d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}", "daa4d8839395": "{counter} mal geklickt", - "52ed9ee761d8": "Hallo Welt", - "f11fc78c3ac0": "Gemischter Inhalt Fragment", - "556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo", - "02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.", "de6bfb30be49": "Text, der als eingefügt wird, wird nicht übersetzt: {text}", - "5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen", - "93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}", - "d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}" + "f11fc78c3ac0": "Gemischter Inhalt Fragment" } } \ No newline at end of file diff --git a/demo/new-compiler-vite-react-spa/public/translations/es.json b/demo/new-compiler-vite-react-spa/public/translations/es.json index 29955df4a..9c0aba939 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/es.json +++ b/demo/new-compiler-vite-react-spa/public/translations/es.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "es", "entries": { + "02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.", + "07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!", + "0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.", + "2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables", + "44a3311c3a4a": "Cómo funciona", + "52ed9ee761d8": "Hola Mundo", + "556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler", + "5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>", "8492c53cfbaf": "Acerca de Lingo.dev", "8aa4fe3f0590": "Esta es una aplicación de demostración que muestra el compilador Lingo.dev para traducciones automáticas en aplicaciones React.", - "af76f667703b": "Características principales", + "93b50fe805b7": "El texto externo al componente no se traduce: {externalText}", "999a96fc5866": "Extracción automática de texto traducible desde JSX", - "b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución", "ab0450919701": "Soporte para múltiples empaquetadores (Vite, Webpack, Next.js)", - "2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables", "aca12d550fe2": "Soporte para componentes de servidor y cliente", - "44a3311c3a4a": "Cómo funciona", - "0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.", - "07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!", + "af76f667703b": "Características principales", + "b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución", + "d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}", "daa4d8839395": "Clicado {counter} veces", - "52ed9ee761d8": "Hola Mundo", - "f11fc78c3ac0": "Contenido mixto fragmento", - "556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler", - "02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.", "de6bfb30be49": "El texto insertado como no se traduce: {text}", - "5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>", - "93b50fe805b7": "El texto externo al componente no se traduce: {externalText}", - "d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}" + "f11fc78c3ac0": "Contenido mixto fragmento" } } \ No newline at end of file diff --git a/demo/new-compiler-vite-react-spa/public/translations/fr.json b/demo/new-compiler-vite-react-spa/public/translations/fr.json index e36029ade..b394cf246 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/fr.json +++ b/demo/new-compiler-vite-react-spa/public/translations/fr.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "fr", "entries": { + "02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.", + "07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !", + "0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.", + "2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables", + "44a3311c3a4a": "Comment ça fonctionne", + "52ed9ee761d8": "Bonjour le monde", + "556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev", + "5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>", "8492c53cfbaf": "À propos de Lingo.dev", "8aa4fe3f0590": "Ceci est une application de démonstration présentant le compilateur Lingo.dev pour les traductions automatiques dans les applications React.", - "af76f667703b": "Fonctionnalités clés", + "93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}", "999a96fc5866": "Extraction automatique du texte traduisible à partir de JSX", - "b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution", "ab0450919701": "Prise en charge de plusieurs bundlers (Vite, Webpack, Next.js)", - "2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables", "aca12d550fe2": "Prise en charge des composants serveur et client", - "44a3311c3a4a": "Comment ça fonctionne", - "0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.", - "07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !", + "af76f667703b": "Fonctionnalités clés", + "b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution", + "d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}", "daa4d8839395": "Cliqué {counter} fois", - "52ed9ee761d8": "Bonjour le monde", - "f11fc78c3ac0": "Contenu mixte fragment", - "556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev", - "02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.", "de6bfb30be49": "Le texte inséré comme un n'est pas traduit : {text}", - "5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>", - "93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}", - "d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}" + "f11fc78c3ac0": "Contenu mixte fragment" } } \ No newline at end of file diff --git a/packages/cli/src/cli/cmd/init.ts b/packages/cli/src/cli/cmd/init.ts index 6ce9c8924..1458bf237 100644 --- a/packages/cli/src/cli/cmd/init.ts +++ b/packages/cli/src/cli/cmd/init.ts @@ -30,11 +30,25 @@ const throwHelpError = (option: string, value: string) => { if (value === "help") { openUrl("/go/call"); } + + // Better error message for invalid locale or bucket format inputs, with instructions to get help for supported formats throw new Error( - `Invalid ${option}: ${value}\n\nDo you need support for ${value} ${option}? Type "help" and we will.`, + `Invalid ${option}: "${value}".\n\n` + + `Accepted formats:\n` + + ` es,fr\n` + + ` es fr\n` + + ` 'es', 'fr'\n\n` + + `If you need support for "${value}" ${option}, type "help" and we will.`, ); }; +// Parses comma or space separated list of values, removing extra whitespace and quotes +const parseListInput = (value: string): string[] => + value + .split(/[,\s]+/) + .map((v) => v.trim().replace(/^['"]|['"]$/g, "")) + .filter(Boolean); + export default new InteractiveCommand() .command("init") .description("Create i18n.json configuration file for a new project") @@ -67,10 +81,8 @@ export default new InteractiveCommand() "-t --targets ", "Target languages to translate to. Accepts locale codes like 'es', 'fr', 'de-AT' separated by commas or spaces. Defaults to 'es'", ) - .argParser((value) => { - const values = ( - value.includes(",") ? value.split(",") : value.split(" ") - ) as LocaleCode[]; + .argParser((value: string) => { + const values = parseListInput(value) as LocaleCode[]; values.forEach((value) => { try { resolveLocaleCode(value); @@ -102,9 +114,7 @@ export default new InteractiveCommand() ) .argParser((value) => { if (!value || value.length === 0) return []; - const values = value.includes(",") - ? value.split(",") - : value.split(" "); + const values = parseListInput(value); for (const p of values) { try { @@ -118,7 +128,6 @@ export default new InteractiveCommand() } } return values; - }) .prompt(undefined) // make non-interactive .default([]), @@ -191,9 +200,7 @@ export default new InteractiveCommand() const customPaths = await input({ message: "Enter paths to use", }); - selectedPatterns = customPaths.includes(",") - ? customPaths.split(",") - : customPaths.split(" "); + selectedPatterns = parseListInput(customPaths); } newConfig.buckets = { From e7b997d4c38e1f167a9a734fbbd2d9757d36ae19 Mon Sep 17 00:00:00 2001 From: wa Date: Thu, 28 May 2026 10:12:02 +0500 Subject: [PATCH 2/3] chore(i18n): remove unnecessary locale file reordering --- .../public/translations/de.json | 26 +++++++++---------- .../public/translations/es.json | 26 +++++++++---------- .../public/translations/fr.json | 26 +++++++++---------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/demo/new-compiler-vite-react-spa/public/translations/de.json b/demo/new-compiler-vite-react-spa/public/translations/de.json index 7de6ecef2..fc47c06b9 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/de.json +++ b/demo/new-compiler-vite-react-spa/public/translations/de.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "de", "entries": { - "02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.", - "07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!", - "0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.", - "2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen", - "44a3311c3a4a": "Wie es funktioniert", - "52ed9ee761d8": "Hallo Welt", - "556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo", - "5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen", "8492c53cfbaf": "Über Lingo.dev", "8aa4fe3f0590": "Dies ist eine Demo-Anwendung, die den Lingo.dev-Compiler für automatische Übersetzungen in React-Anwendungen präsentiert.", - "93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}", + "af76f667703b": "Hauptfunktionen", "999a96fc5866": "Automatische Extraktion übersetzbarer Texte aus JSX", + "b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead", "ab0450919701": "Unterstützung für mehrere Bundler (Vite, Webpack, Next.js)", + "2d626508fb8f": "Hash-basiertes Übersetzungssystem für stabile Kennungen", "aca12d550fe2": "Unterstützung für Server- und Client-Komponenten", - "af76f667703b": "Hauptfunktionen", - "b285bf7876d3": "Build-Zeit-Transformation ohne Laufzeit-Overhead", - "d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}", + "44a3311c3a4a": "Wie es funktioniert", + "0add30e37450": "Der Compiler analysiert Ihre React-Komponenten zur Build-Zeit und extrahiert automatisch alle übersetzbaren Strings. Anschließend generiert er Übersetzungen mit Ihrem konfigurierten Übersetzungsanbieter.", + "07d84d34dd3a": "Fügen Sie einfach die Direktive \"use i18n\" am Anfang Ihrer Komponentendateien hinzu, und der Compiler erledigt den Rest!", "daa4d8839395": "{counter} mal geklickt", + "52ed9ee761d8": "Hallo Welt", + "f11fc78c3ac0": "Gemischter Inhalt Fragment", + "556f5956dca7": "Willkommen zur Lingo.dev Compiler Demo", + "02704ec4e52a": "Es extrahiert automatisch Text aus Ihrem JSX und übersetzt ihn in andere Sprachen.", "de6bfb30be49": "Text, der als eingefügt wird, wird nicht übersetzt: {text}", - "f11fc78c3ac0": "Gemischter Inhalt Fragment" + "5c15bd35e916": "Um es zu übersetzen, müssen Sie es in '<'>{translatableText} '<'/> einschließen", + "93b50fe805b7": "Text außerhalb der Komponente wird nicht übersetzt: {externalText}", + "d756b03ffbf5": "Inhalte, die Text und andere Tags enthalten, werden als eine Einheit übersetzt: {translatableMixedContextFragment}" } } \ No newline at end of file diff --git a/demo/new-compiler-vite-react-spa/public/translations/es.json b/demo/new-compiler-vite-react-spa/public/translations/es.json index 9c0aba939..29955df4a 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/es.json +++ b/demo/new-compiler-vite-react-spa/public/translations/es.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "es", "entries": { - "02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.", - "07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!", - "0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.", - "2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables", - "44a3311c3a4a": "Cómo funciona", - "52ed9ee761d8": "Hola Mundo", - "556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler", - "5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>", "8492c53cfbaf": "Acerca de Lingo.dev", "8aa4fe3f0590": "Esta es una aplicación de demostración que muestra el compilador Lingo.dev para traducciones automáticas en aplicaciones React.", - "93b50fe805b7": "El texto externo al componente no se traduce: {externalText}", + "af76f667703b": "Características principales", "999a96fc5866": "Extracción automática de texto traducible desde JSX", + "b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución", "ab0450919701": "Soporte para múltiples empaquetadores (Vite, Webpack, Next.js)", + "2d626508fb8f": "Sistema de traducción basado en hash para identificadores estables", "aca12d550fe2": "Soporte para componentes de servidor y cliente", - "af76f667703b": "Características principales", - "b285bf7876d3": "Transformación en tiempo de compilación sin sobrecarga en tiempo de ejecución", - "d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}", + "44a3311c3a4a": "Cómo funciona", + "0add30e37450": "El compilador analiza tus componentes de React en tiempo de compilación y extrae automáticamente todas las cadenas traducibles. Luego genera traducciones utilizando tu proveedor de traducción configurado.", + "07d84d34dd3a": "¡Simplemente agrega la directiva \"use i18n\" en la parte superior de tus archivos de componentes, y el compilador se encarga del resto!", "daa4d8839395": "Clicado {counter} veces", + "52ed9ee761d8": "Hola Mundo", + "f11fc78c3ac0": "Contenido mixto fragmento", + "556f5956dca7": "Bienvenido a la demo de Lingo.dev compiler", + "02704ec4e52a": "Extrae automáticamente texto de tu JSX y lo traduce a otros idiomas.", "de6bfb30be49": "El texto insertado como no se traduce: {text}", - "f11fc78c3ac0": "Contenido mixto fragmento" + "5c15bd35e916": "Para traducirlo tienes que envolverlo en el '<'>{translatableText} '<'/>", + "93b50fe805b7": "El texto externo al componente no se traduce: {externalText}", + "d756b03ffbf5": "El contenido que tiene texto y otras etiquetas dentro se traducirá como una sola entidad: {translatableMixedContextFragment}" } } \ No newline at end of file diff --git a/demo/new-compiler-vite-react-spa/public/translations/fr.json b/demo/new-compiler-vite-react-spa/public/translations/fr.json index b394cf246..e36029ade 100644 --- a/demo/new-compiler-vite-react-spa/public/translations/fr.json +++ b/demo/new-compiler-vite-react-spa/public/translations/fr.json @@ -2,25 +2,25 @@ "version": 0.1, "locale": "fr", "entries": { - "02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.", - "07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !", - "0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.", - "2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables", - "44a3311c3a4a": "Comment ça fonctionne", - "52ed9ee761d8": "Bonjour le monde", - "556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev", - "5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>", "8492c53cfbaf": "À propos de Lingo.dev", "8aa4fe3f0590": "Ceci est une application de démonstration présentant le compilateur Lingo.dev pour les traductions automatiques dans les applications React.", - "93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}", + "af76f667703b": "Fonctionnalités clés", "999a96fc5866": "Extraction automatique du texte traduisible à partir de JSX", + "b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution", "ab0450919701": "Prise en charge de plusieurs bundlers (Vite, Webpack, Next.js)", + "2d626508fb8f": "Système de traduction basé sur des hachages pour des identifiants stables", "aca12d550fe2": "Prise en charge des composants serveur et client", - "af76f667703b": "Fonctionnalités clés", - "b285bf7876d3": "Transformation au moment de la compilation sans surcharge d'exécution", - "d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}", + "44a3311c3a4a": "Comment ça fonctionne", + "0add30e37450": "Le compilateur analyse vos composants React au moment de la compilation et extrait automatiquement toutes les chaînes traduisibles. Il génère ensuite des traductions en utilisant votre fournisseur de traduction configuré.", + "07d84d34dd3a": "Ajoutez simplement la directive \"use i18n\" en haut de vos fichiers de composants, et le compilateur s'occupe du reste !", "daa4d8839395": "Cliqué {counter} fois", + "52ed9ee761d8": "Bonjour le monde", + "f11fc78c3ac0": "Contenu mixte fragment", + "556f5956dca7": "Bienvenue dans la démo du compilateur Lingo.dev", + "02704ec4e52a": "Il extrait automatiquement le texte de votre JSX et le traduit dans d'autres langues.", "de6bfb30be49": "Le texte inséré comme un n'est pas traduit : {text}", - "f11fc78c3ac0": "Contenu mixte fragment" + "5c15bd35e916": "Pour le traduire, vous devez l'envelopper dans le '<'>{translatableText} '<'/>", + "93b50fe805b7": "Le texte externe au composant n'est pas traduit : {externalText}", + "d756b03ffbf5": "Le contenu qui contient du texte et d'autres balises sera traduit comme une seule entité : {translatableMixedContextFragment}" } } \ No newline at end of file From 1bf89145fade02ee6553c79f7aaa1aa27164adf1 Mon Sep 17 00:00:00 2001 From: wa Date: Fri, 29 May 2026 09:23:28 +0500 Subject: [PATCH 3/3] feat(cli): export parseListInput function, remove trim(), add unit tests --- .changeset/config.json | 23 +++++------ packages/cli/src/cli/cmd/init.ts | 4 +- .../cli/src/cli/cmd/parseListInput.spec.ts | 40 +++++++++++++++++++ 3 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 packages/cli/src/cli/cmd/parseListInput.spec.ts diff --git a/.changeset/config.json b/.changeset/config.json index 68200943a..500af1667 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,15 +1,10 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": [ - "@changesets/changelog-github", - { - "repo": "lingodotdev/lingo.dev" - } - ], - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch" -} \ No newline at end of file + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "lingodotdev/lingo.dev" }], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch" +} diff --git a/packages/cli/src/cli/cmd/init.ts b/packages/cli/src/cli/cmd/init.ts index 1458bf237..1ecc09422 100644 --- a/packages/cli/src/cli/cmd/init.ts +++ b/packages/cli/src/cli/cmd/init.ts @@ -43,10 +43,10 @@ const throwHelpError = (option: string, value: string) => { }; // Parses comma or space separated list of values, removing extra whitespace and quotes -const parseListInput = (value: string): string[] => +export const parseListInput = (value: string): string[] => value .split(/[,\s]+/) - .map((v) => v.trim().replace(/^['"]|['"]$/g, "")) + .map((v) => v.replace(/^['"]|['"]$/g, "")) .filter(Boolean); export default new InteractiveCommand() diff --git a/packages/cli/src/cli/cmd/parseListInput.spec.ts b/packages/cli/src/cli/cmd/parseListInput.spec.ts new file mode 100644 index 000000000..f29983d59 --- /dev/null +++ b/packages/cli/src/cli/cmd/parseListInput.spec.ts @@ -0,0 +1,40 @@ +import { describe, it, expect } from "vitest"; +import { parseListInput } from "./init"; + +describe("parseListInput", () => { + it("parses comma-separated values", () => { + expect(parseListInput("es,fr")).toEqual(["es", "fr"]); + }); + + it("parses comma-separated values with whitespace", () => { + expect(parseListInput("es, fr")).toEqual(["es", "fr"]); + }); + + it("parses space-separated values", () => { + expect(parseListInput("es fr")).toEqual(["es", "fr"]); + }); + + it("parses single-quoted values", () => { + expect(parseListInput("'es', 'fr'")).toEqual(["es", "fr"]); + }); + + it("parses double-quoted values", () => { + expect(parseListInput('"es", "fr"')).toEqual(["es", "fr"]); + }); + + it("returns empty array for empty input", () => { + expect(parseListInput("")).toEqual([]); + }); + + it("returns empty array for whitespace-only input", () => { + expect(parseListInput(" ")).toEqual([]); + }); + + it("filters duplicate separators", () => { + expect(parseListInput("es,,fr")).toEqual(["es", "fr"]); + }); + + it("parses outer-quoted comma-separated lists", () => { + expect(parseListInput("'es,fr'")).toEqual(["es", "fr"]); + }); +});