helpforbegs 0.0.0-stage → 1.0.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/src/why.js ADDED
@@ -0,0 +1,103 @@
1
+ // src/why.js
2
+ // WHY: When a tool says a package is "used" or "unused", a beginner needs proof!
3
+ // The `why` command shows exact filenames and line numbers so the developer
4
+ // understands their project and can verify everything for themselves.
5
+
6
+ const { analyzeProject } = require('./analyzer');
7
+ const { createStyler } = require('./reporter');
8
+
9
+ /**
10
+ * Explains in plain English why a package is used, unused, or missing.
11
+ *
12
+ * @param {string} projectDir
13
+ * @param {string} targetPkg
14
+ * @param {object} [options]
15
+ * @param {boolean} [options.noColor=false]
16
+ * @returns {number} Exit code
17
+ */
18
+ function explainPackage(projectDir, targetPkg, options = {}) {
19
+ const styler = createStyler(options.noColor);
20
+
21
+ if (!targetPkg) {
22
+ console.log(styler.red('❌ Please specify a package name to inspect.'));
23
+ console.log(styler.dim(' Example: npx helpforbegs why lodash'));
24
+ return 1;
25
+ }
26
+
27
+ const analysis = analyzeProject(projectDir);
28
+
29
+ console.log();
30
+ console.log(styler.bold(`🔍 Investigating "${targetPkg}" in your project:`));
31
+ console.log();
32
+
33
+ // 1. Check if it's missing (imported in code but not installed)
34
+ const missingEntry = analysis.missing.find((m) => m.name === targetPkg);
35
+ if (missingEntry) {
36
+ console.log(styler.red(`âš ī¸ "${targetPkg}" is USED in your code, but MISSING from package.json!`));
37
+ console.log(' Found in the following files:');
38
+ for (const loc of missingEntry.locations) {
39
+ console.log(` â€ĸ ${styler.cyan(loc.file)}:${styler.yellow(loc.line)}`);
40
+ }
41
+ console.log();
42
+ console.log(styler.dim(` 👉 Fix: run \`npm install ${targetPkg}\` to add it properly.`));
43
+ console.log();
44
+ return 1;
45
+ }
46
+
47
+ // 2. Check if it's confirmed USED
48
+ if (analysis.used.has(targetPkg)) {
49
+ const usage = analysis.used.get(targetPkg);
50
+ console.log(styler.green(`✅ "${targetPkg}" is ACTIVELY USED in your project.`));
51
+ console.log();
52
+
53
+ console.log(' Why it is kept:');
54
+ for (const reason of usage.reasons) {
55
+ console.log(` â€ĸ ${reason}`);
56
+ }
57
+
58
+ if (usage.locations.length > 0) {
59
+ console.log();
60
+ console.log(' Import locations in source code:');
61
+ for (const loc of usage.locations) {
62
+ const typeNote = loc.isTypeOnly ? styler.gray(' (type-only import)') : '';
63
+ console.log(` â€ĸ ${styler.cyan(loc.file)}:${styler.yellow(loc.line)}${typeNote}`);
64
+ }
65
+ }
66
+
67
+ console.log();
68
+ return 0;
69
+ }
70
+
71
+ // 3. Check if it's PROBABLY UNUSED
72
+ const probablyEntry = analysis.probablyUnused.find((p) => p.name === targetPkg);
73
+ if (probablyEntry) {
74
+ console.log(styler.yellow(`🤔 "${targetPkg}" is PROBABLY UNUSED.`));
75
+ console.log(` ${probablyEntry.reason}`);
76
+ console.log();
77
+ console.log(' Because this is a known development tool, check your npm scripts');
78
+ console.log(' or config files before uninstalling it.');
79
+ console.log();
80
+ return 1;
81
+ }
82
+
83
+ // 4. Check if it's UNUSED
84
+ const unusedEntry = analysis.unused.find((u) => u.name === targetPkg);
85
+ if (unusedEntry) {
86
+ console.log(styler.red(`❌ "${targetPkg}" is INSTALLED but UNUSED.`));
87
+ console.log(` ${unusedEntry.reason}.`);
88
+ console.log(` We scanned ${analysis.filesReadCount} files and found zero imports or script commands for it.`);
89
+ console.log();
90
+ console.log(styler.dim(` 👉 You can safely remove it with: \`npx helpforbegs remove\``));
91
+ console.log();
92
+ return 1;
93
+ }
94
+
95
+ // 5. Not found anywhere
96
+ console.log(styler.gray(`â„šī¸ "${targetPkg}" was not found in your package.json or your code.`));
97
+ console.log();
98
+ return 0;
99
+ }
100
+
101
+ module.exports = {
102
+ explainPackage,
103
+ };