locadex 0.1.2 → 0.1.4
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 +12 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/fixErrors.d.ts +4 -0
- package/dist/commands/fixErrors.d.ts.map +1 -0
- package/dist/commands/fixErrors.js +41 -0
- package/dist/commands/fixErrors.js.map +1 -0
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js.map +1 -1
- package/dist/mcp/getGuide.d.ts.map +1 -1
- package/dist/mcp/getGuide.js +2 -1
- package/dist/mcp/getGuide.js.map +1 -1
- package/dist/mcp/tools/guides.d.ts.map +1 -1
- package/dist/mcp/tools/guides.js +25 -55
- package/dist/mcp/tools/guides.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +4 -2
- package/dist/mcp.js.map +1 -1
- package/dist/tasks/concurrency.d.ts.map +1 -1
- package/dist/tasks/concurrency.js +15 -23
- package/dist/tasks/concurrency.js.map +1 -1
- package/dist/tasks/fixErrors.d.ts +2 -0
- package/dist/tasks/fixErrors.d.ts.map +1 -0
- package/dist/tasks/fixErrors.js +82 -0
- package/dist/tasks/fixErrors.js.map +1 -0
- package/dist/tasks/i18n.d.ts.map +1 -1
- package/dist/tasks/i18n.js +25 -82
- package/dist/tasks/i18n.js.map +1 -1
- package/dist/tasks/setup.d.ts.map +1 -1
- package/dist/tasks/setup.js +21 -9
- package/dist/tasks/setup.js.map +1 -1
- package/dist/types/claude-sdk.d.ts +13 -9
- package/dist/types/claude-sdk.d.ts.map +1 -1
- package/dist/types/claude-sdk.js.map +1 -1
- package/dist/utils/claudeCode.d.ts +13 -1
- package/dist/utils/claudeCode.d.ts.map +1 -1
- package/dist/utils/claudeCode.js +173 -66
- package/dist/utils/claudeCode.js.map +1 -1
- package/dist/utils/errors.d.ts +20 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +39 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/packages/installPackage.d.ts +1 -2
- package/dist/utils/packages/installPackage.d.ts.map +1 -1
- package/dist/utils/packages/installPackage.js +19 -28
- package/dist/utils/packages/installPackage.js.map +1 -1
- package/dist/utils/shared.d.ts +1 -1
- package/dist/utils/shared.js +1 -1
- package/dist/utils/shared.js.map +1 -1
- package/dist/utils/shutdown.d.ts +1 -2
- package/dist/utils/shutdown.d.ts.map +1 -1
- package/dist/utils/shutdown.js +1 -5
- package/dist/utils/shutdown.js.map +1 -1
- package/guides/next/advanced/{ternary-operators.md → conditional-rendering.md} +97 -39
- package/guides/next/advanced/external-strings.md +346 -0
- package/guides/next/advanced/interpolated-strings.md +35 -115
- package/guides/next/advanced/{complicated-mapping-expressions.md → mapping-expressions.md} +58 -51
- package/guides/next/basic/branches.md +62 -45
- package/guides/next/basic/jsx.md +35 -33
- package/guides/next/basic/strings.md +43 -25
- package/guides/next/basic/variables.md +12 -12
- package/guides/next/important/functions.md +13 -11
- package/guides/next/{advanced → migration}/migrating.md +2 -3
- package/package.json +1 -1
- package/guides/next/advanced/var-outside-client-component.md +0 -446
- package/guides/next/advanced/var-outside-client-server-component.md +0 -550
- package/guides/next/advanced/var-outside-server-component.md +0 -545
- package/guides/next/basic/client-side-components.md +0 -221
- package/guides/next/basic/server-side-components.md +0 -165
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
import { getPackageInfo } from 'gtx-cli/utils/packageInfo';
|
|
2
2
|
import { createSpinner } from '../../logging/console.js';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import {
|
|
4
|
+
import { installPackageGlobal } from 'gtx-cli/utils/installPackage';
|
|
5
5
|
import { logger } from '../../logging/logger.js';
|
|
6
|
-
import { CLAUDE_CODE_VERSION } from '../shared.js';
|
|
7
6
|
import { exit } from '../shutdown.js';
|
|
8
|
-
import { getPackageManager, } from 'gtx-cli/utils/packageManager';
|
|
9
7
|
import { updatePackageJson } from 'gtx-cli/utils/packageJson';
|
|
10
8
|
import path from 'node:path';
|
|
11
|
-
export async function installClaudeCode() {
|
|
12
|
-
const claudeCodeInfo = await getPackageInfo('@anthropic-ai/claude-code');
|
|
13
|
-
if (!claudeCodeInfo) {
|
|
14
|
-
const spinner = createSpinner();
|
|
15
|
-
spinner.start('Installing claude-code...');
|
|
16
|
-
try {
|
|
17
|
-
await installPackageGlobal('@anthropic-ai/claude-code', CLAUDE_CODE_VERSION);
|
|
18
|
-
spinner.stop(chalk.green('Installed claude-code.'));
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
spinner.stop(chalk.red('Failed to install claude-code.'));
|
|
22
|
-
logger.error('Claude Code installation failed. Please install it manually and try again.');
|
|
23
|
-
await exit(1);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
logger.step(`claude-code is already installed: v${claudeCodeInfo.version}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
9
|
export async function addTranslateScript(manager, packageJson, packageManager) {
|
|
31
10
|
if (!packageJson.scripts) {
|
|
32
11
|
packageJson.scripts = {};
|
|
@@ -56,11 +35,23 @@ export async function addTranslateScript(manager, packageJson, packageManager) {
|
|
|
56
35
|
await updatePackageJson(packageJson, manager.appDirectory);
|
|
57
36
|
logger.success(`Added ${chalk.cyan(translateScript)} script to your ${chalk.cyan(path.relative(manager.rootDirectory, path.resolve(manager.appDirectory, 'package.json')))} file and build command. Run ${chalk.cyan(translateScript)} to translate your project.`);
|
|
58
37
|
}
|
|
59
|
-
export async function
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
38
|
+
export async function installGlobalPackage(packageName, version) {
|
|
39
|
+
const packageInfo = await getPackageInfo(packageName);
|
|
40
|
+
if (!packageInfo) {
|
|
41
|
+
const spinner = createSpinner();
|
|
42
|
+
spinner.start(`Installing ${packageName}...`);
|
|
43
|
+
try {
|
|
44
|
+
await installPackageGlobal(packageName, version);
|
|
45
|
+
spinner.stop(chalk.green(`Installed ${packageName}.`));
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
spinner.stop(chalk.red(`Failed to install ${packageName}.`));
|
|
49
|
+
logger.error(`${packageName} installation failed. Please install it manually and try again.`);
|
|
50
|
+
await exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
logger.verboseMessage(`${packageName} is already installed: v${packageInfo.version}`);
|
|
55
|
+
}
|
|
65
56
|
}
|
|
66
57
|
//# sourceMappingURL=installPackage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installPackage.js","sourceRoot":"/","sources":["utils/packages/installPackage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"installPackage.js","sourceRoot":"/","sources":["utils/packages/installPackage.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPackageInfo } from 'gtx-cli/utils/packageInfo';\nimport { createSpinner } from '../../logging/console.js';\nimport chalk from 'chalk';\nimport { installPackageGlobal } from 'gtx-cli/utils/installPackage';\nimport { logger } from '../../logging/logger.js';\nimport { exit } from '../shutdown.js';\nimport { PackageManager } from 'gtx-cli/utils/packageManager';\nimport { updatePackageJson } from 'gtx-cli/utils/packageJson';\nimport path from 'node:path';\nimport { LocadexManager } from '../locadexManager.js';\n\nexport async function addTranslateScript(\n manager: LocadexManager,\n packageJson: Record<string, any>,\n packageManager: PackageManager\n) {\n if (!packageJson.scripts) {\n packageJson.scripts = {};\n }\n const translateCommand = `locadex translate`;\n let translateScript = 'translate';\n if (!packageJson.scripts?.translate) {\n packageJson.scripts.translate = translateCommand;\n translateScript = 'translate';\n } else {\n if (\n packageJson.scripts.translate &&\n packageJson.scripts.translate.includes(translateCommand)\n ) {\n translateScript = 'translate';\n } else {\n packageJson.scripts['translate:gt'] = translateCommand;\n translateScript = 'translate:gt';\n }\n }\n // prefix translate to build command\n const runTranslate = `${packageManager.runScriptCommand} ${translateScript}`;\n if (\n packageJson.scripts.build &&\n !packageJson.scripts.build.includes(runTranslate)\n ) {\n packageJson.scripts.build = `${runTranslate} && ${packageJson.scripts.build}`;\n }\n await updatePackageJson(packageJson, manager.appDirectory);\n logger.success(\n `Added ${chalk.cyan(translateScript)} script to your ${chalk.cyan(\n path.relative(\n manager.rootDirectory,\n path.resolve(manager.appDirectory, 'package.json')\n )\n )} file and build command. Run ${chalk.cyan(translateScript)} to translate your project.`\n );\n}\n\nexport async function installGlobalPackage(\n packageName: string,\n version: string\n) {\n const packageInfo = await getPackageInfo(packageName);\n if (!packageInfo) {\n const spinner = createSpinner();\n spinner.start(`Installing ${packageName}...`);\n try {\n await installPackageGlobal(packageName, version);\n spinner.stop(chalk.green(`Installed ${packageName}.`));\n } catch (error) {\n spinner.stop(chalk.red(`Failed to install ${packageName}.`));\n logger.error(\n `${packageName} installation failed. Please install it manually and try again.`\n );\n await exit(1);\n }\n } else {\n logger.verboseMessage(\n `${packageName} is already installed: v${packageInfo.version}`\n );\n }\n}\n"]}
|
package/dist/utils/shared.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const DAG_IGNORED_FILES: string[];
|
|
2
2
|
export declare const DAG_IGNORED_PATTERNS: string[];
|
|
3
3
|
export declare const DAG_IGNORED_EXTENSIONS: string[];
|
|
4
|
-
export declare const CLAUDE_CODE_VERSION = "1.0.
|
|
4
|
+
export declare const CLAUDE_CODE_VERSION = "1.0.22";
|
|
5
5
|
//# sourceMappingURL=shared.d.ts.map
|
package/dist/utils/shared.js
CHANGED
package/dist/utils/shared.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"/","sources":["utils/shared.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,oBAAoB;IACpB,aAAa;IACb,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,cAAc;IACd,aAAa;IACb,aAAa;IACb,cAAc;IACd,gBAAgB;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,MAAM,EAAE,cAAc;IACtB,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,sBAAsB;IACjC,UAAU,EAAE,aAAa;IACzB,UAAU;IACV,UAAU;IACV,UAAU;IACV,aAAa,EAAE,kBAAkB;IACjC,aAAa;IACb,YAAY,EAAE,uDAAuD;IACrE,YAAY;IACZ,OAAO;IACP,SAAS,EAAE,mBAAmB;IAC9B,SAAS,EAAE,mBAAmB;IAC9B,WAAW,EAAE,mBAAmB;IAChC,WAAW,EAAE,mBAAmB;IAChC,UAAU,EAAE,aAAa;IACzB,UAAU,EAAE,aAAa;IACzB,aAAa,EAAE,gBAAgB;IAC/B,aAAa,EAAE,gBAAgB;CAChC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAQ,CAAC","sourcesContent":["export const DAG_IGNORED_FILES = [\n 'next.config.js',\n 'next.config.ts',\n 'next.config.mjs',\n 'next.config.mts',\n 'next.config.cjs',\n 'next.config.cts',\n 'tailwind.config.js',\n 'webpack.config.js',\n];\n\nexport const DAG_IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.next/**',\n '**/dist/**',\n '**/build/**',\n '**/.git/**',\n '**/.cache/**',\n '**/.nuxt/**',\n '**/.vite/**',\n '**/.turbo/**',\n '**/.locadex/**',\n];\n\nexport const DAG_IGNORED_EXTENSIONS = [\n '.map', // Source maps\n '.map.js', // Source maps\n '.min.js', // Minified JavaScript\n '.min.ts', // Minified TypeScript\n '.spec.js', // Test files\n '.spec.ts',\n '.test.js',\n '.test.ts',\n '.stories.js', // Storybook files\n '.stories.ts',\n '.config.js', // Various config files (though some might be relevant)\n '.config.ts',\n '.d.ts',\n '.e2e.js', // End-to-end tests\n '.e2e.ts', // End-to-end tests\n '.setup.js', // Test setup files\n '.setup.ts', // Test setup files\n '.mock.js', // Mock files\n '.mock.ts', // Mock files\n '.fixture.js', // Test fixtures\n '.fixture.ts', // Test fixtures\n];\n\nexport const CLAUDE_CODE_VERSION = '1.0.
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"/","sources":["utils/shared.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,oBAAoB;IACpB,aAAa;IACb,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,cAAc;IACd,aAAa;IACb,aAAa;IACb,cAAc;IACd,gBAAgB;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,MAAM,EAAE,cAAc;IACtB,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,sBAAsB;IACjC,SAAS,EAAE,sBAAsB;IACjC,UAAU,EAAE,aAAa;IACzB,UAAU;IACV,UAAU;IACV,UAAU;IACV,aAAa,EAAE,kBAAkB;IACjC,aAAa;IACb,YAAY,EAAE,uDAAuD;IACrE,YAAY;IACZ,OAAO;IACP,SAAS,EAAE,mBAAmB;IAC9B,SAAS,EAAE,mBAAmB;IAC9B,WAAW,EAAE,mBAAmB;IAChC,WAAW,EAAE,mBAAmB;IAChC,UAAU,EAAE,aAAa;IACzB,UAAU,EAAE,aAAa;IACzB,aAAa,EAAE,gBAAgB;IAC/B,aAAa,EAAE,gBAAgB;CAChC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAQ,CAAC","sourcesContent":["export const DAG_IGNORED_FILES = [\n 'next.config.js',\n 'next.config.ts',\n 'next.config.mjs',\n 'next.config.mts',\n 'next.config.cjs',\n 'next.config.cts',\n 'tailwind.config.js',\n 'webpack.config.js',\n];\n\nexport const DAG_IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.next/**',\n '**/dist/**',\n '**/build/**',\n '**/.git/**',\n '**/.cache/**',\n '**/.nuxt/**',\n '**/.vite/**',\n '**/.turbo/**',\n '**/.locadex/**',\n];\n\nexport const DAG_IGNORED_EXTENSIONS = [\n '.map', // Source maps\n '.map.js', // Source maps\n '.min.js', // Minified JavaScript\n '.min.ts', // Minified TypeScript\n '.spec.js', // Test files\n '.spec.ts',\n '.test.js',\n '.test.ts',\n '.stories.js', // Storybook files\n '.stories.ts',\n '.config.js', // Various config files (though some might be relevant)\n '.config.ts',\n '.d.ts',\n '.e2e.js', // End-to-end tests\n '.e2e.ts', // End-to-end tests\n '.setup.js', // Test setup files\n '.setup.ts', // Test setup files\n '.mock.js', // Mock files\n '.mock.ts', // Mock files\n '.fixture.js', // Test fixtures\n '.fixture.ts', // Test fixtures\n];\n\nexport const CLAUDE_CODE_VERSION = '1.0.22';\n"]}
|
package/dist/utils/shutdown.d.ts
CHANGED
|
@@ -9,10 +9,9 @@ declare class GracefulShutdown {
|
|
|
9
9
|
private isShuttingDown;
|
|
10
10
|
private exitCode;
|
|
11
11
|
constructor();
|
|
12
|
-
|
|
12
|
+
handleSignal(signal: string): Promise<void>;
|
|
13
13
|
addHandler(handler: ShutdownHandler): void;
|
|
14
14
|
shutdown(exitCode?: ExitCode): Promise<void>;
|
|
15
|
-
exit(code?: ExitCode): Promise<void>;
|
|
16
15
|
}
|
|
17
16
|
export declare const gracefulShutdown: GracefulShutdown;
|
|
18
17
|
export declare function exit(code?: ExitCode): Promise<never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.d.ts","sourceRoot":"/","sources":["utils/shutdown.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;AAE7B,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,gBAAgB;IACpB,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAe;;
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"/","sources":["utils/shutdown.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;AAE7B,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,cAAM,gBAAgB;IACpB,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAe;;IASzB,YAAY,CAAC,MAAM,EAAE,MAAM;IAOjC,UAAU,CAAC,OAAO,EAAE,eAAe;IAI7B,QAAQ,CAAC,QAAQ,GAAE,QAAY;CAiCtC;AAGD,eAAO,MAAM,gBAAgB,kBAAyB,CAAC;AAGvD,wBAAgB,IAAI,CAAC,IAAI,GAAE,QAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAEvD"}
|
package/dist/utils/shutdown.js
CHANGED
|
@@ -4,10 +4,10 @@ class GracefulShutdown {
|
|
|
4
4
|
isShuttingDown = false;
|
|
5
5
|
exitCode = 0;
|
|
6
6
|
constructor() {
|
|
7
|
-
// Handle termination signals
|
|
8
7
|
process.on('SIGINT', () => this.handleSignal('SIGINT'));
|
|
9
8
|
process.on('SIGTERM', () => this.handleSignal('SIGTERM'));
|
|
10
9
|
process.on('SIGUSR2', () => this.handleSignal('SIGUSR2')); // nodemon restart
|
|
10
|
+
process.on('exit', () => this.handleSignal('exit')); // in case other libraries override the signal handlers such as @clack/prompts
|
|
11
11
|
}
|
|
12
12
|
async handleSignal(signal) {
|
|
13
13
|
logger.debugMessage(`Received ${signal}, initiating graceful shutdown with exit code 0...`);
|
|
@@ -40,10 +40,6 @@ class GracefulShutdown {
|
|
|
40
40
|
logger.debugMessage('Graceful shutdown complete');
|
|
41
41
|
process.exit(this.exitCode);
|
|
42
42
|
}
|
|
43
|
-
// For backward compatibility and convenience
|
|
44
|
-
exit(code = 0) {
|
|
45
|
-
return this.shutdown(code);
|
|
46
|
-
}
|
|
47
43
|
}
|
|
48
44
|
// Export singleton instance
|
|
49
45
|
export const gracefulShutdown = new GracefulShutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shutdown.js","sourceRoot":"/","sources":["utils/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAU9C,MAAM,gBAAgB;IACZ,gBAAgB,GAAsB,EAAE,CAAC;IACzC,cAAc,GAAG,KAAK,CAAC;IACvB,QAAQ,GAAa,CAAC,CAAC;IAE/B;QACE,
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"/","sources":["utils/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAU9C,MAAM,gBAAgB;IACZ,gBAAgB,GAAsB,EAAE,CAAC;IACzC,cAAc,GAAG,KAAK,CAAC;IACvB,QAAQ,GAAa,CAAC,CAAC;IAE/B;QACE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,kBAAkB;QAC7E,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,8EAA8E;IACrI,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,MAAM,CAAC,YAAY,CACjB,YAAY,MAAM,oDAAoD,CACvE,CAAC;QACF,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,OAAwB;QACjC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,WAAqB,CAAC;QACnC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,oDAAoD;QACpD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,CAAC;QAEtD,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,IAAI,QAAQ,EAAE,CAAC;YACzD,IAAI,CAAC;gBACH,MAAM,CAAC,YAAY,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;gBAE3D,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;oBACrD,MAAM,CAAC,UAAU,CACf,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,EAC3C,OAAO,CACR,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;gBAEjE,MAAM,CAAC,YAAY,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,MAAM,CAAC,YAAY,CAAC,4BAA4B,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAEvD,yDAAyD;AACzD,MAAM,UAAU,IAAI,CAAC,OAAiB,CAAC;IACrC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAmB,CAAC;AAC3D,CAAC","sourcesContent":["import { logger } from '../logging/logger.js';\n\nexport type ExitCode = 0 | 1;\n\ninterface ShutdownHandler {\n name: string;\n handler: () => Promise<void> | void;\n timeout?: number;\n}\n\nclass GracefulShutdown {\n private shutdownHandlers: ShutdownHandler[] = [];\n private isShuttingDown = false;\n private exitCode: ExitCode = 0;\n\n constructor() {\n process.on('SIGINT', () => this.handleSignal('SIGINT'));\n process.on('SIGTERM', () => this.handleSignal('SIGTERM'));\n process.on('SIGUSR2', () => this.handleSignal('SIGUSR2')); // nodemon restart\n process.on('exit', () => this.handleSignal('exit')); // in case other libraries override the signal handlers such as @clack/prompts\n }\n\n async handleSignal(signal: string) {\n logger.debugMessage(\n `Received ${signal}, initiating graceful shutdown with exit code 0...`\n );\n await this.shutdown(0);\n }\n\n addHandler(handler: ShutdownHandler) {\n this.shutdownHandlers.push(handler);\n }\n\n async shutdown(exitCode: ExitCode = 0) {\n if (this.isShuttingDown) {\n return;\n }\n\n this.isShuttingDown = true;\n this.exitCode = exitCode;\n\n // Execute shutdown handlers in reverse order (LIFO)\n const handlers = [...this.shutdownHandlers].reverse();\n\n for (const { name, handler, timeout = 5000 } of handlers) {\n try {\n logger.debugMessage(`Executing shutdown handler: ${name}`);\n\n const timeoutPromise = new Promise<void>((_, reject) => {\n global.setTimeout(\n () => reject(new Error(`Timeout: ${name}`)),\n timeout\n );\n });\n\n await Promise.race([Promise.resolve(handler()), timeoutPromise]);\n\n logger.debugMessage(`Completed shutdown handler: ${name}`);\n } catch (error) {\n logger.error(`Error in shutdown handler ${name}: ${error}`);\n }\n }\n\n logger.debugMessage('Graceful shutdown complete');\n process.exit(this.exitCode);\n }\n}\n\n// Export singleton instance\nexport const gracefulShutdown = new GracefulShutdown();\n\n// Export convenience function for backward compatibility\nexport function exit(code: ExitCode = 0): Promise<never> {\n return gracefulShutdown.shutdown(code) as Promise<never>;\n}\n"]}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
# Conditional Content Internationalization
|
|
1
|
+
# Guide: Conditional Content Internationalization
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This guide covers how to internationalize more complex conditional rendering patterns.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See the `mcp__locadex__next_basic_branches` guide for more information on the `<Branch>` and `<Plural>` components.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Objective**: Transform ternary operators and conditional rendering into translatable patterns using `<T>`, `<Branch>`, `<Plural>`, `<Var>`, and `useGT()`.
|
|
8
|
+
|
|
9
|
+
## Dynamic Content in `<T>` Components
|
|
10
|
+
|
|
11
|
+
### `<Branch>` Component
|
|
8
12
|
|
|
9
13
|
**Rules**:
|
|
10
14
|
|
|
11
|
-
- `<T>` components cannot contain dynamic expressions. Use `<Branch>` for
|
|
12
|
-
- When working with `useGT()` always add a `"use client"` directive.
|
|
15
|
+
- `<T>` components cannot contain dynamic expressions. Use `<Branch>` for conditionally rendered JSX ternary operators within `<T>`.
|
|
13
16
|
|
|
14
17
|
**Non-internationalized conditional**:
|
|
15
18
|
|
|
@@ -27,7 +30,7 @@ const MyComponent = ({ isLoggedIn }) => {
|
|
|
27
30
|
};
|
|
28
31
|
```
|
|
29
32
|
|
|
30
|
-
**Invalid approach
|
|
33
|
+
**Invalid approach - Dynamic ternary inside `<T>`**
|
|
31
34
|
|
|
32
35
|
```jsx
|
|
33
36
|
const MyComponent = ({ isLoggedIn }) => {
|
|
@@ -43,9 +46,10 @@ const MyComponent = ({ isLoggedIn }) => {
|
|
|
43
46
|
};
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
**Correct implementation
|
|
49
|
+
**Correct implementation - `<Branch>` component**
|
|
47
50
|
|
|
48
51
|
```jsx
|
|
52
|
+
import { T, Branch } from 'gt-next';
|
|
49
53
|
const MyComponent = ({ isLoggedIn }) => {
|
|
50
54
|
return (
|
|
51
55
|
<T>
|
|
@@ -61,19 +65,19 @@ const MyComponent = ({ isLoggedIn }) => {
|
|
|
61
65
|
|
|
62
66
|
**Requirements**:
|
|
63
67
|
|
|
64
|
-
-
|
|
68
|
+
- `branch` prop only accepts strings: `isLoggedIn.toString()`
|
|
65
69
|
- Define static JSX for `true` and `false` props
|
|
66
70
|
- Wrap entire structure in `<T>` component
|
|
67
71
|
|
|
68
72
|
**Recommendation**:
|
|
69
73
|
|
|
70
|
-
- Whenever possible, use `<T>` component with
|
|
71
|
-
- All ternaries used in JSX components can be converted to use
|
|
72
|
-
- Use Variable components to wrap dynamic content.
|
|
74
|
+
- Whenever possible, use `<T>` component with `<Branch>` for internationalizing ternaries.
|
|
75
|
+
- All ternaries used in JSX components can be converted to use `<Branch>`.
|
|
76
|
+
- Use Variable components to wrap dynamic content. See the `mcp__locadex__next_basic_variables` guide for more information on Variable Components.
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
## String-Based Conditional Translation
|
|
75
79
|
|
|
76
|
-
**Pattern**: Apply translation functions to each branch of ternary operators
|
|
80
|
+
**Pattern**: Apply translation functions to each branch of ternary operators.
|
|
77
81
|
|
|
78
82
|
**Non-internationalized ternary**:
|
|
79
83
|
|
|
@@ -86,8 +90,7 @@ const getCountMessage = ({ count }) => {
|
|
|
86
90
|
**Internationalized implementation**:
|
|
87
91
|
|
|
88
92
|
```jsx
|
|
89
|
-
|
|
90
|
-
import { useGT } from 'gt-next/client';
|
|
93
|
+
import { useGT } from 'gt-next';
|
|
91
94
|
const getCountMessage = ({ count }) => {
|
|
92
95
|
const t = useGT();
|
|
93
96
|
return count === 1
|
|
@@ -106,12 +109,32 @@ const getCountMessage = ({ count }) => {
|
|
|
106
109
|
|
|
107
110
|
**Technique**:
|
|
108
111
|
|
|
109
|
-
- For JSX: Use a `<Branch>` or `<Plural>` component.
|
|
112
|
+
- For JSX: Use a `<Branch>` or `<Plural>` component. These can be nested.
|
|
110
113
|
- For Strings: Each condition level receives separate translation call.
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
```jsx
|
|
116
|
+
import { T, Branch } from 'gt-next';
|
|
117
|
+
const MyComponent = ({ isLoggedIn, isAdmin }) => {
|
|
118
|
+
return (
|
|
119
|
+
<T>
|
|
120
|
+
<Branch
|
|
121
|
+
branch={isLoggedIn.toString()}
|
|
122
|
+
true={
|
|
123
|
+
<div>
|
|
124
|
+
Welcome back!
|
|
125
|
+
<Branch
|
|
126
|
+
branch={isAdmin.toString()}
|
|
127
|
+
true={<div>You are an admin!</div>}
|
|
128
|
+
false={<div>You are not an admin!</div>}
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
}
|
|
132
|
+
false={<div>Please log in to continue</div>}
|
|
133
|
+
/>
|
|
134
|
+
</T>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
```
|
|
115
138
|
|
|
116
139
|
#### JSX Approach
|
|
117
140
|
|
|
@@ -171,8 +194,7 @@ const getItemsFoundMessage = ({ items }) => {
|
|
|
171
194
|
Internationalized
|
|
172
195
|
|
|
173
196
|
```jsx
|
|
174
|
-
|
|
175
|
-
import { useGT } from 'gt-next/client';
|
|
197
|
+
import { useGT } from 'gt-next';
|
|
176
198
|
|
|
177
199
|
const getItemsFoundMessage = ({ items }) => {
|
|
178
200
|
const t = useGT();
|
|
@@ -184,32 +206,68 @@ const getItemsFoundMessage = ({ items }) => {
|
|
|
184
206
|
};
|
|
185
207
|
```
|
|
186
208
|
|
|
187
|
-
|
|
209
|
+
## Example
|
|
188
210
|
|
|
189
|
-
|
|
190
|
-
- Use singular form for count === 1
|
|
191
|
-
- Apply variable interpolation for plural cases
|
|
211
|
+
Here is an example demonstrating how to internationalize a conditional rendering pattern.
|
|
192
212
|
|
|
193
|
-
|
|
213
|
+
Original:
|
|
194
214
|
|
|
195
|
-
|
|
215
|
+
```jsx
|
|
216
|
+
const MyComponent = ({ loading, items }) => {
|
|
217
|
+
return (
|
|
218
|
+
<div>
|
|
219
|
+
{loading ? (
|
|
220
|
+
<div>Loading...</div>
|
|
221
|
+
) : items.length > 0 ? (
|
|
222
|
+
<div>{items.length} items found</div>
|
|
223
|
+
) : (
|
|
224
|
+
<div>No items found</div>
|
|
225
|
+
)}
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Internationalized:
|
|
196
232
|
|
|
197
233
|
```jsx
|
|
198
|
-
|
|
234
|
+
import { T, Branch, Plural } from 'gt-next';
|
|
235
|
+
const MyComponent = ({ loading, items }) => {
|
|
236
|
+
return (
|
|
237
|
+
<T>
|
|
238
|
+
<Branch
|
|
239
|
+
branch={loading.toString()} // Expects a string
|
|
240
|
+
true={<div>Loading...</div>}
|
|
241
|
+
false={
|
|
242
|
+
<Plural
|
|
243
|
+
branch={items.length} // Expects a number
|
|
244
|
+
one={<div>{items.length} item found</div>}
|
|
245
|
+
other={<div>{items.length} items found</div>}
|
|
246
|
+
zero={<div>No items found</div>}
|
|
247
|
+
/>
|
|
248
|
+
}
|
|
249
|
+
/>
|
|
250
|
+
</T>
|
|
251
|
+
);
|
|
252
|
+
};
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Alternatively, the same content can be internationalized using `useGT()`:
|
|
256
|
+
|
|
257
|
+
```jsx
|
|
258
|
+
import { useGT } from 'gt-next';
|
|
259
|
+
const MyComponent = ({ loading, items }) => {
|
|
260
|
+
const t = useGT();
|
|
199
261
|
return (
|
|
200
262
|
<div>
|
|
201
263
|
{loading ? (
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
<div>An error occurred</div>
|
|
208
|
-
</T>
|
|
264
|
+
<div>{t('Loading...')}</div>
|
|
265
|
+
) : items.length > 0 ? (
|
|
266
|
+
<div>
|
|
267
|
+
{t('{count} items found', { variables: { count: items.length } })}
|
|
268
|
+
</div>
|
|
209
269
|
) : (
|
|
210
|
-
<
|
|
211
|
-
<div>Content loaded successfully</div>
|
|
212
|
-
</T>
|
|
270
|
+
<div>{t('No items found')}</div>
|
|
213
271
|
)}
|
|
214
272
|
</div>
|
|
215
273
|
);
|