New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

npm-dependencies-extractor

Package Overview
Dependencies
Maintainers
8
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

npm-dependencies-extractor - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

.editorconfig

6

package.json
{
"name": "npm-dependencies-extractor",
"version": "0.0.5",
"version": "0.0.6",
"description": "Retrieves the (flat) list of package dependencies for Javascript projects using npm",

@@ -21,3 +21,7 @@ "main": "index.js",

"npm",
"sbom",
"software bill of material",
"flat list",
"extract",
"retrieve",
"dependencies flat list",

@@ -24,0 +28,0 @@ "extract dependencies",

[![Build Status](https://travis-ci.com/philips-software/npm-dependencies-extractor.svg?branch=master)](https://travis-ci.com/philips-software/npm-dependencies-extractor)
# npm-dependencies-extractor
This is a CLI package that provides a command *extract-dependencies* to extract the flat list of (all) dependencies from a package-lock.json file (or another file with the same structure of your choice. If you want, instead of the package-lock.json, you may specify as input file the JSON file generated by the npm command to list json dependencies, such as:
This is a CLI package that provides a command *extract-dependencies* to extract the flat list of (all installed) dependencies from a package-lock.json file (or another file with the same structure of your choice. If you want, instead of the package-lock.json, you may specify as input file the JSON file generated by the npm command to list json dependencies, such as:
```

@@ -33,2 +33,9 @@ npm list --json > inputFile.json

# Status
0.0.6, see [CHANGELOG.md](./CHANGELOG.md)
## Technology stack
- Javascript
- This software is intended to be used standalone, as a command-line tool
## Prerequisites

@@ -67,3 +74,3 @@ - you should have Node installed (this script was tested with node v8.12.0)

```shell
npx npm-dependencies-extractor extract-dependencies [options]
npx npm-dependencies-extractor [options]
```

@@ -83,3 +90,8 @@

### Sample usage
```
npm run extract-dependencies -- -i ./test-data/input-with-optionals/package-lock-with-2-mandatory-dependencies.json --verbose
```
## Usage scenarios

@@ -94,5 +106,10 @@

```
npx npm-dependencies-extractor extract-dependencies [options]
npx npm-dependencies-extractor [options]
```
or, if you don't want to install it from github master, run:
```
npx github:philips-software/npm-dependencies-extractor [options]
```
### Scenario 2: You include the npm-dependencies-extractor as a dependency of your project, and call its command in your project's scripts, by:

@@ -113,1 +130,27 @@ ```shell

## Owners
See [CODEOWNERS](./CODEOWNERS)
## Maintainers
See [MAINTAINERS.md](./MAINTAINERS.md)
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md)
## License
See [LICENSE.md](./LICENSE.md)
## Author
Sanda Contiu
## Keywords
- dependencies
- npm
- sbom
- software bill of material
- flat list
- extract
- retrieve
- dependencies flat list
- extract dependencies
- list dependencies

32

src/dependencies-extractor.js

@@ -6,18 +6,23 @@ const utilities = require('./utilities');

const isDependencyOptional = ({ jsonDependencyDetails }) => Object.keys(jsonDependencyDetails).includes('optional')
&& (jsonDependencyDetails.optional === true);
// Gets the dependencies from the 'dependencies' attribute
const getRecursivelyDependenciesReducer = (accumulator, currentPackageKeyPairTwoSizedArray) => {
// Push the current package info (name and version only)
accumulator.push(
formatDependencyAsJsonObject(
currentPackageKeyPairTwoSizedArray[0],
currentPackageKeyPairTwoSizedArray[1].version,
),
);
if (!isDependencyOptional({ jsonDependencyDetails: currentPackageKeyPairTwoSizedArray[1] })) {
// Push the current package info (name and version only)
accumulator.push(
formatDependencyAsJsonObject(
currentPackageKeyPairTwoSizedArray[0],
currentPackageKeyPairTwoSizedArray[1].version,
),
);
if (Object.keys(currentPackageKeyPairTwoSizedArray[1]).includes('dependencies')) {
// go recursively and concatenate the found dependencies
accumulator = accumulator.concat( // eslint-disable-line no-param-reassign
Object.entries(currentPackageKeyPairTwoSizedArray[1].dependencies)
.reduce(getRecursivelyDependenciesReducer, []),
);
if (Object.keys(currentPackageKeyPairTwoSizedArray[1]).includes('dependencies')) {
// go recursively and concatenate the found dependencies
accumulator = accumulator.concat( // eslint-disable-line no-param-reassign
Object.entries(currentPackageKeyPairTwoSizedArray[1].dependencies)
.reduce(getRecursivelyDependenciesReducer, []),
);
}
}

@@ -38,2 +43,3 @@ return accumulator;

getFlatListOfDependencies,
isDependencyOptional,
};

@@ -16,2 +16,7 @@ const packageLockFileUniqueVersions = '../test-data/npm-dependencies-unique-versions/test-package-lock.json';

const packageLock2MandatoryDependencies = require('../test-data/input-with-optionals/package-lock-with-2-mandatory-dependencies.json');
const packageLock3DeclaredOptionalDependenciesAllActuallyOptional = require('../test-data/input-with-optionals/package-lock-with-total-3-dependencies-3-optionals-not-required-by-any-mandatory-dependency.json');
const packageLock4Dependencies3DeclaredOptionalActually2Optional = require('../test-data/input-with-optionals/package-lock-with-total-4-dependencies-3-optionals-of-which-1-also-occurs-as-mandatory.json');
/*

@@ -134,1 +139,72 @@ The package-lock.json loaded in the next test case reflects the

});
describe('isDependencyOptional', () => {
it('returns true for a dependency json with key "optional" set to true',
() => {
const jsonDependencyDetails = {
version: '2.14.0',
resolved: 'https://registry.npmjs.org/nan/-/nan-2.14.0.tgz',
integrity: 'some-key',
optional: true,
};
expect(dependenciesExtractor.isDependencyOptional({ jsonDependencyDetails }))
.toBe(true);
});
it('returns false for a dependency json with key "optional" set to false',
() => {
const jsonDependencyDetails = {
version: '2.14.0',
resolved: 'https://registry.npmjs.org/nan/-/nan-2.14.0.tgz',
integrity: 'some-key',
optional: false,
};
expect(dependenciesExtractor.isDependencyOptional({ jsonDependencyDetails }))
.toBe(false);
});
it('returns false for a dependency json with no key "optional"',
() => {
const jsonDependencyDetails = {
version: '2.14.0',
resolved: 'https://registry.npmjs.org/nan/-/nan-2.14.0.tgz',
integrity: 'some-key',
};
expect(dependenciesExtractor.isDependencyOptional({ jsonDependencyDetails }))
.toBe(false);
});
});
describe('getFlatListOfDependencies deals with optional dependencies as follows:', () => {
it(`extracts all mandatory dependencies from input ${packageLock2MandatoryDependencies}`,
() => {
expect(dependenciesExtractor
.getFlatListOfDependencies(packageLock2MandatoryDependencies))
.toEqual([
{ [NAME_KEY]: '@babel/code-frame', [VERSION_KEY]: '7.5.5' },
{ [NAME_KEY]: '@babel/highlight', [VERSION_KEY]: '7.5.0' },
]);
});
// eslint-disable-next-line prefer-template
it('extracts zero dependencies from input (when input\'s dependencies are all optional) '
+ packageLock3DeclaredOptionalDependenciesAllActuallyOptional,
() => {
expect(dependenciesExtractor
.getFlatListOfDependencies(packageLock3DeclaredOptionalDependenciesAllActuallyOptional))
.toEqual([]);
});
// eslint-disable-next-line prefer-template
it('extracts all mandatory dependencies from input json '
+ packageLock4Dependencies3DeclaredOptionalActually2Optional,
() => {
expect(dependenciesExtractor
.getFlatListOfDependencies(packageLock4Dependencies3DeclaredOptionalActually2Optional))
.toEqual([
{ [NAME_KEY]: 'ansi-regex', [VERSION_KEY]: '2.1.1' },
{ [NAME_KEY]: 'has-ansi', [VERSION_KEY]: '2.0.0' },
]);
});
});

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

const formatter = require('./formatter');
const utilities = require('./utilities');

@@ -62,2 +63,7 @@ program

if (!utilities.isValidPackageLockJson(dependencies)) {
infoMessage(chalk`Input {blue ${input}} not a valid {blue package-lock.json} format, exiting.`);
return;
}
const extractedDependenciesJsonArr = dependencyExtractor.getFlatListOfDependencies(dependencies);

@@ -64,0 +70,0 @@

@@ -46,5 +46,14 @@ const {

const isValidPackageLockJson = input => typeof input !== 'undefined'
&& typeof input.dependencies !== 'undefined'
&& !Object.entries(input.dependencies).find(
entry => typeof entry === 'undefined'
|| typeof entry[1] === 'undefined'
|| typeof entry[1].version === 'undefined',
);
module.exports = {
sortByNameAndVersionCaseInsensitive,
getUniquesByNameAndVersion,
isValidPackageLockJson,
};

@@ -111,1 +111,6 @@ const utilities = require('./utilities');

});
test('isValidPackageLockJson returns false if input is incorrect', () => {
const input = { dependencies: { 'some package': { } } };
expect(utilities.isValidPackageLockJson(input)).toBe(false);
});
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc