gt 2.16.1 → 2.16.2

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.16.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2029](https://github.com/generaltranslation/gt/pull/2029) [`c1fd8a0`](https://github.com/generaltranslation/gt/commit/c1fd8a05c5325775e3ec8104e2d48d35da864de6) Thanks [@eoinest](https://github.com/eoinest)! - Configure Vite React apps with `initializeGTSPA` and bundled translation loading without adding the compiler.
8
+
3
9
  ## 2.16.1
4
10
 
5
11
  ### Patch Changes
package/dist/cli/base.js CHANGED
@@ -6,6 +6,7 @@ import { displayHeader, exitSync, logErrorAndExit, promptConfirm, promptGlobPatt
6
6
  import findFilepath from "../fs/findFilepath.js";
7
7
  import { lottieTranslateError } from "../console/index.js";
8
8
  import { INLINE_LIBRARIES } from "../types/libraries.js";
9
+ import { loadConfig } from "../fs/config/loadConfig.js";
9
10
  import { FILE_EXT_TO_EXT_LABEL } from "../formats/files/supportedFiles.js";
10
11
  import { generateSettings } from "../config/generateSettings.js";
11
12
  import { createOrUpdateConfig } from "../fs/config/setupConfig.js";
@@ -35,6 +36,7 @@ import { splitMintlifyLanguageRefs } from "../utils/splitMintlifyLanguageRefs.js
35
36
  import { runMergeDriver } from "../git/mergeDrivers.js";
36
37
  import { setupGitMergeDrivers } from "../git/setupMergeDrivers.js";
37
38
  import { warnReactPackageCompatibility } from "../utils/reactPackageCompatibility.js";
39
+ import { setupViteSPA } from "../setup/setupViteSPA.js";
38
40
  import chalk from "chalk";
39
41
  import path from "node:path";
40
42
  import fs from "node:fs";
@@ -56,8 +58,15 @@ const workspaceRootSetupError = createDiagnosticMessage({
56
58
  why: "GT must be configured in the specific app you want to localize",
57
59
  fix: "Change to that app's directory and rerun `npx gt@latest`"
58
60
  });
59
- async function exitIfWorkspaceRoot() {
61
+ const electronSetupError = createDiagnosticMessage({
62
+ source: "gt",
63
+ severity: "Error",
64
+ whatHappened: "The automatic setup wizard is not ready for Electron applications",
65
+ docsUrl: "https://generaltranslation.com/docs/react"
66
+ });
67
+ async function exitIfUnsupportedSetupTarget() {
60
68
  const packageJson = await searchForPackageJson();
69
+ if (packageJson && isPackageInstalled("electron", packageJson, false, true)) logErrorAndExit(electronSetupError);
61
70
  if (fs.existsSync(path.join(process.cwd(), "pnpm-workspace.yaml")) || packageJson?.workspaces) logErrorAndExit(workspaceRootSetupError);
62
71
  }
63
72
  var BaseCLI = class {
@@ -274,7 +283,7 @@ var BaseCLI = class {
274
283
  }
275
284
  setupInitCommand() {
276
285
  this.program.command("init").description("Run the setup wizard to configure your project for General Translation").option("--src <paths...>", "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'").option("-c, --config <path>", "Filepath to config file, by default gt.config.json", findFilepath(["gt.config.json"])).action(async (options) => {
277
- await exitIfWorkspaceRoot();
286
+ await exitIfUnsupportedSetupTarget();
278
287
  const settings = await generateSettings(options);
279
288
  displayHeader("Running setup wizard...");
280
289
  const framework = await detectFramework();
@@ -294,7 +303,7 @@ var BaseCLI = class {
294
303
  const frameworkDisplayName = framework.type === "react" ? getFrameworkDisplayName(framework) : null;
295
304
  const library = framework.type === "react" ? getReactFrameworkLibrary(framework) : null;
296
305
  const defaultTranslationsDir = framework.name === "vite" ? DEFAULT_VITE_TRANSLATIONS_DIR : DEFAULT_TRANSLATIONS_DIR;
297
- const defaultsDescription = framework.type === "react" ? `${library} & GTProvider, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}` : `Files saved locally in ${defaultTranslationsDir}`;
306
+ const defaultsDescription = framework.name === "vite" ? `${library} & initializeGTSPA, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}` : framework.type === "react" ? `${library} & GTProvider, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}` : `Files saved locally in ${defaultTranslationsDir}`;
298
307
  const useDefaults = await promptConfirm({
299
308
  message: `Would you like to use the recommended General Translation defaults? ${chalk.dim(`(${defaultsDescription})`)}`,
300
309
  defaultValue: true
@@ -302,7 +311,7 @@ var BaseCLI = class {
302
311
  let ranReactSetup = false;
303
312
  if (framework.type === "react") {
304
313
  if (useDefaults ? true : await promptConfirm({
305
- message: `Would you like to install ${library} and add the GTProvider? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`,
314
+ message: framework.name === "vite" ? `Would you like to install ${library} and configure initializeGTSPA? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart` : `Would you like to install ${library} and add the GTProvider? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`,
306
315
  defaultValue: true
307
316
  })) {
308
317
  logger.info(`${chalk.yellow("[EXPERIMENTAL]")} Configuring project...`);
@@ -320,7 +329,7 @@ var BaseCLI = class {
320
329
  }
321
330
  setupConfigureCommand() {
322
331
  this.program.command("configure").description("Configure your project for General Translation. This will create a gt.config.json file in your codebase.").action(async () => {
323
- await exitIfWorkspaceRoot();
332
+ await exitIfUnsupportedSetupTarget();
324
333
  displayHeader("Configuring project...");
325
334
  logger.info("Welcome! This tool will help you configure your gt.config.json file. See the docs: https://generaltranslation.com/docs/cli/reference/config for more information.");
326
335
  const framework = await detectFramework();
@@ -333,7 +342,8 @@ var BaseCLI = class {
333
342
  await upload(settings);
334
343
  }
335
344
  async handleInitCommand(ranReactSetup, useDefaults = false, isVite = false) {
336
- const { defaultLocale, locales } = await getDesiredLocales();
345
+ const configFilepath = !isVite && fs.existsSync("src/gt.config.json") ? "src/gt.config.json" : "gt.config.json";
346
+ const { defaultLocale, locales } = await getDesiredLocales(loadConfig(configFilepath));
337
347
  const packageJson = await searchForPackageJson();
338
348
  const gtInstalled = !!packageJson && INLINE_LIBRARIES.some((lib) => isPackageInstalled(lib, packageJson));
339
349
  const isUsingGT = ranReactSetup || gtInstalled;
@@ -357,7 +367,7 @@ var BaseCLI = class {
357
367
  message: "What is the path to the directory where you would like to store your translation files?",
358
368
  defaultValue: defaultTranslationsDir
359
369
  }) : null)?.trim() || defaultTranslationsDir;
360
- if (isUsingGT && !usingCDN) {
370
+ if (isUsingGT && !usingCDN && !isVite) {
361
371
  await createLoadTranslationsFile(process.cwd(), finalTranslationsDir, locales);
362
372
  logger.message(`Created ${chalk.cyan("loadTranslations.js")} file for local translations.
363
373
  Make sure to add this function to your app configuration.
@@ -404,23 +414,29 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
404
414
  })) };
405
415
  }
406
416
  if (isUsingGT && !usingCDN) files.gt = { output: path.join(finalTranslationsDir, `[locale].json`) };
407
- let configFilepath = "gt.config.json";
408
- if (fs.existsSync("src/gt.config.json")) configFilepath = "src/gt.config.json";
409
417
  await createOrUpdateConfig(configFilepath, {
410
418
  defaultLocale,
411
419
  locales,
412
420
  files: Object.keys(files).length > 0 ? files : void 0,
421
+ framework: isVite ? "vite" : void 0,
413
422
  publish: isUsingGT && usingCDN
414
423
  });
415
424
  logger.success(`Edit ${chalk.cyan(configFilepath)} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
416
- if (!(packageJson ? isPackageInstalled("gt", packageJson, true, true) : true)) {
425
+ if (ranReactSetup && isVite) await setupViteSPA({
426
+ appDirectory: process.cwd(),
427
+ configFilepath,
428
+ defaultLocale,
429
+ locales,
430
+ translationsDir: usingCDN ? void 0 : finalTranslationsDir
431
+ });
432
+ if (!(packageJson ? isPackageInstalled("gt", packageJson, true, true) : true) && !(isUsingGT && isVite)) {
417
433
  const packageManager = await getPackageManager();
418
434
  const spinner = logger.createSpinner();
419
435
  spinner.start(`Installing gt as a dev dependency with ${packageManager.name}...`);
420
436
  await installPackage("gt", packageManager, true);
421
437
  spinner.stop(chalk.green("Installed gt."));
422
438
  }
423
- if (!areCredentialsSet()) {
439
+ if ((!isVite || !isUsingGT || usingCDN) && !areCredentialsSet()) {
424
440
  if (useDefaults ? true : await promptConfirm({
425
441
  message: "Would you like the wizard to automatically generate API keys and a project ID for you?",
426
442
  defaultValue: true
@@ -443,7 +459,7 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
443
459
  }
444
460
  ],
445
461
  defaultValue: "all"
446
- })), settings.framework);
462
+ })), isVite ? "vite" : settings.framework);
447
463
  }
448
464
  }
449
465
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../src/cli/base.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n DEFAULT_TRANSLATIONS_DIR,\n DEFAULT_VITE_TRANSLATIONS_DIR,\n} from '../utils/constants.js';\nimport { createOrUpdateConfig } from '../fs/config/setupConfig.js';\nimport findFilepath from '../fs/findFilepath.js';\nimport {\n displayHeader,\n promptText,\n logErrorAndExit,\n exitSync,\n promptConfirm,\n promptMultiSelect,\n promptSelect,\n promptGlobPatterns,\n} from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { lottieTranslateError } from '../console/index.js';\nimport { parseGlobPatterns } from '../console/promptParsing.js';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport {\n FilesOptions,\n Settings,\n SupportedLibraries,\n SetupOptions,\n TranslateFlags,\n SharedFlags,\n} from '../types/index.js';\nimport { generateSettings } from '../config/generateSettings.js';\nimport chalk from 'chalk';\nimport { FILE_EXT_TO_EXT_LABEL } from '../formats/files/supportedFiles.js';\nimport { handleSetupReactCommand } from '../setup/wizard.js';\nimport {\n isPackageInstalled,\n searchForPackageJson,\n} from '../utils/packageJson.js';\nimport { getDesiredLocales } from '../setup/userInput.js';\nimport { installPackage } from '../utils/installPackage.js';\nimport { getPackageManager } from '../utils/packageManager.js';\nimport { retrieveCredentials, setCredentials } from '../utils/credentials.js';\nimport { areCredentialsSet } from '../utils/credentials.js';\nimport { upload } from './commands/upload.js';\nimport { attachSharedFlags, attachTranslateFlags } from './flags.js';\nimport { handleStage } from './commands/stage.js';\nimport { handleSetupProject } from './commands/setupProject.js';\nimport { handleDownload } from './commands/download.js';\nimport {\n handleTranslate,\n postProcessTranslations,\n} from './commands/translate.js';\nimport {\n getNeedsPostprocessing,\n clearDownloaded,\n} from '../state/recentDownloads.js';\nimport { clearWarnings } from '../state/translateWarnings.js';\nimport { displayTranslateSummary } from '../console/displayTranslateSummary.js';\nimport updateConfig from '../fs/config/updateConfig.js';\nimport { createLoadTranslationsFile } from '../fs/createLoadTranslationsFile.js';\nimport { saveLocalEdits } from '../api/saveLocalEdits.js';\nimport processSharedStaticAssets, {\n mirrorAssetsToLocales,\n} from '../utils/sharedStaticAssets.js';\nimport { setupLocadex } from '../locadex/setupFlow.js';\nimport { detectFramework } from '../setup/detectFramework.js';\nimport {\n getFrameworkDisplayName,\n getReactFrameworkLibrary,\n} from '../setup/frameworkUtils.js';\nimport { INLINE_LIBRARIES } from '../types/libraries.js';\nimport { handleEnqueue } from './commands/enqueue.js';\nimport { splitMintlifyLanguageRefs } from '../utils/splitMintlifyLanguageRefs.js';\nimport { runMergeDriver, type MergeDriverName } from '../git/mergeDrivers.js';\nimport { setupGitMergeDrivers } from '../git/setupMergeDrivers.js';\nimport { warnReactPackageCompatibility } from '../utils/reactPackageCompatibility.js';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\n\nconst ID_COMPATIBILITY_WARNING_COMMANDS = new Set([\n 'download',\n 'enqueue',\n 'generate',\n 'setup',\n 'stage',\n 'translate',\n 'validate',\n]);\nconst workspaceRootSetupError = createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'The setup wizard cannot run from a monorepo workspace root',\n why: 'GT must be configured in the specific app you want to localize',\n fix: \"Change to that app's directory and rerun `npx gt@latest`\",\n});\n\nasync function exitIfWorkspaceRoot(): Promise<void> {\n const packageJson = await searchForPackageJson();\n if (\n fs.existsSync(path.join(process.cwd(), 'pnpm-workspace.yaml')) ||\n packageJson?.workspaces\n ) {\n logErrorAndExit(workspaceRootSetupError);\n }\n}\n\nexport type UploadOptions = {\n config?: string;\n apiKey?: string;\n projectId?: string;\n defaultLocale?: string;\n};\n\nexport type LoginOptions = {\n config?: string;\n keyType?: 'development' | 'production' | 'all';\n};\n\nexport type GitSetupOptions = {\n config?: string;\n dryRun?: boolean;\n omitConfigIds?: boolean;\n driverCommand?: string;\n};\n\nexport class BaseCLI {\n protected library: SupportedLibraries;\n protected additionalModules: SupportedLibraries[];\n protected program: Command;\n // Constructor is shared amongst all CLI class types\n public constructor(\n program: Command,\n library: SupportedLibraries,\n additionalModules?: SupportedLibraries[]\n ) {\n this.program = program;\n this.library = library;\n this.additionalModules = additionalModules || [];\n\n this.program.option(\n '--skip-version-check',\n 'Skip the monorepo GT package version consistency check'\n );\n this.program.option(\n '--suppress-id-compatibility-warning',\n 'Suppress the React package ID compatibility warning'\n );\n this.program.option(\n '-q, --quiet',\n 'Suppress informational output; only warnings and errors are shown'\n );\n // Apply --quiet before any other hook or command action runs so the\n // singleton logger is muted for the rest of the invocation. The flag is a\n // global root option, so commander resolves it in any position and for\n // nested commands (e.g. `gt git setup --quiet`).\n this.program.hook('preAction', () => {\n logger.setQuiet(Boolean(this.program.opts().quiet));\n });\n this.program.hook('preAction', async (thisCommand, actionCommand) => {\n // Nested commands (e.g. `gt git setup`) can share leaf names with\n // translation commands; only direct children of the root qualify\n if (actionCommand.parent !== thisCommand) return;\n if (!ID_COMPATIBILITY_WARNING_COMMANDS.has(actionCommand.name())) return;\n await warnReactPackageCompatibility(\n Boolean(this.program.opts().suppressIdCompatibilityWarning)\n );\n });\n\n this.setupInitCommand();\n this.setupConfigureCommand();\n this.setupUploadCommand();\n this.setupLoginCommand();\n this.setupSendDiffsCommand();\n this.setupGitCommand();\n }\n // Init is never called in a child class\n public init() {\n this.setupSetupProjectCommand();\n this.setupStageCommand();\n this.setupTranslateCommand();\n this.setupDownloadCommand();\n this.setupEnqueueCommand();\n }\n // Execute is called by the main program\n public execute() {\n // If no command is specified, run 'init'\n if (process.argv.length <= 2) {\n process.argv.push('init');\n }\n }\n\n protected setupSetupProjectCommand(): void {\n attachTranslateFlags(\n this.program\n .command('setup')\n .description(\n 'Upload source files and setup the project for translation'\n )\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Uploading source files and setting up project...');\n await this.handleSetupProject(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupStageCommand(): void {\n attachTranslateFlags(\n this.program\n .command('stage')\n .description(\n 'Submits the project to the General Translation API for translation. Translations created using this command will require human approval.'\n )\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader(\n 'Staging project for translation with approval required...'\n );\n await this.handleStage(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n /**\n * Enqueues translations for a given set of files\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected setupEnqueueCommand(): void {\n attachTranslateFlags(\n this.program\n .command('enqueue')\n .description('Enqueues translations for a given set of files')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Enqueuing translations...');\n await this.handleEnqueue(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n /**\n * Downloads translations that were originally staged\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected setupDownloadCommand(): void {\n attachTranslateFlags(\n this.program\n .command('download')\n .description('Download translations that were originally staged')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Downloading translations...');\n await this.handleDownload(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupTranslateCommand(): void {\n attachTranslateFlags(\n this.program\n .command('translate')\n .description('Translate your project using General Translation')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Starting translation...');\n await this.handleTranslate(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupSendDiffsCommand(): void {\n attachSharedFlags(\n this.program\n .command('save-local')\n .description(\n 'Save local edits for all configured files by sending diffs (no translation enqueued)'\n )\n )\n .option('--publish', 'Publish translations to the CDN', false)\n .action(async (initOptions: SharedFlags) => {\n displayHeader('Saving local edits...');\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await saveLocalEdits(settings);\n logger.endCommand('Saved local edits');\n });\n }\n\n protected setupGitCommand(): void {\n const gitCommand = this.program\n .command('git')\n .description('Configure Git integrations for General Translation');\n\n gitCommand\n .command('setup')\n .description('Set up GT merge drivers for generated translation files')\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option('--dry-run', 'Print changes without writing files', false)\n .option(\n '--omit-config-ids',\n 'Persist omitConfigIds and remove generated config IDs'\n )\n .option(\n '--driver-command <command>',\n 'Command Git should use to invoke gt, e.g. \"pnpm exec gt\"'\n )\n .action(async (options: GitSetupOptions) => {\n displayHeader('Setting up GT Git merge drivers...');\n const settings = await generateSettings(options, undefined, {\n requireConfig: true,\n });\n const omitConfigIds = await this.resolveGitSetupOmitConfigIds(\n options,\n settings\n );\n const result = await setupGitMergeDrivers(settings, {\n dryRun: options.dryRun,\n omitConfigIds,\n driverCommand: options.driverCommand,\n });\n\n for (const line of result.addedAttributes) {\n logger.step(\n `${options.dryRun ? 'Would add' : 'Added'} ${chalk.cyan(\n line\n )} to ${chalk.cyan(result.gitattributesPath)}`\n );\n }\n if (result.addedAttributes.length === 0) {\n logger.info(`${chalk.cyan('.gitattributes')} is already configured.`);\n }\n\n for (const args of result.gitConfigCommands) {\n logger.step(\n `${options.dryRun ? 'Would run' : 'Configured'} ${chalk.cyan(\n `git config --local ${args.join(' ')}`\n )}`\n );\n }\n\n if (result.updatedConfig) {\n logger.step(\n `${options.dryRun ? 'Would persist' : 'Persisted'} ${chalk.cyan(\n 'omitConfigIds: true'\n )} in ${chalk.cyan(settings.config)}`\n );\n } else if (options.dryRun && !settings.omitConfigIds) {\n logger.info(\n `Run without ${chalk.cyan('--dry-run')} to be prompted to persist ${chalk.cyan(\n 'omitConfigIds: true'\n )}, or pass ${chalk.cyan('--omit-config-ids')}.`\n );\n }\n\n for (const warning of result.warnings) {\n logger.warn(chalk.yellow(warning));\n }\n\n logger.endCommand(\n options.dryRun\n ? 'Dry run complete.'\n : 'GT Git merge drivers configured.'\n );\n });\n\n gitCommand\n .command('merge-driver', { hidden: true })\n .argument('<driver>', 'Merge driver name')\n .argument('<base>', 'Common ancestor file')\n .argument('<ours>', 'Current branch file')\n .argument('<theirs>', 'Incoming branch file')\n .argument('[path]', 'Merged path')\n .action((driver: string, base: string, ours: string, theirs: string) => {\n if (driver !== 'gt-lock' && driver !== 'gtjson') {\n logger.error(`Unknown GT merge driver: ${driver}`);\n exitSync(1);\n }\n const result = runMergeDriver(\n driver as MergeDriverName,\n base,\n ours,\n theirs\n );\n if (!result.ok) {\n logger.error(result.reason);\n exitSync(1);\n }\n });\n }\n\n protected async resolveGitSetupOmitConfigIds(\n options: GitSetupOptions,\n settings: Settings\n ): Promise<boolean> {\n if (options.omitConfigIds) return true;\n // Already opted in: persist again so stale config IDs still get removed\n if (settings.omitConfigIds) return true;\n if (options.dryRun || !process.stdin.isTTY || !process.stdout.isTTY) {\n return false;\n }\n return promptConfirm({\n message:\n 'Also set omitConfigIds: true to reduce gt.config.json merge conflicts?',\n defaultValue: true,\n });\n }\n\n protected async handleSetupProject(\n initOptions: TranslateFlags\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n await handleSetupProject(initOptions, settings, this.library);\n }\n\n protected async handleStage(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n if (!settings.stageTranslations) {\n // Update settings.stageTranslations to true\n settings.stageTranslations = true;\n await updateConfig(settings.config, {\n stageTranslations: true,\n });\n }\n await handleStage(initOptions, settings, this.library, true);\n }\n\n /**\n * Enqueues translations for a given set of files\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected async handleEnqueue(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await handleEnqueue(initOptions, settings, this.library);\n }\n\n /**\n * Downloads translations that were originally staged\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected async handleDownload(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await handleDownload(initOptions, settings, this.library);\n }\n\n protected async handleTranslate(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n if (!settings.stageTranslations) {\n // Lottie translations finish asynchronously server-side (layout\n // refinement runs after the translation job completes), so the immediate\n // translate flow would try to download them before they're ready. Only\n // the stage + download flow supports them.\n if (settings.files?.resolvedPaths.lottie?.length) {\n return logErrorAndExit(lottieTranslateError);\n }\n const results = await handleStage(\n initOptions,\n settings,\n this.library,\n false\n );\n if (results) {\n await handleTranslate(\n initOptions,\n settings,\n results.fileVersionData,\n results.jobData,\n results.branchData,\n results.publishMap\n );\n }\n } else {\n await handleDownload(initOptions, settings, this.library);\n }\n // Only postprocess files downloaded in this run\n const include = getNeedsPostprocessing();\n if (include.size > 0) {\n await postProcessTranslations(settings, include);\n }\n // Split Mintlify language entries into $ref files to keep docs.json small\n await splitMintlifyLanguageRefs(settings);\n // Mirror assets after translations are downloaded and locale dirs are populated\n await mirrorAssetsToLocales(settings);\n clearDownloaded();\n displayTranslateSummary();\n clearWarnings();\n }\n\n protected setupUploadCommand(): void {\n attachTranslateFlags(\n this.program\n .command('upload')\n .description(\n 'Upload source files and translations to the General Translation platform'\n )\n ).action(async (initOptions: UploadOptions) => {\n displayHeader('Starting upload...');\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n const options = { ...initOptions, ...settings };\n\n await this.handleUploadCommand(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupLoginCommand(): void {\n this.program\n .command('auth')\n .description('Generate General Translation API keys and project ID')\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option(\n '-t, --key-type <type>',\n 'Type of key to generate, production | development | all'\n )\n .action(async (options: LoginOptions) => {\n displayHeader('Authenticating with General Translation...');\n if (!options.keyType) {\n options.keyType = await promptSelect<\n 'development' | 'production' | 'all'\n >({\n message: 'What type of API key would you like to generate?',\n options: [\n { value: 'development', label: 'Development' },\n { value: 'production', label: 'Production' },\n { value: 'all', label: 'Both' },\n ],\n defaultValue: 'all',\n });\n } else {\n if (\n options.keyType !== 'development' &&\n options.keyType !== 'production' &&\n options.keyType !== 'all'\n ) {\n logErrorAndExit(\n 'Invalid key type, must be development, production, or all'\n );\n }\n }\n await this.handleLoginCommand(options);\n logger.endCommand(\n `Done! ${options.keyType} keys have been generated and saved to your .env.local file.`\n );\n });\n }\n\n protected setupInitCommand(): void {\n this.program\n .command('init')\n .description(\n 'Run the setup wizard to configure your project for General Translation'\n )\n .option(\n '--src <paths...>',\n \"Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'\"\n )\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .action(async (options: SetupOptions) => {\n await exitIfWorkspaceRoot();\n const settings = await generateSettings(options);\n displayHeader('Running setup wizard...');\n\n const framework = await detectFramework();\n\n const useAgent = await (async () => {\n let useAgentMessage;\n if (framework.name === 'mintlify') {\n useAgentMessage = `Mintlify project detected. Would you like to connect to GitHub so that the Locadex AI Agent can translate your project automatically?`;\n }\n if (framework.name === 'next-app') {\n useAgentMessage = `Next.js App Router detected. Would you like to connect to GitHub so that the Locadex AI Agent can set up your project automatically?`;\n }\n if (useAgentMessage) {\n return await promptConfirm({\n message: useAgentMessage,\n defaultValue: false,\n });\n }\n return false;\n })();\n\n if (useAgent) {\n await setupLocadex(settings);\n logger.endCommand(\n 'Once installed, Locadex will open a PR to your repository. See the docs for more information: https://generaltranslation.com/docs/locadex'\n );\n } else {\n // Get framework display info for the defaults message\n const frameworkDisplayName =\n framework.type === 'react'\n ? getFrameworkDisplayName(framework)\n : null;\n const library =\n framework.type === 'react'\n ? getReactFrameworkLibrary(framework)\n : null;\n\n // Build defaults description based on detected framework\n const defaultTranslationsDir =\n framework.name === 'vite'\n ? DEFAULT_VITE_TRANSLATIONS_DIR\n : DEFAULT_TRANSLATIONS_DIR;\n\n const defaultsDescription =\n framework.type === 'react'\n ? `${library} & GTProvider, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}`\n : `Files saved locally in ${defaultTranslationsDir}`;\n\n // Ask if user wants to use defaults\n const useDefaults = await promptConfirm({\n message: `Would you like to use the recommended General Translation defaults? ${chalk.dim(`(${defaultsDescription})`)}`,\n defaultValue: true,\n });\n\n let ranReactSetup = false;\n\n // so that people can run init in non-js projects\n if (framework.type === 'react') {\n const wrap = useDefaults\n ? true\n : await promptConfirm({\n message: `Would you like to install ${library} and add the GTProvider? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`,\n defaultValue: true,\n });\n\n if (wrap) {\n logger.info(\n `${chalk.yellow('[EXPERIMENTAL]')} Configuring project...`\n );\n await handleSetupReactCommand(options, framework, useDefaults);\n logger.endCommand(\n `Done! Since this wizard is experimental, please review the changes and make modifications as needed.\n\\nNext step: start internationalizing! See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`\n );\n ranReactSetup = true;\n }\n }\n\n if (ranReactSetup) {\n logger.startCommand('Setting up project config...');\n }\n // Configure gt.config.json\n await this.handleInitCommand(\n ranReactSetup,\n useDefaults,\n framework.name === 'vite'\n );\n\n logger.endCommand(\n 'Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs'\n );\n }\n });\n }\n\n protected setupConfigureCommand(): void {\n this.program\n .command('configure')\n .description(\n 'Configure your project for General Translation. This will create a gt.config.json file in your codebase.'\n )\n .action(async () => {\n await exitIfWorkspaceRoot();\n displayHeader('Configuring project...');\n\n logger.info(\n 'Welcome! This tool will help you configure your gt.config.json file. See the docs: https://generaltranslation.com/docs/cli/reference/config for more information.'\n );\n\n // Configure gt.config.json\n const framework = await detectFramework();\n await this.handleInitCommand(false, false, framework.name === 'vite');\n\n logger.endCommand(\n 'Done! Make sure you have an API key and project ID to use General Translation. Get them on the dashboard: https://generaltranslation.com/dashboard'\n );\n });\n }\n\n protected async handleUploadCommand(\n settings: Settings & UploadOptions\n ): Promise<void> {\n if (!settings.files) {\n return;\n }\n\n // Process all file types at once with a single call\n await upload(settings);\n }\n\n // Wizard for configuring gt.config.json\n protected async handleInitCommand(\n ranReactSetup: boolean,\n useDefaults: boolean = false,\n isVite: boolean = false\n ): Promise<void> {\n const { defaultLocale, locales } = await getDesiredLocales(); // Locales should still be asked for even if using defaults\n\n const packageJson = await searchForPackageJson();\n\n // Ask if using another i18n library\n const gtInstalled =\n !!packageJson &&\n INLINE_LIBRARIES.some((lib) => isPackageInstalled(lib, packageJson));\n const isUsingGT = ranReactSetup || gtInstalled;\n\n // Ask where the translations are stored\n const usingCDN = await (async () => {\n if (!isUsingGT) return false;\n if (useDefaults) return false; // Default to local\n const selectedValue = await promptSelect({\n message: `Would you like to save translation files locally or use the General Translation CDN to store them?`,\n options: [\n { value: 'local', label: 'Save locally' },\n { value: 'cdn', label: 'Use CDN' },\n ],\n defaultValue: 'local',\n });\n return selectedValue === 'cdn';\n })();\n\n const defaultTranslationsDir = isVite\n ? DEFAULT_VITE_TRANSLATIONS_DIR\n : DEFAULT_TRANSLATIONS_DIR;\n\n // Ask where the translations are stored\n const translationsDir =\n isUsingGT && !usingCDN\n ? useDefaults\n ? defaultTranslationsDir\n : await promptText({\n message:\n 'What is the path to the directory where you would like to store your translation files?',\n defaultValue: defaultTranslationsDir,\n })\n : null;\n\n // Determine final translations directory with fallback\n const finalTranslationsDir =\n translationsDir?.trim() || defaultTranslationsDir;\n\n if (isUsingGT && !usingCDN) {\n // Create loadTranslations.js file for local translations\n await createLoadTranslationsFile(\n process.cwd(),\n finalTranslationsDir,\n locales\n );\n logger.message(\n `Created ${chalk.cyan('loadTranslations.js')} file for local translations.\nMake sure to add this function to your app configuration.\nSee https://generaltranslation.com/en/docs/next/guides/local-tx`\n );\n }\n\n const message = !isUsingGT\n ? 'What is the format of your language resource files? Select as many as applicable.\\nAdditionally, you can translate any other files you have in your project.'\n : `Do you have any additional files in this project to translate? For example, Markdown files for docs. ${chalk.dim(\n '(To continue without selecting press Enter)'\n )}`;\n const fileExtensions =\n useDefaults && isUsingGT\n ? [] // Skip for GT projects when using defaults\n : await promptMultiSelect({\n message,\n options: [\n { value: 'json', label: FILE_EXT_TO_EXT_LABEL.json },\n { value: 'md', label: FILE_EXT_TO_EXT_LABEL.md },\n { value: 'mdx', label: FILE_EXT_TO_EXT_LABEL.mdx },\n { value: 'ts', label: FILE_EXT_TO_EXT_LABEL.ts },\n { value: 'js', label: FILE_EXT_TO_EXT_LABEL.js },\n { value: 'yaml', label: FILE_EXT_TO_EXT_LABEL.yaml },\n // TWILIO_CONTENT_JSON not supported in CLI init as its too niche\n ],\n required: !isUsingGT,\n });\n\n const files: FilesOptions = {};\n for (const fileExtension of fileExtensions) {\n const label = FILE_EXT_TO_EXT_LABEL[fileExtension];\n const paths = await promptGlobPatterns({\n label,\n message: `${chalk.cyan(FILE_EXT_TO_EXT_LABEL[fileExtension])}: Enter a space-separated list of glob patterns matching the location of the ${FILE_EXT_TO_EXT_LABEL[fileExtension]} files you would like to translate.\\nMake sure to include [locale] in the patterns.\\nSee https://generaltranslation.com/docs/cli/reference/config#include for more information.`,\n defaultValue: `./**/[locale]/*.${fileExtension}`,\n });\n\n files[fileExtension] = {\n include: parseGlobPatterns(paths),\n };\n }\n\n // Add GT translations if using GT and storing locally\n if (isUsingGT && !usingCDN) {\n files.gt = {\n output: path.join(finalTranslationsDir, `[locale].json`),\n };\n }\n\n let configFilepath = 'gt.config.json';\n if (fs.existsSync('src/gt.config.json')) {\n configFilepath = 'src/gt.config.json';\n }\n\n // Create gt.config.json\n await createOrUpdateConfig(configFilepath, {\n defaultLocale,\n locales,\n files: Object.keys(files).length > 0 ? files : undefined,\n publish: isUsingGT && usingCDN,\n });\n\n logger.success(\n `Edit ${chalk.cyan(\n configFilepath\n )} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`\n );\n\n // Install gt if not installed\n const isCLIInstalled = packageJson\n ? isPackageInstalled('gt', packageJson, true, true)\n : true; // if no package.json, we can't install it\n\n if (!isCLIInstalled) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner();\n spinner.start(\n `Installing gt as a dev dependency with ${packageManager.name}...`\n );\n await installPackage('gt', packageManager, true);\n spinner.stop(chalk.green('Installed gt.'));\n }\n\n // Set credentials\n if (!areCredentialsSet()) {\n const loginQuestion = useDefaults\n ? true\n : await promptConfirm({\n message:\n 'Would you like the wizard to automatically generate API keys and a project ID for you?',\n defaultValue: true,\n });\n if (loginQuestion) {\n const settings = await generateSettings({});\n const keyType = useDefaults\n ? 'all'\n : await promptSelect<'development' | 'production' | 'all'>({\n message: 'What type of API key would you like to generate?',\n options: [\n { value: 'development', label: 'Development' },\n { value: 'production', label: 'Production' },\n { value: 'all', label: 'Both' },\n ],\n defaultValue: 'all',\n });\n const credentials = await retrieveCredentials(settings, keyType);\n await setCredentials(credentials, settings.framework);\n }\n }\n }\n protected async handleLoginCommand(options: LoginOptions): Promise<void> {\n const settings = await generateSettings({ config: options.config });\n const keyType = options.keyType || 'all';\n const credentials = await retrieveCredentials(settings, keyType);\n await setCredentials(credentials, settings.framework);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../src/cli/base.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n DEFAULT_TRANSLATIONS_DIR,\n DEFAULT_VITE_TRANSLATIONS_DIR,\n} from '../utils/constants.js';\nimport { createOrUpdateConfig } from '../fs/config/setupConfig.js';\nimport findFilepath from '../fs/findFilepath.js';\nimport {\n displayHeader,\n promptText,\n logErrorAndExit,\n exitSync,\n promptConfirm,\n promptMultiSelect,\n promptSelect,\n promptGlobPatterns,\n} from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { lottieTranslateError } from '../console/index.js';\nimport { parseGlobPatterns } from '../console/promptParsing.js';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport {\n FilesOptions,\n Settings,\n SupportedLibraries,\n SetupOptions,\n TranslateFlags,\n SharedFlags,\n} from '../types/index.js';\nimport { generateSettings } from '../config/generateSettings.js';\nimport chalk from 'chalk';\nimport { FILE_EXT_TO_EXT_LABEL } from '../formats/files/supportedFiles.js';\nimport { handleSetupReactCommand } from '../setup/wizard.js';\nimport {\n isPackageInstalled,\n searchForPackageJson,\n} from '../utils/packageJson.js';\nimport { getDesiredLocales } from '../setup/userInput.js';\nimport { installPackage } from '../utils/installPackage.js';\nimport { getPackageManager } from '../utils/packageManager.js';\nimport { retrieveCredentials, setCredentials } from '../utils/credentials.js';\nimport { areCredentialsSet } from '../utils/credentials.js';\nimport { upload } from './commands/upload.js';\nimport { attachSharedFlags, attachTranslateFlags } from './flags.js';\nimport { handleStage } from './commands/stage.js';\nimport { handleSetupProject } from './commands/setupProject.js';\nimport { handleDownload } from './commands/download.js';\nimport {\n handleTranslate,\n postProcessTranslations,\n} from './commands/translate.js';\nimport {\n getNeedsPostprocessing,\n clearDownloaded,\n} from '../state/recentDownloads.js';\nimport { clearWarnings } from '../state/translateWarnings.js';\nimport { displayTranslateSummary } from '../console/displayTranslateSummary.js';\nimport updateConfig from '../fs/config/updateConfig.js';\nimport { loadConfig } from '../fs/config/loadConfig.js';\nimport { createLoadTranslationsFile } from '../fs/createLoadTranslationsFile.js';\nimport { saveLocalEdits } from '../api/saveLocalEdits.js';\nimport processSharedStaticAssets, {\n mirrorAssetsToLocales,\n} from '../utils/sharedStaticAssets.js';\nimport { setupLocadex } from '../locadex/setupFlow.js';\nimport { detectFramework } from '../setup/detectFramework.js';\nimport {\n getFrameworkDisplayName,\n getReactFrameworkLibrary,\n} from '../setup/frameworkUtils.js';\nimport { INLINE_LIBRARIES } from '../types/libraries.js';\nimport { handleEnqueue } from './commands/enqueue.js';\nimport { splitMintlifyLanguageRefs } from '../utils/splitMintlifyLanguageRefs.js';\nimport { runMergeDriver, type MergeDriverName } from '../git/mergeDrivers.js';\nimport { setupGitMergeDrivers } from '../git/setupMergeDrivers.js';\nimport { warnReactPackageCompatibility } from '../utils/reactPackageCompatibility.js';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\nimport { setupViteSPA } from '../setup/setupViteSPA.js';\n\nconst ID_COMPATIBILITY_WARNING_COMMANDS = new Set([\n 'download',\n 'enqueue',\n 'generate',\n 'setup',\n 'stage',\n 'translate',\n 'validate',\n]);\nconst workspaceRootSetupError = createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'The setup wizard cannot run from a monorepo workspace root',\n why: 'GT must be configured in the specific app you want to localize',\n fix: \"Change to that app's directory and rerun `npx gt@latest`\",\n});\nconst electronSetupError = createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened:\n 'The automatic setup wizard is not ready for Electron applications',\n docsUrl: 'https://generaltranslation.com/docs/react',\n});\n\nasync function exitIfUnsupportedSetupTarget(): Promise<void> {\n const packageJson = await searchForPackageJson();\n if (packageJson && isPackageInstalled('electron', packageJson, false, true)) {\n logErrorAndExit(electronSetupError);\n }\n if (\n fs.existsSync(path.join(process.cwd(), 'pnpm-workspace.yaml')) ||\n packageJson?.workspaces\n ) {\n logErrorAndExit(workspaceRootSetupError);\n }\n}\n\nexport type UploadOptions = {\n config?: string;\n apiKey?: string;\n projectId?: string;\n defaultLocale?: string;\n};\n\nexport type LoginOptions = {\n config?: string;\n keyType?: 'development' | 'production' | 'all';\n};\n\nexport type GitSetupOptions = {\n config?: string;\n dryRun?: boolean;\n omitConfigIds?: boolean;\n driverCommand?: string;\n};\n\nexport class BaseCLI {\n protected library: SupportedLibraries;\n protected additionalModules: SupportedLibraries[];\n protected program: Command;\n // Constructor is shared amongst all CLI class types\n public constructor(\n program: Command,\n library: SupportedLibraries,\n additionalModules?: SupportedLibraries[]\n ) {\n this.program = program;\n this.library = library;\n this.additionalModules = additionalModules || [];\n\n this.program.option(\n '--skip-version-check',\n 'Skip the monorepo GT package version consistency check'\n );\n this.program.option(\n '--suppress-id-compatibility-warning',\n 'Suppress the React package ID compatibility warning'\n );\n this.program.option(\n '-q, --quiet',\n 'Suppress informational output; only warnings and errors are shown'\n );\n // Apply --quiet before any other hook or command action runs so the\n // singleton logger is muted for the rest of the invocation. The flag is a\n // global root option, so commander resolves it in any position and for\n // nested commands (e.g. `gt git setup --quiet`).\n this.program.hook('preAction', () => {\n logger.setQuiet(Boolean(this.program.opts().quiet));\n });\n this.program.hook('preAction', async (thisCommand, actionCommand) => {\n // Nested commands (e.g. `gt git setup`) can share leaf names with\n // translation commands; only direct children of the root qualify\n if (actionCommand.parent !== thisCommand) return;\n if (!ID_COMPATIBILITY_WARNING_COMMANDS.has(actionCommand.name())) return;\n await warnReactPackageCompatibility(\n Boolean(this.program.opts().suppressIdCompatibilityWarning)\n );\n });\n\n this.setupInitCommand();\n this.setupConfigureCommand();\n this.setupUploadCommand();\n this.setupLoginCommand();\n this.setupSendDiffsCommand();\n this.setupGitCommand();\n }\n // Init is never called in a child class\n public init() {\n this.setupSetupProjectCommand();\n this.setupStageCommand();\n this.setupTranslateCommand();\n this.setupDownloadCommand();\n this.setupEnqueueCommand();\n }\n // Execute is called by the main program\n public execute() {\n // If no command is specified, run 'init'\n if (process.argv.length <= 2) {\n process.argv.push('init');\n }\n }\n\n protected setupSetupProjectCommand(): void {\n attachTranslateFlags(\n this.program\n .command('setup')\n .description(\n 'Upload source files and setup the project for translation'\n )\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Uploading source files and setting up project...');\n await this.handleSetupProject(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupStageCommand(): void {\n attachTranslateFlags(\n this.program\n .command('stage')\n .description(\n 'Submits the project to the General Translation API for translation. Translations created using this command will require human approval.'\n )\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader(\n 'Staging project for translation with approval required...'\n );\n await this.handleStage(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n /**\n * Enqueues translations for a given set of files\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected setupEnqueueCommand(): void {\n attachTranslateFlags(\n this.program\n .command('enqueue')\n .description('Enqueues translations for a given set of files')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Enqueuing translations...');\n await this.handleEnqueue(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n /**\n * Downloads translations that were originally staged\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected setupDownloadCommand(): void {\n attachTranslateFlags(\n this.program\n .command('download')\n .description('Download translations that were originally staged')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Downloading translations...');\n await this.handleDownload(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupTranslateCommand(): void {\n attachTranslateFlags(\n this.program\n .command('translate')\n .description('Translate your project using General Translation')\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Starting translation...');\n await this.handleTranslate(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected setupSendDiffsCommand(): void {\n attachSharedFlags(\n this.program\n .command('save-local')\n .description(\n 'Save local edits for all configured files by sending diffs (no translation enqueued)'\n )\n )\n .option('--publish', 'Publish translations to the CDN', false)\n .action(async (initOptions: SharedFlags) => {\n displayHeader('Saving local edits...');\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await saveLocalEdits(settings);\n logger.endCommand('Saved local edits');\n });\n }\n\n protected setupGitCommand(): void {\n const gitCommand = this.program\n .command('git')\n .description('Configure Git integrations for General Translation');\n\n gitCommand\n .command('setup')\n .description('Set up GT merge drivers for generated translation files')\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option('--dry-run', 'Print changes without writing files', false)\n .option(\n '--omit-config-ids',\n 'Persist omitConfigIds and remove generated config IDs'\n )\n .option(\n '--driver-command <command>',\n 'Command Git should use to invoke gt, e.g. \"pnpm exec gt\"'\n )\n .action(async (options: GitSetupOptions) => {\n displayHeader('Setting up GT Git merge drivers...');\n const settings = await generateSettings(options, undefined, {\n requireConfig: true,\n });\n const omitConfigIds = await this.resolveGitSetupOmitConfigIds(\n options,\n settings\n );\n const result = await setupGitMergeDrivers(settings, {\n dryRun: options.dryRun,\n omitConfigIds,\n driverCommand: options.driverCommand,\n });\n\n for (const line of result.addedAttributes) {\n logger.step(\n `${options.dryRun ? 'Would add' : 'Added'} ${chalk.cyan(\n line\n )} to ${chalk.cyan(result.gitattributesPath)}`\n );\n }\n if (result.addedAttributes.length === 0) {\n logger.info(`${chalk.cyan('.gitattributes')} is already configured.`);\n }\n\n for (const args of result.gitConfigCommands) {\n logger.step(\n `${options.dryRun ? 'Would run' : 'Configured'} ${chalk.cyan(\n `git config --local ${args.join(' ')}`\n )}`\n );\n }\n\n if (result.updatedConfig) {\n logger.step(\n `${options.dryRun ? 'Would persist' : 'Persisted'} ${chalk.cyan(\n 'omitConfigIds: true'\n )} in ${chalk.cyan(settings.config)}`\n );\n } else if (options.dryRun && !settings.omitConfigIds) {\n logger.info(\n `Run without ${chalk.cyan('--dry-run')} to be prompted to persist ${chalk.cyan(\n 'omitConfigIds: true'\n )}, or pass ${chalk.cyan('--omit-config-ids')}.`\n );\n }\n\n for (const warning of result.warnings) {\n logger.warn(chalk.yellow(warning));\n }\n\n logger.endCommand(\n options.dryRun\n ? 'Dry run complete.'\n : 'GT Git merge drivers configured.'\n );\n });\n\n gitCommand\n .command('merge-driver', { hidden: true })\n .argument('<driver>', 'Merge driver name')\n .argument('<base>', 'Common ancestor file')\n .argument('<ours>', 'Current branch file')\n .argument('<theirs>', 'Incoming branch file')\n .argument('[path]', 'Merged path')\n .action((driver: string, base: string, ours: string, theirs: string) => {\n if (driver !== 'gt-lock' && driver !== 'gtjson') {\n logger.error(`Unknown GT merge driver: ${driver}`);\n exitSync(1);\n }\n const result = runMergeDriver(\n driver as MergeDriverName,\n base,\n ours,\n theirs\n );\n if (!result.ok) {\n logger.error(result.reason);\n exitSync(1);\n }\n });\n }\n\n protected async resolveGitSetupOmitConfigIds(\n options: GitSetupOptions,\n settings: Settings\n ): Promise<boolean> {\n if (options.omitConfigIds) return true;\n // Already opted in: persist again so stale config IDs still get removed\n if (settings.omitConfigIds) return true;\n if (options.dryRun || !process.stdin.isTTY || !process.stdout.isTTY) {\n return false;\n }\n return promptConfirm({\n message:\n 'Also set omitConfigIds: true to reduce gt.config.json merge conflicts?',\n defaultValue: true,\n });\n }\n\n protected async handleSetupProject(\n initOptions: TranslateFlags\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n await handleSetupProject(initOptions, settings, this.library);\n }\n\n protected async handleStage(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n if (!settings.stageTranslations) {\n // Update settings.stageTranslations to true\n settings.stageTranslations = true;\n await updateConfig(settings.config, {\n stageTranslations: true,\n });\n }\n await handleStage(initOptions, settings, this.library, true);\n }\n\n /**\n * Enqueues translations for a given set of files\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected async handleEnqueue(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await handleEnqueue(initOptions, settings, this.library);\n }\n\n /**\n * Downloads translations that were originally staged\n * @param initOptions - The options for the command\n * @returns The results of the command\n */\n protected async handleDownload(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n await handleDownload(initOptions, settings, this.library);\n }\n\n protected async handleTranslate(initOptions: TranslateFlags): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // Preprocess shared static assets if configured (move + rewrite sources)\n await processSharedStaticAssets(settings);\n\n if (!settings.stageTranslations) {\n // Lottie translations finish asynchronously server-side (layout\n // refinement runs after the translation job completes), so the immediate\n // translate flow would try to download them before they're ready. Only\n // the stage + download flow supports them.\n if (settings.files?.resolvedPaths.lottie?.length) {\n return logErrorAndExit(lottieTranslateError);\n }\n const results = await handleStage(\n initOptions,\n settings,\n this.library,\n false\n );\n if (results) {\n await handleTranslate(\n initOptions,\n settings,\n results.fileVersionData,\n results.jobData,\n results.branchData,\n results.publishMap\n );\n }\n } else {\n await handleDownload(initOptions, settings, this.library);\n }\n // Only postprocess files downloaded in this run\n const include = getNeedsPostprocessing();\n if (include.size > 0) {\n await postProcessTranslations(settings, include);\n }\n // Split Mintlify language entries into $ref files to keep docs.json small\n await splitMintlifyLanguageRefs(settings);\n // Mirror assets after translations are downloaded and locale dirs are populated\n await mirrorAssetsToLocales(settings);\n clearDownloaded();\n displayTranslateSummary();\n clearWarnings();\n }\n\n protected setupUploadCommand(): void {\n attachTranslateFlags(\n this.program\n .command('upload')\n .description(\n 'Upload source files and translations to the General Translation platform'\n )\n ).action(async (initOptions: UploadOptions) => {\n displayHeader('Starting upload...');\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n const options = { ...initOptions, ...settings };\n\n await this.handleUploadCommand(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupLoginCommand(): void {\n this.program\n .command('auth')\n .description('Generate General Translation API keys and project ID')\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option(\n '-t, --key-type <type>',\n 'Type of key to generate, production | development | all'\n )\n .action(async (options: LoginOptions) => {\n displayHeader('Authenticating with General Translation...');\n if (!options.keyType) {\n options.keyType = await promptSelect<\n 'development' | 'production' | 'all'\n >({\n message: 'What type of API key would you like to generate?',\n options: [\n { value: 'development', label: 'Development' },\n { value: 'production', label: 'Production' },\n { value: 'all', label: 'Both' },\n ],\n defaultValue: 'all',\n });\n } else {\n if (\n options.keyType !== 'development' &&\n options.keyType !== 'production' &&\n options.keyType !== 'all'\n ) {\n logErrorAndExit(\n 'Invalid key type, must be development, production, or all'\n );\n }\n }\n await this.handleLoginCommand(options);\n logger.endCommand(\n `Done! ${options.keyType} keys have been generated and saved to your .env.local file.`\n );\n });\n }\n\n protected setupInitCommand(): void {\n this.program\n .command('init')\n .description(\n 'Run the setup wizard to configure your project for General Translation'\n )\n .option(\n '--src <paths...>',\n \"Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'\"\n )\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .action(async (options: SetupOptions) => {\n await exitIfUnsupportedSetupTarget();\n const settings = await generateSettings(options);\n displayHeader('Running setup wizard...');\n\n const framework = await detectFramework();\n\n const useAgent = await (async () => {\n let useAgentMessage;\n if (framework.name === 'mintlify') {\n useAgentMessage = `Mintlify project detected. Would you like to connect to GitHub so that the Locadex AI Agent can translate your project automatically?`;\n }\n if (framework.name === 'next-app') {\n useAgentMessage = `Next.js App Router detected. Would you like to connect to GitHub so that the Locadex AI Agent can set up your project automatically?`;\n }\n if (useAgentMessage) {\n return await promptConfirm({\n message: useAgentMessage,\n defaultValue: false,\n });\n }\n return false;\n })();\n\n if (useAgent) {\n await setupLocadex(settings);\n logger.endCommand(\n 'Once installed, Locadex will open a PR to your repository. See the docs for more information: https://generaltranslation.com/docs/locadex'\n );\n } else {\n // Get framework display info for the defaults message\n const frameworkDisplayName =\n framework.type === 'react'\n ? getFrameworkDisplayName(framework)\n : null;\n const library =\n framework.type === 'react'\n ? getReactFrameworkLibrary(framework)\n : null;\n\n // Build defaults description based on detected framework\n const defaultTranslationsDir =\n framework.name === 'vite'\n ? DEFAULT_VITE_TRANSLATIONS_DIR\n : DEFAULT_TRANSLATIONS_DIR;\n\n const defaultsDescription =\n framework.name === 'vite'\n ? `${library} & initializeGTSPA, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}`\n : framework.type === 'react'\n ? `${library} & GTProvider, ${frameworkDisplayName}, Files saved locally in ${defaultTranslationsDir}`\n : `Files saved locally in ${defaultTranslationsDir}`;\n\n // Ask if user wants to use defaults\n const useDefaults = await promptConfirm({\n message: `Would you like to use the recommended General Translation defaults? ${chalk.dim(`(${defaultsDescription})`)}`,\n defaultValue: true,\n });\n\n let ranReactSetup = false;\n\n // so that people can run init in non-js projects\n if (framework.type === 'react') {\n const wrap = useDefaults\n ? true\n : await promptConfirm({\n message:\n framework.name === 'vite'\n ? `Would you like to install ${library} and configure initializeGTSPA? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`\n : `Would you like to install ${library} and add the GTProvider? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`,\n defaultValue: true,\n });\n\n if (wrap) {\n logger.info(\n `${chalk.yellow('[EXPERIMENTAL]')} Configuring project...`\n );\n await handleSetupReactCommand(options, framework, useDefaults);\n logger.endCommand(\n `Done! Since this wizard is experimental, please review the changes and make modifications as needed.\n\\nNext step: start internationalizing! See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`\n );\n ranReactSetup = true;\n }\n }\n\n if (ranReactSetup) {\n logger.startCommand('Setting up project config...');\n }\n // Configure gt.config.json\n await this.handleInitCommand(\n ranReactSetup,\n useDefaults,\n framework.name === 'vite'\n );\n\n logger.endCommand(\n 'Done! Check out our docs for more information on how to use General Translation: https://generaltranslation.com/docs'\n );\n }\n });\n }\n\n protected setupConfigureCommand(): void {\n this.program\n .command('configure')\n .description(\n 'Configure your project for General Translation. This will create a gt.config.json file in your codebase.'\n )\n .action(async () => {\n await exitIfUnsupportedSetupTarget();\n displayHeader('Configuring project...');\n\n logger.info(\n 'Welcome! This tool will help you configure your gt.config.json file. See the docs: https://generaltranslation.com/docs/cli/reference/config for more information.'\n );\n\n // Configure gt.config.json\n const framework = await detectFramework();\n await this.handleInitCommand(false, false, framework.name === 'vite');\n\n logger.endCommand(\n 'Done! Make sure you have an API key and project ID to use General Translation. Get them on the dashboard: https://generaltranslation.com/dashboard'\n );\n });\n }\n\n protected async handleUploadCommand(\n settings: Settings & UploadOptions\n ): Promise<void> {\n if (!settings.files) {\n return;\n }\n\n // Process all file types at once with a single call\n await upload(settings);\n }\n\n // Wizard for configuring gt.config.json\n protected async handleInitCommand(\n ranReactSetup: boolean,\n useDefaults: boolean = false,\n isVite: boolean = false\n ): Promise<void> {\n const configFilepath =\n !isVite && fs.existsSync('src/gt.config.json')\n ? 'src/gt.config.json'\n : 'gt.config.json';\n const existingConfig = loadConfig(configFilepath);\n const { defaultLocale, locales } = await getDesiredLocales(existingConfig);\n\n const packageJson = await searchForPackageJson();\n\n // Ask if using another i18n library\n const gtInstalled =\n !!packageJson &&\n INLINE_LIBRARIES.some((lib) => isPackageInstalled(lib, packageJson));\n const isUsingGT = ranReactSetup || gtInstalled;\n\n // Ask where the translations are stored\n const usingCDN = await (async () => {\n if (!isUsingGT) return false;\n if (useDefaults) return false; // Default to local\n const selectedValue = await promptSelect({\n message: `Would you like to save translation files locally or use the General Translation CDN to store them?`,\n options: [\n { value: 'local', label: 'Save locally' },\n { value: 'cdn', label: 'Use CDN' },\n ],\n defaultValue: 'local',\n });\n return selectedValue === 'cdn';\n })();\n\n const defaultTranslationsDir = isVite\n ? DEFAULT_VITE_TRANSLATIONS_DIR\n : DEFAULT_TRANSLATIONS_DIR;\n\n // Ask where the translations are stored\n const translationsDir =\n isUsingGT && !usingCDN\n ? useDefaults\n ? defaultTranslationsDir\n : await promptText({\n message:\n 'What is the path to the directory where you would like to store your translation files?',\n defaultValue: defaultTranslationsDir,\n })\n : null;\n\n // Determine final translations directory with fallback\n const finalTranslationsDir =\n translationsDir?.trim() || defaultTranslationsDir;\n\n if (isUsingGT && !usingCDN && !isVite) {\n // Create loadTranslations.js file for local translations\n await createLoadTranslationsFile(\n process.cwd(),\n finalTranslationsDir,\n locales\n );\n logger.message(\n `Created ${chalk.cyan('loadTranslations.js')} file for local translations.\nMake sure to add this function to your app configuration.\nSee https://generaltranslation.com/en/docs/next/guides/local-tx`\n );\n }\n\n const message = !isUsingGT\n ? 'What is the format of your language resource files? Select as many as applicable.\\nAdditionally, you can translate any other files you have in your project.'\n : `Do you have any additional files in this project to translate? For example, Markdown files for docs. ${chalk.dim(\n '(To continue without selecting press Enter)'\n )}`;\n const fileExtensions =\n useDefaults && isUsingGT\n ? [] // Skip for GT projects when using defaults\n : await promptMultiSelect({\n message,\n options: [\n { value: 'json', label: FILE_EXT_TO_EXT_LABEL.json },\n { value: 'md', label: FILE_EXT_TO_EXT_LABEL.md },\n { value: 'mdx', label: FILE_EXT_TO_EXT_LABEL.mdx },\n { value: 'ts', label: FILE_EXT_TO_EXT_LABEL.ts },\n { value: 'js', label: FILE_EXT_TO_EXT_LABEL.js },\n { value: 'yaml', label: FILE_EXT_TO_EXT_LABEL.yaml },\n // TWILIO_CONTENT_JSON not supported in CLI init as its too niche\n ],\n required: !isUsingGT,\n });\n\n const files: FilesOptions = {};\n for (const fileExtension of fileExtensions) {\n const label = FILE_EXT_TO_EXT_LABEL[fileExtension];\n const paths = await promptGlobPatterns({\n label,\n message: `${chalk.cyan(FILE_EXT_TO_EXT_LABEL[fileExtension])}: Enter a space-separated list of glob patterns matching the location of the ${FILE_EXT_TO_EXT_LABEL[fileExtension]} files you would like to translate.\\nMake sure to include [locale] in the patterns.\\nSee https://generaltranslation.com/docs/cli/reference/config#include for more information.`,\n defaultValue: `./**/[locale]/*.${fileExtension}`,\n });\n\n files[fileExtension] = {\n include: parseGlobPatterns(paths),\n };\n }\n\n // Add GT translations if using GT and storing locally\n if (isUsingGT && !usingCDN) {\n files.gt = {\n output: path.join(finalTranslationsDir, `[locale].json`),\n };\n }\n\n // Create gt.config.json\n await createOrUpdateConfig(configFilepath, {\n defaultLocale,\n locales,\n files: Object.keys(files).length > 0 ? files : undefined,\n framework: isVite ? 'vite' : undefined,\n publish: isUsingGT && usingCDN,\n });\n\n logger.success(\n `Edit ${chalk.cyan(\n configFilepath\n )} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`\n );\n\n if (ranReactSetup && isVite) {\n await setupViteSPA({\n appDirectory: process.cwd(),\n configFilepath,\n defaultLocale,\n locales,\n translationsDir: usingCDN ? undefined : finalTranslationsDir,\n });\n }\n\n // Install gt if not installed\n const isCLIInstalled = packageJson\n ? isPackageInstalled('gt', packageJson, true, true)\n : true; // if no package.json, we can't install it\n\n if (!isCLIInstalled && !(isUsingGT && isVite)) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner();\n spinner.start(\n `Installing gt as a dev dependency with ${packageManager.name}...`\n );\n await installPackage('gt', packageManager, true);\n spinner.stop(chalk.green('Installed gt.'));\n }\n\n // Set credentials\n if ((!isVite || !isUsingGT || usingCDN) && !areCredentialsSet()) {\n const loginQuestion = useDefaults\n ? true\n : await promptConfirm({\n message:\n 'Would you like the wizard to automatically generate API keys and a project ID for you?',\n defaultValue: true,\n });\n if (loginQuestion) {\n const settings = await generateSettings({});\n const keyType = useDefaults\n ? 'all'\n : await promptSelect<'development' | 'production' | 'all'>({\n message: 'What type of API key would you like to generate?',\n options: [\n { value: 'development', label: 'Development' },\n { value: 'production', label: 'Production' },\n { value: 'all', label: 'Both' },\n ],\n defaultValue: 'all',\n });\n const credentials = await retrieveCredentials(settings, keyType);\n await setCredentials(credentials, isVite ? 'vite' : settings.framework);\n }\n }\n }\n protected async handleLoginCommand(options: LoginOptions): Promise<void> {\n const settings = await generateSettings({ config: options.config });\n const keyType = options.keyType || 'all';\n const credentials = await retrieveCredentials(settings, keyType);\n await setCredentials(credentials, settings.framework);\n }\n}\n"],"mappings":"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"}
@@ -30,6 +30,18 @@ async function createOrUpdateConfig(configFilepath, options) {
30
30
  ...oldContent,
31
31
  ...newContent
32
32
  };
33
+ if (options.files) {
34
+ const oldFiles = oldContent.files && typeof oldContent.files === "object" ? oldContent.files : {};
35
+ const oldGt = oldFiles.gt && typeof oldFiles.gt === "object" ? oldFiles.gt : {};
36
+ mergedContent.files = {
37
+ ...oldFiles,
38
+ ...options.files,
39
+ ...options.files.gt && { gt: {
40
+ ...oldGt,
41
+ ...options.files.gt
42
+ } }
43
+ };
44
+ }
33
45
  if (options.locales) mergedContent.locales = mergedContent.locales ? [...new Set([...mergedContent.locales, ...options.locales])] : options.locales;
34
46
  const mergedJsonContent = JSON.stringify(mergedContent, null, 2);
35
47
  await fs.promises.writeFile(configFilepath, mergedJsonContent, "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"setupConfig.js","names":[],"sources":["../../../src/fs/config/setupConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { displayCreatedConfigFile } from '../../console/logging.js';\nimport { FilesOptions, SupportedFrameworks } from '../../types/index.js';\nimport { logger } from '../../console/logger.js';\nimport { GT_CONFIG_SCHEMA_URL } from '../../utils/constants.js';\n\n/**\n * Checks if the config file exists.\n * If yes, make sure make sure projectId is correct\n * If not, creates a new JSON file at the given filepath and writes the provided config object to it.\n * @param {string} configFilepath - The path to the config file.\n * @param {Record<string, any>} configObject - The config object to write if the file does not exist.\n */\nexport async function createOrUpdateConfig(\n configFilepath: string,\n options: {\n projectId?: string;\n defaultLocale?: string;\n locales?: string[];\n files?: FilesOptions;\n framework?: SupportedFrameworks;\n baseUrl?: string;\n publish?: boolean;\n }\n): Promise<string> {\n // Filter out empty string values from the config object\n const newContent = {\n ...(options.projectId && { projectId: options.projectId }),\n ...(options.defaultLocale && { defaultLocale: options.defaultLocale }),\n ...(options.files && { files: options.files }),\n ...(options.framework && { framework: options.framework }),\n ...(options.baseUrl && { baseUrl: options.baseUrl }),\n ...(options.publish && { publish: options.publish }),\n };\n try {\n // if file exists\n let oldContent: Record<string, unknown> = {};\n if (fs.existsSync(configFilepath)) {\n const parsed = JSON.parse(\n await fs.promises.readFile(configFilepath, 'utf-8')\n );\n oldContent =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : {};\n }\n\n // merge old and new content\n const mergedContent = {\n $schema: GT_CONFIG_SCHEMA_URL,\n ...oldContent,\n ...newContent,\n } as Record<string, unknown> & { locales?: string[] };\n\n // Add locales to mergedContent if they exist\n if (options.locales) {\n mergedContent.locales = mergedContent.locales\n ? [...new Set([...mergedContent.locales, ...options.locales])]\n : options.locales;\n }\n\n // write to file\n const mergedJsonContent = JSON.stringify(mergedContent, null, 2);\n await fs.promises.writeFile(configFilepath, mergedJsonContent, 'utf-8');\n\n // show update in console\n displayCreatedConfigFile(configFilepath);\n } catch (error) {\n logger.error(\n `An error occurred while updating ${configFilepath}: ${error}`\n );\n }\n return configFilepath;\n}\n"],"mappings":";;;;;;;;;;;;AAaA,eAAsB,qBACpB,gBACA,SASiB;CAEjB,MAAM,aAAa;EACjB,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,eAAe;EACrE,GAAI,QAAQ,SAAS,EAAE,OAAO,QAAQ,OAAO;EAC7C,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACnD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACpD;AACD,KAAI;EAEF,IAAI,aAAsC,EAAE;AAC5C,MAAI,GAAG,WAAW,eAAe,EAAE;GACjC,MAAM,SAAS,KAAK,MAClB,MAAM,GAAG,SAAS,SAAS,gBAAgB,QAAQ,CACpD;AACD,gBACE,OAAO,WAAW,YAAY,WAAW,OACpC,SACD,EAAE;;EAIV,MAAM,gBAAgB;GACpB,SAAS;GACT,GAAG;GACH,GAAG;GACJ;AAGD,MAAI,QAAQ,QACV,eAAc,UAAU,cAAc,UAClC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,cAAc,SAAS,GAAG,QAAQ,QAAQ,CAAC,CAAC,GAC5D,QAAQ;EAId,MAAM,oBAAoB,KAAK,UAAU,eAAe,MAAM,EAAE;AAChE,QAAM,GAAG,SAAS,UAAU,gBAAgB,mBAAmB,QAAQ;AAGvE,2BAAyB,eAAe;UACjC,OAAO;AACd,SAAO,MACL,oCAAoC,eAAe,IAAI,QACxD;;AAEH,QAAO"}
1
+ {"version":3,"file":"setupConfig.js","names":[],"sources":["../../../src/fs/config/setupConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { displayCreatedConfigFile } from '../../console/logging.js';\nimport { FilesOptions, SupportedFrameworks } from '../../types/index.js';\nimport { logger } from '../../console/logger.js';\nimport { GT_CONFIG_SCHEMA_URL } from '../../utils/constants.js';\n\n/**\n * Checks if the config file exists.\n * If yes, make sure make sure projectId is correct\n * If not, creates a new JSON file at the given filepath and writes the provided config object to it.\n * @param {string} configFilepath - The path to the config file.\n * @param {Record<string, any>} configObject - The config object to write if the file does not exist.\n */\nexport async function createOrUpdateConfig(\n configFilepath: string,\n options: {\n projectId?: string;\n defaultLocale?: string;\n locales?: string[];\n files?: FilesOptions;\n framework?: SupportedFrameworks;\n baseUrl?: string;\n publish?: boolean;\n }\n): Promise<string> {\n // Filter out empty string values from the config object\n const newContent = {\n ...(options.projectId && { projectId: options.projectId }),\n ...(options.defaultLocale && { defaultLocale: options.defaultLocale }),\n ...(options.files && { files: options.files }),\n ...(options.framework && { framework: options.framework }),\n ...(options.baseUrl && { baseUrl: options.baseUrl }),\n ...(options.publish && { publish: options.publish }),\n };\n try {\n // if file exists\n let oldContent: Record<string, unknown> = {};\n if (fs.existsSync(configFilepath)) {\n const parsed = JSON.parse(\n await fs.promises.readFile(configFilepath, 'utf-8')\n );\n oldContent =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : {};\n }\n\n // merge old and new content\n const mergedContent = {\n $schema: GT_CONFIG_SCHEMA_URL,\n ...oldContent,\n ...newContent,\n } as Record<string, unknown> & { locales?: string[] };\n\n // Preserve unrelated file configuration and nested GT options when setup\n // only needs to add or update a translation output path.\n if (options.files) {\n const oldFiles =\n oldContent.files && typeof oldContent.files === 'object'\n ? (oldContent.files as Record<string, unknown>)\n : {};\n const oldGt =\n oldFiles.gt && typeof oldFiles.gt === 'object'\n ? (oldFiles.gt as Record<string, unknown>)\n : {};\n mergedContent.files = {\n ...oldFiles,\n ...options.files,\n ...(options.files.gt && {\n gt: { ...oldGt, ...options.files.gt },\n }),\n };\n }\n\n // Add locales to mergedContent if they exist\n if (options.locales) {\n mergedContent.locales = mergedContent.locales\n ? [...new Set([...mergedContent.locales, ...options.locales])]\n : options.locales;\n }\n\n // write to file\n const mergedJsonContent = JSON.stringify(mergedContent, null, 2);\n await fs.promises.writeFile(configFilepath, mergedJsonContent, 'utf-8');\n\n // show update in console\n displayCreatedConfigFile(configFilepath);\n } catch (error) {\n logger.error(\n `An error occurred while updating ${configFilepath}: ${error}`\n );\n }\n return configFilepath;\n}\n"],"mappings":";;;;;;;;;;;;AAaA,eAAsB,qBACpB,gBACA,SASiB;CAEjB,MAAM,aAAa;EACjB,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,eAAe;EACrE,GAAI,QAAQ,SAAS,EAAE,OAAO,QAAQ,OAAO;EAC7C,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACnD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACpD;AACD,KAAI;EAEF,IAAI,aAAsC,EAAE;AAC5C,MAAI,GAAG,WAAW,eAAe,EAAE;GACjC,MAAM,SAAS,KAAK,MAClB,MAAM,GAAG,SAAS,SAAS,gBAAgB,QAAQ,CACpD;AACD,gBACE,OAAO,WAAW,YAAY,WAAW,OACpC,SACD,EAAE;;EAIV,MAAM,gBAAgB;GACpB,SAAS;GACT,GAAG;GACH,GAAG;GACJ;AAID,MAAI,QAAQ,OAAO;GACjB,MAAM,WACJ,WAAW,SAAS,OAAO,WAAW,UAAU,WAC3C,WAAW,QACZ,EAAE;GACR,MAAM,QACJ,SAAS,MAAM,OAAO,SAAS,OAAO,WACjC,SAAS,KACV,EAAE;AACR,iBAAc,QAAQ;IACpB,GAAG;IACH,GAAG,QAAQ;IACX,GAAI,QAAQ,MAAM,MAAM,EACtB,IAAI;KAAE,GAAG;KAAO,GAAG,QAAQ,MAAM;KAAI,EACtC;IACF;;AAIH,MAAI,QAAQ,QACV,eAAc,UAAU,cAAc,UAClC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,cAAc,SAAS,GAAG,QAAQ,QAAQ,CAAC,CAAC,GAC5D,QAAQ;EAId,MAAM,oBAAoB,KAAK,UAAU,eAAe,MAAM,EAAE;AAChE,QAAM,GAAG,SAAS,UAAU,gBAAgB,mBAAmB,QAAQ;AAGvE,2BAAyB,eAAe;UACjC,OAAO;AACd,SAAO,MACL,oCAAoC,eAAe,IAAI,QACxD;;AAEH,QAAO"}
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "2.16.1";
1
+ export declare const PACKAGE_VERSION = "2.16.2";
@@ -1,5 +1,5 @@
1
1
  //#region src/generated/version.ts
2
- const PACKAGE_VERSION = "2.16.1";
2
+ const PACKAGE_VERSION = "2.16.2";
3
3
  //#endregion
4
4
  export { PACKAGE_VERSION };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../src/generated/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const PACKAGE_VERSION = '2.16.1';\n"],"mappings":";AACA,MAAa,kBAAkB"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../src/generated/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const PACKAGE_VERSION = '2.16.2';\n"],"mappings":";AACA,MAAa,kBAAkB"}
@@ -0,0 +1,9 @@
1
+ type SetupViteSPAOptions = {
2
+ appDirectory: string;
3
+ configFilepath: string;
4
+ defaultLocale: string;
5
+ locales: string[];
6
+ translationsDir?: string;
7
+ };
8
+ export declare function setupViteSPA({ appDirectory, configFilepath, defaultLocale, locales, translationsDir, }: SetupViteSPAOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,111 @@
1
+ import { logger } from "../console/logger.js";
2
+ import path from "node:path";
3
+ import fs from "node:fs";
4
+ import { createDiagnosticMessage } from "generaltranslation/internal";
5
+ //#region src/setup/setupViteSPA.ts
6
+ const defaultBootstrapFilename = "gt-entry.ts";
7
+ const alternateBootstrapFilename = "gt-bootstrap.ts";
8
+ function getBootstrapConflictError(filename) {
9
+ return createDiagnosticMessage({
10
+ source: "gt",
11
+ severity: "Error",
12
+ whatHappened: "The Vite bootstrap file already exists",
13
+ why: `GT will not overwrite an existing src/${filename} file`,
14
+ fix: "Move or rename that file and rerun `npx gt@latest`"
15
+ });
16
+ }
17
+ function getLoaderContent(translationsImport) {
18
+ return `export default async function loadTranslations(locale: string) {
19
+ const translations = await import(\`${translationsImport}/\${locale}.json\`);
20
+ return translations.default;
21
+ }
22
+ `;
23
+ }
24
+ function isGeneratedLoader(content) {
25
+ return /^export default async function loadTranslations\(locale: string\) \{\r?\n const translations = await import\(`[^`]+\/\$\{locale\}\.json`\);\r?\n return translations\.default;\r?\n\}\r?\n?$/.test(content);
26
+ }
27
+ function toRelativeImport(fromDirectory, toPath) {
28
+ const relativePath = path.relative(fromDirectory, toPath).split(path.sep).join(path.posix.sep);
29
+ return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
30
+ }
31
+ function getEntryImport(appDirectory, sourceDirectory, source) {
32
+ const sourcePath = source.replace(/[?#].*$/, "");
33
+ return toRelativeImport(sourceDirectory, sourcePath.startsWith("/") ? path.resolve(appDirectory, `.${sourcePath}`) : path.resolve(appDirectory, sourcePath)).replace(/\.(?:[cm]?[jt]sx?)$/i, "");
34
+ }
35
+ function getBootstrapEntry(bootstrap) {
36
+ return bootstrap.match(/await\s+import\(\s*(['"])([^'"]+)\1\s*\)/)?.[2];
37
+ }
38
+ function getModuleEntry(indexHtml) {
39
+ const moduleScripts = indexHtml.match(/<script\b[^>]*\btype=(['"])module\1[^>]*>\s*<\/script>/gi);
40
+ for (const script of moduleScripts ?? []) {
41
+ const source = script.match(/\bsrc=(['"])([^'"]+)\1/i)?.[2];
42
+ if (source) return {
43
+ script,
44
+ source
45
+ };
46
+ }
47
+ throw new Error(createDiagnosticMessage({
48
+ source: "gt",
49
+ severity: "Error",
50
+ whatHappened: "No Vite module entry was found in index.html",
51
+ fix: "Add a module script for the app entry and rerun `npx gt@latest`"
52
+ }));
53
+ }
54
+ async function setupViteSPA({ appDirectory, configFilepath, defaultLocale, locales, translationsDir }) {
55
+ const indexHtmlPath = path.join(appDirectory, "index.html");
56
+ const sourceDirectory = path.join(appDirectory, "src");
57
+ const indexHtml = await fs.promises.readFile(indexHtmlPath, "utf8");
58
+ const { script, source } = getModuleEntry(indexHtml);
59
+ const declaredEntryImport = getEntryImport(appDirectory, sourceDirectory, source);
60
+ const configuredBootstrap = source.match(/^\/?src\/(gt-entry\.ts|gt-bootstrap\.ts)(?:[?#].*)?$/)?.[1];
61
+ const isAlreadyConfigured = configuredBootstrap !== void 0;
62
+ const bootstrapFilename = configuredBootstrap ?? (declaredEntryImport === "./gt-entry" ? alternateBootstrapFilename : defaultBootstrapFilename);
63
+ const bootstrapPath = path.join(sourceDirectory, bootstrapFilename);
64
+ let existingBootstrap;
65
+ if (fs.existsSync(bootstrapPath)) {
66
+ existingBootstrap = await fs.promises.readFile(bootstrapPath, "utf8");
67
+ if (!existingBootstrap.includes("initializeGTSPA")) throw new Error(getBootstrapConflictError(bootstrapFilename));
68
+ }
69
+ const entryImport = isAlreadyConfigured ? existingBootstrap && getBootstrapEntry(existingBootstrap) : declaredEntryImport;
70
+ if (!entryImport) throw new Error(createDiagnosticMessage({
71
+ source: "gt",
72
+ severity: "Error",
73
+ whatHappened: "The existing Vite bootstrap has no app entry import",
74
+ fix: "Restore the app entry import and rerun `npx gt@latest`"
75
+ }));
76
+ await fs.promises.mkdir(sourceDirectory, { recursive: true });
77
+ let loadTranslationsImport = "";
78
+ let loadTranslationsOption = "gtConfig";
79
+ if (translationsDir) {
80
+ const translationsPath = path.resolve(appDirectory, translationsDir);
81
+ const loaderPath = path.join(sourceDirectory, "loadTranslations.ts");
82
+ const translationsImport = toRelativeImport(sourceDirectory, translationsPath);
83
+ const existingLoader = fs.existsSync(loaderPath) ? await fs.promises.readFile(loaderPath, "utf8") : void 0;
84
+ if (!existingLoader || isGeneratedLoader(existingLoader)) await fs.promises.writeFile(loaderPath, getLoaderContent(translationsImport));
85
+ await fs.promises.mkdir(translationsPath, { recursive: true });
86
+ for (const locale of new Set(locales)) {
87
+ if (locale === defaultLocale) continue;
88
+ const stubPath = path.join(translationsPath, `${locale}.json`);
89
+ if (!fs.existsSync(stubPath)) await fs.promises.writeFile(stubPath, "{}\n");
90
+ }
91
+ loadTranslationsImport = "import loadTranslations from './loadTranslations';\n";
92
+ loadTranslationsOption = "{ ...gtConfig, loadTranslations }";
93
+ }
94
+ const configImport = toRelativeImport(sourceDirectory, path.resolve(appDirectory, configFilepath));
95
+ await fs.promises.writeFile(bootstrapPath, `import { initializeGTSPA } from 'gt-react';
96
+ import gtConfig from '${configImport}';
97
+ ${loadTranslationsImport}
98
+ await initializeGTSPA(${loadTranslationsOption});
99
+
100
+ await import('${entryImport}');
101
+ `);
102
+ if (!isAlreadyConfigured) {
103
+ const updatedScript = script.replace(source, `/src/${bootstrapFilename}`);
104
+ await fs.promises.writeFile(indexHtmlPath, indexHtml.replace(script, updatedScript));
105
+ }
106
+ logger.success("Configured initializeGTSPA for this Vite application.");
107
+ }
108
+ //#endregion
109
+ export { setupViteSPA };
110
+
111
+ //# sourceMappingURL=setupViteSPA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupViteSPA.js","names":[],"sources":["../../src/setup/setupViteSPA.ts"],"sourcesContent":["import { createDiagnosticMessage } from 'generaltranslation/internal';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from '../console/logger.js';\n\ntype SetupViteSPAOptions = {\n appDirectory: string;\n configFilepath: string;\n defaultLocale: string;\n locales: string[];\n translationsDir?: string;\n};\n\nconst defaultBootstrapFilename = 'gt-entry.ts';\nconst alternateBootstrapFilename = 'gt-bootstrap.ts';\n\nfunction getBootstrapConflictError(filename: string): string {\n return createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'The Vite bootstrap file already exists',\n why: `GT will not overwrite an existing src/${filename} file`,\n fix: 'Move or rename that file and rerun `npx gt@latest`',\n });\n}\n\nfunction getLoaderContent(translationsImport: string): string {\n return `export default async function loadTranslations(locale: string) {\n const translations = await import(\\`${translationsImport}/\\${locale}.json\\`);\n return translations.default;\n}\n`;\n}\n\nfunction isGeneratedLoader(content: string): boolean {\n return /^export default async function loadTranslations\\(locale: string\\) \\{\\r?\\n const translations = await import\\(`[^`]+\\/\\$\\{locale\\}\\.json`\\);\\r?\\n return translations\\.default;\\r?\\n\\}\\r?\\n?$/.test(\n content\n );\n}\n\nfunction toRelativeImport(fromDirectory: string, toPath: string): string {\n const relativePath = path\n .relative(fromDirectory, toPath)\n .split(path.sep)\n .join(path.posix.sep);\n return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;\n}\n\nfunction getEntryImport(\n appDirectory: string,\n sourceDirectory: string,\n source: string\n): string {\n const sourcePath = source.replace(/[?#].*$/, '');\n const entryPath = sourcePath.startsWith('/')\n ? path.resolve(appDirectory, `.${sourcePath}`)\n : path.resolve(appDirectory, sourcePath);\n return toRelativeImport(sourceDirectory, entryPath).replace(\n /\\.(?:[cm]?[jt]sx?)$/i,\n ''\n );\n}\n\nfunction getBootstrapEntry(bootstrap: string): string | undefined {\n return bootstrap.match(/await\\s+import\\(\\s*(['\"])([^'\"]+)\\1\\s*\\)/)?.[2];\n}\n\nfunction getModuleEntry(indexHtml: string): {\n script: string;\n source: string;\n} {\n const moduleScripts = indexHtml.match(\n /<script\\b[^>]*\\btype=(['\"])module\\1[^>]*>\\s*<\\/script>/gi\n );\n for (const script of moduleScripts ?? []) {\n const source = script.match(/\\bsrc=(['\"])([^'\"]+)\\1/i)?.[2];\n if (source) return { script, source };\n }\n\n throw new Error(\n createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'No Vite module entry was found in index.html',\n fix: 'Add a module script for the app entry and rerun `npx gt@latest`',\n })\n );\n}\n\nexport async function setupViteSPA({\n appDirectory,\n configFilepath,\n defaultLocale,\n locales,\n translationsDir,\n}: SetupViteSPAOptions): Promise<void> {\n const indexHtmlPath = path.join(appDirectory, 'index.html');\n const sourceDirectory = path.join(appDirectory, 'src');\n const indexHtml = await fs.promises.readFile(indexHtmlPath, 'utf8');\n const { script, source } = getModuleEntry(indexHtml);\n const declaredEntryImport = getEntryImport(\n appDirectory,\n sourceDirectory,\n source\n );\n const configuredBootstrap = source.match(\n /^\\/?src\\/(gt-entry\\.ts|gt-bootstrap\\.ts)(?:[?#].*)?$/\n )?.[1];\n const isAlreadyConfigured = configuredBootstrap !== undefined;\n const bootstrapFilename =\n configuredBootstrap ??\n (declaredEntryImport === './gt-entry'\n ? alternateBootstrapFilename\n : defaultBootstrapFilename);\n const bootstrapPath = path.join(sourceDirectory, bootstrapFilename);\n let existingBootstrap: string | undefined;\n\n if (fs.existsSync(bootstrapPath)) {\n existingBootstrap = await fs.promises.readFile(bootstrapPath, 'utf8');\n if (!existingBootstrap.includes('initializeGTSPA')) {\n throw new Error(getBootstrapConflictError(bootstrapFilename));\n }\n }\n\n const entryImport = isAlreadyConfigured\n ? existingBootstrap && getBootstrapEntry(existingBootstrap)\n : declaredEntryImport;\n if (!entryImport) {\n throw new Error(\n createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'The existing Vite bootstrap has no app entry import',\n fix: 'Restore the app entry import and rerun `npx gt@latest`',\n })\n );\n }\n\n await fs.promises.mkdir(sourceDirectory, { recursive: true });\n\n let loadTranslationsImport = '';\n let loadTranslationsOption = 'gtConfig';\n if (translationsDir) {\n const translationsPath = path.resolve(appDirectory, translationsDir);\n const loaderPath = path.join(sourceDirectory, 'loadTranslations.ts');\n const translationsImport = toRelativeImport(\n sourceDirectory,\n translationsPath\n );\n const existingLoader = fs.existsSync(loaderPath)\n ? await fs.promises.readFile(loaderPath, 'utf8')\n : undefined;\n if (!existingLoader || isGeneratedLoader(existingLoader)) {\n await fs.promises.writeFile(\n loaderPath,\n getLoaderContent(translationsImport)\n );\n }\n\n await fs.promises.mkdir(translationsPath, { recursive: true });\n for (const locale of new Set(locales)) {\n if (locale === defaultLocale) continue;\n const stubPath = path.join(translationsPath, `${locale}.json`);\n if (!fs.existsSync(stubPath)) {\n await fs.promises.writeFile(stubPath, '{}\\n');\n }\n }\n\n loadTranslationsImport =\n \"import loadTranslations from './loadTranslations';\\n\";\n loadTranslationsOption = '{ ...gtConfig, loadTranslations }';\n }\n\n const configImport = toRelativeImport(\n sourceDirectory,\n path.resolve(appDirectory, configFilepath)\n );\n await fs.promises.writeFile(\n bootstrapPath,\n `import { initializeGTSPA } from 'gt-react';\nimport gtConfig from '${configImport}';\n${loadTranslationsImport}\nawait initializeGTSPA(${loadTranslationsOption});\n\nawait import('${entryImport}');\n`\n );\n\n if (!isAlreadyConfigured) {\n const updatedScript = script.replace(source, `/src/${bootstrapFilename}`);\n await fs.promises.writeFile(\n indexHtmlPath,\n indexHtml.replace(script, updatedScript)\n );\n }\n\n logger.success('Configured initializeGTSPA for this Vite application.');\n}\n"],"mappings":";;;;;AAaA,MAAM,2BAA2B;AACjC,MAAM,6BAA6B;AAEnC,SAAS,0BAA0B,UAA0B;AAC3D,QAAO,wBAAwB;EAC7B,QAAQ;EACR,UAAU;EACV,cAAc;EACd,KAAK,yCAAyC,SAAS;EACvD,KAAK;EACN,CAAC;;AAGJ,SAAS,iBAAiB,oBAAoC;AAC5D,QAAO;wCAC+B,mBAAmB;;;;;AAM3D,SAAS,kBAAkB,SAA0B;AACnD,QAAO,iMAAiM,KACtM,QACD;;AAGH,SAAS,iBAAiB,eAAuB,QAAwB;CACvE,MAAM,eAAe,KAClB,SAAS,eAAe,OAAO,CAC/B,MAAM,KAAK,IAAI,CACf,KAAK,KAAK,MAAM,IAAI;AACvB,QAAO,aAAa,WAAW,IAAI,GAAG,eAAe,KAAK;;AAG5D,SAAS,eACP,cACA,iBACA,QACQ;CACR,MAAM,aAAa,OAAO,QAAQ,WAAW,GAAG;AAIhD,QAAO,iBAAiB,iBAHN,WAAW,WAAW,IAAI,GACxC,KAAK,QAAQ,cAAc,IAAI,aAAa,GAC5C,KAAK,QAAQ,cAAc,WAAW,CACS,CAAC,QAClD,wBACA,GACD;;AAGH,SAAS,kBAAkB,WAAuC;AAChE,QAAO,UAAU,MAAM,2CAA2C,GAAG;;AAGvE,SAAS,eAAe,WAGtB;CACA,MAAM,gBAAgB,UAAU,MAC9B,2DACD;AACD,MAAK,MAAM,UAAU,iBAAiB,EAAE,EAAE;EACxC,MAAM,SAAS,OAAO,MAAM,0BAA0B,GAAG;AACzD,MAAI,OAAQ,QAAO;GAAE;GAAQ;GAAQ;;AAGvC,OAAM,IAAI,MACR,wBAAwB;EACtB,QAAQ;EACR,UAAU;EACV,cAAc;EACd,KAAK;EACN,CAAC,CACH;;AAGH,eAAsB,aAAa,EACjC,cACA,gBACA,eACA,SACA,mBACqC;CACrC,MAAM,gBAAgB,KAAK,KAAK,cAAc,aAAa;CAC3D,MAAM,kBAAkB,KAAK,KAAK,cAAc,MAAM;CACtD,MAAM,YAAY,MAAM,GAAG,SAAS,SAAS,eAAe,OAAO;CACnE,MAAM,EAAE,QAAQ,WAAW,eAAe,UAAU;CACpD,MAAM,sBAAsB,eAC1B,cACA,iBACA,OACD;CACD,MAAM,sBAAsB,OAAO,MACjC,uDACD,GAAG;CACJ,MAAM,sBAAsB,wBAAwB,KAAA;CACpD,MAAM,oBACJ,wBACC,wBAAwB,eACrB,6BACA;CACN,MAAM,gBAAgB,KAAK,KAAK,iBAAiB,kBAAkB;CACnE,IAAI;AAEJ,KAAI,GAAG,WAAW,cAAc,EAAE;AAChC,sBAAoB,MAAM,GAAG,SAAS,SAAS,eAAe,OAAO;AACrE,MAAI,CAAC,kBAAkB,SAAS,kBAAkB,CAChD,OAAM,IAAI,MAAM,0BAA0B,kBAAkB,CAAC;;CAIjE,MAAM,cAAc,sBAChB,qBAAqB,kBAAkB,kBAAkB,GACzD;AACJ,KAAI,CAAC,YACH,OAAM,IAAI,MACR,wBAAwB;EACtB,QAAQ;EACR,UAAU;EACV,cAAc;EACd,KAAK;EACN,CAAC,CACH;AAGH,OAAM,GAAG,SAAS,MAAM,iBAAiB,EAAE,WAAW,MAAM,CAAC;CAE7D,IAAI,yBAAyB;CAC7B,IAAI,yBAAyB;AAC7B,KAAI,iBAAiB;EACnB,MAAM,mBAAmB,KAAK,QAAQ,cAAc,gBAAgB;EACpE,MAAM,aAAa,KAAK,KAAK,iBAAiB,sBAAsB;EACpE,MAAM,qBAAqB,iBACzB,iBACA,iBACD;EACD,MAAM,iBAAiB,GAAG,WAAW,WAAW,GAC5C,MAAM,GAAG,SAAS,SAAS,YAAY,OAAO,GAC9C,KAAA;AACJ,MAAI,CAAC,kBAAkB,kBAAkB,eAAe,CACtD,OAAM,GAAG,SAAS,UAChB,YACA,iBAAiB,mBAAmB,CACrC;AAGH,QAAM,GAAG,SAAS,MAAM,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAC9D,OAAK,MAAM,UAAU,IAAI,IAAI,QAAQ,EAAE;AACrC,OAAI,WAAW,cAAe;GAC9B,MAAM,WAAW,KAAK,KAAK,kBAAkB,GAAG,OAAO,OAAO;AAC9D,OAAI,CAAC,GAAG,WAAW,SAAS,CAC1B,OAAM,GAAG,SAAS,UAAU,UAAU,OAAO;;AAIjD,2BACE;AACF,2BAAyB;;CAG3B,MAAM,eAAe,iBACnB,iBACA,KAAK,QAAQ,cAAc,eAAe,CAC3C;AACD,OAAM,GAAG,SAAS,UAChB,eACA;wBACoB,aAAa;EACnC,uBAAuB;wBACD,uBAAuB;;gBAE/B,YAAY;EAEzB;AAED,KAAI,CAAC,qBAAqB;EACxB,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,QAAQ,oBAAoB;AACzE,QAAM,GAAG,SAAS,UAChB,eACA,UAAU,QAAQ,QAAQ,cAAc,CACzC;;AAGH,QAAO,QAAQ,wDAAwD"}
@@ -1,4 +1,7 @@
1
- export declare function getDesiredLocales(): Promise<{
1
+ export declare function getDesiredLocales(existingConfig?: {
2
+ defaultLocale?: unknown;
3
+ locales?: unknown;
4
+ }): Promise<{
2
5
  defaultLocale: string;
3
6
  locales: string[];
4
7
  }>;
@@ -1,13 +1,15 @@
1
1
  import { promptLocale, promptLocaleList } from "../console/logging.js";
2
2
  import { libraryDefaultLocale } from "generaltranslation/internal";
3
3
  //#region src/setup/userInput.ts
4
- async function getDesiredLocales() {
4
+ async function getDesiredLocales(existingConfig) {
5
+ const configuredDefaultLocale = typeof existingConfig?.defaultLocale === "string" && existingConfig.defaultLocale ? existingConfig.defaultLocale : void 0;
6
+ const configuredLocales = Array.isArray(existingConfig?.locales) && existingConfig.locales.every((locale) => typeof locale === "string") ? existingConfig.locales : void 0;
5
7
  return {
6
- defaultLocale: await promptLocale({
8
+ defaultLocale: configuredDefaultLocale ?? await promptLocale({
7
9
  message: "What is the default locale for your project?",
8
10
  defaultValue: libraryDefaultLocale
9
11
  }),
10
- locales: await promptLocaleList({ message: "Which languages would you like to translate your project into?" })
12
+ locales: configuredLocales ?? await promptLocaleList({ message: "Which languages would you like to translate your project into?" })
11
13
  };
12
14
  }
13
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"userInput.js","names":[],"sources":["../../src/setup/userInput.ts"],"sourcesContent":["import { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { promptLocale, promptLocaleList } from '../console/logging.js';\n\nexport async function getDesiredLocales(): Promise<{\n defaultLocale: string;\n locales: string[];\n}> {\n // Ask for the default locale\n const defaultLocale = await promptLocale({\n message: 'What is the default locale for your project?',\n defaultValue: libraryDefaultLocale,\n });\n\n // Ask for the locales\n const locales = await promptLocaleList({\n message: 'Which languages would you like to translate your project into?',\n });\n return { defaultLocale, locales };\n}\n"],"mappings":";;;AAGA,eAAsB,oBAGnB;AAWD,QAAO;EAAE,eAAA,MATmB,aAAa;GACvC,SAAS;GACT,cAAc;GACf,CAAC;EAMsB,SAAA,MAHF,iBAAiB,EACrC,SAAS,kEACV,CAAC;EAC+B"}
1
+ {"version":3,"file":"userInput.js","names":[],"sources":["../../src/setup/userInput.ts"],"sourcesContent":["import { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { promptLocale, promptLocaleList } from '../console/logging.js';\n\nexport async function getDesiredLocales(existingConfig?: {\n defaultLocale?: unknown;\n locales?: unknown;\n}): Promise<{\n defaultLocale: string;\n locales: string[];\n}> {\n const configuredDefaultLocale =\n typeof existingConfig?.defaultLocale === 'string' &&\n existingConfig.defaultLocale\n ? existingConfig.defaultLocale\n : undefined;\n const configuredLocales =\n Array.isArray(existingConfig?.locales) &&\n existingConfig.locales.every((locale) => typeof locale === 'string')\n ? (existingConfig.locales as string[])\n : undefined;\n\n // Ask for the default locale\n const defaultLocale =\n configuredDefaultLocale ??\n (await promptLocale({\n message: 'What is the default locale for your project?',\n defaultValue: libraryDefaultLocale,\n }));\n\n // Ask for the locales\n const locales =\n configuredLocales ??\n (await promptLocaleList({\n message: 'Which languages would you like to translate your project into?',\n }));\n return { defaultLocale, locales };\n}\n"],"mappings":";;;AAGA,eAAsB,kBAAkB,gBAMrC;CACD,MAAM,0BACJ,OAAO,gBAAgB,kBAAkB,YACzC,eAAe,gBACX,eAAe,gBACf,KAAA;CACN,MAAM,oBACJ,MAAM,QAAQ,gBAAgB,QAAQ,IACtC,eAAe,QAAQ,OAAO,WAAW,OAAO,WAAW,SAAS,GAC/D,eAAe,UAChB,KAAA;AAgBN,QAAO;EAAE,eAZP,2BACC,MAAM,aAAa;GAClB,SAAS;GACT,cAAc;GACf,CAAC;EAQoB,SAJtB,qBACC,MAAM,iBAAiB,EACtB,SAAS,kEACV,CAAC;EAC6B"}
@@ -10,7 +10,6 @@ import { handleInitGT } from "../next/parse/handleInitGT.js";
10
10
  import { wrapContentNext } from "../next/parse/wrapContent.js";
11
11
  import { getPackageManager } from "../utils/packageManager.js";
12
12
  import { installPackage } from "../utils/installPackage.js";
13
- import { addVitePlugin } from "../react/parse/addVitePlugin/index.js";
14
13
  import { getFrameworkDisplayName } from "./frameworkUtils.js";
15
14
  import chalk from "chalk";
16
15
  //#region src/setup/wizard.ts
@@ -67,7 +66,7 @@ Make sure you have committed or stashed any changes. Do you want to continue?`),
67
66
  Please let us know what you would like to see added at https://github.com/generaltranslation/gt/issues`);
68
67
  exitSync(0);
69
68
  }
70
- await createOrUpdateConfig(options.config || "gt.config.json", { framework: frameworkType });
69
+ if (frameworkType !== "vite") await createOrUpdateConfig(options.config || "gt.config.json", { framework: frameworkType });
71
70
  const packageJson = await getPackageJson();
72
71
  if (!packageJson) {
73
72
  logger.error(chalk.red("No package.json found in the current directory. Run this command from the root of your project."));
@@ -123,13 +122,6 @@ Please let us know what you would like to see added at https://github.com/genera
123
122
  await handleInitGT(nextConfigPath, errors, warnings, filesUpdated, packageJson, tsconfigJson);
124
123
  logger.step(chalk.green(`Added withGTConfig() to your ${nextConfigPath} file.`));
125
124
  }
126
- if (frameworkType === "vite") await addVitePlugin({
127
- errors,
128
- warnings,
129
- filesUpdated,
130
- packageJson,
131
- tsconfigJson
132
- });
133
125
  if (errors.length > 0) logger.error(chalk.red("Failed to write files:\n") + errors.join("\n"));
134
126
  if (warnings.length > 0) logger.warn(chalk.yellow("Warnings encountered:") + "\n" + warnings.map((warning) => `${chalk.yellow("-")} ${warning}`).join("\n"));
135
127
  const formatter = await detectFormatter();
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.js","names":[],"sources":["../../src/setup/wizard.ts"],"sourcesContent":["import { detectFormatter } from '../hooks/postProcess.js';\nimport { promptSelect } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\nimport { promptConfirm } from '../console/logging.js';\nimport { SetupOptions, SupportedReactFrameworks } from '../types/index.js';\nimport findFilepath from '../fs/findFilepath.js';\nimport { formatFiles } from '../hooks/postProcess.js';\nimport { handleInitGT } from '../next/parse/handleInitGT.js';\nimport { getPackageJson, isPackageInstalled } from '../utils/packageJson.js';\nimport { wrapContentNext } from '../next/parse/wrapContent.js';\nimport { getPackageManager } from '../utils/packageManager.js';\nimport { installPackage } from '../utils/installPackage.js';\nimport { createOrUpdateConfig } from '../fs/config/setupConfig.js';\nimport { loadConfig } from '../fs/config/loadConfig.js';\nimport { addVitePlugin } from '../react/parse/addVitePlugin/index.js';\nimport { exitSync } from '../console/logging.js';\nimport { ReactFrameworkObject } from '../types/index.js';\nimport { getFrameworkDisplayName } from './frameworkUtils.js';\nimport { Libraries } from '../types/libraries.js';\n\nexport async function handleSetupReactCommand(\n options: SetupOptions,\n frameworkObject: ReactFrameworkObject,\n useDefaults: boolean = false\n): Promise<void> {\n const frameworkDisplayName = getFrameworkDisplayName(frameworkObject);\n\n // Ask user for confirmation using inquirer\n if (!useDefaults) {\n const answer = await promptConfirm({\n message: chalk.yellow(\n `This wizard will configure your ${frameworkDisplayName} project for internationalization with GT. If your project is already using a different i18n library, this wizard may cause issues.\n\nMake sure you have committed or stashed any changes. Do you want to continue?`\n ),\n defaultValue: true,\n cancelMessage:\n 'Operation cancelled. You can re-run this wizard with: npx gt setup',\n });\n if (!answer) {\n logger.info(\n 'Operation cancelled. You can re-run this wizard with: npx gt setup'\n );\n exitSync(0);\n }\n }\n\n const frameworkType =\n useDefaults && frameworkObject?.name\n ? frameworkObject.name\n : await promptSelect<SupportedReactFrameworks | 'other'>({\n message: 'Which framework are you using?',\n options: [\n { value: 'next-app', label: chalk.blue('Next.js App Router') },\n { value: 'next-pages', label: chalk.green('Next.js Pages Router') },\n { value: 'vite', label: chalk.cyan('Vite + React') },\n { value: 'gatsby', label: chalk.magenta('Gatsby') },\n { value: 'react', label: chalk.yellow('React') },\n { value: 'redwood', label: chalk.red('RedwoodJS') },\n { value: 'other', label: chalk.dim('Other') },\n ],\n defaultValue: frameworkObject?.name || 'other',\n });\n if (frameworkType === 'other') {\n logger.error(\n `Sorry, the wizard doesn't currently support other React frameworks.\nPlease let us know what you would like to see added at https://github.com/generaltranslation/gt/issues`\n );\n exitSync(0);\n }\n\n // ----- Create a starter gt.config.json file -----\n await createOrUpdateConfig(options.config || 'gt.config.json', {\n framework: frameworkType as SupportedReactFrameworks,\n });\n\n const packageJson = await getPackageJson();\n if (!packageJson) {\n logger.error(\n chalk.red(\n 'No package.json found in the current directory. Run this command from the root of your project.'\n )\n );\n exitSync(1);\n }\n // Check if gt-next or gt-react is installed\n if (\n frameworkType === 'next-app' &&\n !isPackageInstalled(Libraries.GT_NEXT, packageJson)\n ) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner('timer');\n spinner.start(\n `Installing ${Libraries.GT_NEXT} with ${packageManager.name}...`\n );\n await installPackage(Libraries.GT_NEXT, packageManager);\n spinner.stop(chalk.green(`Automatically installed ${Libraries.GT_NEXT}.`));\n } else if (\n ['next-pages', 'react', 'redwood', 'vite', 'gatsby'].includes(\n frameworkType\n ) &&\n !isPackageInstalled(Libraries.GT_REACT, packageJson)\n ) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner('timer');\n spinner.start(\n `Installing ${Libraries.GT_REACT} with ${packageManager.name}...`\n );\n await installPackage(Libraries.GT_REACT, packageManager);\n spinner.stop(chalk.green(`Automatically installed ${Libraries.GT_REACT}.`));\n }\n\n const errors: string[] = [];\n const warnings: string[] = [];\n let filesUpdated: string[] = [];\n\n // Read tsconfig.json if it exists\n const tsconfigPath = findFilepath(['tsconfig.json']);\n const tsconfigJson = tsconfigPath ? loadConfig(tsconfigPath) : undefined;\n\n if (frameworkType === 'next-app') {\n // Check if they have a next.config.js file\n const nextConfigPath = findFilepath([\n './next.config.js',\n './next.config.ts',\n './next.config.mjs',\n './next.config.mts',\n ]);\n if (!nextConfigPath) {\n logger.error('No next.config.[js|ts|mjs|mts] file found.');\n exitSync(1);\n }\n\n const mergeOptions = {\n ...options,\n disableIds: true,\n disableFormatting: true,\n skipTs: true,\n addGTProvider: true,\n };\n const spinner = logger.createSpinner();\n spinner.start('Wrapping JSX content with <T> tags...');\n // Wrap all JSX elements in the src directory with a <T> tag, with unique ids\n const { filesUpdated: filesUpdatedNext } = await wrapContentNext(\n mergeOptions,\n Libraries.GT_NEXT,\n errors,\n warnings\n );\n filesUpdated = [...filesUpdated, ...filesUpdatedNext];\n\n spinner.stop(\n chalk.green(\n `Success! Updated ${chalk.bold.cyan(filesUpdated.length)} files:\\n`\n ) + filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\\n')\n );\n\n // Add the withGTConfig() function to the next.config.js file\n await handleInitGT(\n nextConfigPath,\n errors,\n warnings,\n filesUpdated,\n packageJson,\n tsconfigJson\n );\n logger.step(\n chalk.green(`Added withGTConfig() to your ${nextConfigPath} file.`)\n );\n }\n\n // Add gt compiler plugin\n if (frameworkType === 'vite') {\n await addVitePlugin({\n errors,\n warnings,\n filesUpdated,\n packageJson,\n tsconfigJson,\n });\n }\n\n if (errors.length > 0) {\n logger.error(chalk.red('Failed to write files:\\n') + errors.join('\\n'));\n }\n\n if (warnings.length > 0) {\n logger.warn(\n chalk.yellow('Warnings encountered:') +\n '\\n' +\n warnings.map((warning) => `${chalk.yellow('-')} ${warning}`).join('\\n')\n );\n }\n\n const formatter = await detectFormatter();\n\n if (!formatter || filesUpdated.length === 0) {\n return;\n }\n\n const applyFormatting = useDefaults\n ? true\n : await promptConfirm({\n message: `Would you like the wizard to auto-format the modified files? ${chalk.dim(\n `(${formatter})`\n )}`,\n defaultValue: true,\n });\n // Format updated files if formatters are available\n if (applyFormatting) await formatFiles(filesUpdated, formatter);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"wizard.js","names":[],"sources":["../../src/setup/wizard.ts"],"sourcesContent":["import { detectFormatter } from '../hooks/postProcess.js';\nimport { promptSelect } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\nimport { promptConfirm } from '../console/logging.js';\nimport { SetupOptions, SupportedReactFrameworks } from '../types/index.js';\nimport findFilepath from '../fs/findFilepath.js';\nimport { formatFiles } from '../hooks/postProcess.js';\nimport { handleInitGT } from '../next/parse/handleInitGT.js';\nimport { getPackageJson, isPackageInstalled } from '../utils/packageJson.js';\nimport { wrapContentNext } from '../next/parse/wrapContent.js';\nimport { getPackageManager } from '../utils/packageManager.js';\nimport { installPackage } from '../utils/installPackage.js';\nimport { createOrUpdateConfig } from '../fs/config/setupConfig.js';\nimport { loadConfig } from '../fs/config/loadConfig.js';\nimport { exitSync } from '../console/logging.js';\nimport { ReactFrameworkObject } from '../types/index.js';\nimport { getFrameworkDisplayName } from './frameworkUtils.js';\nimport { Libraries } from '../types/libraries.js';\n\nexport async function handleSetupReactCommand(\n options: SetupOptions,\n frameworkObject: ReactFrameworkObject,\n useDefaults: boolean = false\n): Promise<void> {\n const frameworkDisplayName = getFrameworkDisplayName(frameworkObject);\n\n // Ask user for confirmation using inquirer\n if (!useDefaults) {\n const answer = await promptConfirm({\n message: chalk.yellow(\n `This wizard will configure your ${frameworkDisplayName} project for internationalization with GT. If your project is already using a different i18n library, this wizard may cause issues.\n\nMake sure you have committed or stashed any changes. Do you want to continue?`\n ),\n defaultValue: true,\n cancelMessage:\n 'Operation cancelled. You can re-run this wizard with: npx gt setup',\n });\n if (!answer) {\n logger.info(\n 'Operation cancelled. You can re-run this wizard with: npx gt setup'\n );\n exitSync(0);\n }\n }\n\n const frameworkType =\n useDefaults && frameworkObject?.name\n ? frameworkObject.name\n : await promptSelect<SupportedReactFrameworks | 'other'>({\n message: 'Which framework are you using?',\n options: [\n { value: 'next-app', label: chalk.blue('Next.js App Router') },\n { value: 'next-pages', label: chalk.green('Next.js Pages Router') },\n { value: 'vite', label: chalk.cyan('Vite + React') },\n { value: 'gatsby', label: chalk.magenta('Gatsby') },\n { value: 'react', label: chalk.yellow('React') },\n { value: 'redwood', label: chalk.red('RedwoodJS') },\n { value: 'other', label: chalk.dim('Other') },\n ],\n defaultValue: frameworkObject?.name || 'other',\n });\n if (frameworkType === 'other') {\n logger.error(\n `Sorry, the wizard doesn't currently support other React frameworks.\nPlease let us know what you would like to see added at https://github.com/generaltranslation/gt/issues`\n );\n exitSync(0);\n }\n\n // Vite setup writes its complete config after locales are collected.\n if (frameworkType !== 'vite') {\n await createOrUpdateConfig(options.config || 'gt.config.json', {\n framework: frameworkType as SupportedReactFrameworks,\n });\n }\n\n const packageJson = await getPackageJson();\n if (!packageJson) {\n logger.error(\n chalk.red(\n 'No package.json found in the current directory. Run this command from the root of your project.'\n )\n );\n exitSync(1);\n }\n // Check if gt-next or gt-react is installed\n if (\n frameworkType === 'next-app' &&\n !isPackageInstalled(Libraries.GT_NEXT, packageJson)\n ) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner('timer');\n spinner.start(\n `Installing ${Libraries.GT_NEXT} with ${packageManager.name}...`\n );\n await installPackage(Libraries.GT_NEXT, packageManager);\n spinner.stop(chalk.green(`Automatically installed ${Libraries.GT_NEXT}.`));\n } else if (\n ['next-pages', 'react', 'redwood', 'vite', 'gatsby'].includes(\n frameworkType\n ) &&\n !isPackageInstalled(Libraries.GT_REACT, packageJson)\n ) {\n const packageManager = await getPackageManager();\n const spinner = logger.createSpinner('timer');\n spinner.start(\n `Installing ${Libraries.GT_REACT} with ${packageManager.name}...`\n );\n await installPackage(Libraries.GT_REACT, packageManager);\n spinner.stop(chalk.green(`Automatically installed ${Libraries.GT_REACT}.`));\n }\n\n const errors: string[] = [];\n const warnings: string[] = [];\n let filesUpdated: string[] = [];\n\n // Read tsconfig.json if it exists\n const tsconfigPath = findFilepath(['tsconfig.json']);\n const tsconfigJson = tsconfigPath ? loadConfig(tsconfigPath) : undefined;\n\n if (frameworkType === 'next-app') {\n // Check if they have a next.config.js file\n const nextConfigPath = findFilepath([\n './next.config.js',\n './next.config.ts',\n './next.config.mjs',\n './next.config.mts',\n ]);\n if (!nextConfigPath) {\n logger.error('No next.config.[js|ts|mjs|mts] file found.');\n exitSync(1);\n }\n\n const mergeOptions = {\n ...options,\n disableIds: true,\n disableFormatting: true,\n skipTs: true,\n addGTProvider: true,\n };\n const spinner = logger.createSpinner();\n spinner.start('Wrapping JSX content with <T> tags...');\n // Wrap all JSX elements in the src directory with a <T> tag, with unique ids\n const { filesUpdated: filesUpdatedNext } = await wrapContentNext(\n mergeOptions,\n Libraries.GT_NEXT,\n errors,\n warnings\n );\n filesUpdated = [...filesUpdated, ...filesUpdatedNext];\n\n spinner.stop(\n chalk.green(\n `Success! Updated ${chalk.bold.cyan(filesUpdated.length)} files:\\n`\n ) + filesUpdated.map((file) => `${chalk.green('-')} ${file}`).join('\\n')\n );\n\n // Add the withGTConfig() function to the next.config.js file\n await handleInitGT(\n nextConfigPath,\n errors,\n warnings,\n filesUpdated,\n packageJson,\n tsconfigJson\n );\n logger.step(\n chalk.green(`Added withGTConfig() to your ${nextConfigPath} file.`)\n );\n }\n\n if (errors.length > 0) {\n logger.error(chalk.red('Failed to write files:\\n') + errors.join('\\n'));\n }\n\n if (warnings.length > 0) {\n logger.warn(\n chalk.yellow('Warnings encountered:') +\n '\\n' +\n warnings.map((warning) => `${chalk.yellow('-')} ${warning}`).join('\\n')\n );\n }\n\n const formatter = await detectFormatter();\n\n if (!formatter || filesUpdated.length === 0) {\n return;\n }\n\n const applyFormatting = useDefaults\n ? true\n : await promptConfirm({\n message: `Would you like the wizard to auto-format the modified files? ${chalk.dim(\n `(${formatter})`\n )}`,\n defaultValue: true,\n });\n // Format updated files if formatters are available\n if (applyFormatting) await formatFiles(filesUpdated, formatter);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gt",
3
- "version": "2.16.1",
3
+ "version": "2.16.2",
4
4
  "main": "dist/index.js",
5
5
  "bin": "bin/main.js",
6
6
  "files": [
@@ -118,9 +118,9 @@
118
118
  "@generaltranslation/icu": "0.1.1",
119
119
  "@generaltranslation/format": "0.1.4",
120
120
  "@generaltranslation/python-extractor": "0.2.34",
121
- "@generaltranslation/supported-locales": "2.1.14",
122
121
  "generaltranslation": "9.1.1",
123
- "gt-remark": "1.0.11"
122
+ "gt-remark": "1.0.11",
123
+ "@generaltranslation/supported-locales": "2.1.14"
124
124
  },
125
125
  "devDependencies": {
126
126
  "@types/babel__generator": "^7.27.0",