gtx-cli 2.3.6-alpha.2 → 2.3.6
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 +10 -0
- package/dist/api/checkFileTranslations.d.ts +23 -0
- package/dist/api/checkFileTranslations.js +236 -0
- package/dist/api/downloadFileBatch.d.ts +20 -0
- package/dist/api/downloadFileBatch.js +113 -0
- package/dist/api/sendFiles.d.ts +17 -0
- package/dist/api/sendFiles.js +115 -0
- package/dist/api/uploadFiles.d.ts +27 -0
- package/dist/api/uploadFiles.js +40 -0
- package/dist/cli/base.d.ts +32 -0
- package/dist/cli/base.js +335 -0
- package/dist/cli/commands/stage.d.ts +5 -0
- package/dist/cli/commands/stage.js +100 -0
- package/dist/cli/commands/translate.d.ts +6 -0
- package/dist/cli/commands/translate.js +63 -0
- package/dist/cli/flags.d.ts +3 -0
- package/dist/cli/flags.js +38 -0
- package/dist/cli/next.d.ts +11 -0
- package/dist/cli/next.js +20 -0
- package/dist/cli/react.d.ts +18 -0
- package/dist/cli/react.js +175 -0
- package/dist/config/generateSettings.d.ts +9 -0
- package/dist/config/generateSettings.js +176 -0
- package/dist/config/optionPresets.d.ts +2 -0
- package/dist/config/optionPresets.js +56 -0
- package/dist/config/resolveConfig.d.ts +4 -0
- package/dist/config/resolveConfig.js +19 -0
- package/dist/config/utils.d.ts +2 -0
- package/dist/config/utils.js +4 -0
- package/dist/config/validateSettings.d.ts +3 -0
- package/dist/config/validateSettings.js +32 -0
- package/dist/console/colors.d.ts +5 -0
- package/dist/console/colors.js +16 -0
- package/dist/console/index.d.ts +21 -0
- package/dist/console/index.js +24 -0
- package/dist/console/logging.d.ts +53 -0
- package/dist/console/logging.js +185 -0
- package/dist/formats/files/fileMapping.d.ts +11 -0
- package/dist/formats/files/fileMapping.js +82 -0
- package/dist/formats/files/save.d.ts +5 -0
- package/dist/formats/files/save.js +17 -0
- package/dist/formats/files/supportedFiles.d.ts +10 -0
- package/dist/formats/files/supportedFiles.js +18 -0
- package/dist/formats/files/translate.d.ts +4 -0
- package/dist/formats/files/translate.js +119 -0
- package/dist/formats/files/upload.d.ts +13 -0
- package/dist/formats/files/upload.js +136 -0
- package/dist/formats/gt/save.d.ts +9 -0
- package/dist/formats/gt/save.js +26 -0
- package/dist/formats/json/flattenJson.d.ts +14 -0
- package/dist/formats/json/flattenJson.js +64 -0
- package/dist/formats/json/mergeJson.d.ts +13 -0
- package/dist/formats/json/mergeJson.js +257 -0
- package/dist/formats/json/parseJson.d.ts +2 -0
- package/dist/formats/json/parseJson.js +108 -0
- package/dist/formats/json/utils.d.ts +47 -0
- package/dist/formats/json/utils.js +149 -0
- package/dist/formats/utils.d.ts +2 -0
- package/dist/formats/utils.js +24 -0
- package/dist/formats/yaml/mergeYaml.d.ts +5 -0
- package/dist/formats/yaml/mergeYaml.js +55 -0
- package/dist/formats/yaml/parseYaml.d.ts +5 -0
- package/dist/formats/yaml/parseYaml.js +23 -0
- package/dist/formats/yaml/utils.d.ts +2 -0
- package/dist/formats/yaml/utils.js +22 -0
- package/dist/fs/config/loadConfig.d.ts +1 -0
- package/dist/fs/config/loadConfig.js +9 -0
- package/dist/fs/config/parseFilesConfig.d.ts +27 -0
- package/dist/fs/config/parseFilesConfig.js +129 -0
- package/dist/fs/config/setupConfig.d.ts +17 -0
- package/dist/fs/config/setupConfig.js +50 -0
- package/dist/fs/config/updateConfig.d.ts +10 -0
- package/dist/fs/config/updateConfig.js +36 -0
- package/dist/fs/config/updateVersions.d.ts +10 -0
- package/dist/fs/config/updateVersions.js +30 -0
- package/dist/fs/copyFile.d.ts +7 -0
- package/dist/fs/copyFile.js +39 -0
- package/dist/fs/createLoadTranslationsFile.d.ts +1 -0
- package/dist/fs/createLoadTranslationsFile.js +36 -0
- package/dist/fs/determineFramework.d.ts +5 -0
- package/dist/fs/determineFramework.js +46 -0
- package/dist/fs/findFilepath.d.ts +36 -0
- package/dist/fs/findFilepath.js +89 -0
- package/dist/fs/getPackageResource.d.ts +1 -0
- package/dist/fs/getPackageResource.js +6 -0
- package/dist/fs/index.d.ts +1 -0
- package/dist/fs/index.js +1 -0
- package/dist/fs/loadJSON.d.ts +6 -0
- package/dist/fs/loadJSON.js +17 -0
- package/dist/fs/matchFiles.d.ts +1 -0
- package/dist/fs/matchFiles.js +8 -0
- package/dist/fs/saveJSON.d.ts +1 -0
- package/dist/fs/saveJSON.js +7 -0
- package/dist/fs/utils.d.ts +1 -0
- package/dist/fs/utils.js +16 -0
- package/dist/hooks/postProcess.d.ts +4 -0
- package/dist/hooks/postProcess.js +110 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +9 -0
- package/dist/next/config/parseNextConfig.d.ts +10 -0
- package/dist/next/config/parseNextConfig.js +53 -0
- package/dist/next/jsx/utils.d.ts +7 -0
- package/dist/next/jsx/utils.js +42 -0
- package/dist/next/parse/handleInitGT.d.ts +7 -0
- package/dist/next/parse/handleInitGT.js +208 -0
- package/dist/next/parse/wrapContent.d.ts +11 -0
- package/dist/next/parse/wrapContent.js +163 -0
- package/dist/react/config/createESBuildConfig.d.ts +2 -0
- package/dist/react/config/createESBuildConfig.js +119 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +8 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +111 -0
- package/dist/react/jsx/evaluateJsx.d.ts +17 -0
- package/dist/react/jsx/evaluateJsx.js +85 -0
- package/dist/react/jsx/trimJsxStringChildren.d.ts +7 -0
- package/dist/react/jsx/trimJsxStringChildren.js +95 -0
- package/dist/react/jsx/utils/constants.d.ts +10 -0
- package/dist/react/jsx/utils/constants.js +31 -0
- package/dist/react/jsx/utils/parseAst.d.ts +30 -0
- package/dist/react/jsx/utils/parseAst.js +277 -0
- package/dist/react/jsx/utils/parseJsx.d.ts +21 -0
- package/dist/react/jsx/utils/parseJsx.js +244 -0
- package/dist/react/jsx/utils/parseStringFunction.d.ts +16 -0
- package/dist/react/jsx/utils/parseStringFunction.js +411 -0
- package/dist/react/jsx/utils/validateStringFunction.d.ts +7 -0
- package/dist/react/jsx/utils/validateStringFunction.js +31 -0
- package/dist/react/jsx/wrapJsx.d.ts +51 -0
- package/dist/react/jsx/wrapJsx.js +387 -0
- package/dist/react/parse/createDictionaryUpdates.d.ts +3 -0
- package/dist/react/parse/createDictionaryUpdates.js +169 -0
- package/dist/react/parse/createInlineUpdates.d.ts +6 -0
- package/dist/react/parse/createInlineUpdates.js +122 -0
- package/dist/react/parse/wrapContent.d.ts +11 -0
- package/dist/react/parse/wrapContent.js +162 -0
- package/dist/react/utils/flattenDictionary.d.ts +20 -0
- package/dist/react/utils/flattenDictionary.js +75 -0
- package/dist/react/utils/getEntryAndMetadata.d.ts +5 -0
- package/dist/react/utils/getEntryAndMetadata.js +11 -0
- package/dist/react/utils/getVariableName.d.ts +25 -0
- package/dist/react/utils/getVariableName.js +37 -0
- package/dist/setup/userInput.d.ts +4 -0
- package/dist/setup/userInput.js +29 -0
- package/dist/setup/wizard.d.ts +2 -0
- package/dist/setup/wizard.js +127 -0
- package/dist/translation/parse.d.ts +15 -0
- package/dist/translation/parse.js +76 -0
- package/dist/translation/stage.d.ts +2 -0
- package/dist/translation/stage.js +44 -0
- package/dist/translation/validate.d.ts +2 -0
- package/dist/translation/validate.js +50 -0
- package/dist/types/data/json.d.ts +6 -0
- package/dist/types/data/json.js +1 -0
- package/dist/types/data.d.ts +30 -0
- package/dist/types/data.js +1 -0
- package/dist/types/files.d.ts +1 -0
- package/dist/types/files.js +1 -0
- package/dist/types/index.d.ts +173 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/addExplicitAnchorIds.d.ts +24 -0
- package/dist/utils/addExplicitAnchorIds.js +260 -0
- package/dist/utils/constants.d.ts +2 -0
- package/dist/utils/constants.js +2 -0
- package/dist/utils/credentials.d.ts +12 -0
- package/dist/utils/credentials.js +119 -0
- package/dist/utils/flattenJsonFiles.d.ts +2 -0
- package/dist/utils/flattenJsonFiles.js +36 -0
- package/dist/utils/gt.d.ts +2 -0
- package/dist/utils/gt.js +2 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/hash.js +11 -0
- package/dist/utils/headers.d.ts +1 -0
- package/dist/utils/headers.js +14 -0
- package/dist/utils/installPackage.d.ts +3 -0
- package/dist/utils/installPackage.js +77 -0
- package/dist/utils/localizeStaticImports.d.ts +15 -0
- package/dist/utils/localizeStaticImports.js +341 -0
- package/dist/utils/localizeStaticUrls.d.ts +19 -0
- package/dist/utils/localizeStaticUrls.js +432 -0
- package/dist/utils/packageInfo.d.ts +3 -0
- package/dist/utils/packageInfo.js +17 -0
- package/dist/utils/packageJson.d.ts +6 -0
- package/dist/utils/packageJson.js +76 -0
- package/dist/utils/packageManager.d.ts +28 -0
- package/dist/utils/packageManager.js +269 -0
- package/dist/utils/processAnchorIds.d.ts +6 -0
- package/dist/utils/processAnchorIds.js +47 -0
- package/dist/utils/sanitizeFileContent.d.ts +6 -0
- package/dist/utils/sanitizeFileContent.js +29 -0
- package/dist/utils/validateMdx.d.ts +10 -0
- package/dist/utils/validateMdx.js +25 -0
- package/package.json +3 -3
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { parse } from '@babel/parser';
|
|
3
|
+
import traverseModule from '@babel/traverse';
|
|
4
|
+
// Handle CommonJS/ESM interop
|
|
5
|
+
const traverse = traverseModule.default || traverseModule;
|
|
6
|
+
import { hashSource } from 'generaltranslation/id';
|
|
7
|
+
import { parseJSXElement } from '../jsx/utils/parseJsx.js';
|
|
8
|
+
import { parseStrings } from '../jsx/utils/parseStringFunction.js';
|
|
9
|
+
import { extractImportName } from '../jsx/utils/parseAst.js';
|
|
10
|
+
import { logError } from '../../console/logging.js';
|
|
11
|
+
import { GT_TRANSLATION_FUNCS, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC, MSG_TRANSLATION_HOOK, } from '../jsx/utils/constants.js';
|
|
12
|
+
import { matchFiles } from '../../fs/matchFiles.js';
|
|
13
|
+
import { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';
|
|
14
|
+
export async function createInlineUpdates(pkg, validate, filePatterns) {
|
|
15
|
+
const updates = [];
|
|
16
|
+
const errors = [];
|
|
17
|
+
const warnings = new Set();
|
|
18
|
+
// Use the provided app directory or default to the current directory
|
|
19
|
+
const files = matchFiles(process.cwd(), filePatterns || DEFAULT_SRC_PATTERNS);
|
|
20
|
+
for (const file of files) {
|
|
21
|
+
const code = await fs.promises.readFile(file, 'utf8');
|
|
22
|
+
let ast;
|
|
23
|
+
try {
|
|
24
|
+
ast = parse(code, {
|
|
25
|
+
sourceType: 'module',
|
|
26
|
+
plugins: ['jsx', 'typescript'],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
logError(`Error parsing file ${file}: ${error}`);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const importAliases = {};
|
|
34
|
+
// First pass: collect imports and process translation functions
|
|
35
|
+
const translationPaths = [];
|
|
36
|
+
traverse(ast, {
|
|
37
|
+
ImportDeclaration(path) {
|
|
38
|
+
if (path.node.source.value.startsWith(pkg)) {
|
|
39
|
+
const importName = extractImportName(path.node, pkg, GT_TRANSLATION_FUNCS);
|
|
40
|
+
for (const name of importName) {
|
|
41
|
+
if (name.original === INLINE_TRANSLATION_HOOK ||
|
|
42
|
+
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
43
|
+
name.original === INLINE_MESSAGE_HOOK ||
|
|
44
|
+
name.original === INLINE_MESSAGE_HOOK_ASYNC ||
|
|
45
|
+
name.original === MSG_TRANSLATION_HOOK) {
|
|
46
|
+
translationPaths.push({
|
|
47
|
+
localName: name.local,
|
|
48
|
+
path,
|
|
49
|
+
originalName: name.original,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
importAliases[name.local] = name.original;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
VariableDeclarator(path) {
|
|
59
|
+
// Check if the init is a require call
|
|
60
|
+
if (path.node.init?.type === 'CallExpression' &&
|
|
61
|
+
path.node.init.callee.type === 'Identifier' &&
|
|
62
|
+
path.node.init.callee.name === 'require') {
|
|
63
|
+
// Check if it's requiring our package
|
|
64
|
+
const args = path.node.init.arguments;
|
|
65
|
+
if (args.length === 1 &&
|
|
66
|
+
args[0].type === 'StringLiteral' &&
|
|
67
|
+
args[0].value.startsWith(pkg)) {
|
|
68
|
+
const parentPath = path.parentPath;
|
|
69
|
+
if (parentPath.isVariableDeclaration()) {
|
|
70
|
+
const importName = extractImportName(parentPath.node, pkg, GT_TRANSLATION_FUNCS);
|
|
71
|
+
for (const name of importName) {
|
|
72
|
+
if (name.original === INLINE_TRANSLATION_HOOK ||
|
|
73
|
+
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
74
|
+
name.original === INLINE_MESSAGE_HOOK ||
|
|
75
|
+
name.original === INLINE_MESSAGE_HOOK_ASYNC ||
|
|
76
|
+
name.original === MSG_TRANSLATION_HOOK) {
|
|
77
|
+
translationPaths.push({
|
|
78
|
+
localName: name.local,
|
|
79
|
+
path: parentPath,
|
|
80
|
+
originalName: name.original,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
importAliases[name.local] = name.original;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
// Process translation functions asynchronously
|
|
93
|
+
for (const { localName: name, originalName, path } of translationPaths) {
|
|
94
|
+
parseStrings(name, originalName, path, updates, errors, file);
|
|
95
|
+
}
|
|
96
|
+
// Parse <T> components
|
|
97
|
+
traverse(ast, {
|
|
98
|
+
JSXElement(path) {
|
|
99
|
+
parseJSXElement(importAliases, path.node, updates, errors, warnings, file);
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
// Extra validation (for Locadex)
|
|
103
|
+
// Done in parseStrings() atm
|
|
104
|
+
// if (validate) {
|
|
105
|
+
// for (const { localName: name, path, originalName } of translationPaths) {
|
|
106
|
+
// validateStringFunction(name, path, updates, errors, file, originalName);
|
|
107
|
+
// }
|
|
108
|
+
// }
|
|
109
|
+
}
|
|
110
|
+
// Post-process to add a hash to each update
|
|
111
|
+
await Promise.all(updates.map(async (update) => {
|
|
112
|
+
const context = update.metadata.context;
|
|
113
|
+
const hash = hashSource({
|
|
114
|
+
source: update.source,
|
|
115
|
+
...(context && { context }),
|
|
116
|
+
...(update.metadata.id && { id: update.metadata.id }),
|
|
117
|
+
dataFormat: update.dataFormat,
|
|
118
|
+
});
|
|
119
|
+
update.metadata.hash = hash;
|
|
120
|
+
}));
|
|
121
|
+
return { updates, errors, warnings: [...warnings] };
|
|
122
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SupportedFrameworks, WrapOptions } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps all JSX elements in the src directory with a <T> tag, with unique ids.
|
|
4
|
+
* - Ignores pure strings
|
|
5
|
+
*
|
|
6
|
+
* @param options - The options object
|
|
7
|
+
* @returns An object containing the updates and errors
|
|
8
|
+
*/
|
|
9
|
+
export declare function wrapContentReact(options: WrapOptions, pkg: 'gt-react', framework: SupportedFrameworks, errors: string[], warnings: string[]): Promise<{
|
|
10
|
+
filesUpdated: string[];
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import * as t from '@babel/types';
|
|
4
|
+
import { parse } from '@babel/parser';
|
|
5
|
+
import traverseModule from '@babel/traverse';
|
|
6
|
+
import generateModule from '@babel/generator';
|
|
7
|
+
// Handle CommonJS/ESM interop
|
|
8
|
+
const traverse = traverseModule.default || traverseModule;
|
|
9
|
+
const generate = generateModule.default || generateModule;
|
|
10
|
+
import { isMeaningful } from '../jsx/evaluateJsx.js';
|
|
11
|
+
import { handleJsxElement } from '../jsx/wrapJsx.js';
|
|
12
|
+
import { getRelativePath } from '../../fs/findFilepath.js';
|
|
13
|
+
import { generateImportMap, createImports, } from '../jsx/utils/parseAst.js';
|
|
14
|
+
import { DEFAULT_SRC_PATTERNS } from '../../config/generateSettings.js';
|
|
15
|
+
import { matchFiles } from '../../fs/matchFiles.js';
|
|
16
|
+
const IMPORT_MAP = {
|
|
17
|
+
T: { name: 'T', source: 'gt-react' },
|
|
18
|
+
Var: { name: 'Var', source: 'gt-react' },
|
|
19
|
+
GTT: { name: 'T', source: 'gt-react' },
|
|
20
|
+
GTVar: { name: 'Var', source: 'gt-react' },
|
|
21
|
+
GTProvider: { name: 'GTProvider', source: 'gt-react' },
|
|
22
|
+
// getLocale: { name: 'getLocale', source: 'gt-react/server' },
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Wraps all JSX elements in the src directory with a <T> tag, with unique ids.
|
|
26
|
+
* - Ignores pure strings
|
|
27
|
+
*
|
|
28
|
+
* @param options - The options object
|
|
29
|
+
* @returns An object containing the updates and errors
|
|
30
|
+
*/
|
|
31
|
+
export async function wrapContentReact(options, pkg, framework, errors, warnings) {
|
|
32
|
+
const filePatterns = options.src || DEFAULT_SRC_PATTERNS;
|
|
33
|
+
const files = matchFiles(process.cwd(), filePatterns);
|
|
34
|
+
const filesUpdated = [];
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
const baseFileName = path.basename(file);
|
|
37
|
+
const configPath = path.relative(path.dirname(file), path.resolve(process.cwd(), options.config));
|
|
38
|
+
// Ensure the path starts with ./ or ../
|
|
39
|
+
const normalizedConfigPath = configPath.startsWith('.')
|
|
40
|
+
? configPath
|
|
41
|
+
: './' + configPath;
|
|
42
|
+
const code = await fs.promises.readFile(file, 'utf8');
|
|
43
|
+
// Create relative path from src directory and remove extension
|
|
44
|
+
const relativePath = getRelativePath(file, process.cwd());
|
|
45
|
+
let ast;
|
|
46
|
+
try {
|
|
47
|
+
ast = parse(code, {
|
|
48
|
+
sourceType: 'module',
|
|
49
|
+
plugins: ['jsx', 'typescript'],
|
|
50
|
+
tokens: true,
|
|
51
|
+
createParenthesizedExpressions: true,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
errors.push(`Error:Failed to parse ${file}: ${error}`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
let modified = false;
|
|
59
|
+
const usedImports = [];
|
|
60
|
+
const { importAlias, initialImports } = generateImportMap(ast, pkg);
|
|
61
|
+
// If the file already has a T import, skip processing it
|
|
62
|
+
if (initialImports.includes(IMPORT_MAP.T.name)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
let globalId = 0;
|
|
66
|
+
traverse(ast, {
|
|
67
|
+
JSXElement(path) {
|
|
68
|
+
if (framework === 'next-pages' &&
|
|
69
|
+
options.addGTProvider &&
|
|
70
|
+
(baseFileName === '_app.tsx' || baseFileName === '_app.jsx')) {
|
|
71
|
+
// Check if this is the Component element with pageProps
|
|
72
|
+
const isComponentWithPageProps = t.isJSXElement(path.node) &&
|
|
73
|
+
t.isJSXIdentifier(path.node.openingElement.name) &&
|
|
74
|
+
path.node.openingElement.name.name === 'Component' &&
|
|
75
|
+
path.node.openingElement.attributes.some((attr) => t.isJSXSpreadAttribute(attr) &&
|
|
76
|
+
t.isIdentifier(attr.argument) &&
|
|
77
|
+
attr.argument.name === 'pageProps');
|
|
78
|
+
if (!isComponentWithPageProps) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Check if GTProvider already exists in the ancestors
|
|
82
|
+
let hasGTProvider = false;
|
|
83
|
+
let currentPath = path;
|
|
84
|
+
while (currentPath.parentPath) {
|
|
85
|
+
if (t.isJSXElement(currentPath.node) &&
|
|
86
|
+
t.isJSXIdentifier(currentPath.node.openingElement.name) &&
|
|
87
|
+
currentPath.node.openingElement.name.name === 'GTProvider') {
|
|
88
|
+
hasGTProvider = true;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
currentPath = currentPath.parentPath;
|
|
92
|
+
}
|
|
93
|
+
if (!hasGTProvider) {
|
|
94
|
+
// Wrap the Component element with GTProvider
|
|
95
|
+
const gtProviderJsx = t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier('GTProvider'), [t.jsxSpreadAttribute(t.identifier('gtConfig'))], false), t.jsxClosingElement(t.jsxIdentifier('GTProvider')), [path.node]);
|
|
96
|
+
path.replaceWith(gtProviderJsx);
|
|
97
|
+
usedImports.push('GTProvider');
|
|
98
|
+
usedImports.push({
|
|
99
|
+
local: 'gtConfig',
|
|
100
|
+
imported: 'default',
|
|
101
|
+
source: normalizedConfigPath,
|
|
102
|
+
});
|
|
103
|
+
modified = true;
|
|
104
|
+
path.skip();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Check if this JSX element has any JSX element ancestors
|
|
109
|
+
if (t.isJSXElement(path.parentPath?.node) ||
|
|
110
|
+
t.isJSXExpressionContainer(path.parentPath?.node)) {
|
|
111
|
+
// If we're nested inside JSX, skip processing this node
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// At this point, we're only processing top-level JSX elements
|
|
115
|
+
const opts = {
|
|
116
|
+
...importAlias,
|
|
117
|
+
idPrefix: relativePath,
|
|
118
|
+
idCount: globalId,
|
|
119
|
+
usedImports,
|
|
120
|
+
modified: false,
|
|
121
|
+
createIds: !options.disableIds,
|
|
122
|
+
warnings,
|
|
123
|
+
file,
|
|
124
|
+
};
|
|
125
|
+
const wrapped = handleJsxElement(path.node, opts, isMeaningful);
|
|
126
|
+
path.replaceWith(wrapped.node);
|
|
127
|
+
// Update global counters
|
|
128
|
+
modified = modified || opts.modified;
|
|
129
|
+
globalId = opts.idCount;
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
if (!modified)
|
|
133
|
+
continue;
|
|
134
|
+
const needsImport = usedImports.filter((imp) => typeof imp === 'string'
|
|
135
|
+
? !initialImports.includes(imp)
|
|
136
|
+
: !initialImports.includes(imp.local));
|
|
137
|
+
if (needsImport.length > 0) {
|
|
138
|
+
createImports(ast, needsImport, IMPORT_MAP);
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const output = generate(ast, {
|
|
142
|
+
retainLines: true,
|
|
143
|
+
retainFunctionParens: true,
|
|
144
|
+
comments: true,
|
|
145
|
+
compact: 'auto',
|
|
146
|
+
}, code);
|
|
147
|
+
// Post-process the output to fix import spacing
|
|
148
|
+
let processedCode = output.code;
|
|
149
|
+
if (needsImport.length > 0) {
|
|
150
|
+
// Add newline after the comment only
|
|
151
|
+
processedCode = processedCode.replace(/((?:import\s*{\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale)(?:\s*,\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale))*\s*}\s*from|const\s*{\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale)(?:\s*,\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale))*\s*}\s*=\s*require)\s*['"]gt-(?:next|react)(?:\/server)?['"];?)/, '\n$1\n');
|
|
152
|
+
}
|
|
153
|
+
// Write the modified code back to the file
|
|
154
|
+
await fs.promises.writeFile(file, processedCode);
|
|
155
|
+
filesUpdated.push(file);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
errors.push(`Error: Failed to write ${file}: ${error}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { filesUpdated };
|
|
162
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Dictionary, FlattenedDictionary, FlattenedJSONDictionary, JSONDictionary } from '../../types/data.js';
|
|
2
|
+
/**
|
|
3
|
+
* Flattens a nested dictionary by concatenating nested keys.
|
|
4
|
+
* Throws an error if two keys result in the same flattened key.
|
|
5
|
+
* @param {Record<string, any>} dictionary - The dictionary to flatten.
|
|
6
|
+
* @param {string} [prefix=''] - The prefix for nested keys.
|
|
7
|
+
* @returns {Record<string, React.ReactNode>} The flattened dictionary object.
|
|
8
|
+
* @throws {Error} If two keys result in the same flattened key.
|
|
9
|
+
*/
|
|
10
|
+
export default function flattenDictionary(dictionary: Dictionary, prefix?: string): FlattenedDictionary;
|
|
11
|
+
/**
|
|
12
|
+
* Flattens a nested dictionary containing only string values
|
|
13
|
+
* Throws an error if two keys result in the same flattened key.
|
|
14
|
+
* @param {JSONDictionary} dictionary - The dictionary to flatten.
|
|
15
|
+
* @param {string} [prefix=''] - The prefix for nested keys.
|
|
16
|
+
* @returns {FlattenedJSONDictionary} The flattened dictionary with string values.
|
|
17
|
+
* @throws {Error} If two keys result in the same flattened key.
|
|
18
|
+
* @throws {Error} If a value is an array.
|
|
19
|
+
*/
|
|
20
|
+
export declare function flattenJsonDictionary(dictionary: JSONDictionary, prefix?: string): FlattenedJSONDictionary;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { logErrorAndExit } from '../../console/logging.js';
|
|
2
|
+
const createDuplicateKeyError = (key) => `Duplicate key found in dictionary: "${key}"`;
|
|
3
|
+
/**
|
|
4
|
+
* Flattens a nested dictionary by concatenating nested keys.
|
|
5
|
+
* Throws an error if two keys result in the same flattened key.
|
|
6
|
+
* @param {Record<string, any>} dictionary - The dictionary to flatten.
|
|
7
|
+
* @param {string} [prefix=''] - The prefix for nested keys.
|
|
8
|
+
* @returns {Record<string, React.ReactNode>} The flattened dictionary object.
|
|
9
|
+
* @throws {Error} If two keys result in the same flattened key.
|
|
10
|
+
*/
|
|
11
|
+
export default function flattenDictionary(dictionary, prefix = '') {
|
|
12
|
+
const flattened = {};
|
|
13
|
+
for (const key in dictionary) {
|
|
14
|
+
if (dictionary.hasOwnProperty(key)) {
|
|
15
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
16
|
+
if (typeof dictionary[key] === 'object' &&
|
|
17
|
+
dictionary[key] !== null &&
|
|
18
|
+
!Array.isArray(dictionary[key])) {
|
|
19
|
+
const nestedFlattened = flattenDictionary(dictionary[key], newKey);
|
|
20
|
+
for (const flatKey in nestedFlattened) {
|
|
21
|
+
if (flattened.hasOwnProperty(flatKey)) {
|
|
22
|
+
logErrorAndExit(createDuplicateKeyError(flatKey));
|
|
23
|
+
}
|
|
24
|
+
flattened[flatKey] = nestedFlattened[flatKey];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
if (flattened.hasOwnProperty(newKey)) {
|
|
29
|
+
logErrorAndExit(createDuplicateKeyError(newKey));
|
|
30
|
+
}
|
|
31
|
+
flattened[newKey] = dictionary[key];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return flattened;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Flattens a nested dictionary containing only string values
|
|
39
|
+
* Throws an error if two keys result in the same flattened key.
|
|
40
|
+
* @param {JSONDictionary} dictionary - The dictionary to flatten.
|
|
41
|
+
* @param {string} [prefix=''] - The prefix for nested keys.
|
|
42
|
+
* @returns {FlattenedJSONDictionary} The flattened dictionary with string values.
|
|
43
|
+
* @throws {Error} If two keys result in the same flattened key.
|
|
44
|
+
* @throws {Error} If a value is an array.
|
|
45
|
+
*/
|
|
46
|
+
export function flattenJsonDictionary(dictionary, prefix = '') {
|
|
47
|
+
const flattened = {};
|
|
48
|
+
for (const key in dictionary) {
|
|
49
|
+
if (dictionary.hasOwnProperty(key)) {
|
|
50
|
+
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
51
|
+
const value = dictionary[key];
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
logErrorAndExit(`Arrays are not supported in JSON dictionary at key: "${newKey}"`);
|
|
54
|
+
}
|
|
55
|
+
else if (typeof value === 'object' && value !== null) {
|
|
56
|
+
// Recursively flatten nested objects
|
|
57
|
+
const nestedFlattened = flattenJsonDictionary(value, newKey);
|
|
58
|
+
for (const flatKey in nestedFlattened) {
|
|
59
|
+
if (flattened.hasOwnProperty(flatKey)) {
|
|
60
|
+
logErrorAndExit(createDuplicateKeyError(flatKey));
|
|
61
|
+
}
|
|
62
|
+
flattened[flatKey] = nestedFlattened[flatKey];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (typeof value === 'string') {
|
|
66
|
+
// Handle string values
|
|
67
|
+
if (flattened.hasOwnProperty(newKey)) {
|
|
68
|
+
logErrorAndExit(createDuplicateKeyError(newKey));
|
|
69
|
+
}
|
|
70
|
+
flattened[newKey] = value;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return flattened;
|
|
75
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default function getEntryAndMetadata(value) {
|
|
2
|
+
if (Array.isArray(value)) {
|
|
3
|
+
if (value.length === 1) {
|
|
4
|
+
return { entry: value[0] };
|
|
5
|
+
}
|
|
6
|
+
if (value.length === 2) {
|
|
7
|
+
return { entry: value[0], metadata: value[1] };
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return { entry: value };
|
|
11
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { VariableType } from 'generaltranslation/types';
|
|
2
|
+
/**
|
|
3
|
+
* These are the names of the variable components as they appear in gt-next and gt-react
|
|
4
|
+
*/
|
|
5
|
+
export declare const defaultVariableNames: {
|
|
6
|
+
readonly Var: "value";
|
|
7
|
+
readonly Num: "n";
|
|
8
|
+
readonly DateTime: "date";
|
|
9
|
+
readonly Currency: "cost";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Minify the variable type from the name of the variable component (from gt-next and gt-react)
|
|
13
|
+
* @param variableType - The type of the variable (Var, Num, DateTime, Currency)
|
|
14
|
+
* @returns The minified variable type
|
|
15
|
+
*/
|
|
16
|
+
export declare const minifyVariableType: (variableType: keyof typeof defaultVariableNames) => VariableType;
|
|
17
|
+
export declare const baseVariablePrefix = "_gt_";
|
|
18
|
+
/**
|
|
19
|
+
* Get the name of a variable
|
|
20
|
+
* @param props - The props of the variable
|
|
21
|
+
* @param variableType - The type of the variable (Var, Num, DateTime, Currency)
|
|
22
|
+
* @param id - The id of the variable
|
|
23
|
+
* @returns The name of the variable
|
|
24
|
+
*/
|
|
25
|
+
export declare function getVariableName(props: Record<string, any> | undefined, variableType: keyof typeof defaultVariableNames, id: number): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are the names of the variable components as they appear in gt-next and gt-react
|
|
3
|
+
*/
|
|
4
|
+
export const defaultVariableNames = {
|
|
5
|
+
Var: 'value',
|
|
6
|
+
Num: 'n',
|
|
7
|
+
DateTime: 'date',
|
|
8
|
+
Currency: 'cost',
|
|
9
|
+
};
|
|
10
|
+
const minifyVariableTypeMap = {
|
|
11
|
+
Var: 'v',
|
|
12
|
+
Num: 'n',
|
|
13
|
+
DateTime: 'd',
|
|
14
|
+
Currency: 'c',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Minify the variable type from the name of the variable component (from gt-next and gt-react)
|
|
18
|
+
* @param variableType - The type of the variable (Var, Num, DateTime, Currency)
|
|
19
|
+
* @returns The minified variable type
|
|
20
|
+
*/
|
|
21
|
+
export const minifyVariableType = (variableType) => {
|
|
22
|
+
return minifyVariableTypeMap[variableType];
|
|
23
|
+
};
|
|
24
|
+
export const baseVariablePrefix = '_gt_';
|
|
25
|
+
/**
|
|
26
|
+
* Get the name of a variable
|
|
27
|
+
* @param props - The props of the variable
|
|
28
|
+
* @param variableType - The type of the variable (Var, Num, DateTime, Currency)
|
|
29
|
+
* @param id - The id of the variable
|
|
30
|
+
* @returns The name of the variable
|
|
31
|
+
*/
|
|
32
|
+
export function getVariableName(props = {}, variableType, id) {
|
|
33
|
+
if (props.name)
|
|
34
|
+
return props.name;
|
|
35
|
+
const baseVariableName = defaultVariableNames[variableType] || 'value';
|
|
36
|
+
return `${baseVariablePrefix}${baseVariableName}_${id}`;
|
|
37
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { libraryDefaultLocale } from 'generaltranslation/internal';
|
|
2
|
+
import { promptText } from '../console/logging.js';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { gt } from '../utils/gt.js';
|
|
5
|
+
export async function getDesiredLocales() {
|
|
6
|
+
// Ask for the default locale
|
|
7
|
+
const defaultLocale = await promptText({
|
|
8
|
+
message: 'What is the default locale for your project?',
|
|
9
|
+
defaultValue: libraryDefaultLocale,
|
|
10
|
+
});
|
|
11
|
+
// Ask for the locales
|
|
12
|
+
const locales = await promptText({
|
|
13
|
+
message: `What locales would you like to translate your project into? ${chalk.dim('(space-separated list)')}`,
|
|
14
|
+
defaultValue: 'es zh fr de ja',
|
|
15
|
+
validate: (input) => {
|
|
16
|
+
const localeList = input.split(' ');
|
|
17
|
+
if (localeList.length === 0) {
|
|
18
|
+
return 'Please enter at least one locale';
|
|
19
|
+
}
|
|
20
|
+
for (const locale of localeList) {
|
|
21
|
+
if (!gt.isValidLocale(locale)) {
|
|
22
|
+
return 'Please enter a valid locale (e.g., en, fr, es)';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
return { defaultLocale, locales: locales.split(' ') };
|
|
29
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { detectFormatter } from '../hooks/postProcess.js';
|
|
2
|
+
import { createSpinner, promptSelect } from '../console/logging.js';
|
|
3
|
+
import { logInfo, logError, logStep, logWarning } from '../console/logging.js';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { promptConfirm } from '../console/logging.js';
|
|
6
|
+
import findFilepath from '../fs/findFilepath.js';
|
|
7
|
+
import { formatFiles } from '../hooks/postProcess.js';
|
|
8
|
+
import { handleInitGT } from '../next/parse/handleInitGT.js';
|
|
9
|
+
import { getPackageJson, isPackageInstalled } from '../utils/packageJson.js';
|
|
10
|
+
import { wrapContentNext } from '../next/parse/wrapContent.js';
|
|
11
|
+
import { getPackageManager } from '../utils/packageManager.js';
|
|
12
|
+
import { installPackage } from '../utils/installPackage.js';
|
|
13
|
+
import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
|
|
14
|
+
import { loadConfig } from '../fs/config/loadConfig.js';
|
|
15
|
+
export async function handleSetupReactCommand(options) {
|
|
16
|
+
// Ask user for confirmation using inquirer
|
|
17
|
+
const answer = await promptConfirm({
|
|
18
|
+
message: chalk.yellow(`This wizard will configure your React project for internationalization with GT.
|
|
19
|
+
If your project is already using a different i18n library, this wizard may cause issues.
|
|
20
|
+
|
|
21
|
+
Make sure you have committed or stashed any changes. Do you want to continue?`),
|
|
22
|
+
defaultValue: true,
|
|
23
|
+
cancelMessage: 'Operation cancelled. You can re-run this wizard with: npx gtx-cli setup',
|
|
24
|
+
});
|
|
25
|
+
if (!answer) {
|
|
26
|
+
logInfo('Operation cancelled. You can re-run this wizard with: npx gtx-cli setup');
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
const frameworkType = await promptSelect({
|
|
30
|
+
message: 'What framework are you using?',
|
|
31
|
+
options: [
|
|
32
|
+
{ value: 'next-app', label: chalk.blue('Next.js App Router') },
|
|
33
|
+
{ value: 'next-pages', label: chalk.green('Next.js Pages Router') },
|
|
34
|
+
{ value: 'vite', label: chalk.cyan('Vite + React') },
|
|
35
|
+
{ value: 'gatsby', label: chalk.magenta('Gatsby') },
|
|
36
|
+
{ value: 'react', label: chalk.yellow('React') },
|
|
37
|
+
{ value: 'redwood', label: chalk.red('RedwoodJS') },
|
|
38
|
+
{ value: 'other', label: chalk.dim('Other') },
|
|
39
|
+
],
|
|
40
|
+
defaultValue: 'next-app',
|
|
41
|
+
});
|
|
42
|
+
if (frameworkType === 'other') {
|
|
43
|
+
logError(`Sorry, other React frameworks are not currently supported.
|
|
44
|
+
Please let us know what you would like to see supported at https://github.com/generaltranslation/gt/issues`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
// ----- Create a starter gt.config.json file -----
|
|
48
|
+
await createOrUpdateConfig(options.config || 'gt.config.json', {
|
|
49
|
+
framework: frameworkType,
|
|
50
|
+
});
|
|
51
|
+
const packageJson = await getPackageJson();
|
|
52
|
+
if (!packageJson) {
|
|
53
|
+
logError(chalk.red('No package.json found in the current directory. Please run this command from the root of your project.'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
// Check if gt-next or gt-react is installed
|
|
57
|
+
if (frameworkType === 'next-app' &&
|
|
58
|
+
!isPackageInstalled('gt-next', packageJson)) {
|
|
59
|
+
const packageManager = await getPackageManager();
|
|
60
|
+
const spinner = createSpinner('timer');
|
|
61
|
+
spinner.start(`Installing gt-next with ${packageManager.name}...`);
|
|
62
|
+
await installPackage('gt-next', packageManager);
|
|
63
|
+
spinner.stop(chalk.green('Automatically installed gt-next.'));
|
|
64
|
+
}
|
|
65
|
+
else if (['next-pages', 'react', 'redwood', 'vite', 'gatsby'].includes(frameworkType) &&
|
|
66
|
+
!isPackageInstalled('gt-react', packageJson)) {
|
|
67
|
+
const packageManager = await getPackageManager();
|
|
68
|
+
const spinner = createSpinner('timer');
|
|
69
|
+
spinner.start(`Installing gt-react with ${packageManager.name}...`);
|
|
70
|
+
await installPackage('gt-react', packageManager);
|
|
71
|
+
spinner.stop(chalk.green('Automatically installed gt-react.'));
|
|
72
|
+
}
|
|
73
|
+
const errors = [];
|
|
74
|
+
const warnings = [];
|
|
75
|
+
let filesUpdated = [];
|
|
76
|
+
if (frameworkType === 'next-app') {
|
|
77
|
+
// Check if they have a next.config.js file
|
|
78
|
+
const nextConfigPath = findFilepath([
|
|
79
|
+
'./next.config.js',
|
|
80
|
+
'./next.config.ts',
|
|
81
|
+
'./next.config.mjs',
|
|
82
|
+
'./next.config.mts',
|
|
83
|
+
]);
|
|
84
|
+
if (!nextConfigPath) {
|
|
85
|
+
logError('No next.config.[js|ts|mjs|mts] file found.');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const mergeOptions = {
|
|
89
|
+
...options,
|
|
90
|
+
disableIds: true,
|
|
91
|
+
disableFormatting: true,
|
|
92
|
+
skipTs: true,
|
|
93
|
+
addGTProvider: true,
|
|
94
|
+
};
|
|
95
|
+
const spinner = createSpinner();
|
|
96
|
+
spinner.start('Wrapping JSX content with <T> tags...');
|
|
97
|
+
// Wrap all JSX elements in the src directory with a <T> tag, with unique ids
|
|
98
|
+
const { filesUpdated: filesUpdatedNext } = await wrapContentNext(mergeOptions, 'gt-next', errors, warnings);
|
|
99
|
+
filesUpdated = [...filesUpdated, ...filesUpdatedNext];
|
|
100
|
+
spinner.stop(chalk.green(`Success! Updated ${chalk.bold.cyan(filesUpdated.length)} files:\n`) + filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\n'));
|
|
101
|
+
// Read tsconfig.json if it exists
|
|
102
|
+
const tsconfigPath = findFilepath(['tsconfig.json']);
|
|
103
|
+
const tsconfigJson = tsconfigPath ? loadConfig(tsconfigPath) : undefined;
|
|
104
|
+
// Add the withGTConfig() function to the next.config.js file
|
|
105
|
+
await handleInitGT(nextConfigPath, errors, warnings, filesUpdated, packageJson, tsconfigJson);
|
|
106
|
+
logStep(chalk.green(`Added withGTConfig() to your ${nextConfigPath} file.`));
|
|
107
|
+
}
|
|
108
|
+
if (errors.length > 0) {
|
|
109
|
+
logError(chalk.red('Failed to write files:\n') + errors.join('\n'));
|
|
110
|
+
}
|
|
111
|
+
if (warnings.length > 0) {
|
|
112
|
+
logWarning(chalk.yellow('Warnings encountered:') +
|
|
113
|
+
'\n' +
|
|
114
|
+
warnings.map((warning) => `${chalk.yellow('-')} ${warning}`).join('\n'));
|
|
115
|
+
}
|
|
116
|
+
const formatter = await detectFormatter();
|
|
117
|
+
if (!formatter || filesUpdated.length === 0) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const applyFormatting = await promptConfirm({
|
|
121
|
+
message: `Would you like the wizard to auto-format the modified files? ${chalk.dim(`(${formatter})`)}`,
|
|
122
|
+
defaultValue: true,
|
|
123
|
+
});
|
|
124
|
+
// Format updated files if formatters are available
|
|
125
|
+
if (applyFormatting)
|
|
126
|
+
await formatFiles(filesUpdated, formatter);
|
|
127
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Updates, TranslateFlags } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Searches for gt-react or gt-next dictionary files and creates updates for them,
|
|
4
|
+
* as well as inline updates for <T> tags and useGT()/getGT() calls
|
|
5
|
+
*
|
|
6
|
+
* @param options - The options object
|
|
7
|
+
* @param sourceDictionary - The source dictionary file path
|
|
8
|
+
* @param pkg - The package name
|
|
9
|
+
* @returns An object containing the updates and errors
|
|
10
|
+
*/
|
|
11
|
+
export declare function createUpdates(options: TranslateFlags, src: string[] | undefined, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next', validate: boolean): Promise<{
|
|
12
|
+
updates: Updates;
|
|
13
|
+
errors: string[];
|
|
14
|
+
warnings: string[];
|
|
15
|
+
}>;
|