securesync
Version:
Intelligent dependency security scanner with auto-fix
34 lines (29 loc) • 24.3 kB
JavaScript
"use strict";var de=Object.create;var L=Object.defineProperty;var me=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var he=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var ve=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ye(e))!we.call(n,i)&&i!==t&&L(n,i,{get:()=>e[i],enumerable:!(r=me(e,i))||r.enumerable});return n};var w=(n,e,t)=>(t=n!=null?de(he(n)):{},ve(e||!n||!n.__esModule?L(t,"default",{value:n,enumerable:!0}):t,n));var ue=require("commander");var V=require("commander");var P=require("fs/promises"),A=require("path"),D=require("fs");async function S(n,e={}){let t=await be(n),r=await ke(n),i=Ce(t,r,e.includeDevDependencies??!1),o=await xe(n,i),l=e.enhanceWithOSV?await $e(o):o,a=e.analyzeReachability?await Pe(l,n):l,c={critical:a.filter(f=>f.severity==="critical").length,high:a.filter(f=>f.severity==="high").length,moderate:a.filter(f=>f.severity==="moderate").length,low:a.filter(f=>f.severity==="low").length};return{vulnerabilities:a,totalPackages:i.packages.length,scannedAt:new Date,dependencies:i,summary:c}}async function be(n){let e=(0,A.join)(n,"package.json");if(!(0,D.existsSync)(e))throw new Error(`package.json not found at ${e}`);let t=await(0,P.readFile)(e,"utf-8");return JSON.parse(t)}async function ke(n){let e=(0,A.join)(n,"package-lock.json");if(!(0,D.existsSync)(e))throw new Error(`package-lock.json not found at ${e}. Please run 'npm install' first.`);let t=await(0,P.readFile)(e,"utf-8");return JSON.parse(t)}function Ce(n,e,t){let r=[],i=new Map,o=n.dependencies||{},l=t?n.devDependencies||{}:{};for(let[a]of Object.entries(o)){let c=e.packages?.[`node_modules/${a}`];c&&(i.set(a,{name:a,version:c.version,resolved:c.resolved||"",dependencies:$(e,c)}),r.push({name:a,version:c.version,isDevDependency:!1,isDirect:!0}))}for(let[a]of Object.entries(l)){let c=e.packages?.[`node_modules/${a}`];c&&(i.set(a,{name:a,version:c.version,resolved:c.resolved||"",dependencies:$(e,c)}),r.push({name:a,version:c.version,isDevDependency:!0,isDirect:!0}))}return Se(i,r),{name:n.name,version:n.version,dependencies:i,packages:r}}function $(n,e){if(!e.dependencies)return;let t=new Map;for(let[r]of Object.entries(e.dependencies)){let i=n.packages?.[`node_modules/${r}`];i&&t.set(r,{name:r,version:i.version,resolved:i.resolved||"",dependencies:$(n,i)})}return t.size>0?t:void 0}function Se(n,e){let t=new Set(e.map(i=>`${i.name}@${i.version}`));function r(i,o){if(i)for(let[l,a]of i){let c=`${l}@${a.version}`;t.has(c)||(t.add(c),e.push({name:l,version:a.version,isDevDependency:o,isDirect:!1})),r(a.dependencies,o)}}for(let[,i]of n)r(i.dependencies,!1)}async function xe(n,e){let t=[];try{return t}catch(r){return console.error("Error querying npm audit:",r),t}}async function $e(n){return n}async function Pe(n,e){return n}var g=w(require("chalk")),J=w(require("ora")),M=class{spinner=null;startSpinner(e){this.spinner=(0,J.default)(e).start()}stopSpinner(e=!0,t){this.spinner&&(e?this.spinner.succeed(t):this.spinner.fail(t),this.spinner=null)}updateSpinner(e){this.spinner&&(this.spinner.text=e)}success(e){console.log(g.default.green("\u2713")+" "+e)}error(e){console.log(g.default.red("\u2717")+" "+e)}warning(e){console.log(g.default.yellow("\u26A0")+" "+e)}info(e){console.log(g.default.blue("\u2139")+" "+e)}header(e){console.log(`
`+g.default.bold.underline(e)+`
`)}section(e){console.log(`
`+g.default.bold(e))}printScanResults(e){if(this.header("Security Scan Results"),console.log(g.default.bold("Summary:")),console.log(` Total packages scanned: ${e.totalPackages}`),console.log(` Vulnerabilities found: ${e.vulnerabilities.length}`),console.log(` Scanned at: ${e.scannedAt.toLocaleString()}
`),e.summary&&(console.log(g.default.bold("Severity Breakdown:")),e.summary.critical>0&&console.log(` ${g.default.red("Critical")}: ${e.summary.critical}`),e.summary.high>0&&console.log(` ${g.default.red("High")}: ${e.summary.high}`),e.summary.moderate>0&&console.log(` ${g.default.yellow("Moderate")}: ${e.summary.moderate}`),e.summary.low>0&&console.log(` ${g.default.blue("Low")}: ${e.summary.low}`),console.log()),e.vulnerabilities.length>0){this.section("Vulnerabilities:");for(let t of e.vulnerabilities)this.printVulnerability(t)}else this.success("No vulnerabilities found!")}printVulnerability(e){let r=this.getSeverityColor(e.severity)(e.severity.toUpperCase());console.log(`
${g.default.bold(e.id)} [${r}]`),console.log(` Package: ${g.default.cyan(e.package)}@${e.version}`),console.log(` Description: ${e.description}`),e.patched&&e.patched.length>0&&console.log(` Patched in: ${g.default.green(e.patched.join(", "))}`),e.path&&e.path.length>0&&console.log(` Path: ${e.path.join(" > ")}`),e.cvss&&console.log(` CVSS Score: ${e.cvss}`)}printBreakingChanges(e){if(this.header(`Breaking Change Analysis: ${e.packageName}`),console.log(` From: ${g.default.cyan(e.fromVersion)}`),console.log(` To: ${g.default.cyan(e.toVersion)}`),console.log(` Risk Level: ${this.getRiskColor(e.riskLevel)(e.riskLevel.toUpperCase())}`),console.log(` Breaking Changes: ${e.hasBreakingChanges?g.default.red("YES"):g.default.green("NO")}`),console.log(` Changes Found: ${e.changes.length}
`),e.changes.length>0){this.section("Changes:");for(let t of e.changes){let r=t.type==="breaking"?g.default.red:g.default.green;console.log(`
${r(t.type.toUpperCase())}: ${t.symbol}`),console.log(` Category: ${t.category}`),t.before&&console.log(` Before: ${g.default.gray(t.before)}`),t.after&&console.log(` After: ${g.default.gray(t.after)}`),t.migration&&console.log(` Migration: ${g.default.cyan(t.migration)}`),console.log(` Confidence: ${Math.round(t.confidence*100)}%`)}}}printAlternatives(e){if(this.header("Alternative Packages"),e.length===0){this.warning("No suitable alternatives found.");return}for(let t=0;t<e.length;t++){let r=e[t];console.log(`
${g.default.bold(`${t+1}. ${r.name}`)} (Score: ${r.score}/100)`),console.log(` ${r.description}`),console.log(` Downloads: ${this.formatNumber(r.downloads)}/week`),console.log(` Last publish: ${this.formatDate(r.lastPublish)}`),console.log(` Stars: ${this.formatNumber(r.stars)}`),console.log(` Vulnerabilities: ${r.vulnerabilities===0?g.default.green("0"):g.default.red(r.vulnerabilities)}`),console.log(` API Compatibility: ${r.compatibility}%`),console.log(` Migration Effort: ${this.getMigrationColor(r.migrationEffort)(r.migrationEffort.toUpperCase())}`)}}getSeverityColor(e){switch(e.toLowerCase()){case"critical":case"high":return g.default.red;case"moderate":return g.default.yellow;case"low":return g.default.blue;default:return g.default.gray}}getRiskColor(e){switch(e.toLowerCase()){case"high":return g.default.red;case"medium":return g.default.yellow;case"low":return g.default.green;default:return g.default.gray}}getMigrationColor(e){switch(e.toLowerCase()){case"low":return g.default.green;case"medium":return g.default.yellow;case"high":return g.default.red;default:return g.default.gray}}formatNumber(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toString()}formatDate(e){let r=new Date().getTime()-e.getTime(),i=Math.floor(r/(1e3*60*60*24));if(i===0)return"today";if(i===1)return"yesterday";if(i<30)return`${i} days ago`;if(i<365){let o=Math.floor(i/30);return`${o} month${o>1?"s":""} ago`}else{let o=Math.floor(i/365);return`${o} year${o>1?"s":""} ago`}}},s=new M;function _(){let n=new V.Command("scan");return n.description("Scan project for security vulnerabilities").argument("[path]","Project path to scan",process.cwd()).option("-d, --dev","Include dev dependencies",!1).option("-r, --reachability","Analyze vulnerability reachability",!1).option("--enhance","Enhance with additional vulnerability databases",!1).option("--fail-on <severity>","Exit with error code if vulnerabilities of severity or higher found","").option("--json","Output results as JSON",!1).action(async(e,t)=>{try{s.startSpinner("Scanning dependencies...");let r=await S(e,{projectPath:e,includeDevDependencies:t.dev,analyzeReachability:t.reachability,enhanceWithOSV:t.enhance});if(s.stopSpinner(!0,"Scan complete"),t.json?console.log(JSON.stringify(r,null,2)):s.printScanResults(r),t.failOn){let i=["low","moderate","high","critical"],o=i.indexOf(t.failOn.toLowerCase());o===-1&&(s.error(`Invalid severity level: ${t.failOn}`),process.exit(1)),r.vulnerabilities.some(a=>i.indexOf(a.severity)>=o)&&(s.error(`Found vulnerabilities with severity ${t.failOn} or higher`),process.exit(1))}}catch(r){s.stopSpinner(!1,"Scan failed"),s.error(r.message),process.exit(1)}}),n}var W=require("commander");var v=require("semver");function T(n,e){if(!(0,v.valid)(n)||!(0,v.valid)(e))throw new Error(`Invalid semver versions: ${n} or ${e}`);let t=(0,v.compare)(n,e),r=(0,v.diff)(n,e);return{fromVersion:n,toVersion:e,diffType:r,isUpgrade:t<0,isDowngrade:t>0,expectedBreakingChanges:r==="major"||r==="premajor"}}function U(n){return n.expectedBreakingChanges?!0:n.isUpgrade&&n.diffType!==null}async function j(n){let e=[],t=/^##?\s*\[?(\d+\.\d+\.\d+[^\]]*)\]?.*$/gm,r=[...n.matchAll(t)];for(let i=0;i<r.length;i++){let o=r[i],l=o[1],a=o.index+o[0].length,c=i<r.length-1?r[i+1].index:n.length,f=n.slice(a,c);e.push({version:l,date:Ae(o[0]),changes:De(f)})}return e}function Ae(n){let e=/\d{4}-\d{2}-\d{2}/,t=n.match(e);return t?t[0]:void 0}function De(n){let e={breaking:[],features:[],fixes:[],other:[]},t=n.split(`
`),r="other";for(let i of t){let o=i.trim();if(/^###?\s*(breaking|breaking changes)/i.test(o)){r="breaking";continue}else if(/^###?\s*(features?|added)/i.test(o)){r="features";continue}else if(/^###?\s*(fix(es)?|bug\s*fix(es)?)/i.test(o)){r="fixes";continue}if(/^[-*]\s/.test(o)){let l=o.replace(/^[-*]\s/,"").trim();l&&e[r].push(l)}}return e}function G(n,e){let t=new Map,r=n.find(i=>i.version===e);if(!r)return t;for(let i of r.changes.breaking){let o=Me(i);o&&t.set(o.from,o.to)}return t}function Me(n){let e=/replace\s+`?(\w+)`?\s+with\s+`?(\w+)`?/i,t=/use\s+`?(\w+)`?\s+instead\s+of\s+`?(\w+)`?/i,r=n.match(e);return r?{from:r[1],to:r[2]}:(r=n.match(t),r?{from:r[2],to:r[1]}:null)}function H(n,e){let t=[],r=new Map(n.map(o=>[o.name,o])),i=new Map(e.map(o=>[o.name,o]));for(let[o,l]of r){if(!l.exported)continue;let a=i.get(o);a?a.signature!==l.signature&&t.push({type:"breaking",category:"signature",symbol:o,before:l.signature,after:a.signature,confidence:.9,source:"typescript"}):t.push({type:"breaking",category:"removed",symbol:o,before:l.signature,after:"",confidence:1,source:"typescript"})}for(let[o,l]of i)l.exported&&(r.has(o)||t.push({type:"feature",category:"signature",symbol:o,before:"",after:l.signature,confidence:1,source:"typescript"}));return t}async function I(n){return[]}function q(n,e){return n.map(t=>{if(t.category==="removed"||t.category==="renamed"){let r=e.get(t.symbol);if(r)return{...t,migration:`Replace \`${t.symbol}\` with \`${r}\``,confidence:Math.min(t.confidence+.1,1)}}return t})}async function C(n,e,t){let r=T(e,t);if(!U(r))return{packageName:n,fromVersion:e,toVersion:t,changes:[],hasBreakingChanges:!1,riskLevel:"low",analyzedAt:new Date};let i=await K(n,e),o=await K(n,t),l=await I(i),a=await I(o),c=H(l,a),f=await Te(o),u=f?await j(f):[],d=G(u,t),m=q(c,d),p=u.find(k=>k.version===t);if(p)for(let k of p.changes.breaking)m.some(pe=>pe.symbol===k)||m.push({type:"breaking",category:"behavior",symbol:k,before:"",after:"",confidence:.7,source:"changelog"});let y=je(m,r.expectedBreakingChanges);return{packageName:n,fromVersion:e,toVersion:t,changes:m,hasBreakingChanges:m.some(k=>k.type==="breaking"),riskLevel:y,analyzedAt:new Date}}async function K(n,e){return`/tmp/securesync-cache/${n}@${e}`}async function Te(n){return null}function je(n,e){let t=n.filter(r=>r.type==="breaking");return t.length===0?"low":t.length>5||!e?"high":"medium"}function Y(){let n=new W.Command("analyze");return n.description("Analyze breaking changes for a package update").argument("<package>","Package name").argument("<from-version>","Current version").argument("<to-version>","Target version").option("--json","Output results as JSON",!1).action(async(e,t,r,i)=>{try{s.startSpinner(`Analyzing breaking changes for ${e}...`);let o=await C(e,t,r);s.stopSpinner(!0,"Analysis complete"),i.json?console.log(JSON.stringify(o,null,2)):s.printBreakingChanges(o),o.hasBreakingChanges&&process.exit(1)}catch(o){s.stopSpinner(!1,"Analysis failed"),s.error(o.message),process.exit(1)}}),n}var Q=require("commander");async function O(n,e){let t=0,r=Ie(n.downloads);t+=r*.3;let i=Oe(n.lastPublish);t+=i*.25;let o=await Fe(n.name);t+=o*.25;let l=await Re(n);return t+=l*.2,Math.min(100,Math.round(t))}function Ie(n){return n>=1e6?100:n>=1e5?75+(n-1e5)/9e5*25:n>=1e4?50+(n-1e4)/9e4*25:n>=1e3?25+(n-1e3)/9e3*25:n/1e3*25}function Oe(n){let e=Be(n);return e<30?100:e<90?80+(90-e)/60*20:e<180?60+(180-e)/90*20:e<365?40+(365-e)/185*20:e<730?20+(730-e)/365*20:Math.max(0,20-(e-730)/365*20)}async function Fe(n){return 100}async function Re(n){let e=0;return n.description&&n.description.length>20&&(e+=20),n.repository&&(e+=20),n.homepage&&(e+=15),n.keywords&&n.keywords.length>=3&&(e+=15),n.license&&(e+=15),e}function Be(n){let t=new Date().getTime()-n.getTime();return Math.floor(t/(1e3*60*60*24))}async function F(n,e={}){let t=await ze(n),r=await Ne({keywords:t,exclude:[n]});return(await Promise.all(r.map(async o=>{let l=await O(o,n),a=await Le(o,n),c=Je(a,l);return{name:o.name,description:o.description,downloads:o.downloads,lastPublish:o.lastPublish,stars:0,issues:0,maintainers:0,vulnerabilities:0,compatibility:a,migrationEffort:c,score:l}}))).filter(o=>Ve(o,e)).sort((o,l)=>l.score-o.score).slice(0,10)}async function ze(n){try{return(await Ee(n)).keywords||[]}catch{return n.split("-").filter(e=>e.length>2)}}async function Ne(n){return[]}async function Ee(n){return{name:n,description:"",version:"1.0.0",downloads:0,lastPublish:new Date,keywords:[]}}async function Le(n,e){return 50}function Je(n,e){return n>=80?"low":n>=50?"medium":"high"}function Ve(n,e){return!(e.minDownloads&&n.downloads<e.minDownloads||e.maxAge&&_e(n.lastPublish)>e.maxAge||e.minStars&&n.stars<e.minStars||e.zeroVulnerabilities&&n.vulnerabilities>0||e.minCompatibility&&n.compatibility<e.minCompatibility)}function _e(n){let t=new Date().getTime()-n.getTime();return Math.floor(t/(1e3*60*60*24))}function X(){let n=new Q.Command("alternatives");return n.description("Find alternative packages").argument("<package>","Package name to find alternatives for").option("--min-downloads <number>","Minimum weekly downloads",parseInt).option("--max-age <days>","Maximum days since last publish",parseInt).option("--min-stars <number>","Minimum GitHub stars",parseInt).option("--zero-vulns","Only show packages with zero vulnerabilities",!1).option("--min-compat <number>","Minimum API compatibility score (0-100)",parseInt).option("--json","Output results as JSON",!1).action(async(e,t)=>{try{s.startSpinner(`Finding alternatives for ${e}...`);let r=await F(e,{minDownloads:t.minDownloads,maxAge:t.maxAge,minStars:t.minStars,zeroVulnerabilities:t.zeroVulns,minCompatibility:t.minCompat});s.stopSpinner(!0,`Found ${r.length} alternative(s)`),t.json?console.log(JSON.stringify(r,null,2)):s.printAlternatives(r)}catch(r){s.stopSpinner(!1,"Search failed"),s.error(r.message),process.exit(1)}}),n}var ae=require("commander");var Z=require("fs/promises"),ee=require("@babel/parser"),ne=w(require("@babel/traverse")),R=w(require("@babel/generator"));async function x(n,e,t){let r=[],i=await Ue(n,e);for(let o of i){let l=await(0,Z.readFile)(o,"utf-8"),a;try{a=(0,ee.parse)(l,{sourceType:"module",plugins:["typescript","jsx"]})}catch(u){console.warn(`Failed to parse ${o}:`,u);continue}let c=[],f=t.filter(u=>u.type==="breaking");(0,ne.default)(a,{CallExpression(u){let d=u.node.callee,m=Ge(d,f);if(m){let p=(0,R.default)(u.node),y=He(u.node,m);y&&c.push({line:u.node.loc?.start.line||0,column:u.node.loc?.start.column||0,old:p.code,new:y})}},ImportDeclaration(u){if(u.node.source.value===e){for(let d of u.node.specifiers)if(d.type==="ImportSpecifier"){let m=d.imported.type==="Identifier"?d.imported.name:"",p=f.find(y=>y.symbol===m&&y.category==="renamed");if(p&&p.migration){let y=(0,R.default)(d);c.push({line:d.loc?.start.line||0,column:d.loc?.start.column||0,old:y.code,new:p.migration})}}}}}),c.length>0&&r.push({file:o,changes:c,script:qe(o,c),safe:Ke(c,f)})}return r}async function Ue(n,e){return[]}function Ge(n,e){return n.type==="Identifier"?e.find(t=>t.symbol===n.name)||null:n.type==="MemberExpression"&&n.property.type==="Identifier"&&e.find(t=>t.symbol===n.property.name)||null}function He(n,e){return e.migration?e.migration:(e.category==="signature",null)}function qe(n,e){let t=`// Migration script for ${n}
`;t+=`import { readFile, writeFile } from 'fs/promises';
`,t+=`async function migrate() {
`,t+=` const content = await readFile('${n}', 'utf-8');
`,t+=` let updated = content;
`;for(let r of e)t+=` // Line ${r.line}: ${r.old} -> ${r.new}
`,t+=` updated = updated.replace(
`,t+=` ${JSON.stringify(r.old)},
`,t+=` ${JSON.stringify(r.new)}
`,t+=` );
`;return t+=` await writeFile('${n}', updated, 'utf-8');
`,t+=` console.log('Migration completed for ${n}');
`,t+=`}
`,t+=`migrate().catch(console.error);
`,t}function Ke(n,e){return!(n.length>5||e.some(i=>i.confidence<.8)||n.some(i=>!i.new||i.new===i.old))}var re=require("child_process"),ie=require("util"),oe=require("fs/promises"),h=require("path"),z=(0,ie.promisify)(re.exec);async function N(n,e,t,r,i={}){let o=i.runTests??!0,l=i.createBackup??!0;if(o){let a=await B(n);if(!a.passed)return{success:!1,reason:"Tests failing before update - please fix existing test failures first",failedTests:a.failedTests}}l&&await Qe(n);try{if(await Xe(n,e,t),i.autoApply&&r.length>0)for(let a of r)(a.safe||i.interactive===!1)&&await Ze(a);if(o){let a=await B(n);if(!a.passed)return await te(n),{success:!1,reason:"Tests failed after update",failedTests:a.failedTests,migrations:r,rolledBack:!0}}return{success:!0,migrations:r}}catch(a){throw l&&await te(n),a}}async function B(n){let e=Date.now();try{let t=await We(n);if(!t)return{passed:!0,output:"No test command found, skipping tests",duration:Date.now()-e};let{stdout:r}=await z(t,{cwd:n,env:{...process.env,CI:"true"}});return{passed:!0,output:r,duration:Date.now()-e,exitCode:0}}catch(t){return{passed:!1,output:t.stderr||t.stdout||t.message,duration:Date.now()-e,failedTests:Ye(t.stderr||t.stdout||""),exitCode:t.code}}}async function We(n){try{let e=(0,h.join)(n,"package.json"),t=await(0,oe.readFile)(e,"utf-8");return JSON.parse(t).scripts?.test||null}catch{return null}}function Ye(n){let e=[],t=[/FAIL\s+(.+)/g,/✖\s+(.+)/g,/×\s+(.+)/g,/ERROR\s+(.+)/g];for(let r of t){let i=n.matchAll(r);for(let o of i)o[1]&&!e.includes(o[1])&&e.push(o[1].trim())}return e}async function Qe(n){let{copyFile:e}=await import("fs/promises");try{await e((0,h.join)(n,"package.json"),(0,h.join)(n,"package.json.backup")),await e((0,h.join)(n,"package-lock.json"),(0,h.join)(n,"package-lock.json.backup"))}catch(t){console.warn("Failed to create backup files:",t)}}async function Xe(n,e,t){await z(`npm install ${e}@${t}`,{cwd:n})}async function Ze(n){let{readFile:e,writeFile:t}=await import("fs/promises");try{let r=await e(n.file,"utf-8");for(let i of n.changes)r=r.replace(i.old,i.new);await t(n.file,r,"utf-8")}catch(r){throw console.error(`Failed to apply migration to ${n.file}:`,r),r}}async function te(n){let{copyFile:e,unlink:t}=await import("fs/promises");try{await e((0,h.join)(n,"package.json.backup"),(0,h.join)(n,"package.json")),await e((0,h.join)(n,"package-lock.json.backup"),(0,h.join)(n,"package-lock.json")),await z("npm install",{cwd:n}),await t((0,h.join)(n,"package.json.backup")),await t((0,h.join)(n,"package-lock.json.backup"))}catch(r){throw console.error("Failed to rollback changes:",r),r}}var se=w(require("inquirer"));function ce(){let n=new ae.Command("fix");return n.description("Auto-fix vulnerabilities").argument("[path]","Project path",process.cwd()).option("--auto","Automatically apply fixes without prompts",!1).option("--no-test","Skip running tests",!1).option("--max-severity <level>","Only fix vulnerabilities up to this severity","critical").option("--breaking-changes <action>","How to handle breaking changes (skip, warn, allow)","warn").action(async(e,t)=>{try{s.startSpinner("Scanning for vulnerabilities...");let r=await S(e,{projectPath:e,includeDevDependencies:!1});if(s.stopSpinner(!0,`Found ${r.vulnerabilities.length} vulnerabilities`),r.vulnerabilities.length===0){s.success("No vulnerabilities to fix!");return}let i=["low","moderate","high","critical"],o=i.indexOf(t.maxSeverity.toLowerCase()),l=r.vulnerabilities.filter(c=>i.indexOf(c.severity)>=o);s.info(`Found ${l.length} vulnerabilities matching severity criteria`);let a=new Map;for(let c of l)a.has(c.package)||a.set(c.package,{current:c.version,patched:c.patched});for(let[c,f]of a){let u=f.patched[0];if(!u){s.warning(`No patched version available for ${c}`);continue}s.section(`Processing ${c}@${f.current} -> ${u}`),s.startSpinner("Analyzing breaking changes...");let d=await C(c,f.current,u);if(s.stopSpinner(!0,"Analysis complete"),d.hasBreakingChanges){if(t.breakingChanges==="skip"){s.warning(`Skipping ${c} due to breaking changes`);continue}else if(t.breakingChanges==="warn"&&!t.auto){let{proceed:y}=await se.default.prompt([{type:"confirm",name:"proceed",message:`${c} has breaking changes. Continue?`,default:!1}]);if(!y){s.info(`Skipping ${c}`);continue}}}s.startSpinner("Generating migration scripts...");let m=await x(e,c,d.changes);s.stopSpinner(!0,`Generated ${m.length} migration(s)`),s.startSpinner("Applying update...");let p=await N(e,c,u,m,{autoApply:t.auto,runTests:t.test,createBackup:!0});if(p.success)s.stopSpinner(!0,`Successfully updated ${c}`);else{if(s.stopSpinner(!1,`Failed to update ${c}`),s.error(p.reason||"Unknown error"),p.failedTests){s.error("Failed tests:");for(let y of p.failedTests)console.log(` - ${y}`)}p.rolledBack&&s.info("Changes have been rolled back")}}s.success("Fix process complete!")}catch(r){s.error(r.message),process.exit(1)}}),n}var le=require("commander");var ge=require("fs/promises"),E=require("path");function fe(){let n=new le.Command("migrate");return n.description("Generate migration scripts for a package update").argument("<package>","Package name").argument("<to-version>","Target version").option("-p, --path <path>","Project path",process.cwd()).option("--from <version>","Current version (auto-detected if not provided)").option("--output <path>","Output directory for migration scripts","./migrations").option("--json","Output as JSON",!1).action(async(e,t,r)=>{try{let i=r.from;i||(s.startSpinner("Detecting current version..."),i=await en(r.path,e),s.stopSpinner(!0,`Current version: ${i}`)),s.startSpinner("Analyzing breaking changes...");let o=await C(e,i,t);s.stopSpinner(!0,"Analysis complete"),s.startSpinner("Generating migration scripts...");let l=await x(r.path,e,o.changes);if(s.stopSpinner(!0,`Generated ${l.length} migration(s)`),r.json){console.log(JSON.stringify({analysis:o,migrations:l},null,2));return}if(l.length>0){s.section("Migration Scripts:");for(let a=0;a<l.length;a++){let c=l[a],f=`${a+1}-${e.replace("/","-")}-${t}.js`,u=(0,E.join)(r.output,f);await(0,ge.writeFile)(u,c.script,"utf-8"),s.success(`Saved: ${u}`),console.log(`
File: ${c.file}`),console.log(` Changes: ${c.changes.length}`),console.log(` Safe to auto-apply: ${c.safe?"Yes":"No"}`)}s.info(`
Migration scripts saved to ${r.output}`)}else s.warning("No migration scripts needed");o.hasBreakingChanges&&s.printBreakingChanges(o)}catch(i){s.error(i.message),process.exit(1)}}),n}async function en(n,e){let{readFile:t}=await import("fs/promises"),r=(0,E.join)(n,"package.json");try{let i=await t(r,"utf-8"),o=JSON.parse(i),l=o.dependencies?.[e]||o.devDependencies?.[e];if(!l)throw new Error(`Package ${e} not found in dependencies`);return l.replace(/^[\^~>=<]/,"")}catch(i){throw new Error(`Failed to detect current version: ${i.message}`)}}var b=new ue.Command;b.name("securesync").description("Intelligent dependency security scanner with auto-fix").version("1.0.0");b.addCommand(_());b.addCommand(ce());b.addCommand(Y());b.addCommand(X());b.addCommand(fe());b.parse(process.argv);
//# sourceMappingURL=cli.js.map