Skip to content

Commit 8f6e151

Browse files
committed
feat(bin): add which and whichSync wrapper functions
Add which and whichSync as wrapper functions around getWhich() and getWhich().sync for lazy loading. - Add WhichOptions interface to replace import('which').Options - Export which() async wrapper around getWhich() - Export whichSync() sync wrapper around getWhich().sync - Update whichBin and whichBinSync to use WhichOptions type
1 parent 27b86dc commit 8f6e151

1 file changed

Lines changed: 45 additions & 10 deletions

File tree

src/bin.ts

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { getXdgDataHome } from '#env/xdg'
99

1010
import { WIN32 } from '#constants/platform'
1111
import { readJsonSync } from './fs'
12-
import { getOwn } from './objects'
1312
import { isPath, normalizePath } from './path'
1413
import { spawn } from './spawn'
1514

@@ -86,24 +85,61 @@ export async function execBin(
8685
})
8786
}
8887

88+
/**
89+
* Options for the which function.
90+
*/
91+
export interface WhichOptions {
92+
/** If true, return all matches instead of just the first one. */
93+
all?: boolean | undefined
94+
/** If true, return null instead of throwing when no match is found. */
95+
nothrow?: boolean | undefined
96+
/** Path to search in. */
97+
path?: string | undefined
98+
/** Path separator character. */
99+
pathExt?: string | undefined
100+
/** Environment variables to use. */
101+
env?: Record<string, string | undefined> | undefined
102+
}
103+
104+
/**
105+
* Find an executable in the system PATH asynchronously.
106+
* Wrapper around the which package for lazy loading.
107+
*/
108+
export async function which(
109+
binName: string,
110+
options?: WhichOptions,
111+
): Promise<string | string[] | undefined> {
112+
return await getWhich()(binName, options)
113+
}
114+
115+
/**
116+
* Find an executable in the system PATH synchronously.
117+
* Wrapper around the which package for lazy loading.
118+
*/
119+
export function whichSync(
120+
binName: string,
121+
options?: WhichOptions,
122+
): string | string[] | undefined {
123+
return getWhich().sync(binName, options)
124+
}
125+
89126
/**
90127
* Find and resolve a binary in the system PATH asynchronously.
91-
* @template {import('which').Options} T
92128
* @throws {Error} If the binary is not found and nothrow is false.
93129
*/
94130
export async function whichBin(
95131
binName: string,
96-
options?: import('which').Options,
132+
options?: WhichOptions,
97133
): Promise<string | string[] | undefined> {
98134
const which = getWhich()
99135
// Default to nothrow: true if not specified to return undefined instead of throwing
100136
const opts = { nothrow: true, ...options }
101137
// Depending on options `which` may throw if `binName` is not found.
102138
// With nothrow: true, it returns null when `binName` is not found.
103-
const result = await which?.(binName, opts)
139+
const result = await which(binName, opts)
104140

105141
// When 'all: true' is specified, ensure we always return an array.
106-
if (options?.all) {
142+
if (opts?.all) {
107143
const paths = Array.isArray(result)
108144
? result
109145
: typeof result === 'string'
@@ -123,21 +159,20 @@ export async function whichBin(
123159

124160
/**
125161
* Find and resolve a binary in the system PATH synchronously.
126-
* @template {import('which').Options} T
127162
* @throws {Error} If the binary is not found and nothrow is false.
128163
*/
129164
export function whichBinSync(
130165
binName: string,
131-
options?: import('which').Options,
166+
options?: WhichOptions,
132167
): string | string[] | undefined {
133168
// Default to nothrow: true if not specified to return undefined instead of throwing
134169
const opts = { nothrow: true, ...options }
135170
// Depending on options `which` may throw if `binName` is not found.
136171
// With nothrow: true, it returns null when `binName` is not found.
137-
const result = getWhich()?.sync(binName, opts)
172+
const result = whichSync(binName, opts)
138173

139174
// When 'all: true' is specified, ensure we always return an array.
140-
if (getOwn(options, 'all')) {
175+
if (opts.all) {
141176
const paths = Array.isArray(result)
142177
? result
143178
: typeof result === 'string'
@@ -152,7 +187,7 @@ export function whichBinSync(
152187
return undefined
153188
}
154189

155-
return resolveBinPathSync(result)
190+
return resolveBinPathSync(result as string)
156191
}
157192

158193
/**

0 commit comments

Comments
 (0)