gtx-cli 2.6.17 → 2.6.18
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/cli/base.d.ts +2 -0
- package/dist/cli/base.js +79 -14
- package/dist/cli/flags.d.ts +12 -1
- package/dist/cli/flags.js +24 -5
- package/dist/cli/inline.d.ts +16 -0
- package/dist/cli/inline.js +128 -0
- package/dist/cli/next.d.ts +0 -2
- package/dist/cli/next.js +0 -10
- package/dist/cli/node.d.ts +9 -0
- package/dist/cli/node.js +9 -0
- package/dist/cli/react.d.ts +3 -10
- package/dist/cli/react.js +5 -120
- package/dist/formats/files/collectFiles.js +5 -3
- package/dist/fs/determineFramework.js +3 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/index.js +4 -0
- package/dist/react/jsx/utils/constants.d.ts +9 -2
- package/dist/react/jsx/utils/constants.js +7 -2
- package/dist/react/jsx/utils/getPathsAndAliases.js +3 -4
- package/dist/react/jsx/utils/parseStringFunction.js +2 -2
- package/dist/react/parse/createInlineUpdates.js +22 -19
- package/dist/setup/agentInstructions.d.ts +24 -0
- package/dist/setup/agentInstructions.js +135 -0
- package/dist/setup/instructions/base.md +29 -0
- package/dist/setup/instructions/gt-next.md +107 -0
- package/dist/setup/instructions/gt-react.md +98 -0
- package/dist/translation/parse.d.ts +1 -1
- package/dist/translation/stage.d.ts +1 -1
- package/dist/translation/stage.js +1 -1
- package/dist/translation/validate.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const DECLARE_VAR_FUNCTION = "declareVar";
|
|
2
2
|
export declare const DECLARE_STATIC_FUNCTION = "declareStatic";
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const MSG_REGISTRATION_FUNCTION = "msg";
|
|
4
4
|
export declare const INLINE_TRANSLATION_HOOK = "useGT";
|
|
5
5
|
export declare const INLINE_TRANSLATION_HOOK_ASYNC = "getGT";
|
|
6
6
|
export declare const INLINE_MESSAGE_HOOK = "useMessages";
|
|
@@ -12,6 +12,13 @@ export declare const VARIABLE_COMPONENTS: string[];
|
|
|
12
12
|
export declare const GT_ATTRIBUTES_WITH_SUGAR: readonly ["$id", "$context", "$maxChars"];
|
|
13
13
|
export declare const GT_ATTRIBUTES: readonly ["id", "context", "maxChars", "$id", "$context", "$maxChars"];
|
|
14
14
|
export declare function mapAttributeName(attrName: string): string;
|
|
15
|
-
export declare const GT_LIBRARIES: readonly ["gt-react", "gt-next", "gt-react-native", "gt-i18n", "@generaltranslation/react-core"];
|
|
15
|
+
export declare const GT_LIBRARIES: readonly ["gt-react", "gt-next", "gt-react-native", "gt-node", "gt-i18n", "@generaltranslation/react-core"];
|
|
16
16
|
export type GTLibrary = (typeof GT_LIBRARIES)[number];
|
|
17
|
+
/**
|
|
18
|
+
* GT Libraries that use react translations
|
|
19
|
+
*/
|
|
20
|
+
export type GTReactLibrary = 'gt-react' | 'gt-react-native' | 'gt-next' | '@generaltranslation/react-core';
|
|
21
|
+
/**
|
|
22
|
+
* A mapping of each library to their upstream dependencies for filtering imports
|
|
23
|
+
*/
|
|
17
24
|
export declare const GT_LIBRARIES_UPSTREAM: Record<GTLibrary, GTLibrary[]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const DECLARE_VAR_FUNCTION = 'declareVar';
|
|
2
2
|
export const DECLARE_STATIC_FUNCTION = 'declareStatic';
|
|
3
|
-
export const
|
|
3
|
+
export const MSG_REGISTRATION_FUNCTION = 'msg';
|
|
4
4
|
export const INLINE_TRANSLATION_HOOK = 'useGT';
|
|
5
5
|
export const INLINE_TRANSLATION_HOOK_ASYNC = 'getGT';
|
|
6
6
|
export const INLINE_MESSAGE_HOOK = 'useMessages';
|
|
@@ -13,7 +13,7 @@ export const GT_TRANSLATION_FUNCS = [
|
|
|
13
13
|
INLINE_TRANSLATION_HOOK_ASYNC,
|
|
14
14
|
INLINE_MESSAGE_HOOK,
|
|
15
15
|
INLINE_MESSAGE_HOOK_ASYNC,
|
|
16
|
-
|
|
16
|
+
MSG_REGISTRATION_FUNCTION,
|
|
17
17
|
DECLARE_VAR_FUNCTION,
|
|
18
18
|
DECLARE_STATIC_FUNCTION,
|
|
19
19
|
TRANSLATION_COMPONENT,
|
|
@@ -57,9 +57,13 @@ export const GT_LIBRARIES = [
|
|
|
57
57
|
'gt-react',
|
|
58
58
|
'gt-next',
|
|
59
59
|
'gt-react-native',
|
|
60
|
+
'gt-node',
|
|
60
61
|
'gt-i18n',
|
|
61
62
|
'@generaltranslation/react-core',
|
|
62
63
|
];
|
|
64
|
+
/**
|
|
65
|
+
* A mapping of each library to their upstream dependencies for filtering imports
|
|
66
|
+
*/
|
|
63
67
|
export const GT_LIBRARIES_UPSTREAM = {
|
|
64
68
|
'gt-next': [
|
|
65
69
|
'gt-i18n',
|
|
@@ -79,6 +83,7 @@ export const GT_LIBRARIES_UPSTREAM = {
|
|
|
79
83
|
'gt-react-native',
|
|
80
84
|
'gt-react', // allow for cross-library compatibility (gt-react/gt-react-native only)
|
|
81
85
|
],
|
|
86
|
+
'gt-node': ['gt-i18n', '@generaltranslation/react-core', 'gt-node'],
|
|
82
87
|
'@generaltranslation/react-core': [
|
|
83
88
|
'gt-i18n',
|
|
84
89
|
'@generaltranslation/react-core',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import traverseModule from '@babel/traverse';
|
|
2
|
-
import { GT_TRANSLATION_FUNCS, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC,
|
|
2
|
+
import { GT_TRANSLATION_FUNCS, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC, MSG_REGISTRATION_FUNCTION, TRANSLATION_COMPONENT, } from '../../jsx/utils/constants.js';
|
|
3
3
|
import { extractImportName } from './parseAst.js';
|
|
4
4
|
// Handle CommonJS/ESM interop
|
|
5
5
|
const traverse = traverseModule.default || traverseModule;
|
|
@@ -23,7 +23,7 @@ export function getPathsAndAliases(ast, pkgs) {
|
|
|
23
23
|
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
24
24
|
name.original === INLINE_MESSAGE_HOOK ||
|
|
25
25
|
name.original === INLINE_MESSAGE_HOOK_ASYNC ||
|
|
26
|
-
name.original ===
|
|
26
|
+
name.original === MSG_REGISTRATION_FUNCTION) {
|
|
27
27
|
inlineTranslationPaths.push({
|
|
28
28
|
localName: name.local,
|
|
29
29
|
path,
|
|
@@ -60,8 +60,7 @@ export function getPathsAndAliases(ast, pkgs) {
|
|
|
60
60
|
if (name.original === INLINE_TRANSLATION_HOOK ||
|
|
61
61
|
name.original === INLINE_TRANSLATION_HOOK_ASYNC ||
|
|
62
62
|
name.original === INLINE_MESSAGE_HOOK ||
|
|
63
|
-
name.original === INLINE_MESSAGE_HOOK_ASYNC
|
|
64
|
-
name.original === MSG_TRANSLATION_FUNCTION) {
|
|
63
|
+
name.original === INLINE_MESSAGE_HOOK_ASYNC) {
|
|
65
64
|
inlineTranslationPaths.push({
|
|
66
65
|
localName: name.local,
|
|
67
66
|
path: parentPath,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as t from '@babel/types';
|
|
2
2
|
import { isStaticExpression, isValidIcu } from '../evaluateJsx.js';
|
|
3
|
-
import { GT_ATTRIBUTES_WITH_SUGAR,
|
|
3
|
+
import { GT_ATTRIBUTES_WITH_SUGAR, MSG_REGISTRATION_FUNCTION, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, mapAttributeName, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC, } from './constants.js';
|
|
4
4
|
import { warnNonStaticExpressionSync, warnNonStringSync, warnTemplateLiteralSync, warnAsyncUseGT, warnSyncGetGT, warnInvalidIcuSync, warnInvalidMaxCharsSync, } from '../../../console/index.js';
|
|
5
5
|
import generateModule from '@babel/generator';
|
|
6
6
|
import traverseModule from '@babel/traverse';
|
|
@@ -432,7 +432,7 @@ export function parseStrings(importName, originalName, path, config, output) {
|
|
|
432
432
|
const referencePaths = path.scope.bindings[importName]?.referencePaths || [];
|
|
433
433
|
for (const refPath of referencePaths) {
|
|
434
434
|
// Handle msg() calls directly without variable assignment
|
|
435
|
-
if (originalName ===
|
|
435
|
+
if (originalName === MSG_REGISTRATION_FUNCTION) {
|
|
436
436
|
const msgConfig = {
|
|
437
437
|
parsingOptions: config.parsingOptions,
|
|
438
438
|
file: config.file,
|
|
@@ -41,24 +41,26 @@ export async function createInlineUpdates(pkg, validate, filePatterns, parsingOp
|
|
|
41
41
|
}, { updates, errors, warnings });
|
|
42
42
|
}
|
|
43
43
|
// Parse <T> components
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
if (pkg !== 'gt-node') {
|
|
45
|
+
for (const { localName, path } of translationComponentPaths) {
|
|
46
|
+
parseTranslationComponent({
|
|
47
|
+
originalName: localName,
|
|
48
|
+
localName,
|
|
49
|
+
path,
|
|
50
|
+
updates,
|
|
51
|
+
config: {
|
|
52
|
+
importAliases,
|
|
53
|
+
parsingOptions,
|
|
54
|
+
pkgs,
|
|
55
|
+
file,
|
|
56
|
+
},
|
|
57
|
+
output: {
|
|
58
|
+
errors,
|
|
59
|
+
warnings,
|
|
60
|
+
unwrappedExpressions: [],
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
// Post processing steps:
|
|
@@ -69,7 +71,8 @@ export async function createInlineUpdates(pkg, validate, filePatterns, parsingOp
|
|
|
69
71
|
}
|
|
70
72
|
/**
|
|
71
73
|
* Given a package name, return the upstream packages that it depends on
|
|
72
|
-
* @param pkg
|
|
74
|
+
* @param pkg - The package name
|
|
75
|
+
* @returns The upstream packages that the package depends on
|
|
73
76
|
*/
|
|
74
77
|
function getUpstreamPackages(pkg) {
|
|
75
78
|
return GT_LIBRARIES_UPSTREAM[pkg];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SupportedLibraries } from '../types/index.js';
|
|
2
|
+
export declare const CURSOR_GT_RULES_FILE = ".cursor/rules/gt-i18n.mdc";
|
|
3
|
+
/**
|
|
4
|
+
* Detect existing AI agent instruction files in the project.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findAgentFiles(): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Find agent files that already contain GT instructions.
|
|
9
|
+
*/
|
|
10
|
+
export declare function findAgentFilesWithInstructions(): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Check if the .cursor/rules/ directory exists (for offering to create gt-i18n.mdc).
|
|
13
|
+
*/
|
|
14
|
+
export declare function hasCursorRulesDir(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Generate GT agent instructions content based on the detected library.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getAgentInstructions(library: SupportedLibraries): string;
|
|
19
|
+
/**
|
|
20
|
+
* Append or replace GT instructions in an agent file.
|
|
21
|
+
* Skips writing if the file already contains identical instructions.
|
|
22
|
+
* For .cursor/rules/gt.md, writes the file fresh (dedicated GT rules file).
|
|
23
|
+
*/
|
|
24
|
+
export declare function appendAgentInstructions(filePath: string, instructions: string): boolean;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { getCLIVersion, getPackageVersion } from '../utils/packageJson.js';
|
|
5
|
+
const INSTRUCTIONS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'instructions');
|
|
6
|
+
const AGENT_FILE_PATHS = [
|
|
7
|
+
'CLAUDE.md',
|
|
8
|
+
'AGENTS.md',
|
|
9
|
+
'GPT.md',
|
|
10
|
+
'CHATGPT.md',
|
|
11
|
+
'.cursorrules',
|
|
12
|
+
];
|
|
13
|
+
const CURSOR_RULES_DIR = '.cursor/rules';
|
|
14
|
+
export const CURSOR_GT_RULES_FILE = '.cursor/rules/gt-i18n.mdc';
|
|
15
|
+
const GT_SECTION_START = '<!-- GT I18N RULES START -->';
|
|
16
|
+
const GT_SECTION_END = '<!-- GT I18N RULES END -->';
|
|
17
|
+
function getLibraryVersion(library) {
|
|
18
|
+
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
|
|
19
|
+
if (!fs.existsSync(packageJsonPath))
|
|
20
|
+
return undefined;
|
|
21
|
+
try {
|
|
22
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
23
|
+
return getPackageVersion(library, packageJson);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Detect existing AI agent instruction files in the project.
|
|
31
|
+
*/
|
|
32
|
+
export function findAgentFiles() {
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
const found = [];
|
|
35
|
+
for (const filePath of [...AGENT_FILE_PATHS, CURSOR_GT_RULES_FILE]) {
|
|
36
|
+
const fullPath = path.resolve(cwd, filePath);
|
|
37
|
+
if (fs.existsSync(fullPath)) {
|
|
38
|
+
found.push(filePath);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return found;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Find agent files that already contain GT instructions.
|
|
45
|
+
*/
|
|
46
|
+
export function findAgentFilesWithInstructions() {
|
|
47
|
+
const cwd = process.cwd();
|
|
48
|
+
const found = [];
|
|
49
|
+
for (const filePath of [...AGENT_FILE_PATHS, CURSOR_GT_RULES_FILE]) {
|
|
50
|
+
const fullPath = path.resolve(cwd, filePath);
|
|
51
|
+
if (fs.existsSync(fullPath)) {
|
|
52
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
53
|
+
if (content.includes(GT_SECTION_START)) {
|
|
54
|
+
found.push(filePath);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return found;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if the .cursor/rules/ directory exists (for offering to create gt-i18n.mdc).
|
|
62
|
+
*/
|
|
63
|
+
export function hasCursorRulesDir() {
|
|
64
|
+
const cursorRulesDir = path.resolve(process.cwd(), CURSOR_RULES_DIR);
|
|
65
|
+
return (fs.existsSync(cursorRulesDir) && fs.statSync(cursorRulesDir).isDirectory());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate GT agent instructions content based on the detected library.
|
|
69
|
+
*/
|
|
70
|
+
export function getAgentInstructions(library) {
|
|
71
|
+
const libraryVersion = getLibraryVersion(library);
|
|
72
|
+
const versionLine = libraryVersion
|
|
73
|
+
? `- **${library}**: ${libraryVersion}\n- **gtx-cli**: v${getCLIVersion()}`
|
|
74
|
+
: `- **gtx-cli**: v${getCLIVersion()}`;
|
|
75
|
+
const base = fs.readFileSync(path.join(INSTRUCTIONS_DIR, 'base.md'), 'utf8');
|
|
76
|
+
let body = '';
|
|
77
|
+
const libToFile = {
|
|
78
|
+
'gt-next': 'gt-next.md',
|
|
79
|
+
'gt-react': 'gt-react.md',
|
|
80
|
+
};
|
|
81
|
+
const instructionFile = libToFile[library];
|
|
82
|
+
if (instructionFile) {
|
|
83
|
+
body += '\n\n'; // add two newlines between the base and the specific instructions
|
|
84
|
+
body += fs.readFileSync(path.join(INSTRUCTIONS_DIR, instructionFile), 'utf8');
|
|
85
|
+
}
|
|
86
|
+
return `${GT_SECTION_START}
|
|
87
|
+
|
|
88
|
+
${versionLine}
|
|
89
|
+
|
|
90
|
+
${base}${body}
|
|
91
|
+
${GT_SECTION_END}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Append or replace GT instructions in an agent file.
|
|
95
|
+
* Skips writing if the file already contains identical instructions.
|
|
96
|
+
* For .cursor/rules/gt.md, writes the file fresh (dedicated GT rules file).
|
|
97
|
+
*/
|
|
98
|
+
export function appendAgentInstructions(filePath, instructions) {
|
|
99
|
+
const fullPath = path.resolve(process.cwd(), filePath);
|
|
100
|
+
// For .cursor/rules/gt.md, write as a standalone file with frontmatter
|
|
101
|
+
if (filePath === CURSOR_GT_RULES_FILE) {
|
|
102
|
+
const cursorContent = `---\ndescription: GT internationalization instructions\nalwaysApply: true\n---\n${instructions}\n`;
|
|
103
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
104
|
+
if (fs.existsSync(fullPath)) {
|
|
105
|
+
const existing = fs.readFileSync(fullPath, 'utf8');
|
|
106
|
+
if (existing === cursorContent)
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
fs.writeFileSync(fullPath, cursorContent, 'utf8');
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// For other files, read existing content and append/replace
|
|
113
|
+
let content = '';
|
|
114
|
+
if (fs.existsSync(fullPath)) {
|
|
115
|
+
content = fs.readFileSync(fullPath, 'utf8');
|
|
116
|
+
}
|
|
117
|
+
// Already has identical instructions — skip
|
|
118
|
+
if (content.includes(instructions))
|
|
119
|
+
return false;
|
|
120
|
+
const startIdx = content.indexOf(GT_SECTION_START);
|
|
121
|
+
const endIdx = startIdx !== -1 ? content.indexOf(GT_SECTION_END, startIdx) : -1;
|
|
122
|
+
if (startIdx !== -1 && endIdx !== -1) {
|
|
123
|
+
// Replace existing section
|
|
124
|
+
const before = content.substring(0, startIdx);
|
|
125
|
+
const after = content.substring(endIdx + GT_SECTION_END.length);
|
|
126
|
+
content = before + instructions + after;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// Append to end
|
|
130
|
+
const separator = content.length > 0 && !content.endsWith('\n') ? '\n' : '';
|
|
131
|
+
content = content + separator + '\n' + instructions + '\n';
|
|
132
|
+
}
|
|
133
|
+
fs.writeFileSync(fullPath, content, 'utf8');
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## General Translation (GT) Internationalization Rules
|
|
2
|
+
|
|
3
|
+
This project is using [General Translation](https://generaltranslation.com/docs/overview.md) for internationalization (i18n) and translations. General Translation is a developer-first localization stack, built for the world's best engineering teams to ship apps in every language with ease.
|
|
4
|
+
|
|
5
|
+
### Configuration
|
|
6
|
+
|
|
7
|
+
The General Translation configuration file is called `gt.config.json`. It is usually located in the root or src directory of a project.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"defaultLocale": "en",
|
|
12
|
+
"locales": ["es", "fr", "de"],
|
|
13
|
+
"files": {
|
|
14
|
+
"json": {
|
|
15
|
+
"include": ["./**/[locale]/*.json"]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The API reference for the config file can be found at https://generaltranslation.com/docs/cli/reference/config.md.
|
|
22
|
+
|
|
23
|
+
### Translation
|
|
24
|
+
|
|
25
|
+
Run `npx gtx-cli translate` to create translation files for your project. You must have an API key to do this.
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
|
|
29
|
+
https://generaltranslation.com/llms.txt
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
### gt-next
|
|
2
|
+
|
|
3
|
+
This project is using the `gt-next` internationalization library for Next.js App Router.
|
|
4
|
+
|
|
5
|
+
### gt-next setup
|
|
6
|
+
|
|
7
|
+
- `GTProvider` must wrap the app in the root layout to provide translation context.
|
|
8
|
+
- The `withGTConfig()` plugin wraps `next.config` in the Next.js config file.
|
|
9
|
+
- (optional) `createNextMiddleware()` is used in `proxy.ts` for automatic locale routing.
|
|
10
|
+
|
|
11
|
+
### Translating JSX
|
|
12
|
+
|
|
13
|
+
`gt-next` uses the `<T>` component for translation.
|
|
14
|
+
|
|
15
|
+
Pass JSX content as the direct children of `<T>` to translate it. Children of `<T>` must be static — no JS expressions or variables directly inside.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
import { T } from 'gt-next';
|
|
19
|
+
|
|
20
|
+
<T>
|
|
21
|
+
<h1>Welcome to our store</h1>
|
|
22
|
+
<p>
|
|
23
|
+
Browse our <a href='/products'>latest products</a> and find something you
|
|
24
|
+
love.
|
|
25
|
+
</p>
|
|
26
|
+
</T>;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
You can also add a `context` prop to `<T>` to give context to the translator. For example:
|
|
30
|
+
|
|
31
|
+
```jsx
|
|
32
|
+
import { T } from 'gt-next';
|
|
33
|
+
|
|
34
|
+
<T context="Cookies as in web cookies">
|
|
35
|
+
View your <a href="/cookies">Cookies</a>
|
|
36
|
+
</T>;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Translating simple strings
|
|
40
|
+
|
|
41
|
+
Use the `gt` function returned by the `useGT()` hook to translate strings directly. Invoke `useGT()` in synchronous components or `await getGT()` in async components only.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
import { useGT } from 'gt-next';
|
|
45
|
+
const gt = useGT();
|
|
46
|
+
gt('Hello, world!'); // returns "Hola, mundo"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { getGT } from 'gt-next/server';
|
|
51
|
+
const gt = await getGT(); // use await version in async components only
|
|
52
|
+
gt('Hello, world!');
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- Just like with the children of the `<T>` component, all strings passed to `gt()` must be static string literals. No variables or template literals.
|
|
56
|
+
|
|
57
|
+
### Translating shared or out-of-scope strings
|
|
58
|
+
|
|
59
|
+
Use `msg()` to register strings for translation, and `useMessages()` to translate them. `const m = useMessages()` should be used equivalently to `const gt = useGT()`.
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { msg, useMessages } from 'gt-next';
|
|
63
|
+
|
|
64
|
+
const greeting = msg('Hello, world!');
|
|
65
|
+
|
|
66
|
+
export default function Greeting() {
|
|
67
|
+
const m = useMessages();
|
|
68
|
+
return <p>{m(greeting)}</p>;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- All strings passed to `msg()` must be static string literals. No variables or template literals.
|
|
73
|
+
- Use the equivalent `await getMessages()` for async components.
|
|
74
|
+
- `useMessages()` / `getMessages()` take no arguments.
|
|
75
|
+
|
|
76
|
+
### Dynamic content inside `<T>`
|
|
77
|
+
|
|
78
|
+
Use variable components for dynamic values inside `<T>`:
|
|
79
|
+
|
|
80
|
+
- `<Var>{value}</Var>` — variables (strings, numbers, etc.)
|
|
81
|
+
- `<Num>{value}</Num>` — formatted numbers
|
|
82
|
+
- `<Currency>{value}</Currency>` — formatted currency
|
|
83
|
+
- `<DateTime>{value}</DateTime>` — formatted dates/times
|
|
84
|
+
|
|
85
|
+
```jsx
|
|
86
|
+
import { T, Var, Num } from 'gt-next';
|
|
87
|
+
|
|
88
|
+
<T>
|
|
89
|
+
<Var>{userName}</Var> ordered <Num>{itemCount}</Num> items.
|
|
90
|
+
</T>;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Utility hooks
|
|
94
|
+
|
|
95
|
+
#### `useLocale()`
|
|
96
|
+
|
|
97
|
+
`useLocale` returns the user's current language, as a BCP 47 locale tag.
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import { useLocale } from 'gt-next'
|
|
101
|
+
|
|
102
|
+
const locale = useLocale(); // "en-US"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Quickstart
|
|
106
|
+
|
|
107
|
+
See https://generaltranslation.com/docs/next.md
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
### gt-react
|
|
2
|
+
|
|
3
|
+
This project is using the `gt-react` internationalization library.
|
|
4
|
+
|
|
5
|
+
### gt-react setup
|
|
6
|
+
|
|
7
|
+
- `GTProvider` must wrap the app in the root layout to provide translation context.
|
|
8
|
+
|
|
9
|
+
### Translating JSX
|
|
10
|
+
|
|
11
|
+
`gt-react` uses the `<T>` component for translation.
|
|
12
|
+
|
|
13
|
+
Pass JSX content as the direct children of `<T>` to translate it. Children of `<T>` must be static — no JS expressions or variables directly inside.
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
import { T } from 'gt-react';
|
|
17
|
+
|
|
18
|
+
<T>
|
|
19
|
+
<h1>Welcome to our store</h1>
|
|
20
|
+
<p>
|
|
21
|
+
Browse our <a href='/products'>latest products</a> and find something you
|
|
22
|
+
love.
|
|
23
|
+
</p>
|
|
24
|
+
</T>;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
You can also add a `context` prop to `<T>` to give context to the translator. For example:
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
import { T } from 'gt-react';
|
|
31
|
+
|
|
32
|
+
<T context="Cookies as in web cookies">
|
|
33
|
+
View your <a href="/cookies">Cookies</a>
|
|
34
|
+
</T>;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Translating simple strings
|
|
38
|
+
|
|
39
|
+
Use the `gt` function returned by the `useGT()` hook to translate strings directly.
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { useGT } from 'gt-react';
|
|
43
|
+
const gt = useGT();
|
|
44
|
+
gt('Hello, world!'); // returns "Hola, mundo"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Just like with the children of the `<T>` component, all strings passed to `gt()` must be static string literals. No variables or template literals.
|
|
48
|
+
|
|
49
|
+
### Translating shared or out-of-scope strings
|
|
50
|
+
|
|
51
|
+
Use `msg()` to register strings for translation, and `useMessages()` to translate them. `const m = useMessages()` should be used equivalently to `const gt = useGT()`.
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { msg, useMessages } from 'gt-react';
|
|
55
|
+
|
|
56
|
+
const greeting = msg('Hello, world!');
|
|
57
|
+
|
|
58
|
+
export default function Greeting() {
|
|
59
|
+
const m = useMessages();
|
|
60
|
+
return <p>{m(greeting)}</p>;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- All strings passed to `msg()` must be static string literals. No variables or template literals.
|
|
65
|
+
- `useMessages()` / `getMessages()` take no arguments.
|
|
66
|
+
|
|
67
|
+
### Dynamic content inside `<T>`
|
|
68
|
+
|
|
69
|
+
Use variable components for dynamic values inside `<T>`:
|
|
70
|
+
|
|
71
|
+
- `<Var>{value}</Var>` — variables (strings, numbers, etc.)
|
|
72
|
+
- `<Num>{value}</Num>` — formatted numbers
|
|
73
|
+
- `<Currency>{value}</Currency>` — formatted currency
|
|
74
|
+
- `<DateTime>{value}</DateTime>` — formatted dates/times
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
import { T, Var, Num } from 'gt-react';
|
|
78
|
+
|
|
79
|
+
<T>
|
|
80
|
+
<Var>{userName}</Var> ordered <Num>{itemCount}</Num> items.
|
|
81
|
+
</T>;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Utility hooks
|
|
85
|
+
|
|
86
|
+
#### `useLocale()`
|
|
87
|
+
|
|
88
|
+
`useLocale` returns the user's current language, as a BCP 47 locale tag.
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
import { useLocale } from 'gt-react'
|
|
92
|
+
|
|
93
|
+
const locale = useLocale(); // "en-US"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Quickstart
|
|
97
|
+
|
|
98
|
+
See https://generaltranslation.com/docs/react.md
|
|
@@ -9,7 +9,7 @@ import type { ParsingConfigOptions } from '../types/parsing.js';
|
|
|
9
9
|
* @param pkg - The package name
|
|
10
10
|
* @returns An object containing the updates and errors
|
|
11
11
|
*/
|
|
12
|
-
export declare function createUpdates(options: TranslateFlags, src: string[] | undefined, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next', validate: boolean, parsingOptions: ParsingConfigOptions): Promise<{
|
|
12
|
+
export declare function createUpdates(options: TranslateFlags, src: string[] | undefined, sourceDictionary: string | undefined, pkg: 'gt-react' | 'gt-next' | 'gt-node', validate: boolean, parsingOptions: ParsingConfigOptions): Promise<{
|
|
13
13
|
updates: Updates;
|
|
14
14
|
errors: string[];
|
|
15
15
|
warnings: string[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Settings, TranslateFlags, Updates } from '../types/index.js';
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function aggregateInlineTranslations(options: TranslateFlags, settings: Settings, library: 'gt-react' | 'gt-next' | 'gt-node'): Promise<Updates>;
|
|
@@ -3,7 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import findFilepath from '../fs/findFilepath.js';
|
|
4
4
|
import { logger } from '../console/logger.js';
|
|
5
5
|
import { createUpdates } from './parse.js';
|
|
6
|
-
export async function
|
|
6
|
+
export async function aggregateInlineTranslations(options, settings, library) {
|
|
7
7
|
if (!options.dictionary) {
|
|
8
8
|
options.dictionary = findFilepath([
|
|
9
9
|
'./dictionary.js',
|
|
@@ -10,4 +10,4 @@ export type ValidationResult = Record<string, ValidationMessage[]>;
|
|
|
10
10
|
* Equivalent to running `gtx-cli validate` but returns data.
|
|
11
11
|
*/
|
|
12
12
|
export declare function getValidateJson(settings: Options & Settings, pkg: 'gt-react' | 'gt-next', files?: string[]): Promise<ValidationResult>;
|
|
13
|
-
export declare function validateProject(settings: Options & Settings, pkg: 'gt-react' | 'gt-next', files?: string[]): Promise<void>;
|
|
13
|
+
export declare function validateProject(settings: Options & Settings, pkg: 'gt-react' | 'gt-next' | 'gt-node', files?: string[]): Promise<void>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -111,7 +111,7 @@ export type SupportedFrameworks = FrameworkObject['name'];
|
|
|
111
111
|
export type SupportedReactFrameworks = Extract<FrameworkObject, {
|
|
112
112
|
type: 'react';
|
|
113
113
|
}>['name'];
|
|
114
|
-
export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'i18next' | 'i18next-icu' | 'base';
|
|
114
|
+
export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'i18next' | 'i18next-icu' | 'gt-node' | 'base';
|
|
115
115
|
export interface ContentScanner {
|
|
116
116
|
scanForContent(options: WrapOptions, framework: Framework): Promise<{
|
|
117
117
|
errors: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtx-cli",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.18",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -134,10 +134,10 @@
|
|
|
134
134
|
"typescript": "^5.5.4"
|
|
135
135
|
},
|
|
136
136
|
"scripts": {
|
|
137
|
-
"build": "node scripts/generate-version.js && tsc",
|
|
137
|
+
"build": "node scripts/generate-version.js && tsc && rm -rf dist/setup/instructions && cp -r src/setup/instructions dist/setup/instructions",
|
|
138
138
|
"build:clean": "sh ../../scripts/clean.sh && pnpm bin:restore && rm -rf binaries && pnpm run build",
|
|
139
139
|
"build:release": "pnpm run build:clean",
|
|
140
|
-
"build:bin": "node scripts/generate-version.js && tsc && sh scripts/build-exe.sh all",
|
|
140
|
+
"build:bin": "node scripts/generate-version.js && tsc && rm -rf dist/setup/instructions && cp -r src/setup/instructions dist/setup/instructions && sh scripts/build-exe.sh all",
|
|
141
141
|
"build:bin:clean": "sh ../../scripts/clean.sh && rm -rf binaries && pnpm run build:bin",
|
|
142
142
|
"build:bin:release": "pnpm run build:bin:clean && pnpm run build:bin",
|
|
143
143
|
"build:bin:darwin-x64": "sh scripts/build-exe.sh darwin-x64",
|