-
-
Notifications
You must be signed in to change notification settings - Fork 933
/
extendProjectsWithTargetDirs.ts
32 lines (30 loc) · 1.59 KB
/
extendProjectsWithTargetDirs.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
import path from 'path'
import { Lockfile } from '@pnpm/lockfile-types'
import { depPathToFilename } from 'dependency-path'
import fromPairs from 'ramda/src/fromPairs'
type GetLocalLocations = (depPath: string, pkgName: string) => string[]
export function extendProjectsWithTargetDirs<T> (
projects: Array<T & { id: string }>,
lockfile: Lockfile,
ctx: {
virtualStoreDir: string
pkgLocationsByDepPath?: Record<string, string[]>
}
): Array<T & { id: string, stages: string[], targetDirs: string[] }> {
const getLocalLocations: GetLocalLocations = ctx.pkgLocationsByDepPath != null
? (depPath: string) => ctx.pkgLocationsByDepPath![depPath]
: (depPath: string, pkgName: string) => [path.join(ctx.virtualStoreDir, depPathToFilename(depPath), 'node_modules', pkgName)]
const projectsById: Record<string, T & { id: string, targetDirs: string[], stages?: string[] }> =
fromPairs(projects.map((project) => [project.id, { ...project, targetDirs: [] as string[] }]))
Object.entries(lockfile.packages ?? {})
.forEach(([depPath, pkg]) => {
if (pkg.resolution?.['type'] !== 'directory') return
const pkgId = pkg.id ?? depPath
const importerId = pkgId.replace(/^file:/, '')
if (projectsById[importerId] == null) return
const localLocations = getLocalLocations(depPath, pkg.name!)
projectsById[importerId].targetDirs.push(...localLocations)
projectsById[importerId].stages = ['preinstall', 'install', 'postinstall', 'prepare', 'prepublishOnly']
})
return Object.values(projectsById) as Array<T & { id: string, stages: string[], targetDirs: string[] }>
}