gtx-cli 2.3.5 → 2.3.6-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/package.json +23 -18
- package/dist/api/checkFileTranslations.d.ts +0 -23
- package/dist/api/checkFileTranslations.js +0 -236
- package/dist/api/downloadFileBatch.d.ts +0 -20
- package/dist/api/downloadFileBatch.js +0 -113
- package/dist/api/sendFiles.d.ts +0 -17
- package/dist/api/sendFiles.js +0 -115
- package/dist/api/uploadFiles.d.ts +0 -27
- package/dist/api/uploadFiles.js +0 -40
- package/dist/cli/base.d.ts +0 -32
- package/dist/cli/base.js +0 -335
- package/dist/cli/commands/stage.d.ts +0 -5
- package/dist/cli/commands/stage.js +0 -100
- package/dist/cli/commands/translate.d.ts +0 -6
- package/dist/cli/commands/translate.js +0 -63
- package/dist/cli/flags.d.ts +0 -3
- package/dist/cli/flags.js +0 -38
- package/dist/cli/next.d.ts +0 -11
- package/dist/cli/next.js +0 -20
- package/dist/cli/react.d.ts +0 -18
- package/dist/cli/react.js +0 -175
- package/dist/config/generateSettings.d.ts +0 -9
- package/dist/config/generateSettings.js +0 -176
- package/dist/config/optionPresets.d.ts +0 -2
- package/dist/config/optionPresets.js +0 -56
- package/dist/config/resolveConfig.d.ts +0 -4
- package/dist/config/resolveConfig.js +0 -19
- package/dist/config/utils.d.ts +0 -2
- package/dist/config/utils.js +0 -4
- package/dist/config/validateSettings.d.ts +0 -3
- package/dist/config/validateSettings.js +0 -32
- package/dist/console/colors.d.ts +0 -5
- package/dist/console/colors.js +0 -16
- package/dist/console/index.d.ts +0 -21
- package/dist/console/index.js +0 -24
- package/dist/console/logging.d.ts +0 -53
- package/dist/console/logging.js +0 -185
- package/dist/formats/files/fileMapping.d.ts +0 -11
- package/dist/formats/files/fileMapping.js +0 -82
- package/dist/formats/files/save.d.ts +0 -5
- package/dist/formats/files/save.js +0 -17
- package/dist/formats/files/supportedFiles.d.ts +0 -10
- package/dist/formats/files/supportedFiles.js +0 -18
- package/dist/formats/files/translate.d.ts +0 -4
- package/dist/formats/files/translate.js +0 -119
- package/dist/formats/files/upload.d.ts +0 -13
- package/dist/formats/files/upload.js +0 -136
- package/dist/formats/gt/save.d.ts +0 -9
- package/dist/formats/gt/save.js +0 -26
- package/dist/formats/json/flattenJson.d.ts +0 -14
- package/dist/formats/json/flattenJson.js +0 -64
- package/dist/formats/json/mergeJson.d.ts +0 -13
- package/dist/formats/json/mergeJson.js +0 -257
- package/dist/formats/json/parseJson.d.ts +0 -2
- package/dist/formats/json/parseJson.js +0 -108
- package/dist/formats/json/utils.d.ts +0 -47
- package/dist/formats/json/utils.js +0 -149
- package/dist/formats/utils.d.ts +0 -2
- package/dist/formats/utils.js +0 -24
- package/dist/formats/yaml/mergeYaml.d.ts +0 -5
- package/dist/formats/yaml/mergeYaml.js +0 -55
- package/dist/formats/yaml/parseYaml.d.ts +0 -5
- package/dist/formats/yaml/parseYaml.js +0 -23
- package/dist/formats/yaml/utils.d.ts +0 -2
- package/dist/formats/yaml/utils.js +0 -22
- package/dist/fs/config/loadConfig.d.ts +0 -1
- package/dist/fs/config/loadConfig.js +0 -9
- package/dist/fs/config/parseFilesConfig.d.ts +0 -27
- package/dist/fs/config/parseFilesConfig.js +0 -129
- package/dist/fs/config/setupConfig.d.ts +0 -17
- package/dist/fs/config/setupConfig.js +0 -50
- package/dist/fs/config/updateConfig.d.ts +0 -10
- package/dist/fs/config/updateConfig.js +0 -36
- package/dist/fs/config/updateVersions.d.ts +0 -10
- package/dist/fs/config/updateVersions.js +0 -30
- package/dist/fs/copyFile.d.ts +0 -7
- package/dist/fs/copyFile.js +0 -39
- package/dist/fs/createLoadTranslationsFile.d.ts +0 -1
- package/dist/fs/createLoadTranslationsFile.js +0 -36
- package/dist/fs/determineFramework.d.ts +0 -5
- package/dist/fs/determineFramework.js +0 -46
- package/dist/fs/findFilepath.d.ts +0 -36
- package/dist/fs/findFilepath.js +0 -89
- package/dist/fs/getPackageResource.d.ts +0 -1
- package/dist/fs/getPackageResource.js +0 -6
- package/dist/fs/index.d.ts +0 -1
- package/dist/fs/index.js +0 -1
- package/dist/fs/loadJSON.d.ts +0 -6
- package/dist/fs/loadJSON.js +0 -17
- package/dist/fs/matchFiles.d.ts +0 -1
- package/dist/fs/matchFiles.js +0 -8
- package/dist/fs/saveJSON.d.ts +0 -1
- package/dist/fs/saveJSON.js +0 -7
- package/dist/fs/utils.d.ts +0 -1
- package/dist/fs/utils.js +0 -16
- package/dist/hooks/postProcess.d.ts +0 -4
- package/dist/hooks/postProcess.js +0 -110
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -20
- package/dist/main.d.ts +0 -2
- package/dist/main.js +0 -9
- package/dist/next/config/parseNextConfig.d.ts +0 -10
- package/dist/next/config/parseNextConfig.js +0 -53
- package/dist/next/jsx/utils.d.ts +0 -7
- package/dist/next/jsx/utils.js +0 -42
- package/dist/next/parse/handleInitGT.d.ts +0 -7
- package/dist/next/parse/handleInitGT.js +0 -208
- package/dist/next/parse/wrapContent.d.ts +0 -11
- package/dist/next/parse/wrapContent.js +0 -163
- package/dist/react/config/createESBuildConfig.d.ts +0 -2
- package/dist/react/config/createESBuildConfig.js +0 -119
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +0 -8
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +0 -111
- package/dist/react/jsx/evaluateJsx.d.ts +0 -17
- package/dist/react/jsx/evaluateJsx.js +0 -85
- package/dist/react/jsx/trimJsxStringChildren.d.ts +0 -7
- package/dist/react/jsx/trimJsxStringChildren.js +0 -95
- package/dist/react/jsx/utils/constants.d.ts +0 -10
- package/dist/react/jsx/utils/constants.js +0 -31
- package/dist/react/jsx/utils/parseAst.d.ts +0 -30
- package/dist/react/jsx/utils/parseAst.js +0 -277
- package/dist/react/jsx/utils/parseJsx.d.ts +0 -21
- package/dist/react/jsx/utils/parseJsx.js +0 -244
- package/dist/react/jsx/utils/parseStringFunction.d.ts +0 -16
- package/dist/react/jsx/utils/parseStringFunction.js +0 -411
- package/dist/react/jsx/utils/validateStringFunction.d.ts +0 -7
- package/dist/react/jsx/utils/validateStringFunction.js +0 -31
- package/dist/react/jsx/wrapJsx.d.ts +0 -51
- package/dist/react/jsx/wrapJsx.js +0 -387
- package/dist/react/parse/createDictionaryUpdates.d.ts +0 -3
- package/dist/react/parse/createDictionaryUpdates.js +0 -169
- package/dist/react/parse/createInlineUpdates.d.ts +0 -6
- package/dist/react/parse/createInlineUpdates.js +0 -122
- package/dist/react/parse/wrapContent.d.ts +0 -11
- package/dist/react/parse/wrapContent.js +0 -162
- package/dist/react/utils/flattenDictionary.d.ts +0 -20
- package/dist/react/utils/flattenDictionary.js +0 -75
- package/dist/react/utils/getEntryAndMetadata.d.ts +0 -5
- package/dist/react/utils/getEntryAndMetadata.js +0 -11
- package/dist/react/utils/getVariableName.d.ts +0 -25
- package/dist/react/utils/getVariableName.js +0 -37
- package/dist/setup/userInput.d.ts +0 -4
- package/dist/setup/userInput.js +0 -29
- package/dist/setup/wizard.d.ts +0 -2
- package/dist/setup/wizard.js +0 -127
- package/dist/translation/parse.d.ts +0 -15
- package/dist/translation/parse.js +0 -76
- package/dist/translation/stage.d.ts +0 -2
- package/dist/translation/stage.js +0 -44
- package/dist/translation/validate.d.ts +0 -2
- package/dist/translation/validate.js +0 -50
- package/dist/types/data/json.d.ts +0 -6
- package/dist/types/data/json.js +0 -1
- package/dist/types/data.d.ts +0 -30
- package/dist/types/data.js +0 -1
- package/dist/types/files.d.ts +0 -1
- package/dist/types/files.js +0 -1
- package/dist/types/index.d.ts +0 -173
- package/dist/types/index.js +0 -1
- package/dist/utils/addExplicitAnchorIds.d.ts +0 -24
- package/dist/utils/addExplicitAnchorIds.js +0 -260
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +0 -2
- package/dist/utils/credentials.d.ts +0 -12
- package/dist/utils/credentials.js +0 -119
- package/dist/utils/flattenJsonFiles.d.ts +0 -2
- package/dist/utils/flattenJsonFiles.js +0 -36
- package/dist/utils/gt.d.ts +0 -2
- package/dist/utils/gt.js +0 -2
- package/dist/utils/hash.d.ts +0 -6
- package/dist/utils/hash.js +0 -11
- package/dist/utils/headers.d.ts +0 -1
- package/dist/utils/headers.js +0 -14
- package/dist/utils/installPackage.d.ts +0 -3
- package/dist/utils/installPackage.js +0 -77
- package/dist/utils/localizeStaticImports.d.ts +0 -15
- package/dist/utils/localizeStaticImports.js +0 -341
- package/dist/utils/localizeStaticUrls.d.ts +0 -19
- package/dist/utils/localizeStaticUrls.js +0 -432
- package/dist/utils/packageInfo.d.ts +0 -3
- package/dist/utils/packageInfo.js +0 -17
- package/dist/utils/packageJson.d.ts +0 -6
- package/dist/utils/packageJson.js +0 -76
- package/dist/utils/packageManager.d.ts +0 -28
- package/dist/utils/packageManager.js +0 -269
- package/dist/utils/processAnchorIds.d.ts +0 -6
- package/dist/utils/processAnchorIds.js +0 -47
- package/dist/utils/sanitizeFileContent.d.ts +0 -6
- package/dist/utils/sanitizeFileContent.js +0 -29
- package/dist/utils/validateMdx.d.ts +0 -10
- package/dist/utils/validateMdx.js +0 -25
package/dist/console/logging.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { log, spinner, intro, outro, text, select, confirm, isCancel, cancel, multiselect, } from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { getCLIVersion } from '../utils/packageJson.js';
|
|
4
|
-
// Basic logging functions
|
|
5
|
-
export function logInfo(message) {
|
|
6
|
-
log.info(message);
|
|
7
|
-
}
|
|
8
|
-
export function logWarning(message) {
|
|
9
|
-
log.warn(message);
|
|
10
|
-
}
|
|
11
|
-
export function logError(message) {
|
|
12
|
-
log.error(message);
|
|
13
|
-
}
|
|
14
|
-
export function logSuccess(message) {
|
|
15
|
-
log.success(message);
|
|
16
|
-
}
|
|
17
|
-
export function logStep(message) {
|
|
18
|
-
log.step(message);
|
|
19
|
-
}
|
|
20
|
-
export function logMessage(message) {
|
|
21
|
-
log.message(message, { symbol: chalk.cyan('~') });
|
|
22
|
-
}
|
|
23
|
-
export function logErrorAndExit(message) {
|
|
24
|
-
log.error(message);
|
|
25
|
-
exit(1);
|
|
26
|
-
}
|
|
27
|
-
export function exit(code) {
|
|
28
|
-
process.exit(code);
|
|
29
|
-
}
|
|
30
|
-
// Clack prompts
|
|
31
|
-
export function startCommand(message) {
|
|
32
|
-
intro(chalk.cyan(message));
|
|
33
|
-
}
|
|
34
|
-
export function endCommand(message) {
|
|
35
|
-
outro(chalk.cyan(message));
|
|
36
|
-
}
|
|
37
|
-
// GT specific logging
|
|
38
|
-
export function displayHeader(introString) {
|
|
39
|
-
displayAsciiTitle();
|
|
40
|
-
displayInitializingText();
|
|
41
|
-
if (introString) {
|
|
42
|
-
startCommand(introString);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function displayAsciiTitle() {
|
|
46
|
-
console.log(chalk.cyan(`\n ,ad8888ba, 888888888888
|
|
47
|
-
d8"' \`"8b 88
|
|
48
|
-
d8' 88
|
|
49
|
-
88 88
|
|
50
|
-
88 88888 88
|
|
51
|
-
Y8, 88 88
|
|
52
|
-
Y8a. .a88 88
|
|
53
|
-
\`"Y88888P" 88 `));
|
|
54
|
-
}
|
|
55
|
-
function displayInitializingText() {
|
|
56
|
-
const version = getCLIVersion();
|
|
57
|
-
console.log(`\n${chalk.bold.blue('General Translation, Inc.')}
|
|
58
|
-
${chalk.dim('https://generaltranslation.com/docs')}
|
|
59
|
-
${chalk.dim(`CLI Version: ${version}\n`)}`);
|
|
60
|
-
}
|
|
61
|
-
export function displayProjectId(projectId) {
|
|
62
|
-
logMessage(chalk.dim(`Project ID: ${chalk.bold(projectId)}`));
|
|
63
|
-
}
|
|
64
|
-
export function displayResolvedPaths(resolvedPaths) {
|
|
65
|
-
const paths = resolvedPaths.map(([key, resolvedPath]) => {
|
|
66
|
-
return chalk.dim(`'${chalk.white(key)}' → '${chalk.green(resolvedPath)}'`);
|
|
67
|
-
});
|
|
68
|
-
log.step(`Resolved path aliases:\n${paths.join('\n')}`);
|
|
69
|
-
}
|
|
70
|
-
export function displayCreatedConfigFile(configFilepath) {
|
|
71
|
-
log.step(`Created config file ${chalk.cyan(configFilepath)}`);
|
|
72
|
-
}
|
|
73
|
-
export function displayUpdatedConfigFile(configFilepath) {
|
|
74
|
-
log.success(`Updated config file ${chalk.cyan(configFilepath)}`);
|
|
75
|
-
}
|
|
76
|
-
export function displayUpdatedVersionsFile(versionFilepath) {
|
|
77
|
-
log.success(`Updated versions file ${chalk.cyan(versionFilepath)}`);
|
|
78
|
-
}
|
|
79
|
-
// Spinner functionality
|
|
80
|
-
export function createSpinner(indicator = 'timer') {
|
|
81
|
-
return spinner({ indicator });
|
|
82
|
-
}
|
|
83
|
-
// Spinner functionality
|
|
84
|
-
export async function createOraSpinner(indicator = 'circleHalves') {
|
|
85
|
-
const ora = await import('ora');
|
|
86
|
-
return ora.default({ spinner: indicator });
|
|
87
|
-
}
|
|
88
|
-
// Input prompts
|
|
89
|
-
export async function promptText({ message, defaultValue, validate, }) {
|
|
90
|
-
const result = await text({
|
|
91
|
-
message,
|
|
92
|
-
placeholder: defaultValue,
|
|
93
|
-
validate: validate
|
|
94
|
-
? (value) => {
|
|
95
|
-
const validation = validate(value || '');
|
|
96
|
-
return validation === true ? undefined : validation.toString();
|
|
97
|
-
}
|
|
98
|
-
: undefined,
|
|
99
|
-
});
|
|
100
|
-
if (isCancel(result)) {
|
|
101
|
-
cancel('Operation cancelled');
|
|
102
|
-
process.exit(0);
|
|
103
|
-
}
|
|
104
|
-
return result;
|
|
105
|
-
}
|
|
106
|
-
export async function promptSelect({ message, options, defaultValue, }) {
|
|
107
|
-
// Convert options to the format expected by clack
|
|
108
|
-
const clackOptions = options.map((opt) => ({
|
|
109
|
-
value: opt.value,
|
|
110
|
-
label: opt.label,
|
|
111
|
-
hint: opt.hint,
|
|
112
|
-
}));
|
|
113
|
-
const result = await select({
|
|
114
|
-
message,
|
|
115
|
-
options: clackOptions,
|
|
116
|
-
initialValue: defaultValue,
|
|
117
|
-
});
|
|
118
|
-
if (isCancel(result)) {
|
|
119
|
-
cancel('Operation cancelled');
|
|
120
|
-
process.exit(0);
|
|
121
|
-
}
|
|
122
|
-
return result;
|
|
123
|
-
}
|
|
124
|
-
export async function promptMultiSelect({ message, options, required = true, }) {
|
|
125
|
-
// Convert options to the format expected by clack
|
|
126
|
-
const clackOptions = options.map((opt) => ({
|
|
127
|
-
value: opt.value,
|
|
128
|
-
label: opt.label,
|
|
129
|
-
hint: opt.hint,
|
|
130
|
-
}));
|
|
131
|
-
const result = await multiselect({
|
|
132
|
-
message,
|
|
133
|
-
options: clackOptions,
|
|
134
|
-
required,
|
|
135
|
-
});
|
|
136
|
-
if (isCancel(result)) {
|
|
137
|
-
cancel('Operation cancelled');
|
|
138
|
-
process.exit(0);
|
|
139
|
-
}
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
export async function promptConfirm({ message, defaultValue = true, cancelMessage = 'Operation cancelled', }) {
|
|
143
|
-
const result = await confirm({
|
|
144
|
-
message,
|
|
145
|
-
initialValue: defaultValue,
|
|
146
|
-
});
|
|
147
|
-
if (isCancel(result)) {
|
|
148
|
-
cancel(cancelMessage);
|
|
149
|
-
process.exit(0);
|
|
150
|
-
}
|
|
151
|
-
return result;
|
|
152
|
-
}
|
|
153
|
-
// Warning display functions
|
|
154
|
-
export function warnApiKeyInConfig(optionsFilepath) {
|
|
155
|
-
log.warn(`Found ${chalk.cyan('apiKey')} in "${chalk.green(optionsFilepath)}". ` +
|
|
156
|
-
chalk.white('Your API key is exposed! Please remove it from the file and include it as an environment variable.'));
|
|
157
|
-
}
|
|
158
|
-
export function warnVariableProp(file, attrName, value) {
|
|
159
|
-
log.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with variable ${attrName}: "${chalk.white(value)}". ` +
|
|
160
|
-
`Change "${attrName}" to ensure this content is translated.`);
|
|
161
|
-
}
|
|
162
|
-
export function warnNoId(file) {
|
|
163
|
-
log.warn(`Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with no id. ` +
|
|
164
|
-
chalk.white('Add an id to ensure the content is translated.'));
|
|
165
|
-
}
|
|
166
|
-
export function warnHasUnwrappedExpression(file, id, unwrappedExpressions) {
|
|
167
|
-
log.warn(`${chalk.green('<T>')} with id "${id}" in ${chalk.cyan(file)} has children: ${unwrappedExpressions.join(', ')} that could change at runtime. ` +
|
|
168
|
-
chalk.white('Use a variable component like ') +
|
|
169
|
-
chalk.green('<Var>') +
|
|
170
|
-
chalk.white(' (') +
|
|
171
|
-
chalk.blue('https://generaltranslation.com/docs') +
|
|
172
|
-
chalk.white(') to translate this properly.'));
|
|
173
|
-
}
|
|
174
|
-
export function warnNonStaticExpression(file, attrName, value) {
|
|
175
|
-
log.warn(`Found non-static expression in ${chalk.cyan(file)} for attribute ${attrName}: "${chalk.white(value)}". ` +
|
|
176
|
-
`Change "${attrName}" to ensure this content is translated.`);
|
|
177
|
-
}
|
|
178
|
-
export function warnTemplateLiteral(file, value) {
|
|
179
|
-
log.warn(`Found template literal with quasis (${value}) in ${chalk.cyan(file)}. ` +
|
|
180
|
-
chalk.white('Change the template literal to a string to ensure this content is translated.'));
|
|
181
|
-
}
|
|
182
|
-
export function warnTernary(file) {
|
|
183
|
-
log.warn(`Found ternary expression in ${chalk.cyan(file)}. ` +
|
|
184
|
-
chalk.white('A Branch component may be more appropriate here.'));
|
|
185
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ResolvedFiles, TransformFiles } from '../../types/index.js';
|
|
2
|
-
import { FileMapping } from '../../types/files.js';
|
|
3
|
-
/**
|
|
4
|
-
* Creates a mapping between source files and their translated counterparts for each locale
|
|
5
|
-
* @param filePaths - Resolved file paths for different file types
|
|
6
|
-
* @param placeholderPaths - Placeholder paths for translated files
|
|
7
|
-
* @param transformPaths - Transform paths for file naming
|
|
8
|
-
* @param locales - List of locales to create a mapping for
|
|
9
|
-
* @returns A mapping between source files and their translated counterparts for each locale, in the form of relative paths
|
|
10
|
-
*/
|
|
11
|
-
export declare function createFileMapping(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, targetLocales: string[], defaultLocale: string): FileMapping;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { SUPPORTED_FILE_EXTENSIONS } from '../files/supportedFiles.js';
|
|
2
|
-
import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { getRelative } from '../../fs/findFilepath.js';
|
|
5
|
-
import { getLocaleProperties } from 'generaltranslation';
|
|
6
|
-
import { replaceLocalePlaceholders } from '../utils.js';
|
|
7
|
-
import { TEMPLATE_FILE_NAME } from '../../cli/commands/stage.js';
|
|
8
|
-
/**
|
|
9
|
-
* Creates a mapping between source files and their translated counterparts for each locale
|
|
10
|
-
* @param filePaths - Resolved file paths for different file types
|
|
11
|
-
* @param placeholderPaths - Placeholder paths for translated files
|
|
12
|
-
* @param transformPaths - Transform paths for file naming
|
|
13
|
-
* @param locales - List of locales to create a mapping for
|
|
14
|
-
* @returns A mapping between source files and their translated counterparts for each locale, in the form of relative paths
|
|
15
|
-
*/
|
|
16
|
-
export function createFileMapping(filePaths, placeholderPaths, transformPaths, targetLocales, defaultLocale) {
|
|
17
|
-
const fileMapping = {};
|
|
18
|
-
for (const locale of targetLocales) {
|
|
19
|
-
const translatedPaths = resolveLocaleFiles(placeholderPaths, locale);
|
|
20
|
-
const localeMapping = {};
|
|
21
|
-
// Process each file type
|
|
22
|
-
// Start with GTJSON Template files
|
|
23
|
-
if (translatedPaths.gt) {
|
|
24
|
-
const filepath = translatedPaths.gt;
|
|
25
|
-
localeMapping[TEMPLATE_FILE_NAME] = filepath;
|
|
26
|
-
}
|
|
27
|
-
for (const typeIndex of SUPPORTED_FILE_EXTENSIONS) {
|
|
28
|
-
if (!filePaths[typeIndex] || !translatedPaths[typeIndex])
|
|
29
|
-
continue;
|
|
30
|
-
const sourcePaths = filePaths[typeIndex];
|
|
31
|
-
let translatedFiles = translatedPaths[typeIndex];
|
|
32
|
-
if (!translatedFiles)
|
|
33
|
-
continue;
|
|
34
|
-
const transformPath = transformPaths[typeIndex];
|
|
35
|
-
if (transformPath) {
|
|
36
|
-
if (typeof transformPath === 'string') {
|
|
37
|
-
translatedFiles = translatedFiles.map((filePath) => {
|
|
38
|
-
const directory = path.dirname(filePath);
|
|
39
|
-
const fileName = path.basename(filePath);
|
|
40
|
-
const baseName = fileName.split('.')[0];
|
|
41
|
-
const transformedFileName = transformPath
|
|
42
|
-
.replace('*', baseName)
|
|
43
|
-
.replace('[locale]', locale);
|
|
44
|
-
return path.join(directory, transformedFileName);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
// transformPath is an object
|
|
49
|
-
const targetLocaleProperties = getLocaleProperties(locale);
|
|
50
|
-
const defaultLocaleProperties = getLocaleProperties(defaultLocale);
|
|
51
|
-
if (!transformPath.replace ||
|
|
52
|
-
typeof transformPath.replace !== 'string') {
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
// Replace all locale property placeholders
|
|
56
|
-
const replaceString = replaceLocalePlaceholders(transformPath.replace, targetLocaleProperties);
|
|
57
|
-
translatedFiles = translatedFiles.map((filePath) => {
|
|
58
|
-
let relativePath = getRelative(filePath);
|
|
59
|
-
if (transformPath.match &&
|
|
60
|
-
typeof transformPath.match === 'string') {
|
|
61
|
-
// Replace locale placeholders in the match string using defaultLocale properties
|
|
62
|
-
let matchString = transformPath.match;
|
|
63
|
-
matchString = replaceLocalePlaceholders(matchString, defaultLocaleProperties);
|
|
64
|
-
relativePath = relativePath.replace(new RegExp(matchString, 'g'), replaceString);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
relativePath = replaceString;
|
|
68
|
-
}
|
|
69
|
-
return path.resolve(relativePath);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
for (let i = 0; i < sourcePaths.length; i++) {
|
|
74
|
-
const sourceFile = getRelative(sourcePaths[i]);
|
|
75
|
-
const translatedFile = getRelative(translatedFiles[i]);
|
|
76
|
-
localeMapping[sourceFile] = translatedFile;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
fileMapping[locale] = localeMapping;
|
|
80
|
-
}
|
|
81
|
-
return fileMapping;
|
|
82
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { DataFormat } from '../../types/data.js';
|
|
2
|
-
/**
|
|
3
|
-
* Saves translated MDX/MD file content to the appropriate location
|
|
4
|
-
*/
|
|
5
|
-
export declare function saveTranslatedFile(translatedContent: string, outputDir: string, fileName: string, dataFormat: DataFormat, locales: string[]): Promise<void>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { logSuccess } from '../../console/logging.js';
|
|
4
|
-
/**
|
|
5
|
-
* Saves translated MDX/MD file content to the appropriate location
|
|
6
|
-
*/
|
|
7
|
-
export async function saveTranslatedFile(translatedContent, outputDir, fileName, dataFormat, locales) {
|
|
8
|
-
// Create locale-specific directories if they don't exist
|
|
9
|
-
for (const locale of locales) {
|
|
10
|
-
const localeDir = path.join(outputDir, locale);
|
|
11
|
-
await fs.mkdir(localeDir, { recursive: true });
|
|
12
|
-
// Save the translated file with the appropriate extension
|
|
13
|
-
const outputPath = path.join(localeDir, fileName);
|
|
14
|
-
await fs.writeFile(outputPath, translatedContent);
|
|
15
|
-
logSuccess(`Saved translated ${dataFormat} file to: ${outputPath}`);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare const SUPPORTED_FILE_EXTENSIONS: readonly ["json", "mdx", "md", "ts", "js", "yaml", "html"];
|
|
2
|
-
export declare const FILE_EXT_TO_EXT_LABEL: {
|
|
3
|
-
json: string;
|
|
4
|
-
mdx: string;
|
|
5
|
-
md: string;
|
|
6
|
-
ts: string;
|
|
7
|
-
js: string;
|
|
8
|
-
yaml: string;
|
|
9
|
-
html: string;
|
|
10
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export const SUPPORTED_FILE_EXTENSIONS = [
|
|
2
|
-
'json',
|
|
3
|
-
'mdx',
|
|
4
|
-
'md',
|
|
5
|
-
'ts',
|
|
6
|
-
'js',
|
|
7
|
-
'yaml',
|
|
8
|
-
'html',
|
|
9
|
-
];
|
|
10
|
-
export const FILE_EXT_TO_EXT_LABEL = {
|
|
11
|
-
json: 'JSON',
|
|
12
|
-
mdx: 'MDX',
|
|
13
|
-
md: 'Markdown',
|
|
14
|
-
ts: 'TypeScript',
|
|
15
|
-
js: 'JavaScript',
|
|
16
|
-
yaml: 'YAML',
|
|
17
|
-
html: 'HTML',
|
|
18
|
-
};
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { logError, logWarning } from '../../console/logging.js';
|
|
2
|
-
import { getRelative, readFile } from '../../fs/findFilepath.js';
|
|
3
|
-
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
|
|
4
|
-
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
|
|
5
|
-
import { parseJson } from '../json/parseJson.js';
|
|
6
|
-
import parseYaml from '../yaml/parseYaml.js';
|
|
7
|
-
import { determineLibrary } from '../../fs/determineFramework.js';
|
|
8
|
-
import { isValidMdx } from '../../utils/validateMdx.js';
|
|
9
|
-
export const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
10
|
-
export async function aggregateFiles(settings) {
|
|
11
|
-
// Aggregate all files to translate
|
|
12
|
-
const allFiles = [];
|
|
13
|
-
if (!settings.files ||
|
|
14
|
-
(Object.keys(settings.files.placeholderPaths).length === 1 &&
|
|
15
|
-
settings.files.placeholderPaths.gt)) {
|
|
16
|
-
return allFiles;
|
|
17
|
-
}
|
|
18
|
-
const { resolvedPaths: filePaths } = settings.files;
|
|
19
|
-
// Process JSON files
|
|
20
|
-
if (filePaths.json) {
|
|
21
|
-
const { library, additionalModules } = determineLibrary();
|
|
22
|
-
// Determine dataFormat for JSONs
|
|
23
|
-
let dataFormat;
|
|
24
|
-
if (library === 'next-intl') {
|
|
25
|
-
dataFormat = 'ICU';
|
|
26
|
-
}
|
|
27
|
-
else if (library === 'i18next') {
|
|
28
|
-
if (additionalModules.includes('i18next-icu')) {
|
|
29
|
-
dataFormat = 'ICU';
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
dataFormat = 'I18NEXT';
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
dataFormat = 'JSX';
|
|
37
|
-
}
|
|
38
|
-
const jsonFiles = filePaths.json
|
|
39
|
-
.map((filePath) => {
|
|
40
|
-
const content = readFile(filePath);
|
|
41
|
-
const relativePath = getRelative(filePath);
|
|
42
|
-
const parsedJson = parseJson(content, filePath, settings.options || {}, settings.defaultLocale);
|
|
43
|
-
return {
|
|
44
|
-
content: parsedJson,
|
|
45
|
-
fileName: relativePath,
|
|
46
|
-
fileFormat: 'JSON',
|
|
47
|
-
dataFormat,
|
|
48
|
-
};
|
|
49
|
-
})
|
|
50
|
-
.filter((file) => {
|
|
51
|
-
if (!file || typeof file.content !== 'string' || !file.content.trim()) {
|
|
52
|
-
logWarning(`Skipping ${file?.fileName ?? 'unknown'}: JSON file is empty`);
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
return true;
|
|
56
|
-
});
|
|
57
|
-
allFiles.push(...jsonFiles);
|
|
58
|
-
}
|
|
59
|
-
// Process YAML files
|
|
60
|
-
if (filePaths.yaml) {
|
|
61
|
-
const yamlFiles = filePaths.yaml
|
|
62
|
-
.map((filePath) => {
|
|
63
|
-
const content = readFile(filePath);
|
|
64
|
-
const relativePath = getRelative(filePath);
|
|
65
|
-
const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, settings.options || {});
|
|
66
|
-
return {
|
|
67
|
-
content: parsedYaml,
|
|
68
|
-
fileName: relativePath,
|
|
69
|
-
fileFormat,
|
|
70
|
-
};
|
|
71
|
-
})
|
|
72
|
-
.filter((file) => {
|
|
73
|
-
if (!file || typeof file.content !== 'string' || !file.content.trim()) {
|
|
74
|
-
logWarning(`Skipping ${file?.fileName ?? 'unknown'}: YAML file is empty`);
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
return true;
|
|
78
|
-
});
|
|
79
|
-
allFiles.push(...yamlFiles);
|
|
80
|
-
}
|
|
81
|
-
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
82
|
-
if (fileType === 'json' || fileType === 'yaml')
|
|
83
|
-
continue;
|
|
84
|
-
if (filePaths[fileType]) {
|
|
85
|
-
const files = filePaths[fileType]
|
|
86
|
-
.map((filePath) => {
|
|
87
|
-
const content = readFile(filePath);
|
|
88
|
-
const relativePath = getRelative(filePath);
|
|
89
|
-
if (fileType === 'mdx') {
|
|
90
|
-
const validation = isValidMdx(content, filePath);
|
|
91
|
-
if (!validation.isValid) {
|
|
92
|
-
logWarning(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const sanitizedContent = sanitizeFileContent(content);
|
|
97
|
-
return {
|
|
98
|
-
content: sanitizedContent,
|
|
99
|
-
fileName: relativePath,
|
|
100
|
-
fileFormat: fileType.toUpperCase(),
|
|
101
|
-
};
|
|
102
|
-
})
|
|
103
|
-
.filter((file) => {
|
|
104
|
-
if (!file ||
|
|
105
|
-
typeof file.content !== 'string' ||
|
|
106
|
-
!file.content.trim()) {
|
|
107
|
-
logWarning(`Skipping ${file?.fileName ?? 'unknown'}: File is empty after sanitization`);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
});
|
|
112
|
-
allFiles.push(...files);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (allFiles.length === 0) {
|
|
116
|
-
logError('No files to translate were found. Please check your configuration and try again.');
|
|
117
|
-
}
|
|
118
|
-
return allFiles;
|
|
119
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ResolvedFiles, Settings, TransformFiles } from '../../types/index.js';
|
|
2
|
-
import { DataFormat } from '../../types/data.js';
|
|
3
|
-
import { UploadOptions } from '../../cli/base.js';
|
|
4
|
-
/**
|
|
5
|
-
* Sends multiple files to the API for translation
|
|
6
|
-
* @param filePaths - Resolved file paths for different file types
|
|
7
|
-
* @param placeholderPaths - Placeholder paths for translated files
|
|
8
|
-
* @param transformPaths - Transform paths for file naming
|
|
9
|
-
* @param dataFormat - Format of the data within the files
|
|
10
|
-
* @param options - Translation options including API settings
|
|
11
|
-
* @returns Promise that resolves when translation is complete
|
|
12
|
-
*/
|
|
13
|
-
export declare function upload(filePaths: ResolvedFiles, placeholderPaths: ResolvedFiles, transformPaths: TransformFiles, dataFormat: DataFormat | undefined, options: Settings & UploadOptions): Promise<void>;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { noSupportedFormatError, noDefaultLocaleError, noApiKeyError, noProjectIdError, devApiKeyError, } from '../../console/index.js';
|
|
2
|
-
import { logErrorAndExit, logError } from '../../console/logging.js';
|
|
3
|
-
import { getRelative, readFile } from '../../fs/findFilepath.js';
|
|
4
|
-
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
|
|
5
|
-
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
|
|
6
|
-
import { parseJson } from '../json/parseJson.js';
|
|
7
|
-
import { uploadFiles } from '../../api/uploadFiles.js';
|
|
8
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
-
import { createFileMapping } from './fileMapping.js';
|
|
10
|
-
import parseYaml from '../yaml/parseYaml.js';
|
|
11
|
-
const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
12
|
-
/**
|
|
13
|
-
* Sends multiple files to the API for translation
|
|
14
|
-
* @param filePaths - Resolved file paths for different file types
|
|
15
|
-
* @param placeholderPaths - Placeholder paths for translated files
|
|
16
|
-
* @param transformPaths - Transform paths for file naming
|
|
17
|
-
* @param dataFormat - Format of the data within the files
|
|
18
|
-
* @param options - Translation options including API settings
|
|
19
|
-
* @returns Promise that resolves when translation is complete
|
|
20
|
-
*/
|
|
21
|
-
export async function upload(filePaths, placeholderPaths, transformPaths, dataFormat = 'JSX', options) {
|
|
22
|
-
// Collect all files to translate
|
|
23
|
-
const allFiles = [];
|
|
24
|
-
const additionalOptions = options.options || {};
|
|
25
|
-
// Process JSON files
|
|
26
|
-
if (filePaths.json) {
|
|
27
|
-
if (!SUPPORTED_DATA_FORMATS.includes(dataFormat)) {
|
|
28
|
-
logErrorAndExit(noSupportedFormatError);
|
|
29
|
-
}
|
|
30
|
-
const jsonFiles = filePaths.json.map((filePath) => {
|
|
31
|
-
const content = readFile(filePath);
|
|
32
|
-
const parsedJson = parseJson(content, filePath, additionalOptions, options.defaultLocale);
|
|
33
|
-
const relativePath = getRelative(filePath);
|
|
34
|
-
return {
|
|
35
|
-
content: parsedJson,
|
|
36
|
-
fileName: relativePath,
|
|
37
|
-
fileFormat: 'JSON',
|
|
38
|
-
dataFormat,
|
|
39
|
-
locale: options.defaultLocale,
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
allFiles.push(...jsonFiles);
|
|
43
|
-
}
|
|
44
|
-
// Process YAML files
|
|
45
|
-
if (filePaths.yaml) {
|
|
46
|
-
if (!SUPPORTED_DATA_FORMATS.includes(dataFormat)) {
|
|
47
|
-
logErrorAndExit(noSupportedFormatError);
|
|
48
|
-
}
|
|
49
|
-
const yamlFiles = filePaths.yaml.map((filePath) => {
|
|
50
|
-
const content = readFile(filePath);
|
|
51
|
-
const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, additionalOptions);
|
|
52
|
-
const relativePath = getRelative(filePath);
|
|
53
|
-
return {
|
|
54
|
-
content: parsedYaml,
|
|
55
|
-
fileName: relativePath,
|
|
56
|
-
fileFormat,
|
|
57
|
-
dataFormat,
|
|
58
|
-
locale: options.defaultLocale,
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
allFiles.push(...yamlFiles);
|
|
62
|
-
}
|
|
63
|
-
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
64
|
-
if (fileType === 'json' || fileType === 'yaml')
|
|
65
|
-
continue;
|
|
66
|
-
if (filePaths[fileType]) {
|
|
67
|
-
const files = filePaths[fileType].map((filePath) => {
|
|
68
|
-
const content = readFile(filePath);
|
|
69
|
-
const sanitizedContent = sanitizeFileContent(content);
|
|
70
|
-
const relativePath = getRelative(filePath);
|
|
71
|
-
return {
|
|
72
|
-
content: sanitizedContent,
|
|
73
|
-
fileName: relativePath,
|
|
74
|
-
fileFormat: fileType.toUpperCase(),
|
|
75
|
-
dataFormat,
|
|
76
|
-
locale: options.defaultLocale,
|
|
77
|
-
};
|
|
78
|
-
});
|
|
79
|
-
allFiles.push(...files);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (allFiles.length === 0) {
|
|
83
|
-
logError('No files to upload were found. Please check your configuration and try again.');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (!options.defaultLocale) {
|
|
87
|
-
logErrorAndExit(noDefaultLocaleError);
|
|
88
|
-
}
|
|
89
|
-
if (!options.apiKey) {
|
|
90
|
-
logErrorAndExit(noApiKeyError);
|
|
91
|
-
}
|
|
92
|
-
if (options.apiKey.startsWith('gtx-dev-')) {
|
|
93
|
-
logErrorAndExit(devApiKeyError);
|
|
94
|
-
}
|
|
95
|
-
if (!options.projectId) {
|
|
96
|
-
logErrorAndExit(noProjectIdError);
|
|
97
|
-
}
|
|
98
|
-
const locales = options.locales || [];
|
|
99
|
-
// Create file mapping for all file types
|
|
100
|
-
const fileMapping = createFileMapping(filePaths, placeholderPaths, transformPaths, locales, options.defaultLocale);
|
|
101
|
-
// construct object
|
|
102
|
-
const uploadData = allFiles.map((file) => {
|
|
103
|
-
const sourceFile = {
|
|
104
|
-
content: file.content,
|
|
105
|
-
fileName: file.fileName,
|
|
106
|
-
fileFormat: file.fileFormat,
|
|
107
|
-
dataFormat: file.dataFormat,
|
|
108
|
-
locale: file.locale,
|
|
109
|
-
};
|
|
110
|
-
const translations = [];
|
|
111
|
-
for (const locale of locales) {
|
|
112
|
-
const translatedFileName = fileMapping[locale][file.fileName];
|
|
113
|
-
if (translatedFileName && existsSync(translatedFileName)) {
|
|
114
|
-
const translatedContent = readFileSync(translatedFileName, 'utf8');
|
|
115
|
-
translations.push({
|
|
116
|
-
content: translatedContent,
|
|
117
|
-
fileName: translatedFileName,
|
|
118
|
-
fileFormat: file.fileFormat,
|
|
119
|
-
dataFormat: file.dataFormat,
|
|
120
|
-
locale,
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
source: sourceFile,
|
|
126
|
-
translations,
|
|
127
|
-
};
|
|
128
|
-
});
|
|
129
|
-
try {
|
|
130
|
-
// Send all files in a single API call
|
|
131
|
-
await uploadFiles(uploadData, options);
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
logErrorAndExit(`Error uploading files: ${error}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { RetrievedTranslations } from 'generaltranslation/types';
|
|
2
|
-
import { ResolvedFiles } from '../../types/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Saves translations to a local directory
|
|
5
|
-
* @param translations - The translations to save
|
|
6
|
-
* @param translationsDir - The directory to save the translations to
|
|
7
|
-
* @param fileType - The file type to save the translations as (file extension)
|
|
8
|
-
*/
|
|
9
|
-
export declare function saveTranslations(translations: RetrievedTranslations, placeholderPaths: ResolvedFiles): Promise<void>;
|
package/dist/formats/gt/save.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { logError } from '../../console/logging.js';
|
|
4
|
-
import { noFilesError } from '../../console/index.js';
|
|
5
|
-
import { resolveLocaleFiles } from '../../fs/config/parseFilesConfig.js';
|
|
6
|
-
/**
|
|
7
|
-
* Saves translations to a local directory
|
|
8
|
-
* @param translations - The translations to save
|
|
9
|
-
* @param translationsDir - The directory to save the translations to
|
|
10
|
-
* @param fileType - The file type to save the translations as (file extension)
|
|
11
|
-
*/
|
|
12
|
-
export async function saveTranslations(translations, placeholderPaths) {
|
|
13
|
-
for (const translation of translations) {
|
|
14
|
-
const locale = translation.locale;
|
|
15
|
-
const translationFiles = resolveLocaleFiles(placeholderPaths, locale);
|
|
16
|
-
if (!translationFiles.gt) {
|
|
17
|
-
logError(noFilesError);
|
|
18
|
-
process.exit(1);
|
|
19
|
-
}
|
|
20
|
-
const filepath = translationFiles.gt;
|
|
21
|
-
const translationData = translation.translation;
|
|
22
|
-
// Ensure directory exists
|
|
23
|
-
await fs.promises.mkdir(path.dirname(filepath), { recursive: true });
|
|
24
|
-
await fs.promises.writeFile(filepath, JSON.stringify(translationData, null, 2));
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flattens a JSON object according to a list of JSON paths.
|
|
3
|
-
* @param json - The JSON object to flatten
|
|
4
|
-
* @param jsonPaths - The list of JSON paths to flatten
|
|
5
|
-
* @returns A mapping of json pointers to their values
|
|
6
|
-
*/
|
|
7
|
-
export declare function flattenJson(json: any, jsonPaths: string[]): Record<string, any>;
|
|
8
|
-
/**
|
|
9
|
-
* Flattens a JSON object according to a list of JSON paths, only including strings
|
|
10
|
-
* @param json - The JSON object to flatten
|
|
11
|
-
* @param jsonPaths - The list of JSON paths to flatten
|
|
12
|
-
* @returns A mapping of json pointers to their values
|
|
13
|
-
*/
|
|
14
|
-
export declare function flattenJsonWithStringFilter(json: any, jsonPaths: string[]): Record<string, any>;
|