1- import fs from 'fs' ;
2- import path from 'path' ;
1+ import fs from 'node: fs' ;
2+ import path from 'node: path' ;
33import { execSync } from './exec-utils' ;
44
55export type PackageManagers = 'npm' | 'yarn' | 'pnpm' ;
66
7- function findUp ( names : string [ ] , cwd : string ) : string | undefined {
8- let dir = cwd ;
9- // eslint-disable-next-line no-constant-condition
10- while ( true ) {
11- const target = names . find ( ( name ) => fs . existsSync ( path . join ( dir , name ) ) ) ;
12- if ( target ) return target ;
13-
14- const up = path . resolve ( dir , '..' ) ;
15- if ( up === dir ) return undefined ; // it'll fail anyway
16- dir = up ;
17- }
7+ /**
8+ * A type named FindUp that takes a type parameter e which extends boolean.
9+ * If e extends true, it returns a union type of string[] or undefined.
10+ * If e does not extend true, it returns a union type of string or undefined.
11+ *
12+ * @export
13+ * @template e A type parameter that extends boolean
14+ */
15+ export type FindUp < e extends boolean > = e extends true ? string [ ] | undefined : string | undefined
16+ /**
17+ * Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
18+ * Optionally return a single path or multiple paths.
19+ * If multiple allowed, return all paths found.
20+ * If no paths are found, return undefined.
21+ *
22+ * @export
23+ * @template [e=false]
24+ * @param names An array of strings representing names to search for within the directory
25+ * @param cwd A string representing the current working directory
26+ * @param [multiple=false as e] A boolean flag indicating whether to search for multiple levels. Useful for finding node_modules directories...
27+ * @param [result=[]] An array of strings representing the accumulated results used in multiple results
28+ * @returns Path(s) to a specific file or folder within the directory or parent directories
29+ */
30+ export function findUp < e extends boolean = false > ( names : string [ ] , cwd : string = process . cwd ( ) , multiple : e = false as e , result : string [ ] = [ ] ) : FindUp < e > {
31+ if ( ! names . some ( ( name ) => ! ! name ) ) return undefined ;
32+ const target = names . find ( ( name ) => fs . existsSync ( path . join ( cwd , name ) ) ) ;
33+ if ( multiple == false && target ) return path . join ( cwd , target ) as FindUp < e > ;
34+ if ( target ) result . push ( path . join ( cwd , target ) ) ;
35+ const up = path . resolve ( cwd , '..' ) ;
36+ if ( up === cwd ) return ( multiple && result . length > 0 ? result : undefined ) as FindUp < e > ; // it'll fail anyway
37+ return findUp ( names , up , multiple , result ) ;
1838}
1939
2040function getPackageManager ( projectPath = '.' ) : PackageManagers {
@@ -85,6 +105,11 @@ export function ensurePackage(
85105 }
86106}
87107
108+ /**
109+ * A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
110+ * It iterates through the directory structure going one level up at a time until it finds a package.json file. If no package.json file is found, it returns undefined.
111+ * @deprecated Use findUp instead @see findUp
112+ */
88113export function findPackageJson ( searchPath ?: string ) {
89114 let currDir = searchPath ?? process . cwd ( ) ;
90115 while ( currDir ) {
@@ -102,7 +127,7 @@ export function findPackageJson(searchPath?: string) {
102127}
103128
104129export function getPackageJson ( searchPath ?: string ) {
105- const pkgJsonPath = findPackageJson ( searchPath ) ;
130+ const pkgJsonPath = findUp ( [ 'package.json' ] , searchPath ?? process . cwd ( ) ) ;
106131 if ( pkgJsonPath ) {
107132 return JSON . parse ( fs . readFileSync ( pkgJsonPath , 'utf-8' ) ) ;
108133 } else {
0 commit comments