gtx-cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
1
  import { SupportedLibraries } from '../types';
2
2
  export declare class BaseCLI {
3
3
  private library;
4
- constructor(library: SupportedLibraries);
4
+ private additionalModules;
5
+ constructor(library: SupportedLibraries, additionalModules?: SupportedLibraries[]);
5
6
  init(): void;
6
7
  execute(): void;
7
8
  protected setupGTCommand(): void;
package/dist/cli/base.js CHANGED
@@ -59,11 +59,13 @@ const yaml_1 = __importDefault(require("yaml"));
59
59
  const translate_1 = require("../formats/json/translate");
60
60
  const utils_1 = require("../fs/utils");
61
61
  const generateSettings_1 = require("../config/generateSettings");
62
+ const chalk_1 = __importDefault(require("chalk"));
62
63
  const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
63
64
  class BaseCLI {
64
65
  // Constructor is shared amongst all CLI class types
65
- constructor(library) {
66
+ constructor(library, additionalModules) {
66
67
  this.library = library;
68
+ this.additionalModules = additionalModules || [];
67
69
  this.setupInitCommand();
68
70
  }
69
71
  // Init is never called in a child class
@@ -119,13 +121,21 @@ class BaseCLI {
119
121
  const fileExtension = settings.translationsDir
120
122
  .split('.')
121
123
  .pop();
122
- const dataFormat = this.library === 'next-intl'
123
- ? 'ICU'
124
- : this.library === 'react-i18next'
125
- ? 'I18NEXT'
126
- : this.library === 'next-i18next'
127
- ? 'I18NEXT'
128
- : 'JSX';
124
+ let dataFormat;
125
+ if (this.library === 'next-intl') {
126
+ dataFormat = 'ICU';
127
+ }
128
+ else if (this.library === 'i18next') {
129
+ if (this.additionalModules.includes('i18next-icu')) {
130
+ dataFormat = 'ICU';
131
+ }
132
+ else {
133
+ dataFormat = 'I18NEXT';
134
+ }
135
+ }
136
+ else {
137
+ dataFormat = 'JSX';
138
+ }
129
139
  if (!dataFormat) {
130
140
  console.error(errors_1.noDataFormatError);
131
141
  process.exit(1);
@@ -147,17 +157,14 @@ class BaseCLI {
147
157
  .action(() => __awaiter(this, void 0, void 0, function* () {
148
158
  (0, console_1.displayAsciiTitle)();
149
159
  (0, console_2.displayInitializingText)();
150
- // Ask where the translations are stored
151
- const translationsDir = yield (0, prompts_1.input)({
152
- message: 'Where is the directory containing your language files?',
153
- });
154
160
  // Ask for the default locale
155
161
  const defaultLocale = yield (0, prompts_1.input)({
156
162
  message: 'What is the default locale for your project?',
163
+ default: 'en',
157
164
  });
158
165
  // Ask for the locales
159
166
  const locales = yield (0, prompts_1.input)({
160
- message: 'What locales would you like to translate using General Translation? (space-separated list)',
167
+ message: `What locales would you like to translate using General Translation? ${chalk_1.default.gray('(space-separated list)')}`,
161
168
  validate: (input) => {
162
169
  const locales = input.split(' ');
163
170
  if (locales.length === 0) {
@@ -171,20 +178,63 @@ class BaseCLI {
171
178
  return true;
172
179
  },
173
180
  });
174
- const dataFormat = yield (0, prompts_1.select)({
175
- message: 'What is the format of your language files?',
176
- choices: ['.json', '.yaml'],
177
- default: '.json',
181
+ // Ask where the translations are stored
182
+ const location = yield (0, prompts_1.select)({
183
+ message: 'Where are your language files stored? (CDN or local)',
184
+ choices: [
185
+ { value: 'cdn', name: 'CDN' },
186
+ { value: 'local', name: 'Local' },
187
+ ],
188
+ default: 'cdn',
178
189
  });
179
- // combine translationsDir and dataFormat into something like
180
- // translationsDir/*[.json|.yaml]
181
- const translationsDirWithFormat = path_1.default.join(translationsDir, `*${dataFormat}`);
182
- // Create gt.config.json
183
- (0, setupConfig_1.default)('gt.config.json', {
184
- defaultLocale,
185
- locales: locales.split(' '),
186
- translationsDir: translationsDirWithFormat,
190
+ if (location === 'cdn') {
191
+ // Create gt.config.json
192
+ (0, setupConfig_1.default)('gt.config.json', {
193
+ defaultLocale,
194
+ locales: locales.split(' '),
195
+ });
196
+ return;
197
+ }
198
+ // Ask where the translations are stored
199
+ const translationsDir = yield (0, prompts_1.input)({
200
+ message: 'What is the path to the directory containing your language files?',
187
201
  });
202
+ const thirdPartyLibrary = this.library !== 'gt-next' && this.library !== 'gt-react';
203
+ // Ask if using another i18n library
204
+ const i18nLibrary = thirdPartyLibrary
205
+ ? yield (0, prompts_1.select)({
206
+ message: `Are you using a third-party i18n library? (${chalk_1.default.gray(`Auto-detected: ${this.library}`)})`,
207
+ choices: [
208
+ { value: true, name: 'Yes' },
209
+ { value: false, name: 'No' },
210
+ ],
211
+ default: true,
212
+ })
213
+ : false;
214
+ if (i18nLibrary) {
215
+ const dataFormat = yield (0, prompts_1.select)({
216
+ message: 'What is the format of your language files?',
217
+ choices: ['.json', '.yaml'],
218
+ default: '.json',
219
+ });
220
+ // combine translationsDir and dataFormat into something like
221
+ // translationsDir/*[.json|.yaml]
222
+ const translationsDirWithFormat = path_1.default.join(translationsDir, `*${dataFormat}`);
223
+ // Create gt.config.json
224
+ (0, setupConfig_1.default)('gt.config.json', {
225
+ defaultLocale,
226
+ locales: locales.split(' '),
227
+ translationsDir: translationsDirWithFormat,
228
+ });
229
+ }
230
+ else {
231
+ // Create gt.config.json
232
+ (0, setupConfig_1.default)('gt.config.json', {
233
+ defaultLocale,
234
+ locales: locales.split(' '),
235
+ translationsDir: translationsDir,
236
+ });
237
+ }
188
238
  }));
189
239
  }
190
240
  }
@@ -1,7 +1,7 @@
1
- import { WrapOptions, Options, Updates, SetupOptions, SupportedFrameworks } from '../types';
1
+ import { WrapOptions, Options, Updates, SetupOptions, SupportedFrameworks, SupportedLibraries } from '../types';
2
2
  import { ReactCLI } from './react';
3
3
  export declare class NextCLI extends ReactCLI {
4
- constructor();
4
+ constructor(library: SupportedLibraries, additionalModules?: SupportedLibraries[]);
5
5
  init(): void;
6
6
  execute(): void;
7
7
  protected scanForContent(options: WrapOptions, framework: SupportedFrameworks): Promise<{
package/dist/cli/next.js CHANGED
@@ -26,8 +26,8 @@ const react_1 = require("./react");
26
26
  const generateSettings_1 = require("../config/generateSettings");
27
27
  const pkg = 'gt-next';
28
28
  class NextCLI extends react_1.ReactCLI {
29
- constructor() {
30
- super();
29
+ constructor(library, additionalModules) {
30
+ super(library, additionalModules);
31
31
  }
32
32
  init() {
33
33
  this.setupTranslateCommand();
@@ -1,7 +1,7 @@
1
- import { Options, SetupOptions, SupportedFrameworks, Updates, WrapOptions, GenerateSourceOptions } from '../types';
1
+ import { Options, SetupOptions, SupportedFrameworks, Updates, WrapOptions, GenerateSourceOptions, SupportedLibraries } from '../types';
2
2
  import { BaseCLI } from './base';
3
3
  export declare class ReactCLI extends BaseCLI {
4
- constructor();
4
+ constructor(library: SupportedLibraries, additionalModules?: SupportedLibraries[]);
5
5
  init(): void;
6
6
  execute(): void;
7
7
  protected scanForContent(options: WrapOptions, framework: SupportedFrameworks): Promise<{
package/dist/cli/react.js CHANGED
@@ -70,8 +70,8 @@ const saveJSON_1 = require("../fs/saveJSON");
70
70
  const DEFAULT_TIMEOUT = 600;
71
71
  const pkg = 'gt-react';
72
72
  class ReactCLI extends base_1.BaseCLI {
73
- constructor() {
74
- super('gt-react');
73
+ constructor(library, additionalModules) {
74
+ super(library, additionalModules);
75
75
  }
76
76
  init() {
77
77
  this.setupTranslateCommand();
@@ -152,6 +152,10 @@ class ReactCLI extends base_1.BaseCLI {
152
152
  (0, console_1.displayInitializingText)();
153
153
  const settings = (0, generateSettings_1.generateSettings)(options);
154
154
  options = Object.assign(Object.assign({}, options), settings);
155
+ if (!settings.translationsDir) {
156
+ console.log(chalk_1.default.red('Error: the translationsDir path is required'));
157
+ process.exit(1);
158
+ }
155
159
  if (!options.dictionary) {
156
160
  options.dictionary = (0, findFilepath_1.default)([
157
161
  './dictionary.js',
@@ -192,7 +196,7 @@ class ReactCLI extends base_1.BaseCLI {
192
196
  for (const locale of settings.locales) {
193
197
  const existingTranslations = (0, loadJSON_1.default)(path_1.default.join(settings.translationsDir, `${locale}.json`));
194
198
  const mergedTranslations = Object.assign(Object.assign({}, newData), existingTranslations);
195
- // Filter out only keys that exist in newData
199
+ // Filter out keys that don't exist in newData
196
200
  const filteredTranslations = Object.fromEntries(Object.entries(mergedTranslations).filter(([key]) => newData[key]));
197
201
  (0, saveJSON_1.saveJSON)(path_1.default.join(settings.translationsDir, `${locale}.json`), filteredTranslations);
198
202
  }
@@ -1,2 +1,5 @@
1
1
  import { SupportedLibraries } from '../types';
2
- export declare function determineLibrary(): SupportedLibraries;
2
+ export declare function determineLibrary(): {
3
+ library: SupportedLibraries;
4
+ additionalModules: SupportedLibraries[];
5
+ };
@@ -8,6 +8,8 @@ const chalk_1 = __importDefault(require("chalk"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  function determineLibrary() {
11
+ let library = 'base';
12
+ let additionalModules = [];
11
13
  try {
12
14
  // Get the current working directory (where the CLI is being run)
13
15
  const cwd = process.cwd();
@@ -15,32 +17,32 @@ function determineLibrary() {
15
17
  // Check if package.json exists
16
18
  if (!fs_1.default.existsSync(packageJsonPath)) {
17
19
  console.log(chalk_1.default.red('No package.json found in the current directory. Please run this command from the root of your project.'));
18
- return 'base';
20
+ return { library: 'base', additionalModules: [] };
19
21
  }
20
22
  // Read and parse package.json
21
23
  const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
22
24
  const dependencies = Object.assign(Object.assign({}, packageJson.dependencies), packageJson.devDependencies);
23
25
  // Check for gt-next or gt-react in dependencies
24
26
  if (dependencies['gt-next']) {
25
- return 'gt-next';
27
+ library = 'gt-next';
26
28
  }
27
29
  else if (dependencies['gt-react']) {
28
- return 'gt-react';
30
+ library = 'gt-react';
29
31
  }
30
32
  else if (dependencies['next-intl']) {
31
- return 'next-intl';
33
+ library = 'next-intl';
32
34
  }
33
- else if (dependencies['react-i18next']) {
34
- return 'react-i18next';
35
+ else if (dependencies['i18next']) {
36
+ library = 'i18next';
35
37
  }
36
- else if (dependencies['next-i18next']) {
37
- return 'next-i18next';
38
+ if (dependencies['i18next-icu']) {
39
+ additionalModules.push('i18next-icu');
38
40
  }
39
41
  // Fallback to base if neither is found
40
- return 'base';
42
+ return { library, additionalModules };
41
43
  }
42
44
  catch (error) {
43
45
  console.error('Error determining framework:', error);
44
- return 'base';
46
+ return { library: 'base', additionalModules: [] };
45
47
  }
46
48
  }
package/dist/index.js CHANGED
@@ -8,16 +8,16 @@ const next_1 = require("./cli/next");
8
8
  const react_1 = require("./cli/react");
9
9
  const determineFramework_1 = require("./fs/determineFramework");
10
10
  function main() {
11
- const library = (0, determineFramework_1.determineLibrary)();
11
+ const { library, additionalModules } = (0, determineFramework_1.determineLibrary)();
12
12
  let cli;
13
13
  if (library === 'gt-next') {
14
- cli = new next_1.NextCLI();
14
+ cli = new next_1.NextCLI(library, additionalModules);
15
15
  }
16
16
  else if (library === 'gt-react') {
17
- cli = new react_1.ReactCLI();
17
+ cli = new react_1.ReactCLI(library, additionalModules);
18
18
  }
19
19
  else {
20
- cli = new base_1.BaseCLI(library);
20
+ cli = new base_1.BaseCLI(library, additionalModules);
21
21
  }
22
22
  cli.init();
23
23
  cli.execute();
@@ -53,7 +53,7 @@ export type GenerateSourceOptions = {
53
53
  };
54
54
  export type Framework = 'gt-next' | 'gt-react';
55
55
  export type SupportedFrameworks = 'next-app' | 'next-pages' | 'vite' | 'react' | 'gatsby';
56
- export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'base';
56
+ export type SupportedLibraries = 'gt-next' | 'gt-react' | 'next-intl' | 'react-i18next' | 'next-i18next' | 'i18next' | 'i18next-icu' | 'base';
57
57
  export interface ContentScanner {
58
58
  scanForContent(options: WrapOptions, framework: Framework): Promise<{
59
59
  errors: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "scripts": {