Socket
Socket
Sign inDemoInstall

@namchee/dependent

Package Overview
Dependencies
8
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.1 to 0.9.0

__tests__/parser/svelte.test.ts

94

__tests__/parser/js.test.ts

@@ -12,6 +12,6 @@ import { jest } from '@jest/globals';

describe('ESModule import test', () => {
it('should be able to parse default imports', () => {
it('should be able to parse default imports', async () => {
const content = 'import express from \'express\'; const app = express();';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse named imports', () => {
it('should be able to parse named imports', async () => {
const content = 'import { json } from \'express\'; app.use(json());';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse aliased imports', () => {
it('should be able to parse aliased imports', async () => {
const content = 'import { json as jeson } from \'express\';';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse side-effect imports', () => {
it('should be able to parse side-effect imports', async () => {
const content = 'import \'express\';';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse all-module import', () => {
it('should be able to parse all-module import', async () => {
const content = 'import * as express from \'express\';';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse dynamic imports', () => {
it('should be able to parse dynamic imports', async () => {
const content = 'const a = import(\'express\');';
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to parse module imports nested in code', () => {
it('should be able to parse module imports nested in code', async () => {
const content = `(async () => {

@@ -74,3 +74,3 @@ if (somethingIsTrue) {

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

@@ -80,10 +80,10 @@ expect(dependants[0]).toBe(3);

it('should be able to parse false alarms', () => {
it('should be able to parse false alarms', async () => {
const content = `const a = "import express from 'express'";`;
const dependants = getJSImportLines(content, 'express');
const dependants = await getJSImportLines(content, 'express');
expect(dependants.length).toBe(0);
});
it('should be able to parse shebanged files', () => {
it('should be able to parse shebanged files', async () => {
const content = `#!/usr/bin/env node

@@ -95,3 +95,3 @@

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

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

it('should be able to tolerate CommonJS imports', () => {
it('should be able to tolerate CommonJS imports', async () => {
const content = `const express = require('express');

@@ -107,3 +107,3 @@

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

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

it('should be able to detect nested modules', () => {
it('should be able to detect nested modules', async () => {
const content = `import { defineConfig } from 'windicss/helpers';

@@ -119,3 +119,3 @@

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

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

it('should be able to distinguish dash separated modules', () => {
it('should be able to distinguish dash separated modules', async () => {
const content = `import { defineConfig } from 'windicss-helpers';

@@ -131,3 +131,3 @@

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

@@ -138,3 +138,3 @@ });

describe('React JSX test', () => {
it('should be able to parse default imports', () => {
it('should be able to parse default imports', async () => {
const content = `import react from 'react';

@@ -148,3 +148,3 @@

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

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

it('should be able to parse default imports', () => {
it('should be able to parse default imports', async () => {
const content = `import { useState } from 'react';

@@ -165,3 +165,3 @@

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

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

it('should be able to parse aliased imports', () => {
it('should be able to parse aliased imports', async () => {
const content = `import { useState as a } from 'react';

@@ -182,3 +182,3 @@

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

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

it('should be able to parse namespace imports', () => {
it('should be able to parse namespace imports', async () => {
const content = `import * as React from 'react';

@@ -198,3 +198,3 @@

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

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

it('should be able to parse side-effect imports', () => {
it('should be able to parse side-effect imports', async () => {
const content = `import 'react';

@@ -214,3 +214,3 @@

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

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

it('should be able to parse dynamic imports', () => {
it('should be able to parse dynamic imports', async () => {
const content = `const a = import('react');

@@ -230,3 +230,3 @@

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

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

it('should be able to parse imports nested in code', () => {
it('should be able to parse imports nested in code', async () => {
const content = `import * as React from 'react';

@@ -252,3 +252,3 @@

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

@@ -258,7 +258,7 @@ expect(dependants[0]).toBe(6);

it('should be able to distinguish false alarms', () => {
it('should be able to distinguish false alarms', async () => {
const content = `const react = "import * as React from 'react';";
function Home() {
const isTest = () => {
const isTest = async () => {
if (isDevelopment) {

@@ -274,7 +274,7 @@ const a = require('b');

const dependants = getJSImportLines(content, 'react');
const dependants = await getJSImportLines(content, 'react');
expect(dependants.length).toBe(0);
});
it('should be able to tolerate CommonJS imports', () => {
it('should be able to tolerate CommonJS imports', async () => {
const content = `import express from 'express';

@@ -290,3 +290,3 @@

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

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

it('should be able to parse class-based components', () => {
it('should be able to parse class-based components', async () => {
const content = `import * as React from 'react';

@@ -306,3 +306,3 @@

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

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

it('should be able to detect nested modules', () => {
it('should be able to detect nested modules', async () => {
const content = `import { defineConfig } from 'windicss/helpers';

@@ -318,3 +318,3 @@

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

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

@@ -7,11 +7,11 @@ import { jest } from '@jest/globals';

afterEach(() => {
afterEach(() =>{
jest.clearAllTimers();
});
describe('TypeScript parser test', () => {
it('should be able to parse ES modules import', () => {
describe('TypeScript parser test', () =>{
it('should be able to parse ES modules import', async () =>{
const content = `import express from 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -22,6 +22,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse all modules import', () => {
it('should be able to parse all modules import', async () =>{
const content = `import * as express from 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -32,6 +32,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse named imports', () => {
it('should be able to parse named imports', async () =>{
const content = `import { json } from 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -42,6 +42,6 @@ expect(dependant.length).toBe(1);

it('should be able to aliased imports', () => {
it('should be able to aliased imports', async () =>{
const content = `import { json as jeson } from 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -52,6 +52,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse side-effect imports', () => {
it('should be able to parse side-effect imports', async () =>{
const content = `import 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -62,6 +62,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse type import', () => {
it('should be able to parse type import', async () =>{
const content = `import type { Application } from 'express';`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -72,6 +72,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse dynamic imports', () => {
it('should be able to parse dynamic imports', async () =>{
const content = `const a = import('express');`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

@@ -82,6 +82,6 @@ expect(dependant.length).toBe(1);

it('should be able to parse CommonJS imports', () => {
it('should be able to parse CommonJS imports', async () =>{
const content = `const a = require('express');`;
const dependant = getTSImportLines(content, 'express');
const dependant = await getTSImportLines(content, 'express');

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

it('should be able to parse shebanged files', () => {
it('should be able to parse shebanged files', async () =>{
const content = `#!/usr/bin/env node

@@ -98,3 +98,3 @@

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

@@ -105,4 +105,4 @@ expect(dependant.length).toBe(1);

it('should be able to parse module imports nested in code', () => {
const content = `(async () => {
it('should be able to parse module imports nested in code', async () =>{
const content = `(async () =>{
if (somethingIsTrue) {

@@ -113,3 +113,3 @@ await import('express');

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

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

it('should be able to parse actual TypeScript code', () => {
it('should be able to parse actual TypeScript code', async () =>{
const content = `import express from 'express';

@@ -125,5 +125,5 @@

app.lister(3000, () => console.log('hello world'))`;
app.lister(3000, async () =>console.log('hello world'))`;
const dependants = getTSImportLines(content, 'express');
const dependants = await getTSImportLines(content, 'express');
expect(dependants.length).toBe(1);

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

it('should be able to detect nested modules', () => {
it('should be able to detect nested modules', async () =>{
const content = `import { defineConfig } from 'windicss/helpers';

@@ -139,3 +139,3 @@

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

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

it('should be able to distinguish dash separated modules', () => {
it('should be able to distinguish dash separated modules', async () =>{
const content = `import { defineConfig } from 'windicss-helpers';

@@ -151,3 +151,3 @@

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

@@ -157,4 +157,4 @@ });

describe('React TSX test', () => {
it('should be able to parse default imports', () => {
describe('React TSX test', () =>{
it('should be able to parse default imports', async () =>{
const content = `import React from 'react';

@@ -173,3 +173,3 @@

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

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

it('should be able to parse default imports', () => {
it('should be able to parse default imports', async () =>{
const content = `import * as React from 'react';

@@ -196,3 +196,3 @@ import { useState } from 'react';

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

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

it('should be able to parse aliased imports', () => {
it('should be able to parse aliased imports', async () =>{
const content = `import * as React from 'react';

@@ -220,3 +220,3 @@ import { useState as a } from 'react';

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

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

it('should be able to parse namespace imports', () => {
it('should be able to parse namespace imports', async () =>{
const content = `import * as React from 'react';

@@ -237,3 +237,3 @@

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

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

it('should be able to parse side-effect imports', () => {
it('should be able to parse side-effect imports', async () =>{
const content = `import 'react';

@@ -253,3 +253,3 @@

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

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

it('should be able to parse dynamic imports', () => {
it('should be able to parse dynamic imports', async () =>{
const content = `const a = import('react');

@@ -269,3 +269,3 @@

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

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

it('should be able to parse imports nested in code', () => {
it('should be able to parse imports nested in code', async () =>{
const content = `import * as React from 'react';
function Home(): JSX.Element {
const isTest = () => {
const isTest = () =>{
if (isDevelopment) {

@@ -291,3 +291,3 @@ const a = require('b');

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

@@ -297,7 +297,7 @@ expect(dependants[0]).toBe(6);

it('should be able to distinguish false alarms', () => {
it('should be able to distinguish false alarms', async () =>{
const content = `const react = "import * as React from 'react';";
function Home(): JSX.Element {
const isTest = () => {
const isTest = async () =>{
if (isDevelopment) {

@@ -313,7 +313,7 @@ const a = require('b');

const dependants = getTSImportLines(content, 'react');
const dependants = await getTSImportLines(content, 'react');
expect(dependants.length).toBe(0);
});
it('should be able to tolerate CommonJS imports', () => {
it('should be able to tolerate CommonJS imports', async () =>{
const content = `import express from 'express';

@@ -329,3 +329,3 @@

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

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

it('should be able to parse class-based components', () => {
it('should be able to parse class-based components', async () =>{
const content = `import * as React from 'react';

@@ -345,3 +345,3 @@

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

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

it('should be able to detect nested modules', () => {
it('should be able to detect nested modules', async () =>{
const content = `import { defineConfig } from 'windicss/helpers';

@@ -357,3 +357,3 @@

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

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

@@ -12,3 +12,3 @@ import { jest } from '@jest/globals';

describe('Vue parser test', () => {
it('should be able to parse ES module import', () => {
it('should be able to parse ES module import', async () => {
const content = `<script>

@@ -32,3 +32,3 @@ import Vue from 'vue';

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

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

it('should be able to parse named imports', () => {
it('should be able to parse named imports', async () => {
const content = `<script>

@@ -59,3 +59,3 @@ import { ref } from 'vue';

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

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

it('should be able to parse all module import', () => {
it('should be able to parse all module import', async () => {
const content = `<script>

@@ -86,3 +86,3 @@ import * as Vue from 'vue';

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

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

it('should be able to parse aliased imports', () => {
it('should be able to parse aliased imports', async () => {
const content = `<script>

@@ -113,3 +113,3 @@ import { ref as foo } from 'vue';

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

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

it('should be able to parse side-effect imports', () => {
it('should be able to parse side-effect imports', async () => {
const content = `<script>

@@ -141,3 +141,3 @@ import { ref } from 'vue';

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

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

it('should be able to parse dynamic imports', () => {
it('should be able to parse dynamic imports', async () => {
const content = `<script>

@@ -172,3 +172,3 @@ import { ref } from 'vue';

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

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

it('should be able to distinguish false alarms', () => {
it('should be able to distinguish false alarms', async () => {
const content = `<script>

@@ -200,3 +200,3 @@ import { ref } from 'vue';

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

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

it('should be able to tolerate CommonJS import', () => {
it('should be able to tolerate CommonJS import', async () => {
const content = `<script>

@@ -226,3 +226,3 @@ const vue = require('vue');

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

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

it('should be able to parse TypeScript based script', () => {
it('should be able to parse TypeScript based script', async () => {
const content = `<script lang="ts">

@@ -253,3 +253,3 @@ import { ref, Ref } from 'vue';

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

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

it('should be able to parse TypeScript type imports', () => {
it('should be able to parse TypeScript type imports', async () => {
const content = `<script lang="ts">

@@ -281,3 +281,3 @@ import { ref } from 'vue';

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

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

it('should be able to parse `script setup`', () => {
it('should be able to parse `script setup`', async () => {
const content = `<script setup>

@@ -301,3 +301,3 @@ import _ from 'lodash';

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

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

it('should be able to parse Options API', () => {
it('should be able to parse Options API', async () => {
const content = `<script>

@@ -320,3 +320,3 @@ import _ from 'lodash';

computed: {
formattedName: () => {
formattedName: async () => {
return _.capitalize(this.name);

@@ -335,3 +335,3 @@ },

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

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

it('should be able to parse class components', () => {
it('should be able to parse class components', async () => {
// straightly copy pasted from class component example

@@ -372,3 +372,3 @@ const content = `<template>

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

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

@@ -22,8 +22,8 @@ import { jest } from '@jest/globals';

expect(() => getDependantFiles(files, 'express', {
expect(getDependantFiles(files, 'express', {
silent: false,
})).toThrowError('Failed to parse src/a.js');
})).rejects.toBeTruthy();
});
it('should not throw an error when silent is true', () => {
it('should not throw an error when silent is true', async () => {
const files: ProjectFile[] = [

@@ -37,3 +37,3 @@ {

const dependants = getDependantFiles(files, 'express', {
const dependants = await getDependantFiles(files, 'express', {
silent: true,

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

#!/usr/bin/env node
import e from"ora";import t from"chalk";import n from"yargs";import r,{resolve as o,basename as i}from"path";import{existsSync as s,readFileSync as a}from"fs";import{spawn as c}from"child_process";import l from"glob";import{Parser as p}from"acorn";import{simple as d,base as u}from"acorn-walk";import m from"acorn-jsx";import g from"global-dirs";const f=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","*.js","*.mjs","*.ts","*.jsx","*.tsx","*.vue"]}).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}});const h=p.extend(m());function y(e,t){return function(e,t){const n=[];return d(e,{ImportExpression(e){var r;const o=e;"Literal"===o.source.type&&(null===(r=o.source.value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)},ImportDeclaration(e){var r;const o=e;"Literal"===o.source.type&&(null===(r=o.source.value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)},CallExpression(e){var r;const o=e;"Identifier"===o.callee.type&&"require"===o.callee.name&&"Literal"===o.arguments[0].type&&(null===(r=o.arguments[0].value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)}},Object.assign(Object.assign({},u),{JSXElement:()=>{}})),n}(h.parse(e,{ecmaVersion:"latest",locations:!0,allowHashBang:!0,sourceType:"module"}),t)}let v,w;try{const e=["typescript","lib","typescript.js"],t=new URL(r.posix.resolve("node_modules",...e),import.meta.url),n=new URL(r.posix.resolve(g.npm.packages,...e),import.meta.url),o=new URL(r.posix.resolve(g.yarn.packages,...e),import.meta.url),i=await Promise.allSettled([import(t.toString()),import(n.toString()),import(o.toString())]);for(const e of i)if("fulfilled"===e.status){v=e.value.default;break}}catch(e){}function j(e,t){if(!v)throw new Error("No Typescript parsers available");return function(e,t){const n=[],r=o=>{switch(o.kind){case v.SyntaxKind.ImportDeclaration:{const r=o.moduleSpecifier;10===r.kind&&r.getText().slice(1,-1).split("/")[0]===t&&n.push(e.getLineAndCharacterOfPosition(o.getStart()).line+1);break}case v.SyntaxKind.CallExpression:{const r=o,i=r.expression,s=r.arguments,a=i.kind===v.SyntaxKind.ImportKeyword&&1===s.length&&s[0].kind===v.SyntaxKind.StringLiteral&&s[0].getText().slice(1,-1).split("/")[0]===t,c=i.kind===v.SyntaxKind.Identifier&&"require"===i.getText()&&1===s.length&&s[0].kind===v.SyntaxKind.StringLiteral&&s[0].getText().slice(1,-1).split("/")[0]===t;(a||c)&&n.push(e.getLineAndCharacterOfPosition(o.getStart()).line+1);break}}v.forEachChild(o,r)};return r(e),n}(v.createSourceFile("",e,v.ScriptTarget.Latest,!0,v.ScriptKind.TSX),t)}try{const e=["@vue","compiler-sfc","dist","compiler-sfc.cjs.js"],t=new URL(r.posix.resolve("node_modules",...e),import.meta.url),n=new URL(r.posix.resolve(g.npm.packages,...e),import.meta.url),o=new URL(r.posix.resolve(g.yarn.packages,...e),import.meta.url),i=await Promise.allSettled([import(t.toString()),import(n.toString()),import(o.toString())]);for(const e of i){if("fulfilled"===e.status){w=e.value.default;break}console.log(e.reason)}}catch(e){}const k={js:y,ts:j,jsx:y,tsx:j,vue:function(e,t){var n;if(!w)throw new Error("No Vue parsers available");const r=w.parse(e),o=null!==(n=r.descriptor.script)&&void 0!==n?n:r.descriptor.scriptSetup;if(o){const e=o.loc.start.line;return S(o.lang||"js")(o.content,t).map((t=>t+e-1))}return[]}};function S(e){if(!(e in k))throw new Error(`.${e} files are currently not supported`);return k[e]}function b(e,n,r){console.log("\n"+t.cyanBright(`📦 There are ${e.length} files in this project that depends on '${n}'`)),e.length&&(r?function(e){const t=e.map((e=>({"File name":e.name,"File path":e.path,"Line number":e.lineNumbers.join(", ")})));console.table(t)}(e):function(e){e.forEach((({name:e,path:n,lineNumbers:r})=>{console.log(t.cyan(` └── ${e}:${r.join(", ")} → ${n}`))}))}(e))}(async()=>{const n=f.parseSync(),r=e().start();try{const e=n.package;r.text=t.greenBright("Scanning project directory...");const p=function(){const e=o(process.cwd(),"package.json");if(!s(e))throw new Error("The current project directory is not a NodeJS-based project");try{const t=JSON.parse(a(e,"utf-8"));return{name:t.name,dependencies:t.dependencies,devDependencies:t.devDependencies,peerDependencies:t.peerDependencies}}catch(e){throw new Error("Invalid package.json schema")}}(),d=n.silent,u=n.table;r.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,p),await function(e){return new Promise(((t,n)=>{c(/^win/.test(process.platform)?"npm.cmd":"npm",["ls",e]).stdout.on("data",(r=>{r.includes(e)&&0!==r.lastIndexOf(e)?t():n(new Error(`Package ${e} is not installed in this project`))}))}))}(e);const m=function(e,t){const n=l.sync(`{${e.join(",")}}`,{silent:!0}),r=[];for(const e of n)try{const t=i(e),n=a(e,"utf-8");r.push({name:t,path:e,content:n})}catch(n){if(t)continue;throw new Error(`Failed to read ${e}`)}return r}(n.files,d);r.text=t.greenBright("Analyzing package dependency...");const g=function(e,t,{silent:n}){const r=[];for(const o of e){let e=o.name.split(".").pop();"mjs"===e&&(e="js");try{const n=S(e)(o.content,t);n.length&&r.push({name:o.name,path:o.path,lineNumbers:n})}catch(e){const t=e;if(n)continue;throw new Error(`Failed to parse ${o.path}: ${t.message}`)}}return r}(m,e,{silent:d});r.succeed(t.greenBright("Analysis completed successfully")),b(g,e,u)}catch(e){const n=e;r.fail(t.redBright(n.message)),console.log(t.cyanBright("Terminating..."))}})();
import e from"ora";import t from"chalk";import n from"yargs";import r,{resolve as o,basename as s}from"path";import{existsSync as i,readFileSync as a}from"fs";import{spawn as l}from"child_process";import c from"glob";import{Parser as p}from"acorn";import{simple as u,base as d}from"acorn-walk";import m from"acorn-jsx";import g from"global-dirs";const f=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}});const h=p.extend(m());async function y(e,t){return function(e,t){const n=[];return u(e,{ImportExpression(e){var r;const o=e;"Literal"===o.source.type&&(null===(r=o.source.value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)},ImportDeclaration(e){var r;const o=e;"Literal"===o.source.type&&(null===(r=o.source.value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)},CallExpression(e){var r;const o=e;"Identifier"===o.callee.type&&"require"===o.callee.name&&"Literal"===o.arguments[0].type&&(null===(r=o.arguments[0].value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line)}},Object.assign(Object.assign({},d),{JSXElement:()=>{}})),n}(h.parse(e,{ecmaVersion:"latest",locations:!0,allowHashBang:!0,sourceType:"module"}),t)}let v,w,S;try{const e=["svelte","compiler.js"],t=new URL(r.posix.resolve("node_modules",...e),import.meta.url),n=new URL(r.posix.resolve(g.npm.packages,...e),import.meta.url),o=new URL(r.posix.resolve(g.yarn.packages,...e),import.meta.url),s=await Promise.allSettled([import(t.toString()),import(n.toString()),import(o.toString())]);for(let e=0;e<s.length;e++){const t=s[e];if("fulfilled"===t.status){v=t.value.default;break}}}catch(e){}function k(e,t){const n=[];return v.walk(e,{enter(e){var r,o,s;switch(e.type){case"ImportDeclaration":{const o=e;"Literal"===o.source.type&&(null===(r=o.source.value)||void 0===r?void 0:r.toString().split("/")[0])===t&&n.push(e.loc.start.line);break}case"ImportExpression":{const r=e;"Literal"===r.source.type&&(null===(o=r.source.value)||void 0===o?void 0:o.toString().split("/")[0])===t&&n.push(e.loc.start.line);break}case"CallExpression":{const r=e;"Identifier"===r.callee.type&&"require"===r.callee.name&&"Literal"===r.arguments[0].type&&(null===(s=r.arguments[0].value)||void 0===s?void 0:s.toString().split("/")[0])===t&&n.push(e.loc.start.line);break}}}}),n}try{const e=["typescript","lib","typescript.js"],t=new URL(r.posix.resolve("node_modules",...e),import.meta.url),n=new URL(r.posix.resolve(g.npm.packages,...e),import.meta.url),o=new URL(r.posix.resolve(g.yarn.packages,...e),import.meta.url),s=await Promise.allSettled([import(t.toString()),import(n.toString()),import(o.toString())]);for(let e=0;e<s.length;e++){const t=s[e];if("fulfilled"===t.status){w=t.value.default;break}}}catch(e){}async function b(e,t){if(!w)throw new Error("No Typescript parsers available");return function(e,t){const n=[],r=o=>{switch(o.kind){case w.SyntaxKind.ImportDeclaration:{const r=o.moduleSpecifier;10===r.kind&&r.getText().slice(1,-1).split("/")[0]===t&&n.push(e.getLineAndCharacterOfPosition(o.getStart()).line+1);break}case w.SyntaxKind.CallExpression:{const r=o,s=r.expression,i=r.arguments,a=s.kind===w.SyntaxKind.ImportKeyword&&1===i.length&&i[0].kind===w.SyntaxKind.StringLiteral&&i[0].getText().slice(1,-1).split("/")[0]===t,l=s.kind===w.SyntaxKind.Identifier&&"require"===s.getText()&&1===i.length&&i[0].kind===w.SyntaxKind.StringLiteral&&i[0].getText().slice(1,-1).split("/")[0]===t;(a||l)&&n.push(e.getLineAndCharacterOfPosition(o.getStart()).line+1);break}}w.forEachChild(o,r)};return r(e),n}(w.createSourceFile("",e,w.ScriptTarget.Latest,!0,w.ScriptKind.TSX),t)}try{const e=["@vue","compiler-sfc","dist","compiler-sfc.cjs.js"],t=new URL(r.posix.resolve("node_modules",...e),import.meta.url),n=new URL(r.posix.resolve(g.npm.packages,...e),import.meta.url),o=new URL(r.posix.resolve(g.yarn.packages,...e),import.meta.url),s=await Promise.allSettled([import(t.toString()),import(n.toString()),import(o.toString())]);for(let e=0;e<s.length;e++){const t=s[e];if("fulfilled"===t.status){S=t.value.default;break}}}catch(e){}const x={js:y,ts:b,jsx:y,tsx:b,vue:async function(e,t){var n;if(!S)throw new Error("No Vue parsers available");const r=S.parse(e),o=null!==(n=r.descriptor.script)&&void 0!==n?n:r.descriptor.scriptSetup;if(o){const e=o.loc.start.line;if("vue"===o.lang)throw new Error("Circular parser dependency");const n=j(o.lang||"js");return(await n(o.content,t)).map((t=>t+e-1))}return[]},svelte:async function(e,t){if(!v)throw new Error("No Svelte parsers available");const n=v.parse(e);return[...k(n.instance,t),...k(n.module,t)]}};function j(e){if(!(e in x))throw new Error(`.${e} files are currently not supported`);return x[e]}function L(e,n,r){console.log("\n"+t.cyanBright(`📦 There are ${e.length} files in this project that depends on '${n}'`)),e.length&&(r?function(e){const t=e.map((e=>({"File name":e.name,"File path":e.path,"Line number":e.lineNumbers.join(", ")})));console.table(t)}(e):function(e){e.forEach((({name:e,path:n,lineNumbers:r})=>{console.log(t.cyan(` └── ${e}:${r.join(", ")} → ${n}`))}))}(e))}(async()=>{const n=f.parseSync(),r=e().start();try{const e=n.package;r.text=t.greenBright("Scanning project directory...");const p=function(){const e=o(process.cwd(),"package.json");if(!i(e))throw new Error("The current project directory is not a NodeJS-based project");try{const t=JSON.parse(a(e,"utf-8"));return{name:t.name,dependencies:t.dependencies,devDependencies:t.devDependencies,peerDependencies:t.peerDependencies}}catch(e){throw new Error("Invalid package.json schema")}}(),u=n.silent,d=n.table;r.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,p),await function(e){return new Promise(((t,n)=>{l(/^win/.test(process.platform)?"npm.cmd":"npm",["ls",e]).stdout.on("data",(r=>{r.includes(e)&&0!==r.lastIndexOf(e)?t():n(new Error(`Package ${e} is not installed in this project`))}))}))}(e);const m=function(e,t){const n=c.sync(`{${e.join(",")}}`,{silent:!0}),r=[];for(const e of n)try{const t=s(e),n=a(e,"utf-8");r.push({name:t,path:e,content:n})}catch(n){if(t)continue;throw new Error(`Failed to read ${e}`)}return r}(n.files,u);r.text=t.greenBright("Analyzing package dependency...");const g=await async function(e,n,{silent:r}){const o=e.map((async e=>{try{let t=e.name.split(".").pop();"mjs"===t&&(t="js");const r=j(t),o=await r(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(r){const e=await Promise.allSettled(o),n=[];for(const r of e)"rejected"===r.status?console.log(t.yellow(r.reason)):r.value&&n.push(r.value);return n}return(await Promise.all(o)).filter((e=>null!==e))}(m,e,{silent:u});r.succeed(t.greenBright("Analysis completed successfully")),L(g,e,d)}catch(e){const n=e;r.fail(t.redBright(n.message)),console.log(t.cyanBright("Terminating..."))}})();

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

# v0.9.0 (Wed Sep 01 2021)
#### 🚀 Enhancement
- feat: Add svelte support [#40](https://github.com/Namchee/dependent/pull/40) ([@Namchee](https://github.com/Namchee))
#### Authors: 1
- Cristopher ([@Namchee](https://github.com/Namchee))
---
# v0.8.1 (Sun Aug 29 2021)

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

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

@@ -62,2 +62,4 @@ "repository": "git@github.com:Namchee/dependent.git",

"stylelint-config-standard": "^22.0.0",
"svelte": "^3.42.4",
"svelte-preprocess": "^4.8.0",
"ts-jest": "^27.0.5",

@@ -64,0 +66,0 @@ "typescript": "^4.3.5"

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

4. React Extended JavaScript and TypeScript, `.jsx` and `.tsx`
5. Vue Single File Components, `.vue`
5. Vue Single File Components, `.vue` (`.js` and `.ts` scripts only)
6. Svelte Single File Components, `.svelte` (`.js` script only)

@@ -30,0 +31,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)/**/*.vue',
'!(node_modules)/**/*.svelte',
'*.js',

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

'*.vue',
'*.svelte',
],

@@ -39,0 +41,0 @@ })

@@ -0,1 +1,3 @@

import chalk from 'chalk';
import { getParser } from './parser';

@@ -15,37 +17,54 @@

*/
export function getDependantFiles(
export async function getDependantFiles(
files: ProjectFile[],
dependency: string,
{ silent }: ParserOptions,
): DependantFile[] {
const dependant: DependantFile[] = [];
): Promise<DependantFile[]> {
const dependants: Promise<DependantFile | null>[] = files.map(
async (file) => {
try {
let ext = file.name.split('.').pop() as string;
for (const file of files) {
let ext = file.name.split('.').pop() as string;
if (ext === 'mjs') {
ext = 'js';
}
if (ext === 'mjs') {
ext = 'js';
}
const parse = getParser(ext);
const isDependant = await parse(file.content, dependency);
try {
const parse = getParser(ext);
const isDependant = parse(file.content, dependency);
if (isDependant.length) {
return {
name: file.name,
path: file.path,
lineNumbers: isDependant,
} as DependantFile;
}
if (isDependant.length) {
dependant.push(
{ name: file.name, path: file.path, lineNumbers: isDependant },
);
return null;
} catch (err) {
const error = err as Error;
throw new Error(`Failed to parse ${file.path}: ${error.message}`);
}
} catch (err) {
const error = err as Error;
},
);
if (silent) {
continue;
} else {
throw new Error(`Failed to parse ${file.path}: ${error.message}`);
if (!silent) {
const results = await Promise.all(dependants);
return results.filter(val => val !== null) as DependantFile[];
} else {
const rawResults = await Promise.allSettled(dependants);
const results = [];
for (const result of rawResults) {
if (result.status === 'rejected') {
console.log(
chalk.yellow(result.reason),
);
} else if (result.value) {
results.push(result.value);
}
}
return results;
}
return dependant;
}

@@ -35,3 +35,3 @@ #!/usr/bin/env node

const dependant = getDependantFiles(
const dependant = await getDependantFiles(
files,

@@ -38,0 +38,0 @@ dependency,

import { FileParser } from '../types';
import { getJSImportLines } from './js';
import { getSvelteImportLines } from './svelte';
import { getTSImportLines } from './ts';

@@ -17,2 +18,3 @@ import { getVueImportLines } from './vue';

vue: getVueImportLines,
svelte: getSvelteImportLines,
};

@@ -19,0 +21,0 @@

@@ -24,6 +24,3 @@ import { Parser } from 'acorn';

*/
export function parseNode(
sourceNode: Node,
dependency: string,
): number[] {
function parseNode(sourceNode: Node, dependency: string): number[] {
const lines: number[] = [];

@@ -84,6 +81,6 @@

*/
export function getJSImportLines(
export async function getJSImportLines(
content: string,
dependency: string,
): number[] {
): Promise<number[]> {
const node: Node = parser.parse(content, {

@@ -90,0 +87,0 @@ ecmaVersion: 'latest',

@@ -34,3 +34,5 @@ import globalDirectories from 'global-dirs';

for (const impor of imports) {
for (let i = 0; i < imports.length; i++) {
const impor = imports[i];
if (impor.status === 'fulfilled') {

@@ -53,6 +55,3 @@ ts = impor.value.default as typeof import('typescript');

*/
function parseNode(
sourceNode: SourceFile,
dependency: string,
): number[] {
function parseNode(sourceNode: SourceFile, dependency: string): number[] {
const lineNumbers: number[] = [];

@@ -121,6 +120,6 @@

*/
export function getTSImportLines(
export async function getTSImportLines(
content: string,
dependency: string,
): number[] {
): Promise<number[]> {
if (!ts) {

@@ -127,0 +126,0 @@ throw new Error('No Typescript parsers available');

@@ -34,8 +34,8 @@ import globalDirectories from 'global-dirs';

for (const impor of imports) {
for (let i = 0; i < imports.length; i++) {
const impor = imports[i];
if (impor.status === 'fulfilled') {
vue = impor.value.default as typeof import('@vue/compiler-sfc');
break;
} else {
console.log (impor.reason);
}

@@ -55,6 +55,6 @@ }

*/
export function getVueImportLines(
export async function getVueImportLines(
content: string,
dependency: string,
): number[] {
): Promise<number[]> {
if (!vue) {

@@ -69,5 +69,9 @@ throw new Error('No Vue parsers available');

const startingLine = script.loc.start.line;
if (script.lang === 'vue') {
throw new Error('Circular parser dependency');
}
const parser = getParser(script.lang || 'js');
const lines = parser(script.content, dependency);
const lines = await parser(script.content, dependency);
// -1, since the `<script>` block shouldn't count

@@ -74,0 +78,0 @@ return lines.map(line => line + startingLine - 1);

@@ -30,2 +30,2 @@ export interface ProjectDefinition {

dependency: string,
) => number[];
) => Promise<number[]>;
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