@teambit/dependency-resolver 1.0.1095 → 1.0.1097
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dependency-installer.d.ts +67 -2
- package/dist/dependency-installer.js +155 -1
- package/dist/dependency-installer.js.map +1 -1
- package/dist/dependency-linker.d.ts +23 -0
- package/dist/dependency-linker.js +82 -4
- package/dist/dependency-linker.js.map +1 -1
- package/dist/dependency-resolver-workspace-config.d.ts +5 -1
- package/dist/dependency-resolver-workspace-config.js.map +1 -1
- package/dist/dependency-resolver.main.runtime.d.ts +34 -0
- package/dist/dependency-resolver.main.runtime.js +80 -1
- package/dist/dependency-resolver.main.runtime.js.map +1 -1
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +13 -0
- package/dist/exceptions/index.js.map +1 -1
- package/dist/exceptions/self-hosted-virtual-store-transition.d.ts +16 -0
- package/dist/exceptions/self-hosted-virtual-store-transition.js +36 -0
- package/dist/exceptions/self-hosted-virtual-store-transition.js.map +1 -0
- package/dist/hoisted-resolution-bridge.d.ts +46 -0
- package/dist/hoisted-resolution-bridge.js +291 -0
- package/dist/hoisted-resolution-bridge.js.map +1 -0
- package/dist/hoisted-resolution-bridge.spec.d.ts +1 -0
- package/dist/hoisted-resolution-bridge.spec.js +64 -0
- package/dist/hoisted-resolution-bridge.spec.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/package-manager.d.ts +39 -0
- package/dist/package-manager.js.map +1 -1
- package/dist/{preview-1785883495880.js → preview-1786219819000.js} +2 -2
- package/exceptions/index.ts +1 -0
- package/exceptions/self-hosted-virtual-store-transition.ts +26 -0
- package/package.json +29 -28
|
@@ -5,3 +5,4 @@ export { MainAspectNotLinkable } from './main-aspect-not-linkable';
|
|
|
5
5
|
export { CoreAspectLinkError } from './core-aspect-link-error';
|
|
6
6
|
export { NonAspectCorePackageLinkError } from './non-aspect-core-package-link-error';
|
|
7
7
|
export { InvalidVersionWithPrefix } from './invalid-version-with-prefix';
|
|
8
|
+
export { SelfHostedVirtualStoreTransition } from './self-hosted-virtual-store-transition';
|
package/dist/exceptions/index.js
CHANGED
|
@@ -45,6 +45,12 @@ Object.defineProperty(exports, "RootDirNotDefined", {
|
|
|
45
45
|
return _rootDirNotDefined().RootDirNotDefined;
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
|
+
Object.defineProperty(exports, "SelfHostedVirtualStoreTransition", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _selfHostedVirtualStoreTransition().SelfHostedVirtualStoreTransition;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
48
54
|
function _packageManagerNotFound() {
|
|
49
55
|
const data = require("./package-manager-not-found");
|
|
50
56
|
_packageManagerNotFound = function () {
|
|
@@ -94,5 +100,12 @@ function _invalidVersionWithPrefix() {
|
|
|
94
100
|
};
|
|
95
101
|
return data;
|
|
96
102
|
}
|
|
103
|
+
function _selfHostedVirtualStoreTransition() {
|
|
104
|
+
const data = require("./self-hosted-virtual-store-transition");
|
|
105
|
+
_selfHostedVirtualStoreTransition = function () {
|
|
106
|
+
return data;
|
|
107
|
+
};
|
|
108
|
+
return data;
|
|
109
|
+
}
|
|
97
110
|
|
|
98
111
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_packageManagerNotFound","data","require","_rootDirNotDefined","_mainAspectNotInstallable","_mainAspectNotLinkable","_coreAspectLinkError","_nonAspectCorePackageLinkError","_invalidVersionWithPrefix"],"sources":["index.ts"],"sourcesContent":["export { PackageManagerNotFound } from './package-manager-not-found';\nexport { RootDirNotDefined } from './root-dir-not-defined';\nexport { MainAspectNotInstallable } from './main-aspect-not-installable';\nexport { MainAspectNotLinkable } from './main-aspect-not-linkable';\nexport { CoreAspectLinkError } from './core-aspect-link-error';\nexport { NonAspectCorePackageLinkError } from './non-aspect-core-package-link-error';\nexport { InvalidVersionWithPrefix } from './invalid-version-with-prefix';\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_packageManagerNotFound","data","require","_rootDirNotDefined","_mainAspectNotInstallable","_mainAspectNotLinkable","_coreAspectLinkError","_nonAspectCorePackageLinkError","_invalidVersionWithPrefix","_selfHostedVirtualStoreTransition"],"sources":["index.ts"],"sourcesContent":["export { PackageManagerNotFound } from './package-manager-not-found';\nexport { RootDirNotDefined } from './root-dir-not-defined';\nexport { MainAspectNotInstallable } from './main-aspect-not-installable';\nexport { MainAspectNotLinkable } from './main-aspect-not-linkable';\nexport { CoreAspectLinkError } from './core-aspect-link-error';\nexport { NonAspectCorePackageLinkError } from './non-aspect-core-package-link-error';\nexport { InvalidVersionWithPrefix } from './invalid-version-with-prefix';\nexport { SelfHostedVirtualStoreTransition } from './self-hosted-virtual-store-transition';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAAA,wBAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,uBAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAE,mBAAA;EAAA,MAAAF,IAAA,GAAAC,OAAA;EAAAC,kBAAA,YAAAA,CAAA;IAAA,OAAAF,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,0BAAA;EAAA,MAAAH,IAAA,GAAAC,OAAA;EAAAE,yBAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,uBAAA;EAAA,MAAAJ,IAAA,GAAAC,OAAA;EAAAG,sBAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAK,qBAAA;EAAA,MAAAL,IAAA,GAAAC,OAAA;EAAAI,oBAAA,YAAAA,CAAA;IAAA,OAAAL,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAM,+BAAA;EAAA,MAAAN,IAAA,GAAAC,OAAA;EAAAK,8BAAA,YAAAA,CAAA;IAAA,OAAAN,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAO,0BAAA;EAAA,MAAAP,IAAA,GAAAC,OAAA;EAAAM,yBAAA,YAAAA,CAAA;IAAA,OAAAP,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAQ,kCAAA;EAAA,MAAAR,IAAA,GAAAC,OAAA;EAAAO,iCAAA,YAAAA,CAAA;IAAA,OAAAR,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BitError } from '@teambit/bit-error';
|
|
2
|
+
/**
|
|
3
|
+
* Thrown before an install that would switch this workspace between the project-local virtual
|
|
4
|
+
* store (`node_modules/.pnpm`) and pnpm's global virtual store while the running bit itself is
|
|
5
|
+
* installed inside this workspace's `node_modules`.
|
|
6
|
+
*
|
|
7
|
+
* A layout switch rebuilds the workspace's injected component packages from source, which
|
|
8
|
+
* discards their compiled `dist` until the end-of-install compile restores it. A bit that runs
|
|
9
|
+
* from those very packages loses its own code mid-install and crashes before it can recompile,
|
|
10
|
+
* leaving `node_modules` unusable. Steady-state installs are safe in both layouts - they
|
|
11
|
+
* preserve the top-level package directories - so only the one-time transition has to be driven
|
|
12
|
+
* by a bit that lives outside this workspace.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SelfHostedVirtualStoreTransition extends BitError {
|
|
15
|
+
constructor(workspacePath: string, enablingGlobalVirtualStore: boolean);
|
|
16
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SelfHostedVirtualStoreTransition = void 0;
|
|
7
|
+
function _bitError() {
|
|
8
|
+
const data = require("@teambit/bit-error");
|
|
9
|
+
_bitError = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Thrown before an install that would switch this workspace between the project-local virtual
|
|
16
|
+
* store (`node_modules/.pnpm`) and pnpm's global virtual store while the running bit itself is
|
|
17
|
+
* installed inside this workspace's `node_modules`.
|
|
18
|
+
*
|
|
19
|
+
* A layout switch rebuilds the workspace's injected component packages from source, which
|
|
20
|
+
* discards their compiled `dist` until the end-of-install compile restores it. A bit that runs
|
|
21
|
+
* from those very packages loses its own code mid-install and crashes before it can recompile,
|
|
22
|
+
* leaving `node_modules` unusable. Steady-state installs are safe in both layouts - they
|
|
23
|
+
* preserve the top-level package directories - so only the one-time transition has to be driven
|
|
24
|
+
* by a bit that lives outside this workspace.
|
|
25
|
+
*/
|
|
26
|
+
class SelfHostedVirtualStoreTransition extends _bitError().BitError {
|
|
27
|
+
constructor(workspacePath, enablingGlobalVirtualStore) {
|
|
28
|
+
const direction = enablingGlobalVirtualStore ? 'from the project-local virtual store to the global virtual store' : 'from the global virtual store back to the project-local virtual store';
|
|
29
|
+
super(`this install would switch "${workspacePath}" ${direction}, but the running bit is itself installed inside this workspace's node_modules.
|
|
30
|
+
The switch rebuilds this workspace's component packages from source, which would delete the running bit's compiled code mid-install and leave node_modules broken.
|
|
31
|
+
Run this one install with a bit installation that lives outside the workspace (e.g. a bvm-installed bit). Subsequent installs from within the workspace are safe in either layout.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.SelfHostedVirtualStoreTransition = SelfHostedVirtualStoreTransition;
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=self-hosted-virtual-store-transition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_bitError","data","require","SelfHostedVirtualStoreTransition","BitError","constructor","workspacePath","enablingGlobalVirtualStore","direction","exports"],"sources":["self-hosted-virtual-store-transition.ts"],"sourcesContent":["import { BitError } from '@teambit/bit-error';\n\n/**\n * Thrown before an install that would switch this workspace between the project-local virtual\n * store (`node_modules/.pnpm`) and pnpm's global virtual store while the running bit itself is\n * installed inside this workspace's `node_modules`.\n *\n * A layout switch rebuilds the workspace's injected component packages from source, which\n * discards their compiled `dist` until the end-of-install compile restores it. A bit that runs\n * from those very packages loses its own code mid-install and crashes before it can recompile,\n * leaving `node_modules` unusable. Steady-state installs are safe in both layouts - they\n * preserve the top-level package directories - so only the one-time transition has to be driven\n * by a bit that lives outside this workspace.\n */\nexport class SelfHostedVirtualStoreTransition extends BitError {\n constructor(workspacePath: string, enablingGlobalVirtualStore: boolean) {\n const direction = enablingGlobalVirtualStore\n ? 'from the project-local virtual store to the global virtual store'\n : 'from the global virtual store back to the project-local virtual store';\n super(\n `this install would switch \"${workspacePath}\" ${direction}, but the running bit is itself installed inside this workspace's node_modules.\nThe switch rebuilds this workspace's component packages from source, which would delete the running bit's compiled code mid-install and leave node_modules broken.\nRun this one install with a bit installation that lives outside the workspace (e.g. a bvm-installed bit). Subsequent installs from within the workspace are safe in either layout.`\n );\n }\n}\n"],"mappings":";;;;;;AAAA,SAAAA,UAAA;EAAA,MAAAC,IAAA,GAAAC,OAAA;EAAAF,SAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,gCAAgC,SAASC,oBAAQ,CAAC;EAC7DC,WAAWA,CAACC,aAAqB,EAAEC,0BAAmC,EAAE;IACtE,MAAMC,SAAS,GAAGD,0BAA0B,GACxC,kEAAkE,GAClE,uEAAuE;IAC3E,KAAK,CACH,8BAA8BD,aAAa,KAAKE,SAAS;AAC/D;AACA,mLACI,CAAC;EACH;AACF;AAACC,OAAA,CAAAN,gCAAA,GAAAA,gCAAA","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `virtualStoreDir` pnpm recorded in a `node_modules/.modules.yaml`, or undefined when the
|
|
3
|
+
* manifest records none.
|
|
4
|
+
*
|
|
5
|
+
* Current pnpm writes this manifest as JSON (YAML 1.2 being a superset of it), so the structured
|
|
6
|
+
* read is a plain `JSON.parse` - no dependency, and correct for every value the writer can emit.
|
|
7
|
+
* Older versions wrote block YAML, which the line match handles. A full YAML parser is
|
|
8
|
+
* deliberately avoided: this runs in `bootstrap`, before any command does its work, and parsing
|
|
9
|
+
* the whole manifest costs ~40ms on this repo's own 415KB one against ~0.2ms for the line match
|
|
10
|
+
* (the manifest carries the entire hoisted alias map, so it grows with the dependency graph).
|
|
11
|
+
* Taking a package dependency here would also make the earliest, least recoverable step of CLI
|
|
12
|
+
* startup depend on module resolution - the very thing this module exists to repair.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseRecordedVirtualStoreDir(modulesManifest: string): string | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the workspace's last install used pnpm's global virtual store, judged by the
|
|
17
|
+
* `virtualStoreDir` the engine records in `node_modules/.modules.yaml`: `.pnpm` (or any path
|
|
18
|
+
* inside the workspace) means project-local; a path escaping the workspace means the global
|
|
19
|
+
* store. No manifest or no recorded value reads as project-local - a workspace that never
|
|
20
|
+
* installed under the global store has nothing to bridge.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Platform-safe path containment: `path.relative` is case-insensitive on Windows (where the
|
|
24
|
+
* filesystem is) and case-sensitive on posix, which a bare `startsWith` prefix check gets wrong
|
|
25
|
+
* for drive-letter casing differences between realpath results and given spellings. Equality
|
|
26
|
+
* counts as inside - every caller asks "does this path escape that root", and a path equal to
|
|
27
|
+
* the root has not escaped it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isPathInsideOrEqual(child: string, parent: string): boolean;
|
|
30
|
+
export declare function isGlobalVirtualStoreLayout(workspaceRoot: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Bridge the *running installation's* own hoisted directory when that installation is itself
|
|
33
|
+
* linked to the global virtual store - its packages then live in store slots and their phantom
|
|
34
|
+
* requires need the installation's private hoist exactly like a workspace's do. Judged by the
|
|
35
|
+
* same `.modules.yaml` record, read at the installation root. A conventional project-local
|
|
36
|
+
* installation (bvm's default) reads project-local and stays unbridged, so nothing changes for
|
|
37
|
+
* it or for the processes it spawns.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ensureSelfInstallationBridge(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Put the given root's hoisted directory on the resolution path of this process and its children.
|
|
42
|
+
* Idempotent; a no-op when the hoisted directory doesn't exist. Callers decide *whether* the
|
|
43
|
+
* root needs the bridge ({@link isGlobalVirtualStoreLayout} for the pre-aspect gate, the
|
|
44
|
+
* dependency-resolver's own config after an install).
|
|
45
|
+
*/
|
|
46
|
+
export declare function ensureHoistedDependencyResolution(workspaceRoot: string): void;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ensureHoistedDependencyResolution = ensureHoistedDependencyResolution;
|
|
7
|
+
exports.ensureSelfInstallationBridge = ensureSelfInstallationBridge;
|
|
8
|
+
exports.isGlobalVirtualStoreLayout = isGlobalVirtualStoreLayout;
|
|
9
|
+
exports.isPathInsideOrEqual = isPathInsideOrEqual;
|
|
10
|
+
exports.parseRecordedVirtualStoreDir = parseRecordedVirtualStoreDir;
|
|
11
|
+
function fs() {
|
|
12
|
+
const data = _interopRequireWildcard(require("fs"));
|
|
13
|
+
fs = function () {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
function path() {
|
|
19
|
+
const data = _interopRequireWildcard(require("path"));
|
|
20
|
+
path = function () {
|
|
21
|
+
return data;
|
|
22
|
+
};
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
function _url() {
|
|
26
|
+
const data = require("url");
|
|
27
|
+
_url = function () {
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
30
|
+
return data;
|
|
31
|
+
}
|
|
32
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
33
|
+
/**
|
|
34
|
+
* Make a workspace's privately hoisted dependencies resolvable from pnpm's global virtual store.
|
|
35
|
+
*
|
|
36
|
+
* Under the project-local virtual store, a package in `node_modules/.pnpm` resolves anything it
|
|
37
|
+
* requires without declaring it by walking *up* into the workspace - the hoisted
|
|
38
|
+
* `node_modules/.pnpm/node_modules` first, then the workspace root. Under the global virtual
|
|
39
|
+
* store the package lives in a store shared with every other project on the machine, with no
|
|
40
|
+
* workspace above it, so every such require fails.
|
|
41
|
+
*
|
|
42
|
+
* This covers phantom dependencies generally, not one class of them. Bit's core aspects are the
|
|
43
|
+
* case that motivated it - `@teambit/*` is required by every published env and aspect without
|
|
44
|
+
* being declared, because it has to be the single copy from the running installation - but any
|
|
45
|
+
* under-declared package in the graph resolves the same way, which is why the whole hoisted
|
|
46
|
+
* directory goes on the path rather than a hand-picked list.
|
|
47
|
+
*
|
|
48
|
+
* pnpm's answer for this layout is `NODE_PATH` pointing at the hoisted directory, which stays
|
|
49
|
+
* project-local under the global virtual store. pnpm sets it in the command shims it writes, but
|
|
50
|
+
* bit runs from bvm rather than through a shim and loads aspects in its own process, so it has to
|
|
51
|
+
* do this itself. `NODE_PATH` only covers CommonJS; an ESM loader (adapted from pnpm's
|
|
52
|
+
* `@pnpm/plugin-esm-node-path`, MIT) handles the ESM side, registered both in-process via
|
|
53
|
+
* `module.register` and for child processes via a `NODE_OPTIONS --import` flag.
|
|
54
|
+
*
|
|
55
|
+
* Two call sites, and both matter:
|
|
56
|
+
* - `bootstrap()` in `@teambit/bit`, before any aspect loads, gated on the layout the last
|
|
57
|
+
* install recorded ({@link isGlobalVirtualStoreLayout}). It deep-requires this module's dist
|
|
58
|
+
* file directly so CLI startup never pays for the dependency-resolver barrel.
|
|
59
|
+
* - the install flow, right after the package manager finishes: the first install that switches
|
|
60
|
+
* a workspace onto the global virtual store runs with `bootstrap`'s gate still reflecting the
|
|
61
|
+
* old layout, yet the same process goes on to reload envs and compile from store slots. The
|
|
62
|
+
* installer re-applies the bridge the moment the target layout is known.
|
|
63
|
+
*
|
|
64
|
+
* Everything here is idempotent, so calling it again is always safe: the `NODE_PATH` entry is
|
|
65
|
+
* added once, the ESM loader re-registers only when the entry set grows (the previous, subset
|
|
66
|
+
* loader keeps chaining harmlessly), and the process's own `NODE_OPTIONS` flag is replaced
|
|
67
|
+
* rather than stacked.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Source of the registered ESM loader, with the resolution entries injected at registration time.
|
|
72
|
+
* The entries cannot be read from `NODE_PATH` inside the loader: on modern Node the hooks run on
|
|
73
|
+
* a separate thread whose `process.env` is a snapshot taken at registration, so late additions -
|
|
74
|
+
* an install switching the workspace onto the global virtual store mid-process - would never be
|
|
75
|
+
* seen. Injecting the list makes each registration self-contained; when the set grows, a new
|
|
76
|
+
* loader is registered and chains after the previous (whose entries are a subset - harmless).
|
|
77
|
+
*/
|
|
78
|
+
const esmNodePathLoaderSource = dirs => `
|
|
79
|
+
import { createRequire } from 'node:module'
|
|
80
|
+
import { pathToFileURL } from 'node:url'
|
|
81
|
+
|
|
82
|
+
const extraNodePaths = ${JSON.stringify(dirs)}
|
|
83
|
+
|
|
84
|
+
export async function resolve (specifier, context, defaultResolve) {
|
|
85
|
+
try {
|
|
86
|
+
return await defaultResolve(specifier, context, defaultResolve)
|
|
87
|
+
} catch (originalError) {
|
|
88
|
+
// Only bare specifiers can come from the hoisted directory; the rest are already anchored.
|
|
89
|
+
// Windows absolute (drive-letter) and UNC paths are path specifiers too.
|
|
90
|
+
if (
|
|
91
|
+
specifier.startsWith('.') ||
|
|
92
|
+
specifier.startsWith('/') ||
|
|
93
|
+
specifier.startsWith('node:') ||
|
|
94
|
+
specifier.startsWith('\\\\') ||
|
|
95
|
+
/^[a-zA-Z]:[\\\\/]/.test(specifier)
|
|
96
|
+
) {
|
|
97
|
+
throw originalError
|
|
98
|
+
}
|
|
99
|
+
// createRequire anchored inside the entry searches the entry itself: Node skips appending
|
|
100
|
+
// /node_modules to a directory already named node_modules, and the parent step re-yields it
|
|
101
|
+
// (.pnpm -> .pnpm/node_modules). Exact for the hoisted-dir entries this loader exists for;
|
|
102
|
+
// an entry not named node_modules would be searched one level deeper than CommonJS NODE_PATH
|
|
103
|
+
// does - those entries are already covered by the CommonJS side and are not ours to fix.
|
|
104
|
+
for (const basePath of extraNodePaths) {
|
|
105
|
+
try {
|
|
106
|
+
const require = createRequire(pathToFileURL(basePath + '/').href)
|
|
107
|
+
return { url: pathToFileURL(require.resolve(specifier)).href, shortCircuit: true }
|
|
108
|
+
} catch {}
|
|
109
|
+
}
|
|
110
|
+
throw originalError
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
`;
|
|
114
|
+
const registeredEsmDirs = new Set();
|
|
115
|
+
let lastImportFlag;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The `virtualStoreDir` pnpm recorded in a `node_modules/.modules.yaml`, or undefined when the
|
|
119
|
+
* manifest records none.
|
|
120
|
+
*
|
|
121
|
+
* Current pnpm writes this manifest as JSON (YAML 1.2 being a superset of it), so the structured
|
|
122
|
+
* read is a plain `JSON.parse` - no dependency, and correct for every value the writer can emit.
|
|
123
|
+
* Older versions wrote block YAML, which the line match handles. A full YAML parser is
|
|
124
|
+
* deliberately avoided: this runs in `bootstrap`, before any command does its work, and parsing
|
|
125
|
+
* the whole manifest costs ~40ms on this repo's own 415KB one against ~0.2ms for the line match
|
|
126
|
+
* (the manifest carries the entire hoisted alias map, so it grows with the dependency graph).
|
|
127
|
+
* Taking a package dependency here would also make the earliest, least recoverable step of CLI
|
|
128
|
+
* startup depend on module resolution - the very thing this module exists to repair.
|
|
129
|
+
*/
|
|
130
|
+
function parseRecordedVirtualStoreDir(modulesManifest) {
|
|
131
|
+
try {
|
|
132
|
+
const parsed = JSON.parse(modulesManifest);
|
|
133
|
+
return typeof parsed.virtualStoreDir === 'string' ? parsed.virtualStoreDir : undefined;
|
|
134
|
+
} catch {
|
|
135
|
+
// not JSON - a block-YAML manifest from an older pnpm
|
|
136
|
+
}
|
|
137
|
+
return modulesManifest.match(/^\s*"?virtualStoreDir"?:\s*"?([^"\n]+?)"?,?\s*$/m)?.[1];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Whether the workspace's last install used pnpm's global virtual store, judged by the
|
|
142
|
+
* `virtualStoreDir` the engine records in `node_modules/.modules.yaml`: `.pnpm` (or any path
|
|
143
|
+
* inside the workspace) means project-local; a path escaping the workspace means the global
|
|
144
|
+
* store. No manifest or no recorded value reads as project-local - a workspace that never
|
|
145
|
+
* installed under the global store has nothing to bridge.
|
|
146
|
+
*/
|
|
147
|
+
/**
|
|
148
|
+
* Platform-safe path containment: `path.relative` is case-insensitive on Windows (where the
|
|
149
|
+
* filesystem is) and case-sensitive on posix, which a bare `startsWith` prefix check gets wrong
|
|
150
|
+
* for drive-letter casing differences between realpath results and given spellings. Equality
|
|
151
|
+
* counts as inside - every caller asks "does this path escape that root", and a path equal to
|
|
152
|
+
* the root has not escaped it.
|
|
153
|
+
*/
|
|
154
|
+
function isPathInsideOrEqual(child, parent) {
|
|
155
|
+
const rel = path().relative(parent, child);
|
|
156
|
+
// component-aware traversal check: a child legitimately named `..foo` also starts with `..`
|
|
157
|
+
return !path().isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${path().sep}`);
|
|
158
|
+
}
|
|
159
|
+
function isGlobalVirtualStoreLayout(workspaceRoot) {
|
|
160
|
+
let modulesManifest;
|
|
161
|
+
try {
|
|
162
|
+
modulesManifest = fs().readFileSync(path().join(workspaceRoot, 'node_modules', '.modules.yaml'), 'utf8');
|
|
163
|
+
} catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
const virtualStoreDir = parseRecordedVirtualStoreDir(modulesManifest);
|
|
167
|
+
if (!virtualStoreDir) return false;
|
|
168
|
+
let workspaceRealpath = workspaceRoot;
|
|
169
|
+
try {
|
|
170
|
+
workspaceRealpath = fs().realpathSync(workspaceRoot);
|
|
171
|
+
} catch {
|
|
172
|
+
// fall back to the given spelling
|
|
173
|
+
}
|
|
174
|
+
const resolved = path().resolve(workspaceRealpath, 'node_modules', virtualStoreDir);
|
|
175
|
+
let storeRealpath = resolved;
|
|
176
|
+
try {
|
|
177
|
+
storeRealpath = fs().realpathSync(resolved);
|
|
178
|
+
} catch {
|
|
179
|
+
// dangling recorded dir - judge by the lexical resolution
|
|
180
|
+
}
|
|
181
|
+
return !isPathInsideOrEqual(storeRealpath, workspaceRealpath);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* The root of the installation this module runs from: the nearest ancestor that owns a
|
|
186
|
+
* `node_modules/.modules.yaml`. For a bvm-installed bit that is the bvm version directory; for a
|
|
187
|
+
* workspace-provided bit it is the workspace.
|
|
188
|
+
*
|
|
189
|
+
* Two candidate starting points, because Node realpaths module filenames: under the global
|
|
190
|
+
* virtual store this module's `__dirname` is the *store slot* - a dead end with no
|
|
191
|
+
* `.modules.yaml` and no physical path back to the installation. The entry script's
|
|
192
|
+
* `process.argv[1]` is the path *as invoked*, unresolved through symlinks, so for a store-linked
|
|
193
|
+
* installation it still sits inside the installation tree. `__dirname` remains the fallback for
|
|
194
|
+
* setups that invoke bit through a resolved path (and for the copy-shaped installations where it
|
|
195
|
+
* works fine). `undefined` when neither leads to an installation (e.g. running from source).
|
|
196
|
+
*/
|
|
197
|
+
function selfInstallationRoot() {
|
|
198
|
+
const candidates = [process.argv[1], __dirname].filter(Boolean);
|
|
199
|
+
for (const candidate of candidates) {
|
|
200
|
+
let dir = path().dirname(path().resolve(candidate));
|
|
201
|
+
for (;;) {
|
|
202
|
+
if (fs().existsSync(path().join(dir, 'node_modules', '.modules.yaml'))) return dir;
|
|
203
|
+
const parent = path().dirname(dir);
|
|
204
|
+
if (parent === dir) break;
|
|
205
|
+
dir = parent;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Bridge the *running installation's* own hoisted directory when that installation is itself
|
|
213
|
+
* linked to the global virtual store - its packages then live in store slots and their phantom
|
|
214
|
+
* requires need the installation's private hoist exactly like a workspace's do. Judged by the
|
|
215
|
+
* same `.modules.yaml` record, read at the installation root. A conventional project-local
|
|
216
|
+
* installation (bvm's default) reads project-local and stays unbridged, so nothing changes for
|
|
217
|
+
* it or for the processes it spawns.
|
|
218
|
+
*/
|
|
219
|
+
function ensureSelfInstallationBridge() {
|
|
220
|
+
const installationRoot = selfInstallationRoot();
|
|
221
|
+
if (!installationRoot) return;
|
|
222
|
+
if (!isGlobalVirtualStoreLayout(installationRoot)) return;
|
|
223
|
+
ensureHoistedDependencyResolution(installationRoot);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Put the given root's hoisted directory on the resolution path of this process and its children.
|
|
228
|
+
* Idempotent; a no-op when the hoisted directory doesn't exist. Callers decide *whether* the
|
|
229
|
+
* root needs the bridge ({@link isGlobalVirtualStoreLayout} for the pre-aspect gate, the
|
|
230
|
+
* dependency-resolver's own config after an install).
|
|
231
|
+
*/
|
|
232
|
+
function ensureHoistedDependencyResolution(workspaceRoot) {
|
|
233
|
+
const hoistedDir = path().join(workspaceRoot, 'node_modules', '.pnpm', 'node_modules');
|
|
234
|
+
if (!fs().existsSync(hoistedDir)) return;
|
|
235
|
+
const existing = process.env.NODE_PATH;
|
|
236
|
+
if (!existing?.split(path().delimiter).includes(hoistedDir)) {
|
|
237
|
+
process.env.NODE_PATH = existing ? `${hoistedDir}${path().delimiter}${existing}` : hoistedDir;
|
|
238
|
+
// `NODE_PATH` is read once when the module system initializes, so a later assignment only
|
|
239
|
+
// takes effect after re-deriving the global paths.
|
|
240
|
+
require('module')._initPaths();
|
|
241
|
+
}
|
|
242
|
+
registerEsmNodePathLoader();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* The ESM half of {@link ensureHoistedDependencyResolution}.
|
|
247
|
+
*
|
|
248
|
+
* Node consults `NODE_PATH` only for CommonJS; ESM resolution ignores it entirely. Bit supports
|
|
249
|
+
* ESM components, so without this an ESM package in the store cannot reach the hoisted directory
|
|
250
|
+
* at all and the CommonJS half would only cover part of the problem.
|
|
251
|
+
*
|
|
252
|
+
* Registered two ways, because both matter:
|
|
253
|
+
* - `module.register` for bit's own process, which is where aspects and envs are loaded.
|
|
254
|
+
* - `NODE_OPTIONS`, so the processes bit spawns - env build steps, app servers, test workers -
|
|
255
|
+
* inherit it. They resolve their own dependencies and hit the same wall.
|
|
256
|
+
*
|
|
257
|
+
* The loader is inlined as a data URL rather than taken as a dependency so there is no file to
|
|
258
|
+
* ship and no install step to depend on. `module.register` needs Node 20.6, so this is skipped
|
|
259
|
+
* on older runtimes - the CommonJS half still applies there.
|
|
260
|
+
*/
|
|
261
|
+
function registerEsmNodePathLoader() {
|
|
262
|
+
const nodeModule = require('module');
|
|
263
|
+
if (typeof nodeModule.register !== 'function') return;
|
|
264
|
+
// mirror the CommonJS side exactly: every current NODE_PATH entry participates
|
|
265
|
+
const dirs = (process.env.NODE_PATH || '').split(path().delimiter).filter(Boolean);
|
|
266
|
+
if (!dirs.length) return;
|
|
267
|
+
if (lastImportFlag && dirs.every(dir => registeredEsmDirs.has(dir))) return;
|
|
268
|
+
const loaderUrl = `data:text/javascript,${encodeURIComponent(esmNodePathLoaderSource(dirs))}`;
|
|
269
|
+
const parentUrl = (0, _url().pathToFileURL)(path().join(process.cwd(), '/')).href;
|
|
270
|
+
try {
|
|
271
|
+
nodeModule.register(loaderUrl, parentUrl);
|
|
272
|
+
} catch {
|
|
273
|
+
// A runtime that rejects the loader must not take the whole CLI down with it - the CommonJS
|
|
274
|
+
// half of the workaround is unaffected, and only ESM packages relying on hoisting are lost.
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
dirs.forEach(dir => registeredEsmDirs.add(dir));
|
|
278
|
+
const registration = `import{register}from'node:module';register(${JSON.stringify(loaderUrl)},${JSON.stringify(parentUrl)});`;
|
|
279
|
+
const importFlag = `--import=data:text/javascript,${encodeURIComponent(registration)}`;
|
|
280
|
+
// children get one flag carrying the full current set: replace our previous flag rather than
|
|
281
|
+
// stacking loaders, and match our own flag exactly - a user's `--require ts-node/register`
|
|
282
|
+
// in NODE_OPTIONS must not suppress the loader's propagation
|
|
283
|
+
if (lastImportFlag && process.env.NODE_OPTIONS?.includes(lastImportFlag)) {
|
|
284
|
+
process.env.NODE_OPTIONS = process.env.NODE_OPTIONS.replace(lastImportFlag, importFlag);
|
|
285
|
+
} else if (!process.env.NODE_OPTIONS?.includes(importFlag)) {
|
|
286
|
+
process.env.NODE_OPTIONS = process.env.NODE_OPTIONS ? `${process.env.NODE_OPTIONS} ${importFlag}` : importFlag;
|
|
287
|
+
}
|
|
288
|
+
lastImportFlag = importFlag;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
//# sourceMappingURL=hoisted-resolution-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fs","data","_interopRequireWildcard","require","path","_url","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","esmNodePathLoaderSource","dirs","JSON","stringify","registeredEsmDirs","Set","lastImportFlag","parseRecordedVirtualStoreDir","modulesManifest","parsed","parse","virtualStoreDir","undefined","match","isPathInsideOrEqual","child","parent","rel","relative","isAbsolute","startsWith","sep","isGlobalVirtualStoreLayout","workspaceRoot","readFileSync","join","workspaceRealpath","realpathSync","resolved","resolve","storeRealpath","selfInstallationRoot","candidates","process","argv","__dirname","filter","Boolean","candidate","dir","dirname","existsSync","ensureSelfInstallationBridge","installationRoot","ensureHoistedDependencyResolution","hoistedDir","existing","env","NODE_PATH","split","delimiter","includes","_initPaths","registerEsmNodePathLoader","nodeModule","register","length","every","loaderUrl","encodeURIComponent","parentUrl","pathToFileURL","cwd","href","forEach","add","registration","importFlag","NODE_OPTIONS","replace"],"sources":["hoisted-resolution-bridge.ts"],"sourcesContent":["/**\n * Make a workspace's privately hoisted dependencies resolvable from pnpm's global virtual store.\n *\n * Under the project-local virtual store, a package in `node_modules/.pnpm` resolves anything it\n * requires without declaring it by walking *up* into the workspace - the hoisted\n * `node_modules/.pnpm/node_modules` first, then the workspace root. Under the global virtual\n * store the package lives in a store shared with every other project on the machine, with no\n * workspace above it, so every such require fails.\n *\n * This covers phantom dependencies generally, not one class of them. Bit's core aspects are the\n * case that motivated it - `@teambit/*` is required by every published env and aspect without\n * being declared, because it has to be the single copy from the running installation - but any\n * under-declared package in the graph resolves the same way, which is why the whole hoisted\n * directory goes on the path rather than a hand-picked list.\n *\n * pnpm's answer for this layout is `NODE_PATH` pointing at the hoisted directory, which stays\n * project-local under the global virtual store. pnpm sets it in the command shims it writes, but\n * bit runs from bvm rather than through a shim and loads aspects in its own process, so it has to\n * do this itself. `NODE_PATH` only covers CommonJS; an ESM loader (adapted from pnpm's\n * `@pnpm/plugin-esm-node-path`, MIT) handles the ESM side, registered both in-process via\n * `module.register` and for child processes via a `NODE_OPTIONS --import` flag.\n *\n * Two call sites, and both matter:\n * - `bootstrap()` in `@teambit/bit`, before any aspect loads, gated on the layout the last\n * install recorded ({@link isGlobalVirtualStoreLayout}). It deep-requires this module's dist\n * file directly so CLI startup never pays for the dependency-resolver barrel.\n * - the install flow, right after the package manager finishes: the first install that switches\n * a workspace onto the global virtual store runs with `bootstrap`'s gate still reflecting the\n * old layout, yet the same process goes on to reload envs and compile from store slots. The\n * installer re-applies the bridge the moment the target layout is known.\n *\n * Everything here is idempotent, so calling it again is always safe: the `NODE_PATH` entry is\n * added once, the ESM loader re-registers only when the entry set grows (the previous, subset\n * loader keeps chaining harmlessly), and the process's own `NODE_OPTIONS` flag is replaced\n * rather than stacked.\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { pathToFileURL } from 'url';\n\n/**\n * Source of the registered ESM loader, with the resolution entries injected at registration time.\n * The entries cannot be read from `NODE_PATH` inside the loader: on modern Node the hooks run on\n * a separate thread whose `process.env` is a snapshot taken at registration, so late additions -\n * an install switching the workspace onto the global virtual store mid-process - would never be\n * seen. Injecting the list makes each registration self-contained; when the set grows, a new\n * loader is registered and chains after the previous (whose entries are a subset - harmless).\n */\nconst esmNodePathLoaderSource = (dirs: string[]) => `\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\nconst extraNodePaths = ${JSON.stringify(dirs)}\n\nexport async function resolve (specifier, context, defaultResolve) {\n try {\n return await defaultResolve(specifier, context, defaultResolve)\n } catch (originalError) {\n // Only bare specifiers can come from the hoisted directory; the rest are already anchored.\n // Windows absolute (drive-letter) and UNC paths are path specifiers too.\n if (\n specifier.startsWith('.') ||\n specifier.startsWith('/') ||\n specifier.startsWith('node:') ||\n specifier.startsWith('\\\\\\\\') ||\n /^[a-zA-Z]:[\\\\\\\\/]/.test(specifier)\n ) {\n throw originalError\n }\n // createRequire anchored inside the entry searches the entry itself: Node skips appending\n // /node_modules to a directory already named node_modules, and the parent step re-yields it\n // (.pnpm -> .pnpm/node_modules). Exact for the hoisted-dir entries this loader exists for;\n // an entry not named node_modules would be searched one level deeper than CommonJS NODE_PATH\n // does - those entries are already covered by the CommonJS side and are not ours to fix.\n for (const basePath of extraNodePaths) {\n try {\n const require = createRequire(pathToFileURL(basePath + '/').href)\n return { url: pathToFileURL(require.resolve(specifier)).href, shortCircuit: true }\n } catch {}\n }\n throw originalError\n }\n}\n`;\n\nconst registeredEsmDirs = new Set<string>();\nlet lastImportFlag: string | undefined;\n\n/**\n * The `virtualStoreDir` pnpm recorded in a `node_modules/.modules.yaml`, or undefined when the\n * manifest records none.\n *\n * Current pnpm writes this manifest as JSON (YAML 1.2 being a superset of it), so the structured\n * read is a plain `JSON.parse` - no dependency, and correct for every value the writer can emit.\n * Older versions wrote block YAML, which the line match handles. A full YAML parser is\n * deliberately avoided: this runs in `bootstrap`, before any command does its work, and parsing\n * the whole manifest costs ~40ms on this repo's own 415KB one against ~0.2ms for the line match\n * (the manifest carries the entire hoisted alias map, so it grows with the dependency graph).\n * Taking a package dependency here would also make the earliest, least recoverable step of CLI\n * startup depend on module resolution - the very thing this module exists to repair.\n */\nexport function parseRecordedVirtualStoreDir(modulesManifest: string): string | undefined {\n try {\n const parsed = JSON.parse(modulesManifest) as { virtualStoreDir?: unknown };\n return typeof parsed.virtualStoreDir === 'string' ? parsed.virtualStoreDir : undefined;\n } catch {\n // not JSON - a block-YAML manifest from an older pnpm\n }\n return modulesManifest.match(/^\\s*\"?virtualStoreDir\"?:\\s*\"?([^\"\\n]+?)\"?,?\\s*$/m)?.[1];\n}\n\n/**\n * Whether the workspace's last install used pnpm's global virtual store, judged by the\n * `virtualStoreDir` the engine records in `node_modules/.modules.yaml`: `.pnpm` (or any path\n * inside the workspace) means project-local; a path escaping the workspace means the global\n * store. No manifest or no recorded value reads as project-local - a workspace that never\n * installed under the global store has nothing to bridge.\n */\n/**\n * Platform-safe path containment: `path.relative` is case-insensitive on Windows (where the\n * filesystem is) and case-sensitive on posix, which a bare `startsWith` prefix check gets wrong\n * for drive-letter casing differences between realpath results and given spellings. Equality\n * counts as inside - every caller asks \"does this path escape that root\", and a path equal to\n * the root has not escaped it.\n */\nexport function isPathInsideOrEqual(child: string, parent: string): boolean {\n const rel = path.relative(parent, child);\n // component-aware traversal check: a child legitimately named `..foo` also starts with `..`\n return !path.isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${path.sep}`);\n}\n\nexport function isGlobalVirtualStoreLayout(workspaceRoot: string): boolean {\n let modulesManifest: string;\n try {\n modulesManifest = fs.readFileSync(path.join(workspaceRoot, 'node_modules', '.modules.yaml'), 'utf8');\n } catch {\n return false;\n }\n const virtualStoreDir = parseRecordedVirtualStoreDir(modulesManifest);\n if (!virtualStoreDir) return false;\n let workspaceRealpath = workspaceRoot;\n try {\n workspaceRealpath = fs.realpathSync(workspaceRoot);\n } catch {\n // fall back to the given spelling\n }\n const resolved = path.resolve(workspaceRealpath, 'node_modules', virtualStoreDir);\n let storeRealpath = resolved;\n try {\n storeRealpath = fs.realpathSync(resolved);\n } catch {\n // dangling recorded dir - judge by the lexical resolution\n }\n return !isPathInsideOrEqual(storeRealpath, workspaceRealpath);\n}\n\n/**\n * The root of the installation this module runs from: the nearest ancestor that owns a\n * `node_modules/.modules.yaml`. For a bvm-installed bit that is the bvm version directory; for a\n * workspace-provided bit it is the workspace.\n *\n * Two candidate starting points, because Node realpaths module filenames: under the global\n * virtual store this module's `__dirname` is the *store slot* - a dead end with no\n * `.modules.yaml` and no physical path back to the installation. The entry script's\n * `process.argv[1]` is the path *as invoked*, unresolved through symlinks, so for a store-linked\n * installation it still sits inside the installation tree. `__dirname` remains the fallback for\n * setups that invoke bit through a resolved path (and for the copy-shaped installations where it\n * works fine). `undefined` when neither leads to an installation (e.g. running from source).\n */\nfunction selfInstallationRoot(): string | undefined {\n const candidates = [process.argv[1], __dirname].filter(Boolean) as string[];\n for (const candidate of candidates) {\n let dir = path.dirname(path.resolve(candidate));\n for (;;) {\n if (fs.existsSync(path.join(dir, 'node_modules', '.modules.yaml'))) return dir;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n }\n return undefined;\n}\n\n/**\n * Bridge the *running installation's* own hoisted directory when that installation is itself\n * linked to the global virtual store - its packages then live in store slots and their phantom\n * requires need the installation's private hoist exactly like a workspace's do. Judged by the\n * same `.modules.yaml` record, read at the installation root. A conventional project-local\n * installation (bvm's default) reads project-local and stays unbridged, so nothing changes for\n * it or for the processes it spawns.\n */\nexport function ensureSelfInstallationBridge(): void {\n const installationRoot = selfInstallationRoot();\n if (!installationRoot) return;\n if (!isGlobalVirtualStoreLayout(installationRoot)) return;\n ensureHoistedDependencyResolution(installationRoot);\n}\n\n/**\n * Put the given root's hoisted directory on the resolution path of this process and its children.\n * Idempotent; a no-op when the hoisted directory doesn't exist. Callers decide *whether* the\n * root needs the bridge ({@link isGlobalVirtualStoreLayout} for the pre-aspect gate, the\n * dependency-resolver's own config after an install).\n */\nexport function ensureHoistedDependencyResolution(workspaceRoot: string): void {\n const hoistedDir = path.join(workspaceRoot, 'node_modules', '.pnpm', 'node_modules');\n if (!fs.existsSync(hoistedDir)) return;\n const existing = process.env.NODE_PATH;\n if (!existing?.split(path.delimiter).includes(hoistedDir)) {\n process.env.NODE_PATH = existing ? `${hoistedDir}${path.delimiter}${existing}` : hoistedDir;\n // `NODE_PATH` is read once when the module system initializes, so a later assignment only\n // takes effect after re-deriving the global paths.\n (require('module') as { _initPaths(): void })._initPaths();\n }\n registerEsmNodePathLoader();\n}\n\n/**\n * The ESM half of {@link ensureHoistedDependencyResolution}.\n *\n * Node consults `NODE_PATH` only for CommonJS; ESM resolution ignores it entirely. Bit supports\n * ESM components, so without this an ESM package in the store cannot reach the hoisted directory\n * at all and the CommonJS half would only cover part of the problem.\n *\n * Registered two ways, because both matter:\n * - `module.register` for bit's own process, which is where aspects and envs are loaded.\n * - `NODE_OPTIONS`, so the processes bit spawns - env build steps, app servers, test workers -\n * inherit it. They resolve their own dependencies and hit the same wall.\n *\n * The loader is inlined as a data URL rather than taken as a dependency so there is no file to\n * ship and no install step to depend on. `module.register` needs Node 20.6, so this is skipped\n * on older runtimes - the CommonJS half still applies there.\n */\nfunction registerEsmNodePathLoader(): void {\n const nodeModule = require('module') as {\n register?: (specifier: string, parentURL: string) => void;\n };\n if (typeof nodeModule.register !== 'function') return;\n // mirror the CommonJS side exactly: every current NODE_PATH entry participates\n const dirs = (process.env.NODE_PATH || '').split(path.delimiter).filter(Boolean);\n if (!dirs.length) return;\n if (lastImportFlag && dirs.every((dir) => registeredEsmDirs.has(dir))) return;\n const loaderUrl = `data:text/javascript,${encodeURIComponent(esmNodePathLoaderSource(dirs))}`;\n const parentUrl = pathToFileURL(path.join(process.cwd(), '/')).href;\n try {\n nodeModule.register(loaderUrl, parentUrl);\n } catch {\n // A runtime that rejects the loader must not take the whole CLI down with it - the CommonJS\n // half of the workaround is unaffected, and only ESM packages relying on hoisting are lost.\n return;\n }\n dirs.forEach((dir) => registeredEsmDirs.add(dir));\n const registration = `import{register}from'node:module';register(${JSON.stringify(loaderUrl)},${JSON.stringify(parentUrl)});`;\n const importFlag = `--import=data:text/javascript,${encodeURIComponent(registration)}`;\n // children get one flag carrying the full current set: replace our previous flag rather than\n // stacking loaders, and match our own flag exactly - a user's `--require ts-node/register`\n // in NODE_OPTIONS must not suppress the loader's propagation\n if (lastImportFlag && process.env.NODE_OPTIONS?.includes(lastImportFlag)) {\n process.env.NODE_OPTIONS = process.env.NODE_OPTIONS.replace(lastImportFlag, importFlag);\n } else if (!process.env.NODE_OPTIONS?.includes(importFlag)) {\n process.env.NODE_OPTIONS = process.env.NODE_OPTIONS\n ? `${process.env.NODE_OPTIONS} ${importFlag}`\n : importFlag;\n }\n lastImportFlag = importFlag;\n}\n"],"mappings":";;;;;;;;;;AAoCA,SAAAA,GAAA;EAAA,MAAAC,IAAA,GAAAC,uBAAA,CAAAC,OAAA;EAAAH,EAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,KAAA;EAAA,MAAAH,IAAA,GAAAC,uBAAA,CAAAC,OAAA;EAAAC,IAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAI,KAAA;EAAA,MAAAJ,IAAA,GAAAE,OAAA;EAAAE,IAAA,YAAAA,CAAA;IAAA,OAAAJ,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAAoC,SAAAC,wBAAAI,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAN,uBAAA,YAAAA,CAAAI,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAtCpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMkB,uBAAuB,GAAIC,IAAc,IAAK;AACpD;AACA;AACA;AACA,yBAAyBC,IAAI,CAACC,SAAS,CAACF,IAAI,CAAC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,MAAMG,iBAAiB,GAAG,IAAIC,GAAG,CAAS,CAAC;AAC3C,IAAIC,cAAkC;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,4BAA4BA,CAACC,eAAuB,EAAsB;EACxF,IAAI;IACF,MAAMC,MAAM,GAAGP,IAAI,CAACQ,KAAK,CAACF,eAAe,CAAkC;IAC3E,OAAO,OAAOC,MAAM,CAACE,eAAe,KAAK,QAAQ,GAAGF,MAAM,CAACE,eAAe,GAAGC,SAAS;EACxF,CAAC,CAAC,MAAM;IACN;EAAA;EAEF,OAAOJ,eAAe,CAACK,KAAK,CAAC,kDAAkD,CAAC,GAAG,CAAC,CAAC;AACvF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,mBAAmBA,CAACC,KAAa,EAAEC,MAAc,EAAW;EAC1E,MAAMC,GAAG,GAAGtC,IAAI,CAAD,CAAC,CAACuC,QAAQ,CAACF,MAAM,EAAED,KAAK,CAAC;EACxC;EACA,OAAO,CAACpC,IAAI,CAAD,CAAC,CAACwC,UAAU,CAACF,GAAG,CAAC,IAAIA,GAAG,KAAK,IAAI,IAAI,CAACA,GAAG,CAACG,UAAU,CAAC,KAAKzC,IAAI,CAAD,CAAC,CAAC0C,GAAG,EAAE,CAAC;AAClF;AAEO,SAAS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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _chai() {
|
|
4
|
+
const data = require("chai");
|
|
5
|
+
_chai = function () {
|
|
6
|
+
return data;
|
|
7
|
+
};
|
|
8
|
+
return data;
|
|
9
|
+
}
|
|
10
|
+
function _path() {
|
|
11
|
+
const data = _interopRequireDefault(require("path"));
|
|
12
|
+
_path = function () {
|
|
13
|
+
return data;
|
|
14
|
+
};
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
function _hoistedResolutionBridge() {
|
|
18
|
+
const data = require("./hoisted-resolution-bridge");
|
|
19
|
+
_hoistedResolutionBridge = function () {
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
25
|
+
describe('isPathInsideOrEqual()', () => {
|
|
26
|
+
const base = _path().default.resolve('/base');
|
|
27
|
+
it('should count a descendant as inside', () => {
|
|
28
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().isPathInsideOrEqual)(_path().default.join(base, 'child'), base)).to.eq(true);
|
|
29
|
+
});
|
|
30
|
+
it('should count a descendant whose name starts with dots as inside', () => {
|
|
31
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().isPathInsideOrEqual)(_path().default.join(base, '..foo', 'child'), base)).to.eq(true);
|
|
32
|
+
});
|
|
33
|
+
it('should count the parent itself as inside', () => {
|
|
34
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().isPathInsideOrEqual)(base, base)).to.eq(true);
|
|
35
|
+
});
|
|
36
|
+
it('should count an ancestor as outside', () => {
|
|
37
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().isPathInsideOrEqual)(_path().default.dirname(base), base)).to.eq(false);
|
|
38
|
+
});
|
|
39
|
+
it('should count a sibling as outside', () => {
|
|
40
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().isPathInsideOrEqual)(_path().default.join(_path().default.dirname(base), 'sibling'), base)).to.eq(false);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('parseRecordedVirtualStoreDir()', () => {
|
|
44
|
+
it('should read the JSON manifest current pnpm writes', () => {
|
|
45
|
+
const manifest = JSON.stringify({
|
|
46
|
+
hoistedDependencies: {},
|
|
47
|
+
virtualStoreDir: '../../store/v11/links'
|
|
48
|
+
}, null, 2);
|
|
49
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().parseRecordedVirtualStoreDir)(manifest)).to.eq('../../store/v11/links');
|
|
50
|
+
});
|
|
51
|
+
it('should read a block-YAML manifest from an older pnpm', () => {
|
|
52
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().parseRecordedVirtualStoreDir)('layoutVersion: 5\nvirtualStoreDir: .pnpm\n')).to.eq('.pnpm');
|
|
53
|
+
});
|
|
54
|
+
it('should not confuse virtualStoreDirMaxLength for the store dir', () => {
|
|
55
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().parseRecordedVirtualStoreDir)('virtualStoreDirMaxLength: 120\n')).to.eq(undefined);
|
|
56
|
+
});
|
|
57
|
+
it('should return undefined when the manifest records no store dir', () => {
|
|
58
|
+
(0, _chai().expect)((0, _hoistedResolutionBridge().parseRecordedVirtualStoreDir)(JSON.stringify({
|
|
59
|
+
layoutVersion: 5
|
|
60
|
+
}))).to.eq(undefined);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=hoisted-resolution-bridge.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_chai","data","require","_path","_interopRequireDefault","_hoistedResolutionBridge","e","__esModule","default","describe","base","path","resolve","it","expect","isPathInsideOrEqual","join","to","eq","dirname","manifest","JSON","stringify","hoistedDependencies","virtualStoreDir","parseRecordedVirtualStoreDir","undefined","layoutVersion"],"sources":["hoisted-resolution-bridge.spec.ts"],"sourcesContent":["import { expect } from 'chai';\nimport path from 'path';\nimport { isPathInsideOrEqual, parseRecordedVirtualStoreDir } from './hoisted-resolution-bridge';\n\ndescribe('isPathInsideOrEqual()', () => {\n const base = path.resolve('/base');\n it('should count a descendant as inside', () => {\n expect(isPathInsideOrEqual(path.join(base, 'child'), base)).to.eq(true);\n });\n it('should count a descendant whose name starts with dots as inside', () => {\n expect(isPathInsideOrEqual(path.join(base, '..foo', 'child'), base)).to.eq(true);\n });\n it('should count the parent itself as inside', () => {\n expect(isPathInsideOrEqual(base, base)).to.eq(true);\n });\n it('should count an ancestor as outside', () => {\n expect(isPathInsideOrEqual(path.dirname(base), base)).to.eq(false);\n });\n it('should count a sibling as outside', () => {\n expect(isPathInsideOrEqual(path.join(path.dirname(base), 'sibling'), base)).to.eq(false);\n });\n});\n\ndescribe('parseRecordedVirtualStoreDir()', () => {\n it('should read the JSON manifest current pnpm writes', () => {\n const manifest = JSON.stringify({ hoistedDependencies: {}, virtualStoreDir: '../../store/v11/links' }, null, 2);\n expect(parseRecordedVirtualStoreDir(manifest)).to.eq('../../store/v11/links');\n });\n it('should read a block-YAML manifest from an older pnpm', () => {\n expect(parseRecordedVirtualStoreDir('layoutVersion: 5\\nvirtualStoreDir: .pnpm\\n')).to.eq('.pnpm');\n });\n it('should not confuse virtualStoreDirMaxLength for the store dir', () => {\n expect(parseRecordedVirtualStoreDir('virtualStoreDirMaxLength: 120\\n')).to.eq(undefined);\n });\n it('should return undefined when the manifest records no store dir', () => {\n expect(parseRecordedVirtualStoreDir(JSON.stringify({ layoutVersion: 5 }))).to.eq(undefined);\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type { UpdatedComponent } from './apply-updates';
|
|
|
3
3
|
export type { RawComponentState, ComponentsManifestsMap, RegistriesMap } from './types';
|
|
4
4
|
export { WorkspaceManifest, ComponentManifest } from './manifest';
|
|
5
5
|
export type { CreateFromComponentsOptions, ManifestDependenciesObject } from './manifest';
|
|
6
|
-
export type { InstallationContext, PackageImportMethod, PackageManager, PackageManagerInstallOptions, PackageManagerResolveRemoteVersionOptions, ResolvedPackageVersion, CalcDepsGraphOptions, CalcDepsGraphForComponentOptions, ComponentIdByPkgName, } from './package-manager';
|
|
6
|
+
export type { InstallationContext, PackageImportMethod, PackageExtension, PackageManager, PackageManagerInstallOptions, PackageManagerResolveRemoteVersionOptions, ResolvedPackageVersion, CalcDepsGraphOptions, CalcDepsGraphForComponentOptions, ComponentIdByPkgName, } from './package-manager';
|
|
7
7
|
export type { DependencyResolverWorkspaceConfig, NodeLinker, ComponentRangePrefix, } from './dependency-resolver-workspace-config';
|
|
8
8
|
export type { DependencyResolverMain, DependencyResolverVariantConfig, MergedOutdatedPkg, } from './dependency-resolver.main.runtime';
|
|
9
9
|
export { NPM_REGISTRY, BIT_CLOUD_REGISTRY } from './dependency-resolver.main.runtime';
|
|
@@ -22,4 +22,5 @@ export { extendWithComponentsFromDir } from './extend-with-components-from-dir';
|
|
|
22
22
|
export { isRange } from './manifest/deduping/hoist-dependencies';
|
|
23
23
|
export type { DependencyEnv } from './dependency-env';
|
|
24
24
|
export { DetectorHook, DependencyDetector, FileContext } from './detector-hook';
|
|
25
|
+
export { ensureHoistedDependencyResolution, ensureSelfInstallationBridge, isGlobalVirtualStoreLayout } from './hoisted-resolution-bridge';
|
|
25
26
|
export { DependencyResolverAspect as default, DependencyResolverAspect };
|
package/dist/index.js
CHANGED
|
@@ -123,12 +123,30 @@ Object.defineProperty(exports, "default", {
|
|
|
123
123
|
return _dependencyResolver().DependencyResolverAspect;
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
|
+
Object.defineProperty(exports, "ensureHoistedDependencyResolution", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
get: function () {
|
|
129
|
+
return _hoistedResolutionBridge().ensureHoistedDependencyResolution;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(exports, "ensureSelfInstallationBridge", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
get: function () {
|
|
135
|
+
return _hoistedResolutionBridge().ensureSelfInstallationBridge;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
126
138
|
Object.defineProperty(exports, "extendWithComponentsFromDir", {
|
|
127
139
|
enumerable: true,
|
|
128
140
|
get: function () {
|
|
129
141
|
return _extendWithComponentsFromDir().extendWithComponentsFromDir;
|
|
130
142
|
}
|
|
131
143
|
});
|
|
144
|
+
Object.defineProperty(exports, "isGlobalVirtualStoreLayout", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
get: function () {
|
|
147
|
+
return _hoistedResolutionBridge().isGlobalVirtualStoreLayout;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
132
150
|
Object.defineProperty(exports, "isRange", {
|
|
133
151
|
enumerable: true,
|
|
134
152
|
get: function () {
|
|
@@ -205,5 +223,12 @@ function _detectorHook() {
|
|
|
205
223
|
};
|
|
206
224
|
return data;
|
|
207
225
|
}
|
|
226
|
+
function _hoistedResolutionBridge() {
|
|
227
|
+
const data = require("./hoisted-resolution-bridge");
|
|
228
|
+
_hoistedResolutionBridge = function () {
|
|
229
|
+
return data;
|
|
230
|
+
};
|
|
231
|
+
return data;
|
|
232
|
+
}
|
|
208
233
|
|
|
209
234
|
//# sourceMappingURL=index.js.map
|