Socket
Socket
Sign inDemoInstall

@namchee/dependent

Package Overview
Dependencies
62
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.14.1 to 0.15.0

src/service/parser/astro.test.ts

2

bin/index.js
#!/usr/bin/env node
import e from"ora";import t from"chalk";import n from"yargs";import{resolve as o,basename as r}from"path";import{existsSync as s,readFileSync as i}from"fs";import{spawn as a}from"child_process";import c from"glob";import{pathToFileURL as l}from"url";import p from"typescript";import{table as d}from"table";const u=n(process.argv.slice(2)).scriptName("dependent").command("$0 <package> [files...]","Analyze package usage in your project directory.").usage("Usage: $0 <package> [files...]").positional("package",{alias:"p",type:"string",description:"Package name to be analyzed."}).positional("files",{alias:"f",type:"string",description:"Files to be analyzed in glob pattern relative to the current project directory.",default:["!(node_modules)/**/*.js","!(node_modules)/**/*.mjs","!(node_modules)/**/*.ts","!(node_modules)/**/*.jsx","!(node_modules)/**/*.tsx","!(node_modules)/**/*.vue","!(node_modules)/**/*.svelte","*.js","*.mjs","*.ts","*.jsx","*.tsx","*.vue","*.svelte"]}).options({silent:{alias:"s",describe:"Skip all unreadable and unparseable files instead of throwing errors",type:"boolean",default:!1,demandOption:!1},table:{alias:"t",describe:"Print the output in table format",type:"boolean",default:!1,demandOption:!1},precheck:{alias:"c",describe:"Check if the package is installed",type:"boolean",default:!0,demandOption:!1},include:{describe:"Type of possible dependant to be scanned for dependency. Defaults to files and scripts",type:"array",default:["scripts","files"],demandOption:!1}});function m(e,t){return new Promise(((n,o)=>{const r=a(e,t);r.stdout.on("data",(e=>n(e))),r.on("error",(()=>o(new Error("Command not found"))))}))}const f={npm:"ls",pnpm:"ls",yarn:"why"};function h(){var e,t,n,r,a,c;const l=o(process.cwd(),"package.json");if(!s(l))throw new Error("The current project directory is not a NodeJS-based project");try{const o=JSON.parse(i(l,"utf-8"));return{name:null!==(e=o.name)&&void 0!==e?e:"",executables:null!==(t=o.bin)&&void 0!==t?t:{},scripts:null!==(n=o.scripts)&&void 0!==n?n:{},dependencies:null!==(r=o.dependencies)&&void 0!==r?r:{},devDependencies:null!==(a=o.devDependencies)&&void 0!==a?a:{},peerDependencies:null!==(c=o.peerDependencies)&&void 0!==c?c:{}}}catch(e){const{message:t}=e;throw new Error(`Failed to read package.json: ${t}`)}}async function g(e){let t=function(){const e=o(process.cwd(),"package-lock.json");if(s(e))return"npm";const t=o(process.cwd(),"yarn.lock");return s(t)?"yarn":"pnpm"}();const n=f[t];/^win/.test(process.platform)&&(t=`${t}.cmd`);const r=await m(t,[n,e]);if(!(r.includes(e)&&0!==r.lastIndexOf(e)))throw new Error(`Package ${e} has not been installed in this project`)}function y(e){const t=e.split("/");return e.startsWith("@")?t.slice(0,2).join("/"):t[0]}let w,v,j;function b(e,t,n){const o=[];return e.walk(t,{enter(e){var t,r,s;switch(e.type){case"ImportDeclaration":{const r=e;"Literal"===r.source.type&&y(null===(t=r.source.value)||void 0===t?void 0:t.toString())===n&&o.push(e.loc.start.line);break}case"ImportExpression":{const t=e;"Literal"===t.source.type&&y(null===(r=t.source.value)||void 0===r?void 0:r.toString())===n&&o.push(e.loc.start.line);break}case"CallExpression":{const t=e;"Identifier"===t.callee.type&&"require"===t.callee.name&&"Literal"===t.arguments[0].type&&y(null===(s=t.arguments[0].value)||void 0===s?void 0:s.toString())===n&&o.push(e.loc.start.line);break}}}}),o}async function S(e,t,n){v||await async function(e){if(v)return;const t=["typescript","lib","typescript.js"],n=[o(process.cwd(),"node_modules",...t),...e.map((e=>o(e,...t)))].map((e=>import(l(e).toString()))),r=await Promise.allSettled(n);for(let e=0;e<r.length;e++){const t=r[e];if("fulfilled"===t.status)return void(v=t.value.default)}throw new Error("No TypeScript parsers available")}(n);return function(e,t){const n=[],o=r=>{switch(r.kind){case p.SyntaxKind.ImportDeclaration:{const o=r.moduleSpecifier;o.kind===p.SyntaxKind.StringLiteral&&y(o.getText().slice(1,-1))===t&&n.push(e.getLineAndCharacterOfPosition(r.getStart()).line+1);break}case p.SyntaxKind.CallExpression:{const o=r,{expression:s}=o,i=o.arguments,a=s.kind===p.SyntaxKind.ImportKeyword&&1===i.length&&i[0].kind===p.SyntaxKind.StringLiteral&&y(i[0].getText().slice(1,-1))===t,c=s.kind===p.SyntaxKind.Identifier&&"require"===s.getText()&&1===i.length&&i[0].kind===p.SyntaxKind.StringLiteral&&y(i[0].getText().slice(1,-1))===t;(a||c)&&n.push(e.getLineAndCharacterOfPosition(r.getStart()).line+1);break}}v.forEachChild(r,o)};return o(e),n}(v.createSourceFile("",e,v.ScriptTarget.Latest,!0,v.ScriptKind.TSX),t)}const k={js:S,mjs:S,cjs:S,jsx:S,ts:S,vue:async function(e,t,n){var r;j||await async function(e){if(j)return;const t=["@vue","compiler-sfc","dist","compiler-sfc.cjs.js"],n=[o(process.cwd(),"node_modules","vue","compiler-sfc","index.js"),o(process.cwd(),"node_modules",...t),...e.map((e=>o(e,...t)))].map((e=>import(l(e).toString()))),r=await Promise.allSettled(n);for(let e=0;e<r.length;e++){const t=r[e];if("fulfilled"===t.status)return void(j=t.value.default)}throw new Error("No Vue 3 parser available")}(n);const s=j.parse(e),i=null!==(r=s.descriptor.script)&&void 0!==r?r:s.descriptor.scriptSetup;if(i){const e=i.loc.start.line;return(await S(i.content,t,n)).map((t=>t+e-1))}return[]},svelte:async function(e,t,n){w||await async function(e){if(w)return;const t=["svelte","compiler.js"],n=[o(process.cwd(),"node_modules",...t),...e.map((e=>o(e,...t)))].map((e=>import(l(e).toString()))),r=await Promise.allSettled(n);for(let e=0;e<r.length;e++){const t=r[e];if("fulfilled"===t.status)return void(w=t.value.default)}throw new Error("No Svelte compiler available")}(n);const r=w.parse(e);return[...b(w,r.instance,t),...b(w,r.module,t)]}};async function x(){try{return(await m(/^win/.test(process.platform)?"npm.cmd":"npm",["root","--global"])).toString().trim()}catch(e){if("Command not found"===e.message)return"";throw e}}async function $(){try{const e=await m(/^win/.test(process.platform)?"yarn.cmd":"yarn",["global","dir"]);return o(e.toString().trim(),"node_modules")}catch(e){if("Command not found"===e.message)return"";throw e}}async function E(){try{return(await m(/^win/.test(process.platform)?"pnpm.cmd":"pnpm",["root","--global"])).toString().trim()}catch(e){if("Command not found"===e.message)return"";throw e}}async function O(e,n,{silent:o}){const r=(await Promise.allSettled([x(),$(),E()])).map((e=>"fulfilled"===e.status?e.value:"")),s=e.map((async e=>{try{const t=function(e){return e.name.split(".").pop()}(e),o=function(e){if(!(e in k))throw new Error(`.${e} files are currently not supported`);return k[e]}(t),s=await o(e.content,n,r);return s.length?{name:e.name,path:e.path,lineNumbers:s}:null}catch(t){const n=t;throw new Error(`Failed to parse ${e.path}: ${n.message}`)}}));if(!o){return(await Promise.all(s)).filter((e=>null!==e))}const i=await Promise.allSettled(s),a=[];for(const e of i)"rejected"===e.status?console.log(t.yellow(e.reason)):e.value&&a.push(e.value);return a}function F(e){const{scripts:t}=h(),{executables:n}=function(e){var t,n,r,a,c,l;const p=o(process.cwd(),"node_modules",e,"package.json");if(!s(p))throw new Error("The current project directory is not a NodeJS-based project");try{const e=JSON.parse(i(p,"utf-8"));return{name:null!==(t=e.name)&&void 0!==t?t:"",executables:null!==(n=e.bin)&&void 0!==n?n:{},scripts:null!==(r=e.scripts)&&void 0!==r?r:{},dependencies:null!==(a=e.dependencies)&&void 0!==a?a:{},devDependencies:null!==(c=e.devDependencies)&&void 0!==c?c:{},peerDependencies:null!==(l=e.peerDependencies)&&void 0!==l?l:{}}}catch(e){const{message:t}=e;throw new Error(`Failed to read package.json: ${t}`)}}(e),r=[];if(Object.keys(n).length){const e=`(${Object.keys(n).join("|")})`;for(const[n,o]of Object.entries(t))o.match(e)&&r.push(n)}return r}const C={js:"JavaScript Files",cjs:"CommonJS Files",mjs:"ESModule Files",jsx:"JavaScript Extended Files",ts:"TypeScript Files",tsx:"TypeScript Extended Files",vue:"Vue's Single File Component",svelte:"Svelte's Single File Component"};function P(e,t){const n=e.path.split("/").length,o=t.path.split("/").length;return n>o?1:n<o?-1:e.name>t.name?1:-1}function T(e,n,o){return t.cyanBright(`${{files:"📁",scripts:"📜"}[e]} There are ${o} ${e} in this project that depends on '${n}'`)}function _(e){const t=[];for(const[n,o]of Object.entries(e)){const e=C[n];if(o.length){const n=`📜 ${e}`,r=o.map((e=>[e.name,e.path,e.lineNumbers.join(", ")])),s=d([["Filename","Path","Line Number"],...r]);t.push(n+"\n"+s)}}return t.join("\n").slice(0,-1)}function D(e){const n=[];for(const[o,r]of Object.entries(e)){const e=C[o];if(r.length){const o=`📜 ${e}`,s=r.map((({name:e,path:n,lineNumbers:o})=>t.cyan(` └── ${e}:${o.join(", ")} → ${n}`)));n.push(o+"\n"+s.join("\n"))}}return n.join("\n\n")}function N(e){return e.map((e=>t.cyan(` └── ${e}`))).join("\n")}function L(e){return d([["Script"],e.map((e=>[e]))]).slice(0,-1)}function K(e,t,{format:n}){const o=[T("files",t,e.length)],r={lines:D,table:_},s=function(e){const t={js:[],cjs:[],mjs:[],jsx:[],ts:[],tsx:[],vue:[],svelte:[]};for(const n of e)t[n.name.split(".").pop()].push(n);for(const e of Object.values(t))e.sort(P);return t}(e);return e.length&&o.push(r[n](s)),o.join("\n\n")}(async()=>{const n=u.parseSync(),o=e().start();try{const e=n.package;o.text=t.greenBright("Scanning project directory...");const{silent:s,table:a,precheck:l,include:p}=n;l&&(o.text=t.greenBright("Checking package installation..."),function(e,t){if(!(Object.keys(t.dependencies||{}).includes(e)||Object.keys(t.devDependencies||{}).includes(e)||Object.keys(t.peerDependencies||{}).includes(e)))throw new Error(`Package ${e} is not defined in this project`)}(e,h()),await g(e));const d=function(e,t){const n=c.sync(`{${e.join(",")}}`,{silent:!0}),o=[];for(const e of n)try{const t=r(e),n=i(e,"utf-8");o.push({name:t,path:e,content:n})}catch(n){if(t)continue;throw new Error(`Failed to read ${e}`)}return o}(n.files,s);o.text=t.greenBright("Analyzing project for dependency...");const u=[];if(p.includes("files")){const t=await O(d,e,{silent:s});u.push(K(t,e,{format:a?"table":"lines"}))}if(p.includes("scripts")){const t=F(e);u.push(function(e,t,{format:n}){const o=[T("scripts",t,e.length)],r={lines:N,table:L};return e.length&&o.push(r[n](e)),o.join("\n")}(t,e,{format:a?"table":"lines"}))}o.succeed(t.greenBright("Analysis completed successfully")),console.log(u.join("\n\n"))}catch(e){const n=e;o.fail(t.redBright(n.message)),console.log(t.cyanBright("Terminating..."))}})();
import e from"ora";import t from"chalk";import n from"yargs";import{resolve as o,basename as s}from"path";import{existsSync as r,readFileSync as i}from"fs";import{spawn as a}from"child_process";import c from"glob";import l from"typescript";import{pathToFileURL as d}from"url";import{table as p}from"table";const u=n(process.argv.slice(2)).scriptName("dependent").command("$0 <package> [files...]","Analyze package usage in your project directory.").usage("Usage: $0 <package> [files...]").positional("package",{alias:"p",type:"string",description:"Package name to be analyzed."}).positional("files",{alias:"f",type:"string",description:"Files to be analyzed in glob pattern relative to the current project directory.",default:["!(node_modules)/**/*.js","!(node_modules)/**/*.mjs","!(node_modules)/**/*.ts","!(node_modules)/**/*.jsx","!(node_modules)/**/*.tsx","!(node_modules)/**/*.vue","!(node_modules)/**/*.svelte","!(node_modules)/**/*.astro","*.js","*.mjs","*.ts","*.jsx","*.tsx","*.vue","*.svelte","*.astro"]}).options({silent:{alias:"s",describe:"Skip all unreadable and unparseable files instead of throwing errors",type:"boolean",default:!1,demandOption:!1},table:{alias:"t",describe:"Print the output in table format",type:"boolean",default:!1,demandOption:!1},precheck:{alias:"c",describe:"Check if the package is installed",type:"boolean",default:!0,demandOption:!1},include:{describe:"Type of possible dependant to be scanned for dependency. Defaults to files and scripts",type:"array",default:["scripts","files"],demandOption:!1}});function m(e,t){return new Promise(((n,o)=>{const s=a(e,t);s.stdout.on("data",(e=>n(e))),s.on("error",(()=>o(new Error("Command not found"))))}))}const f={npm:"ls",pnpm:"ls",yarn:"why"};function h(){var e,t,n,s,a,c;const l=o(process.cwd(),"package.json");if(!r(l))throw new Error("The current project directory is not a NodeJS-based project");try{const o=JSON.parse(i(l,"utf-8"));return{name:null!==(e=o.name)&&void 0!==e?e:"",executables:null!==(t=o.bin)&&void 0!==t?t:{},scripts:null!==(n=o.scripts)&&void 0!==n?n:{},dependencies:null!==(s=o.dependencies)&&void 0!==s?s:{},devDependencies:null!==(a=o.devDependencies)&&void 0!==a?a:{},peerDependencies:null!==(c=o.peerDependencies)&&void 0!==c?c:{}}}catch(e){const{message:t}=e;throw new Error(`Failed to read package.json: ${t}`)}}function g(e){var t,n,s,a,c,l;const d=o(process.cwd(),"node_modules",e,"package.json");if(!r(d))throw new Error(`Cannot find metadata for dependency ${e}`);try{const e=JSON.parse(i(d,"utf-8"));return{name:null!==(t=e.name)&&void 0!==t?t:"",executables:null!==(n=e.bin)&&void 0!==n?n:{},scripts:null!==(s=e.scripts)&&void 0!==s?s:{},dependencies:null!==(a=e.dependencies)&&void 0!==a?a:{},devDependencies:null!==(c=e.devDependencies)&&void 0!==c?c:{},peerDependencies:null!==(l=e.peerDependencies)&&void 0!==l?l:{}}}catch(e){const{message:t}=e;throw new Error(`Failed to read package.json: ${t}`)}}async function w(e){let t=function(){const e=o(process.cwd(),"package-lock.json");if(r(e))return"npm";const t=o(process.cwd(),"yarn.lock");return r(t)?"yarn":"pnpm"}();const n=f[t];/^win/.test(process.platform)&&(t=`${t}.cmd`);const s=await m(t,[n,e]);if(!(s.includes(e)&&0!==s.lastIndexOf(e)))throw new Error(`Package ${e} has not been installed in this project`)}function y(e){const t=e.split("/");return e.startsWith("@")?t.slice(0,2).join("/"):t[0]}function v(e){return e.replace(/^([\^~><>=])+/,"")}async function j(e,t){return function(e,t){const n=[],o=s=>{switch(s.kind){case l.SyntaxKind.ImportDeclaration:{const o=s.moduleSpecifier;o.kind===l.SyntaxKind.StringLiteral&&y(o.getText().slice(1,-1))===t&&n.push(e.getLineAndCharacterOfPosition(s.getStart()).line+1);break}case l.SyntaxKind.CallExpression:{const o=s,{expression:r}=o,i=o.arguments,a=r.kind===l.SyntaxKind.ImportKeyword&&1===i.length&&i[0].kind===l.SyntaxKind.StringLiteral&&y(i[0].getText().slice(1,-1))===t,c=r.kind===l.SyntaxKind.Identifier&&"require"===r.getText()&&1===i.length&&i[0].kind===l.SyntaxKind.StringLiteral&&y(i[0].getText().slice(1,-1))===t;(a||c)&&n.push(e.getLineAndCharacterOfPosition(s.getStart()).line+1);break}}l.forEachChild(s,o)};return o(e),n}(l.createSourceFile("",e,l.ScriptTarget.Latest,!0,l.ScriptKind.TSX),t)}let b,S,k,x,$=[];async function _(){try{return(await m(/^win/.test(process.platform)?"npm.cmd":"npm",["root","--global"])).toString().trim()}catch(e){if("Command not found"===e.message)return"";throw e}}async function E(){try{const e=await m(/^win/.test(process.platform)?"yarn.cmd":"yarn",["global","dir"]);return o(e.toString().trim(),"node_modules")}catch(e){if("Command not found"===e.message)return"";throw e}}async function O(){try{return(await m(/^win/.test(process.platform)?"pnpm.cmd":"pnpm",["root","--global"])).toString().trim()}catch(e){if("Command not found"===e.message)return"";throw e}}async function F(){if($.length)return $;const e=await Promise.allSettled([_(),E(),O()]);return $=e.map((e=>"fulfilled"===e.status?e.value:"")).filter(Boolean),$}function P(e,t){const n=[];return S.walk(e,{enter(e){var o,s,r;switch(e.type){case"ImportDeclaration":{const s=e;"Literal"===s.source.type&&y(null===(o=s.source.value)||void 0===o?void 0:o.toString())===t&&n.push(e.loc.start.line);break}case"ImportExpression":{const o=e;"Literal"===o.source.type&&y(null===(s=o.source.value)||void 0===s?void 0:s.toString())===t&&n.push(e.loc.start.line);break}case"CallExpression":{const o=e;"Identifier"===o.callee.type&&"require"===o.callee.name&&"Literal"===o.arguments[0].type&&y(null===(r=o.arguments[0].value)||void 0===r?void 0:r.toString())===t&&n.push(e.loc.start.line);break}}}}),n}function C(){try{const{dependencies:e}=g("astro");return[".pnpm",`@astrojs+compiler@${v(e["@astrojs/compiler"])}`,"node_modules"]}catch(e){return[]}}async function D(e){if(k)return;const t=["@astrojs","compiler","node","index.js"],n=["@astrojs","compiler","dist","node","index.js"],s=C(),r=[o(process.cwd(),"node_modules",...t),o(process.cwd(),"node_modules",...n)];s.length&&r.push(o(process.cwd(),"node_modules",...s,...t),o(process.cwd(),"node_modules",...s,...n));const i=[...r,...e.map((e=>o(e,...t)))].map((e=>import(d(e).toString()))),a=await Promise.allSettled(i);for(let e=0;e<a.length;e++){const t=a[e];if("fulfilled"===t.status)return void(k=t.value)}throw new Error("No Astro parser available")}async function T(e){if(x)return;const t=["@astrojs","compiler","browser","utils.js"],n=["@astrojs","compiler","dist","browser","utils.js"],s=C(),r=[o(process.cwd(),"node_modules",...t),o(process.cwd(),"node_modules",...n)];s.length&&r.push(o(process.cwd(),"node_modules",...s,...t),o(process.cwd(),"node_modules",...s,...n));const i=[...r,...e.map((e=>o(e,...t)))].map((e=>import(d(e).toString()))),a=await Promise.allSettled(i);for(let e=0;e<a.length;e++){const t=a[e];if("fulfilled"===t.status)return void(x=t.value)}throw new Error("Failed to load Astro utility")}const N={js:j,mjs:j,cjs:j,jsx:j,ts:j,vue:async function(e,t){var n;if(!b)throw new Error("Vue compiler has not been loaded yet");const o=b.parse(e),s=null!==(n=o.descriptor.script)&&void 0!==n?n:o.descriptor.scriptSetup;if(s){const e=s.loc.start.line;return(await j(s.content,t)).map((t=>t+e-1))}return[]},svelte:async function(e,t){if(!S)throw new Error("Svelte compiler has not been loaded yet");const n=S.parse(e);return[...P(n.instance,t),...P(n.module,t)]},astro:async function(e,t){if(!k||!x)throw new Error("Astro compiler has not been loaded yet");return async function(e,t){const n=[];return await x.walk(e,(async e=>{if(x.is.frontmatter(e)){const o=await j(e.value,t);n.push(...o)}})),n}((await k.parse(e)).ast,t)}},B={vue:async function(){if(b)return;const e=await F(),t=["@vue","compiler-sfc","dist","compiler-sfc.cjs.js"],n=["vue","compiler-sfc","index.js"],s=function(){try{const{dependencies:e}=g("vue");return[".pnpm",`@vue+compiler-sfc@${v(e["@vue/compiler-sfc"])}`,"node_modules"]}catch(e){return[]}}(),r=[o(process.cwd(),"node_modules",...n)];s.length&&r.push(o(process.cwd(),"node_modules",...s,...t));const i=[...r,o(process.cwd(),"node_modules",...t),...e.map((e=>o(e,...n))),...e.map((e=>o(e,...t)))].map((e=>import(d(e).toString()))),a=await Promise.allSettled(i);for(let e=0;e<a.length;e++){const t=a[e];if("fulfilled"===t.status)return void(b=t.value.default)}throw new Error("No Vue 3 parser available")},svelte:async function(){if(S)return;const e=await F(),t=["svelte","compiler.js"],n=["svelte","src","compiler","index.js"],s=[o(process.cwd(),"node_modules",...n),o(process.cwd(),"node_modules",...t),...e.map((e=>o(e,...n))),...e.map((e=>o(e,...t)))].map((e=>import(d(e).toString()))),r=await Promise.allSettled(s);for(let e=0;e<r.length;e++){const t=r[e];if("fulfilled"===t.status)return void(S=t.value.default)}throw new Error("No Svelte compiler available")},astro:async function(){const e=await F();await Promise.allSettled([D(e),T(e)])}};function L(e){return e.name.split(".").pop()}const A={js:"JavaScript Files",cjs:"CommonJS Files",mjs:"ESModule Files",jsx:"JavaScript Extended Files",ts:"TypeScript Files",tsx:"TypeScript Extended Files",vue:"Vue Single File Component",svelte:"Svelte Single File Component",astro:"Astro Components"};async function K(e,n,{silent:o}){e=e.filter((e=>!e.name.endsWith(".d.ts"))),await async function(e){const t=[...new Set(e.map((e=>L(e))))].map((e=>{try{const t=function(e){return e in B?B[e]:null}(e);return t?t():null}catch(t){throw new Error(`Failed to load compiler for ${A[e]}: ${t.message}`)}})).filter(Boolean);await Promise.all(t)}(e);const s=e.map((async e=>{try{const t=function(e){if(!(e in N))throw new Error(`.${e} files are currently not supported`);return N[e]}(L(e)),o=await t(e.content,n);return o.length?{name:e.name,path:e.path,lineNumbers:o}:null}catch(t){const n=t;throw new Error(`Failed to parse ${e.path}: ${n.message}`)}}));if(!o){return(await Promise.all(s)).filter(Boolean)}const r=await Promise.allSettled(s),i=[];for(const e of r)"rejected"===e.status?console.log(t.yellow(e.reason)):e.value&&i.push(e.value);return i}function I(e,t){const n=e.path.split("/").length,o=t.path.split("/").length;return n>o?1:n<o?-1:e.name>t.name?1:-1}function J(e,n,o){return t.cyanBright(`${{files:"📁",scripts:"📜"}[e]} There are ${o} ${e} in this project that depends on '${n}'`)}function z(e){const t=[];for(const[n,o]of Object.entries(e)){const e=A[n];if(o.length){const n=`📝 ${e}`,s=o.map((e=>[e.name,e.path,e.lineNumbers.join(", ")])),r=p([["Filename","Path","Line Number"],...s]);t.push(n+"\n"+r)}}return t.join("\n").slice(0,-1)}function V(e){const n=[];for(const[o,s]of Object.entries(e)){const e=A[o];if(s.length){const o=`📜 ${e}`,r=s.map((({name:e,path:n,lineNumbers:o})=>t.cyan(` └── ${e}:${o.join(", ")} → ${n}`)));n.push(o+"\n"+r.join("\n"))}}return n.join("\n\n")}function q(e){return e.map((e=>t.cyan(` └── ${e}`))).join("\n")}function W(e){return p([["Script"],e.map((e=>[e]))]).slice(0,-1)}function M(e,t,{format:n}){const o=[J("files",t,e.length)],s={lines:V,table:z},r=function(e){const t={js:[],cjs:[],mjs:[],jsx:[],ts:[],tsx:[],vue:[],svelte:[],astro:[]};for(const n of e)t[n.name.split(".").pop()].push(n);for(const e of Object.values(t))e.sort(I);return t}(e);return e.length&&o.push(s[n](r)),o.join("\n\n")}(async()=>{const n=u.parseSync(),o=e().start();try{const e=n.package;o.text=t.greenBright("Scanning project directory...");const{silent:r,table:a,precheck:l,include:d}=n;l&&(o.text=t.greenBright("Checking package installation..."),function(e,t){if(!(Object.keys(t.dependencies||{}).includes(e)||Object.keys(t.devDependencies||{}).includes(e)||Object.keys(t.peerDependencies||{}).includes(e)))throw new Error(`Package ${e} is not defined in this project`)}(e,h()),await w(e));const p=function(e,t){const n=c.sync(`{${e.join(",")}}`,{silent:!0}),o=[];for(const e of n)try{const t=s(e),n=i(e,"utf-8");o.push({name:t,path:e,content:n})}catch(n){if(t)continue;throw new Error(`Failed to read ${e}`)}return o}(n.files,r);o.text=t.greenBright("Analyzing project for dependency...");const u=[];if(d.includes("files")){const t=await K(p,e,{silent:r});u.push(M(t,e,{format:a?"table":"lines"}))}if(d.includes("scripts")){const t=function(e){const{scripts:t}=h(),{executables:n}=g(e),o=[];if(Object.keys(n).length){const e=`(${Object.keys(n).join("|")})`;for(const[n,s]of Object.entries(t))s.match(e)&&o.push(n)}return o}(e);u.push(function(e,t,{format:n}){const o=[J("scripts",t,e.length)],s={lines:q,table:W};return e.length&&o.push(s[n](e)),o.join("\n")}(t,e,{format:a?"table":"lines"}))}o.succeed(t.greenBright("Analysis completed successfully")),console.log(u.join("\n\n"))}catch(e){const n=e;o.fail(t.redBright(n.message)),console.log(t.cyanBright("Terminating..."))}})();

@@ -0,1 +1,13 @@

# v0.15.0 (Sat Aug 12 2023)
#### 🚀 Enhancement
- feat: add astro support [#62](https://github.com/Namchee/dependent/pull/62) ([@Namchee](https://github.com/Namchee))
#### Authors: 1
- Cristopher ([@Namchee](https://github.com/Namchee))
---
# v0.14.1 (Sun Aug 06 2023)

@@ -2,0 +14,0 @@

{
"name": "@namchee/dependent",
"version": "0.14.1",
"version": "0.15.0",
"description": "Simple utility CLI tool to analyze which files are using a Node dependency 🚀",

@@ -32,2 +32,3 @@ "repository": "git@github.com:Namchee/dependent.git",

"devDependencies": {
"@astrojs/compiler": "^1.6.3",
"@auto-it/conventional-commits": "^10.37.0",

@@ -34,0 +35,0 @@ "@auto-it/npm": "^10.37.0",

@@ -28,3 +28,4 @@ # Dependent

5. Vue Single File Components, `.vue` (`.js` and `.ts` scripts only)
6. Svelte Single File Components, `.svelte` (`.js` script only)
6. Svelte Single File Components, `.svelte`
7. Astro Components, `.astro`

@@ -31,0 +32,0 @@ More language support are incoming! Submit your language support ideas [here](https://github.com/Namchee/dependent/issues/new/choose)

@@ -30,2 +30,3 @@ import yargs from 'yargs';

'!(node_modules)/**/*.svelte',
'!(node_modules)/**/*.astro',
'*.js',

@@ -38,2 +39,3 @@ '*.mjs',

'*.svelte',
'*.astro',
],

@@ -40,0 +42,0 @@ })

@@ -12,4 +12,5 @@ /**

tsx: 'TypeScript Extended Files',
vue: 'Vue\'s Single File Component',
svelte: 'Svelte\'s Single File Component',
vue: 'Vue Single File Component',
svelte: 'Svelte Single File Component',
astro: 'Astro Components'
};
import chalk from 'chalk';
import { getParser } from '@/service/parser';
import { getParser, getCompiler } from '@/service/parser';

@@ -12,3 +12,3 @@ import type {

import { getFileExtension } from '@/utils/file';
import { getGlobalNPMPath, getGlobalYarnPath, getGlobalPnpmPath } from '@/utils/global';
import { FILE_TYPES } from '@/constant/files';

@@ -20,9 +20,6 @@ export async function getDependantFiles(

): Promise<DependantFile[]> {
const managerPaths = await Promise.allSettled([
getGlobalNPMPath(),
getGlobalYarnPath(),
getGlobalPnpmPath(),
]);
// Quickfix, please remove when glob pattern is found
files = files.filter(file => !file.name.endsWith('.d.ts'));
const globs = managerPaths.map(result => result.status === 'fulfilled' ? result.value : '');
await loadCompilers(files);

@@ -35,3 +32,3 @@ const dependants: Promise<DependantFile | null>[] = files.map(

const parse = getParser(ext);
const dependants = await parse(file.content, dependency, globs);
const dependants = await parse(file.content, dependency);

@@ -56,3 +53,3 @@ if (dependants.length) {

const results = await Promise.all(dependants);
return results.filter(val => val !== null) as DependantFile[];
return results.filter(Boolean) as DependantFile[];
}

@@ -75,1 +72,25 @@

}
async function loadCompilers(files: ProjectFile[]) {
const compilers = [
...new Set(
files.map(file => getFileExtension(file))
),
].map((ext: string) => {
try {
const compiler = getCompiler(ext);
if (compiler) {
return compiler();
}
return null;
} catch (err) {
const error = err as Error;
throw new Error(
`Failed to load compiler for ${FILE_TYPES[ext as keyof typeof FILE_TYPES]}: ${error.message}`,
);
}
}).filter(Boolean);
await Promise.all(compilers);
}

@@ -48,2 +48,3 @@ import chalk from 'chalk';

svelte: [],
astro: [],
};

@@ -88,3 +89,3 @@

if (extFiles.length) {
const header = `📜 ${alias}`;
const header = `📝 ${alias}`;

@@ -91,0 +92,0 @@ const entries = extFiles.map(file => ([

@@ -81,3 +81,3 @@ import { resolve } from 'path';

throw new Error(
'The current project directory is not a NodeJS-based project',
`Cannot find metadata for dependency ${dependency}`,
);

@@ -84,0 +84,0 @@ }

@@ -1,6 +0,7 @@

import { FileParser } from '@/types';
import { CompilerLoader, FileParser } from '@/types';
import { getSvelteImportLines } from '@/service/parser/svelte';
import { getTSImportLines } from '@/service/parser/ts';
import { getVueImportLines } from '@/service/parser/vue';
import { getVueImportLines, loadVueCompiler } from '@/service/parser/vue';
import { getSvelteImportLines, loadSvelteCompiler } from '@/service/parser/svelte';
import { getAstroImportLines, loadAstroCompiler } from '@/service/parser/astro';

@@ -19,4 +20,11 @@ /**

svelte: getSvelteImportLines,
astro: getAstroImportLines,
};
const COMPILER_MAP: Record<string, CompilerLoader> = {
vue: loadVueCompiler,
svelte: loadSvelteCompiler,
astro: loadAstroCompiler,
};
/**

@@ -37,1 +45,5 @@ * Get the parser function for a file extension

}
export function getCompiler(ext: string): CompilerLoader | null {
return ext in COMPILER_MAP ? COMPILER_MAP[ext] : null;
}

@@ -1,6 +0,18 @@

import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeAll } from 'vitest';
import { getSvelteImportLines } from '@/service/parser/svelte';
import { getSvelteImportLines, loadSvelteCompiler } from '@/service/parser/svelte';
describe('Svelte parser test', () => {
beforeAll(async () => {
await loadSvelteCompiler();
});
it('should be able to parse empty file', async () => {
const content = ``;
const result = await getSvelteImportLines(content, 'lodash');
expect(result.length).toBe(0);
});
it('should be able to parse ES module import', async () => {

@@ -19,3 +31,3 @@ const content = `<script>

const result = await getSvelteImportLines(content, 'lodash', []);
const result = await getSvelteImportLines(content, 'lodash');

@@ -39,3 +51,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'lodash', []);
const result = await getSvelteImportLines(content, 'lodash');

@@ -59,3 +71,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'lodash', []);
const result = await getSvelteImportLines(content, 'lodash');

@@ -79,3 +91,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'lodash', []);
const result = await getSvelteImportLines(content, 'lodash');

@@ -100,3 +112,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'foo', []);
const result = await getSvelteImportLines(content, 'foo');

@@ -124,3 +136,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'foo', []);
const result = await getSvelteImportLines(content, 'foo');

@@ -145,3 +157,3 @@ expect(result.length).toBe(1);

const result = await getSvelteImportLines(content, 'baz', []);
const result = await getSvelteImportLines(content, 'baz');

@@ -165,3 +177,3 @@ expect(result.length).toBe(0);

const result = await getSvelteImportLines(content, 'bar', []);
const result = await getSvelteImportLines(content, 'bar');

@@ -168,0 +180,0 @@ expect(result.length).toBe(1);

@@ -14,6 +14,7 @@ import { resolve } from 'path';

import { getRootPackage } from '@/utils/package';
import { getGlobs } from '@/utils/global';
let compiler: typeof import('svelte/compiler');
async function loadSvelteCompiler(globs: string[]): Promise<void> {
export async function loadSvelteCompiler(): Promise<void> {
// Do not load the compiler twice

@@ -24,6 +25,12 @@ if (compiler) {

const compilerPath = ['svelte', 'compiler.js'];
const globs = await getGlobs();
const oldCompilerPath = ['svelte', 'compiler.js'];
const newCompilerPath = ['svelte', 'src', 'compiler', 'index.js'];
const paths = [
resolve(process.cwd(), 'node_modules', ...compilerPath),
...globs.map(path => resolve(path, ...compilerPath)),
resolve(process.cwd(), 'node_modules', ...newCompilerPath),
resolve(process.cwd(), 'node_modules', ...oldCompilerPath),
...globs.map(path => resolve(path, ...newCompilerPath)),
...globs.map(path => resolve(path, ...oldCompilerPath)),
];

@@ -56,3 +63,2 @@

export function parseNode(
svelte: typeof compiler,
sourceNode: BaseNode,

@@ -63,3 +69,3 @@ dependency: string,

svelte.walk(sourceNode, {
compiler.walk(sourceNode, {
enter(node) {

@@ -133,6 +139,5 @@ switch (node.type) {

dependency: string,
globs: string[],
): Promise<number[]> {
if (!compiler) {
await loadSvelteCompiler(globs);
throw new Error('Svelte compiler has not been loaded yet');
}

@@ -142,5 +147,5 @@

return [
...parseNode(compiler, node.instance as BaseNode, dependency),
...parseNode(compiler, node.module as BaseNode, dependency),
...parseNode(node.instance as BaseNode, dependency),
...parseNode(node.module as BaseNode, dependency),
];
}

@@ -6,6 +6,14 @@ import { describe, it, expect } from 'vitest';

describe('TypeScript parser test', () => {
it('should be able to parse empty file', async () =>{
const content = ``;
const dependant = await getTSImportLines(content, 'express');
expect(dependant.length).toBe(0);
});
it('should be able to parse ES modules import', async () =>{
const content = `import express from 'express';`;
const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -19,3 +27,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -29,3 +37,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -39,3 +47,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -49,3 +57,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -59,3 +67,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -69,3 +77,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -76,15 +84,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse combined default and named imports', async () =>{
const content = `import defaultExport, { export1 } from 'express';`;
const dependant = await getTSImportLines(content, 'express', []);
expect(dependant.length).toBe(1);
expect(dependant[0]).toBe(1);
});
it('should be able to parse combined default and named imports in separated imports', async () =>{
const content = `import defaultExport from 'express';\nimport { foo } from 'express';`;
const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -98,3 +97,3 @@ expect(dependant.length).toBe(2);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -108,3 +107,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -118,3 +117,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -128,3 +127,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -140,3 +139,3 @@ expect(dependant.length).toBe(1);

const dependant = await getTSImportLines(content, 'express', []);
const dependant = await getTSImportLines(content, 'express');

@@ -154,3 +153,3 @@ expect(dependant.length).toBe(1);

const dependants = await getTSImportLines(content, 'express', []);
const dependants = await getTSImportLines(content, 'express');
expect(dependants.length).toBe(1);

@@ -167,3 +166,3 @@ expect(dependants[0]).toBe(3);

const dependants = await getTSImportLines(content, 'express', []);
const dependants = await getTSImportLines(content, 'express');
expect(dependants.length).toBe(1);

@@ -178,3 +177,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'windicss', []);
const dependants = await getTSImportLines(content, 'windicss');
expect(dependants.length).toBe(1);

@@ -189,3 +188,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'windicss', []);
const dependants = await getTSImportLines(content, 'windicss');
expect(dependants.length).toBe(0);

@@ -210,3 +209,3 @@ });

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -232,3 +231,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(2);

@@ -255,3 +254,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(2);

@@ -271,3 +270,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -286,3 +285,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -301,3 +300,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -322,3 +321,3 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'b', []);
const dependants = await getTSImportLines(content, 'b');
expect(dependants.length).toBe(1);

@@ -343,3 +342,3 @@ expect(dependants[0]).toBe(6);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(0);

@@ -359,3 +358,3 @@ });

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -374,3 +373,3 @@ expect(dependants[0]).toBe(3);

const dependants = await getTSImportLines(content, 'react', []);
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(1);

@@ -385,3 +384,4 @@ expect(dependants[0]).toBe(1);

const dependants = await getTSImportLines(content, 'windicss', []);
const dependants = await getTSImportLines(content, 'windicss');
expect(dependants.length).toBe(1);

@@ -388,0 +388,0 @@ expect(dependants[0]).toBe(1);

@@ -1,4 +0,1 @@

import { resolve } from 'path';
import { pathToFileURL } from 'url';
import { getRootPackage } from '@/utils/package';

@@ -9,32 +6,2 @@

let compiler: typeof import('typescript');
async function loadTSCompiler(globs: string[]): Promise<void> {
// Do not load the compiler twice
if (compiler) {
return;
}
const compilerPath = ['typescript', 'lib', 'typescript.js'];
const paths = [
resolve(process.cwd(), 'node_modules', ...compilerPath),
...globs.map(path => resolve(path, ...compilerPath)),
];
const imports = paths.map(path => import(pathToFileURL(path).toString()));
const compilerImports = await Promise.allSettled(imports);
for (let i = 0; i < compilerImports.length; i++) {
const fileModule = compilerImports[i];
if (fileModule.status === 'fulfilled') {
compiler = fileModule.value.default as typeof import('typescript');
return;
}
}
throw new Error('No TypeScript parsers available');
}
/**

@@ -102,3 +69,3 @@ * Parse TypeScript node for imports to `dependency`

compiler.forEachChild(node, walk);
ts.forEachChild(node, walk);
}

@@ -122,14 +89,9 @@

dependency: string,
globs: string[],
): Promise<number[]> {
if (!compiler) {
await loadTSCompiler(globs);
}
const node = compiler.createSourceFile(
const node = ts.createSourceFile(
'',
content,
compiler.ScriptTarget.Latest,
ts.ScriptTarget.Latest,
true,
compiler.ScriptKind.TSX,
ts.ScriptKind.TSX,
);

@@ -136,0 +98,0 @@

@@ -1,6 +0,37 @@

import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeEach, vi, afterEach, beforeAll } from 'vitest';
import { getVueImportLines } from '@/service/parser/vue';
import { getVueImportLines, loadVueCompiler } from '@/service/parser/vue';
import * as pkgUtils from '@/service/package';
describe('Vue parser test', () => {
beforeAll(async () => {
await loadVueCompiler();
});
beforeEach(() => {
vi.spyOn(pkgUtils, 'resolveDependencyPackageJSON').mockImplementation(() => ({
name: 'vue',
executables: {},
scripts: {},
dependencies: {
'@vue/compiler-sfc': '^3.3.4',
},
devDependencies: {},
peerDependencies: {},
}));
});
afterEach(() => {
vi.restoreAllMocks();
});
it('should be able to parse empty files', async () => {
const content = ``;
const result = await getVueImportLines(content, 'vue');
expect(result.length).toBe(0);
});
it('should be able to parse ES module import', async () => {

@@ -25,3 +56,3 @@ const content = `<script>

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -51,3 +82,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -77,3 +108,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -103,3 +134,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -130,3 +161,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'foo', []);
const result = await getVueImportLines(content, 'foo');

@@ -160,3 +191,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'baz', []);
const result = await getVueImportLines(content, 'baz');

@@ -187,3 +218,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'baz', []);
const result = await getVueImportLines(content, 'baz');

@@ -212,3 +243,3 @@ expect(result.length).toBe(0);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -238,3 +269,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -265,3 +296,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue', []);
const result = await getVueImportLines(content, 'vue');

@@ -284,3 +315,3 @@ expect(result.length).toBe(2);

const result = await getVueImportLines(content, 'lodash', []);
const result = await getVueImportLines(content, 'lodash');

@@ -316,3 +347,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'lodash', []);
const result = await getVueImportLines(content, 'lodash');

@@ -352,3 +383,3 @@ expect(result.length).toBe(1);

const result = await getVueImportLines(content, 'vue-class-component', []);
const result = await getVueImportLines(content, 'vue-class-component');

@@ -355,0 +386,0 @@ expect(result.length).toBe(1);

@@ -6,5 +6,25 @@ import { resolve } from 'path';

import { getActualVersion } from '@/utils/package';
import { getGlobs } from '@/utils/global';
import { resolveDependencyPackageJSON } from '@/service/package';
let compiler: typeof import('@vue/compiler-sfc');
export async function loadVueCompiler(globs: string[]): Promise<void> {
function getPnpmCompilerPath(): string[] {
try {
const { dependencies } = resolveDependencyPackageJSON('vue');
const compilerVersion = dependencies['@vue/compiler-sfc'];
return [
'.pnpm',
`@vue+compiler-sfc@${getActualVersion(compilerVersion)}`,
'node_modules',
]
} catch (err) {
return [];
}
}
export async function loadVueCompiler(): Promise<void> {
// Do not load the compiler twice

@@ -15,3 +35,5 @@ if (compiler) {

const oldCompilerPath = [
const globs = await getGlobs();
const flatCompilerPath = [
'@vue',

@@ -30,6 +52,16 @@ 'compiler-sfc',

const pnpmCompilerPath = getPnpmCompilerPath();
const nonGlobs = [resolve(process.cwd(), 'node_modules', ...newCompilerPath)];
if (pnpmCompilerPath.length) {
nonGlobs.push(
resolve(process.cwd(), 'node_modules', ...pnpmCompilerPath, ...flatCompilerPath)
)
}
const paths = [
resolve(process.cwd(), 'node_modules', ...newCompilerPath),
resolve(process.cwd(), 'node_modules', ...oldCompilerPath),
...globs.map(path => resolve(path, ...oldCompilerPath)),
...nonGlobs,
resolve(process.cwd(), 'node_modules', ...flatCompilerPath),
...globs.map(path => resolve(path, ...newCompilerPath)),
...globs.map(path => resolve(path, ...flatCompilerPath)),
];

@@ -63,6 +95,5 @@

dependency: string,
globs: string[],
): Promise<number[]> {
if (!compiler) {
await loadVueCompiler(globs);
throw new Error('Vue compiler has not been loaded yet');
}

@@ -76,4 +107,4 @@

const lines = await getTSImportLines(script.content, dependency, globs);
// -1, since the `<script>` block shouldn't count
const lines = await getTSImportLines(script.content, dependency);
return lines.map(line => line + startingLine - 1);

@@ -80,0 +111,0 @@ }

@@ -50,7 +50,8 @@ /**

dependency: string,
globs: string[],
) => Promise<number[]>;
export type CompilerLoader = () => Promise<void>;
export interface LoggerConfig {
format: 'lines' | 'table';
}

@@ -5,2 +5,4 @@ import { resolve } from 'path';

let globs: string[] = [];
/**

@@ -11,3 +13,3 @@ * Get the current npm global installation path

*/
export async function getGlobalNPMPath(): Promise<string> {
async function getGlobalNPMPath(): Promise<string> {
try {

@@ -36,3 +38,3 @@ const path = await executeCommand(

*/
export async function getGlobalYarnPath(): Promise<string> {
async function getGlobalYarnPath(): Promise<string> {
try {

@@ -61,3 +63,3 @@ const path = await executeCommand(

*/
export async function getGlobalPnpmPath(): Promise<string> {
async function getGlobalPnpmPath(): Promise<string> {
try {

@@ -80,1 +82,19 @@ const path = await executeCommand(

}
export async function getGlobs(): Promise<string[]> {
if (globs.length) {
return globs;
}
const managerPaths = await Promise.allSettled([
getGlobalNPMPath(),
getGlobalYarnPath(),
getGlobalPnpmPath(),
]);
globs = managerPaths
.map(result => result.status === 'fulfilled' ? result.value : '')
.filter(Boolean);
return globs;
}
import { describe, expect, it } from 'vitest';
import { getRootPackage } from './package';
import { getActualVersion, getRootPackage } from './package';

@@ -33,1 +33,38 @@ describe('getRootPackage', () => {

});
describe('getInstalledVersion', () => {
it('should replace nothing', () => {
const version = '1.6.3';
const result = getActualVersion(version);
expect(result).toBe('1.6.3');
});
it('should replace ^', () => {
const version = '^1.6.3';
const result = getActualVersion(version);
expect(result).toBe('1.6.3');
});
it('should replace ~', () => {
const version = '~1.6.3';
const result = getActualVersion(version);
expect(result).toBe('1.6.3');
});
it('should replace <', () => {
const version = '<1.6.3';
const result = getActualVersion(version);
expect(result).toBe('1.6.3');
});
it('should replace <> with =', () => {
const version = '>=1.6.3';
const result = getActualVersion(version);
expect(result).toBe('1.6.3');
});
})

@@ -17,1 +17,5 @@ /**

}
export function getActualVersion(semver: string): string {
return semver.replace(/^([\^~><>=])+/, '');
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc