superjs-core 0.5.0 → 0.6.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/dep-exray/cli.js +95 -43
- package/dist/dep-exray/cli.js.map +1 -1
- package/dist/dep-exray/index.js +48 -34
- package/dist/dep-exray/index.js.map +1 -1
- package/dist/dep-exray/reporter/index.js +48 -34
- package/dist/dep-exray/reporter/index.js.map +1 -1
- package/dist/index.js +50 -36
- package/dist/index.js.map +1 -1
- package/package.json +2 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/dep-exray/scanner/index.ts","../../src/dep-exray/known-mappings.ts","../../src/dep-exray/reporter/index.ts","../../src/dep-exray/analyzer/index.ts"],"sourcesContent":["import { readFileSync, readdirSync, existsSync } from 'node:fs'\r\nimport { join, basename } from 'node:path'\r\nimport type { ScanResult, ReplacementSuggestion, SecurityIssue, ScannerConfig } from '../types.js'\r\nimport { KNOWN_MAPPINGS, KNOWN_CVES, type PackageMapping } from '../known-mappings.js'\r\n\r\ninterface LockfilePackages {\r\n [key: string]: { version?: string; dependencies?: Record<string, string> } | undefined\r\n}\r\n\r\ninterface LockfileData {\r\n packages: LockfilePackages\r\n}\r\n\r\nfunction parsePackageJson(path: string): { name: string; dependencies: Record<string, string>; devDependencies: Record<string, string> } {\r\n const raw = readFileSync(path, 'utf-8')\r\n const json = JSON.parse(raw)\r\n return {\r\n name: json.name ?? basename(join(path, '..')),\r\n dependencies: (json.dependencies as Record<string, string>) ?? {},\r\n devDependencies: (json.devDependencies as Record<string, string>) ?? {},\r\n }\r\n}\r\n\r\nfunction parseLockfile(projectPath: string): LockfileData | null {\r\n const lockPath = join(projectPath, 'package-lock.json')\r\n if (!existsSync(lockPath)) return null\r\n try {\r\n const raw = readFileSync(lockPath, 'utf-8')\r\n const json = JSON.parse(raw)\r\n const packages: LockfilePackages = {}\r\n\r\n if (json.packages) {\r\n for (const [key, val] of Object.entries(json.packages as Record<string, { version?: string }>)) {\r\n if (key) {\r\n packages[key] = val\r\n }\r\n }\r\n }\r\n\r\n if (json.dependencies && Object.keys(packages).length === 0) {\r\n for (const [key, val] of Object.entries(json.dependencies as Record<string, { version?: string; requires?: Record<string, string> }>)) {\r\n packages[key] = { version: val.version, dependencies: val.requires }\r\n }\r\n }\r\n\r\n return { packages }\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction detectImportInFile(filePath: string, regex: RegExp): boolean {\r\n try {\r\n const content = readFileSync(filePath, 'utf-8')\r\n return regex.test(content)\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nfunction detectImportsInSrc(projectPath: string, mapping: PackageMapping): boolean {\r\n const regex = new RegExp(mapping.detectionPattern)\r\n const srcDir = join(projectPath, 'src')\r\n if (!existsSync(srcDir)) return false\r\n\r\n try {\r\n const files = collectSourceFiles(srcDir)\r\n for (const file of files) {\r\n if (detectImportInFile(file, regex)) return true\r\n }\r\n } catch {\r\n return false\r\n }\r\n return false\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n const full = join(dir, entry.name)\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(full))\r\n } else if (entry.isFile()) {\r\n const ext = entry.name.split('.').pop()\r\n if (ext === 'ts' || ext === 'tsx' || ext === 'js' || ext === 'jsx' || ext === 'mjs' || ext === 'cjs') {\r\n results.push(full)\r\n }\r\n }\r\n }\r\n } catch {\r\n // skip inaccessible dirs\r\n }\r\n return results\r\n}\r\n\r\nfunction estimateTransitiveCount(lockfile: LockfileData | null, directNames: Set<string>): number {\r\n if (!lockfile) return 0\r\n let count = 0\r\n for (const key of Object.keys(lockfile.packages)) {\r\n if (!key || key === '') continue\r\n const name = key.startsWith('node_modules/') ? key.slice('node_modules/'.length) : key\r\n const rootName = name.startsWith('@') ? `${name.split('/')[0]}/${name.split('/')[1]}` : name.split('/')[0]\r\n if (rootName && !directNames.has(rootName)) {\r\n count++\r\n }\r\n }\r\n return count\r\n}\r\n\r\nfunction parseSize(value: string): number {\r\n const cleaned = value.replace(/\\(.*?\\)/g, '').trim()\r\n const match = cleaned.match(/^([\\d.]+)\\s*(KB|MB)/i)\r\n if (!match) return 0\r\n const num = Number.parseFloat(match[1]!)\r\n if (!match[2]) return 0\r\n if (match[2].toUpperCase() === 'MB') return num * 1024\r\n return num\r\n}\r\n\r\nexport async function scanProject(config: ScannerConfig): Promise<ScanResult> {\r\n const projectPath = config.path ?? '.'\r\n const pkgPath = join(projectPath, 'package.json')\r\n\r\n if (!existsSync(pkgPath)) {\r\n throw new Error(`No package.json found at ${projectPath}. Run dep-exray in a JavaScript/TypeScript project directory.`)\r\n }\r\n\r\n const pkg = parsePackageJson(pkgPath)\r\n const lockfile = parseLockfile(projectPath)\r\n\r\n const allDeps: Record<string, string> = { ...pkg.dependencies, ...pkg.devDependencies }\r\n const directNames = new Set(Object.keys(allDeps))\r\n\r\n const transitiveCount = estimateTransitiveCount(lockfile, directNames)\r\n\r\n const highImpactReplacements: ReplacementSuggestion[] = []\r\n const mediumImpactReplacements: ReplacementSuggestion[] = []\r\n const securityIssues: SecurityIssue[] = []\r\n\r\n const sizeMap: Record<string, string> = {}\r\n for (const m of KNOWN_MAPPINGS) {\r\n sizeMap[m.name] = m.size\r\n }\r\n\r\n for (const mapping of KNOWN_MAPPINGS) {\r\n const isDirect = directNames.has(mapping.name)\r\n if (!isDirect) continue\r\n\r\n const isUsed = detectImportsInSrc(projectPath, mapping)\r\n if (!isUsed && !config.verbose) continue\r\n\r\n const mappingSize = parseSize(sizeMap[mapping.name] ?? '0 KB')\r\n const replacementSize = mapping.replacement.startsWith('native') ? 0 : 5\r\n const reductionStr = mappingSize > 1024\r\n ? `${(mappingSize / 1024).toFixed(1)} MB → ${replacementSize} KB`\r\n : `${mappingSize.toFixed(0)} KB → ${replacementSize} KB`\r\n\r\n const suggestion: ReplacementSuggestion = {\r\n packageName: mapping.name,\r\n reason: mapping.reason,\r\n replacement: mapping.replacement,\r\n estimatedSizeReduction: reductionStr,\r\n confidence: mapping.confidence,\r\n autoPrReady: mapping.autoPrReady,\r\n }\r\n\r\n if (mapping.confidence === 'high') {\r\n highImpactReplacements.push(suggestion)\r\n } else {\r\n mediumImpactReplacements.push(suggestion)\r\n }\r\n }\r\n\r\n for (const [name, cves] of Object.entries(KNOWN_CVES)) {\r\n if (directNames.has(name)) {\r\n for (const cveItem of cves) {\r\n securityIssues.push({\r\n packageName: name,\r\n cveId: cveItem.cve,\r\n severity: cveItem.severity as SecurityIssue['severity'],\r\n fix: cveItem.fix,\r\n })\r\n }\r\n }\r\n }\r\n\r\n let totalSizeKB = 0\r\n for (const depName of directNames) {\r\n const sizeStr = sizeMap[depName]\r\n if (sizeStr) {\r\n totalSizeKB += parseSize(sizeStr)\r\n } else {\r\n totalSizeKB += 50\r\n }\r\n }\r\n totalSizeKB += transitiveCount * 30\r\n\r\n const totalSizeStr = totalSizeKB > 1024\r\n ? `${(totalSizeKB / 1024).toFixed(1)} MB`\r\n : `${totalSizeKB.toFixed(0)} KB`\r\n\r\n return {\r\n projectName: pkg.name,\r\n directDeps: directNames.size,\r\n transitiveDeps: transitiveCount,\r\n totalEstimatedSize: totalSizeStr,\r\n highImpactReplacements,\r\n mediumImpactReplacements,\r\n securityIssues,\r\n }\r\n}\r\n","\r\n\r\nexport interface PackageMapping {\r\n name: string\r\n size: string\r\n replacement: string\r\n confidence: 'high' | 'medium' | 'low'\r\n autoPrReady: boolean\r\n reason: string\r\n detectionPattern: string\r\n}\r\n\r\nexport const KNOWN_MAPPINGS: PackageMapping[] = [\r\n {\r\n name: 'lodash',\r\n size: '4.2 MB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Most lodash functions have direct replacements in jscore-core with 99% API compatibility',\r\n detectionPattern: 'from [\\'\"]lodash[\\'\"]|require\\\\([\\'\"]lodash[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'moment',\r\n size: '2.5 MB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'date utilities in jscore-core cover 95% of common moment use cases',\r\n detectionPattern: 'from [\\'\"]moment[\\'\"]|require\\\\([\\'\"]moment[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'date-fns',\r\n size: '1.2 MB (tree-shaked ~50KB)',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — jscore-core covers basic date ops but not all locale support',\r\n detectionPattern: 'from [\\'\"]date-fns[\\'\"]|require\\\\([\\'\"]date-fns[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'axios',\r\n size: '1.6 MB',\r\n replacement: 'native fetch + jscore-core/async/retry',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Native fetch covers most use cases; needs manual review for interceptors',\r\n detectionPattern: 'from [\\'\"]axios[\\'\"]|require\\\\([\\'\"]axios[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'uuid',\r\n size: '30 KB',\r\n replacement: 'crypto.randomUUID() (native)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'crypto.randomUUID() is available in all modern Node.js and browsers',\r\n detectionPattern: 'from [\\'\"]uuid[\\'\"]|require\\\\([\\'\"]uuid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'deepmerge',\r\n size: '15 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]deepmerge[\\'\"]|require\\\\([\\'\"]deepmerge[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'lodash.merge',\r\n size: '25 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]lodash\\\\.(merge|clone|pick|omit|get|set)[\\'\"]',\r\n },\r\n {\r\n name: 'chalk',\r\n size: '45 KB',\r\n replacement: 'picocolors',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: \"picocolors is 3KB vs chalk's 45KB with same API\",\r\n detectionPattern: 'from [\\'\"]chalk[\\'\"]|require\\\\([\\'\"]chalk[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'nanoid',\r\n size: '8 KB',\r\n replacement: 'jscore-core/string (nanoid)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides nanoid with same API',\r\n detectionPattern: 'from [\\'\"]nanoid[\\'\"]|require\\\\([\\'\"]nanoid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'dayjs',\r\n size: '50 KB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — covers basics but not all plugins',\r\n detectionPattern: 'from [\\'\"]dayjs[\\'\"]|require\\\\([\\'\"]dayjs[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'clsx',\r\n size: '5 KB',\r\n replacement: 'native template literals',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Can be replaced with simple template literal conditional pattern',\r\n detectionPattern: 'from [\\'\"]clsx[\\'\"]|require\\\\([\\'\"]clsx[\\'\"]\\\\)',\r\n },\r\n]\r\n\r\nexport const KNOWN_CVES: Record<string, { cve: string; severity: string; fix: string }[]> = {\r\n 'ansi-regex': [\r\n { cve: 'CVE-2021-3807', severity: 'high', fix: 'Update to ansi-regex@6.0.1 or later' },\r\n ],\r\n 'semver': [\r\n { cve: 'CVE-2022-25883', severity: 'medium', fix: 'Update to semver@7.5.2 or later' },\r\n ],\r\n 'json5': [\r\n { cve: 'CVE-2022-46175', severity: 'high', fix: 'Update to json5@2.2.3 or later' },\r\n ],\r\n 'lodash': [\r\n { cve: 'CVE-2020-28502', severity: 'high', fix: 'Update to lodash@4.17.21 or later' },\r\n { cve: 'CVE-2020-8203', severity: 'medium', fix: 'Update to lodash@4.17.21 or later' },\r\n ],\r\n}\r\n","import pc from 'picocolors'\r\nimport type { ScanResult, ReplacementSuggestion, SecurityIssue } from '../types.js'\r\n\r\nfunction severityColor(severity: SecurityIssue['severity']): string {\r\n switch (severity) {\r\n case 'critical': return pc.bold(pc.red(severity.toUpperCase()))\r\n case 'high': return pc.red(severity.toUpperCase())\r\n case 'medium': return pc.yellow(severity.toUpperCase())\r\n case 'low': return pc.dim(severity.toUpperCase())\r\n }\r\n}\r\n\r\nfunction confidenceIcon(confidence: ReplacementSuggestion['confidence']): string {\r\n switch (confidence) {\r\n case 'high': return pc.green('●')\r\n case 'medium': return pc.yellow('●')\r\n case 'low': return pc.red('●')\r\n }\r\n}\r\n\r\nexport function generateReport(result: ScanResult, jsonOutput?: boolean): string {\r\n if (jsonOutput) {\r\n return JSON.stringify(result, null, 2)\r\n }\r\n\r\n const lines: string[] = []\r\n\r\n // ┌─┐│└┘─\r\n lines.push(pc.bold(pc.cyan(`┌${'─'.repeat(58)}┐`)))\r\n lines.push(pc.bold(pc.cyan(`│${' '.repeat(18)}dep-exray Report${' '.repeat(21)}│`)))\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.white('📦 PROJECT:')} ${pc.bold(result.projectName)}${' '.repeat(Math.max(1, 47 - result.projectName.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.white('📊 DEPENDENCIES:')} ${pc.bold(String(result.directDeps))} direct + ${pc.bold(String(result.transitiveDeps))} transitive${' '.repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.white('💾 TOTAL SIZE:')} ${pc.bold(result.totalEstimatedSize)}${' '.repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n\r\n if (result.highImpactReplacements.length > 0) {\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.green('🟢')} ${pc.bold(pc.green('HIGH IMPACT REPLACEMENTS'))}${' '.repeat(23)}│`)))\r\n for (const item of result.highImpactReplacements) {\r\n const autoPr = item.autoPrReady ? pc.green('✓ Auto-PR ready') : pc.dim('Manual review needed')\r\n const confIcon = confidenceIcon(item.confidence)\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.red('✗')} ${pc.bold(item.packageName)} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.dim('→')} ${pc.cyan(item.replacement)}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.dim('└─')} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`)))\r\n }\r\n }\r\n\r\n if (result.mediumImpactReplacements.length > 0) {\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.yellow('🟡')} ${pc.bold(pc.yellow('MEDIUM IMPACT REPLACEMENTS'))}${' '.repeat(20)}│`)))\r\n for (const item of result.mediumImpactReplacements) {\r\n const autoPr = item.autoPrReady ? pc.green('✓ Auto-PR ready') : pc.dim('Manual review needed')\r\n const confIcon = confidenceIcon(item.confidence)\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.red('✗')} ${pc.bold(item.packageName)} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.dim('→')} ${pc.cyan(item.replacement)}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.dim('└─')} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`)))\r\n }\r\n }\r\n\r\n if (result.securityIssues.length > 0) {\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.red('🔴')} ${pc.bold(pc.red('SECURITY ISSUES'))}${' '.repeat(33)}│`)))\r\n for (const issue of result.securityIssues) {\r\n lines.push(pc.bold(pc.cyan(`├${'─'.repeat(58)}┤`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${severityColor(issue.severity)} ${pc.bold(issue.cveId)} in ${issue.packageName}${' '.repeat(Math.max(1, 40 - issue.packageName.length))}│`)))\r\n lines.push(pc.bold(pc.cyan(`│ ${pc.dim('→')} ${issue.fix}${' '.repeat(Math.max(1, 52 - issue.fix.length))}│`)))\r\n }\r\n }\r\n\r\n lines.push(pc.bold(pc.cyan(`└${'─'.repeat(58)}┘`)))\r\n\r\n return lines.join('\\n')\r\n}\r\n","import { readFileSync } from 'node:fs'\r\nimport { readdirSync, statSync } from 'node:fs'\r\nimport { join, extname } from 'node:path'\r\n\r\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'])\r\n\r\nfunction isSourceFile(file: string): boolean {\r\n return SOURCE_EXTENSIONS.has(extname(file))\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name)\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(fullPath))\r\n } else if (entry.isFile() && isSourceFile(entry.name)) {\r\n results.push(fullPath)\r\n }\r\n }\r\n } catch {\r\n // skip directories we can't read\r\n }\r\n return results\r\n}\r\n\r\nfunction escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\r\n}\r\n\r\nexport async function analyzeUsage(\r\n projectPath: string,\r\n packageName: string,\r\n): Promise<{\r\n isUsed: boolean\r\n importCount: number\r\n importLocations: string[]\r\n}> {\r\n const importLocations: string[] = []\r\n const escaped = escapeRegex(packageName)\r\n const importRegex = new RegExp(\r\n `(?:from\\\\s+['\"]${escaped}(?:/['\"]|['\"])|require\\\\(\\\\s*['\"]${escaped}(?:/|['\"]))`,\r\n 'g',\r\n )\r\n\r\n const srcDir = join(projectPath, 'src')\r\n let files: string[]\r\n try {\r\n if (statSync(srcDir).isDirectory()) {\r\n files = collectSourceFiles(srcDir)\r\n } else {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n } catch {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n\r\n for (const file of files) {\r\n try {\r\n const content = readFileSync(file, 'utf-8')\r\n importRegex.lastIndex = 0\r\n if (importRegex.test(content)) {\r\n importLocations.push(file)\r\n }\r\n } catch {\r\n // skip unreadable files\r\n }\r\n }\r\n\r\n return {\r\n isUsed: importLocations.length > 0,\r\n importCount: importLocations.length,\r\n importLocations,\r\n }\r\n}\r\n"],"mappings":"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","names":["readFileSync","readdirSync","join","collectSourceFiles"]}
|
|
1
|
+
{"version":3,"sources":["../../src/dep-exray/scanner/index.ts","../../src/dep-exray/known-mappings.ts","../../src/dep-exray/reporter/index.ts","../../src/dep-exray/analyzer/index.ts"],"sourcesContent":["import { readFileSync, readdirSync, existsSync } from 'node:fs'\r\nimport { join, basename } from 'node:path'\r\nimport type { ScanResult, ReplacementSuggestion, SecurityIssue, ScannerConfig } from '../types.js'\r\nimport { KNOWN_MAPPINGS, KNOWN_CVES, type PackageMapping } from '../known-mappings.js'\r\n\r\ninterface LockfilePackages {\r\n [key: string]: { version?: string; dependencies?: Record<string, string> } | undefined\r\n}\r\n\r\ninterface LockfileData {\r\n packages: LockfilePackages\r\n}\r\n\r\nfunction parsePackageJson(path: string): { name: string; dependencies: Record<string, string>; devDependencies: Record<string, string> } {\r\n const raw = readFileSync(path, 'utf-8')\r\n const json = JSON.parse(raw)\r\n return {\r\n name: json.name ?? basename(join(path, '..')),\r\n dependencies: (json.dependencies as Record<string, string>) ?? {},\r\n devDependencies: (json.devDependencies as Record<string, string>) ?? {},\r\n }\r\n}\r\n\r\nfunction parseLockfile(projectPath: string): LockfileData | null {\r\n const lockPath = join(projectPath, 'package-lock.json')\r\n if (!existsSync(lockPath)) return null\r\n try {\r\n const raw = readFileSync(lockPath, 'utf-8')\r\n const json = JSON.parse(raw)\r\n const packages: LockfilePackages = {}\r\n\r\n if (json.packages) {\r\n for (const [key, val] of Object.entries(json.packages as Record<string, { version?: string }>)) {\r\n if (key) {\r\n packages[key] = val\r\n }\r\n }\r\n }\r\n\r\n if (json.dependencies && Object.keys(packages).length === 0) {\r\n for (const [key, val] of Object.entries(json.dependencies as Record<string, { version?: string; requires?: Record<string, string> }>)) {\r\n packages[key] = { version: val.version, dependencies: val.requires }\r\n }\r\n }\r\n\r\n return { packages }\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction detectImportInFile(filePath: string, regex: RegExp): boolean {\r\n try {\r\n const content = readFileSync(filePath, 'utf-8')\r\n return regex.test(content)\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nfunction detectImportsInSrc(projectPath: string, mapping: PackageMapping): boolean {\r\n const regex = new RegExp(mapping.detectionPattern)\r\n const srcDir = join(projectPath, 'src')\r\n if (!existsSync(srcDir)) return false\r\n\r\n try {\r\n const files = collectSourceFiles(srcDir)\r\n for (const file of files) {\r\n if (detectImportInFile(file, regex)) return true\r\n }\r\n } catch {\r\n return false\r\n }\r\n return false\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n const full = join(dir, entry.name)\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(full))\r\n } else if (entry.isFile()) {\r\n const ext = entry.name.split('.').pop()\r\n if (ext === 'ts' || ext === 'tsx' || ext === 'js' || ext === 'jsx' || ext === 'mjs' || ext === 'cjs') {\r\n results.push(full)\r\n }\r\n }\r\n }\r\n } catch {\r\n // skip inaccessible dirs\r\n }\r\n return results\r\n}\r\n\r\nfunction estimateTransitiveCount(lockfile: LockfileData | null, directNames: Set<string>): number {\r\n if (!lockfile) return 0\r\n let count = 0\r\n for (const key of Object.keys(lockfile.packages)) {\r\n if (!key || key === '') continue\r\n const name = key.startsWith('node_modules/') ? key.slice('node_modules/'.length) : key\r\n const rootName = name.startsWith('@') ? `${name.split('/')[0]}/${name.split('/')[1]}` : name.split('/')[0]\r\n if (rootName && !directNames.has(rootName)) {\r\n count++\r\n }\r\n }\r\n return count\r\n}\r\n\r\nfunction parseSize(value: string): number {\r\n const cleaned = value.replace(/\\(.*?\\)/g, '').trim()\r\n const match = cleaned.match(/^([\\d.]+)\\s*(KB|MB)/i)\r\n if (!match) return 0\r\n const num = Number.parseFloat(match[1]!)\r\n if (!match[2]) return 0\r\n if (match[2].toUpperCase() === 'MB') return num * 1024\r\n return num\r\n}\r\n\r\nexport async function scanProject(config: ScannerConfig): Promise<ScanResult> {\r\n const projectPath = config.path ?? '.'\r\n const pkgPath = join(projectPath, 'package.json')\r\n\r\n if (!existsSync(pkgPath)) {\r\n throw new Error(`No package.json found at ${projectPath}. Run dep-exray in a JavaScript/TypeScript project directory.`)\r\n }\r\n\r\n const pkg = parsePackageJson(pkgPath)\r\n const lockfile = parseLockfile(projectPath)\r\n\r\n const allDeps: Record<string, string> = { ...pkg.dependencies, ...pkg.devDependencies }\r\n const directNames = new Set(Object.keys(allDeps))\r\n\r\n const transitiveCount = estimateTransitiveCount(lockfile, directNames)\r\n\r\n const highImpactReplacements: ReplacementSuggestion[] = []\r\n const mediumImpactReplacements: ReplacementSuggestion[] = []\r\n const securityIssues: SecurityIssue[] = []\r\n\r\n const sizeMap: Record<string, string> = {}\r\n for (const m of KNOWN_MAPPINGS) {\r\n sizeMap[m.name] = m.size\r\n }\r\n\r\n for (const mapping of KNOWN_MAPPINGS) {\r\n const isDirect = directNames.has(mapping.name)\r\n if (!isDirect) continue\r\n\r\n const isUsed = detectImportsInSrc(projectPath, mapping)\r\n if (!isUsed && !config.verbose) continue\r\n\r\n const mappingSize = parseSize(sizeMap[mapping.name] ?? '0 KB')\r\n const replacementSize = mapping.replacement.startsWith('native') ? 0 : 5\r\n const reductionStr = mappingSize > 1024\r\n ? `${(mappingSize / 1024).toFixed(1)} MB → ${replacementSize} KB`\r\n : `${mappingSize.toFixed(0)} KB → ${replacementSize} KB`\r\n\r\n const suggestion: ReplacementSuggestion = {\r\n packageName: mapping.name,\r\n reason: mapping.reason,\r\n replacement: mapping.replacement,\r\n estimatedSizeReduction: reductionStr,\r\n confidence: mapping.confidence,\r\n autoPrReady: mapping.autoPrReady,\r\n }\r\n\r\n if (mapping.confidence === 'high') {\r\n highImpactReplacements.push(suggestion)\r\n } else {\r\n mediumImpactReplacements.push(suggestion)\r\n }\r\n }\r\n\r\n for (const [name, cves] of Object.entries(KNOWN_CVES)) {\r\n if (directNames.has(name)) {\r\n for (const cveItem of cves) {\r\n securityIssues.push({\r\n packageName: name,\r\n cveId: cveItem.cve,\r\n severity: cveItem.severity as SecurityIssue['severity'],\r\n fix: cveItem.fix,\r\n })\r\n }\r\n }\r\n }\r\n\r\n let totalSizeKB = 0\r\n for (const depName of directNames) {\r\n const sizeStr = sizeMap[depName]\r\n if (sizeStr) {\r\n totalSizeKB += parseSize(sizeStr)\r\n } else {\r\n totalSizeKB += 50\r\n }\r\n }\r\n totalSizeKB += transitiveCount * 30\r\n\r\n const totalSizeStr = totalSizeKB > 1024\r\n ? `${(totalSizeKB / 1024).toFixed(1)} MB`\r\n : `${totalSizeKB.toFixed(0)} KB`\r\n\r\n return {\r\n projectName: pkg.name,\r\n directDeps: directNames.size,\r\n transitiveDeps: transitiveCount,\r\n totalEstimatedSize: totalSizeStr,\r\n highImpactReplacements,\r\n mediumImpactReplacements,\r\n securityIssues,\r\n }\r\n}\r\n","\r\n\r\nexport interface PackageMapping {\r\n name: string\r\n size: string\r\n replacement: string\r\n confidence: 'high' | 'medium' | 'low'\r\n autoPrReady: boolean\r\n reason: string\r\n detectionPattern: string\r\n}\r\n\r\nexport const KNOWN_MAPPINGS: PackageMapping[] = [\r\n {\r\n name: 'lodash',\r\n size: '4.2 MB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Most lodash functions have direct replacements in jscore-core with 99% API compatibility',\r\n detectionPattern: 'from [\\'\"]lodash[\\'\"]|require\\\\([\\'\"]lodash[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'moment',\r\n size: '2.5 MB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'date utilities in jscore-core cover 95% of common moment use cases',\r\n detectionPattern: 'from [\\'\"]moment[\\'\"]|require\\\\([\\'\"]moment[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'date-fns',\r\n size: '1.2 MB (tree-shaked ~50KB)',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — jscore-core covers basic date ops but not all locale support',\r\n detectionPattern: 'from [\\'\"]date-fns[\\'\"]|require\\\\([\\'\"]date-fns[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'axios',\r\n size: '1.6 MB',\r\n replacement: 'native fetch + jscore-core/async/retry',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Native fetch covers most use cases; needs manual review for interceptors',\r\n detectionPattern: 'from [\\'\"]axios[\\'\"]|require\\\\([\\'\"]axios[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'uuid',\r\n size: '30 KB',\r\n replacement: 'crypto.randomUUID() (native)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'crypto.randomUUID() is available in all modern Node.js and browsers',\r\n detectionPattern: 'from [\\'\"]uuid[\\'\"]|require\\\\([\\'\"]uuid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'deepmerge',\r\n size: '15 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]deepmerge[\\'\"]|require\\\\([\\'\"]deepmerge[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'lodash.merge',\r\n size: '25 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]lodash\\\\.(merge|clone|pick|omit|get|set)[\\'\"]',\r\n },\r\n {\r\n name: 'chalk',\r\n size: '45 KB',\r\n replacement: 'picocolors',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: \"picocolors is 3KB vs chalk's 45KB with same API\",\r\n detectionPattern: 'from [\\'\"]chalk[\\'\"]|require\\\\([\\'\"]chalk[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'nanoid',\r\n size: '8 KB',\r\n replacement: 'jscore-core/string (nanoid)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides nanoid with same API',\r\n detectionPattern: 'from [\\'\"]nanoid[\\'\"]|require\\\\([\\'\"]nanoid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'dayjs',\r\n size: '50 KB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — covers basics but not all plugins',\r\n detectionPattern: 'from [\\'\"]dayjs[\\'\"]|require\\\\([\\'\"]dayjs[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'clsx',\r\n size: '5 KB',\r\n replacement: 'native template literals',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Can be replaced with simple template literal conditional pattern',\r\n detectionPattern: 'from [\\'\"]clsx[\\'\"]|require\\\\([\\'\"]clsx[\\'\"]\\\\)',\r\n },\r\n]\r\n\r\nexport const KNOWN_CVES: Record<string, { cve: string; severity: string; fix: string }[]> = {\r\n 'ansi-regex': [\r\n { cve: 'CVE-2021-3807', severity: 'high', fix: 'Update to ansi-regex@6.0.1 or later' },\r\n ],\r\n 'semver': [\r\n { cve: 'CVE-2022-25883', severity: 'medium', fix: 'Update to semver@7.5.2 or later' },\r\n ],\r\n 'json5': [\r\n { cve: 'CVE-2022-46175', severity: 'high', fix: 'Update to json5@2.2.3 or later' },\r\n ],\r\n 'lodash': [\r\n { cve: 'CVE-2020-28502', severity: 'high', fix: 'Update to lodash@4.17.21 or later' },\r\n { cve: 'CVE-2020-8203', severity: 'medium', fix: 'Update to lodash@4.17.21 or later' },\r\n ],\r\n}\r\n","import type { ScanResult, ReplacementSuggestion, SecurityIssue } from '../types.js'\n\n// ANSI color codes — zero dependencies\nconst _ = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n}\n\nfunction style(text: string, codes: string[]): string {\n return codes.join('') + text + _.reset\n}\n\nfunction severityColor(severity: SecurityIssue['severity']): string {\n switch (severity) {\n case 'critical': return style(severity.toUpperCase(), [_.bold, _.red])\n case 'high': return style(severity.toUpperCase(), [_.red])\n case 'medium': return style(severity.toUpperCase(), [_.yellow])\n case 'low': return style(severity.toUpperCase(), [_.dim])\n }\n}\n\nfunction confidenceIcon(confidence: ReplacementSuggestion['confidence']): string {\n switch (confidence) {\n case 'high': return style('●', [_.green])\n case 'medium': return style('●', [_.yellow])\n case 'low': return style('●', [_.red])\n }\n}\n\nexport function generateReport(result: ScanResult, jsonOutput?: boolean): string {\n if (jsonOutput) {\n return JSON.stringify(result, null, 2)\n }\n\n const lines: string[] = []\n\n const t = (text: string, codes: string[] = [_.cyan]) => style(text, [_.bold, ...codes])\n\n lines.push(t(`┌${'─'.repeat(58)}┐`))\n lines.push(t(`│${' '.repeat(18)}dep-exray Report${' '.repeat(21)}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('📦 PROJECT:', [_.white])} ${style(result.projectName, [_.bold])}${' '.repeat(Math.max(1, 47 - result.projectName.length))}│`))\n lines.push(t(`│ ${style('📊 DEPENDENCIES:', [_.white])} ${style(String(result.directDeps), [_.bold])} direct + ${style(String(result.transitiveDeps), [_.bold])} transitive${' '.repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}│`))\n lines.push(t(`│ ${style('💾 TOTAL SIZE:', [_.white])} ${style(result.totalEstimatedSize, [_.bold])}${' '.repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n\n if (result.highImpactReplacements.length > 0) {\n lines.push(t(`│ ${style('🟢', [_.green])} ${style('HIGH IMPACT REPLACEMENTS', [_.bold, _.green])}${' '.repeat(23)}│`))\n for (const item of result.highImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.mediumImpactReplacements.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🟡', [_.yellow])} ${style('MEDIUM IMPACT REPLACEMENTS', [_.bold, _.yellow])}${' '.repeat(20)}│`))\n for (const item of result.mediumImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.securityIssues.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🔴', [_.red])} ${style('SECURITY ISSUES', [_.bold, _.red])}${' '.repeat(33)}│`))\n for (const issue of result.securityIssues) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${severityColor(issue.severity)} ${style(issue.cveId, [_.bold])} in ${issue.packageName}${' '.repeat(Math.max(1, 40 - issue.packageName.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${issue.fix}${' '.repeat(Math.max(1, 52 - issue.fix.length))}│`))\n }\n }\n\n lines.push(t(`└${'─'.repeat(58)}┘`))\n\n return lines.join('\\n')\n}\n","import { readFileSync } from 'node:fs'\r\nimport { readdirSync, statSync } from 'node:fs'\r\nimport { join, extname } from 'node:path'\r\n\r\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'])\r\n\r\nfunction isSourceFile(file: string): boolean {\r\n return SOURCE_EXTENSIONS.has(extname(file))\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name)\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(fullPath))\r\n } else if (entry.isFile() && isSourceFile(entry.name)) {\r\n results.push(fullPath)\r\n }\r\n }\r\n } catch {\r\n // skip directories we can't read\r\n }\r\n return results\r\n}\r\n\r\nfunction escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\r\n}\r\n\r\nexport async function analyzeUsage(\r\n projectPath: string,\r\n packageName: string,\r\n): Promise<{\r\n isUsed: boolean\r\n importCount: number\r\n importLocations: string[]\r\n}> {\r\n const importLocations: string[] = []\r\n const escaped = escapeRegex(packageName)\r\n const importRegex = new RegExp(\r\n `(?:from\\\\s+['\"]${escaped}(?:/['\"]|['\"])|require\\\\(\\\\s*['\"]${escaped}(?:/|['\"]))`,\r\n 'g',\r\n )\r\n\r\n const srcDir = join(projectPath, 'src')\r\n let files: string[]\r\n try {\r\n if (statSync(srcDir).isDirectory()) {\r\n files = collectSourceFiles(srcDir)\r\n } else {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n } catch {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n\r\n for (const file of files) {\r\n try {\r\n const content = readFileSync(file, 'utf-8')\r\n importRegex.lastIndex = 0\r\n if (importRegex.test(content)) {\r\n importLocations.push(file)\r\n }\r\n } catch {\r\n // skip unreadable files\r\n }\r\n }\r\n\r\n return {\r\n isUsed: importLocations.length > 0,\r\n importCount: importLocations.length,\r\n importLocations,\r\n }\r\n}\r\n"],"mappings":"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","names":["readFileSync","readdirSync","join","collectSourceFiles"]}
|
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
// src/dep-exray/reporter/index.ts
|
|
2
|
-
|
|
2
|
+
var _ = {
|
|
3
|
+
reset: "\x1B[0m",
|
|
4
|
+
bold: "\x1B[1m",
|
|
5
|
+
dim: "\x1B[2m",
|
|
6
|
+
red: "\x1B[31m",
|
|
7
|
+
green: "\x1B[32m",
|
|
8
|
+
yellow: "\x1B[33m",
|
|
9
|
+
blue: "\x1B[34m",
|
|
10
|
+
cyan: "\x1B[36m",
|
|
11
|
+
white: "\x1B[37m"
|
|
12
|
+
};
|
|
13
|
+
function style(text, codes) {
|
|
14
|
+
return codes.join("") + text + _.reset;
|
|
15
|
+
}
|
|
3
16
|
function severityColor(severity) {
|
|
4
17
|
switch (severity) {
|
|
5
18
|
case "critical":
|
|
6
|
-
return
|
|
19
|
+
return style(severity.toUpperCase(), [_.bold, _.red]);
|
|
7
20
|
case "high":
|
|
8
|
-
return
|
|
21
|
+
return style(severity.toUpperCase(), [_.red]);
|
|
9
22
|
case "medium":
|
|
10
|
-
return
|
|
23
|
+
return style(severity.toUpperCase(), [_.yellow]);
|
|
11
24
|
case "low":
|
|
12
|
-
return
|
|
25
|
+
return style(severity.toUpperCase(), [_.dim]);
|
|
13
26
|
}
|
|
14
27
|
}
|
|
15
28
|
function confidenceIcon(confidence) {
|
|
16
29
|
switch (confidence) {
|
|
17
30
|
case "high":
|
|
18
|
-
return
|
|
31
|
+
return style("\u25CF", [_.green]);
|
|
19
32
|
case "medium":
|
|
20
|
-
return
|
|
33
|
+
return style("\u25CF", [_.yellow]);
|
|
21
34
|
case "low":
|
|
22
|
-
return
|
|
35
|
+
return style("\u25CF", [_.red]);
|
|
23
36
|
}
|
|
24
37
|
}
|
|
25
38
|
function generateReport(result, jsonOutput) {
|
|
@@ -27,46 +40,47 @@ function generateReport(result, jsonOutput) {
|
|
|
27
40
|
return JSON.stringify(result, null, 2);
|
|
28
41
|
}
|
|
29
42
|
const lines = [];
|
|
30
|
-
|
|
31
|
-
lines.push(
|
|
32
|
-
lines.push(
|
|
33
|
-
lines.push(
|
|
34
|
-
lines.push(
|
|
35
|
-
lines.push(
|
|
36
|
-
lines.push(
|
|
43
|
+
const t = (text, codes = [_.cyan]) => style(text, [_.bold, ...codes]);
|
|
44
|
+
lines.push(t(`\u250C${"\u2500".repeat(58)}\u2510`));
|
|
45
|
+
lines.push(t(`\u2502${" ".repeat(18)}dep-exray Report${" ".repeat(21)}\u2502`));
|
|
46
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
47
|
+
lines.push(t(`\u2502 ${style("\u{1F4E6} PROJECT:", [_.white])} ${style(result.projectName, [_.bold])}${" ".repeat(Math.max(1, 47 - result.projectName.length))}\u2502`));
|
|
48
|
+
lines.push(t(`\u2502 ${style("\u{1F4CA} DEPENDENCIES:", [_.white])} ${style(String(result.directDeps), [_.bold])} direct + ${style(String(result.transitiveDeps), [_.bold])} transitive${" ".repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}\u2502`));
|
|
49
|
+
lines.push(t(`\u2502 ${style("\u{1F4BE} TOTAL SIZE:", [_.white])} ${style(result.totalEstimatedSize, [_.bold])}${" ".repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}\u2502`));
|
|
50
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
37
51
|
if (result.highImpactReplacements.length > 0) {
|
|
38
|
-
lines.push(
|
|
52
|
+
lines.push(t(`\u2502 ${style("\u{1F7E2}", [_.green])} ${style("HIGH IMPACT REPLACEMENTS", [_.bold, _.green])}${" ".repeat(23)}\u2502`));
|
|
39
53
|
for (const item of result.highImpactReplacements) {
|
|
40
|
-
const autoPr = item.autoPrReady ?
|
|
54
|
+
const autoPr = item.autoPrReady ? style("\u2713 Auto-PR ready", [_.green]) : style("Manual review needed", [_.dim]);
|
|
41
55
|
const confIcon = confidenceIcon(item.confidence);
|
|
42
|
-
lines.push(
|
|
43
|
-
lines.push(
|
|
44
|
-
lines.push(
|
|
45
|
-
lines.push(
|
|
56
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
57
|
+
lines.push(t(`\u2502 ${style("\u2717", [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${" ".repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}\u2502`));
|
|
58
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${style(item.replacement, [_.cyan])}${" ".repeat(Math.max(1, 51 - item.replacement.length))}\u2502`));
|
|
59
|
+
lines.push(t(`\u2502 ${style("\u2514\u2500", [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${" ".repeat(Math.max(1, 35))}\u2502`));
|
|
46
60
|
}
|
|
47
61
|
}
|
|
48
62
|
if (result.mediumImpactReplacements.length > 0) {
|
|
49
|
-
lines.push(
|
|
50
|
-
lines.push(
|
|
63
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
64
|
+
lines.push(t(`\u2502 ${style("\u{1F7E1}", [_.yellow])} ${style("MEDIUM IMPACT REPLACEMENTS", [_.bold, _.yellow])}${" ".repeat(20)}\u2502`));
|
|
51
65
|
for (const item of result.mediumImpactReplacements) {
|
|
52
|
-
const autoPr = item.autoPrReady ?
|
|
66
|
+
const autoPr = item.autoPrReady ? style("\u2713 Auto-PR ready", [_.green]) : style("Manual review needed", [_.dim]);
|
|
53
67
|
const confIcon = confidenceIcon(item.confidence);
|
|
54
|
-
lines.push(
|
|
55
|
-
lines.push(
|
|
56
|
-
lines.push(
|
|
57
|
-
lines.push(
|
|
68
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
69
|
+
lines.push(t(`\u2502 ${style("\u2717", [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${" ".repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}\u2502`));
|
|
70
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${style(item.replacement, [_.cyan])}${" ".repeat(Math.max(1, 51 - item.replacement.length))}\u2502`));
|
|
71
|
+
lines.push(t(`\u2502 ${style("\u2514\u2500", [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${" ".repeat(Math.max(1, 35))}\u2502`));
|
|
58
72
|
}
|
|
59
73
|
}
|
|
60
74
|
if (result.securityIssues.length > 0) {
|
|
61
|
-
lines.push(
|
|
62
|
-
lines.push(
|
|
75
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
76
|
+
lines.push(t(`\u2502 ${style("\u{1F534}", [_.red])} ${style("SECURITY ISSUES", [_.bold, _.red])}${" ".repeat(33)}\u2502`));
|
|
63
77
|
for (const issue of result.securityIssues) {
|
|
64
|
-
lines.push(
|
|
65
|
-
lines.push(
|
|
66
|
-
lines.push(
|
|
78
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
79
|
+
lines.push(t(`\u2502 ${severityColor(issue.severity)} ${style(issue.cveId, [_.bold])} in ${issue.packageName}${" ".repeat(Math.max(1, 40 - issue.packageName.length))}\u2502`));
|
|
80
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${issue.fix}${" ".repeat(Math.max(1, 52 - issue.fix.length))}\u2502`));
|
|
67
81
|
}
|
|
68
82
|
}
|
|
69
|
-
lines.push(
|
|
83
|
+
lines.push(t(`\u2514${"\u2500".repeat(58)}\u2518`));
|
|
70
84
|
return lines.join("\n");
|
|
71
85
|
}
|
|
72
86
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/dep-exray/reporter/index.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../src/dep-exray/reporter/index.ts"],"sourcesContent":["import type { ScanResult, ReplacementSuggestion, SecurityIssue } from '../types.js'\n\n// ANSI color codes — zero dependencies\nconst _ = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n}\n\nfunction style(text: string, codes: string[]): string {\n return codes.join('') + text + _.reset\n}\n\nfunction severityColor(severity: SecurityIssue['severity']): string {\n switch (severity) {\n case 'critical': return style(severity.toUpperCase(), [_.bold, _.red])\n case 'high': return style(severity.toUpperCase(), [_.red])\n case 'medium': return style(severity.toUpperCase(), [_.yellow])\n case 'low': return style(severity.toUpperCase(), [_.dim])\n }\n}\n\nfunction confidenceIcon(confidence: ReplacementSuggestion['confidence']): string {\n switch (confidence) {\n case 'high': return style('●', [_.green])\n case 'medium': return style('●', [_.yellow])\n case 'low': return style('●', [_.red])\n }\n}\n\nexport function generateReport(result: ScanResult, jsonOutput?: boolean): string {\n if (jsonOutput) {\n return JSON.stringify(result, null, 2)\n }\n\n const lines: string[] = []\n\n const t = (text: string, codes: string[] = [_.cyan]) => style(text, [_.bold, ...codes])\n\n lines.push(t(`┌${'─'.repeat(58)}┐`))\n lines.push(t(`│${' '.repeat(18)}dep-exray Report${' '.repeat(21)}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('📦 PROJECT:', [_.white])} ${style(result.projectName, [_.bold])}${' '.repeat(Math.max(1, 47 - result.projectName.length))}│`))\n lines.push(t(`│ ${style('📊 DEPENDENCIES:', [_.white])} ${style(String(result.directDeps), [_.bold])} direct + ${style(String(result.transitiveDeps), [_.bold])} transitive${' '.repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}│`))\n lines.push(t(`│ ${style('💾 TOTAL SIZE:', [_.white])} ${style(result.totalEstimatedSize, [_.bold])}${' '.repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n\n if (result.highImpactReplacements.length > 0) {\n lines.push(t(`│ ${style('🟢', [_.green])} ${style('HIGH IMPACT REPLACEMENTS', [_.bold, _.green])}${' '.repeat(23)}│`))\n for (const item of result.highImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.mediumImpactReplacements.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🟡', [_.yellow])} ${style('MEDIUM IMPACT REPLACEMENTS', [_.bold, _.yellow])}${' '.repeat(20)}│`))\n for (const item of result.mediumImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.securityIssues.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🔴', [_.red])} ${style('SECURITY ISSUES', [_.bold, _.red])}${' '.repeat(33)}│`))\n for (const issue of result.securityIssues) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${severityColor(issue.severity)} ${style(issue.cveId, [_.bold])} in ${issue.packageName}${' '.repeat(Math.max(1, 40 - issue.packageName.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${issue.fix}${' '.repeat(Math.max(1, 52 - issue.fix.length))}│`))\n }\n }\n\n lines.push(t(`└${'─'.repeat(58)}┘`))\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1018,7 +1018,7 @@ function truncate(str, maxLength, suffix = "...") {
|
|
|
1018
1018
|
return str.slice(0, Math.max(0, maxLength - suffix.length)) + suffix;
|
|
1019
1019
|
}
|
|
1020
1020
|
function template(str, data) {
|
|
1021
|
-
return str.replace(/\{\{(\w+)\}\}/g, (
|
|
1021
|
+
return str.replace(/\{\{(\w+)\}\}/g, (_2, key) => {
|
|
1022
1022
|
const value = data[key];
|
|
1023
1023
|
return value !== void 0 ? String(value) : `{{${key}}}`;
|
|
1024
1024
|
});
|
|
@@ -1118,7 +1118,7 @@ function sleep(ms) {
|
|
|
1118
1118
|
}
|
|
1119
1119
|
async function timeout(promise, ms, errorMessage) {
|
|
1120
1120
|
let timer;
|
|
1121
|
-
const timeoutPromise = new Promise((
|
|
1121
|
+
const timeoutPromise = new Promise((_2, reject) => {
|
|
1122
1122
|
timer = setTimeout(() => reject(new Error(errorMessage ?? `Promise timed out after ${ms}ms`)), ms);
|
|
1123
1123
|
});
|
|
1124
1124
|
try {
|
|
@@ -1668,27 +1668,40 @@ async function scanProject(config) {
|
|
|
1668
1668
|
}
|
|
1669
1669
|
|
|
1670
1670
|
// src/dep-exray/reporter/index.ts
|
|
1671
|
-
|
|
1671
|
+
var _ = {
|
|
1672
|
+
reset: "\x1B[0m",
|
|
1673
|
+
bold: "\x1B[1m",
|
|
1674
|
+
dim: "\x1B[2m",
|
|
1675
|
+
red: "\x1B[31m",
|
|
1676
|
+
green: "\x1B[32m",
|
|
1677
|
+
yellow: "\x1B[33m",
|
|
1678
|
+
blue: "\x1B[34m",
|
|
1679
|
+
cyan: "\x1B[36m",
|
|
1680
|
+
white: "\x1B[37m"
|
|
1681
|
+
};
|
|
1682
|
+
function style(text, codes) {
|
|
1683
|
+
return codes.join("") + text + _.reset;
|
|
1684
|
+
}
|
|
1672
1685
|
function severityColor(severity) {
|
|
1673
1686
|
switch (severity) {
|
|
1674
1687
|
case "critical":
|
|
1675
|
-
return
|
|
1688
|
+
return style(severity.toUpperCase(), [_.bold, _.red]);
|
|
1676
1689
|
case "high":
|
|
1677
|
-
return
|
|
1690
|
+
return style(severity.toUpperCase(), [_.red]);
|
|
1678
1691
|
case "medium":
|
|
1679
|
-
return
|
|
1692
|
+
return style(severity.toUpperCase(), [_.yellow]);
|
|
1680
1693
|
case "low":
|
|
1681
|
-
return
|
|
1694
|
+
return style(severity.toUpperCase(), [_.dim]);
|
|
1682
1695
|
}
|
|
1683
1696
|
}
|
|
1684
1697
|
function confidenceIcon(confidence) {
|
|
1685
1698
|
switch (confidence) {
|
|
1686
1699
|
case "high":
|
|
1687
|
-
return
|
|
1700
|
+
return style("\u25CF", [_.green]);
|
|
1688
1701
|
case "medium":
|
|
1689
|
-
return
|
|
1702
|
+
return style("\u25CF", [_.yellow]);
|
|
1690
1703
|
case "low":
|
|
1691
|
-
return
|
|
1704
|
+
return style("\u25CF", [_.red]);
|
|
1692
1705
|
}
|
|
1693
1706
|
}
|
|
1694
1707
|
function generateReport(result, jsonOutput) {
|
|
@@ -1696,46 +1709,47 @@ function generateReport(result, jsonOutput) {
|
|
|
1696
1709
|
return JSON.stringify(result, null, 2);
|
|
1697
1710
|
}
|
|
1698
1711
|
const lines = [];
|
|
1699
|
-
|
|
1700
|
-
lines.push(
|
|
1701
|
-
lines.push(
|
|
1702
|
-
lines.push(
|
|
1703
|
-
lines.push(
|
|
1704
|
-
lines.push(
|
|
1705
|
-
lines.push(
|
|
1712
|
+
const t = (text, codes = [_.cyan]) => style(text, [_.bold, ...codes]);
|
|
1713
|
+
lines.push(t(`\u250C${"\u2500".repeat(58)}\u2510`));
|
|
1714
|
+
lines.push(t(`\u2502${" ".repeat(18)}dep-exray Report${" ".repeat(21)}\u2502`));
|
|
1715
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1716
|
+
lines.push(t(`\u2502 ${style("\u{1F4E6} PROJECT:", [_.white])} ${style(result.projectName, [_.bold])}${" ".repeat(Math.max(1, 47 - result.projectName.length))}\u2502`));
|
|
1717
|
+
lines.push(t(`\u2502 ${style("\u{1F4CA} DEPENDENCIES:", [_.white])} ${style(String(result.directDeps), [_.bold])} direct + ${style(String(result.transitiveDeps), [_.bold])} transitive${" ".repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}\u2502`));
|
|
1718
|
+
lines.push(t(`\u2502 ${style("\u{1F4BE} TOTAL SIZE:", [_.white])} ${style(result.totalEstimatedSize, [_.bold])}${" ".repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}\u2502`));
|
|
1719
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1706
1720
|
if (result.highImpactReplacements.length > 0) {
|
|
1707
|
-
lines.push(
|
|
1721
|
+
lines.push(t(`\u2502 ${style("\u{1F7E2}", [_.green])} ${style("HIGH IMPACT REPLACEMENTS", [_.bold, _.green])}${" ".repeat(23)}\u2502`));
|
|
1708
1722
|
for (const item of result.highImpactReplacements) {
|
|
1709
|
-
const autoPr = item.autoPrReady ?
|
|
1723
|
+
const autoPr = item.autoPrReady ? style("\u2713 Auto-PR ready", [_.green]) : style("Manual review needed", [_.dim]);
|
|
1710
1724
|
const confIcon = confidenceIcon(item.confidence);
|
|
1711
|
-
lines.push(
|
|
1712
|
-
lines.push(
|
|
1713
|
-
lines.push(
|
|
1714
|
-
lines.push(
|
|
1725
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1726
|
+
lines.push(t(`\u2502 ${style("\u2717", [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${" ".repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}\u2502`));
|
|
1727
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${style(item.replacement, [_.cyan])}${" ".repeat(Math.max(1, 51 - item.replacement.length))}\u2502`));
|
|
1728
|
+
lines.push(t(`\u2502 ${style("\u2514\u2500", [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${" ".repeat(Math.max(1, 35))}\u2502`));
|
|
1715
1729
|
}
|
|
1716
1730
|
}
|
|
1717
1731
|
if (result.mediumImpactReplacements.length > 0) {
|
|
1718
|
-
lines.push(
|
|
1719
|
-
lines.push(
|
|
1732
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1733
|
+
lines.push(t(`\u2502 ${style("\u{1F7E1}", [_.yellow])} ${style("MEDIUM IMPACT REPLACEMENTS", [_.bold, _.yellow])}${" ".repeat(20)}\u2502`));
|
|
1720
1734
|
for (const item of result.mediumImpactReplacements) {
|
|
1721
|
-
const autoPr = item.autoPrReady ?
|
|
1735
|
+
const autoPr = item.autoPrReady ? style("\u2713 Auto-PR ready", [_.green]) : style("Manual review needed", [_.dim]);
|
|
1722
1736
|
const confIcon = confidenceIcon(item.confidence);
|
|
1723
|
-
lines.push(
|
|
1724
|
-
lines.push(
|
|
1725
|
-
lines.push(
|
|
1726
|
-
lines.push(
|
|
1737
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1738
|
+
lines.push(t(`\u2502 ${style("\u2717", [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${" ".repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}\u2502`));
|
|
1739
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${style(item.replacement, [_.cyan])}${" ".repeat(Math.max(1, 51 - item.replacement.length))}\u2502`));
|
|
1740
|
+
lines.push(t(`\u2502 ${style("\u2514\u2500", [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${" ".repeat(Math.max(1, 35))}\u2502`));
|
|
1727
1741
|
}
|
|
1728
1742
|
}
|
|
1729
1743
|
if (result.securityIssues.length > 0) {
|
|
1730
|
-
lines.push(
|
|
1731
|
-
lines.push(
|
|
1744
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1745
|
+
lines.push(t(`\u2502 ${style("\u{1F534}", [_.red])} ${style("SECURITY ISSUES", [_.bold, _.red])}${" ".repeat(33)}\u2502`));
|
|
1732
1746
|
for (const issue of result.securityIssues) {
|
|
1733
|
-
lines.push(
|
|
1734
|
-
lines.push(
|
|
1735
|
-
lines.push(
|
|
1747
|
+
lines.push(t(`\u251C${"\u2500".repeat(58)}\u2524`));
|
|
1748
|
+
lines.push(t(`\u2502 ${severityColor(issue.severity)} ${style(issue.cveId, [_.bold])} in ${issue.packageName}${" ".repeat(Math.max(1, 40 - issue.packageName.length))}\u2502`));
|
|
1749
|
+
lines.push(t(`\u2502 ${style("\u2192", [_.dim])} ${issue.fix}${" ".repeat(Math.max(1, 52 - issue.fix.length))}\u2502`));
|
|
1736
1750
|
}
|
|
1737
1751
|
}
|
|
1738
|
-
lines.push(
|
|
1752
|
+
lines.push(t(`\u2514${"\u2500".repeat(58)}\u2518`));
|
|
1739
1753
|
return lines.join("\n");
|
|
1740
1754
|
}
|
|
1741
1755
|
|