gt 2.16.4 → 2.17.0-iris.0

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE.md +18 -102
  3. package/dist/api/downloadFileBatch.d.ts +6 -3
  4. package/dist/api/downloadFileBatch.js +10 -7
  5. package/dist/api/downloadFileBatch.js.map +1 -1
  6. package/dist/cli/base.d.ts +24 -2
  7. package/dist/cli/base.js +67 -20
  8. package/dist/cli/base.js.map +1 -1
  9. package/dist/cli/commands/download.js +9 -4
  10. package/dist/cli/commands/download.js.map +1 -1
  11. package/dist/cli/commands/enqueue.js +3 -2
  12. package/dist/cli/commands/enqueue.js.map +1 -1
  13. package/dist/cli/commands/setupProject.js +3 -3
  14. package/dist/cli/commands/setupProject.js.map +1 -1
  15. package/dist/cli/commands/stage.d.ts +2 -0
  16. package/dist/cli/commands/stage.js +6 -4
  17. package/dist/cli/commands/stage.js.map +1 -1
  18. package/dist/cli/commands/translate.d.ts +2 -1
  19. package/dist/cli/commands/translate.js +2 -1
  20. package/dist/cli/commands/translate.js.map +1 -1
  21. package/dist/cli/flags.d.ts +2 -2
  22. package/dist/cli/flags.js +6 -6
  23. package/dist/cli/flags.js.map +1 -1
  24. package/dist/cli/inline.d.ts +5 -1
  25. package/dist/cli/inline.js +15 -8
  26. package/dist/cli/inline.js.map +1 -1
  27. package/dist/cli/react.js +1 -1
  28. package/dist/cli/vue.d.ts +17 -0
  29. package/dist/cli/vue.js +42 -0
  30. package/dist/cli/vue.js.map +1 -0
  31. package/dist/console/logging.d.ts +2 -1
  32. package/dist/console/logging.js +4 -2
  33. package/dist/console/logging.js.map +1 -1
  34. package/dist/formats/files/collectFiles.d.ts +4 -0
  35. package/dist/formats/files/collectFiles.js +16 -4
  36. package/dist/formats/files/collectFiles.js.map +1 -1
  37. package/dist/fs/config/setupConfig.d.ts +3 -0
  38. package/dist/fs/config/setupConfig.js +2 -0
  39. package/dist/fs/config/setupConfig.js.map +1 -1
  40. package/dist/fs/determineFramework/index.d.ts +9 -1
  41. package/dist/fs/determineFramework/index.js +15 -3
  42. package/dist/fs/determineFramework/index.js.map +1 -1
  43. package/dist/generated/version.d.ts +1 -1
  44. package/dist/generated/version.js +1 -1
  45. package/dist/generated/version.js.map +1 -1
  46. package/dist/index.js +5 -2
  47. package/dist/index.js.map +1 -1
  48. package/dist/next/parse/wrapContent.js +1 -1
  49. package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.js.map +1 -1
  50. package/dist/react/jsx/utils/parseString.js +1 -1
  51. package/dist/react/jsx/utils/stringParsing/derivation/handleDerivation.d.ts +0 -1
  52. package/dist/react/jsx/utils/stringParsing/derivation/handleDerivation.js.map +1 -1
  53. package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.js +1 -1
  54. package/dist/react/parse/createInlineUpdates.js +1 -1
  55. package/dist/react/parse/wrapContent.js +1 -1
  56. package/dist/setup/wizard.js +1 -1
  57. package/dist/translation/extractInline.d.ts +12 -0
  58. package/dist/translation/extractInline.js +37 -0
  59. package/dist/translation/extractInline.js.map +1 -0
  60. package/dist/translation/parse.js +3 -2
  61. package/dist/translation/parse.js.map +1 -1
  62. package/dist/translation/validate.d.ts +1 -1
  63. package/dist/translation/validate.js +7 -3
  64. package/dist/translation/validate.js.map +1 -1
  65. package/dist/types/libraries.d.ts +4 -1
  66. package/dist/types/libraries.js +7 -1
  67. package/dist/types/libraries.js.map +1 -1
  68. package/dist/types/parsing.d.ts +5 -0
  69. package/dist/types/parsing.js.map +1 -1
  70. package/dist/workflows/download.d.ts +3 -1
  71. package/dist/workflows/download.js +3 -3
  72. package/dist/workflows/download.js.map +1 -1
  73. package/dist/workflows/enqueue.d.ts +3 -1
  74. package/dist/workflows/enqueue.js +2 -2
  75. package/dist/workflows/enqueue.js.map +1 -1
  76. package/dist/workflows/setupProject.d.ts +2 -1
  77. package/dist/workflows/setupProject.js +2 -2
  78. package/dist/workflows/setupProject.js.map +1 -1
  79. package/dist/workflows/stage.d.ts +3 -1
  80. package/dist/workflows/stage.js +2 -2
  81. package/dist/workflows/stage.js.map +1 -1
  82. package/dist/workflows/steps/DownloadStep.d.ts +3 -1
  83. package/dist/workflows/steps/DownloadStep.js +3 -2
  84. package/dist/workflows/steps/DownloadStep.js.map +1 -1
  85. package/dist/workflows/steps/PollJobsStep.d.ts +3 -1
  86. package/dist/workflows/steps/PollJobsStep.js +4 -2
  87. package/dist/workflows/steps/PollJobsStep.js.map +1 -1
  88. package/package.json +10 -8
@@ -1 +1 @@
1
- {"version":3,"file":"flags.js","names":[],"sources":["../../src/cli/flags.ts"],"sourcesContent":["import { Command } from 'commander';\nimport findFilepath from '../fs/findFilepath.js';\nimport { DEFAULT_GIT_REMOTE_NAME } from '../utils/constants.js';\n\nconst DEFAULT_TIMEOUT = 900;\n\nexport function attachSharedFlags(command: Command) {\n command\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option('--api-key <key>', 'API key for General Translation cloud service')\n .option('--project-id <id>', 'General Translation project ID');\n return command;\n}\n\nexport function attachTranslateFlags(command: Command) {\n attachSharedFlags(command)\n .option('--version-id <id>', 'General Translation version ID')\n .option(\n '--default-language, --default-locale <locale>',\n 'Default locale (e.g., en)'\n )\n .option(\n '--new, --locales <locales...>',\n 'Space-separated list of locales (e.g., en fr es)'\n )\n .option(\n '--dry-run',\n 'Dry run, do not send updates to the General Translation API',\n false\n )\n .option(\n '--timeout <seconds>',\n 'Translation wait timeout in seconds',\n (value) => {\n const parsedValue = parseInt(value, 10);\n if (isNaN(parsedValue)) {\n throw new Error('Invalid timeout: not a number.');\n }\n if (parsedValue < 0) {\n throw new Error('Invalid timeout: must be a positive number.');\n }\n return parsedValue;\n },\n DEFAULT_TIMEOUT\n )\n .option(\n '--save-local',\n 'Detect and save local edits before enqueuing translations',\n true\n )\n .option(\n '--no-save-local',\n 'Skip detecting and saving local edits before enqueuing translations'\n )\n .option('--publish', 'Publish translations to the CDN', false)\n .option(\n '--experimental-localize-static-urls',\n 'Triggering this will run a script after the cli tool that localizes all urls in content files. Currently only supported for md and mdx files.',\n false\n )\n .option(\n '--experimental-hide-default-locale',\n 'When localizing static locales, hide the default locale from the path',\n false\n )\n .option(\n '--experimental-flatten-json-files',\n 'Triggering this will flatten the json files into a single file. This is useful for projects that have a lot of json files.',\n false\n )\n .option(\n '--experimental-localize-static-imports',\n 'Triggering this will run a script after the cli tool that localizes all static imports in content files. Currently only supported for md and mdx files.',\n false\n )\n .option(\n '--experimental-localize-relative-assets',\n 'Triggering this will rewrite relative image asset URLs in translated md/mdx files to valid paths.',\n false\n )\n .option(\n '--force',\n 'Force a retranslation, invalidating all existing cached translations if they exist.',\n false\n )\n .option(\n '--force-download',\n 'Force download and overwrite local files, bypassing gt-lock.json checks.',\n false\n )\n .option(\n '--omit-config-ids',\n 'Do not write _versionId or _branchId to gt.config.json'\n )\n .option(\n '--experimental-clear-locale-dirs',\n 'Clear locale directories before downloading new translations',\n false\n )\n .option(\n '--branch <branch>',\n 'Specify a custom branch to use for translations'\n )\n .option(\n '--disable-branch-detection',\n 'Disable additional branch detection and optimizations and use the manually specified branch',\n false\n )\n .option('--enable-branching', 'Enable branching for the project')\n .option(\n '--remote-name <name>',\n 'Specify a custom remote name to use for branch detection',\n DEFAULT_GIT_REMOTE_NAME\n )\n .option(\n '--tag [value]',\n 'Tag this translation run (auto-resolves from git if no value provided)'\n )\n .option(\n '-m, --message <message>',\n 'Message to attach to the translation tag'\n );\n return command;\n}\n\n/**\n * Attaches flags necessary for parsing inline content\n * @param command - The command to attach the flags to\n * @returns The command with the inline content parsing flags attached\n */\nfunction attachInlineContentParsingFlags(command: Command) {\n return command\n .option(\n '--tsconfig, --jsconfig <path>',\n 'Path to custom jsconfig or tsconfig file',\n findFilepath(['./tsconfig.json', './jsconfig.json'])\n )\n .option('--dictionary <path>', 'Path to dictionary file')\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 '--inline',\n 'Include inline content in translations (e.g., inline jsx translations, inline string translations, etc.)',\n true\n );\n}\n\n/**\n * Attaches flags necessary for validating a project\n * @param command\n * @returns The command with the validate flags attached\n */\nexport function attachValidateFlags(command: Command) {\n return attachInlineContentParsingFlags(\n command.option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n );\n}\n\n/**\n * Attaches flags necessary for translating a project\n * @param command\n * @returns The command with the translate flags attached\n */\nexport function attachInlineTranslateFlags(command: Command) {\n return attachInlineContentParsingFlags(\n command.option(\n '--ignore-errors',\n 'Ignore errors encountered while scanning for inline content',\n false\n )\n );\n}\n"],"mappings":";;;AAIA,MAAM,kBAAkB;AAExB,SAAgB,kBAAkB,SAAkB;AAClD,SACG,OACC,uBACA,sDACA,aAAa,CAAC,iBAAiB,CAAC,CACjC,CACA,OAAO,mBAAmB,gDAAgD,CAC1E,OAAO,qBAAqB,iCAAiC;AAChE,QAAO;;AAGT,SAAgB,qBAAqB,SAAkB;AACrD,mBAAkB,QAAQ,CACvB,OAAO,qBAAqB,iCAAiC,CAC7D,OACC,iDACA,4BACD,CACA,OACC,iCACA,mDACD,CACA,OACC,aACA,+DACA,MACD,CACA,OACC,uBACA,wCACC,UAAU;EACT,MAAM,cAAc,SAAS,OAAO,GAAG;AACvC,MAAI,MAAM,YAAY,CACpB,OAAM,IAAI,MAAM,iCAAiC;AAEnD,MAAI,cAAc,EAChB,OAAM,IAAI,MAAM,8CAA8C;AAEhE,SAAO;IAET,gBACD,CACA,OACC,gBACA,6DACA,KACD,CACA,OACC,mBACA,sEACD,CACA,OAAO,aAAa,mCAAmC,MAAM,CAC7D,OACC,uCACA,iJACA,MACD,CACA,OACC,sCACA,yEACA,MACD,CACA,OACC,qCACA,8HACA,MACD,CACA,OACC,0CACA,2JACA,MACD,CACA,OACC,2CACA,qGACA,MACD,CACA,OACC,WACA,uFACA,MACD,CACA,OACC,oBACA,4EACA,MACD,CACA,OACC,qBACA,yDACD,CACA,OACC,oCACA,gEACA,MACD,CACA,OACC,qBACA,kDACD,CACA,OACC,8BACA,+FACA,MACD,CACA,OAAO,sBAAsB,mCAAmC,CAChE,OACC,wBACA,4DACA,wBACD,CACA,OACC,iBACA,yEACD,CACA,OACC,2BACA,2CACD;AACH,QAAO;;;;;;;AAQT,SAAS,gCAAgC,SAAkB;AACzD,QAAO,QACJ,OACC,iCACA,4CACA,aAAa,CAAC,mBAAmB,kBAAkB,CAAC,CACrD,CACA,OAAO,uBAAuB,0BAA0B,CACxD,OACC,oBACA,0MACD,CACA,OACC,YACA,4GACA,KACD;;;;;;;AAQL,SAAgB,oBAAoB,SAAkB;AACpD,QAAO,gCACL,QAAQ,OACN,uBACA,sDACA,aAAa,CAAC,iBAAiB,CAAC,CACjC,CACF;;;;;;;AAQH,SAAgB,2BAA2B,SAAkB;AAC3D,QAAO,gCACL,QAAQ,OACN,mBACA,+DACA,MACD,CACF"}
1
+ {"version":3,"file":"flags.js","names":[],"sources":["../../src/cli/flags.ts"],"sourcesContent":["import { Command } from 'commander';\nimport findFilepath from '../fs/findFilepath.js';\nimport { DEFAULT_GIT_REMOTE_NAME } from '../utils/constants.js';\n\nconst DEFAULT_TIMEOUT = 900;\n\nexport function attachSharedFlags(command: Command) {\n command\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .option('--api-key <key>', 'API key for General Translation cloud service')\n .option('--project-id <id>', 'General Translation project ID');\n return command;\n}\n\nexport function attachTranslateFlags(command: Command) {\n attachSharedFlags(command)\n .option('--version-id <id>', 'General Translation version ID')\n .option(\n '--default-language, --default-locale <locale>',\n 'Default locale (e.g., en)'\n )\n .option(\n '--new, --locales <locales...>',\n 'Space-separated list of locales (e.g., en fr es)'\n )\n .option(\n '--dry-run',\n 'Dry run, do not send updates to the General Translation API',\n false\n )\n .option(\n '--timeout <seconds>',\n 'Translation wait timeout in seconds',\n (value) => {\n const parsedValue = parseInt(value, 10);\n if (isNaN(parsedValue)) {\n throw new Error('Invalid timeout: not a number.');\n }\n if (parsedValue < 0) {\n throw new Error('Invalid timeout: must be a positive number.');\n }\n return parsedValue;\n },\n DEFAULT_TIMEOUT\n )\n .option(\n '--save-local',\n 'Detect and save local edits before enqueuing translations',\n true\n )\n .option(\n '--no-save-local',\n 'Skip detecting and saving local edits before enqueuing translations'\n )\n .option('--publish', 'Publish translations to the CDN', false)\n .option(\n '--experimental-localize-static-urls',\n 'Triggering this will run a script after the cli tool that localizes all urls in content files. Currently only supported for md and mdx files.',\n false\n )\n .option(\n '--experimental-hide-default-locale',\n 'When localizing static locales, hide the default locale from the path',\n false\n )\n .option(\n '--experimental-flatten-json-files',\n 'Triggering this will flatten the json files into a single file. This is useful for projects that have a lot of json files.',\n false\n )\n .option(\n '--experimental-localize-static-imports',\n 'Triggering this will run a script after the cli tool that localizes all static imports in content files. Currently only supported for md and mdx files.',\n false\n )\n .option(\n '--experimental-localize-relative-assets',\n 'Triggering this will rewrite relative image asset URLs in translated md/mdx files to valid paths.',\n false\n )\n .option(\n '--force',\n 'Force a retranslation, invalidating all existing cached translations if they exist.',\n false\n )\n .option(\n '--force-download',\n 'Force download and overwrite local files, bypassing gt-lock.json checks.',\n false\n )\n .option(\n '--omit-config-ids',\n 'Do not write _versionId or _branchId to gt.config.json'\n )\n .option(\n '--experimental-clear-locale-dirs',\n 'Clear locale directories before downloading new translations',\n false\n )\n .option(\n '--branch <branch>',\n 'Specify a custom branch to use for translations'\n )\n .option(\n '--disable-branch-detection',\n 'Disable additional branch detection and optimizations and use the manually specified branch',\n false\n )\n .option('--enable-branching', 'Enable branching for the project')\n .option(\n '--remote-name <name>',\n 'Specify a custom remote name to use for branch detection',\n DEFAULT_GIT_REMOTE_NAME\n )\n .option(\n '--tag [value]',\n 'Tag this translation run (auto-resolves from git if no value provided)'\n )\n .option(\n '-m, --message <message>',\n 'Message to attach to the translation tag'\n );\n return command;\n}\n\n/**\n * Attaches flags necessary for parsing inline content\n * @param command - The command to attach the flags to\n * @returns The command with the inline content parsing flags attached\n */\nfunction attachInlineContentParsingFlags(\n command: Command,\n sourceHelp?: string\n) {\n return command\n .option(\n '--tsconfig, --jsconfig <path>',\n 'Path to custom jsconfig or tsconfig file',\n findFilepath(['./tsconfig.json', './jsconfig.json'])\n )\n .option('--dictionary <path>', 'Path to dictionary file')\n .option(\n '--src <paths...>',\n sourceHelp ??\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 '--inline',\n 'Include inline content in translations (e.g., inline jsx translations, inline string translations, etc.)',\n true\n );\n}\n\n/**\n * Attaches flags necessary for validating a project\n * @param command\n * @returns The command with the validate flags attached\n */\nexport function attachValidateFlags(command: Command, sourceHelp?: string) {\n return attachInlineContentParsingFlags(\n command.option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n ),\n sourceHelp\n );\n}\n\n/**\n * Attaches flags necessary for translating a project\n * @param command\n * @returns The command with the translate flags attached\n */\nexport function attachInlineTranslateFlags(\n command: Command,\n sourceHelp?: string\n) {\n return attachInlineContentParsingFlags(\n command.option(\n '--ignore-errors',\n 'Ignore errors encountered while scanning for inline content',\n false\n ),\n sourceHelp\n );\n}\n"],"mappings":";;;AAIA,MAAM,kBAAkB;AAExB,SAAgB,kBAAkB,SAAkB;AAClD,SACG,OACC,uBACA,sDACA,aAAa,CAAC,iBAAiB,CAAC,CACjC,CACA,OAAO,mBAAmB,gDAAgD,CAC1E,OAAO,qBAAqB,iCAAiC;AAChE,QAAO;;AAGT,SAAgB,qBAAqB,SAAkB;AACrD,mBAAkB,QAAQ,CACvB,OAAO,qBAAqB,iCAAiC,CAC7D,OACC,iDACA,4BACD,CACA,OACC,iCACA,mDACD,CACA,OACC,aACA,+DACA,MACD,CACA,OACC,uBACA,wCACC,UAAU;EACT,MAAM,cAAc,SAAS,OAAO,GAAG;AACvC,MAAI,MAAM,YAAY,CACpB,OAAM,IAAI,MAAM,iCAAiC;AAEnD,MAAI,cAAc,EAChB,OAAM,IAAI,MAAM,8CAA8C;AAEhE,SAAO;IAET,gBACD,CACA,OACC,gBACA,6DACA,KACD,CACA,OACC,mBACA,sEACD,CACA,OAAO,aAAa,mCAAmC,MAAM,CAC7D,OACC,uCACA,iJACA,MACD,CACA,OACC,sCACA,yEACA,MACD,CACA,OACC,qCACA,8HACA,MACD,CACA,OACC,0CACA,2JACA,MACD,CACA,OACC,2CACA,qGACA,MACD,CACA,OACC,WACA,uFACA,MACD,CACA,OACC,oBACA,4EACA,MACD,CACA,OACC,qBACA,yDACD,CACA,OACC,oCACA,gEACA,MACD,CACA,OACC,qBACA,kDACD,CACA,OACC,8BACA,+FACA,MACD,CACA,OAAO,sBAAsB,mCAAmC,CAChE,OACC,wBACA,4DACA,wBACD,CACA,OACC,iBACA,yEACD,CACA,OACC,2BACA,2CACD;AACH,QAAO;;;;;;;AAQT,SAAS,gCACP,SACA,YACA;AACA,QAAO,QACJ,OACC,iCACA,4CACA,aAAa,CAAC,mBAAmB,kBAAkB,CAAC,CACrD,CACA,OAAO,uBAAuB,0BAA0B,CACxD,OACC,oBACA,cACE,0MACH,CACA,OACC,YACA,4GACA,KACD;;;;;;;AAQL,SAAgB,oBAAoB,SAAkB,YAAqB;AACzE,QAAO,gCACL,QAAQ,OACN,uBACA,sDACA,aAAa,CAAC,iBAAiB,CAAC,CACjC,EACD,WACD;;;;;;;AAQH,SAAgB,2BACd,SACA,YACA;AACA,QAAO,gCACL,QAAQ,OACN,mBACA,+DACA,MACD,EACD,WACD"}
@@ -6,8 +6,12 @@ import { InlineLibrary } from '../types/libraries.js';
6
6
  * Stand in for a CLI tool that does any sort of inline content translations
7
7
  */
8
8
  export declare class InlineCLI extends BaseCLI {
9
- constructor(command: Command, library: InlineLibrary, additionalModules?: SupportedLibraries[]);
9
+ constructor(command: Command, library: SupportedLibraries, additionalModules?: SupportedLibraries[]);
10
10
  init(): void;
11
+ /** Allows framework adapters to describe their own default source scope. */
12
+ protected getInlineSourceHelp(): string | undefined;
13
+ /** Returns the inline parser used by generate and targeted validation. */
14
+ protected getInlineLibrary(): InlineLibrary;
11
15
  protected setupStageCommand(): void;
12
16
  protected setupTranslateCommand(): void;
13
17
  protected setupValidateCommand(): void;
@@ -1,8 +1,8 @@
1
1
  import { logger } from "../console/logger.js";
2
+ import "../types/libraries.js";
2
3
  import { displayHeader, exitSync } from "../console/logging.js";
3
4
  import loadJSON from "../fs/loadJSON.js";
4
5
  import { noFilesError } from "../console/index.js";
5
- import "../types/libraries.js";
6
6
  import { resolveLocaleFiles } from "../fs/config/parseFilesConfig.js";
7
7
  import { generateSettings } from "../config/generateSettings.js";
8
8
  import { validateProject } from "../translation/validate.js";
@@ -26,29 +26,35 @@ var InlineCLI = class extends BaseCLI {
26
26
  this.setupDownloadCommand();
27
27
  this.setupEnqueueCommand();
28
28
  }
29
+ /** Allows framework adapters to describe their own default source scope. */
30
+ getInlineSourceHelp() {}
31
+ /** Returns the inline parser used by generate and targeted validation. */
32
+ getInlineLibrary() {
33
+ return fallbackToGtReact(this.library);
34
+ }
29
35
  setupStageCommand() {
30
- attachInlineTranslateFlags(attachTranslateFlags(this.program.command("stage").description("Submits the project to the General Translation API for translation. Translations created using this command will require human approval."))).action(async (options) => {
36
+ attachInlineTranslateFlags(attachTranslateFlags(this.program.command("stage").description("Submits the project to the General Translation API for translation. Translations created using this command will require human approval.")), this.getInlineSourceHelp()).action(async (options) => {
31
37
  displayHeader("Staging project for translation with approval required...");
32
38
  await this.handleStage(options);
33
39
  logger.endCommand("Done!");
34
40
  });
35
41
  }
36
42
  setupTranslateCommand() {
37
- attachInlineTranslateFlags(attachTranslateFlags(this.program.command("translate").description("Scans the project for a dictionary and inline translations and sends the updates to the General Translation API for translation."))).action(async (options) => {
43
+ attachInlineTranslateFlags(attachTranslateFlags(this.program.command("translate").description("Scans the project for a dictionary and inline translations and sends the updates to the General Translation API for translation.")), this.getInlineSourceHelp()).action(async (options) => {
38
44
  displayHeader("Translating project...");
39
45
  await this.handleTranslate(options);
40
46
  logger.endCommand("Done!");
41
47
  });
42
48
  }
43
49
  setupValidateCommand() {
44
- attachValidateFlags(this.program.command("validate [files...]").description("Scans the project for a dictionary and/or inline content and validates the project for errors.")).action(async (files, options) => {
50
+ attachValidateFlags(this.program.command("validate [files...]").description("Scans the project for a dictionary and/or inline content and validates the project for errors."), this.getInlineSourceHelp()).action(async (files, options) => {
45
51
  logger.startCommand("Validating project...");
46
52
  await this.handleValidate(options, files);
47
53
  logger.endCommand("Done!");
48
54
  });
49
55
  }
50
56
  setupGenerateSourceCommand() {
51
- attachInlineTranslateFlags(attachTranslateFlags(this.program.command("generate").description("Generate a translation file for the source locale. This command should be used if you are handling your own translations."))).action(async (initOptions) => {
57
+ attachInlineTranslateFlags(attachTranslateFlags(this.program.command("generate").description("Generate a translation file for the source locale. This command should be used if you are handling your own translations.")), this.getInlineSourceHelp()).action(async (initOptions) => {
52
58
  displayHeader("Generating source templates...");
53
59
  await this.handleGenerateSourceCommand(initOptions);
54
60
  logger.endCommand("Done!");
@@ -56,7 +62,7 @@ var InlineCLI = class extends BaseCLI {
56
62
  }
57
63
  async handleGenerateSourceCommand(initOptions) {
58
64
  const settings = await generateSettings(initOptions, void 0, { requireConfig: true });
59
- const updates = await aggregateInlineTranslations(initOptions, settings, fallbackToGtReact(this.library));
65
+ const updates = await aggregateInlineTranslations(initOptions, settings, this.getInlineLibrary());
60
66
  const newData = {};
61
67
  for (const update of updates) {
62
68
  const { source, metadata } = update;
@@ -91,7 +97,7 @@ var InlineCLI = class extends BaseCLI {
91
97
  ...initOptions,
92
98
  ...settings
93
99
  };
94
- const pkg = fallbackToGtReact(this.library);
100
+ const pkg = this.getInlineLibrary();
95
101
  if (files && files.length > 0) await validateProject(options, pkg, files);
96
102
  else await validateProject(options, pkg);
97
103
  }
@@ -103,7 +109,8 @@ function fallbackToGtReact(library) {
103
109
  "gt-react-native",
104
110
  "gt-tanstack-start",
105
111
  "gt-flask",
106
- "gt-fastapi"
112
+ "gt-fastapi",
113
+ "gt-vue"
107
114
  ].includes(library) ? library : "gt-react";
108
115
  }
109
116
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"inline.js","names":[],"sources":["../../src/cli/inline.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { BaseCLI } from './base.js';\nimport { SupportedLibraries, TranslateFlags, Options } from '../types/index.js';\nimport {\n attachInlineTranslateFlags,\n attachTranslateFlags,\n attachValidateFlags,\n} from './flags.js';\nimport { displayHeader, exitSync } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { resolveLocaleFiles } from '../fs/config/parseFilesConfig.js';\nimport { noFilesError } from '../console/index.js';\nimport { saveJSON } from '../fs/saveJSON.js';\nimport loadJSON from '../fs/loadJSON.js';\nimport { generateSettings } from '../config/generateSettings.js';\nimport { aggregateInlineTranslations } from '../translation/stage.js';\nimport { validateProject } from '../translation/validate.js';\nimport { Libraries, InlineLibrary } from '../types/libraries.js';\n\n/**\n * Stand in for a CLI tool that does any sort of inline content translations\n */\nexport class InlineCLI extends BaseCLI {\n constructor(\n command: Command,\n library: InlineLibrary,\n additionalModules?: SupportedLibraries[]\n ) {\n super(command, library, additionalModules);\n }\n public init() {\n this.setupStageCommand();\n this.setupTranslateCommand();\n this.setupGenerateSourceCommand();\n this.setupValidateCommand();\n this.setupDownloadCommand();\n this.setupEnqueueCommand();\n }\n\n protected setupStageCommand(): void {\n attachInlineTranslateFlags(\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 )\n ).action(async (options: TranslateFlags) => {\n displayHeader(\n 'Staging project for translation with approval required...'\n );\n await this.handleStage(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupTranslateCommand(): void {\n attachInlineTranslateFlags(\n attachTranslateFlags(\n this.program\n .command('translate')\n .description(\n 'Scans the project for a dictionary and inline translations and sends the updates to the General Translation API for translation.'\n )\n )\n ).action(async (options: TranslateFlags) => {\n displayHeader('Translating project...');\n await this.handleTranslate(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupValidateCommand(): void {\n attachValidateFlags(\n this.program\n .command('validate [files...]')\n .description(\n 'Scans the project for a dictionary and/or inline content and validates the project for errors.'\n )\n ).action(async (files: string[], options: Options) => {\n // startCommand here since we don't want to show the ascii title; it\n // renders the same intro while honoring --quiet.\n logger.startCommand('Validating project...');\n await this.handleValidate(options, files);\n logger.endCommand('Done!');\n });\n }\n\n protected setupGenerateSourceCommand(): void {\n attachInlineTranslateFlags(\n attachTranslateFlags(\n this.program\n .command('generate')\n .description(\n 'Generate a translation file for the source locale. This command should be used if you are handling your own translations.'\n )\n )\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Generating source templates...');\n await this.handleGenerateSourceCommand(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected async handleGenerateSourceCommand(\n initOptions: TranslateFlags\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n const updates = await aggregateInlineTranslations(\n initOptions,\n settings,\n fallbackToGtReact(this.library)\n );\n\n // Convert updates to the proper data format\n const newData: Record<string, unknown> = {};\n for (const update of updates) {\n const { source, metadata } = update;\n const { hash } = metadata;\n if (hash) {\n newData[hash] = source;\n }\n }\n\n // Save source file if files.json is provided\n if (settings.files && settings.files.placeholderPaths.gt) {\n const translationFiles = resolveLocaleFiles(\n settings.files.placeholderPaths,\n settings.defaultLocale\n );\n if (!translationFiles.gt) {\n logger.error(noFilesError);\n exitSync(1);\n }\n await saveJSON(translationFiles.gt, newData);\n logger.step('Source file saved successfully!');\n // Also save translations (after merging with existing translations)\n for (const locale of settings.locales) {\n const translationsFile = resolveLocaleFiles(\n settings.files.placeholderPaths,\n locale\n );\n\n if (!translationsFile.gt) {\n continue;\n }\n const existingTranslations = loadJSON(translationsFile.gt);\n const mergedTranslations = {\n ...newData,\n ...existingTranslations,\n };\n // Filter out keys that don't exist in newData\n const filteredTranslations = Object.fromEntries(\n Object.entries(mergedTranslations).filter(([key]) => newData[key])\n );\n await saveJSON(translationsFile.gt, filteredTranslations);\n }\n logger.step('Merged translations successfully!');\n }\n }\n\n protected async handleValidate(\n initOptions: Options,\n files?: string[]\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // First run the base class's handleTranslate method\n const options = { ...initOptions, ...settings };\n\n // Fallback to gt-react\n const pkg = fallbackToGtReact(this.library);\n\n if (files && files.length > 0) {\n // Validate specific files using createInlineUpdates\n await validateProject(options, pkg, files);\n } else {\n // Validate whole project as before\n await validateProject(options, pkg);\n }\n }\n}\n\nfunction fallbackToGtReact(library: SupportedLibraries): InlineLibrary {\n return [\n Libraries.GT_NEXT,\n Libraries.GT_NODE,\n Libraries.GT_REACT_NATIVE,\n Libraries.GT_TANSTACK_START,\n Libraries.GT_FLASK,\n Libraries.GT_FASTAPI,\n ].includes(library as Libraries)\n ? (library as\n | typeof Libraries.GT_NEXT\n | typeof Libraries.GT_NODE\n | typeof Libraries.GT_REACT_NATIVE\n | typeof Libraries.GT_TANSTACK_START\n | typeof Libraries.GT_FLASK\n | typeof Libraries.GT_FASTAPI)\n : Libraries.GT_REACT;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"inline.js","names":[],"sources":["../../src/cli/inline.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { BaseCLI } from './base.js';\nimport { SupportedLibraries, TranslateFlags, Options } from '../types/index.js';\nimport {\n attachInlineTranslateFlags,\n attachTranslateFlags,\n attachValidateFlags,\n} from './flags.js';\nimport { displayHeader, exitSync } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { resolveLocaleFiles } from '../fs/config/parseFilesConfig.js';\nimport { noFilesError } from '../console/index.js';\nimport { saveJSON } from '../fs/saveJSON.js';\nimport loadJSON from '../fs/loadJSON.js';\nimport { generateSettings } from '../config/generateSettings.js';\nimport { aggregateInlineTranslations } from '../translation/stage.js';\nimport { validateProject } from '../translation/validate.js';\nimport { Libraries, InlineLibrary } from '../types/libraries.js';\n\n/**\n * Stand in for a CLI tool that does any sort of inline content translations\n */\nexport class InlineCLI extends BaseCLI {\n constructor(\n command: Command,\n library: SupportedLibraries,\n additionalModules?: SupportedLibraries[]\n ) {\n super(command, library, additionalModules);\n }\n public init() {\n this.setupStageCommand();\n this.setupTranslateCommand();\n this.setupGenerateSourceCommand();\n this.setupValidateCommand();\n this.setupDownloadCommand();\n this.setupEnqueueCommand();\n }\n\n /** Allows framework adapters to describe their own default source scope. */\n protected getInlineSourceHelp(): string | undefined {\n return undefined;\n }\n\n /** Returns the inline parser used by generate and targeted validation. */\n protected getInlineLibrary(): InlineLibrary {\n return fallbackToGtReact(this.library);\n }\n\n protected setupStageCommand(): void {\n attachInlineTranslateFlags(\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 ),\n this.getInlineSourceHelp()\n ).action(async (options: TranslateFlags) => {\n displayHeader(\n 'Staging project for translation with approval required...'\n );\n await this.handleStage(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupTranslateCommand(): void {\n attachInlineTranslateFlags(\n attachTranslateFlags(\n this.program\n .command('translate')\n .description(\n 'Scans the project for a dictionary and inline translations and sends the updates to the General Translation API for translation.'\n )\n ),\n this.getInlineSourceHelp()\n ).action(async (options: TranslateFlags) => {\n displayHeader('Translating project...');\n await this.handleTranslate(options);\n logger.endCommand('Done!');\n });\n }\n\n protected setupValidateCommand(): void {\n attachValidateFlags(\n this.program\n .command('validate [files...]')\n .description(\n 'Scans the project for a dictionary and/or inline content and validates the project for errors.'\n ),\n this.getInlineSourceHelp()\n ).action(async (files: string[], options: Options) => {\n // startCommand here since we don't want to show the ascii title; it\n // renders the same intro while honoring --quiet.\n logger.startCommand('Validating project...');\n await this.handleValidate(options, files);\n logger.endCommand('Done!');\n });\n }\n\n protected setupGenerateSourceCommand(): void {\n attachInlineTranslateFlags(\n attachTranslateFlags(\n this.program\n .command('generate')\n .description(\n 'Generate a translation file for the source locale. This command should be used if you are handling your own translations.'\n )\n ),\n this.getInlineSourceHelp()\n ).action(async (initOptions: TranslateFlags) => {\n displayHeader('Generating source templates...');\n await this.handleGenerateSourceCommand(initOptions);\n logger.endCommand('Done!');\n });\n }\n\n protected async handleGenerateSourceCommand(\n initOptions: TranslateFlags\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n const updates = await aggregateInlineTranslations(\n initOptions,\n settings,\n this.getInlineLibrary()\n );\n\n // Convert updates to the proper data format\n const newData: Record<string, unknown> = {};\n for (const update of updates) {\n const { source, metadata } = update;\n const { hash } = metadata;\n if (hash) {\n newData[hash] = source;\n }\n }\n\n // Save source file if files.json is provided\n if (settings.files && settings.files.placeholderPaths.gt) {\n const translationFiles = resolveLocaleFiles(\n settings.files.placeholderPaths,\n settings.defaultLocale\n );\n if (!translationFiles.gt) {\n logger.error(noFilesError);\n exitSync(1);\n }\n await saveJSON(translationFiles.gt, newData);\n logger.step('Source file saved successfully!');\n // Also save translations (after merging with existing translations)\n for (const locale of settings.locales) {\n const translationsFile = resolveLocaleFiles(\n settings.files.placeholderPaths,\n locale\n );\n\n if (!translationsFile.gt) {\n continue;\n }\n const existingTranslations = loadJSON(translationsFile.gt);\n const mergedTranslations = {\n ...newData,\n ...existingTranslations,\n };\n // Filter out keys that don't exist in newData\n const filteredTranslations = Object.fromEntries(\n Object.entries(mergedTranslations).filter(([key]) => newData[key])\n );\n await saveJSON(translationsFile.gt, filteredTranslations);\n }\n logger.step('Merged translations successfully!');\n }\n }\n\n protected async handleValidate(\n initOptions: Options,\n files?: string[]\n ): Promise<void> {\n const settings = await generateSettings(initOptions, undefined, {\n requireConfig: true,\n });\n\n // First run the base class's handleTranslate method\n const options = { ...initOptions, ...settings };\n\n // Fallback to gt-react\n const pkg = this.getInlineLibrary();\n\n if (files && files.length > 0) {\n // Validate specific files using createInlineUpdates\n await validateProject(options, pkg, files);\n } else {\n // Validate whole project as before\n await validateProject(options, pkg);\n }\n }\n}\n\nfunction fallbackToGtReact(library: SupportedLibraries): InlineLibrary {\n return [\n Libraries.GT_NEXT,\n Libraries.GT_NODE,\n Libraries.GT_REACT_NATIVE,\n Libraries.GT_TANSTACK_START,\n Libraries.GT_FLASK,\n Libraries.GT_FASTAPI,\n Libraries.GT_VUE,\n ].includes(library as Libraries)\n ? (library as\n | typeof Libraries.GT_NEXT\n | typeof Libraries.GT_NODE\n | typeof Libraries.GT_REACT_NATIVE\n | typeof Libraries.GT_TANSTACK_START\n | typeof Libraries.GT_FLASK\n | typeof Libraries.GT_FASTAPI\n | typeof Libraries.GT_VUE)\n : Libraries.GT_REACT;\n}\n"],"mappings":"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"}
package/dist/cli/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { logger } from "../console/logger.js";
2
- import { displayHeader, exitSync, promptConfirm } from "../console/logging.js";
3
2
  import { REACT_LIBRARIES } from "../types/libraries.js";
3
+ import { displayHeader, exitSync, promptConfirm } from "../console/logging.js";
4
4
  import { generateSettings } from "../config/generateSettings.js";
5
5
  import { formatFiles } from "../hooks/postProcess.js";
6
6
  import { attachInlineTranslateFlags, attachTranslateFlags } from "./flags.js";
@@ -0,0 +1,17 @@
1
+ import type { Command } from 'commander';
2
+ import type { SupportedLibraries } from '../types/index.js';
3
+ import { Libraries } from '../types/libraries.js';
4
+ import { InlineCLI } from './inline.js';
5
+ /** CLI commands for an application whose selected inline runtime is gt-vue. */
6
+ export declare class VueCLI extends InlineCLI {
7
+ constructor(command: Command, additionalModules?: SupportedLibraries[], fileLibrary?: SupportedLibraries);
8
+ init(): void;
9
+ /** Uses Vue-specific default source guidance on inherited inline commands. */
10
+ protected getInlineSourceHelp(): string;
11
+ /** Mixed file projects still use Vue for generate and validation. */
12
+ protected getInlineLibrary(): typeof Libraries.GT_VUE;
13
+ /** Configure Vue without entering the React application setup wizard. */
14
+ protected setupInitCommand(): void;
15
+ /** Uploads Vue inline sources with the same targeting flags as extraction. */
16
+ protected setupSetupProjectCommand(): void;
17
+ }
@@ -0,0 +1,42 @@
1
+ import { logger } from "../console/logger.js";
2
+ import "../types/libraries.js";
3
+ import { displayHeader } from "../console/logging.js";
4
+ import findFilepath from "../fs/findFilepath.js";
5
+ import { attachInlineTranslateFlags, attachTranslateFlags } from "./flags.js";
6
+ import { InlineCLI } from "./inline.js";
7
+ //#region src/cli/vue.ts
8
+ const VUE_SOURCE_HELP = "Space-separated list of glob patterns containing the app's Vue source code; defaults cover root SFCs and conventional Vue and Nuxt directories";
9
+ /** CLI commands for an application whose selected inline runtime is gt-vue. */
10
+ var VueCLI = class extends InlineCLI {
11
+ constructor(command, additionalModules, fileLibrary = "gt-vue") {
12
+ super(command, fileLibrary, additionalModules);
13
+ }
14
+ init() {
15
+ this.setupSetupProjectCommand();
16
+ super.init();
17
+ }
18
+ /** Uses Vue-specific default source guidance on inherited inline commands. */
19
+ getInlineSourceHelp() {
20
+ return VUE_SOURCE_HELP;
21
+ }
22
+ /** Mixed file projects still use Vue for generate and validation. */
23
+ getInlineLibrary() {
24
+ return "gt-vue";
25
+ }
26
+ /** Configure Vue without entering the React application setup wizard. */
27
+ setupInitCommand() {
28
+ this.program.command("init").description("Configure a gt-vue project for General Translation without modifying application source").option("--src <paths...>", VUE_SOURCE_HELP).option("-c, --config <path>", "Filepath to config file, by default gt.config.json", findFilepath(["gt.config.json"])).action((options) => this.handleConfigureCommand(options));
29
+ }
30
+ /** Uploads Vue inline sources with the same targeting flags as extraction. */
31
+ setupSetupProjectCommand() {
32
+ attachInlineTranslateFlags(attachTranslateFlags(this.program.command("setup").description("Upload source files and setup the project for translation")), this.getInlineSourceHelp()).action(async (options) => {
33
+ displayHeader("Uploading source files and setting up project...");
34
+ await this.handleSetupProject(options);
35
+ logger.endCommand("Done!");
36
+ });
37
+ }
38
+ };
39
+ //#endregion
40
+ export { VueCLI };
41
+
42
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.js","names":[],"sources":["../../src/cli/vue.ts"],"sourcesContent":["import type { Command } from 'commander';\nimport type {\n SetupOptions,\n SupportedLibraries,\n TranslateFlags,\n} from '../types/index.js';\nimport { Libraries } from '../types/libraries.js';\nimport findFilepath from '../fs/findFilepath.js';\nimport { displayHeader } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { attachInlineTranslateFlags, attachTranslateFlags } from './flags.js';\nimport { InlineCLI } from './inline.js';\n\nconst VUE_SOURCE_HELP =\n \"Space-separated list of glob patterns containing the app's Vue source code; defaults cover root SFCs and conventional Vue and Nuxt directories\";\n\n/** CLI commands for an application whose selected inline runtime is gt-vue. */\nexport class VueCLI extends InlineCLI {\n public constructor(\n command: Command,\n additionalModules?: SupportedLibraries[],\n fileLibrary: SupportedLibraries = Libraries.GT_VUE\n ) {\n super(command, fileLibrary, additionalModules);\n }\n\n public override init(): void {\n this.setupSetupProjectCommand();\n super.init();\n }\n\n /** Uses Vue-specific default source guidance on inherited inline commands. */\n protected override getInlineSourceHelp(): string {\n return VUE_SOURCE_HELP;\n }\n\n /** Mixed file projects still use Vue for generate and validation. */\n protected override getInlineLibrary(): typeof Libraries.GT_VUE {\n return Libraries.GT_VUE;\n }\n\n /** Configure Vue without entering the React application setup wizard. */\n protected override setupInitCommand(): void {\n this.program\n .command('init')\n .description(\n 'Configure a gt-vue project for General Translation without modifying application source'\n )\n .option('--src <paths...>', VUE_SOURCE_HELP)\n .option(\n '-c, --config <path>',\n 'Filepath to config file, by default gt.config.json',\n findFilepath(['gt.config.json'])\n )\n .action((options: SetupOptions) => this.handleConfigureCommand(options));\n }\n\n /** Uploads Vue inline sources with the same targeting flags as extraction. */\n protected override setupSetupProjectCommand(): void {\n attachInlineTranslateFlags(\n attachTranslateFlags(\n this.program\n .command('setup')\n .description(\n 'Upload source files and setup the project for translation'\n )\n ),\n this.getInlineSourceHelp()\n ).action(async (options: TranslateFlags) => {\n displayHeader('Uploading source files and setting up project...');\n await this.handleSetupProject(options);\n logger.endCommand('Done!');\n });\n }\n}\n"],"mappings":";;;;;;;AAaA,MAAM,kBACJ;;AAGF,IAAa,SAAb,cAA4B,UAAU;CACpC,YACE,SACA,mBACA,cAAA,UACA;AACA,QAAM,SAAS,aAAa,kBAAkB;;CAGhD,OAA6B;AAC3B,OAAK,0BAA0B;AAC/B,QAAM,MAAM;;;CAId,sBAAiD;AAC/C,SAAO;;;CAIT,mBAA+D;AAC7D,SAAA;;;CAIF,mBAA4C;AAC1C,OAAK,QACF,QAAQ,OAAO,CACf,YACC,0FACD,CACA,OAAO,oBAAoB,gBAAgB,CAC3C,OACC,uBACA,sDACA,aAAa,CAAC,iBAAiB,CAAC,CACjC,CACA,QAAQ,YAA0B,KAAK,uBAAuB,QAAQ,CAAC;;;CAI5E,2BAAoD;AAClD,6BACE,qBACE,KAAK,QACF,QAAQ,QAAQ,CAChB,YACC,4DACD,CACJ,EACD,KAAK,qBAAqB,CAC3B,CAAC,OAAO,OAAO,YAA4B;AAC1C,iBAAc,mDAAmD;AACjE,SAAM,KAAK,mBAAmB,QAAQ;AACtC,UAAO,WAAW,QAAQ;IAC1B"}
@@ -1,4 +1,5 @@
1
1
  import { FileToUpload } from 'generaltranslation/types';
2
+ import { type InlineLibrary } from '../types/libraries.js';
2
3
  /**
3
4
  * Strip ANSI escape codes from a string (e.g., chalk color codes)
4
5
  */
@@ -63,4 +64,4 @@ export declare function warnDeprecatedField(deprecatedField: string, replacement
63
64
  /**
64
65
  * Helper: Log all collected files
65
66
  */
66
- export declare function logCollectedFiles(files: Pick<FileToUpload, 'fileName'>[], reactComponents?: number): void;
67
+ export declare function logCollectedFiles(files: Pick<FileToUpload, 'fileName'>[], inlineComponents?: number, inlineLibrary?: InlineLibrary): void;
@@ -3,6 +3,7 @@ import { logger } from "./logger.js";
3
3
  import { getCLIVersion } from "../utils/packageJson.js";
4
4
  import "../utils/constants.js";
5
5
  import { parseLocaleList, validateLocale, validateLocaleList } from "./promptParsing.js";
6
+ import { getInlineElementsLabel } from "../types/libraries.js";
6
7
  import { cancel, confirm, isCancel, multiselect, select, text } from "@clack/prompts";
7
8
  import chalk from "chalk";
8
9
  //#region src/console/logging.ts
@@ -210,9 +211,10 @@ function warnDeprecatedField(deprecatedField, replacement) {
210
211
  /**
211
212
  * Helper: Log all collected files
212
213
  */
213
- function logCollectedFiles(files, reactComponents) {
214
+ function logCollectedFiles(files, inlineComponents, inlineLibrary) {
215
+ const elementLabel = getInlineElementsLabel(inlineLibrary);
214
216
  logger.message(chalk.cyan("Files found in project:") + "\n" + files.map((file) => {
215
- if (file.fileName === "__INTERNAL_GT_TEMPLATE_NAME__") return `- <React Elements>${reactComponents ? ` (${reactComponents})` : ""}`;
217
+ if (file.fileName === "__INTERNAL_GT_TEMPLATE_NAME__") return `- <${elementLabel}>${inlineComponents ? ` (${inlineComponents})` : ""}`;
216
218
  return `- ${file.fileName}`;
217
219
  }).join("\n"));
218
220
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","names":[],"sources":["../../src/console/logging.ts"],"sourcesContent":["import {\n text,\n select,\n confirm,\n isCancel,\n cancel,\n multiselect,\n} from '@clack/prompts';\nimport type { Option } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { getCLIVersion } from '../utils/packageJson.js';\nimport { logger } from './logger.js';\nimport { TEMPLATE_FILE_NAME } from '../utils/constants.js';\nimport { FileToUpload } from 'generaltranslation/types';\nimport { endTerminalSession, shouldUseInkPrompts } from './terminalSession.js';\nimport {\n parseLocaleList,\n validateLocale,\n validateLocaleList,\n} from './promptParsing.js';\n\nfunction cancelPromptAndExit(message: string): never {\n endTerminalSession();\n cancel(message);\n return exitSync(0);\n}\n\nasync function loadInkPrompts() {\n return import('./inkPrompts.js');\n}\n\nasync function runInkPrompt<T>(\n prompt: (prompts: Awaited<ReturnType<typeof loadInkPrompts>>) => Promise<{\n value?: T;\n cancelled: boolean;\n }>,\n cancelMessage = 'Operation cancelled'\n) {\n const result = await prompt(await loadInkPrompts());\n if (result.cancelled) {\n return cancelPromptAndExit(cancelMessage);\n }\n return result.value;\n}\n\n/**\n * Strip ANSI escape codes from a string (e.g., chalk color codes)\n */\nexport function stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex, no-useless-escape\n return str.replace(/\\x1B\\[[0-9;]*m/g, '');\n}\n\nexport function logErrorAndExit(message: string): never {\n logger.error(message);\n return exitSync(1);\n}\n\nexport function exitSync(code: number): never {\n // Flush logs before exit\n logger.flush();\n process.exit(code);\n}\n\n// GT specific logging\nexport function displayHeader(introString?: string) {\n // The ASCII banner is pure chatter and writes to console directly, bypassing\n // the logger, so gate it here to honor --quiet. startCommand stays outside\n // the gate: it is quiet-aware itself and must still run so the file log\n // gets its [START] marker.\n if (!logger.isQuiet()) {\n displayAsciiTitle();\n displayInitializingText();\n }\n\n if (introString) {\n logger.startCommand(introString);\n }\n}\n\nfunction displayAsciiTitle() {\n // eslint-disable-next-line no-console\n console.log(\n chalk.cyan(\n `\\n @@@@@@@@@@@@@@@@@@@@@@\n @@ @@@@@@@@@@@@ @@@@@@@\n @@ @@@ @ @\n@@ @@ @ @\n@@ @ @@@@@ @ @\n@@ @@ @@@ @ @ @\n @@ @@ @ @ @ @\n @@ @@@@@@@ @ @ @\n @@@@@@@@@ @ @`\n )\n );\n}\n\nfunction displayInitializingText() {\n const version = getCLIVersion();\n // eslint-disable-next-line no-console\n console.log(\n `\\n${chalk.bold.blue('General Translation, Inc.')}\n${chalk.dim('https://generaltranslation.com/docs')}\n${chalk.dim(`CLI Version: ${version}\\n`)}`\n );\n}\n\nexport function displayProjectId(projectId: string) {\n logger.message(\n chalk.dim(`Project ID: ${chalk.bold(projectId)}`),\n chalk.cyan('~')\n );\n}\n\nexport function displayResolvedPaths(resolvedPaths: [string, string][]) {\n const paths = resolvedPaths.map(([key, resolvedPath]) => {\n return chalk.dim(`'${chalk.white(key)}' → '${chalk.green(resolvedPath)}'`);\n });\n logger.step(`Resolved path aliases:\\n${paths.join('\\n')}`);\n}\n\nexport function displayCreatedConfigFile(configFilepath: string) {\n logger.step(`Created config file ${chalk.cyan(configFilepath)}`);\n}\n\nexport function displayUpdatedConfigFile(configFilepath: string) {\n logger.success(`Updated config file ${chalk.cyan(configFilepath)}`);\n}\n\nexport function displayUpdatedVersionsFile(versionFilepath: string) {\n logger.success(`Updated versions file ${chalk.cyan(versionFilepath)}`);\n}\n\n// Input prompts\nexport async function promptText({\n message,\n defaultValue,\n validate,\n}: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => boolean | string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptText({ message, defaultValue, validate })\n )) ?? ''\n );\n }\n\n const result = await text({\n message,\n placeholder: defaultValue,\n validate: validate\n ? (value) => {\n const validation = validate(value || '');\n return validation === true ? undefined : validation.toString();\n }\n : undefined,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result;\n}\n\nexport async function promptLocale({\n message,\n defaultValue,\n}: {\n message: string;\n defaultValue?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptLocale({ message, defaultValue })\n )) ?? ''\n );\n }\n\n return promptText({\n message,\n defaultValue,\n validate: validateLocale,\n });\n}\n\nexport async function promptLocaleList({\n message,\n defaultValue,\n required = true,\n}: {\n message: string;\n defaultValue?: string[];\n required?: boolean;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string[]>((prompts) =>\n prompts.inkPromptLocaleMulti({\n message,\n defaultValue,\n required,\n })\n )) ?? []\n );\n }\n\n return promptText({\n message,\n defaultValue: defaultValue?.join(' '),\n validate: validateLocaleList,\n }).then(parseLocaleList);\n}\n\nexport async function promptGlobPatterns({\n label,\n message,\n defaultValue,\n}: {\n label: string;\n message: string;\n defaultValue?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptGlob({ label, message, defaultValue })\n )) ?? ''\n );\n }\n\n return promptText({\n message,\n defaultValue,\n });\n}\n\nexport async function promptSelect<T>({\n message,\n options,\n defaultValue,\n}: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n defaultValue?: T;\n}) {\n if (shouldUseInkPrompts()) {\n return (await runInkPrompt<T>((prompts) =>\n prompts.inkPromptSelect({ message, options, defaultValue })\n )) as T;\n }\n\n // Convert options to the format expected by clack\n const clackOptions = options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })) as Option<T>[];\n\n const result = await select({\n message,\n options: clackOptions,\n initialValue: defaultValue,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result as T;\n}\n\nexport async function promptMultiSelect<T extends string>({\n message,\n options,\n required = true,\n}: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n required?: boolean;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<Array<T>>((prompts) =>\n prompts.inkPromptMultiSelect({\n message,\n options,\n required,\n })\n )) ?? []\n );\n }\n\n // Convert options to the format expected by clack\n const clackOptions = options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })) as Option<T>[];\n\n const result = await multiselect({\n message,\n options: clackOptions,\n required,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result as Array<T>;\n}\n\nexport async function promptConfirm({\n message,\n defaultValue = true,\n cancelMessage = 'Operation cancelled',\n}: {\n message: string;\n defaultValue?: boolean;\n cancelMessage?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<boolean>(\n (prompts) => prompts.inkPromptConfirm({ message, defaultValue }),\n cancelMessage\n )) ?? defaultValue\n );\n }\n\n const result = await confirm({\n message,\n initialValue: defaultValue,\n });\n\n if (isCancel(result)) {\n cancel(cancelMessage);\n return exitSync(0);\n }\n\n return result;\n}\n\n// Warning display functions\nexport function warnApiKeyInConfig(optionsFilepath: string) {\n logger.warn(\n `Found ${chalk.cyan('apiKey')} in \"${chalk.green(optionsFilepath)}\". ` +\n chalk.white(\n 'Your API key is exposed! Remove it from the file and include it as an environment variable.'\n )\n );\n}\n\nexport function warnVariableProp(\n file: string,\n attrName: string,\n value: string\n) {\n logger.warn(\n `Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with variable ${attrName}: \"${chalk.white(value)}\". ` +\n `Change \"${attrName}\" to ensure this content is translated.`\n );\n}\n\nexport function warnNoId(file: string) {\n logger.warn(\n `Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with no id. ` +\n chalk.white('Add an id to ensure the content is translated.')\n );\n}\n\nexport function warnHasUnwrappedExpression(\n file: string,\n id: string,\n unwrappedExpressions: string[]\n) {\n logger.warn(\n `${chalk.green('<T>')} with id \"${id}\" in ${chalk.cyan(file)} has children: ${unwrappedExpressions.join(', ')} that could change at runtime. ` +\n chalk.white('Use a variable component like ') +\n chalk.green('<Var>') +\n chalk.white(' (') +\n chalk.blue('https://generaltranslation.com/docs') +\n chalk.white(') to translate this properly.')\n );\n}\n\nexport function warnTemplateLiteral(file: string, value: string) {\n logger.warn(\n `Found template literal with quasis (${value}) in ${chalk.cyan(file)}. ` +\n chalk.white(\n 'Change the template literal to a string to ensure this content is translated.'\n )\n );\n}\n\nexport function warnTernary(file: string) {\n logger.warn(\n `Found ternary expression in ${chalk.cyan(file)}. ` +\n chalk.white('A Branch component may be more appropriate here.')\n );\n}\n\nexport function warnDeprecatedField(\n deprecatedField: string,\n replacement: string\n) {\n logger.warn(\n `${chalk.green(deprecatedField)} is deprecated. ` +\n chalk.white(`Use ${chalk.green(replacement)} instead.`)\n );\n}\n\n/**\n * Helper: Log all collected files\n */\nexport function logCollectedFiles(\n files: Pick<FileToUpload, 'fileName'>[],\n reactComponents?: number\n): void {\n logger.message(\n chalk.cyan('Files found in project:') +\n '\\n' +\n files\n .map((file) => {\n if (file.fileName === TEMPLATE_FILE_NAME) {\n return `- <React Elements>${reactComponents ? ` (${reactComponents})` : ''}`;\n }\n return `- ${file.fileName}`;\n })\n .join('\\n')\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","names":[],"sources":["../../src/console/logging.ts"],"sourcesContent":["import {\n text,\n select,\n confirm,\n isCancel,\n cancel,\n multiselect,\n} from '@clack/prompts';\nimport type { Option } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { getCLIVersion } from '../utils/packageJson.js';\nimport { logger } from './logger.js';\nimport { TEMPLATE_FILE_NAME } from '../utils/constants.js';\nimport { FileToUpload } from 'generaltranslation/types';\nimport { endTerminalSession, shouldUseInkPrompts } from './terminalSession.js';\nimport {\n parseLocaleList,\n validateLocale,\n validateLocaleList,\n} from './promptParsing.js';\nimport {\n getInlineElementsLabel,\n type InlineLibrary,\n} from '../types/libraries.js';\n\nfunction cancelPromptAndExit(message: string): never {\n endTerminalSession();\n cancel(message);\n return exitSync(0);\n}\n\nasync function loadInkPrompts() {\n return import('./inkPrompts.js');\n}\n\nasync function runInkPrompt<T>(\n prompt: (prompts: Awaited<ReturnType<typeof loadInkPrompts>>) => Promise<{\n value?: T;\n cancelled: boolean;\n }>,\n cancelMessage = 'Operation cancelled'\n) {\n const result = await prompt(await loadInkPrompts());\n if (result.cancelled) {\n return cancelPromptAndExit(cancelMessage);\n }\n return result.value;\n}\n\n/**\n * Strip ANSI escape codes from a string (e.g., chalk color codes)\n */\nexport function stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex, no-useless-escape\n return str.replace(/\\x1B\\[[0-9;]*m/g, '');\n}\n\nexport function logErrorAndExit(message: string): never {\n logger.error(message);\n return exitSync(1);\n}\n\nexport function exitSync(code: number): never {\n // Flush logs before exit\n logger.flush();\n process.exit(code);\n}\n\n// GT specific logging\nexport function displayHeader(introString?: string) {\n // The ASCII banner is pure chatter and writes to console directly, bypassing\n // the logger, so gate it here to honor --quiet. startCommand stays outside\n // the gate: it is quiet-aware itself and must still run so the file log\n // gets its [START] marker.\n if (!logger.isQuiet()) {\n displayAsciiTitle();\n displayInitializingText();\n }\n\n if (introString) {\n logger.startCommand(introString);\n }\n}\n\nfunction displayAsciiTitle() {\n // eslint-disable-next-line no-console\n console.log(\n chalk.cyan(\n `\\n @@@@@@@@@@@@@@@@@@@@@@\n @@ @@@@@@@@@@@@ @@@@@@@\n @@ @@@ @ @\n@@ @@ @ @\n@@ @ @@@@@ @ @\n@@ @@ @@@ @ @ @\n @@ @@ @ @ @ @\n @@ @@@@@@@ @ @ @\n @@@@@@@@@ @ @`\n )\n );\n}\n\nfunction displayInitializingText() {\n const version = getCLIVersion();\n // eslint-disable-next-line no-console\n console.log(\n `\\n${chalk.bold.blue('General Translation, Inc.')}\n${chalk.dim('https://generaltranslation.com/docs')}\n${chalk.dim(`CLI Version: ${version}\\n`)}`\n );\n}\n\nexport function displayProjectId(projectId: string) {\n logger.message(\n chalk.dim(`Project ID: ${chalk.bold(projectId)}`),\n chalk.cyan('~')\n );\n}\n\nexport function displayResolvedPaths(resolvedPaths: [string, string][]) {\n const paths = resolvedPaths.map(([key, resolvedPath]) => {\n return chalk.dim(`'${chalk.white(key)}' → '${chalk.green(resolvedPath)}'`);\n });\n logger.step(`Resolved path aliases:\\n${paths.join('\\n')}`);\n}\n\nexport function displayCreatedConfigFile(configFilepath: string) {\n logger.step(`Created config file ${chalk.cyan(configFilepath)}`);\n}\n\nexport function displayUpdatedConfigFile(configFilepath: string) {\n logger.success(`Updated config file ${chalk.cyan(configFilepath)}`);\n}\n\nexport function displayUpdatedVersionsFile(versionFilepath: string) {\n logger.success(`Updated versions file ${chalk.cyan(versionFilepath)}`);\n}\n\n// Input prompts\nexport async function promptText({\n message,\n defaultValue,\n validate,\n}: {\n message: string;\n defaultValue?: string;\n validate?: (value: string) => boolean | string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptText({ message, defaultValue, validate })\n )) ?? ''\n );\n }\n\n const result = await text({\n message,\n placeholder: defaultValue,\n validate: validate\n ? (value) => {\n const validation = validate(value || '');\n return validation === true ? undefined : validation.toString();\n }\n : undefined,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result;\n}\n\nexport async function promptLocale({\n message,\n defaultValue,\n}: {\n message: string;\n defaultValue?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptLocale({ message, defaultValue })\n )) ?? ''\n );\n }\n\n return promptText({\n message,\n defaultValue,\n validate: validateLocale,\n });\n}\n\nexport async function promptLocaleList({\n message,\n defaultValue,\n required = true,\n}: {\n message: string;\n defaultValue?: string[];\n required?: boolean;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string[]>((prompts) =>\n prompts.inkPromptLocaleMulti({\n message,\n defaultValue,\n required,\n })\n )) ?? []\n );\n }\n\n return promptText({\n message,\n defaultValue: defaultValue?.join(' '),\n validate: validateLocaleList,\n }).then(parseLocaleList);\n}\n\nexport async function promptGlobPatterns({\n label,\n message,\n defaultValue,\n}: {\n label: string;\n message: string;\n defaultValue?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<string>((prompts) =>\n prompts.inkPromptGlob({ label, message, defaultValue })\n )) ?? ''\n );\n }\n\n return promptText({\n message,\n defaultValue,\n });\n}\n\nexport async function promptSelect<T>({\n message,\n options,\n defaultValue,\n}: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n defaultValue?: T;\n}) {\n if (shouldUseInkPrompts()) {\n return (await runInkPrompt<T>((prompts) =>\n prompts.inkPromptSelect({ message, options, defaultValue })\n )) as T;\n }\n\n // Convert options to the format expected by clack\n const clackOptions = options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })) as Option<T>[];\n\n const result = await select({\n message,\n options: clackOptions,\n initialValue: defaultValue,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result as T;\n}\n\nexport async function promptMultiSelect<T extends string>({\n message,\n options,\n required = true,\n}: {\n message: string;\n options: Array<{ value: T; label: string; hint?: string }>;\n required?: boolean;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<Array<T>>((prompts) =>\n prompts.inkPromptMultiSelect({\n message,\n options,\n required,\n })\n )) ?? []\n );\n }\n\n // Convert options to the format expected by clack\n const clackOptions = options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })) as Option<T>[];\n\n const result = await multiselect({\n message,\n options: clackOptions,\n required,\n });\n\n if (isCancel(result)) {\n cancel('Operation cancelled');\n return exitSync(0);\n }\n\n return result as Array<T>;\n}\n\nexport async function promptConfirm({\n message,\n defaultValue = true,\n cancelMessage = 'Operation cancelled',\n}: {\n message: string;\n defaultValue?: boolean;\n cancelMessage?: string;\n}) {\n if (shouldUseInkPrompts()) {\n return (\n (await runInkPrompt<boolean>(\n (prompts) => prompts.inkPromptConfirm({ message, defaultValue }),\n cancelMessage\n )) ?? defaultValue\n );\n }\n\n const result = await confirm({\n message,\n initialValue: defaultValue,\n });\n\n if (isCancel(result)) {\n cancel(cancelMessage);\n return exitSync(0);\n }\n\n return result;\n}\n\n// Warning display functions\nexport function warnApiKeyInConfig(optionsFilepath: string) {\n logger.warn(\n `Found ${chalk.cyan('apiKey')} in \"${chalk.green(optionsFilepath)}\". ` +\n chalk.white(\n 'Your API key is exposed! Remove it from the file and include it as an environment variable.'\n )\n );\n}\n\nexport function warnVariableProp(\n file: string,\n attrName: string,\n value: string\n) {\n logger.warn(\n `Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with variable ${attrName}: \"${chalk.white(value)}\". ` +\n `Change \"${attrName}\" to ensure this content is translated.`\n );\n}\n\nexport function warnNoId(file: string) {\n logger.warn(\n `Found ${chalk.green('<T>')} component in ${chalk.cyan(file)} with no id. ` +\n chalk.white('Add an id to ensure the content is translated.')\n );\n}\n\nexport function warnHasUnwrappedExpression(\n file: string,\n id: string,\n unwrappedExpressions: string[]\n) {\n logger.warn(\n `${chalk.green('<T>')} with id \"${id}\" in ${chalk.cyan(file)} has children: ${unwrappedExpressions.join(', ')} that could change at runtime. ` +\n chalk.white('Use a variable component like ') +\n chalk.green('<Var>') +\n chalk.white(' (') +\n chalk.blue('https://generaltranslation.com/docs') +\n chalk.white(') to translate this properly.')\n );\n}\n\nexport function warnTemplateLiteral(file: string, value: string) {\n logger.warn(\n `Found template literal with quasis (${value}) in ${chalk.cyan(file)}. ` +\n chalk.white(\n 'Change the template literal to a string to ensure this content is translated.'\n )\n );\n}\n\nexport function warnTernary(file: string) {\n logger.warn(\n `Found ternary expression in ${chalk.cyan(file)}. ` +\n chalk.white('A Branch component may be more appropriate here.')\n );\n}\n\nexport function warnDeprecatedField(\n deprecatedField: string,\n replacement: string\n) {\n logger.warn(\n `${chalk.green(deprecatedField)} is deprecated. ` +\n chalk.white(`Use ${chalk.green(replacement)} instead.`)\n );\n}\n\n/**\n * Helper: Log all collected files\n */\nexport function logCollectedFiles(\n files: Pick<FileToUpload, 'fileName'>[],\n inlineComponents?: number,\n inlineLibrary?: InlineLibrary\n): void {\n const elementLabel = getInlineElementsLabel(inlineLibrary);\n logger.message(\n chalk.cyan('Files found in project:') +\n '\\n' +\n files\n .map((file) => {\n if (file.fileName === TEMPLATE_FILE_NAME) {\n return `- <${elementLabel}>${inlineComponents ? ` (${inlineComponents})` : ''}`;\n }\n return `- ${file.fileName}`;\n })\n .join('\\n')\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,11 @@
1
1
  import { Settings, SupportedLibraries, TranslateFlags } from '../../types/index.js';
2
2
  import type { FileToUpload } from 'generaltranslation/types';
3
+ import { type InlineLibrary } from '../../types/libraries.js';
4
+ /** Resolves the inline runtime that owns this project's shared GTJSON file. */
5
+ export declare function resolveInlineLibrary(library: SupportedLibraries, projectRoot?: string): InlineLibrary | undefined;
3
6
  export declare function collectFiles(options: TranslateFlags, settings: Settings, library: SupportedLibraries): Promise<{
4
7
  files: FileToUpload[];
5
8
  reactComponents: number;
9
+ inlineLibrary?: InlineLibrary;
6
10
  publishMap: Map<string, boolean>;
7
11
  }>;
@@ -1,17 +1,28 @@
1
1
  import { hashStringSync } from "../../utils/hash.js";
2
2
  import { TEMPLATE_FILE_ID, TEMPLATE_FILE_NAME } from "../../utils/constants.js";
3
+ import { isInlineLibrary } from "../../types/libraries.js";
3
4
  import { logErrorAndExit } from "../../console/logging.js";
4
5
  import { invalidConfigurationError } from "../../console/index.js";
5
- import { isInlineLibrary } from "../../types/libraries.js";
6
6
  import { shouldPublishGt } from "../../utils/resolvePublish.js";
7
7
  import { aggregateFiles } from "./aggregateFiles.js";
8
8
  import { aggregateInlineTranslations } from "../../translation/stage.js";
9
+ import { planVueExtraction } from "@generaltranslation/vue-extractor/integration";
9
10
  //#region src/formats/files/collectFiles.ts
11
+ /** Resolves the inline runtime that owns this project's shared GTJSON file. */
12
+ function resolveInlineLibrary(library, projectRoot = process.cwd()) {
13
+ if (planVueExtraction({
14
+ library,
15
+ projectRoot
16
+ }).handled) return "gt-vue";
17
+ return isInlineLibrary(library) ? library : void 0;
18
+ }
10
19
  async function collectFiles(options, settings, library) {
11
20
  const { files, publishMap } = await aggregateFiles(settings);
12
21
  let reactComponents = 0;
13
- if (isInlineLibrary(library)) {
14
- const updates = await aggregateInlineTranslations(options, settings, library);
22
+ const inlineLibrary = resolveInlineLibrary(library);
23
+ const extractionLibrary = isInlineLibrary(library) ? library : inlineLibrary === "gt-vue" ? "gt-vue" : void 0;
24
+ if (extractionLibrary) {
25
+ const updates = await aggregateInlineTranslations(options, settings, extractionLibrary);
15
26
  if (updates.length > 0) {
16
27
  if (!settings.publish && !settings.files?.placeholderPaths.gt) logErrorAndExit(invalidConfigurationError);
17
28
  const fileData = {};
@@ -48,10 +59,11 @@ async function collectFiles(options, settings, library) {
48
59
  return {
49
60
  files,
50
61
  reactComponents,
62
+ inlineLibrary,
51
63
  publishMap
52
64
  };
53
65
  }
54
66
  //#endregion
55
- export { collectFiles };
67
+ export { collectFiles, resolveInlineLibrary };
56
68
 
57
69
  //# sourceMappingURL=collectFiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collectFiles.js","names":[],"sources":["../../../src/formats/files/collectFiles.ts"],"sourcesContent":["import { logErrorAndExit } from '../../console/logging.js';\nimport {\n Settings,\n SupportedLibraries,\n TranslateFlags,\n} from '../../types/index.js';\nimport { invalidConfigurationError } from '../../console/index.js';\nimport { aggregateFiles } from './aggregateFiles.js';\nimport { aggregateInlineTranslations } from '../../translation/stage.js';\nimport type { JsxChildren } from '@generaltranslation/format/types';\nimport type { FileToUpload } from 'generaltranslation/types';\nimport { hashStringSync } from '../../utils/hash.js';\nimport { TEMPLATE_FILE_NAME, TEMPLATE_FILE_ID } from '../../utils/constants.js';\nimport { isInlineLibrary } from '../../types/libraries.js';\nimport { shouldPublishGt } from '../../utils/resolvePublish.js';\n\nexport async function collectFiles(\n options: TranslateFlags,\n settings: Settings,\n library: SupportedLibraries\n): Promise<{\n files: FileToUpload[];\n reactComponents: number;\n publishMap: Map<string, boolean>;\n}> {\n // Aggregate files\n const { files, publishMap } = await aggregateFiles(settings);\n\n // Parse for React components\n let reactComponents = 0;\n if (isInlineLibrary(library)) {\n const updates = await aggregateInlineTranslations(\n options,\n settings,\n library\n );\n if (updates.length > 0) {\n if (!settings.publish && !settings.files?.placeholderPaths.gt) {\n logErrorAndExit(invalidConfigurationError);\n }\n // Convert updates to a file object\n const fileData: Record<string, JsxChildren> = {};\n const fileMetadata: Record<string, unknown> = {};\n // Convert updates to the proper data format\n for (const update of updates) {\n const { source, metadata, dataFormat } = update;\n metadata.dataFormat = dataFormat; // add the data format to the metadata\n // Materialize effective requiresReview into component metadata:\n // the explicit prop wins; otherwise inherit the top-level config\n // default. Only the explicit prop is part of component hashes — the\n // effective flag here is what the platform filters serving on.\n // Uploaded metadata uses the platform's canonical snake_case key;\n // camelCase requiresReview stays client-internal (props + hashing).\n // An explicit prop (true or false) is always materialized; without\n // one, only a true config default is — a false/absent default means\n // the key is omitted entirely, matching pre-feature metadata.\n const effectiveRequiresReview =\n metadata.requiresReview !== undefined\n ? metadata.requiresReview\n : settings.requiresReview\n ? true\n : undefined;\n delete metadata.requiresReview;\n if (effectiveRequiresReview !== undefined) {\n metadata.requires_review = effectiveRequiresReview;\n }\n const { hash } = metadata;\n if (hash) {\n fileData[hash] = source;\n fileMetadata[hash] = metadata;\n }\n }\n reactComponents = updates.length;\n // Version identity includes which components effectively require\n // review, so config-only review changes produce a new source version.\n // When nothing requires review this reduces to the legacy key-only\n // hash, keeping existing projects' version IDs stable.\n const sortedKeys = Object.keys(fileData).sort();\n const reviewRequiredKeys = sortedKeys.filter(\n (key) =>\n (fileMetadata[key] as { requires_review?: boolean })\n ?.requires_review === true\n );\n const versionId = reviewRequiredKeys.length\n ? hashStringSync(\n JSON.stringify(sortedKeys) +\n '\\u0000requiresReview\\u0000' +\n JSON.stringify(reviewRequiredKeys)\n )\n : hashStringSync(JSON.stringify(sortedKeys));\n files.push({\n fileName: TEMPLATE_FILE_NAME,\n content: JSON.stringify(fileData),\n fileFormat: 'GTJSON',\n formatMetadata: fileMetadata,\n fileId: TEMPLATE_FILE_ID,\n versionId,\n locale: settings.defaultLocale,\n } satisfies FileToUpload);\n // Only add GT JSON to publishMap if there's an explicit publish config\n const gtPublishValue = shouldPublishGt(settings);\n if (gtPublishValue !== undefined) {\n publishMap.set(TEMPLATE_FILE_ID, gtPublishValue);\n }\n }\n }\n return { files, reactComponents, publishMap };\n}\n"],"mappings":";;;;;;;;;AAgBA,eAAsB,aACpB,SACA,UACA,SAKC;CAED,MAAM,EAAE,OAAO,eAAe,MAAM,eAAe,SAAS;CAG5D,IAAI,kBAAkB;AACtB,KAAI,gBAAgB,QAAQ,EAAE;EAC5B,MAAM,UAAU,MAAM,4BACpB,SACA,UACA,QACD;AACD,MAAI,QAAQ,SAAS,GAAG;AACtB,OAAI,CAAC,SAAS,WAAW,CAAC,SAAS,OAAO,iBAAiB,GACzD,iBAAgB,0BAA0B;GAG5C,MAAM,WAAwC,EAAE;GAChD,MAAM,eAAwC,EAAE;AAEhD,QAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,EAAE,QAAQ,UAAU,eAAe;AACzC,aAAS,aAAa;IAUtB,MAAM,0BACJ,SAAS,mBAAmB,KAAA,IACxB,SAAS,iBACT,SAAS,iBACP,OACA,KAAA;AACR,WAAO,SAAS;AAChB,QAAI,4BAA4B,KAAA,EAC9B,UAAS,kBAAkB;IAE7B,MAAM,EAAE,SAAS;AACjB,QAAI,MAAM;AACR,cAAS,QAAQ;AACjB,kBAAa,QAAQ;;;AAGzB,qBAAkB,QAAQ;GAK1B,MAAM,aAAa,OAAO,KAAK,SAAS,CAAC,MAAM;GAC/C,MAAM,qBAAqB,WAAW,QACnC,QACE,aAAa,MACV,oBAAoB,KAC3B;GACD,MAAM,YAAY,mBAAmB,SACjC,eACE,KAAK,UAAU,WAAW,GACxB,uBACA,KAAK,UAAU,mBAAmB,CACrC,GACD,eAAe,KAAK,UAAU,WAAW,CAAC;AAC9C,SAAM,KAAK;IACT,UAAU;IACV,SAAS,KAAK,UAAU,SAAS;IACjC,YAAY;IACZ,gBAAgB;IAChB,QAAQ;IACR;IACA,QAAQ,SAAS;IAClB,CAAwB;GAEzB,MAAM,iBAAiB,gBAAgB,SAAS;AAChD,OAAI,mBAAmB,KAAA,EACrB,YAAW,IAAI,kBAAkB,eAAe;;;AAItD,QAAO;EAAE;EAAO;EAAiB;EAAY"}
1
+ {"version":3,"file":"collectFiles.js","names":[],"sources":["../../../src/formats/files/collectFiles.ts"],"sourcesContent":["import { logErrorAndExit } from '../../console/logging.js';\nimport {\n Settings,\n SupportedLibraries,\n TranslateFlags,\n} from '../../types/index.js';\nimport { invalidConfigurationError } from '../../console/index.js';\nimport { aggregateFiles } from './aggregateFiles.js';\nimport { aggregateInlineTranslations } from '../../translation/stage.js';\nimport type { JsxChildren } from '@generaltranslation/format/types';\nimport type { FileToUpload } from 'generaltranslation/types';\nimport { hashStringSync } from '../../utils/hash.js';\nimport { TEMPLATE_FILE_NAME, TEMPLATE_FILE_ID } from '../../utils/constants.js';\nimport {\n isInlineLibrary,\n Libraries,\n type InlineLibrary,\n} from '../../types/libraries.js';\nimport { shouldPublishGt } from '../../utils/resolvePublish.js';\nimport { planVueExtraction } from '@generaltranslation/vue-extractor/integration';\n\n/** Resolves the inline runtime that owns this project's shared GTJSON file. */\nexport function resolveInlineLibrary(\n library: SupportedLibraries,\n projectRoot: string = process.cwd()\n): InlineLibrary | undefined {\n const includesVue = planVueExtraction({ library, projectRoot }).handled;\n if (includesVue) return Libraries.GT_VUE;\n return isInlineLibrary(library) ? library : undefined;\n}\n\nexport async function collectFiles(\n options: TranslateFlags,\n settings: Settings,\n library: SupportedLibraries\n): Promise<{\n files: FileToUpload[];\n reactComponents: number;\n inlineLibrary?: InlineLibrary;\n publishMap: Map<string, boolean>;\n}> {\n // Aggregate files\n const { files, publishMap } = await aggregateFiles(settings);\n\n // Parse for React components\n let reactComponents = 0;\n const inlineLibrary = resolveInlineLibrary(library);\n const extractionLibrary = isInlineLibrary(library)\n ? library\n : inlineLibrary === Libraries.GT_VUE\n ? Libraries.GT_VUE\n : undefined;\n if (extractionLibrary) {\n const updates = await aggregateInlineTranslations(\n options,\n settings,\n extractionLibrary\n );\n if (updates.length > 0) {\n if (!settings.publish && !settings.files?.placeholderPaths.gt) {\n logErrorAndExit(invalidConfigurationError);\n }\n // Convert updates to a file object\n const fileData: Record<string, JsxChildren> = {};\n const fileMetadata: Record<string, unknown> = {};\n // Convert updates to the proper data format\n for (const update of updates) {\n const { source, metadata, dataFormat } = update;\n metadata.dataFormat = dataFormat; // add the data format to the metadata\n // Materialize effective requiresReview into component metadata:\n // the explicit prop wins; otherwise inherit the top-level config\n // default. Only the explicit prop is part of component hashes — the\n // effective flag here is what the platform filters serving on.\n // Uploaded metadata uses the platform's canonical snake_case key;\n // camelCase requiresReview stays client-internal (props + hashing).\n // An explicit prop (true or false) is always materialized; without\n // one, only a true config default is — a false/absent default means\n // the key is omitted entirely, matching pre-feature metadata.\n const effectiveRequiresReview =\n metadata.requiresReview !== undefined\n ? metadata.requiresReview\n : settings.requiresReview\n ? true\n : undefined;\n delete metadata.requiresReview;\n if (effectiveRequiresReview !== undefined) {\n metadata.requires_review = effectiveRequiresReview;\n }\n const { hash } = metadata;\n if (hash) {\n fileData[hash] = source;\n fileMetadata[hash] = metadata;\n }\n }\n reactComponents = updates.length;\n // Version identity includes which components effectively require\n // review, so config-only review changes produce a new source version.\n // When nothing requires review this reduces to the legacy key-only\n // hash, keeping existing projects' version IDs stable.\n const sortedKeys = Object.keys(fileData).sort();\n const reviewRequiredKeys = sortedKeys.filter(\n (key) =>\n (fileMetadata[key] as { requires_review?: boolean })\n ?.requires_review === true\n );\n const versionId = reviewRequiredKeys.length\n ? hashStringSync(\n JSON.stringify(sortedKeys) +\n '\\u0000requiresReview\\u0000' +\n JSON.stringify(reviewRequiredKeys)\n )\n : hashStringSync(JSON.stringify(sortedKeys));\n files.push({\n fileName: TEMPLATE_FILE_NAME,\n content: JSON.stringify(fileData),\n fileFormat: 'GTJSON',\n formatMetadata: fileMetadata,\n fileId: TEMPLATE_FILE_ID,\n versionId,\n locale: settings.defaultLocale,\n } satisfies FileToUpload);\n // Only add GT JSON to publishMap if there's an explicit publish config\n const gtPublishValue = shouldPublishGt(settings);\n if (gtPublishValue !== undefined) {\n publishMap.set(TEMPLATE_FILE_ID, gtPublishValue);\n }\n }\n }\n return { files, reactComponents, inlineLibrary, publishMap };\n}\n"],"mappings":";;;;;;;;;;;AAsBA,SAAgB,qBACd,SACA,cAAsB,QAAQ,KAAK,EACR;AAE3B,KADoB,kBAAkB;EAAE;EAAS;EAAa,CAAC,CAAC,QAC/C,QAAA;AACjB,QAAO,gBAAgB,QAAQ,GAAG,UAAU,KAAA;;AAG9C,eAAsB,aACpB,SACA,UACA,SAMC;CAED,MAAM,EAAE,OAAO,eAAe,MAAM,eAAe,SAAS;CAG5D,IAAI,kBAAkB;CACtB,MAAM,gBAAgB,qBAAqB,QAAQ;CACnD,MAAM,oBAAoB,gBAAgB,QAAQ,GAC9C,UACA,kBAAA,WAAA,WAEE,KAAA;AACN,KAAI,mBAAmB;EACrB,MAAM,UAAU,MAAM,4BACpB,SACA,UACA,kBACD;AACD,MAAI,QAAQ,SAAS,GAAG;AACtB,OAAI,CAAC,SAAS,WAAW,CAAC,SAAS,OAAO,iBAAiB,GACzD,iBAAgB,0BAA0B;GAG5C,MAAM,WAAwC,EAAE;GAChD,MAAM,eAAwC,EAAE;AAEhD,QAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,EAAE,QAAQ,UAAU,eAAe;AACzC,aAAS,aAAa;IAUtB,MAAM,0BACJ,SAAS,mBAAmB,KAAA,IACxB,SAAS,iBACT,SAAS,iBACP,OACA,KAAA;AACR,WAAO,SAAS;AAChB,QAAI,4BAA4B,KAAA,EAC9B,UAAS,kBAAkB;IAE7B,MAAM,EAAE,SAAS;AACjB,QAAI,MAAM;AACR,cAAS,QAAQ;AACjB,kBAAa,QAAQ;;;AAGzB,qBAAkB,QAAQ;GAK1B,MAAM,aAAa,OAAO,KAAK,SAAS,CAAC,MAAM;GAC/C,MAAM,qBAAqB,WAAW,QACnC,QACE,aAAa,MACV,oBAAoB,KAC3B;GACD,MAAM,YAAY,mBAAmB,SACjC,eACE,KAAK,UAAU,WAAW,GACxB,uBACA,KAAK,UAAU,mBAAmB,CACrC,GACD,eAAe,KAAK,UAAU,WAAW,CAAC;AAC9C,SAAM,KAAK;IACT,UAAU;IACV,SAAS,KAAK,UAAU,SAAS;IACjC,YAAY;IACZ,gBAAgB;IAChB,QAAQ;IACR;IACA,QAAQ,SAAS;IAClB,CAAwB;GAEzB,MAAM,iBAAiB,gBAAgB,SAAS;AAChD,OAAI,mBAAmB,KAAA,EACrB,YAAW,IAAI,kBAAkB,eAAe;;;AAItD,QAAO;EAAE;EAAO;EAAiB;EAAe;EAAY"}
@@ -10,8 +10,11 @@ export declare function createOrUpdateConfig(configFilepath: string, options: {
10
10
  projectId?: string;
11
11
  defaultLocale?: string;
12
12
  locales?: string[];
13
+ src?: string[];
13
14
  files?: FilesOptions;
14
15
  framework?: SupportedFrameworks;
15
16
  baseUrl?: string;
16
17
  publish?: boolean;
18
+ /** Removes stale global CDN intent when the selected runtime forbids it. */
19
+ clearPublish?: boolean;
17
20
  }): Promise<string>;
@@ -14,6 +14,7 @@ async function createOrUpdateConfig(configFilepath, options) {
14
14
  const newContent = {
15
15
  ...options.projectId && { projectId: options.projectId },
16
16
  ...options.defaultLocale && { defaultLocale: options.defaultLocale },
17
+ ...options.src && { src: options.src },
17
18
  ...options.files && { files: options.files },
18
19
  ...options.framework && { framework: options.framework },
19
20
  ...options.baseUrl && { baseUrl: options.baseUrl },
@@ -30,6 +31,7 @@ async function createOrUpdateConfig(configFilepath, options) {
30
31
  ...oldContent,
31
32
  ...newContent
32
33
  };
34
+ if (options.clearPublish) delete mergedContent.publish;
33
35
  if (options.files) {
34
36
  const oldFiles = oldContent.files && typeof oldContent.files === "object" ? oldContent.files : {};
35
37
  const oldGt = oldFiles.gt && typeof oldFiles.gt === "object" ? oldFiles.gt : {};
@@ -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 // 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
+ {"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 src?: string[];\n files?: FilesOptions;\n framework?: SupportedFrameworks;\n baseUrl?: string;\n publish?: boolean;\n /** Removes stale global CDN intent when the selected runtime forbids it. */\n clearPublish?: 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.src && { src: options.src }),\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 if (options.clearPublish) {\n delete mergedContent.publish;\n }\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,SAYiB;CAEjB,MAAM,aAAa;EACjB,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,eAAe;EACrE,GAAI,QAAQ,OAAO,EAAE,KAAK,QAAQ,KAAK;EACvC,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;AAED,MAAI,QAAQ,aACV,QAAO,cAAc;AAKvB,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,5 +1,13 @@
1
1
  import { SupportedLibraries } from '../../types/index.js';
2
- export declare function determineLibrary(): {
2
+ type DeterminedLibrary = {
3
3
  library: SupportedLibraries;
4
4
  additionalModules: SupportedLibraries[];
5
5
  };
6
+ type DeterminedCLILibrary = DeterminedLibrary & {
7
+ directlyDeclaresVue: boolean;
8
+ };
9
+ /** Preserves the historical public detection result shape. */
10
+ export declare function determineLibrary(): DeterminedLibrary;
11
+ /** Includes the direct Vue signal needed to select a mixed command adapter. */
12
+ export declare function determineLibraryForCLI(): DeterminedCLILibrary;
13
+ export {};
@@ -3,15 +3,24 @@ import "../../types/libraries.js";
3
3
  import { detectPythonLibrary } from "./detectPythonLibrary.js";
4
4
  import path from "node:path";
5
5
  import fs from "node:fs";
6
+ import { manifestDirectlyDeclaresGTVue } from "@generaltranslation/vue-extractor/integration";
6
7
  //#region src/fs/determineFramework/index.ts
8
+ /** Preserves the historical public detection result shape. */
7
9
  function determineLibrary() {
10
+ const { directlyDeclaresVue: _directlyDeclaresVue, ...selection } = determineLibraryForCLI();
11
+ return selection;
12
+ }
13
+ /** Includes the direct Vue signal needed to select a mixed command adapter. */
14
+ function determineLibraryForCLI() {
8
15
  let library = "base";
9
16
  const additionalModules = [];
17
+ let directlyDeclaresVue = false;
10
18
  try {
11
19
  const cwd = process.cwd();
12
20
  const packageJsonPath = path.join(cwd, "package.json");
13
21
  if (fs.existsSync(packageJsonPath)) {
14
22
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
23
+ directlyDeclaresVue = manifestDirectlyDeclaresGTVue(packageJson);
15
24
  const dependencies = {
16
25
  ...packageJson.dependencies,
17
26
  ...packageJson.devDependencies
@@ -29,19 +38,22 @@ function determineLibrary() {
29
38
  const pythonLibrary = detectPythonLibrary(cwd);
30
39
  if (pythonLibrary) library = pythonLibrary;
31
40
  }
41
+ if (library === "base" && directlyDeclaresVue) library = "gt-vue";
32
42
  return {
33
43
  library,
34
- additionalModules
44
+ additionalModules,
45
+ directlyDeclaresVue
35
46
  };
36
47
  } catch (error) {
37
48
  logger.error("Error determining framework: " + String(error));
38
49
  return {
39
50
  library: "base",
40
- additionalModules: []
51
+ additionalModules: [],
52
+ directlyDeclaresVue: false
41
53
  };
42
54
  }
43
55
  }
44
56
  //#endregion
45
- export { determineLibrary };
57
+ export { determineLibrary, determineLibraryForCLI };
46
58
 
47
59
  //# sourceMappingURL=index.js.map