gtx-cli 1.0.3-alpha.1 → 1.1.0-alpha.1
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/dist/api/checkFileTranslations.d.ts +16 -0
- package/dist/api/checkFileTranslations.js +167 -0
- package/dist/api/downloadFile.d.ts +1 -0
- package/dist/api/downloadFile.js +75 -0
- package/dist/api/sendFiles.d.ts +22 -0
- package/dist/api/sendFiles.js +69 -0
- package/dist/api/sendUpdates.js +1 -1
- package/dist/cli/base.d.ts +2 -1
- package/dist/cli/base.js +60 -37
- package/dist/cli/next.d.ts +0 -3
- package/dist/cli/next.js +0 -4
- package/dist/cli/react.d.ts +3 -5
- package/dist/cli/react.js +74 -44
- package/dist/config/generateSettings.js +3 -1
- package/dist/console/errors.d.ts +3 -3
- package/dist/console/errors.js +4 -4
- package/dist/formats/files/save.d.ts +5 -0
- package/dist/formats/files/save.js +33 -0
- package/dist/formats/files/translate.d.ts +9 -0
- package/dist/formats/files/translate.js +75 -0
- package/dist/formats/gt/save.d.ts +2 -1
- package/dist/formats/gt/save.js +9 -2
- package/dist/formats/json/save.d.ts +6 -5
- package/dist/formats/json/save.js +13 -7
- package/dist/formats/json/translate.d.ts +3 -2
- package/dist/formats/json/translate.js +3 -13
- package/dist/fs/config/parseFilesConfig.d.ts +22 -0
- package/dist/fs/config/parseFilesConfig.js +137 -0
- package/dist/fs/config/setupConfig.d.ts +2 -1
- package/dist/fs/config/setupConfig.js +1 -3
- package/dist/fs/findFilepath.d.ts +7 -0
- package/dist/fs/findFilepath.js +17 -0
- package/dist/react/parse/createDictionaryUpdates.d.ts +1 -3
- package/dist/react/parse/createDictionaryUpdates.js +4 -4
- package/dist/types/data.d.ts +2 -1
- package/dist/types/index.d.ts +23 -3
- package/package.json +5 -4
- package/dist/next/parse/index.d.ts +0 -4
- package/dist/next/parse/index.js +0 -14
- package/dist/react/parse/index.d.ts +0 -3
- package/dist/react/parse/index.js +0 -12
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks the status of translations for a given version ID
|
|
3
|
+
* @param apiKey - The API key for the General Translation API
|
|
4
|
+
* @param baseUrl - The base URL for the General Translation API
|
|
5
|
+
* @param versionId - The version ID of the project
|
|
6
|
+
* @param locales - The locales to wait for
|
|
7
|
+
* @param startTime - The start time of the wait
|
|
8
|
+
* @param timeoutDuration - The timeout duration for the wait in seconds
|
|
9
|
+
* @returns True if all translations are deployed, false otherwise
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkFileTranslations(apiKey: string, baseUrl: string, data: {
|
|
12
|
+
[key: string]: {
|
|
13
|
+
versionId: string;
|
|
14
|
+
canonicalName: string;
|
|
15
|
+
};
|
|
16
|
+
}, locales: string[], timeoutDuration: number, resolveOutputPath: (sourcePath: string, locale: string) => string): Promise<boolean>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.checkFileTranslations = checkFileTranslations;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const console_1 = require("../console/console");
|
|
18
|
+
const generaltranslation_1 = require("generaltranslation");
|
|
19
|
+
const downloadFile_1 = require("./downloadFile");
|
|
20
|
+
/**
|
|
21
|
+
* Checks the status of translations for a given version ID
|
|
22
|
+
* @param apiKey - The API key for the General Translation API
|
|
23
|
+
* @param baseUrl - The base URL for the General Translation API
|
|
24
|
+
* @param versionId - The version ID of the project
|
|
25
|
+
* @param locales - The locales to wait for
|
|
26
|
+
* @param startTime - The start time of the wait
|
|
27
|
+
* @param timeoutDuration - The timeout duration for the wait in seconds
|
|
28
|
+
* @returns True if all translations are deployed, false otherwise
|
|
29
|
+
*/
|
|
30
|
+
function checkFileTranslations(apiKey, baseUrl, data, locales, timeoutDuration, resolveOutputPath) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
const spinner = yield (0, console_1.displayLoadingAnimation)('Waiting for translation...');
|
|
34
|
+
const downloadedFiles = new Set(); // Track which file+locale combinations have been downloaded
|
|
35
|
+
let fileQueryData = [];
|
|
36
|
+
// Initialize the query data
|
|
37
|
+
for (const file in data) {
|
|
38
|
+
for (const locale of locales) {
|
|
39
|
+
fileQueryData.push({
|
|
40
|
+
versionId: data[file].versionId,
|
|
41
|
+
fileName: data[file].canonicalName,
|
|
42
|
+
locale,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const checkDeployment = () => __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
try {
|
|
48
|
+
// Only query for files that haven't been downloaded yet
|
|
49
|
+
const currentQueryData = fileQueryData.filter((item) => !downloadedFiles.has(`${item.fileName}:${item.locale}`));
|
|
50
|
+
// If all files have been downloaded, we're done
|
|
51
|
+
if (currentQueryData.length === 0) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
const response = yield fetch(`${baseUrl}/v1/project/translations/files/retrieve`, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: Object.assign({ 'Content-Type': 'application/json' }, (apiKey && { 'x-gt-api-key': apiKey })),
|
|
57
|
+
body: JSON.stringify({ files: currentQueryData }),
|
|
58
|
+
});
|
|
59
|
+
if (response.ok) {
|
|
60
|
+
const responseData = yield response.json();
|
|
61
|
+
const translations = responseData.translations || [];
|
|
62
|
+
// Process available translations
|
|
63
|
+
for (const translation of translations) {
|
|
64
|
+
const locale = translation.locale;
|
|
65
|
+
const fileName = data[translation.fileName].canonicalName;
|
|
66
|
+
if (translation.isReady && fileName) {
|
|
67
|
+
// Mark this file+locale as downloaded
|
|
68
|
+
downloadedFiles.add(`${fileName}:${locale}`);
|
|
69
|
+
// Download the file
|
|
70
|
+
const outputPath = resolveOutputPath(fileName, locale);
|
|
71
|
+
yield (0, downloadFile_1.downloadFile)(baseUrl, apiKey, translation.fileId, outputPath);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Update the spinner text
|
|
75
|
+
spinner.suffixText = generateStatusSuffixText(downloadedFiles, fileQueryData);
|
|
76
|
+
}
|
|
77
|
+
if (downloadedFiles.size === fileQueryData.length) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error('Error checking translation status:', error);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Generates a formatted status text showing translation progress
|
|
89
|
+
* @param downloadedFiles - Set of downloaded file+locale combinations
|
|
90
|
+
* @param fileQueryData - Array of file query data objects
|
|
91
|
+
* @returns Formatted status text
|
|
92
|
+
*/
|
|
93
|
+
function generateStatusSuffixText(downloadedFiles, fileQueryData) {
|
|
94
|
+
var _a;
|
|
95
|
+
const newSuffixText = [
|
|
96
|
+
`\n\n` +
|
|
97
|
+
chalk_1.default.green(`${downloadedFiles.size}/${fileQueryData.length}`) +
|
|
98
|
+
` translations completed\n`,
|
|
99
|
+
];
|
|
100
|
+
// Group by filename for better organization
|
|
101
|
+
const fileGroups = new Map();
|
|
102
|
+
// Initialize with all files and locales from fileQueryData
|
|
103
|
+
for (const item of fileQueryData) {
|
|
104
|
+
if (!fileGroups.has(item.fileName)) {
|
|
105
|
+
fileGroups.set(item.fileName, new Set());
|
|
106
|
+
}
|
|
107
|
+
(_a = fileGroups.get(item.fileName)) === null || _a === void 0 ? void 0 : _a.add(item.locale);
|
|
108
|
+
}
|
|
109
|
+
// Mark which ones are completed
|
|
110
|
+
for (const fileLocale of downloadedFiles) {
|
|
111
|
+
const [fileName, locale] = fileLocale.split(':');
|
|
112
|
+
const completedLocales = fileGroups.get(fileName);
|
|
113
|
+
if (completedLocales) {
|
|
114
|
+
completedLocales.delete(locale); // Remove from pending
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Display each file with its status
|
|
118
|
+
for (const [fileName, pendingLocales] of fileGroups.entries()) {
|
|
119
|
+
newSuffixText.push(`\n${chalk_1.default.bold(fileName)}`);
|
|
120
|
+
// Show completed locales for this file
|
|
121
|
+
for (const fileLocale of downloadedFiles) {
|
|
122
|
+
const [currentFileName, locale] = fileLocale.split(':');
|
|
123
|
+
if (currentFileName === fileName) {
|
|
124
|
+
const localeProperties = (0, generaltranslation_1.getLocaleProperties)(locale);
|
|
125
|
+
newSuffixText.push(` ${chalk_1.default.green('✓')} ${chalk_1.default.green(localeProperties.code)}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Show pending locales for this file
|
|
129
|
+
for (const locale of pendingLocales) {
|
|
130
|
+
const localeProperties = (0, generaltranslation_1.getLocaleProperties)(locale);
|
|
131
|
+
newSuffixText.push(` ${chalk_1.default.yellow('[==>')} ${chalk_1.default.yellow(localeProperties.code)}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return newSuffixText.join('\n');
|
|
135
|
+
}
|
|
136
|
+
// Calculate time until next 5-second interval since startTime
|
|
137
|
+
const msUntilNextInterval = Math.max(0, 5000 - ((Date.now() - startTime) % 5000));
|
|
138
|
+
// Do first check immediately
|
|
139
|
+
const initialCheck = yield checkDeployment();
|
|
140
|
+
if (initialCheck) {
|
|
141
|
+
spinner.succeed(chalk_1.default.green('All translations are live!'));
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return new Promise((resolve) => {
|
|
145
|
+
let intervalCheck;
|
|
146
|
+
// Start the interval aligned with the original request time
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
intervalCheck = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
const isDeployed = yield checkDeployment();
|
|
150
|
+
const elapsed = Date.now() - startTime;
|
|
151
|
+
if (isDeployed || elapsed >= timeoutDuration * 1000) {
|
|
152
|
+
process.stdout.write('\n');
|
|
153
|
+
clearInterval(intervalCheck);
|
|
154
|
+
if (isDeployed) {
|
|
155
|
+
spinner.succeed(chalk_1.default.green('All translations are live!'));
|
|
156
|
+
resolve(true);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
spinner.fail(chalk_1.default.red('Timed out waiting for translations'));
|
|
160
|
+
resolve(false);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}), 5000);
|
|
164
|
+
}, msUntilNextInterval);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function downloadFile(baseUrl: string, apiKey: string, fileId: string, outputPath: string): Promise<boolean>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.downloadFile = downloadFile;
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
// Helper function to download a file
|
|
49
|
+
function downloadFile(baseUrl, apiKey, fileId, outputPath) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
try {
|
|
52
|
+
const downloadResponse = yield fetch(`${baseUrl}/v1/project/translations/files/${fileId}/download`, {
|
|
53
|
+
method: 'GET',
|
|
54
|
+
headers: Object.assign({}, (apiKey && { 'x-gt-api-key': apiKey })),
|
|
55
|
+
});
|
|
56
|
+
if (downloadResponse.ok) {
|
|
57
|
+
// Ensure the directory exists
|
|
58
|
+
const dir = path.dirname(outputPath);
|
|
59
|
+
if (!fs.existsSync(dir)) {
|
|
60
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
// Get the file data as an ArrayBuffer
|
|
63
|
+
const fileData = yield downloadResponse.arrayBuffer();
|
|
64
|
+
// Write the file to disk
|
|
65
|
+
fs.writeFileSync(outputPath, Buffer.from(fileData));
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error('Error downloading file:', error);
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Settings } from '../types';
|
|
2
|
+
import { FileFormats } from '../types/data';
|
|
3
|
+
export interface FileToTranslate {
|
|
4
|
+
content: string;
|
|
5
|
+
fileName: string;
|
|
6
|
+
fileFormat: FileFormats;
|
|
7
|
+
}
|
|
8
|
+
type ApiOptions = Settings & {
|
|
9
|
+
publish: boolean;
|
|
10
|
+
wait: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Sends multiple files for translation to the API
|
|
14
|
+
* @param files - Array of file objects to translate
|
|
15
|
+
* @param options - The options for the API call
|
|
16
|
+
* @returns The translated content or version ID
|
|
17
|
+
*/
|
|
18
|
+
export declare function sendFiles(files: FileToTranslate[], options: ApiOptions): Promise<{
|
|
19
|
+
data: any;
|
|
20
|
+
locales: any;
|
|
21
|
+
}>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.sendFiles = sendFiles;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const console_1 = require("../console/console");
|
|
18
|
+
/**
|
|
19
|
+
* Sends multiple files for translation to the API
|
|
20
|
+
* @param files - Array of file objects to translate
|
|
21
|
+
* @param options - The options for the API call
|
|
22
|
+
* @returns The translated content or version ID
|
|
23
|
+
*/
|
|
24
|
+
function sendFiles(files, options) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const { apiKey } = options;
|
|
27
|
+
console.log(chalk_1.default.cyan('\nFiles to translate:'));
|
|
28
|
+
console.log(files.map((file) => ` - ${chalk_1.default.bold(file.fileName)}`).join('\n'));
|
|
29
|
+
console.log();
|
|
30
|
+
const spinner = yield (0, console_1.displayLoadingAnimation)(`Sending ${files.length} file${files.length > 1 ? 's' : ''} to Translation API...`);
|
|
31
|
+
try {
|
|
32
|
+
// Create form data
|
|
33
|
+
const formData = new FormData();
|
|
34
|
+
// Add each file to the form data
|
|
35
|
+
files.forEach((file, index) => {
|
|
36
|
+
formData.append(`file${index}`, new Blob([file.content]), file.fileName);
|
|
37
|
+
formData.append(`fileFormat${index}`, file.fileFormat);
|
|
38
|
+
formData.append(`fileName${index}`, file.fileName);
|
|
39
|
+
});
|
|
40
|
+
// Add number of files
|
|
41
|
+
formData.append('fileCount', String(files.length));
|
|
42
|
+
// Add other metadata
|
|
43
|
+
formData.append('sourceLocale', options.defaultLocale);
|
|
44
|
+
formData.append('targetLocales', JSON.stringify(options.locales));
|
|
45
|
+
formData.append('projectId', options.projectId);
|
|
46
|
+
formData.append('publish', String(options.publish));
|
|
47
|
+
formData.append('versionId', options.versionId || '');
|
|
48
|
+
const response = yield fetch(`${options.baseUrl}/v1/project/translations/files/upload`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: Object.assign({}, (apiKey && { 'x-gt-api-key': apiKey })),
|
|
51
|
+
body: formData,
|
|
52
|
+
});
|
|
53
|
+
process.stdout.write('\n\n');
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
spinner.fail(yield response.text());
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const responseData = yield response.json();
|
|
59
|
+
// Handle version ID response (for async processing)
|
|
60
|
+
const { data, message, locales } = responseData;
|
|
61
|
+
spinner.succeed(chalk_1.default.green(message || 'Translation job submitted successfully'));
|
|
62
|
+
return { data, locales };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
spinner.fail(chalk_1.default.red('Failed to send files for translation'));
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
package/dist/api/sendUpdates.js
CHANGED
|
@@ -60,7 +60,7 @@ function sendUpdates(updates, options) {
|
|
|
60
60
|
if (options.wait && locales) {
|
|
61
61
|
// timeout was validated earlier
|
|
62
62
|
const timeout = parseInt(options.timeout) * 1000;
|
|
63
|
-
|
|
63
|
+
yield (0, waitForUpdates_1.waitForUpdates)(apiKey, options.baseUrl, versionId, locales, startTime, timeout);
|
|
64
64
|
}
|
|
65
65
|
return { versionId };
|
|
66
66
|
}
|
package/dist/cli/base.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SupportedLibraries } from '../types';
|
|
1
|
+
import { Settings, SupportedLibraries } from '../types';
|
|
2
2
|
export declare class BaseCLI {
|
|
3
3
|
private library;
|
|
4
4
|
private additionalModules;
|
|
@@ -6,5 +6,6 @@ export declare class BaseCLI {
|
|
|
6
6
|
init(): void;
|
|
7
7
|
execute(): void;
|
|
8
8
|
protected setupGTCommand(): void;
|
|
9
|
+
protected handleGenericTranslate(settings: Settings): Promise<void>;
|
|
9
10
|
protected setupInitCommand(): void;
|
|
10
11
|
}
|
package/dist/cli/base.js
CHANGED
|
@@ -55,12 +55,12 @@ const generaltranslation_1 = require("generaltranslation");
|
|
|
55
55
|
const findFilepath_1 = __importStar(require("../fs/findFilepath"));
|
|
56
56
|
const errors_1 = require("../console/errors");
|
|
57
57
|
const path_1 = __importDefault(require("path"));
|
|
58
|
-
const yaml_1 = __importDefault(require("yaml"));
|
|
59
58
|
const translate_1 = require("../formats/json/translate");
|
|
60
59
|
const utils_1 = require("../fs/utils");
|
|
61
60
|
const generateSettings_1 = require("../config/generateSettings");
|
|
62
61
|
const chalk_1 = __importDefault(require("chalk"));
|
|
63
62
|
const internal_1 = require("generaltranslation/internal");
|
|
63
|
+
const translate_2 = require("../formats/files/translate");
|
|
64
64
|
const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
65
65
|
class BaseCLI {
|
|
66
66
|
// Constructor is shared amongst all CLI class types
|
|
@@ -86,11 +86,16 @@ class BaseCLI {
|
|
|
86
86
|
.option('--project-id <id>', 'Project ID for the translation service', (0, utils_1.resolveProjectId)())
|
|
87
87
|
.option('--default-language, --default-locale <locale>', 'Default locale (e.g., en)')
|
|
88
88
|
.option('--new, --locales <locales...>', 'Space-separated list of locales (e.g., en fr es)')
|
|
89
|
-
.option('-t, --translations-dir, --translation-dir <path>', 'Directory containing your language files. Should be in the format path/to/translations/*.json or path/to/translations/*.yaml')
|
|
90
89
|
.action((options) => __awaiter(this, void 0, void 0, function* () {
|
|
91
90
|
(0, console_1.displayAsciiTitle)();
|
|
92
91
|
(0, console_2.displayInitializingText)();
|
|
93
92
|
const settings = (0, generateSettings_1.generateSettings)(options);
|
|
93
|
+
yield this.handleGenericTranslate(settings);
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
handleGenericTranslate(settings) {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
// Validate required settings are present
|
|
94
99
|
if (!settings.locales) {
|
|
95
100
|
console.error(errors_1.noLocalesError);
|
|
96
101
|
process.exit(1);
|
|
@@ -99,8 +104,8 @@ class BaseCLI {
|
|
|
99
104
|
console.error(errors_1.noDefaultLocaleError);
|
|
100
105
|
process.exit(1);
|
|
101
106
|
}
|
|
102
|
-
if (!settings.
|
|
103
|
-
console.error(errors_1.
|
|
107
|
+
if (!settings.files) {
|
|
108
|
+
console.error(errors_1.noFilesError);
|
|
104
109
|
process.exit(1);
|
|
105
110
|
}
|
|
106
111
|
if (!settings.apiKey) {
|
|
@@ -111,17 +116,7 @@ class BaseCLI {
|
|
|
111
116
|
console.error(errors_1.noProjectIdError);
|
|
112
117
|
process.exit(1);
|
|
113
118
|
}
|
|
114
|
-
//
|
|
115
|
-
// Find the source file in the translationsDir
|
|
116
|
-
const rawSource = (0, findFilepath_1.findFile)(settings.translationsDir, settings.defaultLocale);
|
|
117
|
-
if (!rawSource) {
|
|
118
|
-
console.error(errors_1.noSourceFileError);
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
// Get the data format from the ending of the translationsDir
|
|
122
|
-
const fileExtension = settings.translationsDir
|
|
123
|
-
.split('.')
|
|
124
|
-
.pop();
|
|
119
|
+
// dataFormat for JSONs
|
|
125
120
|
let dataFormat;
|
|
126
121
|
if (this.library === 'next-intl') {
|
|
127
122
|
dataFormat = 'ICU';
|
|
@@ -137,19 +132,38 @@ class BaseCLI {
|
|
|
137
132
|
else {
|
|
138
133
|
dataFormat = 'JSX';
|
|
139
134
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
const { resolvedPaths: sourceFiles, placeholderPaths } = settings.files;
|
|
136
|
+
// ---- CREATING UPDATES ---- //
|
|
137
|
+
if (sourceFiles.json) {
|
|
138
|
+
// Only translate JSON files if not using gt-react or gt-next
|
|
139
|
+
// ReactCLI will handle the JSON files differently
|
|
140
|
+
if (this.library !== 'gt-react' && this.library !== 'gt-next') {
|
|
141
|
+
const rawSource = (0, findFilepath_1.readFile)(sourceFiles.json[0]);
|
|
142
|
+
if (!rawSource) {
|
|
143
|
+
console.error(errors_1.noSourceFileError);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
if (!dataFormat) {
|
|
147
|
+
console.error(errors_1.noDataFormatError);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
else if (!SUPPORTED_DATA_FORMATS.includes(dataFormat)) {
|
|
151
|
+
console.error(errors_1.noSupportedDataFormatError);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
const source = JSON.parse(rawSource);
|
|
155
|
+
yield (0, translate_1.translateJson)(source, settings, dataFormat, placeholderPaths);
|
|
156
|
+
}
|
|
143
157
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
if (sourceFiles.mdx || sourceFiles.md) {
|
|
159
|
+
if (sourceFiles.mdx) {
|
|
160
|
+
yield (0, translate_2.translateFiles)(sourceFiles, placeholderPaths, 'MDX', settings);
|
|
161
|
+
}
|
|
162
|
+
if (sourceFiles.md) {
|
|
163
|
+
yield (0, translate_2.translateFiles)(sourceFiles, placeholderPaths, 'MD', settings);
|
|
164
|
+
}
|
|
147
165
|
}
|
|
148
|
-
|
|
149
|
-
? JSON.parse(rawSource)
|
|
150
|
-
: yaml_1.default.parse(rawSource);
|
|
151
|
-
const result = yield (0, translate_1.translateJson)(source, settings, dataFormat, fileExtension);
|
|
152
|
-
}));
|
|
166
|
+
});
|
|
153
167
|
}
|
|
154
168
|
setupInitCommand() {
|
|
155
169
|
commander_1.program
|
|
@@ -181,14 +195,14 @@ class BaseCLI {
|
|
|
181
195
|
});
|
|
182
196
|
// Ask where the translations are stored
|
|
183
197
|
const location = yield (0, prompts_1.select)({
|
|
184
|
-
message:
|
|
198
|
+
message: `Where are your language files stored? ${chalk_1.default.gray('(remote or local)')}`,
|
|
185
199
|
choices: [
|
|
186
|
-
{ value: '
|
|
200
|
+
{ value: 'remote', name: 'Remote' },
|
|
187
201
|
{ value: 'local', name: 'Local' },
|
|
188
202
|
],
|
|
189
|
-
default: '
|
|
203
|
+
default: 'remote',
|
|
190
204
|
});
|
|
191
|
-
if (location === '
|
|
205
|
+
if (location === 'remote') {
|
|
192
206
|
// Create gt.config.json
|
|
193
207
|
(0, setupConfig_1.default)('gt.config.json', {
|
|
194
208
|
defaultLocale,
|
|
@@ -204,7 +218,7 @@ class BaseCLI {
|
|
|
204
218
|
// Ask if using another i18n library
|
|
205
219
|
const i18nLibrary = thirdPartyLibrary
|
|
206
220
|
? yield (0, prompts_1.select)({
|
|
207
|
-
message: `Are you using a
|
|
221
|
+
message: `Are you using a 3rd-party i18n library? ${chalk_1.default.gray(`(Auto-detected: ${this.library === 'base' ? 'none' : this.library})`)}`,
|
|
208
222
|
choices: [
|
|
209
223
|
{ value: true, name: 'Yes' },
|
|
210
224
|
{ value: false, name: 'No' },
|
|
@@ -215,25 +229,34 @@ class BaseCLI {
|
|
|
215
229
|
if (i18nLibrary) {
|
|
216
230
|
const dataFormat = yield (0, prompts_1.select)({
|
|
217
231
|
message: 'What is the format of your language files?',
|
|
218
|
-
choices: ['
|
|
219
|
-
default: '
|
|
232
|
+
choices: ['json'],
|
|
233
|
+
default: 'json',
|
|
220
234
|
});
|
|
221
235
|
// combine translationsDir and dataFormat into something like
|
|
222
|
-
// translationsDir
|
|
223
|
-
const translationsDirWithFormat = path_1.default.join(translationsDir,
|
|
236
|
+
// translationsDir/[locale].json
|
|
237
|
+
const translationsDirWithFormat = path_1.default.join(translationsDir, `[locale].${dataFormat}`);
|
|
224
238
|
// Create gt.config.json
|
|
225
239
|
(0, setupConfig_1.default)('gt.config.json', {
|
|
226
240
|
defaultLocale,
|
|
227
241
|
locales: locales.split(' '),
|
|
228
|
-
|
|
242
|
+
files: {
|
|
243
|
+
json: {
|
|
244
|
+
include: [translationsDirWithFormat],
|
|
245
|
+
},
|
|
246
|
+
},
|
|
229
247
|
});
|
|
230
248
|
}
|
|
231
249
|
else {
|
|
250
|
+
const translationsDirWithFormat = path_1.default.join(translationsDir, `[locale].json`);
|
|
232
251
|
// Create gt.config.json
|
|
233
252
|
(0, setupConfig_1.default)('gt.config.json', {
|
|
234
253
|
defaultLocale,
|
|
235
254
|
locales: locales.split(' '),
|
|
236
|
-
|
|
255
|
+
files: {
|
|
256
|
+
json: {
|
|
257
|
+
include: [translationsDirWithFormat],
|
|
258
|
+
},
|
|
259
|
+
},
|
|
237
260
|
});
|
|
238
261
|
}
|
|
239
262
|
}));
|
package/dist/cli/next.d.ts
CHANGED
|
@@ -9,9 +9,6 @@ export declare class NextCLI extends ReactCLI {
|
|
|
9
9
|
filesUpdated: string[];
|
|
10
10
|
warnings: string[];
|
|
11
11
|
}>;
|
|
12
|
-
protected createDictionaryUpdates(options: Options & {
|
|
13
|
-
dictionary: string;
|
|
14
|
-
}, esbuildConfig: any): Promise<Updates>;
|
|
15
12
|
protected createInlineUpdates(options: Options): Promise<{
|
|
16
13
|
updates: Updates;
|
|
17
14
|
errors: string[];
|
package/dist/cli/next.js
CHANGED
|
@@ -19,7 +19,6 @@ const prompts_1 = require("@inquirer/prompts");
|
|
|
19
19
|
const postProcess_1 = require("../hooks/postProcess");
|
|
20
20
|
const findFilepath_1 = __importDefault(require("../fs/findFilepath"));
|
|
21
21
|
const scanForContent_1 = __importDefault(require("../next/parse/scanForContent"));
|
|
22
|
-
const createDictionaryUpdates_1 = __importDefault(require("../react/parse/createDictionaryUpdates"));
|
|
23
22
|
const createInlineUpdates_1 = __importDefault(require("../react/parse/createInlineUpdates"));
|
|
24
23
|
const handleInitGT_1 = __importDefault(require("../next/parse/handleInitGT"));
|
|
25
24
|
const react_1 = require("./react");
|
|
@@ -41,9 +40,6 @@ class NextCLI extends react_1.ReactCLI {
|
|
|
41
40
|
scanForContent(options, framework) {
|
|
42
41
|
return (0, scanForContent_1.default)(options, pkg, framework);
|
|
43
42
|
}
|
|
44
|
-
createDictionaryUpdates(options, esbuildConfig) {
|
|
45
|
-
return (0, createDictionaryUpdates_1.default)(options, esbuildConfig);
|
|
46
|
-
}
|
|
47
43
|
createInlineUpdates(options) {
|
|
48
44
|
return (0, createInlineUpdates_1.default)(options, pkg);
|
|
49
45
|
}
|
package/dist/cli/react.d.ts
CHANGED
|
@@ -9,9 +9,7 @@ export declare class ReactCLI extends BaseCLI {
|
|
|
9
9
|
filesUpdated: string[];
|
|
10
10
|
warnings: string[];
|
|
11
11
|
}>;
|
|
12
|
-
protected createDictionaryUpdates(options: Options
|
|
13
|
-
dictionary: string;
|
|
14
|
-
}, esbuildConfig: any): Promise<Updates>;
|
|
12
|
+
protected createDictionaryUpdates(options: Options, dictionaryPath: string, esbuildConfig?: any): Promise<Updates>;
|
|
15
13
|
protected createInlineUpdates(options: Options): Promise<{
|
|
16
14
|
updates: Updates;
|
|
17
15
|
errors: string[];
|
|
@@ -20,11 +18,11 @@ export declare class ReactCLI extends BaseCLI {
|
|
|
20
18
|
protected setupGenerateSourceCommand(): void;
|
|
21
19
|
protected setupSetupCommand(): void;
|
|
22
20
|
protected setupScanCommand(): void;
|
|
23
|
-
protected handleGenerateSourceCommand(
|
|
21
|
+
protected handleGenerateSourceCommand(initOptions: GenerateSourceOptions): Promise<void>;
|
|
24
22
|
protected handleScanCommand(options: WrapOptions): Promise<void>;
|
|
25
23
|
protected handleSetupCommand(options: SetupOptions): Promise<void>;
|
|
26
24
|
protected handleTranslateCommand(initOptions: Options): Promise<void>;
|
|
27
|
-
protected createUpdates(options: Options | GenerateSourceOptions): Promise<{
|
|
25
|
+
protected createUpdates(options: Options | GenerateSourceOptions, sourceDictionary: string | undefined): Promise<{
|
|
28
26
|
updates: Updates;
|
|
29
27
|
errors: string[];
|
|
30
28
|
}>;
|