UNPKG

@augment-vir/node

Version:

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

76 lines (66 loc) 2.74 kB
import {check} from '@augment-vir/assert'; import {filterMap, fromAsyncIterable} from '@augment-vir/common'; import {existsSync} from 'node:fs'; import {glob, readFile} from 'node:fs/promises'; import {join} from 'node:path'; import {type PackageJson} from 'type-fest'; import {findAncestor, joinFilesToDir} from '../path/ancestor.js'; /** * Finds all `package.json` files contained within the workspaces present in the current * `startDirPath`. A workspace root dir is found by recursively looking for a parent * `package-lock.json` file. * * @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 findAllPackageJsonFilePaths(startDirPath: string) { const packageRootDir = findAncestor(startDirPath, (dir) => existsSync(join(dir, 'package-lock.json')), ); if (!packageRootDir) { throw new Error( `Cannot find all package.json files: failed to find any directory with a package-lock.json file. Started at '${startDirPath}'.`, ); } const rootPackageJsonPath = join(packageRootDir, 'package.json'); return [ rootPackageJsonPath, ...(await getWorkspacePackageJsonFilePaths(packageRootDir)), ]; } /** * Get all workspace package.json paths starting at the given directory path. The output is string * sorted to keep it stable. * * @category Node : Npm * @category Package : @augment-vir/node * @throws Error if there is no `package.json` file at the given `rootDirPath`. * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node) */ export async function getWorkspacePackageJsonFilePaths(rootDirPath: string): Promise<string[]> { const packageJson: PackageJson = JSON.parse( await readFile(join(rootDirPath, 'package.json'), 'utf8'), ); /* node:coverage ignore next 3: this package only uses one type of workspace */ const patterns = check.isArray(packageJson.workspaces) ? packageJson.workspaces : packageJson.workspaces?.packages || []; const matchedPaths: string[] = joinFilesToDir( rootDirPath, ( await Promise.all( patterns.map(async (pattern) => { return await fromAsyncIterable(glob(pattern, {cwd: rootDirPath})); }), ) ).flat(), ); const workspacePackageJsonPaths = filterMap( matchedPaths, (matchedPath) => join(matchedPath, 'package.json'), (packageJsonPath) => existsSync(packageJsonPath), ); return workspacePackageJsonPaths.sort(); }