-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
PnpLooseLinker.ts
86 lines (69 loc) Β· 2.98 KB
/
PnpLooseLinker.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
86
import {LinkOptions, structUtils} from '@yarnpkg/core';
import {VirtualFS, ppath, Filename} from '@yarnpkg/fslib';
import {ZipOpenFS} from '@yarnpkg/libzip';
import {NodeModulesPackageNode, buildNodeModulesTree} from '@yarnpkg/nm';
import {PnpInstaller, PnpLinker} from '@yarnpkg/plugin-pnp';
import {PnpSettings, makeRuntimeApi, DependencyTarget} from '@yarnpkg/pnp';
export class PnpLooseLinker extends PnpLinker {
protected mode = `loose`;
makeInstaller(opts: LinkOptions) {
return new PnpLooseInstaller(opts);
}
}
class PnpLooseInstaller extends PnpInstaller {
protected mode = `loose`;
async transformPnpSettings(pnpSettings: PnpSettings) {
const defaultFsLayer = new VirtualFS({
baseFs: new ZipOpenFS({
maxOpenFiles: 80,
readOnlyArchives: true,
}),
});
const pnp = makeRuntimeApi(pnpSettings, this.opts.project.cwd, defaultFsLayer);
const {tree, errors} = buildNodeModulesTree(pnp, {pnpifyFs: false, project: this.opts.project});
if (!tree) {
for (const {messageName, text} of errors)
this.opts.report.reportError(messageName, text);
return;
}
const fallbackPool = new Map<string, DependencyTarget>();
pnpSettings.fallbackPool = fallbackPool;
const registerFallback = (name: string, entry: NodeModulesPackageNode) => {
const locator = structUtils.parseLocator(entry.locator);
const identStr = structUtils.stringifyIdent(locator);
if (identStr === name) {
fallbackPool.set(name, locator.reference);
} else {
fallbackPool.set(name, [identStr, locator.reference]);
}
};
const root = ppath.join(this.opts.project.cwd, Filename.nodeModules);
const entry = tree.get(root);
// If there's no root junction point, it means that there are no dependencies to add to the fallback pool
if (typeof entry === `undefined`)
return;
if (`target` in entry)
throw new Error(`Assertion failed: Expected the root junction point to be a directory`);
for (const childName of entry.dirList) {
const childP = ppath.join(root, childName);
const child = tree.get(childP);
if (typeof child === `undefined`)
throw new Error(`Assertion failed: Expected the child to have been registered`);
if (`target` in child) {
registerFallback(childName, child);
} else {
for (const subChildName of child.dirList) {
const subChildP = ppath.join(childP, subChildName);
const subChild = tree.get(subChildP);
if (typeof subChild === `undefined`)
throw new Error(`Assertion failed: Expected the subchild to have been registered`);
if (`target` in subChild) {
registerFallback(`${childName}/${subChildName}`, subChild);
} else {
throw new Error(`Assertion failed: Expected the leaf junction to be a package`);
}
}
}
}
}
}