Socket
Socket
Sign inDemoInstall

mr-dep-walk

Package Overview
Dependencies
7
Maintainers
3
Versions
9
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.1 to 1.4.0

lib/default-parser.js

1

index.js

@@ -6,3 +6,4 @@ 'use strict';

depsFromSource: require('./lib/deps-from-source'),
depsFromAST: require('./lib/deps-from-ast'),
depFilesFromFile: require('./lib/dep-files-from-file'),
};

@@ -11,3 +11,5 @@ 'use strict';

let cwd = options.cwd || '';
let deps = depsFromFile(path.join(root, cwd, file));
let deps = depsFromFile(path.join(root, cwd, file), {
parse: options.parse,
});

@@ -29,2 +31,3 @@ for (let i = 0; i < deps.length; i++) {

files.push(fullDependency);
depFilesFromFile(

@@ -36,2 +39,3 @@ root,

external: options.external,
parse: options.parse,
},

@@ -38,0 +42,0 @@ files

4

lib/deps-from-file.js

@@ -6,5 +6,5 @@ 'use strict';

module.exports = function depsFromFile(file) {
module.exports = function depsFromFile(file, options) {
if (fs.existsSync(file)) {
return depsFromSource(fs.readFileSync(file, 'UTF8'));
return depsFromSource(fs.readFileSync(file, 'UTF8'), options);
} else {

@@ -11,0 +11,0 @@ return [];

'use strict';
const acorn = require('acorn');
// lifted from: https://github.com/ef4/ember-browserify/blob/master/lib/stubs.js (EF4 deserves credit);
//
const STOP = {};
function forEachNode(node, visit) {
if (node && typeof node === 'object' && !node._eb_visited) {
node._eb_visited = true;
let shouldStop = visit(node);
if (STOP === shouldStop) {
return STOP;
}
let keys = Object.keys(node);
for (let i = 0; i < keys.length; i++) {
let shouldStop = forEachNode(node[keys[i]], visit);
if (STOP === shouldStop) {
return STOP;
}
}
}
}
const depsFromAST = require('./deps-from-ast');
const defaultParser = require('./default-parser');
module.exports = function depsFromSource(source) {
// TODO: add a persistent cache
let imports = [];
module.exports = function depsFromSource(source, _options) {
let options = _options || {};
let parse = options.parse || defaultParser;
let ast = acorn.parse(source, {
ecmaVersion: 8,
sourceType: 'module',
});
let hasImportDeclaration = false;
forEachNode(ast, function(entry) {
if (entry.type === 'ImportDeclaration') {
hasImportDeclaration = true;
let value = entry.source.value;
if (value === 'exports' || value === 'require') {
return;
}
imports.push(value);
}
if (hasImportDeclaration) {
return;
}
if (entry.type === 'CallExpression' && entry.callee.name === 'define') {
for (let i = 0; i < entry.arguments.length; i++) {
let item = entry.arguments[i];
if (item.type === 'ArrayExpression') {
for (let j = 0; j < item.elements.length; j++) {
let element = item.elements[j];
let value = element.value;
if (value !== 'exports' && value !== 'require') {
imports.push(value);
}
}
return STOP;
}
}
return STOP;
}
});
return imports;
return depsFromAST(
parse(source, {
ecmaVersion: 8,
sourceType: 'module',
})
);
};

@@ -32,3 +32,3 @@ {

"name": "mr-dep-walk",
"version": "1.3.1",
"version": "1.4.0",
"main": "index.js",

@@ -35,0 +35,0 @@ "directories": {

@@ -6,1 +6,86 @@ # mr-dep-walk

This library extracts dependent files from both ES6 module syntax, and AMD module syntax;
## Usage
```
yarn add mr-dep-walk
```
```js
const {
depFilesFromFile,
depsFromFile,
depsFromSource,
depsFromAST
} = require('mr-dep-walk');
```
For `depFilesFromFile` given an entry file, it will produce a list of all dependent files (recursively):
```js
// file.js
import x from 'y';
// y.js
```
```js
depFilesFromFile({
entry: 'file.js',
/* cwd: optional, */
/* parse: optional, */
}); // => 'y.js';
```
For `depsFromFile` given a file, it will produce a list of its immediate dependent moduleNames;
```js
// file.js
import x from 'y';
// y.js
```
```js
depsFromFile({
entry: 'file.js',
/* cwd: optional, */
/* parse: optional, */
}); // => 'y';
```
For `depsFromSource` given the raw source, it will produce a list of its immediate dependent moduleNames;
```js
depsFromSource(`import x from 'y'`/*, options */); // => 'y'
```
For `depsFromAST` given the AST, it will produce a list of its immediate dependent moduleNames;
```js
depsFromSource(acorn.parse(`import x from 'y'`, {
ecmaVersion: 8,
sourceType: 'module'
})); // => 'y'
```
### Custom Parse Step
By default mr-dep-walk will use:
```js
source => acorn.parse(source, { ecmaVersion: 8, sourceType: 'module'})
```
But some methods (`depFilesFromFile`, `depsFromFile`, `depsFromSource`) support
an alt-parser, example:
```js
depFilesFromFile('some-file.js', {
entry: 'foo.js',
parse(source) {
return customParser(source);
},
});
```

@@ -9,2 +9,3 @@ 'use strict';

const depsFromFile = require('../lib/deps-from-file');
const defaultParser = require('../lib/default-parser');

@@ -58,2 +59,33 @@ describe('.depsFromFile', function() {

});
describe('pluggable parse', function() {
fs.removeSync(ROOT);
fixturify.writeSync(ROOT + 'es6', {
'foo.js': `
import x from 'a';
import y from 'b/c';`,
'a.js': ``,
b: {
'c.js': `
import a from '../a';
import d from '../d';
`,
},
'd.js': `import foo from 'foo';`,
});
it('provide alternative parser', function() {
let parseCount = 0;
expect(
depsFromFile(ROOT + 'es6/foo.js', {
parse(source) {
parseCount++;
return defaultParser(source);
},
})
).to.eql(['a', 'b/c']);
expect(parseCount).to.eql(1);
});
});
});

@@ -5,2 +5,3 @@ 'use strict';

const depsFromSrouce = require('../lib/deps-from-source');
const defaultParser = require('../lib/default-parser');

@@ -63,2 +64,24 @@ describe('.depsFromSource', function() {

});
describe('pluggable parse', function() {
it('provide alternative parser', function() {
let parseCount = 0;
expect(
depsFromSrouce(
`
import x from 'a';
import y from 'b/c';
`,
{
parse(source) {
parseCount++;
return defaultParser(source);
},
}
)
).to.eql(['a', 'b/c']);
expect(parseCount).to.eql(1);
});
});
});
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