/
index.ts
85 lines (80 loc) · 2.89 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import path from 'path'
import pnpmExec from '@pnpm/exec'
import exportableManifest from '@pnpm/exportable-manifest'
import {
getLockfileImporterId,
ProjectSnapshot,
readWantedLockfile,
writeWantedLockfile,
} from '@pnpm/lockfile-file'
import { pruneSharedLockfile } from '@pnpm/prune-lockfile'
import readProjectManifest from '@pnpm/read-project-manifest'
import { DEPENDENCIES_FIELDS } from '@pnpm/types'
import fromPairs from 'ramda/src/fromPairs'
import renameOverwrite from 'rename-overwrite'
export default async function (lockfileDir: string, projectDir: string) {
const lockfile = await readWantedLockfile(lockfileDir, { ignoreIncompatible: false })
if (lockfile == null) {
throw new Error('no lockfile found')
}
const allImporters = lockfile.importers
lockfile.importers = {}
const baseImporterId = getLockfileImporterId(lockfileDir, projectDir)
for (const [importerId, importer] of Object.entries(allImporters)) {
if (importerId.startsWith(`${baseImporterId}/`)) {
const newImporterId = importerId.slice(baseImporterId.length + 1)
lockfile.importers[newImporterId] = projectSnapshotWithoutLinkedDeps(importer)
continue
}
if (importerId === baseImporterId) {
lockfile.importers['.'] = projectSnapshotWithoutLinkedDeps(importer)
}
}
const dedicatedLockfile = pruneSharedLockfile(lockfile)
await writeWantedLockfile(projectDir, dedicatedLockfile)
const modulesDir = path.join(projectDir, 'node_modules')
const tmp = path.join(projectDir, 'tmp_node_modules')
const tempModulesDir = path.join(projectDir, 'node_modules/.tmp')
let modulesRenamed = false
try {
await renameOverwrite(modulesDir, tmp)
await renameOverwrite(tmp, tempModulesDir)
modulesRenamed = true
} catch (err: any) { // eslint-disable-line
if (err['code'] !== 'ENOENT') throw err
}
const { manifest, writeProjectManifest } = await readProjectManifest(projectDir)
const publishManifest = await exportableManifest(projectDir, manifest)
await writeProjectManifest(publishManifest)
try {
await pnpmExec([
'install',
'--frozen-lockfile',
'--lockfile-dir=.',
'--lockfile-only',
'--filter=.',
'--no-link-workspace-packages',
], {
cwd: projectDir,
})
} finally {
if (modulesRenamed) {
await renameOverwrite(tempModulesDir, tmp)
await renameOverwrite(tmp, modulesDir)
}
await writeProjectManifest(manifest)
}
}
function projectSnapshotWithoutLinkedDeps (projectSnapshot: ProjectSnapshot) {
const newProjectSnapshot: ProjectSnapshot = {
specifiers: projectSnapshot.specifiers,
}
for (const depField of DEPENDENCIES_FIELDS) {
if (projectSnapshot[depField] == null) continue
newProjectSnapshot[depField] = fromPairs(
Object.entries(projectSnapshot[depField]!)
.filter(([depName, depVersion]) => !depVersion.startsWith('link:'))
)
}
return newProjectSnapshot
}