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.
@@ -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 MSG_TRANSLATION_FUNCTION = "msg";
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 MSG_TRANSLATION_FUNCTION = 'msg';
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
- MSG_TRANSLATION_FUNCTION,
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, MSG_TRANSLATION_FUNCTION, TRANSLATION_COMPONENT, } from '../../jsx/utils/constants.js';
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 === MSG_TRANSLATION_FUNCTION) {
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, MSG_TRANSLATION_FUNCTION, INLINE_TRANSLATION_HOOK, INLINE_TRANSLATION_HOOK_ASYNC, mapAttributeName, INLINE_MESSAGE_HOOK, INLINE_MESSAGE_HOOK_ASYNC, } from './constants.js';
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 === MSG_TRANSLATION_FUNCTION) {
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
- for (const { localName, path } of translationComponentPaths) {
45
- parseTranslationComponent({
46
- originalName: localName,
47
- localName,
48
- path,
49
- updates,
50
- config: {
51
- importAliases,
52
- parsingOptions,
53
- pkgs,
54
- file,
55
- },
56
- output: {
57
- errors,
58
- warnings,
59
- unwrappedExpressions: [],
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 aggregateReactTranslations(options: TranslateFlags, settings: Settings, library: 'gt-react' | 'gt-next'): Promise<Updates>;
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 aggregateReactTranslations(options, settings, library) {
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>;
@@ -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.17",
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",