errlens 1.0.9 ā 1.1.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/bin/index.js +17 -17
- package/lib/matcher.js +52 -3
- package/package.json +6 -3
package/bin/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { Command } = require("commander");
|
|
4
4
|
const { spawn } = require("child_process");
|
|
5
|
-
const chalk = require("chalk");
|
|
6
5
|
const path = require("path");
|
|
7
6
|
const { findError } = require("../lib/matcher");
|
|
8
7
|
const { formatError } = require("../lib/formatter");
|
|
@@ -20,9 +19,12 @@ program
|
|
|
20
19
|
program
|
|
21
20
|
.command("run <file>")
|
|
22
21
|
.description("Run a Javascript file and analyze crashes")
|
|
23
|
-
.
|
|
24
|
-
const { default: ora } = await import("ora");
|
|
22
|
+
.option("--lang <code>", "output language (e.g. hi, es, fr)", "en")
|
|
25
23
|
|
|
24
|
+
.action(async (file,options) => {
|
|
25
|
+
const { default: ora } = await import("ora");
|
|
26
|
+
const { default: chalk } = await import("chalk");
|
|
27
|
+
|
|
26
28
|
const isJson = Boolean(program.opts().json);
|
|
27
29
|
const filePath = path.resolve(process.cwd(), file);
|
|
28
30
|
const spinner = isJson
|
|
@@ -58,7 +60,7 @@ program
|
|
|
58
60
|
spinner.stop();
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
const { count, matches } = findError(errorOutput);
|
|
63
|
+
const { count, matches } = findError(errorOutput,options.lang);
|
|
62
64
|
|
|
63
65
|
// Process killed by signal
|
|
64
66
|
if (code === null) {
|
|
@@ -107,6 +109,7 @@ program
|
|
|
107
109
|
if (isJson) {
|
|
108
110
|
console.log(JSON.stringify(result, null, 2));
|
|
109
111
|
} else {
|
|
112
|
+
if (spinner) spinner.stop();
|
|
110
113
|
console.log(chalk.red(`System Error: ${err.message}`));
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -115,35 +118,32 @@ program
|
|
|
115
118
|
});
|
|
116
119
|
|
|
117
120
|
// ----------------- ANALYZE COMMAND -----------------
|
|
118
|
-
program
|
|
121
|
+
program
|
|
119
122
|
.command("analyze <errorString>")
|
|
120
123
|
.description("Analyze a specific error string")
|
|
121
|
-
.
|
|
124
|
+
.option("--lang <code>", "output language (e.g. hi, es, fr)", "en")
|
|
125
|
+
.action(async (errorString, options) => {
|
|
126
|
+
const { default: chalk } = await import("chalk");
|
|
122
127
|
const isJson = Boolean(program.opts().json);
|
|
123
|
-
const { count, matches } = findError(errorString);
|
|
128
|
+
const { count, matches } = findError(errorString, options.lang);
|
|
124
129
|
const exitCode = count > 0 ? 1 : 0;
|
|
125
130
|
|
|
126
131
|
if (isJson) {
|
|
127
|
-
console.log(
|
|
128
|
-
JSON.stringify({ code: exitCode, count, matches }, null, 2)
|
|
129
|
-
);
|
|
132
|
+
console.log(JSON.stringify({ code: exitCode, count, matches }, null, 2));
|
|
130
133
|
process.exit(exitCode);
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
if (count > 0) {
|
|
134
|
-
console.log(
|
|
135
|
-
chalk.bold.cyan(`\nš ErrLens Analysis (${count} Issue(s)):`)
|
|
136
|
-
);
|
|
137
|
+
console.log(chalk.bold.cyan(`\nš ErrLens Analysis (${count} Issue(s)):`));
|
|
137
138
|
matches.forEach((m) => console.log(formatError(m)));
|
|
138
139
|
} else {
|
|
139
|
-
console.log(
|
|
140
|
-
chalk.red.bold("\nā Crash detected (No known fix in database):")
|
|
141
|
-
);
|
|
140
|
+
console.log(chalk.red.bold("\nā Crash detected (No known fix in database):"));
|
|
142
141
|
console.log(chalk.gray(errorString));
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
process.exit(exitCode);
|
|
146
145
|
});
|
|
146
|
+
|
|
147
147
|
|
|
148
148
|
// ----------------- PARSE -----------------
|
|
149
149
|
program.parse(process.argv);
|
package/lib/matcher.js
CHANGED
|
@@ -1,13 +1,62 @@
|
|
|
1
1
|
const database = require("./database.json");
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const path = require("path");
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
// Loading the locale file
|
|
6
|
+
function loadLocale(lang = "en"){
|
|
7
|
+
const localesDir = path.resolve(__dirname, "../locales");
|
|
8
|
+
const normalizedLang =
|
|
9
|
+
typeof lang === "string" && /^[a-zA-Z0-9_-]+$/.test(lang)
|
|
10
|
+
? lang
|
|
11
|
+
: "en";
|
|
12
|
+
const filepath = path.resolve(localesDir, `${normalizedLang}.json`);
|
|
13
|
+
const fallback = path.resolve(localesDir, "en.json");
|
|
14
|
+
const relativeToLocales = path.relative(localesDir, filepath);
|
|
15
|
+
const safeFilepath =
|
|
16
|
+
!relativeToLocales.startsWith("..") && !path.isAbsolute(relativeToLocales)
|
|
17
|
+
? filepath
|
|
18
|
+
: fallback;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(fs.readFileSync(safeFilepath,"utf8"))
|
|
22
|
+
} catch (primaryError) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(fs.readFileSync(fallback,"utf8"))
|
|
25
|
+
} catch (fallbackError) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Failed to load locale \"${normalizedLang}\" at \"${safeFilepath}\" and fallback \"${fallback}\". Primary error: ${primaryError.message}. Fallback error: ${fallbackError.message}`
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//this function will translate every single entry using the loaded locals
|
|
34
|
+
function translateEntry(entry,locale){
|
|
35
|
+
const key = entry.match
|
|
36
|
+
return{
|
|
37
|
+
...entry,
|
|
38
|
+
explanation:locale[`${key}__explanation`] || entry.explanation,
|
|
39
|
+
why: locale[`${key}__why`] || entry.why,
|
|
40
|
+
fixes: (Array.isArray(entry.fixes) ? entry.fixes : []).map(
|
|
41
|
+
(fix,i) =>locale[`${key}__fix_${i}`] || fix
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
function findError(input,lang = "en") {
|
|
48
|
+
|
|
4
49
|
if (!input) return { count: 0, matches: [] };
|
|
5
50
|
|
|
6
51
|
if (typeof input !== "string") input = String(input);
|
|
7
52
|
|
|
8
53
|
// 1. Normalize the input (Lowercase and remove extra whitespace)
|
|
9
54
|
const lowerInput = input.toLowerCase();
|
|
10
|
-
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
const locale = loadLocale(lang) // I'm calling the load local file here
|
|
58
|
+
|
|
59
|
+
//untouched
|
|
11
60
|
// 2. Filter the database
|
|
12
61
|
let foundMatches = database.filter(entry => {
|
|
13
62
|
const matchPhrase = entry.match.toLowerCase();
|
|
@@ -28,7 +77,7 @@ function findError(input) {
|
|
|
28
77
|
|
|
29
78
|
for (const match of foundMatches) {
|
|
30
79
|
if (!seenNames.has(match.name)) {
|
|
31
|
-
uniqueMatches.push(match);
|
|
80
|
+
uniqueMatches.push(translateEntry(match,locale));
|
|
32
81
|
seenNames.add(match.name);
|
|
33
82
|
}
|
|
34
83
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "errlens",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Professional CLI tool that explains JavaScript and Node.js errors in plain English with actionable fixes directly in your terminal.",
|
|
5
5
|
"main": "./bin/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"LICENSE"
|
|
33
33
|
],
|
|
34
34
|
"scripts": {
|
|
35
|
-
"test": "node --test test/**/*.test.js"
|
|
35
|
+
"test": "node --test test/**/*.test-lang.js"
|
|
36
36
|
},
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
@@ -48,9 +48,12 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"boxen": "^5.1.2",
|
|
51
|
-
"chalk": "^
|
|
51
|
+
"chalk": "^4.1.2",
|
|
52
52
|
"commander": "^14.0.3",
|
|
53
53
|
"fuse.js": "^7.0.0",
|
|
54
54
|
"ora": "^9.3.0"
|
|
55
|
+
},
|
|
56
|
+
"directories": {
|
|
57
|
+
"lib": "lib"
|
|
55
58
|
}
|
|
56
59
|
}
|