depstein 0.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.
Files changed (65) hide show
  1. package/README.md +438 -0
  2. package/dist/core/cache.d.ts +15 -0
  3. package/dist/core/cache.js +75 -0
  4. package/dist/core/cache.js.map +1 -0
  5. package/dist/core/fetcher.d.ts +7 -0
  6. package/dist/core/fetcher.js +59 -0
  7. package/dist/core/fetcher.js.map +1 -0
  8. package/dist/core/replacements.d.ts +32 -0
  9. package/dist/core/replacements.js +419 -0
  10. package/dist/core/replacements.js.map +1 -0
  11. package/dist/core/scanner.d.ts +7 -0
  12. package/dist/core/scanner.js +298 -0
  13. package/dist/core/scanner.js.map +1 -0
  14. package/dist/core/scorer.d.ts +5 -0
  15. package/dist/core/scorer.js +289 -0
  16. package/dist/core/scorer.js.map +1 -0
  17. package/dist/core/types.d.ts +99 -0
  18. package/dist/core/types.js +2 -0
  19. package/dist/core/types.js.map +1 -0
  20. package/dist/core/vulnerabilities.d.ts +5 -0
  21. package/dist/core/vulnerabilities.js +93 -0
  22. package/dist/core/vulnerabilities.js.map +1 -0
  23. package/dist/ecosystems/cargo.d.ts +2 -0
  24. package/dist/ecosystems/cargo.js +74 -0
  25. package/dist/ecosystems/cargo.js.map +1 -0
  26. package/dist/ecosystems/golang.d.ts +2 -0
  27. package/dist/ecosystems/golang.js +90 -0
  28. package/dist/ecosystems/golang.js.map +1 -0
  29. package/dist/ecosystems/npm.d.ts +2 -0
  30. package/dist/ecosystems/npm.js +92 -0
  31. package/dist/ecosystems/npm.js.map +1 -0
  32. package/dist/ecosystems/pypi.d.ts +2 -0
  33. package/dist/ecosystems/pypi.js +80 -0
  34. package/dist/ecosystems/pypi.js.map +1 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +303 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/tui/colors.d.ts +17 -0
  39. package/dist/tui/colors.js +86 -0
  40. package/dist/tui/colors.js.map +1 -0
  41. package/dist/tui/dashboard.d.ts +7 -0
  42. package/dist/tui/dashboard.js +236 -0
  43. package/dist/tui/dashboard.js.map +1 -0
  44. package/dist/tui/detail.d.ts +6 -0
  45. package/dist/tui/detail.js +68 -0
  46. package/dist/tui/detail.js.map +1 -0
  47. package/dist/tui/picker.d.ts +7 -0
  48. package/dist/tui/picker.js +62 -0
  49. package/dist/tui/picker.js.map +1 -0
  50. package/dist/tui/summary.d.ts +6 -0
  51. package/dist/tui/summary.js +13 -0
  52. package/dist/tui/summary.js.map +1 -0
  53. package/dist/tui/table.d.ts +9 -0
  54. package/dist/tui/table.js +50 -0
  55. package/dist/tui/table.js.map +1 -0
  56. package/dist/utils/format.d.ts +9 -0
  57. package/dist/utils/format.js +72 -0
  58. package/dist/utils/format.js.map +1 -0
  59. package/dist/utils/http.d.ts +2 -0
  60. package/dist/utils/http.js +53 -0
  61. package/dist/utils/http.js.map +1 -0
  62. package/dist/utils/spinner.d.ts +11 -0
  63. package/dist/utils/spinner.js +40 -0
  64. package/dist/utils/spinner.js.map +1 -0
  65. package/package.json +50 -0
@@ -0,0 +1,298 @@
1
+ import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ // ── npm / Node.js ──────────────────────────────────────────────────────────────
4
+ function parseNpm(projectPath) {
5
+ const pkgPath = join(projectPath, 'package.json');
6
+ if (!existsSync(pkgPath))
7
+ return [];
8
+ let pkg;
9
+ try {
10
+ pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
11
+ }
12
+ catch {
13
+ return [];
14
+ }
15
+ const deps = [];
16
+ const addDeps = (map, isDev) => {
17
+ if (!map)
18
+ return;
19
+ for (const [name, version] of Object.entries(map)) {
20
+ if (typeof version !== 'string')
21
+ continue;
22
+ deps.push({
23
+ name,
24
+ // Strip semver range operators: ^1.2.3 → 1.2.3
25
+ version: version.replace(/^[^0-9]*/, '') || version,
26
+ ecosystem: 'npm',
27
+ isDev,
28
+ });
29
+ }
30
+ };
31
+ addDeps(pkg.dependencies, false);
32
+ addDeps(pkg.devDependencies, true);
33
+ addDeps(pkg.peerDependencies, false);
34
+ return deps;
35
+ }
36
+ // ── Python ─────────────────────────────────────────────────────────────────────
37
+ function parsePythonRequirements(path) {
38
+ const deps = [];
39
+ const lines = readFileSync(path, 'utf-8').split('\n');
40
+ for (const raw of lines) {
41
+ const line = raw.split('#')[0].trim();
42
+ if (!line || line.startsWith('-'))
43
+ continue;
44
+ // Handle: package==1.0, package>=1.0, package[extra]==1.0, package
45
+ const m = line.match(/^([A-Za-z0-9_.-]+)(?:\[.*?\])?(?:[=<>!~,\s]+([^\s;]+))?/);
46
+ if (m) {
47
+ deps.push({
48
+ name: m[1].toLowerCase().replace(/_/g, '-'),
49
+ version: m[2] ? m[2].replace(/^[^0-9]*/, '') || m[2] : 'latest',
50
+ ecosystem: 'pypi',
51
+ isDev: false,
52
+ });
53
+ }
54
+ }
55
+ return deps;
56
+ }
57
+ function parsePyprojectToml(content) {
58
+ const deps = [];
59
+ // [tool.poetry.dependencies]
60
+ const poetryMatch = content.match(/\[tool\.poetry\.dependencies\]([\s\S]*?)(?=\n\[)/);
61
+ if (poetryMatch) {
62
+ for (const line of poetryMatch[1].split('\n')) {
63
+ const m = line.match(/^([a-zA-Z0-9_-]+)\s*=\s*["']([^"']+)["']/);
64
+ if (m && m[1].toLowerCase() !== 'python') {
65
+ deps.push({
66
+ name: m[1].toLowerCase(),
67
+ version: m[2].replace(/^[^0-9]*/, '') || m[2],
68
+ ecosystem: 'pypi',
69
+ isDev: false,
70
+ });
71
+ }
72
+ }
73
+ }
74
+ // [tool.poetry.dev-dependencies]
75
+ const poetryDevMatch = content.match(/\[tool\.poetry\.dev-dependencies\]([\s\S]*?)(?=\n\[)/);
76
+ if (poetryDevMatch) {
77
+ for (const line of poetryDevMatch[1].split('\n')) {
78
+ const m = line.match(/^([a-zA-Z0-9_-]+)\s*=\s*["']([^"']+)["']/);
79
+ if (m) {
80
+ deps.push({
81
+ name: m[1].toLowerCase(),
82
+ version: m[2].replace(/^[^0-9]*/, '') || m[2],
83
+ ecosystem: 'pypi',
84
+ isDev: true,
85
+ });
86
+ }
87
+ }
88
+ }
89
+ // [project.dependencies] (PEP 621)
90
+ const pep621Match = content.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
91
+ if (pep621Match) {
92
+ const items = pep621Match[1].match(/["']([^"']+)["']/g) ?? [];
93
+ for (const item of items) {
94
+ const pkg = item.replace(/["']/g, '');
95
+ const m = pkg.match(/^([A-Za-z0-9_.-]+)/);
96
+ if (m) {
97
+ deps.push({
98
+ name: m[1].toLowerCase().replace(/_/g, '-'),
99
+ version: 'latest',
100
+ ecosystem: 'pypi',
101
+ isDev: false,
102
+ });
103
+ }
104
+ }
105
+ }
106
+ return deps;
107
+ }
108
+ function parsePython(projectPath) {
109
+ const deps = [];
110
+ const reqPath = join(projectPath, 'requirements.txt');
111
+ if (existsSync(reqPath)) {
112
+ deps.push(...parsePythonRequirements(reqPath));
113
+ }
114
+ const pyprojectPath = join(projectPath, 'pyproject.toml');
115
+ if (existsSync(pyprojectPath)) {
116
+ try {
117
+ const content = readFileSync(pyprojectPath, 'utf-8');
118
+ deps.push(...parsePyprojectToml(content));
119
+ }
120
+ catch { /* ignore */ }
121
+ }
122
+ const setupPyPath = join(projectPath, 'setup.py');
123
+ if (existsSync(setupPyPath)) {
124
+ try {
125
+ const content = readFileSync(setupPyPath, 'utf-8');
126
+ const m = content.match(/install_requires\s*=\s*\[([\s\S]*?)\]/);
127
+ if (m) {
128
+ const items = m[1].match(/["']([^"']+)["']/g) ?? [];
129
+ for (const item of items) {
130
+ const pkg = item.replace(/["']/g, '');
131
+ const nm = pkg.match(/^([A-Za-z0-9_.-]+)/);
132
+ if (nm) {
133
+ deps.push({
134
+ name: nm[1].toLowerCase().replace(/_/g, '-'),
135
+ version: 'latest',
136
+ ecosystem: 'pypi',
137
+ isDev: false,
138
+ });
139
+ }
140
+ }
141
+ }
142
+ }
143
+ catch { /* ignore */ }
144
+ }
145
+ return deps;
146
+ }
147
+ // ── Go ─────────────────────────────────────────────────────────────────────────
148
+ function parseGo(projectPath) {
149
+ const goModPath = join(projectPath, 'go.mod');
150
+ if (!existsSync(goModPath))
151
+ return [];
152
+ const deps = [];
153
+ const content = readFileSync(goModPath, 'utf-8');
154
+ // require ( ... ) blocks
155
+ const blockMatches = [...content.matchAll(/require\s*\(([\s\S]*?)\)/g)];
156
+ for (const block of blockMatches) {
157
+ for (const line of block[1].split('\n')) {
158
+ const trimmed = line.trim();
159
+ if (!trimmed || trimmed.startsWith('//'))
160
+ continue;
161
+ const parts = trimmed.split(/\s+/);
162
+ if (parts.length >= 2) {
163
+ deps.push({
164
+ name: parts[0],
165
+ version: parts[1],
166
+ ecosystem: 'golang',
167
+ isDev: trimmed.includes('// indirect'),
168
+ });
169
+ }
170
+ }
171
+ }
172
+ // Single-line: require module v1.2.3
173
+ const singleMatches = [...content.matchAll(/^require\s+(\S+)\s+(v[\d.]+[\w.-]*)/gm)];
174
+ for (const m of singleMatches) {
175
+ deps.push({
176
+ name: m[1],
177
+ version: m[2],
178
+ ecosystem: 'golang',
179
+ isDev: false,
180
+ });
181
+ }
182
+ return deps;
183
+ }
184
+ // ── Rust / Cargo ───────────────────────────────────────────────────────────────
185
+ function parseCargo(projectPath) {
186
+ const cargoPath = join(projectPath, 'Cargo.toml');
187
+ if (!existsSync(cargoPath))
188
+ return [];
189
+ const deps = [];
190
+ const content = readFileSync(cargoPath, 'utf-8');
191
+ // Split into sections
192
+ const sectionRegex = /^\[([^\]]+)\]/gm;
193
+ const sections = [];
194
+ let m;
195
+ while ((m = sectionRegex.exec(content)) !== null) {
196
+ if (sections.length > 0) {
197
+ sections[sections.length - 1].end = m.index;
198
+ }
199
+ sections.push({ header: m[1].trim(), start: m.index + m[0].length, end: content.length });
200
+ }
201
+ for (const section of sections) {
202
+ const isDepsSection = section.header === 'dependencies';
203
+ const isDevDepsSection = section.header === 'dev-dependencies';
204
+ if (!isDepsSection && !isDevDepsSection)
205
+ continue;
206
+ const body = content.slice(section.start, section.end);
207
+ for (const line of body.split('\n')) {
208
+ const trimmed = line.trim();
209
+ if (!trimmed || trimmed.startsWith('#'))
210
+ continue;
211
+ // name = "version"
212
+ const simple = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=\s*["']([^"']+)["']/);
213
+ if (simple) {
214
+ deps.push({ name: simple[1], version: simple[2], ecosystem: 'cargo', isDev: isDevDepsSection });
215
+ continue;
216
+ }
217
+ // name = { version = "version", ... }
218
+ const complex = trimmed.match(/^([a-zA-Z0-9_-]+)\s*=\s*\{[^}]*version\s*=\s*["']([^"']+)["']/);
219
+ if (complex) {
220
+ deps.push({ name: complex[1], version: complex[2], ecosystem: 'cargo', isDev: isDevDepsSection });
221
+ }
222
+ }
223
+ }
224
+ return deps;
225
+ }
226
+ // ── Ecosystem detection ────────────────────────────────────────────────────────
227
+ function detectEcosystem(projectPath) {
228
+ if (existsSync(join(projectPath, 'package.json')))
229
+ return 'npm';
230
+ if (existsSync(join(projectPath, 'requirements.txt')) || existsSync(join(projectPath, 'pyproject.toml')))
231
+ return 'pypi';
232
+ if (existsSync(join(projectPath, 'go.mod')))
233
+ return 'golang';
234
+ if (existsSync(join(projectPath, 'Cargo.toml')))
235
+ return 'cargo';
236
+ return null;
237
+ }
238
+ /**
239
+ * Find nested package.json files for monorepo support.
240
+ * Returns paths relative to the project root where separate package.json exist.
241
+ */
242
+ export function findWorkspaceRoots(projectPath) {
243
+ const roots = [];
244
+ const resolved = resolve(projectPath);
245
+ try {
246
+ const pkg = JSON.parse(readFileSync(join(resolved, 'package.json'), 'utf-8'));
247
+ const patterns = Array.isArray(pkg.workspaces)
248
+ ? pkg.workspaces
249
+ : (pkg.workspaces?.packages ?? []);
250
+ for (const pattern of patterns) {
251
+ // Simple glob: packages/* or apps/*
252
+ const base = pattern.replace(/\/\*$/, '');
253
+ const absBase = join(resolved, base);
254
+ if (existsSync(absBase) && statSync(absBase).isDirectory()) {
255
+ for (const dir of readdirSync(absBase)) {
256
+ const full = join(absBase, dir);
257
+ if (statSync(full).isDirectory() && existsSync(join(full, 'package.json'))) {
258
+ roots.push(full);
259
+ }
260
+ }
261
+ }
262
+ }
263
+ }
264
+ catch { /* no workspaces */ }
265
+ return roots;
266
+ }
267
+ // ── Main export ────────────────────────────────────────────────────────────────
268
+ export function scan(projectPath, forceEcosystem) {
269
+ const resolvedPath = resolve(projectPath);
270
+ const ecosystem = forceEcosystem ?? detectEcosystem(resolvedPath);
271
+ if (!ecosystem)
272
+ return null;
273
+ let dependencies;
274
+ switch (ecosystem) {
275
+ case 'npm':
276
+ dependencies = parseNpm(resolvedPath);
277
+ break;
278
+ case 'pypi':
279
+ dependencies = parsePython(resolvedPath);
280
+ break;
281
+ case 'golang':
282
+ dependencies = parseGo(resolvedPath);
283
+ break;
284
+ case 'cargo':
285
+ dependencies = parseCargo(resolvedPath);
286
+ break;
287
+ }
288
+ // Deduplicate by name (keep first occurrence)
289
+ const seen = new Set();
290
+ dependencies = dependencies.filter(dep => {
291
+ if (seen.has(dep.name))
292
+ return false;
293
+ seen.add(dep.name);
294
+ return true;
295
+ });
296
+ return { projectPath: resolvedPath, ecosystem, dependencies };
297
+ }
298
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { PackageMetadata, RawDependency, ScoredDependency, Grade } from './types.js';
2
+ export { getBestReplacementPackage as getReplacementPackage } from './replacements.js';
3
+ export { getSuggestedLabel as getSuggestedAlternative } from './replacements.js';
4
+ export declare function getGrade(score: number): Grade;
5
+ export declare function score(raw: RawDependency, metadata: PackageMetadata): ScoredDependency;
@@ -0,0 +1,289 @@
1
+ import { formatDownloads, formatBytes } from '../utils/format.js';
2
+ import { getSuggestedLabel } from './replacements.js';
3
+ // Re-export for backward compat (index.ts uses getReplacementPackage)
4
+ export { getBestReplacementPackage as getReplacementPackage } from './replacements.js';
5
+ export { getSuggestedLabel as getSuggestedAlternative } from './replacements.js';
6
+ // ── 1. Maintenance (0–20 pts) ─────────────────────────────────────────────────
7
+ // Formula: base 20, -10 if last publish > 1 year, -20 if > 2 years
8
+ function getMaintenanceScore(metadata) {
9
+ if (!metadata.publishedAt) {
10
+ return { name: 'Maintenance', score: 0, maxScore: 20, reason: 'No publish date available' };
11
+ }
12
+ const daysSince = (Date.now() - metadata.publishedAt.getTime()) / (1000 * 60 * 60 * 24);
13
+ let score;
14
+ let reason;
15
+ if (daysSince <= 30) {
16
+ score = 20;
17
+ reason = 'Updated within 30 days';
18
+ }
19
+ else if (daysSince <= 90) {
20
+ score = 18;
21
+ reason = 'Updated within 90 days';
22
+ }
23
+ else if (daysSince <= 180) {
24
+ score = 16;
25
+ reason = 'Updated within 6 months';
26
+ }
27
+ else if (daysSince <= 365) {
28
+ score = 10;
29
+ reason = 'Updated within 1 year';
30
+ } // -10 from max
31
+ else if (daysSince <= 730) {
32
+ score = 2;
33
+ reason = 'Updated within 2 years';
34
+ } // -18 ≈ -20
35
+ else {
36
+ const years = (daysSince / 365).toFixed(1);
37
+ score = 0; // -20
38
+ reason = `Not updated in ${years} years`;
39
+ }
40
+ return { name: 'Maintenance', score, maxScore: 20, reason };
41
+ }
42
+ // ── 2. Popularity (0–10 pts) ──────────────────────────────────────────────────
43
+ // Formula: -5 if < 1000/wk, baseline 5, +5 bonus if > 1M/wk
44
+ // Represented as: <100=0, <1000=5, <100K=6, <1M=8, ≥1M=10
45
+ function getPopularityScore(metadata) {
46
+ const eco = metadata.ecosystem;
47
+ if (eco === 'npm' && metadata.weeklyDownloads != null) {
48
+ const d = metadata.weeklyDownloads;
49
+ let score;
50
+ if (d >= 1_000_000)
51
+ score = 10; // +5 bonus tier
52
+ else if (d >= 100_000)
53
+ score = 8;
54
+ else if (d >= 10_000)
55
+ score = 7;
56
+ else if (d >= 1_000)
57
+ score = 5; // baseline: no penalty
58
+ else if (d >= 100)
59
+ score = 2;
60
+ else
61
+ score = 0; // -5 penalty tier
62
+ return { name: 'Popularity', score, maxScore: 10, reason: `${formatDownloads(d)}/week` };
63
+ }
64
+ if (eco === 'pypi' && metadata.monthlyDownloads != null) {
65
+ const d = metadata.monthlyDownloads;
66
+ let score;
67
+ if (d >= 10_000_000)
68
+ score = 10;
69
+ else if (d >= 1_000_000)
70
+ score = 8;
71
+ else if (d >= 100_000)
72
+ score = 6;
73
+ else if (d >= 10_000)
74
+ score = 5;
75
+ else if (d >= 1_000)
76
+ score = 2;
77
+ else
78
+ score = 0;
79
+ return { name: 'Popularity', score, maxScore: 10, reason: `${formatDownloads(d)}/month` };
80
+ }
81
+ if (eco === 'cargo' && metadata.totalDownloads != null) {
82
+ const d = metadata.totalDownloads;
83
+ let score;
84
+ if (d >= 10_000_000)
85
+ score = 10;
86
+ else if (d >= 1_000_000)
87
+ score = 8;
88
+ else if (d >= 100_000)
89
+ score = 6;
90
+ else if (d >= 10_000)
91
+ score = 5;
92
+ else if (d >= 1_000)
93
+ score = 2;
94
+ else
95
+ score = 0;
96
+ return { name: 'Popularity', score, maxScore: 10, reason: `${formatDownloads(d)} total` };
97
+ }
98
+ // golang or missing download data — give benefit of the doubt
99
+ return { name: 'Popularity', score: 5, maxScore: 10, reason: 'Download data unavailable' };
100
+ }
101
+ // ── 3. Bundle size (0–15 pts, npm only) ───────────────────────────────────────
102
+ //
103
+ // Two data sources, in preference order:
104
+ // A) bundlephobia gzip size — the ACTUAL browser-visible weight (preferred)
105
+ // B) npm registry unpackedSize — total extracted bytes (10–50× larger, fallback)
106
+ //
107
+ // Thresholds are calibrated against real npm packages:
108
+ // gzip: react=6.4KB, lodash=24KB, moment=72KB, chart.js=47KB
109
+ // unpackedSize: react=1.3MB, lodash=1.4MB (hence separate, wider thresholds)
110
+ function getBundleSizeScore(metadata) {
111
+ if (metadata.ecosystem !== 'npm') {
112
+ return { name: 'Bundle Size', score: 15, maxScore: 15, reason: 'N/A (not npm)' };
113
+ }
114
+ // Prefer bundlephobia gzip (real minified+gzipped browser weight)
115
+ if (metadata.gzipSize != null) {
116
+ const kb = metadata.gzipSize / 1024;
117
+ let score;
118
+ let tag;
119
+ if (kb < 5) {
120
+ score = 15;
121
+ tag = 'tiny';
122
+ }
123
+ else if (kb < 25) {
124
+ score = 12;
125
+ tag = 'small';
126
+ }
127
+ else if (kb < 100) {
128
+ score = 8;
129
+ tag = 'medium';
130
+ }
131
+ else if (kb < 250) {
132
+ score = 4;
133
+ tag = 'large';
134
+ }
135
+ else if (kb < 500) {
136
+ score = 2;
137
+ tag = 'very large';
138
+ }
139
+ else {
140
+ score = 0;
141
+ tag = 'huge';
142
+ }
143
+ return { name: 'Bundle Size', score, maxScore: 15, reason: `${formatBytes(metadata.gzipSize)} gzip (${tag})` };
144
+ }
145
+ // Fallback: npm registry unpackedSize (all source files, much larger)
146
+ if (metadata.unpackedSize != null) {
147
+ const kb = metadata.unpackedSize / 1024;
148
+ let score;
149
+ let tag;
150
+ if (kb < 10) {
151
+ score = 15;
152
+ tag = 'tiny';
153
+ }
154
+ else if (kb < 50) {
155
+ score = 12;
156
+ tag = 'small';
157
+ }
158
+ else if (kb < 200) {
159
+ score = 8;
160
+ tag = 'medium';
161
+ }
162
+ else if (kb < 500) {
163
+ score = 4;
164
+ tag = 'large';
165
+ }
166
+ else if (kb < 1024) {
167
+ score = 2;
168
+ tag = 'very large';
169
+ }
170
+ else {
171
+ score = 0;
172
+ tag = 'huge';
173
+ }
174
+ return { name: 'Bundle Size', score, maxScore: 15, reason: `${formatBytes(metadata.unpackedSize)} unpacked (${tag})` };
175
+ }
176
+ return { name: 'Bundle Size', score: 8, maxScore: 15, reason: 'Size unknown' };
177
+ }
178
+ // ── 4. TypeScript support (0–10 pts, npm only) ────────────────────────────────
179
+ // Formula: -10 if no types and no @types package
180
+ function getTypescriptScore(metadata) {
181
+ if (metadata.ecosystem !== 'npm') {
182
+ return { name: 'TypeScript', score: 10, maxScore: 10, reason: 'N/A (not npm)' };
183
+ }
184
+ if (metadata.hasBuiltinTypes) {
185
+ return { name: 'TypeScript', score: 10, maxScore: 10, reason: 'Built-in types' };
186
+ }
187
+ if (metadata.hasTypesPackage) {
188
+ return { name: 'TypeScript', score: 7, maxScore: 10, reason: `@types/${metadata.name} available` };
189
+ }
190
+ return { name: 'TypeScript', score: 0, maxScore: 10, reason: 'No TypeScript types' };
191
+ }
192
+ // ── 5. License (0–15 pts) ─────────────────────────────────────────────────────
193
+ const PERMISSIVE = new Set(['MIT', 'Apache-2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'ISC', 'BSD']);
194
+ const PUBLIC_DOMAIN = new Set(['Unlicense', 'CC0-1.0', 'CC0']);
195
+ const WEAK_COPYLEFT = new Set(['MPL-2.0', 'LGPL-2.0', 'LGPL-2.1', 'LGPL-3.0']);
196
+ const STRONG_COPYLEFT_PATTERNS = ['GPL-2.0', 'GPL-3.0', 'AGPL-3.0', 'GPL', 'AGPL'];
197
+ function getLicenseScore(metadata) {
198
+ const lic = (metadata.license ?? '').trim();
199
+ if (!lic || lic === 'Unknown' || lic === 'UNKNOWN') {
200
+ return { name: 'License', score: 0, maxScore: 15, reason: 'License unknown' };
201
+ }
202
+ if (PERMISSIVE.has(lic) || lic.startsWith('MIT') || lic.startsWith('Apache') || lic.startsWith('BSD')) {
203
+ return { name: 'License', score: 15, maxScore: 15, reason: `${lic} (permissive)` };
204
+ }
205
+ if (PUBLIC_DOMAIN.has(lic)) {
206
+ return { name: 'License', score: 12, maxScore: 15, reason: `${lic} (public domain)` };
207
+ }
208
+ if (WEAK_COPYLEFT.has(lic) || lic.startsWith('LGPL')) {
209
+ return { name: 'License', score: 10, maxScore: 15, reason: `${lic} (weak copyleft)` };
210
+ }
211
+ if (STRONG_COPYLEFT_PATTERNS.some(p => lic.includes(p))) {
212
+ return { name: 'License', score: 5, maxScore: 15, reason: `${lic} (copyleft)` };
213
+ }
214
+ if (lic.toLowerCase().includes('proprietary') || lic.toLowerCase().includes('commercial')) {
215
+ return { name: 'License', score: 0, maxScore: 15, reason: `${lic} (proprietary)` };
216
+ }
217
+ return { name: 'License', score: 5, maxScore: 15, reason: `${lic} (review needed)` };
218
+ }
219
+ // ── 6. Vulnerability (0–30 pts) ───────────────────────────────────────────────
220
+ // Formula: -30 if any CVE found (proportional: CRITICAL=0, HIGH=3, MEDIUM=15, LOW=22)
221
+ function getVulnerabilityScore(metadata) {
222
+ const vulns = metadata.vulnerabilities ?? [];
223
+ if (vulns.length === 0) {
224
+ return { name: 'Security', score: 30, maxScore: 30, reason: 'No known vulnerabilities' };
225
+ }
226
+ const hasCritical = vulns.some(v => v.severity === 'CRITICAL');
227
+ const hasHigh = vulns.some(v => v.severity === 'HIGH');
228
+ const hasMedium = vulns.some(v => v.severity === 'MEDIUM');
229
+ const count = vulns.length;
230
+ if (hasCritical)
231
+ return { name: 'Security', score: 0, maxScore: 30, reason: `${count} vuln(s), CRITICAL` };
232
+ if (hasHigh)
233
+ return { name: 'Security', score: 3, maxScore: 30, reason: `${count} vuln(s), HIGH` };
234
+ if (hasMedium)
235
+ return { name: 'Security', score: 15, maxScore: 30, reason: `${count} vuln(s), MEDIUM` };
236
+ return { name: 'Security', score: 22, maxScore: 30, reason: `${count} vuln(s), LOW` };
237
+ }
238
+ // ── Grade assignment ───────────────────────────────────────────────────────────
239
+ export function getGrade(score) {
240
+ if (score >= 85)
241
+ return 'A';
242
+ if (score >= 70)
243
+ return 'B';
244
+ if (score >= 50)
245
+ return 'C';
246
+ if (score >= 30)
247
+ return 'D';
248
+ return 'F';
249
+ }
250
+ // ── Issue labels ───────────────────────────────────────────────────────────────
251
+ function buildIssues(metadata, dims) {
252
+ const issues = [];
253
+ if (dims.maintenance.score === 0)
254
+ issues.push('abandoned');
255
+ else if (dims.maintenance.score <= 2)
256
+ issues.push('outdated');
257
+ if (dims.vulnerability.score === 0)
258
+ issues.push('critical vuln');
259
+ else if (dims.vulnerability.score <= 15)
260
+ issues.push('vulnerable');
261
+ if (metadata.ecosystem === 'npm' && dims.bundleSize.score === 0)
262
+ issues.push('huge size');
263
+ if (metadata.ecosystem === 'npm' && dims.typescript.score === 0)
264
+ issues.push('no types');
265
+ if (dims.license.score === 0)
266
+ issues.push('license risk');
267
+ if (dims.popularity.score === 0)
268
+ issues.push('unpopular');
269
+ if (metadata.fetchError)
270
+ issues.push('fetch error');
271
+ return issues;
272
+ }
273
+ // ── Main scoring export ────────────────────────────────────────────────────────
274
+ export function score(raw, metadata) {
275
+ const dimensions = {
276
+ maintenance: getMaintenanceScore(metadata),
277
+ popularity: getPopularityScore(metadata),
278
+ bundleSize: getBundleSizeScore(metadata),
279
+ typescript: getTypescriptScore(metadata),
280
+ license: getLicenseScore(metadata),
281
+ vulnerability: getVulnerabilityScore(metadata),
282
+ };
283
+ const totalScore = Object.values(dimensions).reduce((sum, d) => sum + d.score, 0);
284
+ const grade = getGrade(totalScore);
285
+ const issues = buildIssues(metadata, dimensions);
286
+ const suggestion = getSuggestedLabel(raw.name);
287
+ return { raw, metadata, dimensions, totalScore, grade, issues, suggestion };
288
+ }
289
+ //# sourceMappingURL=scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../src/core/scorer.ts"],"names":[],"mappings":"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"}