react-i18next-scanner 0.1.0 → 0.1.1

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/cli/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
3
  import chalk from "chalk";
4
+ import { runInit } from "../core/runInit.js";
4
5
  import { runScanner } from "../core/scanner.js";
5
6
  import { sortJsonFiles } from "../core/sortJsonFiles.js";
6
7
  import { runSyncMissing } from "../core/runSyncMissing.js";
@@ -13,7 +14,7 @@ function resolveConfigPath(configPath) {
13
14
  finalConfigPath = findDefaultConfig() ?? undefined;
14
15
  }
15
16
  if (!finalConfigPath) {
16
- throw new Error(`Config file not found. Create one of: ${POSSIBLE_CONFIGS.join(", ")}`);
17
+ throw new Error(`Config file not found. Create one of: ${POSSIBLE_CONFIGS.join(", ")}\nRun: react-i18next-scanner init`);
17
18
  }
18
19
  return finalConfigPath;
19
20
  }
@@ -96,4 +97,15 @@ program
96
97
  handleCliError(error);
97
98
  }
98
99
  });
100
+ program
101
+ .command("init")
102
+ .description("Create scanner config file automatically")
103
+ .action(async () => {
104
+ try {
105
+ await runInit();
106
+ }
107
+ catch (error) {
108
+ handleCliError(error);
109
+ }
110
+ });
99
111
  await program.parseAsync(process.argv);
@@ -0,0 +1,58 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import readline from "readline/promises";
4
+ import { stdin as input, stdout as output } from "process";
5
+ function getConfigFileName(format) {
6
+ return `i18n-scanner.config.${format}`;
7
+ }
8
+ function getConfigTemplate(format) {
9
+ const configObject = `{
10
+ srcPaths: ["./src/**/*.{js,jsx,ts,tsx}"],
11
+ jsonDir: [
12
+ "./src/i18n/locales/translations.en.json",
13
+ "./src/i18n/locales/translations.es.json"
14
+ ],
15
+ sortJsonFiles: [
16
+ "./src/i18n/locales/translations.en.json",
17
+ "./src/i18n/locales/translations.es.json"
18
+ ],
19
+ outputDir: "./unused",
20
+ syncMissing: false,
21
+ removeUnused: false
22
+ }`;
23
+ if (format === "cjs") {
24
+ return `module.exports = ${configObject};\n`;
25
+ }
26
+ return `export default ${configObject};\n`;
27
+ }
28
+ export async function runInit() {
29
+ const rl = readline.createInterface({ input, output });
30
+ try {
31
+ const answer = await rl.question("Choose config format (js / mjs / cjs): ");
32
+ const normalized = answer.trim().toLowerCase();
33
+ if (normalized !== "js" && normalized !== "mjs" && normalized !== "cjs") {
34
+ throw new Error("Invalid format. Use js, mjs, or cjs.");
35
+ }
36
+ const format = normalized;
37
+ const fileName = getConfigFileName(format);
38
+ const filePath = path.resolve(process.cwd(), fileName);
39
+ try {
40
+ await fs.access(filePath);
41
+ throw new Error(`${fileName} already exists.`);
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error && !error.message.includes("already exists")) {
45
+ // file does not exist, continue
46
+ }
47
+ else if (error instanceof Error) {
48
+ throw error;
49
+ }
50
+ }
51
+ const content = getConfigTemplate(format);
52
+ await fs.writeFile(filePath, content, "utf-8");
53
+ console.log(`✅ Created: ${fileName}`);
54
+ }
55
+ finally {
56
+ rl.close();
57
+ }
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-i18next-scanner",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI tool to scan React projects for missing and unused react-i18next translation keys",
5
5
  "bin": {
6
6
  "react-i18next-scanner": "./dist/cli/cli.js"