gtx-cli 1.2.15 → 1.2.17

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 (142) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/api/checkFileTranslations.d.ts +19 -0
  3. package/dist/api/checkFileTranslations.js +244 -0
  4. package/dist/api/downloadFile.d.ts +1 -0
  5. package/dist/api/downloadFile.js +83 -0
  6. package/dist/api/downloadFileBatch.d.ts +16 -0
  7. package/dist/api/downloadFileBatch.js +127 -0
  8. package/dist/api/fetchTranslations.d.ts +10 -0
  9. package/dist/api/fetchTranslations.js +35 -0
  10. package/dist/api/sendFiles.d.ts +24 -0
  11. package/dist/api/sendFiles.js +63 -0
  12. package/dist/api/sendUpdates.d.ts +19 -0
  13. package/dist/api/sendUpdates.js +75 -0
  14. package/dist/api/waitForUpdates.d.ts +11 -0
  15. package/dist/api/waitForUpdates.js +96 -0
  16. package/dist/cli/base.d.ts +28 -0
  17. package/dist/cli/base.js +322 -0
  18. package/dist/cli/next.d.ts +10 -0
  19. package/dist/cli/next.js +27 -0
  20. package/dist/cli/react.d.ts +18 -0
  21. package/dist/cli/react.js +305 -0
  22. package/dist/config/generateSettings.d.ts +7 -0
  23. package/dist/config/generateSettings.js +94 -0
  24. package/dist/config/utils.d.ts +2 -0
  25. package/dist/config/utils.js +7 -0
  26. package/dist/config/validateSettings.d.ts +2 -0
  27. package/dist/config/validateSettings.js +23 -0
  28. package/dist/console/colors.d.ts +5 -0
  29. package/dist/console/colors.js +26 -0
  30. package/dist/console/console.d.ts +1 -0
  31. package/dist/console/console.js +20 -0
  32. package/dist/console/errors.d.ts +1 -0
  33. package/dist/console/errors.js +20 -0
  34. package/dist/console/index.d.ts +19 -0
  35. package/dist/console/index.js +48 -0
  36. package/dist/console/logging.d.ts +55 -0
  37. package/dist/console/logging.js +207 -0
  38. package/dist/console/warnings.d.ts +1 -0
  39. package/dist/console/warnings.js +20 -0
  40. package/dist/formats/files/save.d.ts +5 -0
  41. package/dist/formats/files/save.js +23 -0
  42. package/dist/formats/files/supportedFiles.d.ts +8 -0
  43. package/dist/formats/files/supportedFiles.js +17 -0
  44. package/dist/formats/files/translate.d.ts +14 -0
  45. package/dist/formats/files/translate.js +218 -0
  46. package/dist/formats/gt/save.d.ts +10 -0
  47. package/dist/formats/gt/save.js +34 -0
  48. package/dist/fs/config/loadConfig.d.ts +1 -0
  49. package/dist/fs/config/loadConfig.js +15 -0
  50. package/dist/fs/config/parseFilesConfig.d.ts +23 -0
  51. package/dist/fs/config/parseFilesConfig.js +128 -0
  52. package/dist/fs/config/setupConfig.d.ts +15 -0
  53. package/dist/fs/config/setupConfig.js +51 -0
  54. package/dist/fs/config/updateConfig.d.ts +11 -0
  55. package/dist/fs/config/updateConfig.js +41 -0
  56. package/dist/fs/determineFramework.d.ts +5 -0
  57. package/dist/fs/determineFramework.js +52 -0
  58. package/dist/fs/findFilepath.d.ts +36 -0
  59. package/dist/fs/findFilepath.js +101 -0
  60. package/dist/fs/findJsxFilepath.d.ts +7 -0
  61. package/dist/fs/findJsxFilepath.js +36 -0
  62. package/dist/fs/index.d.ts +1 -0
  63. package/dist/fs/index.js +2 -0
  64. package/dist/fs/loadJSON.d.ts +6 -0
  65. package/dist/fs/loadJSON.js +23 -0
  66. package/dist/fs/saveJSON.d.ts +1 -0
  67. package/dist/fs/saveJSON.js +13 -0
  68. package/dist/fs/utils.d.ts +1 -0
  69. package/dist/fs/utils.js +19 -0
  70. package/dist/hooks/postProcess.d.ts +4 -0
  71. package/dist/hooks/postProcess.js +118 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +24 -0
  74. package/dist/main.d.ts +2 -0
  75. package/dist/main.js +12 -0
  76. package/dist/next/config/parseNextConfig.d.ts +10 -0
  77. package/dist/next/config/parseNextConfig.js +59 -0
  78. package/dist/next/jsx/utils.d.ts +7 -0
  79. package/dist/next/jsx/utils.js +82 -0
  80. package/dist/next/parse/handleInitGT.d.ts +1 -0
  81. package/dist/next/parse/handleInitGT.js +153 -0
  82. package/dist/next/parse/wrapContent.d.ts +11 -0
  83. package/dist/next/parse/wrapContent.js +181 -0
  84. package/dist/react/config/createESBuildConfig.d.ts +2 -0
  85. package/dist/react/config/createESBuildConfig.js +125 -0
  86. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +1 -0
  87. package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +87 -0
  88. package/dist/react/jsx/evaluateJsx.d.ts +17 -0
  89. package/dist/react/jsx/evaluateJsx.js +133 -0
  90. package/dist/react/jsx/parse/parseStringFunction.d.ts +12 -0
  91. package/dist/react/jsx/parse/parseStringFunction.js +118 -0
  92. package/dist/react/jsx/trimJsxStringChildren.d.ts +7 -0
  93. package/dist/react/jsx/trimJsxStringChildren.js +100 -0
  94. package/dist/react/jsx/utils/parseAst.d.ts +30 -0
  95. package/dist/react/jsx/utils/parseAst.js +319 -0
  96. package/dist/react/jsx/utils/parseJsx.d.ts +13 -0
  97. package/dist/react/jsx/utils/parseJsx.js +250 -0
  98. package/dist/react/jsx/utils/parseStringFunction.d.ts +12 -0
  99. package/dist/react/jsx/utils/parseStringFunction.js +121 -0
  100. package/dist/react/jsx/wrapJsx.d.ts +51 -0
  101. package/dist/react/jsx/wrapJsx.js +411 -0
  102. package/dist/react/parse/createDictionaryUpdates.d.ts +3 -0
  103. package/dist/react/parse/createDictionaryUpdates.js +78 -0
  104. package/dist/react/parse/createInlineUpdates.d.ts +5 -0
  105. package/dist/react/parse/createInlineUpdates.js +135 -0
  106. package/dist/react/parse/wrapContent.d.ts +11 -0
  107. package/dist/react/parse/wrapContent.js +197 -0
  108. package/dist/react/utils/flattenDictionary.d.ts +20 -0
  109. package/dist/react/utils/flattenDictionary.js +79 -0
  110. package/dist/react/utils/getEntryAndMetadata.d.ts +5 -0
  111. package/dist/react/utils/getEntryAndMetadata.js +14 -0
  112. package/dist/react/utils/getVariableName.d.ts +2 -0
  113. package/dist/react/utils/getVariableName.js +17 -0
  114. package/dist/setup/userInput.d.ts +4 -0
  115. package/dist/setup/userInput.js +35 -0
  116. package/dist/setup/wizard.d.ts +2 -0
  117. package/dist/setup/wizard.js +171 -0
  118. package/dist/translation/parse.d.ts +14 -0
  119. package/dist/translation/parse.js +82 -0
  120. package/dist/translation/stage.d.ts +5 -0
  121. package/dist/translation/stage.js +80 -0
  122. package/dist/translation/translate.d.ts +2 -0
  123. package/dist/translation/translate.js +21 -0
  124. package/dist/types/api.d.ts +6 -0
  125. package/dist/types/api.js +2 -0
  126. package/dist/types/data.d.ts +31 -0
  127. package/dist/types/data.js +2 -0
  128. package/dist/types/index.d.ts +101 -0
  129. package/dist/types/index.js +2 -0
  130. package/dist/utils/constants.d.ts +1 -0
  131. package/dist/utils/constants.js +4 -0
  132. package/dist/utils/credentials.d.ts +12 -0
  133. package/dist/utils/credentials.js +128 -0
  134. package/dist/utils/installPackage.d.ts +2 -0
  135. package/dist/utils/installPackage.js +45 -0
  136. package/dist/utils/packageJson.d.ts +5 -0
  137. package/dist/utils/packageJson.js +78 -0
  138. package/dist/utils/packageManager.d.ts +23 -0
  139. package/dist/utils/packageManager.js +261 -0
  140. package/package.json +5 -1
  141. package/.prettierrc +0 -15
  142. package/tsconfig.json +0 -16
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.stageProject = stageProject;
7
+ const errors_1 = require("../console/errors");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const findFilepath_1 = __importDefault(require("../fs/findFilepath"));
10
+ const logging_1 = require("../console/logging");
11
+ const parse_1 = require("./parse");
12
+ const errors_2 = require("../console/errors");
13
+ const sendUpdates_1 = require("../api/sendUpdates");
14
+ async function stageProject(settings, pkg) {
15
+ if (!settings.dictionary) {
16
+ settings.dictionary = (0, findFilepath_1.default)([
17
+ './dictionary.js',
18
+ './src/dictionary.js',
19
+ './dictionary.json',
20
+ './src/dictionary.json',
21
+ './dictionary.ts',
22
+ './src/dictionary.ts',
23
+ ]);
24
+ }
25
+ // Separate defaultLocale from locales
26
+ settings.locales = settings.locales.filter((locale) => locale !== settings.defaultLocale);
27
+ // validate timeout
28
+ const timeout = parseInt(settings.timeout);
29
+ if (isNaN(timeout) || timeout < 0) {
30
+ (0, errors_1.logErrorAndExit)(`Invalid timeout: ${settings.timeout}. Must be a positive integer.`);
31
+ }
32
+ settings.timeout = timeout.toString();
33
+ // ---- CREATING UPDATES ---- //
34
+ const { updates, errors } = await (0, parse_1.createUpdates)(settings, settings.dictionary, pkg);
35
+ if (errors.length > 0) {
36
+ if (settings.ignoreErrors) {
37
+ (0, logging_1.logWarning)(chalk_1.default.yellow(`Warning: CLI tool encountered syntax errors while scanning for translatable content. These components will not be translated.\n` +
38
+ errors
39
+ .map((error) => chalk_1.default.yellow('• ') + chalk_1.default.white(error) + '\n')
40
+ .join('')));
41
+ }
42
+ else {
43
+ (0, errors_1.logErrorAndExit)(chalk_1.default.red(`Error: CLI tool encountered syntax errors while scanning for translatable content. ${chalk_1.default.gray('To ignore these errors, re-run with --ignore-errors')}\n` +
44
+ errors
45
+ .map((error) => chalk_1.default.red('• ') + chalk_1.default.white(error) + '\n')
46
+ .join('')));
47
+ }
48
+ }
49
+ if (settings.dryRun) {
50
+ (0, logging_1.logSuccess)('Dry run: No translations were sent to General Translation.');
51
+ return null;
52
+ }
53
+ if (updates.length == 0) {
54
+ (0, logging_1.logError)(chalk_1.default.red(`No in-line content or dictionaries were found for ${chalk_1.default.green(pkg)}. Are you sure you're running this command in the right directory?`));
55
+ return null;
56
+ }
57
+ // Send updates to General Translation API
58
+ if (!settings.locales) {
59
+ (0, errors_1.logErrorAndExit)(errors_2.noLocalesError);
60
+ }
61
+ if (!settings.defaultLocale) {
62
+ (0, errors_1.logErrorAndExit)(errors_2.noDefaultLocaleError);
63
+ }
64
+ if (!settings.apiKey) {
65
+ (0, errors_1.logErrorAndExit)(errors_2.noApiKeyError);
66
+ }
67
+ if (settings.apiKey.startsWith('gtx-dev-')) {
68
+ (0, errors_1.logErrorAndExit)(errors_1.devApiKeyError);
69
+ }
70
+ if (!settings.projectId) {
71
+ (0, errors_1.logErrorAndExit)(errors_2.noProjectIdError);
72
+ }
73
+ const updateResponse = await (0, sendUpdates_1.sendUpdates)(updates, {
74
+ ...settings,
75
+ timeout: settings.timeout,
76
+ dataFormat: 'JSX',
77
+ }, pkg);
78
+ const { versionId, locales } = updateResponse;
79
+ return { versionId, locales };
80
+ }
@@ -0,0 +1,2 @@
1
+ import { Options, Settings } from '../types';
2
+ export declare function translate(settings: Options & Settings, versionId: string): Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translate = translate;
4
+ const fetchTranslations_1 = require("../api/fetchTranslations");
5
+ const waitForUpdates_1 = require("../api/waitForUpdates");
6
+ const save_1 = require("../formats/gt/save");
7
+ const utils_1 = require("../config/utils");
8
+ async function translate(settings, versionId) {
9
+ // timeout was validated earlier
10
+ const startTime = Date.now();
11
+ const timeout = parseInt(settings.timeout) * 1000;
12
+ const result = await (0, waitForUpdates_1.waitForUpdates)(settings.apiKey, settings.baseUrl, versionId, startTime, timeout);
13
+ if (!result) {
14
+ process.exit(1);
15
+ }
16
+ const translations = await (0, fetchTranslations_1.fetchTranslations)(settings.baseUrl, settings.apiKey, versionId);
17
+ // Save translations to local directory if files.gt.output is provided
18
+ if (settings.files && (0, utils_1.isUsingLocalTranslations)(settings)) {
19
+ await (0, save_1.saveTranslations)(translations, settings.files.placeholderPaths, 'JSX');
20
+ }
21
+ }
@@ -0,0 +1,6 @@
1
+ export type RetrievedTranslation = {
2
+ locale: string;
3
+ translation: any;
4
+ metadata: any;
5
+ };
6
+ export type RetrievedTranslations = RetrievedTranslation[];
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,31 @@
1
+ export type Entry = string;
2
+ export type DictionaryMetadata = {
3
+ context?: string;
4
+ variablesOptions?: Record<string, any>;
5
+ [key: string]: any;
6
+ };
7
+ export type DictionaryEntry = Entry | [Entry] | [Entry, DictionaryMetadata];
8
+ export type Dictionary = {
9
+ [key: string]: Dictionary | DictionaryEntry;
10
+ };
11
+ export type FlattenedDictionary = {
12
+ [key: string]: DictionaryEntry;
13
+ };
14
+ export type JSONDictionary = {
15
+ [key: string]: string | JSONDictionary;
16
+ };
17
+ export type FlattenedJSONDictionary = {
18
+ [key: string]: string;
19
+ };
20
+ export type DataFormat = 'JSX' | 'ICU' | 'I18NEXT';
21
+ export type FileFormats = 'JSON' | 'YAML' | 'MDX' | 'MD' | 'TS' | 'JS';
22
+ export type JsxChildren = string | string[] | any;
23
+ export type Translations = {
24
+ [key: string]: JsxChildren;
25
+ };
26
+ export type TranslationsMetadata = {
27
+ [key: string]: {
28
+ id?: string;
29
+ hash?: string;
30
+ };
31
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,101 @@
1
+ import { JsxChildren } from 'generaltranslation/internal';
2
+ import { SUPPORTED_FILE_EXTENSIONS } from '../formats/files/supportedFiles';
3
+ export type Updates = ({
4
+ metadata: Record<string, any>;
5
+ } & ({
6
+ dataFormat: 'JSX';
7
+ source: JsxChildren;
8
+ } | {
9
+ dataFormat: 'ICU';
10
+ source: string;
11
+ } | {
12
+ dataFormat: 'I18NEXT';
13
+ source: string;
14
+ }))[];
15
+ export type Options = {
16
+ config: string;
17
+ apiKey?: string;
18
+ projectId?: string;
19
+ versionId?: string;
20
+ jsconfig?: string;
21
+ dictionary?: string;
22
+ src?: string[];
23
+ defaultLocale?: string;
24
+ locales?: string[];
25
+ baseUrl: string;
26
+ inline?: boolean;
27
+ ignoreErrors: boolean;
28
+ dryRun: boolean;
29
+ timeout: string;
30
+ stageTranslations?: boolean;
31
+ };
32
+ export type WrapOptions = {
33
+ src: string[];
34
+ config: string;
35
+ disableIds: boolean;
36
+ disableFormatting: boolean;
37
+ addGTProvider: boolean;
38
+ };
39
+ export type SetupOptions = {
40
+ src: string[];
41
+ config: string;
42
+ };
43
+ export type GenerateSourceOptions = {
44
+ src: string[];
45
+ config: string;
46
+ defaultLocale: string;
47
+ dictionary?: string;
48
+ jsconfig?: string;
49
+ inline?: boolean;
50
+ ignoreErrors: boolean;
51
+ };
52
+ export type Framework = 'gt-next' | 'gt-react';
53
+ export type SupportedFrameworks = 'next-app' | 'next-pages' | 'vite' | 'gatsby' | 'react' | 'redwood';
54
+ export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'i18next' | 'i18next-icu' | 'base';
55
+ export interface ContentScanner {
56
+ scanForContent(options: WrapOptions, framework: Framework): Promise<{
57
+ errors: string[];
58
+ filesUpdated: string[];
59
+ warnings: string[];
60
+ }>;
61
+ }
62
+ export type SupportedFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
63
+ export type ResolvedFiles = {
64
+ [K in SupportedFileExtension]?: string[];
65
+ } & {
66
+ gt?: string;
67
+ };
68
+ export type TransformFiles = {
69
+ [K in SupportedFileExtension]?: string;
70
+ };
71
+ export type FilesOptions = {
72
+ [K in SupportedFileExtension]?: {
73
+ include: string[];
74
+ exclude?: string[];
75
+ transform?: string;
76
+ };
77
+ } & {
78
+ gt?: {
79
+ output: string;
80
+ };
81
+ };
82
+ export type Settings = {
83
+ config: string;
84
+ baseUrl: string;
85
+ dashboardUrl: string;
86
+ apiKey: string;
87
+ projectId: string;
88
+ defaultLocale: string;
89
+ locales: string[];
90
+ files: {
91
+ resolvedPaths: ResolvedFiles;
92
+ placeholderPaths: ResolvedFiles;
93
+ transformPaths: TransformFiles;
94
+ } | undefined;
95
+ stageTranslations: boolean;
96
+ _versionId?: string;
97
+ version?: string;
98
+ description?: string;
99
+ src?: string[];
100
+ framework?: SupportedFrameworks;
101
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare const GT_DASHBOARD_URL = "https://dash.generaltranslation.com";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GT_DASHBOARD_URL = void 0;
4
+ exports.GT_DASHBOARD_URL = 'https://dash.generaltranslation.com';
@@ -0,0 +1,12 @@
1
+ import { Settings, SupportedFrameworks } from '../types';
2
+ type Credentials = {
3
+ apiKey: string;
4
+ projectId: string;
5
+ };
6
+ export declare function retrieveCredentials(settings: Settings, keyType: 'development' | 'production'): Promise<Credentials>;
7
+ export declare function generateCredentialsSession(url: string, keyType: 'development' | 'production'): Promise<{
8
+ sessionId: string;
9
+ }>;
10
+ export declare function areCredentialsSet(): string | undefined;
11
+ export declare function setCredentials(credentials: Credentials, type: 'development' | 'production', framework?: SupportedFrameworks): Promise<void>;
12
+ export {};
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.retrieveCredentials = retrieveCredentials;
7
+ exports.generateCredentialsSession = generateCredentialsSession;
8
+ exports.areCredentialsSet = areCredentialsSet;
9
+ exports.setCredentials = setCredentials;
10
+ const console_1 = require("../console");
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const chalk_1 = __importDefault(require("chalk"));
14
+ // Fetches project ID and API key by opening the dashboard in the browser
15
+ async function retrieveCredentials(settings, keyType) {
16
+ // Generate a session ID
17
+ const { sessionId } = await generateCredentialsSession(settings.baseUrl, keyType);
18
+ const urlToOpen = `${settings.dashboardUrl}/cli/wizard/${sessionId}`;
19
+ await import('open').then((open) => open.default(urlToOpen, {
20
+ wait: false,
21
+ }));
22
+ (0, console_1.logMessage)(`${chalk_1.default.gray(`If the browser window didn't open automatically, please open the following link:`)}\n\n${chalk_1.default.cyan(urlToOpen)}`);
23
+ const spinner = (0, console_1.createSpinner)('dots');
24
+ spinner.start('Waiting for response from dashboard...');
25
+ const credentials = await new Promise(async (resolve, reject) => {
26
+ const interval = setInterval(async () => {
27
+ // Ping the dashboard to see if the credentials are set
28
+ try {
29
+ const res = await fetch(`${settings.baseUrl}/cli/wizard/${sessionId}`, {
30
+ method: 'GET',
31
+ });
32
+ if (res.status === 200) {
33
+ const data = await res.json();
34
+ resolve(data);
35
+ clearInterval(interval);
36
+ clearTimeout(timeout);
37
+ fetch(`${settings.baseUrl}/cli/wizard/${sessionId}`, {
38
+ method: 'DELETE',
39
+ });
40
+ }
41
+ }
42
+ catch (err) {
43
+ console.error(err);
44
+ }
45
+ }, 2000);
46
+ // timeout after 1 hour
47
+ const timeout = setTimeout(() => {
48
+ spinner.stop('Timed out');
49
+ clearInterval(interval);
50
+ (0, console_1.logErrorAndExit)('Timed out waiting for response from dashboard');
51
+ }, 1000 * 60 * 60);
52
+ });
53
+ spinner.stop('Received credentials');
54
+ return credentials;
55
+ }
56
+ async function generateCredentialsSession(url, keyType) {
57
+ const res = await fetch(`${url}/cli/wizard/session`, {
58
+ method: 'POST',
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ },
62
+ body: JSON.stringify({
63
+ keyType,
64
+ }),
65
+ });
66
+ if (!res.ok) {
67
+ (0, console_1.logErrorAndExit)('Failed to generate credentials session');
68
+ }
69
+ return await res.json();
70
+ }
71
+ // Checks if the credentials are set in the environment variables
72
+ function areCredentialsSet() {
73
+ return process.env.GT_PROJECT_ID && process.env.GT_API_KEY;
74
+ }
75
+ // Sets the credentials in .env.local file
76
+ async function setCredentials(credentials, type, framework) {
77
+ const envFile = node_path_1.default.join(process.cwd(), '.env.local');
78
+ let envContent = '';
79
+ // Check if .env.local exists, create it if it doesn't
80
+ if (!node_fs_1.default.existsSync(envFile)) {
81
+ // File doesn't exist, create it
82
+ await node_fs_1.default.promises.writeFile(envFile, '', 'utf8');
83
+ // Add .env.local to .gitignore if it exists
84
+ const gitignoreFile = node_path_1.default.join(process.cwd(), '.gitignore');
85
+ if (node_fs_1.default.existsSync(gitignoreFile)) {
86
+ const gitignoreContent = await node_fs_1.default.promises.readFile(gitignoreFile, 'utf8');
87
+ if (!gitignoreContent.includes('.env.local')) {
88
+ await node_fs_1.default.promises.appendFile(gitignoreFile, '\n.env.local\n', 'utf8');
89
+ }
90
+ }
91
+ else {
92
+ // Create .gitignore file with .env.local
93
+ await node_fs_1.default.promises.writeFile(gitignoreFile, '.env.local\n', 'utf8');
94
+ }
95
+ }
96
+ else {
97
+ // Read existing content
98
+ envContent = await node_fs_1.default.promises.readFile(envFile, 'utf8');
99
+ }
100
+ // Always append the credentials to the file
101
+ let prefix = '';
102
+ if (framework === 'next-pages') {
103
+ prefix = 'NEXT_PUBLIC_';
104
+ }
105
+ else if (framework === 'vite') {
106
+ prefix = 'VITE_';
107
+ }
108
+ else if (framework === 'gatsby') {
109
+ prefix = 'GATSBY_';
110
+ }
111
+ else if (framework === 'react') {
112
+ prefix = 'REACT_APP_';
113
+ }
114
+ else if (framework === 'redwood') {
115
+ prefix = 'REDWOOD_ENV_';
116
+ }
117
+ envContent += `\n${prefix}GT_PROJECT_ID=${credentials.projectId}\n`;
118
+ if (type === 'development') {
119
+ envContent += `${prefix || ''}GT_DEV_API_KEY=${credentials.apiKey}\n`;
120
+ }
121
+ else {
122
+ envContent += `GT_API_KEY=${credentials.apiKey}\n`;
123
+ }
124
+ // Ensure we don't have excessive newlines
125
+ envContent = envContent.replace(/\n{3,}/g, '\n\n').trim() + '\n';
126
+ // Write the updated content back to the file
127
+ await node_fs_1.default.promises.writeFile(envFile, envContent, 'utf8');
128
+ }
@@ -0,0 +1,2 @@
1
+ import { PackageManager } from './packageManager';
2
+ export declare function installPackage(packageName: string, packageManager: PackageManager, asDevDependency?: boolean): Promise<void>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.installPackage = installPackage;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ const console_1 = require("../console");
10
+ async function installPackage(packageName, packageManager, asDevDependency) {
11
+ return new Promise((resolve, reject) => {
12
+ const command = packageManager.name;
13
+ const args = [packageManager.installCommand, packageName];
14
+ if (asDevDependency) {
15
+ args.push(packageManager.devDependencyFlag);
16
+ }
17
+ const childProcess = (0, child_process_1.spawn)(command, args, {
18
+ stdio: ['pipe', 'ignore', 'pipe'],
19
+ });
20
+ let errorOutput = '';
21
+ if (childProcess.stderr) {
22
+ childProcess.stderr.on('data', (data) => {
23
+ errorOutput += data.toString();
24
+ });
25
+ }
26
+ childProcess.on('error', (error) => {
27
+ (0, console_1.logError)(chalk_1.default.red(`Installation error: ${error.message}`));
28
+ (0, console_1.logInfo)(`Please manually install ${packageName} with: ${packageManager.name} ${packageManager.installCommand} ${packageName}`);
29
+ reject(error);
30
+ });
31
+ childProcess.on('close', (code) => {
32
+ if (code === 0) {
33
+ resolve();
34
+ }
35
+ else {
36
+ (0, console_1.logError)(chalk_1.default.red(`Installation failed with exit code ${code}`));
37
+ if (errorOutput) {
38
+ (0, console_1.logError)(chalk_1.default.red(`Error details: ${errorOutput}`));
39
+ }
40
+ (0, console_1.logInfo)(`Please manually install ${packageName} with: ${packageManager.name} ${packageManager.installCommand} ${packageName}`);
41
+ reject(new Error(`Process exited with code ${code}`));
42
+ }
43
+ });
44
+ });
45
+ }
@@ -0,0 +1,5 @@
1
+ export declare function searchForPackageJson(): Promise<Record<string, any> | null>;
2
+ export declare function getPackageJson(): Promise<Record<string, any>>;
3
+ export declare function updatePackageJson(packageJson: Record<string, any>): Promise<void>;
4
+ export declare function isPackageInstalled(packageName: string, packageJson: Record<string, any>, asDevDependency?: boolean, checkBoth?: boolean): boolean;
5
+ export declare function getPackageVersion(packageName: string, packageJson: Record<string, any>): string | undefined;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.searchForPackageJson = searchForPackageJson;
7
+ exports.getPackageJson = getPackageJson;
8
+ exports.updatePackageJson = updatePackageJson;
9
+ exports.isPackageInstalled = isPackageInstalled;
10
+ exports.getPackageVersion = getPackageVersion;
11
+ const console_1 = require("../console");
12
+ const chalk_1 = __importDefault(require("chalk"));
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const node_fs_1 = __importDefault(require("node:fs"));
15
+ const console_2 = require("../console");
16
+ // search for package.json such that we can run init in non-js projects
17
+ async function searchForPackageJson() {
18
+ // Get the current working directory (where the CLI is being run)
19
+ const cwd = process.cwd();
20
+ const packageJsonPath = node_path_1.default.join(cwd, 'package.json');
21
+ // Check if package.json exists
22
+ if (!node_fs_1.default.existsSync(packageJsonPath)) {
23
+ return null;
24
+ }
25
+ try {
26
+ return JSON.parse(await node_fs_1.default.promises.readFile(packageJsonPath, 'utf8'));
27
+ }
28
+ catch (error) {
29
+ return null;
30
+ }
31
+ }
32
+ async function getPackageJson() {
33
+ // Get the current working directory (where the CLI is being run)
34
+ const cwd = process.cwd();
35
+ const packageJsonPath = node_path_1.default.join(cwd, 'package.json');
36
+ // Check if package.json exists
37
+ if (!node_fs_1.default.existsSync(packageJsonPath)) {
38
+ (0, console_2.logErrorAndExit)(chalk_1.default.red('No package.json found in the current directory. Please run this command from the root of your project.'));
39
+ }
40
+ try {
41
+ return JSON.parse(await node_fs_1.default.promises.readFile(packageJsonPath, 'utf8'));
42
+ }
43
+ catch (error) {
44
+ (0, console_1.logError)(chalk_1.default.red('Error parsing package.json: ' + String(error)));
45
+ process.exit(1);
46
+ }
47
+ }
48
+ async function updatePackageJson(packageJson) {
49
+ try {
50
+ await node_fs_1.default.promises.writeFile(node_path_1.default.join(process.cwd(), 'package.json'), JSON.stringify(packageJson, null, 2));
51
+ }
52
+ catch (error) {
53
+ (0, console_1.logError)(chalk_1.default.red('Error updating package.json: ' + String(error)));
54
+ process.exit(1);
55
+ }
56
+ }
57
+ // check if a package is installed in the package.json file
58
+ function isPackageInstalled(packageName, packageJson, asDevDependency = false, checkBoth = false) {
59
+ const dependencies = checkBoth
60
+ ? {
61
+ ...packageJson.devDependencies,
62
+ ...packageJson.dependencies,
63
+ }
64
+ : asDevDependency
65
+ ? packageJson.devDependencies
66
+ : packageJson.dependencies;
67
+ if (!dependencies) {
68
+ return false;
69
+ }
70
+ return dependencies[packageName] !== undefined;
71
+ }
72
+ function getPackageVersion(packageName, packageJson) {
73
+ const dependencies = {
74
+ ...packageJson.dependencies,
75
+ ...packageJson.devDependencies,
76
+ };
77
+ return dependencies[packageName] ?? undefined;
78
+ }
@@ -0,0 +1,23 @@
1
+ export interface PackageManager {
2
+ name: string;
3
+ label: string;
4
+ installCommand: string;
5
+ buildCommand: string;
6
+ runScriptCommand: string;
7
+ flags: string;
8
+ forceInstallFlag: string;
9
+ devDependencyFlag: string;
10
+ registry?: string;
11
+ detect: () => boolean;
12
+ addOverride: (pkgName: string, pkgVersion: string) => Promise<void>;
13
+ }
14
+ export declare const BUN: PackageManager;
15
+ export declare const DENO: PackageManager;
16
+ export declare const YARN_V1: PackageManager;
17
+ /** YARN V2/3/4 */
18
+ export declare const YARN_V2: PackageManager;
19
+ export declare const PNPM: PackageManager;
20
+ export declare const NPM: PackageManager;
21
+ export declare const packageManagers: PackageManager[];
22
+ export declare function _detectPackageManger(managers?: PackageManager[]): PackageManager | null;
23
+ export declare function getPackageManager(): Promise<PackageManager>;