ai-l10n-sdk 1.1.3 → 1.2.0
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/README.md +32 -0
- package/dist/i18nProjectManager.d.ts +1 -0
- package/dist/i18nProjectManager.js +25 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,6 +94,38 @@ const result = await translator.translate({
|
|
|
94
94
|
- **Automatic Metadata Updates**: The API automatically updates `@@locale` to the target language code and `@@last_modified` to the current UTC timestamp
|
|
95
95
|
- **Custom Prefixes**: Supports custom file naming patterns (e.g., `app_en_US.arb`, `my_app_fr.arb`)
|
|
96
96
|
|
|
97
|
+
### JSONC Files
|
|
98
|
+
|
|
99
|
+
Full support for JSONC (JSON with Comments) files:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const result = await translator.translate({
|
|
103
|
+
sourceFile: './locales/en.jsonc',
|
|
104
|
+
targetLanguages: ['es', 'fr', 'de']
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**JSONC Features:**
|
|
109
|
+
- Works exactly like JSON files but with `.jsonc` extension
|
|
110
|
+
- Auto-detects `.jsonc` files in project structure alongside `.json` files
|
|
111
|
+
|
|
112
|
+
### Shopify Theme Localization
|
|
113
|
+
|
|
114
|
+
Full support for Shopify theme localization file patterns:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const result = await translator.translate({
|
|
118
|
+
sourceFile: './locales/en.default.schema.json',
|
|
119
|
+
targetLanguages: ['es-ES', 'fr', 'de']
|
|
120
|
+
});
|
|
121
|
+
// Creates: es-ES.schema.json, fr.schema.json, de.schema.json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Shopify Theme Features:**
|
|
125
|
+
- **Automatic Pattern Recognition**: Detects files with `.default.` in the name (e.g., `en.default.schema.json`)
|
|
126
|
+
- **Smart Output Naming**: Removes `.default.` from target files while preserving the `.schema.` suffix
|
|
127
|
+
- **Language Detection**: Auto-detects target languages from existing files (e.g., `es-ES.schema.json`, `fr.schema.json`)
|
|
128
|
+
|
|
97
129
|
### Multiple Files
|
|
98
130
|
|
|
99
131
|
```typescript
|
|
@@ -14,6 +14,7 @@ export declare class I18nProjectManager {
|
|
|
14
14
|
* Extracts language code from file name, handling custom prefixes for ARB files
|
|
15
15
|
* ARB files: app_en_US.arb -> en_US, my_app_fr.arb -> fr
|
|
16
16
|
* JSON files: en-US.json -> en-US
|
|
17
|
+
* Shopify theme: en.default.schema.json -> en, es-ES.schema.json -> es-ES
|
|
17
18
|
*/
|
|
18
19
|
private extractLanguageCodeFromFileName;
|
|
19
20
|
}
|
|
@@ -80,17 +80,22 @@ class I18nProjectManager {
|
|
|
80
80
|
}
|
|
81
81
|
else if (structureInfo.type === ProjectStructureType.FileBased) {
|
|
82
82
|
// For file-based, scan the base path for language files
|
|
83
|
-
const
|
|
83
|
+
const fileExtensions = isArbFile ? [".arb"] : [".json", ".jsonc"];
|
|
84
84
|
try {
|
|
85
85
|
const entries = fs.readdirSync(structureInfo.basePath, {
|
|
86
86
|
withFileTypes: true,
|
|
87
87
|
});
|
|
88
88
|
for (const entry of entries) {
|
|
89
|
-
if (entry.isFile()
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
if (entry.isFile()) {
|
|
90
|
+
for (const ext of fileExtensions) {
|
|
91
|
+
if (entry.name.endsWith(ext)) {
|
|
92
|
+
const fileName = path.basename(entry.name, ext);
|
|
93
|
+
const languageCode = this.extractLanguageCodeFromFileName(fileName, isArbFile);
|
|
94
|
+
if (languageCode) {
|
|
95
|
+
languageCodes.add(languageCode);
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
}
|
|
@@ -141,8 +146,12 @@ class I18nProjectManager {
|
|
|
141
146
|
return targetFilePath;
|
|
142
147
|
}
|
|
143
148
|
else {
|
|
149
|
+
// Handle Shopify theme pattern: en.default.schema.json -> es-ES.schema.json
|
|
150
|
+
// Extract suffix (e.g., ".schema") if present
|
|
151
|
+
const schemaMatch = sourceFileName.match(/\.(schema)$/);
|
|
152
|
+
const suffix = schemaMatch ? `.${schemaMatch[1]}` : "";
|
|
144
153
|
// Save in the same directory with target language as filename
|
|
145
|
-
const targetFilePath = path.join(structureInfo.basePath, `${languageCode}${fileExtension}`);
|
|
154
|
+
const targetFilePath = path.join(structureInfo.basePath, `${languageCode}${suffix}${fileExtension}`);
|
|
146
155
|
return targetFilePath;
|
|
147
156
|
}
|
|
148
157
|
}
|
|
@@ -226,6 +235,7 @@ class I18nProjectManager {
|
|
|
226
235
|
* Extracts language code from file name, handling custom prefixes for ARB files
|
|
227
236
|
* ARB files: app_en_US.arb -> en_US, my_app_fr.arb -> fr
|
|
228
237
|
* JSON files: en-US.json -> en-US
|
|
238
|
+
* Shopify theme: en.default.schema.json -> en, es-ES.schema.json -> es-ES
|
|
229
239
|
*/
|
|
230
240
|
extractLanguageCodeFromFileName(fileName, isArbFile) {
|
|
231
241
|
if (isArbFile) {
|
|
@@ -242,8 +252,15 @@ class I18nProjectManager {
|
|
|
242
252
|
return null;
|
|
243
253
|
}
|
|
244
254
|
else {
|
|
255
|
+
// Handle Shopify theme pattern: en.default.schema, es-ES.schema
|
|
256
|
+
// Remove .schema first, then .default before extracting language code
|
|
257
|
+
let cleanedFileName = fileName
|
|
258
|
+
.replace(/\.schema$/, "")
|
|
259
|
+
.replace(/\.default$/, "");
|
|
245
260
|
// For JSON files, the entire filename should be the language code
|
|
246
|
-
return this.languageCodeRegex.test(
|
|
261
|
+
return this.languageCodeRegex.test(cleanedFileName)
|
|
262
|
+
? cleanedFileName
|
|
263
|
+
: null;
|
|
247
264
|
}
|
|
248
265
|
}
|
|
249
266
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -70,9 +70,9 @@ class AiTranslator {
|
|
|
70
70
|
}
|
|
71
71
|
const fileExtension = path.extname(sourceFilePath);
|
|
72
72
|
const isArbFile = fileExtension === ".arb";
|
|
73
|
-
const isJsonFile = fileExtension === ".json";
|
|
73
|
+
const isJsonFile = fileExtension === ".json" || fileExtension === ".jsonc";
|
|
74
74
|
if (!isArbFile && !isJsonFile) {
|
|
75
|
-
throw new Error(`Unsupported file type: ${fileExtension}. Only .json and .arb files are supported.`);
|
|
75
|
+
throw new Error(`Unsupported file type: ${fileExtension}. Only .json, .jsonc, and .arb files are supported.`);
|
|
76
76
|
}
|
|
77
77
|
if (verbose) {
|
|
78
78
|
console.log(`📂 Source file: ${sourceFilePath}`);
|
|
@@ -140,6 +140,7 @@ class AiTranslator {
|
|
|
140
140
|
for (const result of results) {
|
|
141
141
|
totalCharsUsed += result.charsUsed || 0;
|
|
142
142
|
if (result.remainingBalance !== undefined &&
|
|
143
|
+
result.remainingBalance !== null &&
|
|
143
144
|
result.remainingBalance < (remainingBalance ?? Infinity)) {
|
|
144
145
|
remainingBalance = result.remainingBalance;
|
|
145
146
|
}
|
|
@@ -151,7 +152,7 @@ class AiTranslator {
|
|
|
151
152
|
console.log(`${"=".repeat(50)}`);
|
|
152
153
|
console.log(`✅ Successful: ${successCount}/${targetLanguages.length}`);
|
|
153
154
|
console.log(`📝 Total characters used: ${totalCharsUsed.toLocaleString()}`);
|
|
154
|
-
if (remainingBalance !== undefined) {
|
|
155
|
+
if (remainingBalance !== undefined && remainingBalance !== null) {
|
|
155
156
|
console.log(`💰 Remaining balance: ${remainingBalance.toLocaleString()} characters`);
|
|
156
157
|
}
|
|
157
158
|
if (successCount < targetLanguages.length) {
|