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

dependencies-hierarchy

Package Overview
Dependencies
Maintainers
1
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dependencies-hierarchy - npm Package Compare versions

Comparing version 5.0.12 to 6.0.0-0

36

lib/index.d.ts

@@ -1,2 +0,2 @@

import { Registries } from '@pnpm/types';
import { DependenciesField, Registries } from '@pnpm/types';
export declare type PackageSelector = string | {

@@ -7,23 +7,35 @@ name: string;

export interface PackageNode {
pkg: {
name: string;
version: string;
path: string;
};
alias: string;
circular?: true;
dependencies?: PackageNode[];
dev?: boolean;
isPeer: boolean;
name: string;
optional?: true;
path: string;
resolved?: string;
searched?: true;
circular?: true;
saved?: false;
version: string;
}
export declare function forPackages(packages: PackageSelector[], projectPath: string, opts?: {
depth: number;
only?: 'dev' | 'prod';
include?: {
[dependenciesField in DependenciesField]: boolean;
};
registries?: Registries;
lockfileDirectory?: string;
}): never[] | Promise<PackageNode[]>;
}): {};
export default function (projectPath: string, opts?: {
depth: number;
only?: 'dev' | 'prod';
include?: {
[dependenciesField in DependenciesField]: boolean;
};
registries?: Registries;
lockfileDirectory?: string;
}): Promise<PackageNode[]>;
}): Promise<DependenciesHierarchy>;
export declare type DependenciesHierarchy = {
dependencies?: PackageNode[];
devDependencies?: PackageNode[];
optionalDependencies?: PackageNode[];
unsavedDependencies?: PackageNode[];
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const lockfile_file_1 = require("@pnpm/lockfile-file");
const lockfile_utils_1 = require("@pnpm/lockfile-utils");
const modules_yaml_1 = require("@pnpm/modules-yaml");
const read_modules_dir_1 = require("@pnpm/read-modules-dir");
const types_1 = require("@pnpm/types");
const utils_1 = require("@pnpm/utils");

@@ -16,3 +18,3 @@ const assert = require("assert");

if (!packages.length)
return [];
return {};
return dependenciesHierarchy(projectPath, packages, opts);

@@ -31,8 +33,12 @@ }

if (!lockfile)
return [];
const opts = Object.assign({ depth: 0, only: undefined }, maybeOpts);
return {};
const opts = Object.assign({ depth: 0 }, maybeOpts);
const include = maybeOpts && maybeOpts.include || {
dependencies: true,
devDependencies: true,
optionalDependencies: true,
};
const importerId = lockfile_file_1.getLockfileImporterId(lockfileDirectory, projectPath);
if (!lockfile.importers[importerId])
return [];
const topDeps = getFilteredDependencies(lockfile.importers[importerId], opts) || {};
return {};
const modulesDir = path.join(projectPath, 'node_modules');

@@ -42,47 +48,47 @@ const savedDeps = getAllDirectDependencies(lockfile.importers[importerId]);

const unsavedDeps = allDirectDeps.filter((directDep) => !savedDeps[directDep]);
if (Object.keys(topDeps).length === 0 && unsavedDeps.length === 0)
return [];
const getChildrenTree = getTree.bind(null, {
currentDepth: 1,
includeOptionalDependencies: include.optionalDependencies === true,
maxDepth: opts.depth,
modulesDir,
prod: opts.only === 'prod',
registries,
searched,
}, lockfile.packages);
const result = [];
Object.keys(topDeps).forEach((depName) => {
const pkgPath = dependency_path_1.refToAbsolute(topDeps[depName], depName, registries);
const pkg = {
name: depName,
path: pkgPath && path.join(modulesDir, `.${pkgPath}`) || path.join(modulesDir, '..', topDeps[depName].substr(5)),
version: topDeps[depName],
};
let newEntry = null;
const matchedSearched = searched.length && matches(searched, pkg);
if (pkgPath === null) {
if (searched.length && !matchedSearched)
return;
newEntry = { pkg };
}
else {
const relativeId = dependency_path_1.refToRelative(topDeps[depName], depName);
const dependencies = getChildrenTree([relativeId], relativeId);
if (dependencies.length) {
newEntry = {
dependencies,
pkg,
};
const result = {};
for (const dependenciesField of types_1.DEPENDENCIES_FIELDS.sort().filter(dependenciedField => include[dependenciedField])) {
const topDeps = lockfile.importers[importerId][dependenciesField] || {};
result[dependenciesField] = [];
Object.keys(topDeps).forEach((alias) => {
const { packageInfo, packageAbsolutePath } = getPkgInfo({
alias,
modulesDir,
packages: lockfile.packages || {},
ref: topDeps[alias],
registries,
});
let newEntry = null;
const matchedSearched = searched.length && matches(searched, packageInfo);
if (packageAbsolutePath === null) {
if (searched.length && !matchedSearched)
return;
newEntry = packageInfo;
}
else if (!searched.length || matches(searched, pkg)) {
newEntry = { pkg };
else {
const relativeId = dependency_path_1.refToRelative(topDeps[alias], alias);
const dependencies = getChildrenTree([relativeId], relativeId);
if (dependencies.length) {
newEntry = Object.assign({}, packageInfo, { dependencies });
}
else if (!searched.length || matches(searched, packageInfo)) {
newEntry = packageInfo;
}
}
}
if (newEntry) {
if (matchedSearched) {
newEntry.searched = true;
if (newEntry) {
if (matchedSearched) {
newEntry.searched = true;
}
result[dependenciesField].push(newEntry);
}
result.push(newEntry);
}
});
});
}
await Promise.all(unsavedDeps.map(async (unsavedDep) => {

@@ -101,2 +107,4 @@ let pkgPath = path.join(modulesDir, unsavedDep);

const pkg = {
alias: unsavedDep,
isPeer: false,
name: unsavedDep,

@@ -109,23 +117,11 @@ path: pkgPath,

return;
const newEntry = {
pkg,
saved: false,
};
const newEntry = pkg;
if (matchedSearched) {
newEntry.searched = true;
}
result.push(newEntry);
result.unsavedDependencies = result.unsavedDependencies || [];
result.unsavedDependencies.push(newEntry);
}));
return result;
}
function getFilteredDependencies(lockfileImporter, opts) {
switch (opts.only) {
case 'prod':
return lockfileImporter.dependencies;
case 'dev':
return lockfileImporter.devDependencies;
default:
return getAllDirectDependencies(lockfileImporter);
}
}
function getAllDirectDependencies(lockfileImporter) {

@@ -137,3 +133,3 @@ return Object.assign({}, lockfileImporter.dependencies, lockfileImporter.devDependencies, lockfileImporter.optionalDependencies);

return [];
const deps = opts.prod
const deps = opts.includeOptionalDependencies === false
? packages[parentId].dependencies

@@ -144,29 +140,29 @@ : Object.assign({}, packages[parentId].dependencies, packages[parentId].optionalDependencies);

const getChildrenTree = getTree.bind(null, Object.assign({}, opts, { currentDepth: opts.currentDepth + 1 }), packages);
const peers = new Set(Object.keys(packages[parentId].peerDependencies || {}));
const result = [];
Object.keys(deps).forEach((depName) => {
const pkgPath = dependency_path_1.refToAbsolute(deps[depName], depName, opts.registries);
const pkg = {
name: depName,
path: pkgPath && path.join(opts.modulesDir, `.${pkgPath}`) || path.join(opts.modulesDir, '..', deps[depName].substr(5)),
version: deps[depName],
};
Object.keys(deps).forEach((alias) => {
const { packageInfo, packageAbsolutePath } = getPkgInfo({
alias,
modulesDir: opts.modulesDir,
packages,
peers,
ref: deps[alias],
registries: opts.registries,
});
let circular;
const matchedSearched = opts.searched.length && matches(opts.searched, pkg);
const matchedSearched = opts.searched.length && matches(opts.searched, packageInfo);
let newEntry = null;
if (pkgPath === null) {
if (packageAbsolutePath === null) {
circular = false;
newEntry = { pkg };
newEntry = packageInfo;
}
else {
const relativeId = dependency_path_1.refToRelative(deps[depName], depName); // we know for sure that relative is not null if pkgPath is not null
const relativeId = dependency_path_1.refToRelative(deps[alias], alias); // we know for sure that relative is not null if pkgPath is not null
circular = keypath.includes(relativeId);
const dependencies = circular ? [] : getChildrenTree(keypath.concat([relativeId]), relativeId);
if (dependencies.length) {
newEntry = {
dependencies,
pkg,
};
newEntry = Object.assign({}, packageInfo, { dependencies });
}
else if (!opts.searched.length || matchedSearched) {
newEntry = { pkg };
newEntry = packageInfo;
}

@@ -186,2 +182,43 @@ }

}
function getPkgInfo(opts) {
let name;
let version;
let resolved = undefined;
let dev = undefined;
let optional = undefined;
const relDepPath = dependency_path_1.refToRelative(opts.ref, opts.alias);
if (relDepPath) {
const parsed = lockfile_utils_1.nameVerFromPkgSnapshot(relDepPath, opts.packages[relDepPath]);
name = parsed.name;
version = parsed.version;
resolved = lockfile_utils_1.pkgSnapshotToResolution(relDepPath, opts.packages[relDepPath], opts.registries)['tarball'];
dev = opts.packages[relDepPath].dev;
optional = opts.packages[relDepPath].optional;
}
else {
name = opts.alias;
version = opts.ref;
}
const packageAbsolutePath = dependency_path_1.refToAbsolute(opts.ref, opts.alias, opts.registries);
const packageInfo = {
alias: opts.alias,
isPeer: Boolean(opts.peers && opts.peers.has(opts.alias)),
name,
path: packageAbsolutePath && path.join(opts.modulesDir, `.${packageAbsolutePath}`) || path.join(opts.modulesDir, '..', opts.ref.substr(5)),
version,
};
if (resolved) {
packageInfo['resolved'] = resolved;
}
if (optional === true) {
packageInfo['optional'] = true;
}
if (typeof dev === 'boolean') {
packageInfo['dev'] = dev;
}
return {
packageAbsolutePath,
packageInfo,
};
}
function matches(searched, pkg) {

@@ -188,0 +225,0 @@ return searched.some((searchedPkg) => {

{
"name": "dependencies-hierarchy",
"version": "5.0.12",
"version": "6.0.0-0",
"description": "Creates a dependencies hierarchy for a symlinked `node_modules`",

@@ -40,2 +40,3 @@ "main": "lib/index.js",

"@pnpm/lockfile-file": "1.1.1",
"@pnpm/lockfile-utils": "1.0.10",
"@pnpm/modules-yaml": "3.0.3",

@@ -42,0 +43,0 @@ "@pnpm/read-modules-dir": "2.0.1",

@@ -17,78 +17,4 @@ # dependencies-hierarchy

## Usage
```js
'use strict'
const hierarchyForPackages = require('dependencies-hierarchy').forPackages
hierarchyForPackages(['graceful-fs', {name: 'pify', range: '2'}], __dirname, {depth: 2})
.then(tree => {
console.log(JSON.stringify(tree, null, 2))
//> [
// {
// "dependencies": [
// {
// "dependencies": [
// {
// "pkg": {
// "name": "graceful-fs",
// "path": "/home/zoltan/src/pnpm/pnpm/packages/dependencies-hierarchy/example/node_modules/.registry.npmjs.org/graceful-fs/4.1.11",
// "version": "4.1.11"
// },
// "searched": true
// },
// {
// "pkg": {
// "name": "pify",
// "path": "/home/zoltan/src/pnpm/pnpm/packages/dependencies-hierarchy/example/node_modules/.registry.npmjs.org/pify/2.3.0",
// "version": "2.3.0"
// },
// "searched": true
// }
// ],
// "pkg": {
// "name": "write-json-file",
// "path": "/home/zoltan/src/pnpm/pnpm/packages/dependencies-hierarchy/example/node_modules/.registry.npmjs.org/write-json-file/2.2.0",
// "version": "2.2.0"
// }
// }
// ],
// "pkg": {
// "name": "write-pkg",
// "path": "/home/zoltan/src/pnpm/pnpm/packages/dependencies-hierarchy/example/node_modules/.registry.npmjs.org/write-pkg/3.1.0",
// "version": "3.1.0"
// }
// }
// ]
})
```
## API
### default: `dependenciesHierarchy(projectPath, [opts]): Promise<Hierarchy>`
Creates a dependency tree for a project's `node_modules`.
#### Arguments:
- `projectPath` - _String_ - The path to the project.
- `[opts.depth]` - _Number_ - 0 by default. How deep should the `node_modules` be analyzed.
- `[opts.only]` - _'dev' | 'prod'_ - Optional. If set to `dev`, then only packages from `devDependencies` are analyzed.
If set to `prod`, then only packages from `dependencies` are analyzed.
### `forPackages(packageSelectors, projectPath, [opts]): Promise<Hierarchy>`
Creates a dependency tree for a project's `node_modules`. Limits the results to only the paths to the packages named.
#### Arguments:
- `packageSelectors` - _(string | {name: string, version: string})\[]_ - An array that consist of package names or package names and version ranges.
E.g. `['foo', {name: 'bar', version: '^2.0.0'}]`.
- `projectPath` - _String_ - The path to the project
- `[opts.depth]` - _Number_ - 0 by default. How deep should the `node_modules` be analyzed.
- `[opts.only]` - _'dev' | 'prod'_ - Optional. If set to `dev`, then only packages from `devDependencies` are analyzed.
If set to `prod`, then only packages from `dependencies` are analyzed.
## License
MIT © [Zoltan Kochan](https://www.kochan.io/)
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