@kopynator/cli 1.0.14 → 1.2.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.
package/dist/index.js CHANGED
@@ -34,12 +34,53 @@ var import_fs = __toESM(require("fs"));
34
34
  var import_path = __toESM(require("path"));
35
35
  async function initCommand() {
36
36
  console.log(import_chalk.default.bold.blue("\n\u{1F680} Initializing Kopynator...\n"));
37
+ let detectedFramework = null;
38
+ let isReactNative = false;
39
+ let isIonic = false;
40
+ let ionicFramework = null;
41
+ const packageJsonPath = import_path.default.join(process.cwd(), "package.json");
42
+ if (import_fs.default.existsSync(packageJsonPath)) {
43
+ try {
44
+ const packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
45
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
46
+ if (deps["react-native"]) {
47
+ isReactNative = true;
48
+ detectedFramework = "React Native";
49
+ console.log(import_chalk.default.cyan("\u{1F4F1} Detected React Native project!"));
50
+ } else if (deps["@ionic/angular"] || deps["@ionic/react"] || deps["@ionic/vue"] || deps["@capacitor/core"]) {
51
+ isIonic = true;
52
+ if (deps["@ionic/angular"] || deps["@angular/core"]) {
53
+ ionicFramework = "Angular";
54
+ detectedFramework = "Ionic (Angular)";
55
+ } else if (deps["@ionic/react"] || deps["react"]) {
56
+ ionicFramework = "React";
57
+ detectedFramework = "Ionic (React)";
58
+ } else if (deps["@ionic/vue"] || deps["vue"]) {
59
+ ionicFramework = "Vue";
60
+ detectedFramework = "Ionic (Vue)";
61
+ }
62
+ console.log(import_chalk.default.magenta(`\u{1F50C} Detected ${detectedFramework} project!`));
63
+ } else if (deps["@angular/core"]) {
64
+ detectedFramework = "Angular";
65
+ console.log(import_chalk.default.red("\u{1F170}\uFE0F Detected Angular project!"));
66
+ } else if (deps["react"] && !deps["react-native"]) {
67
+ detectedFramework = "React";
68
+ console.log(import_chalk.default.blue("\u269B\uFE0F Detected React project!"));
69
+ } else if (deps["vue"]) {
70
+ detectedFramework = "Vue";
71
+ console.log(import_chalk.default.green("\u{1F7E2} Detected Vue project!"));
72
+ }
73
+ } catch (error) {
74
+ console.log(import_chalk.default.yellow("\u26A0\uFE0F Could not read package.json"));
75
+ }
76
+ }
37
77
  const answers = await import_inquirer.default.prompt([
38
78
  {
39
79
  type: "list",
40
80
  name: "framework",
41
- message: "What framework are you using?",
42
- choices: ["Angular", "React", "Vue", "Other"]
81
+ message: detectedFramework ? `Detected ${detectedFramework}. Is this correct?` : "What framework are you using?",
82
+ choices: detectedFramework ? [detectedFramework, "Other"] : ["Angular", "React", "Vue", "React Native", "Ionic", "Other"],
83
+ default: detectedFramework || "React"
43
84
  },
44
85
  {
45
86
  type: "input",
@@ -146,6 +187,70 @@ async function initCommand() {
146
187
  console.log(import_chalk.default.yellow("\u26A0\uFE0F Could not find app.config.ts or app.module.ts. Falling back to config file."));
147
188
  }
148
189
  }
190
+ if (isReactNative || answers.framework === "React Native") {
191
+ console.log(import_chalk.default.green("\n\u2705 React Native Setup"));
192
+ console.log(import_chalk.default.cyan("\nInstall the package:"));
193
+ console.log(import_chalk.default.white(" npm install @kopynator/react"));
194
+ console.log(import_chalk.default.cyan("\nWrap your App.tsx:"));
195
+ console.log(import_chalk.default.gray(`
196
+ import { KopyProvider } from '@kopynator/react';
197
+
198
+ export default function App() {
199
+ return (
200
+ <KopyProvider config={{ apiKey: 'YOUR_API_KEY', languages: ${JSON.stringify(answers.languages)} }}>
201
+ <YourApp />
202
+ </KopyProvider>
203
+ );
204
+ }`));
205
+ console.log(import_chalk.default.yellow("\n\u{1F4CC} Get your API Key from: https://www.kopynator.com"));
206
+ return;
207
+ }
208
+ if (isIonic) {
209
+ console.log(import_chalk.default.green(`
210
+ \u2705 Ionic (${ionicFramework}) Setup`));
211
+ console.log(import_chalk.default.magenta("\n\u2139\uFE0F Ionic/Capacitor apps use the standard web framework packages."));
212
+ if (ionicFramework === "Angular") {
213
+ console.log(import_chalk.default.cyan("\nInstall the package:"));
214
+ console.log(import_chalk.default.white(" npm install @kopynator/angular"));
215
+ console.log(import_chalk.default.cyan("\nAdd to your app.config.ts or app.module.ts:"));
216
+ console.log(import_chalk.default.gray(`
217
+ import { provideKopynator } from '@kopynator/angular';
218
+
219
+ providers: [
220
+ provideKopynator({
221
+ apiKey: 'YOUR_API_KEY',
222
+ mode: 'hybrid',
223
+ languages: ${JSON.stringify(answers.languages)}
224
+ })
225
+ ]`));
226
+ } else if (ionicFramework === "React") {
227
+ console.log(import_chalk.default.cyan("\nInstall the package:"));
228
+ console.log(import_chalk.default.white(" npm install @kopynator/react"));
229
+ console.log(import_chalk.default.cyan("\nWrap your App:"));
230
+ console.log(import_chalk.default.gray(`
231
+ import { KopyProvider } from '@kopynator/react';
232
+
233
+ <KopyProvider config={{ apiKey: 'YOUR_API_KEY', languages: ${JSON.stringify(answers.languages)} }}>
234
+ <IonApp>...</IonApp>
235
+ </KopyProvider>`));
236
+ } else if (ionicFramework === "Vue") {
237
+ console.log(import_chalk.default.cyan("\nInstall the package:"));
238
+ console.log(import_chalk.default.white(" npm install @kopynator/vue"));
239
+ console.log(import_chalk.default.cyan("\nAdd to your main.ts:"));
240
+ console.log(import_chalk.default.gray(`
241
+ import { createKopy } from '@kopynator/vue';
242
+
243
+ const kopy = createKopy({
244
+ apiKey: 'YOUR_API_KEY',
245
+ defaultLocale: '${answers.defaultLocale}'
246
+ });
247
+
248
+ app.use(kopy);`));
249
+ }
250
+ console.log(import_chalk.default.yellow("\n\u{1F4CC} Get your API Key from: https://www.kopynator.com"));
251
+ console.log(import_chalk.default.green("\n\u{1F4A1} Pro Tip: Your translations will work seamlessly across iOS, Android, and web!"));
252
+ return;
253
+ }
149
254
  const configContent = {
150
255
  apiKey: "YOUR_API_KEY_HERE",
151
256
  defaultLocale: answers.defaultLocale,
@@ -339,7 +444,11 @@ async function syncCommand() {
339
444
  try {
340
445
  spinner.text = "\u{1F4E1} Fetching available languages...";
341
446
  const languagesUrl = `${baseUrl}/languages?token=${token}`;
342
- const languagesResponse = await fetch(languagesUrl);
447
+ const languagesResponse = await fetch(languagesUrl, {
448
+ headers: {
449
+ "x-kopynator-version": "1.1.0"
450
+ }
451
+ });
343
452
  if (!languagesResponse.ok) {
344
453
  spinner.fail(`Failed to fetch languages: ${languagesResponse.status} ${languagesResponse.statusText}`);
345
454
  return;
@@ -355,7 +464,11 @@ async function syncCommand() {
355
464
  const downloadSpinner = (0, import_ora.default)(`\u2B07\uFE0F Downloading ${locale}...`).start();
356
465
  const fetchUrl = `${baseUrl}/fetch?token=${token}&langs=${locale}&nested=${syncConfig.nested}&includeLangKey=${syncConfig.includeLangKey}&pretty=${syncConfig.pretty}&indent=${syncConfig.indent}`;
357
466
  try {
358
- const translationResponse = await fetch(fetchUrl);
467
+ const translationResponse = await fetch(fetchUrl, {
468
+ headers: {
469
+ "x-kopynator-version": "1.1.0"
470
+ }
471
+ });
359
472
  if (!translationResponse.ok) {
360
473
  downloadSpinner.warn(`Failed to fetch ${locale}: ${translationResponse.status}`);
361
474
  continue;
@@ -383,7 +496,7 @@ async function syncCommand() {
383
496
 
384
497
  // src/index.ts
385
498
  var program = new import_commander.Command();
386
- program.name("kopynator").description("Kopynator CLI - Manage your i18n workflow").version("1.0.0");
499
+ program.name("kopynator").description("Kopynator CLI - Manage your i18n workflow").version("1.2.0");
387
500
  program.command("init").description("Initialize Kopynator in your project").action(initCommand);
388
501
  program.command("check").description("Validate your local JSON translation files").action(checkCommand);
389
502
  program.command("sync").description("Sync your translations with the Kopynator Cloud").action(syncCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kopynator/cli",
3
- "version": "1.0.14",
3
+ "version": "1.2.0",
4
4
  "description": "CLI tool for Kopynator - The i18n management solution",
5
5
  "bin": {
6
6
  "kopynator": "dist/index.js"
@@ -22,6 +22,7 @@
22
22
  "author": "Carlos Florio",
23
23
  "license": "ISC",
24
24
  "dependencies": {
25
+ "@kopynator/core": "^1.0.1",
25
26
  "chalk": "^4.1.2",
26
27
  "commander": "^11.1.0",
27
28
  "inquirer": "^8.2.6",
@@ -6,12 +6,66 @@ import path from 'path';
6
6
  export async function initCommand() {
7
7
  console.log(chalk.bold.blue('\nšŸš€ Initializing Kopynator...\n'));
8
8
 
9
+ // Auto-detect framework from package.json
10
+ let detectedFramework: string | null = null;
11
+ let isReactNative = false;
12
+ let isIonic = false;
13
+ let ionicFramework: string | null = null;
14
+
15
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
16
+ if (fs.existsSync(packageJsonPath)) {
17
+ try {
18
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
19
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
20
+
21
+ // Check for React Native
22
+ if (deps['react-native']) {
23
+ isReactNative = true;
24
+ detectedFramework = 'React Native';
25
+ console.log(chalk.cyan('šŸ“± Detected React Native project!'));
26
+ }
27
+ // Check for Ionic/Capacitor
28
+ else if (deps['@ionic/angular'] || deps['@ionic/react'] || deps['@ionic/vue'] || deps['@capacitor/core']) {
29
+ isIonic = true;
30
+ if (deps['@ionic/angular'] || deps['@angular/core']) {
31
+ ionicFramework = 'Angular';
32
+ detectedFramework = 'Ionic (Angular)';
33
+ } else if (deps['@ionic/react'] || deps['react']) {
34
+ ionicFramework = 'React';
35
+ detectedFramework = 'Ionic (React)';
36
+ } else if (deps['@ionic/vue'] || deps['vue']) {
37
+ ionicFramework = 'Vue';
38
+ detectedFramework = 'Ionic (Vue)';
39
+ }
40
+ console.log(chalk.magenta(`šŸ”Œ Detected ${detectedFramework} project!`));
41
+ }
42
+ // Check for standard frameworks
43
+ else if (deps['@angular/core']) {
44
+ detectedFramework = 'Angular';
45
+ console.log(chalk.red('šŸ…°ļø Detected Angular project!'));
46
+ } else if (deps['react'] && !deps['react-native']) {
47
+ detectedFramework = 'React';
48
+ console.log(chalk.blue('āš›ļø Detected React project!'));
49
+ } else if (deps['vue']) {
50
+ detectedFramework = 'Vue';
51
+ console.log(chalk.green('🟢 Detected Vue project!'));
52
+ }
53
+ } catch (error) {
54
+ console.log(chalk.yellow('āš ļø Could not read package.json'));
55
+ }
56
+ }
57
+
9
58
  const answers = await inquirer.prompt([
10
59
  {
11
60
  type: 'list',
12
61
  name: 'framework',
13
- message: 'What framework are you using?',
14
- choices: ['Angular', 'React', 'Vue', 'Other']
62
+ message: detectedFramework
63
+ ? `Detected ${detectedFramework}. Is this correct?`
64
+ : 'What framework are you using?',
65
+ choices: detectedFramework
66
+ ? [detectedFramework, 'Other']
67
+ : ['Angular', 'React', 'Vue', 'React Native', 'Ionic', 'Other'],
68
+ default: detectedFramework || 'React'
15
69
  },
16
70
  {
17
71
  type: 'input',
@@ -133,6 +187,75 @@ export async function initCommand() {
133
187
  }
134
188
  }
135
189
 
190
+ // React Native specific instructions
191
+ if (isReactNative || answers.framework === 'React Native') {
192
+ console.log(chalk.green('\nāœ… React Native Setup'));
193
+ console.log(chalk.cyan('\nInstall the package:'));
194
+ console.log(chalk.white(' npm install @kopynator/react'));
195
+ console.log(chalk.cyan('\nWrap your App.tsx:'));
196
+ console.log(chalk.gray(`
197
+ import { KopyProvider } from '@kopynator/react';
198
+
199
+ export default function App() {
200
+ return (
201
+ <KopyProvider config={{ apiKey: 'YOUR_API_KEY', languages: ${JSON.stringify(answers.languages)} }}>
202
+ <YourApp />
203
+ </KopyProvider>
204
+ );
205
+ }`));
206
+ console.log(chalk.yellow('\nšŸ“Œ Get your API Key from: https://www.kopynator.com'));
207
+ return;
208
+ }
209
+
210
+ // Ionic/Capacitor specific instructions
211
+ if (isIonic) {
212
+ console.log(chalk.green(`\nāœ… Ionic (${ionicFramework}) Setup`));
213
+ console.log(chalk.magenta('\nā„¹ļø Ionic/Capacitor apps use the standard web framework packages.'));
214
+
215
+ if (ionicFramework === 'Angular') {
216
+ console.log(chalk.cyan('\nInstall the package:'));
217
+ console.log(chalk.white(' npm install @kopynator/angular'));
218
+ console.log(chalk.cyan('\nAdd to your app.config.ts or app.module.ts:'));
219
+ console.log(chalk.gray(`
220
+ import { provideKopynator } from '@kopynator/angular';
221
+
222
+ providers: [
223
+ provideKopynator({
224
+ apiKey: 'YOUR_API_KEY',
225
+ mode: 'hybrid',
226
+ languages: ${JSON.stringify(answers.languages)}
227
+ })
228
+ ]`));
229
+ } else if (ionicFramework === 'React') {
230
+ console.log(chalk.cyan('\nInstall the package:'));
231
+ console.log(chalk.white(' npm install @kopynator/react'));
232
+ console.log(chalk.cyan('\nWrap your App:'));
233
+ console.log(chalk.gray(`
234
+ import { KopyProvider } from '@kopynator/react';
235
+
236
+ <KopyProvider config={{ apiKey: 'YOUR_API_KEY', languages: ${JSON.stringify(answers.languages)} }}>
237
+ <IonApp>...</IonApp>
238
+ </KopyProvider>`));
239
+ } else if (ionicFramework === 'Vue') {
240
+ console.log(chalk.cyan('\nInstall the package:'));
241
+ console.log(chalk.white(' npm install @kopynator/vue'));
242
+ console.log(chalk.cyan('\nAdd to your main.ts:'));
243
+ console.log(chalk.gray(`
244
+ import { createKopy } from '@kopynator/vue';
245
+
246
+ const kopy = createKopy({
247
+ apiKey: 'YOUR_API_KEY',
248
+ defaultLocale: '${answers.defaultLocale}'
249
+ });
250
+
251
+ app.use(kopy);`));
252
+ }
253
+ console.log(chalk.yellow('\nšŸ“Œ Get your API Key from: https://www.kopynator.com'));
254
+ console.log(chalk.green('\nšŸ’” Pro Tip: Your translations will work seamlessly across iOS, Android, and web!'));
255
+ return;
256
+ }
257
+
258
+
136
259
  // Fallback: Creates a basic config file
137
260
  const configContent = {
138
261
  apiKey: "YOUR_API_KEY_HERE",
@@ -202,8 +202,11 @@ export async function syncCommand() {
202
202
  // 1. Fetch available languages
203
203
  spinner.text = 'šŸ“” Fetching available languages...';
204
204
  const languagesUrl = `${baseUrl}/languages?token=${token}`;
205
- const languagesResponse = await fetch(languagesUrl);
206
-
205
+ const languagesResponse = await fetch(languagesUrl, {
206
+ headers: {
207
+ 'x-kopynator-version': '1.1.0'
208
+ }
209
+ });
207
210
  if (!languagesResponse.ok) {
208
211
  spinner.fail(`Failed to fetch languages: ${languagesResponse.status} ${languagesResponse.statusText}`);
209
212
  return;
@@ -225,7 +228,11 @@ export async function syncCommand() {
225
228
  const fetchUrl = `${baseUrl}/fetch?token=${token}&langs=${locale}&nested=${syncConfig.nested}&includeLangKey=${syncConfig.includeLangKey}&pretty=${syncConfig.pretty}&indent=${syncConfig.indent}`;
226
229
 
227
230
  try {
228
- const translationResponse = await fetch(fetchUrl);
231
+ const translationResponse = await fetch(fetchUrl, {
232
+ headers: {
233
+ 'x-kopynator-version': '1.1.0'
234
+ }
235
+ });
229
236
 
230
237
  if (!translationResponse.ok) {
231
238
  downloadSpinner.warn(`Failed to fetch ${locale}: ${translationResponse.status}`);
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ const program = new Command();
8
8
  program
9
9
  .name('kopynator')
10
10
  .description('Kopynator CLI - Manage your i18n workflow')
11
- .version('1.0.0');
11
+ .version('1.2.0');
12
12
 
13
13
  program
14
14
  .command('init')