/
index.ts
57 lines (53 loc) · 1.55 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import path from 'path'
import { DependencyManifest, PackageBin } from '@pnpm/types'
import fastGlob from 'fast-glob'
import isSubdir from 'is-subdir'
export interface Command {
name: string
path: string
}
export default async function binify (manifest: DependencyManifest, pkgPath: string): Promise<Command[]> {
if (manifest.bin) {
return commandsFromBin(manifest.bin, manifest.name, pkgPath)
}
if (manifest.directories?.bin) {
const binDir = path.join(pkgPath, manifest.directories.bin)
const files = await findFiles(binDir)
return files.map((file) => ({
name: path.basename(file),
path: path.join(binDir, file),
}))
}
return []
}
async function findFiles (dir: string): Promise<string[]> {
try {
return await fastGlob('**', {
cwd: dir,
onlyFiles: true,
followSymbolicLinks: false,
})
} catch (err: any) { // eslint-disable-line
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
throw err
}
return []
}
}
function commandsFromBin (bin: PackageBin, pkgName: string, pkgPath: string) {
if (typeof bin === 'string') {
return [
{
name: pkgName.startsWith('@') ? pkgName.slice(pkgName.indexOf('/') + 1) : pkgName,
path: path.join(pkgPath, bin),
},
]
}
return Object.keys(bin)
.filter((commandName) => encodeURIComponent(commandName) === commandName || commandName === '$')
.map((commandName) => ({
name: commandName,
path: path.join(pkgPath, bin[commandName]),
}))
.filter((cmd) => isSubdir(pkgPath, cmd.path))
}