gtx-cli 2.5.44 → 2.5.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.5.45
4
+
5
+ ### Patch Changes
6
+
7
+ - [#944](https://github.com/generaltranslation/gt/pull/944) [`0a58f13`](https://github.com/generaltranslation/gt/commit/0a58f13c9d25938a5e12644349248ce18aebb796) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Add option to skip file validation when passing for translation
8
+
9
+ - [#942](https://github.com/generaltranslation/gt/pull/942) [`0cb890b`](https://github.com/generaltranslation/gt/commit/0cb890b84d775b360de0d8f6ed2b1ec8aeaa0af2) Thanks [@archie-mckenzie](https://github.com/archie-mckenzie)! - Refreshed CLI setup wizard flow
10
+
3
11
  ## 2.5.44
4
12
 
5
13
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  import { Command } from 'commander';
2
- import { Settings, SupportedLibraries, SetupOptions, TranslateFlags } from '../types/index.js';
2
+ import { Settings, ReactFrameworkObject, SupportedLibraries, SetupOptions, TranslateFlags } from '../types/index.js';
3
3
  export type UploadOptions = {
4
4
  config?: string;
5
5
  apiKey?: string;
@@ -28,7 +28,7 @@ export declare class BaseCLI {
28
28
  protected setupInitCommand(): void;
29
29
  protected setupConfigureCommand(): void;
30
30
  protected handleUploadCommand(settings: Settings & UploadOptions): Promise<void>;
31
- protected handleSetupReactCommand(options: SetupOptions): Promise<void>;
31
+ protected handleSetupReactCommand(options: SetupOptions, frameworkObject: ReactFrameworkObject): Promise<void>;
32
32
  protected handleInitCommand(ranReactSetup: boolean): Promise<void>;
33
33
  protected handleLoginCommand(options: LoginOptions): Promise<void>;
34
34
  }
package/dist/cli/base.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
2
2
  import findFilepath from '../fs/findFilepath.js';
3
- import { displayHeader, promptText, logErrorAndExit, promptConfirm, promptMultiSelect, } from '../console/logging.js';
3
+ import { displayHeader, promptText, logErrorAndExit, promptConfirm, promptMultiSelect, promptSelect, } from '../console/logging.js';
4
4
  import { logger } from '../console/logger.js';
5
5
  import path from 'node:path';
6
6
  import fs from 'node:fs';
@@ -25,6 +25,8 @@ import { createLoadTranslationsFile } from '../fs/createLoadTranslationsFile.js'
25
25
  import { saveLocalEdits } from '../api/saveLocalEdits.js';
26
26
  import processSharedStaticAssets from '../utils/sharedStaticAssets.js';
27
27
  import { setupLocadex } from '../locadex/setupFlow.js';
28
+ import { detectFramework } from '../setup/detectFramework.js';
29
+ import { getFrameworkDisplayName, getReactFrameworkLibrary, } from '../setup/frameworkUtils.js';
28
30
  export class BaseCLI {
29
31
  library;
30
32
  additionalModules;
@@ -183,32 +185,42 @@ export class BaseCLI {
183
185
  .action(async (options) => {
184
186
  const settings = await generateSettings(options);
185
187
  displayHeader('Running setup wizard...');
186
- const packageJson = await searchForPackageJson();
187
- const isUsingNextjs = packageJson && isPackageInstalled('next', packageJson);
188
- const useAgent = isUsingNextjs
189
- ? await promptConfirm({
190
- message: `Detected that this project is using Next.js. Would you like to use the Locadex AI Agent to automatically set up your project?`,
191
- defaultValue: true,
192
- })
193
- : false;
188
+ const framework = await detectFramework();
189
+ const useAgent = await (async () => {
190
+ let useAgentMessage;
191
+ if (framework.name === 'mintlify') {
192
+ useAgentMessage = `Mintlify project detected. Would you like to connect to GitHub so that the Locadex AI Agent can translate your project automatically?`;
193
+ }
194
+ if (framework.name === 'next-app') {
195
+ useAgentMessage = `Next.js App Router detected. Would you like to connect to GitHub so that the Locadex AI Agent can set up your project automatically?`;
196
+ }
197
+ if (useAgentMessage) {
198
+ return await promptConfirm({
199
+ message: useAgentMessage,
200
+ defaultValue: false,
201
+ });
202
+ }
203
+ return false;
204
+ })();
194
205
  if (useAgent) {
195
206
  await setupLocadex(settings);
196
- logger.endCommand('Done! The Locadex AI Agent will run in the background and set up your project. See the docs for more information: https://generaltranslation.com/docs');
207
+ logger.endCommand('Once installed, Locadex will open a PR to your repository. See the docs for more information: https://generaltranslation.com/docs/locadex');
197
208
  }
198
209
  else {
199
210
  let ranReactSetup = false;
200
211
  // so that people can run init in non-js projects
201
- if (packageJson && isPackageInstalled('react', packageJson)) {
212
+ if (framework.type === 'react') {
213
+ const frameworkDisplayName = getFrameworkDisplayName(framework);
214
+ const library = getReactFrameworkLibrary(framework);
202
215
  const wrap = await promptConfirm({
203
- message: `Detected that this project is using React. Would you like to run the React setup wizard?\nThis will install gt-react|gt-next as a dependency and internationalize your app.`,
216
+ message: `${frameworkDisplayName} detected. Would you like to install ${library} and add the GTProvider? See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`,
204
217
  defaultValue: true,
205
218
  });
206
219
  if (wrap) {
207
- logger.info(`${chalk.yellow('[EXPERIMENTAL]')} Running React setup wizard...`);
208
- await this.handleSetupReactCommand(options);
220
+ logger.info(`${chalk.yellow('[EXPERIMENTAL]')} Configuring project...`);
221
+ await this.handleSetupReactCommand(options, framework);
209
222
  logger.endCommand(`Done! Since this wizard is experimental, please review the changes and make modifications as needed.
210
- Certain aspects of your app may still need manual setup.
211
- See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`);
223
+ \nNext step: start internationalizing! See the docs for more information: https://generaltranslation.com/docs/react/tutorials/quickstart`);
212
224
  ranReactSetup = true;
213
225
  }
214
226
  }
@@ -257,8 +269,8 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
257
269
  // Process all file types at once with a single call
258
270
  await upload(sourceFiles, placeholderPaths, transformPaths, dataFormat, settings);
259
271
  }
260
- async handleSetupReactCommand(options) {
261
- await handleSetupReactCommand(options);
272
+ async handleSetupReactCommand(options, frameworkObject) {
273
+ await handleSetupReactCommand(options, frameworkObject);
262
274
  }
263
275
  // Wizard for configuring gt.config.json
264
276
  async handleInitCommand(ranReactSetup) {
@@ -273,18 +285,23 @@ See the docs for more information: https://generaltranslation.com/docs/react/tut
273
285
  // Ask if using another i18n library
274
286
  const isUsingGT = isUsingGTNext || isUsingGTReact || ranReactSetup;
275
287
  // Ask where the translations are stored
276
- const usingCDN = isUsingGT
277
- ? await promptConfirm({
278
- message: `Auto-detected that you're using gt-next or gt-react. Would you like to use the General Translation CDN to store your translations?\nSee ${isUsingGTNext
279
- ? 'https://generaltranslation.com/en/docs/next/guides/local-tx'
280
- : 'https://generaltranslation.com/en/docs/react/guides/local-tx'} for more information.\nIf you answer no, we'll configure the CLI tool to download completed translations.`,
281
- defaultValue: false,
282
- })
283
- : false;
288
+ const usingCDN = await (async () => {
289
+ if (!isUsingGT)
290
+ return false;
291
+ const selectedValue = await promptSelect({
292
+ message: `Would you like to save translation files locally or use the General Translation CDN to store them?`,
293
+ options: [
294
+ { value: 'local', label: 'Save locally' },
295
+ { value: 'cdn', label: 'Use CDN' },
296
+ ],
297
+ defaultValue: 'local',
298
+ });
299
+ return selectedValue === 'cdn';
300
+ })();
284
301
  // Ask where the translations are stored
285
302
  const translationsDir = isUsingGT && !usingCDN
286
303
  ? await promptText({
287
- message: 'What is the path to the directory where you would like to locally store your translations?',
304
+ message: 'What is the path to the directory where you would like to store your translation files?',
288
305
  defaultValue: './public/_gt',
289
306
  })
290
307
  : null;
@@ -299,7 +316,7 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
299
316
  }
300
317
  const message = !isUsingGT
301
318
  ? 'What is the format of your language resource files? Select as many as applicable.\nAdditionally, you can translate any other files you have in your project.'
302
- : `${chalk.dim('(Optional)')} Do you have any separate files you would like to translate? For example, extra Markdown files for docs.`;
319
+ : `Do you have any additional files in this project to translate? For example, Markdown files for docs. ${chalk.dim('(To continue without selecting press Enter)')}`;
303
320
  const fileExtensions = await promptMultiSelect({
304
321
  message,
305
322
  options: [
@@ -339,7 +356,7 @@ See https://generaltranslation.com/en/docs/next/guides/local-tx`);
339
356
  files: Object.keys(files).length > 0 ? files : undefined,
340
357
  publish: isUsingGT && usingCDN,
341
358
  });
342
- logger.success(`Feel free to edit ${chalk.cyan(configFilepath)} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
359
+ logger.success(`Edit ${chalk.cyan(configFilepath)} to customize your translation setup. Docs: https://generaltranslation.com/docs/cli/reference/config`);
343
360
  // Install gtx-cli if not installed
344
361
  const isCLIInstalled = packageJson
345
362
  ? isPackageInstalled('gtx-cli', packageJson, true, true)
@@ -18,6 +18,7 @@ export async function aggregateFiles(settings) {
18
18
  return allFiles;
19
19
  }
20
20
  const { resolvedPaths: filePaths } = settings.files;
21
+ const skipValidation = settings.options?.skipFileValidation;
21
22
  // Process JSON files
22
23
  if (filePaths.json) {
23
24
  const { library, additionalModules } = determineLibrary();
@@ -42,12 +43,14 @@ export async function aggregateFiles(settings) {
42
43
  const content = readFile(filePath);
43
44
  const relativePath = getRelative(filePath);
44
45
  // Pre-validate JSON parseability
45
- try {
46
- JSON.parse(content);
47
- }
48
- catch (e) {
49
- logger.warn(`Skipping ${relativePath}: JSON file is not parsable`);
50
- return null;
46
+ if (!skipValidation?.json) {
47
+ try {
48
+ JSON.parse(content);
49
+ }
50
+ catch (e) {
51
+ logger.warn(`Skipping ${relativePath}: JSON file is not parsable`);
52
+ return null;
53
+ }
51
54
  }
52
55
  const parsedJson = parseJson(content, filePath, settings.options || {}, settings.defaultLocale);
53
56
  return {
@@ -78,12 +81,14 @@ export async function aggregateFiles(settings) {
78
81
  const content = readFile(filePath);
79
82
  const relativePath = getRelative(filePath);
80
83
  // Pre-validate YAML parseability
81
- try {
82
- YAML.parse(content);
83
- }
84
- catch (e) {
85
- logger.warn(`Skipping ${relativePath}: YAML file is not parsable`);
86
- return null;
84
+ if (!skipValidation?.yaml) {
85
+ try {
86
+ YAML.parse(content);
87
+ }
88
+ catch (e) {
89
+ logger.warn(`Skipping ${relativePath}: YAML file is not parsable`);
90
+ return null;
91
+ }
87
92
  }
88
93
  const { content: parsedYaml, fileFormat } = parseYaml(content, filePath, settings.options || {});
89
94
  return {
@@ -113,10 +118,12 @@ export async function aggregateFiles(settings) {
113
118
  const content = readFile(filePath);
114
119
  const relativePath = getRelative(filePath);
115
120
  if (fileType === 'mdx') {
116
- const validation = isValidMdx(content, filePath);
117
- if (!validation.isValid) {
118
- logger.warn(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
119
- return null;
121
+ if (!skipValidation?.mdx) {
122
+ const validation = isValidMdx(content, filePath);
123
+ if (!validation.isValid) {
124
+ logger.warn(`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`);
125
+ return null;
126
+ }
120
127
  }
121
128
  }
122
129
  const sanitizedContent = sanitizeFileContent(content);
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "2.5.44";
1
+ export declare const PACKAGE_VERSION = "2.5.45";
@@ -1,2 +1,2 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
- export const PACKAGE_VERSION = '2.5.44';
2
+ export const PACKAGE_VERSION = '2.5.45';
@@ -0,0 +1,31 @@
1
+ import { FrameworkObject } from '../types/index.js';
2
+ /**
3
+ * Detects the frontend framework used in the current project.
4
+ *
5
+ * Analyzes the project structure and dependencies to identify the framework.
6
+ * Detection order: Mintlify → Next.js (App/Pages Router) → Gatsby → RedwoodJS → Vite → React.
7
+ *
8
+ * For Next.js projects, further determines whether it uses App Router or Pages Router
9
+ * by checking for the presence of `app/` or `pages/` directories.
10
+ *
11
+ * @returns A promise resolving to a FrameworkObject containing:
12
+ * - `name`: The detected framework identifier (e.g., 'next-app', 'gatsby', 'react')
13
+ * or undefined if no framework is detected
14
+ * - `type`: The framework category (currently only 'react' for React-based frameworks)
15
+ */
16
+ export declare function detectFramework(): Promise<FrameworkObject | {
17
+ name: undefined;
18
+ type?: undefined;
19
+ }>;
20
+ /**
21
+ * Detects if the current project is a Mintlify documentation project.
22
+ *
23
+ * Checks for the presence of docs.json (preferred) or mint.json (legacy) files.
24
+ * For docs.json, validates that the $schema field contains "mintlify.com/docs.json".
25
+ * Rejects projects with Next.js config files to avoid misclassification.
26
+ *
27
+ * @param _packageJson - The parsed package.json object (not used for Mintlify detection,
28
+ * but kept for API consistency with other detection functions)
29
+ * @returns True if the project is identified as a Mintlify project, false otherwise
30
+ */
31
+ export declare function isMintlifyProject(_packageJson: Record<string, any> | null): boolean;
@@ -0,0 +1,106 @@
1
+ import { isPackageInstalled } from '../utils/packageJson.js';
2
+ import { searchForPackageJson } from '../utils/packageJson.js';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ /* ----- MAIN ----- */
6
+ /**
7
+ * Detects the frontend framework used in the current project.
8
+ *
9
+ * Analyzes the project structure and dependencies to identify the framework.
10
+ * Detection order: Mintlify → Next.js (App/Pages Router) → Gatsby → RedwoodJS → Vite → React.
11
+ *
12
+ * For Next.js projects, further determines whether it uses App Router or Pages Router
13
+ * by checking for the presence of `app/` or `pages/` directories.
14
+ *
15
+ * @returns A promise resolving to a FrameworkObject containing:
16
+ * - `name`: The detected framework identifier (e.g., 'next-app', 'gatsby', 'react')
17
+ * or undefined if no framework is detected
18
+ * - `type`: The framework category (currently only 'react' for React-based frameworks)
19
+ */
20
+ export async function detectFramework() {
21
+ const packageJson = await searchForPackageJson();
22
+ if (isMintlifyProject(packageJson)) {
23
+ return { name: 'mintlify' };
24
+ }
25
+ if (!packageJson) {
26
+ return { name: undefined };
27
+ }
28
+ // Check for Next.js first
29
+ if (isPackageInstalled('next', packageJson, false, true)) {
30
+ // Determine if it's App Router or Pages Router
31
+ const cwd = process.cwd();
32
+ const hasAppDir = fs.existsSync(path.join(cwd, 'app')) ||
33
+ fs.existsSync(path.join(cwd, 'src', 'app'));
34
+ const hasPagesDir = fs.existsSync(path.join(cwd, 'pages')) ||
35
+ fs.existsSync(path.join(cwd, 'src', 'pages'));
36
+ // App Router takes precedence if both exist
37
+ if (hasAppDir) {
38
+ return { name: 'next-app', type: 'react' };
39
+ }
40
+ if (hasPagesDir) {
41
+ return { name: 'next-pages', type: 'react' };
42
+ }
43
+ // Default to app router for new Next.js projects
44
+ return { name: 'next-app', type: 'react' };
45
+ }
46
+ // Check for Gatsby
47
+ if (isPackageInstalled('gatsby', packageJson, false, true)) {
48
+ return { name: 'gatsby', type: 'react' };
49
+ }
50
+ // Check for RedwoodJS
51
+ if (isPackageInstalled('@redwoodjs/core', packageJson, false, true)) {
52
+ return { name: 'redwood', type: 'react' };
53
+ }
54
+ // Check for Vite
55
+ if (isPackageInstalled('vite', packageJson, false, true)) {
56
+ return { name: 'vite', type: 'react' };
57
+ }
58
+ // Check for React (generic)
59
+ if (isPackageInstalled('react', packageJson, false, true)) {
60
+ return { name: 'react', type: 'react' };
61
+ }
62
+ return { name: undefined };
63
+ }
64
+ // ----- HELPER FUNCTIONS ----- //
65
+ /**
66
+ * Detects if the current project is a Mintlify documentation project.
67
+ *
68
+ * Checks for the presence of docs.json (preferred) or mint.json (legacy) files.
69
+ * For docs.json, validates that the $schema field contains "mintlify.com/docs.json".
70
+ * Rejects projects with Next.js config files to avoid misclassification.
71
+ *
72
+ * @param _packageJson - The parsed package.json object (not used for Mintlify detection,
73
+ * but kept for API consistency with other detection functions)
74
+ * @returns True if the project is identified as a Mintlify project, false otherwise
75
+ */
76
+ export function isMintlifyProject(_packageJson) {
77
+ const cwd = process.cwd();
78
+ // Check for Next.js config files - if present, this is not a Mintlify project
79
+ const nextConfigFiles = [
80
+ 'next.config.js',
81
+ 'next.config.ts',
82
+ 'next.config.mjs',
83
+ 'next.config.cjs',
84
+ ];
85
+ for (const configFile of nextConfigFiles) {
86
+ if (fs.existsSync(path.join(cwd, configFile))) {
87
+ return false;
88
+ }
89
+ }
90
+ // Check for docs.json (preferred format)
91
+ const docsJsonPath = path.join(cwd, 'docs.json');
92
+ if (fs.existsSync(docsJsonPath)) {
93
+ try {
94
+ const docsJson = JSON.parse(fs.readFileSync(docsJsonPath, 'utf-8'));
95
+ // Validate the $schema field contains mintlify.com/docs.json
96
+ if (docsJson.$schema &&
97
+ docsJson.$schema.includes('mintlify.com/docs.json')) {
98
+ return true;
99
+ }
100
+ }
101
+ catch {
102
+ return false;
103
+ }
104
+ }
105
+ return false;
106
+ }
@@ -0,0 +1,3 @@
1
+ import { FrameworkObject, ReactFrameworkObject } from '../types/index.js';
2
+ export declare function getFrameworkDisplayName(frameworkObject: FrameworkObject): string;
3
+ export declare function getReactFrameworkLibrary(frameworkObject: ReactFrameworkObject): string;
@@ -0,0 +1,27 @@
1
+ export function getFrameworkDisplayName(frameworkObject) {
2
+ if (frameworkObject.name === 'mintlify') {
3
+ return 'Mintlify';
4
+ }
5
+ if (frameworkObject.name === 'next-app') {
6
+ return 'Next.js App Router';
7
+ }
8
+ if (frameworkObject.name === 'next-pages') {
9
+ return 'Next.js Pages Router';
10
+ }
11
+ if (frameworkObject.name === 'vite') {
12
+ return 'Vite + React';
13
+ }
14
+ if (frameworkObject.name === 'gatsby') {
15
+ return 'Gatsby';
16
+ }
17
+ if (frameworkObject.name === 'redwood') {
18
+ return 'RedwoodJS';
19
+ }
20
+ if (frameworkObject.type === 'react') {
21
+ return 'React';
22
+ }
23
+ return 'another framework';
24
+ }
25
+ export function getReactFrameworkLibrary(frameworkObject) {
26
+ return frameworkObject.name === 'next-app' ? 'gt-next' : 'gt-react';
27
+ }
@@ -10,19 +10,19 @@ export async function getDesiredLocales() {
10
10
  });
11
11
  // Ask for the locales
12
12
  const locales = await promptText({
13
- message: `What locales would you like to translate your project into? ${chalk.dim('(space-separated list)')}`,
14
- defaultValue: 'es zh fr de ja',
13
+ message: `Which languages would you like to translate your project into? Enter your response as a list of BCP-47 locale tags. ${chalk.dim('(space-separated list)')}`,
14
+ defaultValue: 'es fr de ja zh',
15
15
  validate: (input) => {
16
16
  const localeList = input.split(' ');
17
17
  if (localeList.length === 0) {
18
18
  return 'Please enter at least one locale';
19
19
  }
20
20
  if (localeList.some((locale) => !locale.trim())) {
21
- return 'Please enter a valid locale (e.g., en, fr, es)';
21
+ return 'Please enter a valid locale (e.g., es fr de)';
22
22
  }
23
23
  for (const locale of localeList) {
24
24
  if (!gt.isValidLocale(locale)) {
25
- return 'Please enter a valid locale (e.g., en, fr, es)';
25
+ return 'Please enter a valid locale (e.g., es fr de)';
26
26
  }
27
27
  }
28
28
  return true;
@@ -1,2 +1,3 @@
1
1
  import { SetupOptions } from '../types/index.js';
2
- export declare function handleSetupReactCommand(options: SetupOptions): Promise<void>;
2
+ import { ReactFrameworkObject } from '../types/index.js';
3
+ export declare function handleSetupReactCommand(options: SetupOptions, frameworkObject: ReactFrameworkObject): Promise<void>;
@@ -14,11 +14,12 @@ import { createOrUpdateConfig } from '../fs/config/setupConfig.js';
14
14
  import { loadConfig } from '../fs/config/loadConfig.js';
15
15
  import { addVitePlugin } from '../react/parse/addVitePlugin/index.js';
16
16
  import { exitSync } from '../console/logging.js';
17
- export async function handleSetupReactCommand(options) {
17
+ import { getFrameworkDisplayName } from './frameworkUtils.js';
18
+ export async function handleSetupReactCommand(options, frameworkObject) {
19
+ const frameworkDisplayName = getFrameworkDisplayName(frameworkObject);
18
20
  // Ask user for confirmation using inquirer
19
21
  const answer = await promptConfirm({
20
- message: chalk.yellow(`This wizard will configure your React project for internationalization with GT.
21
- If your project is already using a different i18n library, this wizard may cause issues.
22
+ message: chalk.yellow(`This wizard will configure your ${frameworkDisplayName} project for internationalization with GT. If your project is already using a different i18n library, this wizard may cause issues.
22
23
 
23
24
  Make sure you have committed or stashed any changes. Do you want to continue?`),
24
25
  defaultValue: true,
@@ -29,7 +30,7 @@ Make sure you have committed or stashed any changes. Do you want to continue?`),
29
30
  exitSync(0);
30
31
  }
31
32
  const frameworkType = await promptSelect({
32
- message: 'What framework are you using?',
33
+ message: 'Which framework are you using?',
33
34
  options: [
34
35
  { value: 'next-app', label: chalk.blue('Next.js App Router') },
35
36
  { value: 'next-pages', label: chalk.green('Next.js Pages Router') },
@@ -39,11 +40,11 @@ Make sure you have committed or stashed any changes. Do you want to continue?`),
39
40
  { value: 'redwood', label: chalk.red('RedwoodJS') },
40
41
  { value: 'other', label: chalk.dim('Other') },
41
42
  ],
42
- defaultValue: 'next-app',
43
+ defaultValue: frameworkObject?.name || 'other',
43
44
  });
44
45
  if (frameworkType === 'other') {
45
- logger.error(`Sorry, other React frameworks are not currently supported.
46
- Please let us know what you would like to see supported at https://github.com/generaltranslation/gt/issues`);
46
+ logger.error(`Sorry, the wizard doesn't currently support other React frameworks.
47
+ Please let us know what you would like to see added at https://github.com/generaltranslation/gt/issues`);
47
48
  exitSync(0);
48
49
  }
49
50
  // ----- Create a starter gt.config.json file -----
@@ -93,7 +93,21 @@ export type GenerateSourceOptions = {
93
93
  suppressWarnings: boolean;
94
94
  };
95
95
  export type Framework = 'gt-next' | 'gt-react';
96
- export type SupportedFrameworks = 'next-app' | 'next-pages' | 'vite' | 'gatsby' | 'react' | 'redwood';
96
+ export type FrameworkObject = {
97
+ name: 'mintlify';
98
+ type?: undefined;
99
+ } | {
100
+ name: 'next-app' | 'next-pages' | 'vite' | 'gatsby' | 'redwood' | 'react';
101
+ type: 'react';
102
+ };
103
+ export type ReactFrameworkObject = Extract<FrameworkObject, {
104
+ type: 'react';
105
+ }>;
106
+ export type FrameworkType = FrameworkObject['type'];
107
+ export type SupportedFrameworks = FrameworkObject['name'];
108
+ export type SupportedReactFrameworks = Extract<FrameworkObject, {
109
+ type: 'react';
110
+ }>['name'];
97
111
  export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'i18next' | 'i18next-icu' | 'base';
98
112
  export interface ContentScanner {
99
113
  scanForContent(options: WrapOptions, framework: Framework): Promise<{
@@ -167,6 +181,11 @@ export type AdditionalOptions = {
167
181
  yamlSchema?: {
168
182
  [fileGlob: string]: YamlSchema;
169
183
  };
184
+ skipFileValidation?: {
185
+ json?: boolean;
186
+ yaml?: boolean;
187
+ mdx?: boolean;
188
+ };
170
189
  mintlify?: MintlifyOptions;
171
190
  docsUrlPattern?: string;
172
191
  docsImportPattern?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.5.44",
3
+ "version": "2.5.45",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [