bun-nested-workspace 0.3.1 → 0.3.2
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/README.md +2 -2
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +1 -1
- package/dist/{workspace-BzA7ccrb.mjs → workspace-ChlHn5I8.mjs} +63 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ A package version patched by both the host and the nested repository is an error
|
|
|
113
113
|
### Lockfile
|
|
114
114
|
|
|
115
115
|
The nested lockfile entries replace the host entries, so the nested packages keep their versions.
|
|
116
|
-
When a replaced entry no longer satisfies a dependency of a host package, the host package keeps its previous resolution
|
|
116
|
+
When a replaced entry no longer satisfies a dependency of a host package, the host package keeps its previous resolution, and the nested packages keep theirs.
|
|
117
117
|
When neither satisfies the range, which Bun lockfiles occasionally contain, the dependency gets the highest satisfying version recorded in either lockfile.
|
|
118
118
|
Ranges are checked as `bun install` applies them: an override replaces the declared range, and an `npm:` alias requires the package it names.
|
|
119
119
|
`bun install` then resolves new dependencies of host packages and drops unused entries.
|
|
@@ -121,7 +121,7 @@ Ranges are checked as `bun install` applies them: an override replaces the decla
|
|
|
121
121
|
After the install, the sync compares the direct dependencies of host packages with the original host lockfile.
|
|
122
122
|
A dependency may only change to the version that the nested lockfile hoists to its top level, and only within the host range.
|
|
123
123
|
Any other change means either that the host lockfile did not pin the host dependencies, for example after an edit of a host `package.json` without `bun install`, or that the lockfile cannot record the host version next to the nested one.
|
|
124
|
-
The latter happens to a host workspace without a name, because Bun records workspace-specific versions under the workspace name; name the workspace or align its range with the nested version.
|
|
124
|
+
The latter happens to a host workspace other than the root without a name, because Bun records workspace-specific versions under the workspace name; name the workspace or align its range with the nested version.
|
|
125
125
|
|
|
126
126
|
Only `bun.lock` with `lockfileVersion` 1 or 2 is supported, because the lockfile format is internal to Bun.
|
|
127
127
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { a as syncNestedWorkspace, i as loadNestedWorkspace, n as checkNestedWorkspace, r as isInSync, t as BunInstallError, y as getErrorMessage } from "./workspace-
|
|
2
|
+
import { a as syncNestedWorkspace, i as loadNestedWorkspace, n as checkNestedWorkspace, r as isInSync, t as BunInstallError, y as getErrorMessage } from "./workspace-ChlHn5I8.mjs";
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
const usage = `Usage:
|
|
5
5
|
bun-nested-workspace [bun install options] Sync package.json and bun.lock, then run bun install
|
package/dist/index.d.mts
CHANGED
|
@@ -194,7 +194,9 @@ export declare function applyManifestToLockfile(lock: Lockfile, manifest: Packag
|
|
|
194
194
|
* A root entry overridden by the nested lockfile might not satisfy a dependency of a host package:
|
|
195
195
|
* such a dependency gets back its previous host resolution as a nested entry, so `bun install` keeps the host version
|
|
196
196
|
* instead of resolving the range again.
|
|
197
|
-
* A host
|
|
197
|
+
* A dependency of the host root package gets it back at the top level instead, as `keepHostRootResolutions` describes.
|
|
198
|
+
* A host workspace other than the root without a name cannot have nested entries,
|
|
199
|
+
* so `bun install` resolves its dependency again.
|
|
198
200
|
* When the previous host resolution does not satisfy the range either, which Bun lockfiles occasionally contain,
|
|
199
201
|
* the dependency gets the highest satisfying version recorded in either lockfile.
|
|
200
202
|
* Catalog dependencies are checked against the catalogs of the host lockfile, so apply the synced root fields
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as BunInstallError, d as applyManifestToLockfile, n as checkNestedWorkspace, g as diffManifests, o as findDirectDependencyMismatches, s as findOwnDependencyChanges, c as findTransitiveMismatches, l as findUncoveredWorkspaces, u as findWorkspaceMismatches, r as isInSync, i as loadNestedWorkspace, f as mergeLockfiles, p as parseLockfile, m as relocateLockfile, h as supportedLockfileVersions, _ as syncManifest, a as syncNestedWorkspace, v as syncedFields } from "./workspace-
|
|
1
|
+
export { t as BunInstallError, d as applyManifestToLockfile, n as checkNestedWorkspace, g as diffManifests, o as findDirectDependencyMismatches, s as findOwnDependencyChanges, c as findTransitiveMismatches, l as findUncoveredWorkspaces, u as findWorkspaceMismatches, r as isInSync, i as loadNestedWorkspace, f as mergeLockfiles, p as parseLockfile, m as relocateLockfile, h as supportedLockfileVersions, _ as syncManifest, a as syncNestedWorkspace, v as syncedFields } from "./workspace-ChlHn5I8.mjs";
|
|
@@ -557,7 +557,9 @@ function applyManifestToLockfile(lock, manifest) {
|
|
|
557
557
|
* A root entry overridden by the nested lockfile might not satisfy a dependency of a host package:
|
|
558
558
|
* such a dependency gets back its previous host resolution as a nested entry, so `bun install` keeps the host version
|
|
559
559
|
* instead of resolving the range again.
|
|
560
|
-
* A host
|
|
560
|
+
* A dependency of the host root package gets it back at the top level instead, as `keepHostRootResolutions` describes.
|
|
561
|
+
* A host workspace other than the root without a name cannot have nested entries,
|
|
562
|
+
* so `bun install` resolves its dependency again.
|
|
561
563
|
* When the previous host resolution does not satisfy the range either, which Bun lockfiles occasionally contain,
|
|
562
564
|
* the dependency gets the highest satisfying version recorded in either lockfile.
|
|
563
565
|
* Catalog dependencies are checked against the catalogs of the host lockfile, so apply the synced root fields
|
|
@@ -571,16 +573,16 @@ function mergeLockfiles(lock, nestedLock, dir) {
|
|
|
571
573
|
...nestedLock.packages
|
|
572
574
|
};
|
|
573
575
|
const hostWorkspaces = Object.entries(lock.workspaces).filter(([workspacePath]) => !isNestedPath(workspacePath, dir));
|
|
574
|
-
|
|
576
|
+
if (lock.workspaces[""]) keepHostRootResolutions(lock, nestedLock, packages);
|
|
577
|
+
const dependents = [...hostWorkspaces.flatMap(([workspacePath, workspace]) => workspacePath && workspace.name ? [{
|
|
575
578
|
key: workspace.name,
|
|
576
579
|
dependencies: getWorkspaceDependencies(workspace)
|
|
577
|
-
})
|
|
580
|
+
}] : []), ...Object.keys(packages).map((key) => ({
|
|
578
581
|
key,
|
|
579
582
|
dependencies: getPackageDependencies(packages[key])
|
|
580
583
|
}))];
|
|
581
584
|
for (let index = 0; index < dependents.length; index++) {
|
|
582
585
|
const { key, dependencies } = dependents[index];
|
|
583
|
-
if (key === void 0) continue;
|
|
584
586
|
for (const [dependency, specifier] of Object.entries(dependencies)) {
|
|
585
587
|
const requirement = getRequirement(lock, dependency, specifier);
|
|
586
588
|
const resolved = resolveDependencyLockKey(key, dependency, packages);
|
|
@@ -606,6 +608,63 @@ function mergeLockfiles(lock, nestedLock, dir) {
|
|
|
606
608
|
packages
|
|
607
609
|
};
|
|
608
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Gives the dependencies of the host root package back their previous host resolutions where top-level nested
|
|
613
|
+
* entries do not satisfy them.
|
|
614
|
+
*
|
|
615
|
+
* Bun resolves the dependencies of the root package at the top level only, so placing the host resolution under the
|
|
616
|
+
* root name does not pin the root dependency: the host resolution returns to the top level with its host chain instead.
|
|
617
|
+
* Then every dependency of a nested workspace or package that no longer resolves to its nested entry or a copy of it,
|
|
618
|
+
* such as one that resolved the replaced entry, gets a copy of its nested entry under the dependent,
|
|
619
|
+
* so the copied entries keep their whole nested dependency trees.
|
|
620
|
+
*/
|
|
621
|
+
function keepHostRootResolutions(lock, nestedLock, packages) {
|
|
622
|
+
const replaced = /* @__PURE__ */ new Set();
|
|
623
|
+
for (const [dependency, specifier] of Object.entries(getWorkspaceDependencies(lock.workspaces[""]))) {
|
|
624
|
+
const requirement = getRequirement(lock, dependency, specifier);
|
|
625
|
+
const nestedEntry = Object.hasOwn(nestedLock.packages, dependency) ? nestedLock.packages[dependency] : void 0;
|
|
626
|
+
if (!requirement || !nestedEntry || satisfies(nestedEntry, requirement)) continue;
|
|
627
|
+
const previous = Object.hasOwn(lock.packages, dependency) ? lock.packages[dependency] : void 0;
|
|
628
|
+
const replacement = previous && satisfies(previous, requirement) ? previous : findSatisfyingEntry([nestedLock.packages, lock.packages], requirement);
|
|
629
|
+
if (!replacement) continue;
|
|
630
|
+
replaced.add(dependency);
|
|
631
|
+
const prefix = `${dependency}/`;
|
|
632
|
+
for (const key of Object.keys(packages)) if (key.startsWith(prefix)) delete packages[key];
|
|
633
|
+
packages[dependency] = replacement;
|
|
634
|
+
if (replacement === previous) {
|
|
635
|
+
for (const [key, entry] of Object.entries(lock.packages)) if (key.startsWith(prefix)) packages[key] = entry;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (!replaced.size) return;
|
|
639
|
+
const nestedKeys = new Map(Object.keys(nestedLock.packages).filter((key) => !replaced.has(splitPackageKey(key)[0])).map((key) => [key, key]));
|
|
640
|
+
const queue = [...Object.values(nestedLock.workspaces).flatMap((workspace) => workspace.name ? [{
|
|
641
|
+
key: workspace.name,
|
|
642
|
+
nestedKey: workspace.name,
|
|
643
|
+
dependencies: getWorkspaceDependencies(workspace)
|
|
644
|
+
}] : []), ...[...nestedKeys.keys()].map((key) => ({
|
|
645
|
+
key,
|
|
646
|
+
nestedKey: key,
|
|
647
|
+
dependencies: getPackageDependencies(nestedLock.packages[key])
|
|
648
|
+
}))];
|
|
649
|
+
for (let index = 0; index < queue.length; index++) {
|
|
650
|
+
const { key, nestedKey, dependencies } = queue[index];
|
|
651
|
+
for (const dependency of Object.keys(dependencies)) {
|
|
652
|
+
const expected = resolveDependencyLockKey(nestedKey, dependency, nestedLock.packages);
|
|
653
|
+
if (expected === void 0) continue;
|
|
654
|
+
const actual = resolveDependencyLockKey(key, dependency, packages);
|
|
655
|
+
if (actual !== void 0 && nestedKeys.get(actual) === expected) continue;
|
|
656
|
+
const entry = nestedLock.packages[expected];
|
|
657
|
+
const pinnedKey = `${key}/${dependency}`;
|
|
658
|
+
packages[pinnedKey] = entry;
|
|
659
|
+
nestedKeys.set(pinnedKey, expected);
|
|
660
|
+
queue.push({
|
|
661
|
+
key: pinnedKey,
|
|
662
|
+
nestedKey: expected,
|
|
663
|
+
dependencies: getPackageDependencies(entry)
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
609
668
|
/** Returns the installed dependencies declared by a lockfile workspace. */
|
|
610
669
|
function getWorkspaceDependencies(workspace) {
|
|
611
670
|
return {
|
package/package.json
CHANGED