UNPKG

@augment-vir/node

Version:

A collection of augments, helpers types, functions, and classes only for Node.js (backend) JavaScript environments.

99 lines (89 loc) 3.4 kB
import {check} from '@augment-vir/assert'; import {filterMap, getEnumValues, getObjectTypedEntries, getOrSet} from '@augment-vir/common'; import {type PackageJson} from 'type-fest'; import {readJsonFile} from '../fs/json.js'; import {findAllPackageJsonFilePaths} from './package-json.js'; /** * All `package.json` keys that are parsed as direct dependencies. * * @category Internal */ export enum PackageJsonDependencyKey { DevDependencies = 'devDependencies', Dependencies = 'dependencies', PeerDependencies = 'peerDependencies', Overrides = 'overrides', } /** * A record of package names to package versions included in the direct dependencies. This is the * output from {@link listAllDirectNpmDeps}. * * @category Internal * @category Package : @augment-vir/node * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node) */ export type NpmDeps = Record<string, NpmDep[]>; /** * An individual dependency used in {@link NpmDeps}. * * @category Internal * @category Package : @augment-vir/node * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node) */ export type NpmDep = { /** Path to the `package.json` file that depends on this. */ requiredBy: string; dependencyKey: PackageJsonDependencyKey; /** * The version as it is directly noted in the `package.json` file. This might not necessarily * correlate to any actually published versions. */ versionValue: string; /** If true, this dependency is part of the workspace's own packages. */ isWorkspace: boolean; }; /** * Finds all direct deps for the workspace at, or that contains, the given dir path. * * @category Node : Npm * @category Package : @augment-vir/node * @throws If no directory with a `package-lock.json` file is found. * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node) */ export async function listAllDirectNpmDeps(startDirPath: string): Promise<NpmDeps> { const packageJsonFilePaths = await findAllPackageJsonFilePaths(startDirPath); const deps: NpmDeps = {}; const packageJsonFiles = await Promise.all( packageJsonFilePaths.map(async (packageJsonFilePath) => { return { packageJsonFilePath, packageJson: (await readJsonFile(packageJsonFilePath)) as PackageJson, }; }), ); const allWorkspacePackageNames = filterMap( packageJsonFiles, (packageJsonFile) => packageJsonFile.packageJson.name, check.isTruthy, ); packageJsonFiles.forEach(({packageJson, packageJsonFilePath}) => { getEnumValues(PackageJsonDependencyKey).forEach((dependencyKey) => { getObjectTypedEntries(packageJson[dependencyKey] || {}).forEach( ([ dependencyName, versionValue, ]) => { if (typeof versionValue === 'string') { getOrSet(deps, dependencyName, () => []).push({ dependencyKey, requiredBy: packageJsonFilePath, versionValue, isWorkspace: allWorkspacePackageNames.includes(dependencyName), }); } }, ); }); }); return deps; }