mirror of
https://github.com/oven-sh/bun
synced 2026-02-25 19:17:20 +01:00
Compare commits
14 Commits
ben/revert
...
dylan/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98bc0167d5 | ||
|
|
9d238abe4f | ||
|
|
68946504eb | ||
|
|
3eba5fa63b | ||
|
|
bbee0fb617 | ||
|
|
d2cef13f90 | ||
|
|
c24bbeb45d | ||
|
|
4a1c947c59 | ||
|
|
271af9074b | ||
|
|
5b0204f08f | ||
|
|
34170fb5de | ||
|
|
9ae235cc0e | ||
|
|
00343df755 | ||
|
|
cbbe8f6dea |
@@ -309,7 +309,6 @@ pub const BunxCommand = struct {
|
||||
defer requests_buf.deinit(ctx.allocator);
|
||||
const update_requests = UpdateRequest.parse(
|
||||
ctx.allocator,
|
||||
null,
|
||||
ctx.log,
|
||||
&.{opts.package_name},
|
||||
&requests_buf,
|
||||
|
||||
@@ -1293,7 +1293,6 @@ pub fn parseIntoBinaryLockfile(
|
||||
root: JSON.Expr,
|
||||
source: *const logger.Source,
|
||||
log: *logger.Log,
|
||||
manager: ?*PackageManager,
|
||||
) ParseError!void {
|
||||
lockfile.initEmpty(allocator);
|
||||
|
||||
@@ -1416,7 +1415,6 @@ pub fn parseIntoBinaryLockfile(
|
||||
version_sliced.slice,
|
||||
&version_sliced,
|
||||
log,
|
||||
manager,
|
||||
) orelse {
|
||||
try log.addError(source, value.loc, "Invalid override version");
|
||||
return error.InvalidOverridesObject;
|
||||
@@ -2084,7 +2082,6 @@ fn parseAppendDependencies(
|
||||
version_sliced.slice,
|
||||
&version_sliced,
|
||||
log,
|
||||
null,
|
||||
) orelse {
|
||||
try log.addError(source, value.loc, "Invalid dependency version");
|
||||
return error.InvalidDependencyVersion;
|
||||
|
||||
@@ -78,11 +78,11 @@ pub fn count(this: *const Dependency, buf: []const u8, comptime StringBuilder: t
|
||||
this.countWithDifferentBuffers(buf, buf, StringBuilder, builder);
|
||||
}
|
||||
|
||||
pub fn clone(this: *const Dependency, package_manager: *PackageManager, buf: []const u8, comptime StringBuilder: type, builder: StringBuilder) !Dependency {
|
||||
return this.cloneWithDifferentBuffers(package_manager, buf, buf, StringBuilder, builder);
|
||||
pub fn clone(this: *const Dependency, buf: []const u8, comptime StringBuilder: type, builder: StringBuilder) !Dependency {
|
||||
return this.cloneWithDifferentBuffers(buf, buf, StringBuilder, builder);
|
||||
}
|
||||
|
||||
pub fn cloneWithDifferentBuffers(this: *const Dependency, package_manager: *PackageManager, name_buf: []const u8, version_buf: []const u8, comptime StringBuilder: type, builder: StringBuilder) !Dependency {
|
||||
pub fn cloneWithDifferentBuffers(this: *const Dependency, name_buf: []const u8, version_buf: []const u8, comptime StringBuilder: type, builder: StringBuilder) !Dependency {
|
||||
const out_slice = builder.lockfile.buffers.string_bytes.items;
|
||||
const new_literal = builder.append(String, this.version.literal.slice(version_buf));
|
||||
const sliced = new_literal.sliced(out_slice);
|
||||
@@ -99,7 +99,6 @@ pub fn cloneWithDifferentBuffers(this: *const Dependency, package_manager: *Pack
|
||||
this.version.tag,
|
||||
&sliced,
|
||||
null,
|
||||
package_manager,
|
||||
) orelse Dependency.Version{},
|
||||
.behavior = this.behavior,
|
||||
};
|
||||
@@ -116,7 +115,6 @@ pub const Context = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
log: *logger.Log,
|
||||
buffer: []const u8,
|
||||
package_manager: ?*PackageManager,
|
||||
};
|
||||
|
||||
/// Get the name of the package as it should appear in a remote registry.
|
||||
@@ -430,7 +428,6 @@ pub const Version = struct {
|
||||
tag,
|
||||
sliced,
|
||||
ctx.log,
|
||||
ctx.package_manager,
|
||||
) orelse Dependency.Version.zeroed;
|
||||
}
|
||||
|
||||
@@ -856,10 +853,9 @@ pub inline fn parse(
|
||||
dependency: string,
|
||||
sliced: *const SlicedString,
|
||||
log: ?*logger.Log,
|
||||
manager: ?*PackageManager,
|
||||
) ?Version {
|
||||
const dep = std.mem.trimLeft(u8, dependency, " \t\n\r");
|
||||
return parseWithTag(allocator, alias, alias_hash, dep, Version.Tag.infer(dep), sliced, log, manager);
|
||||
return parseWithTag(allocator, alias, alias_hash, dep, Version.Tag.infer(dep), sliced, log);
|
||||
}
|
||||
|
||||
pub fn parseWithOptionalTag(
|
||||
@@ -870,7 +866,6 @@ pub fn parseWithOptionalTag(
|
||||
tag: ?Dependency.Version.Tag,
|
||||
sliced: *const SlicedString,
|
||||
log: ?*logger.Log,
|
||||
package_manager: ?*PackageManager,
|
||||
) ?Version {
|
||||
const dep = std.mem.trimLeft(u8, dependency, " \t\n\r");
|
||||
return parseWithTag(
|
||||
@@ -881,7 +876,6 @@ pub fn parseWithOptionalTag(
|
||||
tag orelse Version.Tag.infer(dep),
|
||||
sliced,
|
||||
log,
|
||||
package_manager,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -893,7 +887,6 @@ pub fn parseWithTag(
|
||||
tag: Dependency.Version.Tag,
|
||||
sliced: *const SlicedString,
|
||||
log_: ?*logger.Log,
|
||||
package_manager: ?*PackageManager,
|
||||
) ?Version {
|
||||
switch (tag) {
|
||||
.npm => {
|
||||
@@ -932,7 +925,6 @@ pub fn parseWithTag(
|
||||
|
||||
const version = Semver.Query.parse(
|
||||
allocator,
|
||||
input,
|
||||
sliced.sub(input),
|
||||
) catch |err| {
|
||||
switch (err) {
|
||||
@@ -952,16 +944,6 @@ pub fn parseWithTag(
|
||||
.tag = .npm,
|
||||
};
|
||||
|
||||
if (is_alias) {
|
||||
if (package_manager) |pm| {
|
||||
pm.known_npm_aliases.put(
|
||||
allocator,
|
||||
alias_hash.?,
|
||||
result,
|
||||
) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
.dist_tag => {
|
||||
@@ -1284,7 +1266,7 @@ pub fn fromJS(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS
|
||||
var log = logger.Log.init(allocator);
|
||||
const sliced = SlicedString.init(buf, name);
|
||||
|
||||
const dep: Version = Dependency.parse(allocator, SlicedString.init(buf, alias).value(), null, buf, &sliced, &log, null) orelse {
|
||||
const dep: Version = Dependency.parse(allocator, SlicedString.init(buf, alias).value(), null, buf, &sliced, &log) orelse {
|
||||
if (log.msgs.items.len > 0) {
|
||||
return globalThis.throwValue(log.toJS(globalThis, bun.default_allocator, "Failed to parse dependency"));
|
||||
}
|
||||
|
||||
@@ -2684,7 +2684,6 @@ pub const PackageManager = struct {
|
||||
task_queue: TaskDependencyQueue = .{},
|
||||
|
||||
manifests: PackageManifestMap = .{},
|
||||
folders: FolderResolution.Map = .{},
|
||||
git_repositories: RepositoryMap = .{},
|
||||
|
||||
network_dedupe_map: NetworkTask.DedupeMap = NetworkTask.DedupeMap.init(bun.default_allocator),
|
||||
@@ -2732,9 +2731,6 @@ pub const PackageManager = struct {
|
||||
|
||||
peer_dependencies: std.fifo.LinearFifo(DependencyID, .Dynamic) = std.fifo.LinearFifo(DependencyID, .Dynamic).init(default_allocator),
|
||||
|
||||
// name hash from alias package name -> aliased package dependency version info
|
||||
known_npm_aliases: NpmAliasMap = .{},
|
||||
|
||||
event_loop: JSC.AnyEventLoop,
|
||||
|
||||
// During `installPackages` we learn exactly what dependencies from --trust
|
||||
@@ -3273,7 +3269,7 @@ pub const PackageManager = struct {
|
||||
|
||||
builder.allocate() catch |err| return .{ .failure = err };
|
||||
|
||||
const dep = dummy.cloneWithDifferentBuffers(this, name, version_buf, @TypeOf(&builder), &builder) catch unreachable;
|
||||
const dep = dummy.cloneWithDifferentBuffers(name, version_buf, @TypeOf(&builder), &builder) catch unreachable;
|
||||
builder.clamp();
|
||||
const index = this.lockfile.buffers.dependencies.items.len;
|
||||
this.lockfile.buffers.dependencies.append(this.allocator, dep) catch unreachable;
|
||||
@@ -4276,7 +4272,7 @@ pub const PackageManager = struct {
|
||||
},
|
||||
},
|
||||
};
|
||||
switch (FolderResolution.getOrPut(.{ .cache_folder = npm_package_path }, dependency, ".", this)) {
|
||||
switch (FolderResolution.getOrPut(.{ .cache_folder = npm_package_path }, dependency, ".", this, this.lockfile)) {
|
||||
.new_package_id => |id| {
|
||||
this.enqueueDependencyList(this.lockfile.packages.items(.dependencies)[id]);
|
||||
return id;
|
||||
@@ -4316,7 +4312,6 @@ pub const PackageManager = struct {
|
||||
name_hash: PackageNameHash,
|
||||
name: String,
|
||||
dependency: *const Dependency,
|
||||
version: Dependency.Version,
|
||||
dependency_id: DependencyID,
|
||||
behavior: Behavior,
|
||||
manifest: *const Npm.PackageManifest,
|
||||
@@ -4324,17 +4319,9 @@ pub const PackageManager = struct {
|
||||
install_peer: bool,
|
||||
comptime successFn: SuccessFn,
|
||||
) !?ResolvedPackageResult {
|
||||
const should_update = this.to_update and
|
||||
// If updating, only update packages in the current workspace
|
||||
this.lockfile.isRootDependency(this, dependency_id) and
|
||||
// no need to do a look up if update requests are empty (`bun update` with no args)
|
||||
(this.update_requests.len == 0 or
|
||||
this.updating_packages.contains(dependency.name.slice(this.lockfile.buffers.string_bytes.items)));
|
||||
|
||||
// Was this package already allocated? Let's reuse the existing one.
|
||||
if (this.lockfile.getPackageID(
|
||||
name_hash,
|
||||
if (should_update) null else version,
|
||||
&.{
|
||||
.tag = .npm,
|
||||
.value = .{
|
||||
@@ -4356,7 +4343,6 @@ pub const PackageManager = struct {
|
||||
|
||||
// appendPackage sets the PackageID on the package
|
||||
const package = try this.lockfile.appendPackage(try Lockfile.Package.fromNPM(
|
||||
this,
|
||||
this.allocator,
|
||||
this.lockfile,
|
||||
this.log,
|
||||
@@ -4767,7 +4753,6 @@ pub const PackageManager = struct {
|
||||
name_hash,
|
||||
name,
|
||||
dependency,
|
||||
version,
|
||||
dependency_id,
|
||||
behavior,
|
||||
manifest,
|
||||
@@ -4797,7 +4782,7 @@ pub const PackageManager = struct {
|
||||
// .auto,
|
||||
// );
|
||||
};
|
||||
break :res FolderResolution.getOrPut(.{ .relative = .folder }, version, folder_path_abs, this);
|
||||
break :res FolderResolution.getOrPut(.{ .relative = .folder }, version, folder_path_abs, this, this.lockfile);
|
||||
}
|
||||
|
||||
// transitive folder dependencies do not have their dependencies resolved
|
||||
@@ -4860,7 +4845,7 @@ pub const PackageManager = struct {
|
||||
break :blk Path.joinAbsStringBuf(FileSystem.instance.top_level_dir, &buf2, &[_]string{workspace_path}, .auto);
|
||||
};
|
||||
|
||||
const res = FolderResolution.getOrPut(.{ .relative = .workspace }, version, workspace_path_u8, this);
|
||||
const res = FolderResolution.getOrPut(.{ .relative = .workspace }, version, workspace_path_u8, this, this.lockfile);
|
||||
|
||||
switch (res) {
|
||||
.err => |err| return err,
|
||||
@@ -4876,7 +4861,7 @@ pub const PackageManager = struct {
|
||||
}
|
||||
},
|
||||
.symlink => {
|
||||
const res = FolderResolution.getOrPut(.{ .global = try this.globalLinkDirPath() }, version, this.lockfile.str(&version.value.symlink), this);
|
||||
const res = FolderResolution.getOrPut(.{ .global = try this.globalLinkDirPath() }, version, this.lockfile.str(&version.value.symlink), this, this.lockfile);
|
||||
|
||||
switch (res) {
|
||||
.err => |err| return err,
|
||||
@@ -5188,29 +5173,6 @@ pub const PackageManager = struct {
|
||||
};
|
||||
|
||||
const version = version: {
|
||||
if (dependency.version.tag == .npm) {
|
||||
if (this.known_npm_aliases.get(name_hash)) |aliased| {
|
||||
const group = dependency.version.value.npm.version;
|
||||
const buf = this.lockfile.buffers.string_bytes.items;
|
||||
var curr_list: ?*const Semver.Query.List = &aliased.value.npm.version.head;
|
||||
while (curr_list) |queries| {
|
||||
var curr: ?*const Semver.Query = &queries.head;
|
||||
while (curr) |query| {
|
||||
if (group.satisfies(query.range.left.version, buf, buf) or group.satisfies(query.range.right.version, buf, buf)) {
|
||||
name = aliased.value.npm.name;
|
||||
name_hash = String.Builder.stringHash(this.lockfile.str(&name));
|
||||
break :version aliased;
|
||||
}
|
||||
curr = query.next;
|
||||
}
|
||||
curr_list = queries.next;
|
||||
}
|
||||
|
||||
// fallthrough. a package that matches the name of an alias but does not match
|
||||
// the version should be enqueued as a normal npm dependency, overrides allowed
|
||||
}
|
||||
}
|
||||
|
||||
// allow overriding all dependencies unless the dependency is coming directly from an alias, "npm:<this dep>"
|
||||
if (dependency.version.tag != .npm or !dependency.version.value.npm.is_alias and this.lockfile.hasOverrides()) {
|
||||
if (this.lockfile.overrides.get(name_hash)) |new| {
|
||||
@@ -5412,7 +5374,6 @@ pub const PackageManager = struct {
|
||||
name_hash,
|
||||
name,
|
||||
dependency,
|
||||
version,
|
||||
id,
|
||||
dependency.behavior,
|
||||
&loaded_manifest.?,
|
||||
@@ -5483,7 +5444,7 @@ pub const PackageManager = struct {
|
||||
};
|
||||
|
||||
// First: see if we already loaded the git package in-memory
|
||||
if (this.lockfile.getPackageID(name_hash, null, &res)) |pkg_id| {
|
||||
if (this.lockfile.getPackageID(name_hash, &res)) |pkg_id| {
|
||||
successFn(this, id, pkg_id);
|
||||
return;
|
||||
}
|
||||
@@ -5572,7 +5533,7 @@ pub const PackageManager = struct {
|
||||
};
|
||||
|
||||
// First: see if we already loaded the github package in-memory
|
||||
if (this.lockfile.getPackageID(name_hash, null, &res)) |pkg_id| {
|
||||
if (this.lockfile.getPackageID(name_hash, &res)) |pkg_id| {
|
||||
successFn(this, id, pkg_id);
|
||||
return;
|
||||
}
|
||||
@@ -5757,7 +5718,7 @@ pub const PackageManager = struct {
|
||||
};
|
||||
|
||||
// First: see if we already loaded the tarball package in-memory
|
||||
if (this.lockfile.getPackageID(name_hash, null, &res)) |pkg_id| {
|
||||
if (this.lockfile.getPackageID(name_hash, &res)) |pkg_id| {
|
||||
successFn(this, id, pkg_id);
|
||||
return;
|
||||
}
|
||||
@@ -10348,7 +10309,7 @@ pub const PackageManager = struct {
|
||||
|
||||
var array = Array{};
|
||||
|
||||
const update_requests = parseWithError(allocator, null, &log, all_positionals.items, &array, .add, false) catch {
|
||||
const update_requests = parseWithError(allocator, &log, all_positionals.items, &array, .add, false) catch {
|
||||
return globalThis.throwValue(log.toJS(globalThis, bun.default_allocator, "Failed to parse dependencies"));
|
||||
};
|
||||
if (update_requests.len == 0) return .undefined;
|
||||
@@ -10370,18 +10331,16 @@ pub const PackageManager = struct {
|
||||
|
||||
pub fn parse(
|
||||
allocator: std.mem.Allocator,
|
||||
pm: ?*PackageManager,
|
||||
log: *logger.Log,
|
||||
positionals: []const string,
|
||||
update_requests: *Array,
|
||||
subcommand: Subcommand,
|
||||
) []UpdateRequest {
|
||||
return parseWithError(allocator, pm, log, positionals, update_requests, subcommand, true) catch Global.crash();
|
||||
return parseWithError(allocator, log, positionals, update_requests, subcommand, true) catch Global.crash();
|
||||
}
|
||||
|
||||
fn parseWithError(
|
||||
allocator: std.mem.Allocator,
|
||||
pm: ?*PackageManager,
|
||||
log: *logger.Log,
|
||||
positionals: []const string,
|
||||
update_requests: *Array,
|
||||
@@ -10432,7 +10391,6 @@ pub const PackageManager = struct {
|
||||
null,
|
||||
&SlicedString.init(input, value),
|
||||
log,
|
||||
pm,
|
||||
) orelse {
|
||||
if (fatal) {
|
||||
Output.errGeneric("unrecognised dependency format: {s}", .{
|
||||
@@ -10455,7 +10413,6 @@ pub const PackageManager = struct {
|
||||
null,
|
||||
&SlicedString.init(input, input),
|
||||
log,
|
||||
pm,
|
||||
)) |ver| {
|
||||
alias = null;
|
||||
version = ver;
|
||||
@@ -10710,7 +10667,7 @@ pub const PackageManager = struct {
|
||||
const updates: []UpdateRequest = if (manager.subcommand == .@"patch-commit" or manager.subcommand == .patch)
|
||||
&[_]UpdateRequest{}
|
||||
else
|
||||
UpdateRequest.parse(ctx.allocator, manager, ctx.log, manager.options.positionals[1..], &update_requests, manager.subcommand);
|
||||
UpdateRequest.parse(ctx.allocator, ctx.log, manager.options.positionals[1..], &update_requests, manager.subcommand);
|
||||
try manager.updatePackageJSONAndInstallWithManagerWithUpdates(
|
||||
ctx,
|
||||
updates,
|
||||
@@ -14514,8 +14471,17 @@ pub const PackageManager = struct {
|
||||
&resolver,
|
||||
Features.main,
|
||||
);
|
||||
const mapping = try manager.lockfile.allocator.alloc(PackageID, maybe_root.dependencies.len);
|
||||
@memset(mapping, invalid_package_id);
|
||||
|
||||
try lockfile.packages.append(lockfile.allocator, maybe_root);
|
||||
|
||||
var dep_map = try std.ArrayList(DependencyID).initCapacity(manager.lockfile.allocator, maybe_root.dependencies.len);
|
||||
dep_map.appendNTimesAssumeCapacity(invalid_dependency_id, maybe_root.dependencies.len);
|
||||
|
||||
// only used for workspaces
|
||||
var pkg_map = try std.ArrayList(PackageID).initCapacity(manager.lockfile.allocator, manager.lockfile.workspace_paths.count() + 1);
|
||||
|
||||
// root is always 0
|
||||
pkg_map.appendAssumeCapacity(0);
|
||||
|
||||
manager.summary = try Package.Diff.generate(
|
||||
manager,
|
||||
@@ -14523,13 +14489,14 @@ pub const PackageManager = struct {
|
||||
manager.log,
|
||||
manager.lockfile,
|
||||
&lockfile,
|
||||
&root,
|
||||
&maybe_root,
|
||||
0,
|
||||
0,
|
||||
if (manager.to_update) manager.update_requests else null,
|
||||
mapping,
|
||||
&dep_map,
|
||||
&pkg_map,
|
||||
);
|
||||
|
||||
had_any_diffs = manager.summary.hasDiffs();
|
||||
had_any_diffs = manager.summary.hasDiffs() or manager.summary.satisfied_versions > 0;
|
||||
|
||||
if (!had_any_diffs) {
|
||||
// always grab latest scripts for root package
|
||||
@@ -14549,30 +14516,45 @@ pub const PackageManager = struct {
|
||||
// ensure we use one pointer to reference it instead of creating new ones and potentially aliasing
|
||||
var builder = &builder_;
|
||||
// If you changed packages, we will copy over the new package from the new lockfile
|
||||
const new_dependencies = maybe_root.dependencies.get(lockfile.buffers.dependencies.items);
|
||||
|
||||
for (new_dependencies) |new_dep| {
|
||||
new_dep.count(lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
const new_pkgs = lockfile.packages.slice();
|
||||
const new_pkg_dependencies = new_pkgs.items(.dependencies);
|
||||
const new_pkg_scripts = new_pkgs.items(.scripts);
|
||||
const new_pkg_names: []String = new_pkgs.items(.name);
|
||||
const new_pkg_name_hashes = new_pkgs.items(.name_hash);
|
||||
|
||||
var deps_off: DependencyID = @truncate(manager.lockfile.buffers.dependencies.items.len);
|
||||
for (new_pkg_dependencies, 0..) |new_pkg_deps, _new_pkg_id| {
|
||||
const new_pkg_id: PackageID = @truncate(_new_pkg_id);
|
||||
|
||||
for (new_pkg_deps.get(lockfile.buffers.dependencies.items)) |new_pkg_dep| {
|
||||
new_pkg_dep.count(lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
}
|
||||
|
||||
new_pkg_scripts[new_pkg_id].count(lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
builder.count(new_pkg_names[new_pkg_id].slice(lockfile.buffers.string_bytes.items));
|
||||
|
||||
const existing_pkg_id = pkg_map.items[new_pkg_id];
|
||||
|
||||
manager.lockfile.packages.items(.dependencies)[existing_pkg_id] = .{ .off = deps_off, .len = new_pkg_deps.len };
|
||||
manager.lockfile.packages.items(.resolutions)[existing_pkg_id] = .{ .off = deps_off, .len = new_pkg_deps.len };
|
||||
|
||||
deps_off += new_pkg_deps.len;
|
||||
}
|
||||
|
||||
const new_deps_len = deps_off - manager.lockfile.buffers.dependencies.items.len;
|
||||
deps_off = @truncate(manager.lockfile.buffers.dependencies.items.len);
|
||||
|
||||
for (lockfile.workspace_paths.values()) |path| builder.count(path.slice(lockfile.buffers.string_bytes.items));
|
||||
for (lockfile.workspace_versions.values()) |version| version.count(lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
for (lockfile.patched_dependencies.values()) |patch_dep| builder.count(patch_dep.path.slice(lockfile.buffers.string_bytes.items));
|
||||
|
||||
lockfile.overrides.count(&lockfile, builder);
|
||||
maybe_root.scripts.count(lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
|
||||
const off = @as(u32, @truncate(manager.lockfile.buffers.dependencies.items.len));
|
||||
const len = @as(u32, @truncate(new_dependencies.len));
|
||||
var packages = manager.lockfile.packages.slice();
|
||||
var dep_lists = packages.items(.dependencies);
|
||||
var resolution_lists = packages.items(.resolutions);
|
||||
const old_resolutions_list = resolution_lists[0];
|
||||
dep_lists[0] = .{ .off = off, .len = len };
|
||||
resolution_lists[0] = .{ .off = off, .len = len };
|
||||
try builder.allocate();
|
||||
|
||||
const all_name_hashes: []PackageNameHash = brk: {
|
||||
const all_override_name_hashes: []PackageNameHash = brk: {
|
||||
if (!manager.summary.overrides_changed) break :brk &.{};
|
||||
const hashes_len = manager.lockfile.overrides.map.entries.len + lockfile.overrides.map.entries.len;
|
||||
if (hashes_len == 0) break :brk &.{};
|
||||
@@ -14591,41 +14573,64 @@ pub const PackageManager = struct {
|
||||
break :brk all_name_hashes;
|
||||
};
|
||||
|
||||
manager.lockfile.overrides = try lockfile.overrides.clone(manager, &lockfile, manager.lockfile, builder);
|
||||
manager.lockfile.overrides = try lockfile.overrides.clone(&lockfile, manager.lockfile, builder);
|
||||
|
||||
manager.lockfile.trusted_dependencies = if (lockfile.trusted_dependencies) |trusted_dependencies|
|
||||
try trusted_dependencies.clone(manager.lockfile.allocator)
|
||||
else
|
||||
null;
|
||||
|
||||
try manager.lockfile.buffers.dependencies.ensureUnusedCapacity(manager.lockfile.allocator, len);
|
||||
try manager.lockfile.buffers.resolutions.ensureUnusedCapacity(manager.lockfile.allocator, len);
|
||||
{
|
||||
// clone deps
|
||||
try manager.lockfile.buffers.dependencies.ensureUnusedCapacity(manager.lockfile.allocator, new_deps_len);
|
||||
try manager.lockfile.buffers.resolutions.ensureUnusedCapacity(manager.lockfile.allocator, new_deps_len);
|
||||
|
||||
const old_resolutions = old_resolutions_list.get(manager.lockfile.buffers.resolutions.items);
|
||||
var dependencies = manager.lockfile.buffers.dependencies.items.ptr[deps_off .. deps_off + new_deps_len];
|
||||
var resolutions = manager.lockfile.buffers.resolutions.items.ptr[deps_off .. deps_off + new_deps_len];
|
||||
|
||||
var dependencies = manager.lockfile.buffers.dependencies.items.ptr[off .. off + len];
|
||||
var resolutions = manager.lockfile.buffers.resolutions.items.ptr[off .. off + len];
|
||||
// It is too easy to accidentally undefined memory
|
||||
@memset(resolutions, invalid_package_id);
|
||||
@memset(dependencies, Dependency{});
|
||||
|
||||
// It is too easy to accidentally undefined memory
|
||||
@memset(resolutions, invalid_package_id);
|
||||
@memset(dependencies, Dependency{});
|
||||
manager.lockfile.buffers.dependencies.items = manager.lockfile.buffers.dependencies.items.ptr[0 .. deps_off + new_deps_len];
|
||||
manager.lockfile.buffers.resolutions.items = manager.lockfile.buffers.resolutions.items.ptr[0 .. deps_off + new_deps_len];
|
||||
|
||||
manager.lockfile.buffers.dependencies.items = manager.lockfile.buffers.dependencies.items.ptr[0 .. off + len];
|
||||
manager.lockfile.buffers.resolutions.items = manager.lockfile.buffers.resolutions.items.ptr[0 .. off + len];
|
||||
for (new_pkg_dependencies, 0..) |new_pkg_deps, _new_pkg_id| {
|
||||
const new_pkg_id: PackageID = @truncate(_new_pkg_id);
|
||||
const existing_pkg_id = pkg_map.items[new_pkg_id];
|
||||
|
||||
for (new_dependencies, 0..) |new_dep, i| {
|
||||
dependencies[i] = try new_dep.clone(manager, lockfile.buffers.string_bytes.items, *Lockfile.StringBuilder, builder);
|
||||
if (mapping[i] != invalid_package_id) {
|
||||
resolutions[i] = old_resolutions[mapping[i]];
|
||||
for (new_pkg_deps.begin()..new_pkg_deps.end()) |_new_pkg_dep_id| {
|
||||
const new_pkg_dep_id: DependencyID = @truncate(_new_pkg_dep_id);
|
||||
dependencies[new_pkg_dep_id] = try lockfile.buffers.dependencies.items[new_pkg_dep_id].clone(
|
||||
lockfile.buffers.string_bytes.items,
|
||||
*Lockfile.StringBuilder,
|
||||
builder,
|
||||
);
|
||||
|
||||
if (new_pkg_dep_id < dep_map.items.len) {
|
||||
const mapped_dep_id = dep_map.items[new_pkg_dep_id];
|
||||
if (mapped_dep_id != invalid_dependency_id) {
|
||||
resolutions[new_pkg_dep_id] = manager.lockfile.buffers.resolutions.items[mapped_dep_id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packages.items(.scripts)[existing_pkg_id] = new_pkg_scripts[new_pkg_id].clone(
|
||||
lockfile.buffers.string_bytes.items,
|
||||
*Lockfile.StringBuilder,
|
||||
builder,
|
||||
);
|
||||
|
||||
packages.items(.name)[existing_pkg_id] = builder.appendWithHash(
|
||||
String,
|
||||
new_pkg_names[new_pkg_id].slice(lockfile.buffers.string_bytes.items),
|
||||
new_pkg_name_hashes[new_pkg_id],
|
||||
);
|
||||
|
||||
packages.items(.name_hash)[existing_pkg_id] = new_pkg_name_hashes[new_pkg_id];
|
||||
}
|
||||
}
|
||||
|
||||
manager.lockfile.packages.items(.scripts)[0] = maybe_root.scripts.clone(
|
||||
lockfile.buffers.string_bytes.items,
|
||||
*Lockfile.StringBuilder,
|
||||
builder,
|
||||
);
|
||||
|
||||
// Update workspace paths
|
||||
try manager.lockfile.workspace_paths.ensureTotalCapacity(manager.lockfile.allocator, lockfile.workspace_paths.entries.len);
|
||||
{
|
||||
@@ -14696,9 +14701,9 @@ pub const PackageManager = struct {
|
||||
|
||||
builder.clamp();
|
||||
|
||||
if (manager.summary.overrides_changed and all_name_hashes.len > 0) {
|
||||
if (manager.summary.overrides_changed and all_override_name_hashes.len > 0) {
|
||||
for (manager.lockfile.buffers.dependencies.items, 0..) |*dependency, dependency_i| {
|
||||
if (std.mem.indexOfScalar(PackageNameHash, all_name_hashes, dependency.name_hash)) |_| {
|
||||
if (std.mem.indexOfScalar(PackageNameHash, all_override_name_hashes, dependency.name_hash)) |_| {
|
||||
manager.lockfile.buffers.resolutions.items[dependency_i] = invalid_package_id;
|
||||
try manager.enqueueDependencyWithMain(
|
||||
@truncate(dependency_i),
|
||||
@@ -14712,15 +14717,15 @@ pub const PackageManager = struct {
|
||||
|
||||
// Split this into two passes because the below may allocate memory or invalidate pointers
|
||||
if (manager.summary.add > 0 or manager.summary.update > 0) {
|
||||
const changes = @as(PackageID, @truncate(mapping.len));
|
||||
var counter_i: PackageID = 0;
|
||||
const changes: DependencyID = @truncate(dep_map.items.len);
|
||||
var counter_i: DependencyID = 0;
|
||||
|
||||
_ = manager.getCacheDirectory();
|
||||
_ = manager.getTemporaryDirectory();
|
||||
|
||||
while (counter_i < changes) : (counter_i += 1) {
|
||||
if (mapping[counter_i] == invalid_package_id) {
|
||||
const dependency_i = counter_i + off;
|
||||
if (counter_i < dep_map.items.len and dep_map.items[counter_i] == invalid_dependency_id) {
|
||||
const dependency_i = counter_i + deps_off;
|
||||
const dependency = manager.lockfile.buffers.dependencies.items[dependency_i];
|
||||
try manager.enqueueDependencyWithMain(
|
||||
dependency_i,
|
||||
|
||||
@@ -157,6 +157,8 @@ trusted_dependencies: ?TrustedDependenciesSet = null,
|
||||
patched_dependencies: PatchedDependenciesMap = .{},
|
||||
overrides: OverrideMap = .{},
|
||||
|
||||
folder_resolutions: FolderResolution.Map = .{},
|
||||
|
||||
const Stream = std.io.FixedBufferStream([]u8);
|
||||
pub const default_filename = "bun.lockb";
|
||||
|
||||
@@ -388,7 +390,7 @@ pub fn loadFromDir(
|
||||
};
|
||||
};
|
||||
|
||||
TextLockfile.parseIntoBinaryLockfile(this, allocator, json, &source, log, manager) catch |err| {
|
||||
TextLockfile.parseIntoBinaryLockfile(this, allocator, json, &source, log) catch |err| {
|
||||
switch (err) {
|
||||
error.OutOfMemory => bun.outOfMemory(),
|
||||
else => {
|
||||
@@ -443,7 +445,7 @@ pub fn loadFromDir(
|
||||
Output.panic("failed to print valid json from binary lockfile: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
TextLockfile.parseIntoBinaryLockfile(this, allocator, json, &source, log, manager) catch |err| {
|
||||
TextLockfile.parseIntoBinaryLockfile(this, allocator, json, &source, log) catch |err| {
|
||||
Output.panic("failed to parse text lockfile converted from binary lockfile: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
||||
@@ -466,6 +468,7 @@ pub fn loadFromBytes(this: *Lockfile, pm: ?*PackageManager, buf: []u8, allocator
|
||||
this.workspace_versions = .{};
|
||||
this.overrides = .{};
|
||||
this.patched_dependencies = .{};
|
||||
this.folder_resolutions = .{};
|
||||
|
||||
const load_result = Lockfile.Serializer.load(this, &stream, allocator, log, pm) catch |err| {
|
||||
return LoadResult{ .err = .{ .step = .parse_file, .value = err, .lockfile_path = "bun.lockb", .format = .binary } };
|
||||
@@ -725,11 +728,13 @@ pub const Tree = struct {
|
||||
pub fn Builder(comptime method: BuilderMethod) type {
|
||||
return struct {
|
||||
allocator: Allocator,
|
||||
name_hashes: []const PackageNameHash,
|
||||
pkg_names: []const String,
|
||||
pkg_metas: []const Package.Meta,
|
||||
pkg_resolutions: []const Resolution,
|
||||
pkg_resolution_lists: []const Lockfile.DependencyIDSlice,
|
||||
list: bun.MultiArrayList(Entry) = .{},
|
||||
resolutions: []const PackageID,
|
||||
dependencies: []const Dependency,
|
||||
resolution_lists: []const Lockfile.DependencyIDSlice,
|
||||
queue: Lockfile.TreeFiller,
|
||||
log: *logger.Log,
|
||||
lockfile: *const Lockfile,
|
||||
@@ -821,7 +826,7 @@ pub const Tree = struct {
|
||||
root_dep_id => 0,
|
||||
else => |id| builder.resolutions[id],
|
||||
};
|
||||
const resolution_list = builder.resolution_lists[parent_pkg_id];
|
||||
const resolution_list = builder.pkg_resolution_lists[parent_pkg_id];
|
||||
|
||||
if (resolution_list.len == 0) return;
|
||||
|
||||
@@ -838,13 +843,7 @@ pub const Tree = struct {
|
||||
const trees = list_slice.items(.tree);
|
||||
const dependency_lists = list_slice.items(.dependencies);
|
||||
const next: *Tree = &trees[builder.list.len - 1];
|
||||
const name_hashes: []const PackageNameHash = builder.name_hashes;
|
||||
const max_package_id = @as(PackageID, @truncate(name_hashes.len));
|
||||
|
||||
const pkgs = builder.lockfile.packages.slice();
|
||||
const pkg_resolutions = pkgs.items(.resolution);
|
||||
const pkg_metas = pkgs.items(.meta);
|
||||
const pkg_names = pkgs.items(.name);
|
||||
const max_package_id = @as(PackageID, @truncate(builder.lockfile.packages.len));
|
||||
|
||||
builder.sort_buf.clearRetainingCapacity();
|
||||
try builder.sort_buf.ensureUnusedCapacity(builder.allocator, resolution_list.len);
|
||||
@@ -889,15 +888,15 @@ pub const Tree = struct {
|
||||
if (comptime method == .filter) {
|
||||
if (builder.lockfile.isResolvedDependencyDisabled(
|
||||
dep_id,
|
||||
switch (pkg_resolutions[parent_pkg_id].tag) {
|
||||
switch (builder.pkg_resolutions[parent_pkg_id].tag) {
|
||||
.root, .workspace, .folder => builder.manager.options.local_package_features,
|
||||
else => builder.manager.options.remote_package_features,
|
||||
},
|
||||
&pkg_metas[pkg_id],
|
||||
&builder.pkg_metas[pkg_id],
|
||||
)) {
|
||||
if (log_level.isVerbose()) {
|
||||
const meta = &pkg_metas[pkg_id];
|
||||
const name = builder.lockfile.str(&pkg_names[pkg_id]);
|
||||
const meta = &builder.pkg_metas[pkg_id];
|
||||
const name = builder.lockfile.str(&builder.pkg_names[pkg_id]);
|
||||
if (!meta.os.isMatch() and !meta.arch.isMatch()) {
|
||||
Output.prettyErrorln("<d>Skip installing '<b>{s}<r><d>' cpu & os mismatch", .{name});
|
||||
} else if (!meta.os.isMatch()) {
|
||||
@@ -928,10 +927,10 @@ pub const Tree = struct {
|
||||
const res_id = builder.resolutions[dep_id];
|
||||
|
||||
const pattern, const path_or_name = switch (workspace_filter) {
|
||||
.name => |pattern| .{ pattern, pkg_names[res_id].slice(builder.buf()) },
|
||||
.name => |pattern| .{ pattern, builder.pkg_names[res_id].slice(builder.buf()) },
|
||||
|
||||
.path => |pattern| path: {
|
||||
const res = &pkg_resolutions[res_id];
|
||||
const res = &builder.pkg_resolutions[res_id];
|
||||
if (res.tag != .workspace) {
|
||||
break :dont_skip;
|
||||
}
|
||||
@@ -985,14 +984,14 @@ pub const Tree = struct {
|
||||
}
|
||||
|
||||
const hoisted: HoistDependencyResult = hoisted: {
|
||||
const dependency = builder.dependencies[dep_id];
|
||||
const dep = builder.dependencies[dep_id];
|
||||
|
||||
// don't hoist if it's a folder dependency or a bundled dependency.
|
||||
if (dependency.behavior.isBundled()) {
|
||||
if (dep.behavior.isBundled()) {
|
||||
break :hoisted .{ .placement = .{ .id = next.id, .bundled = true } };
|
||||
}
|
||||
|
||||
if (pkg_resolutions[pkg_id].tag == .folder) {
|
||||
if (builder.pkg_resolutions[pkg_id].tag == .folder) {
|
||||
break :hoisted .{ .placement = .{ .id = next.id } };
|
||||
}
|
||||
|
||||
@@ -1000,7 +999,8 @@ pub const Tree = struct {
|
||||
true,
|
||||
hoist_root_id,
|
||||
pkg_id,
|
||||
&dependency,
|
||||
dep_id,
|
||||
&dep,
|
||||
dependency_lists,
|
||||
trees,
|
||||
method,
|
||||
@@ -1011,9 +1011,9 @@ pub const Tree = struct {
|
||||
switch (hoisted) {
|
||||
.dependency_loop, .hoisted => continue,
|
||||
.placement => |dest| {
|
||||
dependency_lists[dest.id].append(builder.allocator, dep_id) catch bun.outOfMemory();
|
||||
try dependency_lists[dest.id].append(builder.allocator, dep_id);
|
||||
trees[dest.id].dependencies.len += 1;
|
||||
if (builder.resolution_lists[pkg_id].len > 0) {
|
||||
if (builder.pkg_resolution_lists[pkg_id].len > 0) {
|
||||
try builder.queue.writeItem(.{
|
||||
.tree_id = dest.id,
|
||||
.dependency_id = dep_id,
|
||||
@@ -1040,8 +1040,9 @@ pub const Tree = struct {
|
||||
this: *Tree,
|
||||
comptime as_defined: bool,
|
||||
hoist_root_id: Id,
|
||||
package_id: PackageID,
|
||||
dependency: *const Dependency,
|
||||
pkg_id: PackageID,
|
||||
target_dep_id: DependencyID,
|
||||
target_dep: *const Dependency,
|
||||
dependency_lists: []Lockfile.DependencyIDList,
|
||||
trees: []Tree,
|
||||
comptime method: BuilderMethod,
|
||||
@@ -1051,15 +1052,15 @@ pub const Tree = struct {
|
||||
for (0..this_dependencies.len) |i| {
|
||||
const dep_id = this_dependencies[i];
|
||||
const dep = builder.dependencies[dep_id];
|
||||
if (dep.name_hash != dependency.name_hash) continue;
|
||||
if (dep.name_hash != target_dep.name_hash) continue;
|
||||
|
||||
if (builder.resolutions[dep_id] == package_id) {
|
||||
if (builder.resolutions[dep_id] == pkg_id) {
|
||||
// this dependency is the same package as the other, hoist
|
||||
return .hoisted; // 1
|
||||
}
|
||||
|
||||
if (comptime as_defined) {
|
||||
if (dep.behavior.isDev() != dependency.behavior.isDev()) {
|
||||
if (dep.behavior.isDev() != target_dep.behavior.isDev()) {
|
||||
// will only happen in workspaces and root package because
|
||||
// dev dependencies won't be included in other types of
|
||||
// dependencies
|
||||
@@ -1070,15 +1071,16 @@ pub const Tree = struct {
|
||||
// now we either keep the dependency at this place in the tree,
|
||||
// or hoist if peer version allows it
|
||||
|
||||
if (dependency.behavior.isPeer()) {
|
||||
if (dependency.version.tag == .npm) {
|
||||
const resolution: Resolution = builder.lockfile.packages.items(.resolution)[builder.resolutions[dep_id]];
|
||||
const version = dependency.version.value.npm.version;
|
||||
if (resolution.tag == .npm and version.satisfies(resolution.value.npm.version, builder.buf(), builder.buf())) {
|
||||
return .hoisted; // 1
|
||||
}
|
||||
}
|
||||
const target_res = builder.pkg_resolutions[builder.resolutions[target_dep_id]];
|
||||
const existing_res = builder.pkg_resolutions[builder.resolutions[dep_id]];
|
||||
|
||||
if (target_res.tag == .npm and existing_res.tag == .npm) {
|
||||
if (target_dep.version.tag == .npm and target_dep.version.value.npm.version.satisfies(existing_res.value.npm.version, builder.buf(), builder.buf())) {
|
||||
return .hoisted; // 1
|
||||
}
|
||||
}
|
||||
|
||||
if (target_dep.behavior.isPeer()) {
|
||||
// Root dependencies are manually chosen by the user. Allow them
|
||||
// to hoist other peers even if they don't satisfy the version
|
||||
if (builder.lockfile.isWorkspaceRootDependency(dep_id)) {
|
||||
@@ -1089,12 +1091,12 @@ pub const Tree = struct {
|
||||
|
||||
if (as_defined and !dep.behavior.isPeer()) {
|
||||
builder.maybeReportError("Package \"{}@{}\" has a dependency loop\n Resolution: \"{}@{}\"\n Dependency: \"{}@{}\"", .{
|
||||
builder.packageName(package_id),
|
||||
builder.packageVersion(package_id),
|
||||
builder.packageName(pkg_id),
|
||||
builder.packageVersion(pkg_id),
|
||||
builder.packageName(builder.resolutions[dep_id]),
|
||||
builder.packageVersion(builder.resolutions[dep_id]),
|
||||
dependency.name.fmt(builder.buf()),
|
||||
dependency.version.literal.fmt(builder.buf()),
|
||||
target_dep.name.fmt(builder.buf()),
|
||||
target_dep.version.literal.fmt(builder.buf()),
|
||||
});
|
||||
return error.DependencyLoop;
|
||||
}
|
||||
@@ -1107,8 +1109,9 @@ pub const Tree = struct {
|
||||
const id = trees[this.parent].hoistDependency(
|
||||
false,
|
||||
hoist_root_id,
|
||||
package_id,
|
||||
dependency,
|
||||
pkg_id,
|
||||
target_dep_id,
|
||||
target_dep,
|
||||
dependency_lists,
|
||||
trees,
|
||||
method,
|
||||
@@ -1257,7 +1260,6 @@ fn preprocessUpdateRequests(old: *Lockfile, manager: *PackageManager, updates: [
|
||||
sliced.slice,
|
||||
&sliced,
|
||||
null,
|
||||
manager,
|
||||
) orelse Dependency.Version{};
|
||||
}
|
||||
}
|
||||
@@ -1383,7 +1385,7 @@ pub fn cleanWithLogger(
|
||||
var builder = new.stringBuilder();
|
||||
old.overrides.count(old, &builder);
|
||||
try builder.allocate();
|
||||
new.overrides = try old.overrides.clone(manager, old, new, &builder);
|
||||
new.overrides = try old.overrides.clone(old, new, &builder);
|
||||
}
|
||||
|
||||
// Step 1. Recreate the lockfile with only the packages that are still alive
|
||||
@@ -1406,7 +1408,7 @@ pub fn cleanWithLogger(
|
||||
};
|
||||
|
||||
// try clone_queue.ensureUnusedCapacity(root.dependencies.len);
|
||||
_ = try root.clone(manager, old, new, package_id_mapping, &cloner);
|
||||
_ = try root.clone(old, new, package_id_mapping, &cloner);
|
||||
|
||||
// Clone workspace_paths and workspace_versions at the end.
|
||||
if (old.workspace_paths.count() > 0 or old.workspace_versions.count() > 0) {
|
||||
@@ -1588,7 +1590,6 @@ const Cloner = struct {
|
||||
const old_package = this.old.packages.get(to_clone.old_resolution);
|
||||
|
||||
this.lockfile.buffers.resolutions.items[to_clone.resolve_id] = try old_package.clone(
|
||||
this.manager,
|
||||
this.old,
|
||||
this.lockfile,
|
||||
this.mapping,
|
||||
@@ -1638,14 +1639,16 @@ pub fn hoist(
|
||||
workspace_filters: if (method == .filter) []const WorkspaceFilter else void,
|
||||
) Tree.SubtreeError!void {
|
||||
const allocator = lockfile.allocator;
|
||||
var slice = lockfile.packages.slice();
|
||||
var pkgs = lockfile.packages.slice();
|
||||
|
||||
var path_buf: bun.PathBuffer = undefined;
|
||||
|
||||
var builder = Tree.Builder(method){
|
||||
.name_hashes = slice.items(.name_hash),
|
||||
.pkg_names = pkgs.items(.name),
|
||||
.pkg_metas = pkgs.items(.meta),
|
||||
.pkg_resolutions = pkgs.items(.resolution),
|
||||
.queue = TreeFiller.init(allocator),
|
||||
.resolution_lists = slice.items(.resolutions),
|
||||
.pkg_resolution_lists = pkgs.items(.resolutions),
|
||||
.resolutions = lockfile.buffers.resolutions.items,
|
||||
.allocator = allocator,
|
||||
.dependencies = lockfile.buffers.dependencies.items,
|
||||
@@ -2638,23 +2641,17 @@ pub fn initEmpty(this: *Lockfile, allocator: Allocator) void {
|
||||
.workspace_versions = .{},
|
||||
.overrides = .{},
|
||||
.meta_hash = zero_hash,
|
||||
.folder_resolutions = .{},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getPackageID(
|
||||
this: *Lockfile,
|
||||
name_hash: u64,
|
||||
// If non-null, attempt to use an existing package
|
||||
// that satisfies this version range.
|
||||
version: ?Dependency.Version,
|
||||
resolution: *const Resolution,
|
||||
) ?PackageID {
|
||||
const entry = this.package_index.get(name_hash) orelse return null;
|
||||
const resolutions: []const Resolution = this.packages.items(.resolution);
|
||||
const npm_version = if (version) |v| switch (v.tag) {
|
||||
.npm => v.value.npm.version,
|
||||
else => null,
|
||||
} else null;
|
||||
const buf = this.buffers.string_bytes.items;
|
||||
|
||||
switch (entry) {
|
||||
@@ -2664,10 +2661,6 @@ pub fn getPackageID(
|
||||
if (resolutions[id].eql(resolution, buf, buf)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
if (resolutions[id].tag == .npm and npm_version != null) {
|
||||
if (npm_version.?.satisfies(resolutions[id].value.npm.version, buf, buf)) return id;
|
||||
}
|
||||
},
|
||||
.ids => |ids| {
|
||||
for (ids.items) |id| {
|
||||
@@ -2676,10 +2669,6 @@ pub fn getPackageID(
|
||||
if (resolutions[id].eql(resolution, buf, buf)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
if (resolutions[id].tag == .npm and npm_version != null) {
|
||||
if (npm_version.?.satisfies(resolutions[id].value.npm.version, buf, buf)) return id;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -2807,7 +2796,7 @@ pub fn appendPackage(this: *Lockfile, package_: Lockfile.Package) OOM!Lockfile.P
|
||||
fn appendPackageWithID(this: *Lockfile, package_: Lockfile.Package, id: PackageID) OOM!Lockfile.Package {
|
||||
defer {
|
||||
if (comptime Environment.allow_assert) {
|
||||
assert(this.getPackageID(package_.name_hash, null, &package_.resolution) != null);
|
||||
assert(this.getPackageID(package_.name_hash, &package_.resolution) != null);
|
||||
}
|
||||
}
|
||||
var package = package_;
|
||||
@@ -3026,14 +3015,14 @@ pub const OverrideMap = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone(this: *OverrideMap, pm: *PackageManager, old_lockfile: *Lockfile, new_lockfile: *Lockfile, new_builder: *Lockfile.StringBuilder) !OverrideMap {
|
||||
pub fn clone(this: *OverrideMap, old_lockfile: *Lockfile, new_lockfile: *Lockfile, new_builder: *Lockfile.StringBuilder) !OverrideMap {
|
||||
var new = OverrideMap{};
|
||||
try new.map.ensureTotalCapacity(new_lockfile.allocator, this.map.entries.len);
|
||||
|
||||
for (this.map.keys(), this.map.values()) |k, v| {
|
||||
new.map.putAssumeCapacity(
|
||||
k,
|
||||
try v.clone(pm, old_lockfile.buffers.string_bytes.items, @TypeOf(new_builder), new_builder),
|
||||
try v.clone(old_lockfile.buffers.string_bytes.items, @TypeOf(new_builder), new_builder),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3083,7 +3072,6 @@ pub const OverrideMap = struct {
|
||||
/// It is assumed the input map is uninitialized (zero entries)
|
||||
pub fn parseAppend(
|
||||
this: *OverrideMap,
|
||||
pm: *PackageManager,
|
||||
lockfile: *Lockfile,
|
||||
root_package: *Lockfile.Package,
|
||||
log: *logger.Log,
|
||||
@@ -3095,9 +3083,9 @@ pub const OverrideMap = struct {
|
||||
assert(this.map.entries.len == 0); // only call parse once
|
||||
}
|
||||
if (expr.asProperty("overrides")) |overrides| {
|
||||
try this.parseFromOverrides(pm, lockfile, root_package, json_source, log, overrides.expr, builder);
|
||||
try this.parseFromOverrides(lockfile, root_package, json_source, log, overrides.expr, builder);
|
||||
} else if (expr.asProperty("resolutions")) |resolutions| {
|
||||
try this.parseFromResolutions(pm, lockfile, root_package, json_source, log, resolutions.expr, builder);
|
||||
try this.parseFromResolutions(lockfile, root_package, json_source, log, resolutions.expr, builder);
|
||||
}
|
||||
debug("parsed {d} overrides", .{this.map.entries.len});
|
||||
}
|
||||
@@ -3105,7 +3093,6 @@ pub const OverrideMap = struct {
|
||||
/// https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides
|
||||
pub fn parseFromOverrides(
|
||||
this: *OverrideMap,
|
||||
pm: *PackageManager,
|
||||
lockfile: *Lockfile,
|
||||
root_package: *Lockfile.Package,
|
||||
source: logger.Source,
|
||||
@@ -3165,7 +3152,6 @@ pub const OverrideMap = struct {
|
||||
if (try parseOverrideValue(
|
||||
"override",
|
||||
lockfile,
|
||||
pm,
|
||||
root_package,
|
||||
source,
|
||||
value.loc,
|
||||
@@ -3183,7 +3169,6 @@ pub const OverrideMap = struct {
|
||||
/// yarn berry: https://yarnpkg.com/configuration/manifest#resolutions
|
||||
pub fn parseFromResolutions(
|
||||
this: *OverrideMap,
|
||||
pm: *PackageManager,
|
||||
lockfile: *Lockfile,
|
||||
root_package: *Lockfile.Package,
|
||||
source: logger.Source,
|
||||
@@ -3237,7 +3222,6 @@ pub const OverrideMap = struct {
|
||||
if (try parseOverrideValue(
|
||||
"resolution",
|
||||
lockfile,
|
||||
pm,
|
||||
root_package,
|
||||
source,
|
||||
value.loc,
|
||||
@@ -3255,7 +3239,6 @@ pub const OverrideMap = struct {
|
||||
pub fn parseOverrideValue(
|
||||
comptime field: []const u8,
|
||||
lockfile: *Lockfile,
|
||||
package_manager: *PackageManager,
|
||||
root_package: *Lockfile.Package,
|
||||
source: logger.Source,
|
||||
loc: logger.Loc,
|
||||
@@ -3303,7 +3286,6 @@ pub const OverrideMap = struct {
|
||||
literalSliced.slice,
|
||||
&literalSliced,
|
||||
log,
|
||||
package_manager,
|
||||
) orelse {
|
||||
try log.addWarningFmt(&source, loc, lockfile.allocator, "Invalid " ++ field ++ " value \"{s}\"", .{value});
|
||||
return null;
|
||||
@@ -3804,7 +3786,6 @@ pub const Package = extern struct {
|
||||
|
||||
pub fn clone(
|
||||
this: *const Lockfile.Package,
|
||||
pm: *PackageManager,
|
||||
old: *Lockfile,
|
||||
new: *Lockfile,
|
||||
package_id_mapping: []PackageID,
|
||||
@@ -3901,7 +3882,6 @@ pub const Package = extern struct {
|
||||
|
||||
for (old_dependencies, dependencies) |old_dep, *new_dep| {
|
||||
new_dep.* = try old_dep.clone(
|
||||
pm,
|
||||
old_string_buf,
|
||||
*Lockfile.StringBuilder,
|
||||
builder,
|
||||
@@ -3935,7 +3915,6 @@ pub const Package = extern struct {
|
||||
|
||||
pub fn fromPackageJSON(
|
||||
lockfile: *Lockfile,
|
||||
pm: *PackageManager,
|
||||
package_json: *PackageJSON,
|
||||
comptime features: Features,
|
||||
) !Lockfile.Package {
|
||||
@@ -3995,7 +3974,7 @@ pub const Package = extern struct {
|
||||
for (package_dependencies) |dep| {
|
||||
if (!dep.behavior.isEnabled(features)) continue;
|
||||
|
||||
dependencies[0] = try dep.clone(pm, source_buf, @TypeOf(&string_builder), &string_builder);
|
||||
dependencies[0] = try dep.clone(source_buf, @TypeOf(&string_builder), &string_builder);
|
||||
dependencies = dependencies[1..];
|
||||
if (dependencies.len == 0) break;
|
||||
}
|
||||
@@ -4025,7 +4004,6 @@ pub const Package = extern struct {
|
||||
}
|
||||
|
||||
pub fn fromNPM(
|
||||
pm: *PackageManager,
|
||||
allocator: Allocator,
|
||||
lockfile: *Lockfile,
|
||||
log: *logger.Log,
|
||||
@@ -4189,7 +4167,6 @@ pub const Package = extern struct {
|
||||
sliced.slice,
|
||||
&sliced,
|
||||
log,
|
||||
pm,
|
||||
) orelse Dependency.Version{},
|
||||
};
|
||||
|
||||
@@ -4257,6 +4234,10 @@ pub const Package = extern struct {
|
||||
update: u32 = 0,
|
||||
overrides_changed: bool = false,
|
||||
|
||||
// Dependency version literal changed, but it still
|
||||
// satisfies the version of the package in the lockfile.
|
||||
satisfied_versions: u32 = 0,
|
||||
|
||||
// bool for if this dependency should be added to lockfile trusted dependencies.
|
||||
// it is false when the new trusted dependency is coming from the default list.
|
||||
added_trusted_dependencies: std.ArrayHashMapUnmanaged(TruncatedPackageNameHash, bool, ArrayIdentityContext, false) = .{},
|
||||
@@ -4282,18 +4263,22 @@ pub const Package = extern struct {
|
||||
pm: *PackageManager,
|
||||
allocator: Allocator,
|
||||
log: *logger.Log,
|
||||
from_lockfile: *Lockfile,
|
||||
from_lockfile: *const Lockfile,
|
||||
to_lockfile: *Lockfile,
|
||||
from: *Lockfile.Package,
|
||||
to: *Lockfile.Package,
|
||||
from_pkg_id: PackageID,
|
||||
to_pkg_id: PackageID,
|
||||
update_requests: ?[]PackageManager.UpdateRequest,
|
||||
id_mapping: ?[]PackageID,
|
||||
dep_map: *std.ArrayList(DependencyID),
|
||||
pkg_map: *std.ArrayList(PackageID),
|
||||
) !Summary {
|
||||
var summary = Summary{};
|
||||
var to_deps = to.dependencies.get(to_lockfile.buffers.dependencies.items);
|
||||
const from_deps = from.dependencies.get(from_lockfile.buffers.dependencies.items);
|
||||
const from_resolutions = from.resolutions.get(from_lockfile.buffers.resolutions.items);
|
||||
var to_i: usize = 0;
|
||||
|
||||
const from_pkgs = from_lockfile.packages.slice();
|
||||
const from_pkg_resolutions = from_pkgs.items(.resolution);
|
||||
const from_pkg_dependencies = from_pkgs.items(.dependencies);
|
||||
const from_pkg_scripts = from_pkgs.items(.scripts);
|
||||
|
||||
const from_deps = from_pkg_dependencies[from_pkg_id];
|
||||
|
||||
if (from_lockfile.overrides.map.count() != to_lockfile.overrides.map.count()) {
|
||||
summary.overrides_changed = true;
|
||||
@@ -4438,17 +4423,28 @@ pub const Package = extern struct {
|
||||
break :patched_dependencies_changed false;
|
||||
};
|
||||
|
||||
for (from_deps, 0..) |*from_dep, i| {
|
||||
const to_deps_off: DependencyID, const to_deps_len = to_deps: {
|
||||
const to_deps = to_lockfile.packages.items(.dependencies)[to_pkg_id];
|
||||
break :to_deps .{ to_deps.off, to_deps.len };
|
||||
};
|
||||
const to_deps_end = to_deps_off + to_deps_len;
|
||||
|
||||
var to_dep_id = to_deps_off;
|
||||
|
||||
for (from_deps.begin()..from_deps.end()) |_from_dep_id| {
|
||||
const from_dep_id: DependencyID = @truncate(_from_dep_id);
|
||||
const from_dep = from_lockfile.buffers.dependencies.items[from_dep_id];
|
||||
|
||||
found: {
|
||||
const prev_i = to_i;
|
||||
const prev_i = to_dep_id;
|
||||
|
||||
// common case, dependency is present in both versions:
|
||||
// - in the same position
|
||||
// - shifted by a constant offset
|
||||
while (to_i < to_deps.len) : (to_i += 1) {
|
||||
if (from_dep.name_hash == to_deps[to_i].name_hash) {
|
||||
while (to_dep_id < to_deps_end) : (to_dep_id += 1) {
|
||||
if (from_dep.name_hash == to_lockfile.buffers.dependencies.items[to_dep_id].name_hash) {
|
||||
const from_is_workspace_only = from_dep.behavior.isWorkspaceOnly();
|
||||
const to_is_workspace_only = to_deps[to_i].behavior.isWorkspaceOnly();
|
||||
const to_is_workspace_only = to_lockfile.buffers.dependencies.items[to_dep_id].behavior.isWorkspaceOnly();
|
||||
|
||||
if (from_is_workspace_only and to_is_workspace_only) {
|
||||
break :found;
|
||||
@@ -4463,11 +4459,11 @@ pub const Package = extern struct {
|
||||
}
|
||||
|
||||
// less common, o(n^2) case
|
||||
to_i = 0;
|
||||
while (to_i < prev_i) : (to_i += 1) {
|
||||
if (from_dep.name_hash == to_deps[to_i].name_hash) {
|
||||
to_dep_id = to_deps_off;
|
||||
while (to_dep_id < prev_i) : (to_dep_id += 1) {
|
||||
if (from_dep.name_hash == to_lockfile.buffers.dependencies.items[to_dep_id].name_hash) {
|
||||
const from_is_workspace_only = from_dep.behavior.isWorkspaceOnly();
|
||||
const to_is_workspace_only = to_deps[to_i].behavior.isWorkspaceOnly();
|
||||
const to_is_workspace_only = to_lockfile.buffers.dependencies.items[to_dep_id].behavior.isWorkspaceOnly();
|
||||
|
||||
if (from_is_workspace_only and to_is_workspace_only) {
|
||||
break :found;
|
||||
@@ -4487,9 +4483,49 @@ pub const Package = extern struct {
|
||||
summary.remove += 1;
|
||||
continue;
|
||||
}
|
||||
defer to_i += 1;
|
||||
defer to_dep_id += 1;
|
||||
|
||||
if (to_deps[to_i].eql(from_dep, to_lockfile.buffers.string_bytes.items, from_lockfile.buffers.string_bytes.items)) {
|
||||
const match = match: {
|
||||
const to_dep = to_lockfile.buffers.dependencies.items[to_dep_id];
|
||||
eql: {
|
||||
if (to_dep.version.tag != .npm) {
|
||||
break :eql;
|
||||
}
|
||||
if (from_dep_id >= from_lockfile.buffers.resolutions.items.len) {
|
||||
break :eql;
|
||||
}
|
||||
const from_dep_pkg_id = from_lockfile.buffers.resolutions.items[from_dep_id];
|
||||
if (from_dep_pkg_id >= from_lockfile.packages.len) {
|
||||
break :eql;
|
||||
}
|
||||
const from_res = from_pkg_resolutions[from_dep_pkg_id];
|
||||
if (from_res.tag != .npm) {
|
||||
break :eql;
|
||||
}
|
||||
|
||||
const equals = to_dep.eql(&from_dep, to_lockfile.buffers.string_bytes.items, from_lockfile.buffers.string_bytes.items);
|
||||
|
||||
if (equals) {
|
||||
break :match true;
|
||||
}
|
||||
|
||||
// if it satisfies we should not update the resolution
|
||||
const satisfies = to_dep.version.value.npm.version.satisfies(
|
||||
from_res.value.npm.version,
|
||||
to_lockfile.buffers.string_bytes.items,
|
||||
from_lockfile.buffers.string_bytes.items,
|
||||
);
|
||||
|
||||
// but we want the version to update in the lockfile
|
||||
summary.satisfied_versions += @intFromBool(satisfies);
|
||||
|
||||
break :match satisfies;
|
||||
}
|
||||
|
||||
break :match to_dep.eql(&from_dep, to_lockfile.buffers.string_bytes.items, from_lockfile.buffers.string_bytes.items);
|
||||
};
|
||||
|
||||
if (match) {
|
||||
if (update_requests) |updates| {
|
||||
if (updates.len == 0 or brk: {
|
||||
for (updates) |request| {
|
||||
@@ -4503,49 +4539,48 @@ pub const Package = extern struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (id_mapping) |mapping| {
|
||||
const version = to_deps[to_i].version;
|
||||
const update_mapping = switch (version.tag) {
|
||||
.workspace => if (to_lockfile.workspace_paths.getPtr(from_dep.name_hash)) |path_ptr| brk: {
|
||||
{
|
||||
const is_workspace_only = to_lockfile.buffers.dependencies.items[to_dep_id].behavior.isWorkspaceOnly();
|
||||
const is_workspace_version = to_lockfile.buffers.dependencies.items[to_dep_id].version.tag == .workspace;
|
||||
const update_mapping = !is_workspace_only or !is_workspace_version or update_mapping: {
|
||||
const path_ptr = to_lockfile.workspace_paths.getPtr(from_dep.name_hash) orelse {
|
||||
break :update_mapping false;
|
||||
};
|
||||
|
||||
{
|
||||
const path = to_lockfile.str(path_ptr);
|
||||
var local_buf: bun.PathBuffer = undefined;
|
||||
const package_json_path = Path.joinAbsStringBuf(FileSystem.instance.top_level_dir, &local_buf, &.{ path, "package.json" }, .auto);
|
||||
|
||||
const source = bun.sys.File.toSource(package_json_path, allocator).unwrap() catch {
|
||||
// Can't guarantee this workspace still exists
|
||||
break :brk false;
|
||||
};
|
||||
|
||||
var workspace = Package{};
|
||||
|
||||
const json = pm.workspace_package_json_cache.getWithSource(bun.default_allocator, log, source, .{}).unwrap() catch break :brk false;
|
||||
|
||||
var resolver: void = {};
|
||||
try workspace.parseWithJSON(
|
||||
to_lockfile,
|
||||
pm,
|
||||
allocator,
|
||||
log,
|
||||
source,
|
||||
json.root,
|
||||
void,
|
||||
&resolver,
|
||||
Features.workspace,
|
||||
const workspace_path = Path.joinAbsStringBuf(
|
||||
FileSystem.instance.top_level_dir,
|
||||
&local_buf,
|
||||
&[_]string{path},
|
||||
.auto,
|
||||
);
|
||||
|
||||
to_deps = to.dependencies.get(to_lockfile.buffers.dependencies.items);
|
||||
// version isn't used for workspaces
|
||||
const dummy_version: Dependency.Version = .{};
|
||||
const workspace_to_pkg_id = switch (FolderResolution.getOrPut(.{ .relative = .workspace }, dummy_version, workspace_path, pm, to_lockfile)) {
|
||||
.err => break :update_mapping false,
|
||||
.new_package_id, .package_id => |pkg_id| pkg_id,
|
||||
};
|
||||
|
||||
to_lockfile.buffers.resolutions.items[to_dep_id] = workspace_to_pkg_id;
|
||||
const workspace_from_pkg_id = from_lockfile.buffers.resolutions.items[from_dep_id];
|
||||
|
||||
try pkg_map.append(workspace_from_pkg_id);
|
||||
|
||||
var from_pkg = from_lockfile.packages.get(from_resolutions[i]);
|
||||
const diff = try generate(
|
||||
pm,
|
||||
allocator,
|
||||
log,
|
||||
from_lockfile,
|
||||
to_lockfile,
|
||||
&from_pkg,
|
||||
&workspace,
|
||||
workspace_from_pkg_id,
|
||||
workspace_to_pkg_id,
|
||||
update_requests,
|
||||
null,
|
||||
dep_map,
|
||||
pkg_map,
|
||||
);
|
||||
|
||||
if (PackageManager.verbose_install and (diff.add + diff.remove + diff.update) > 0) {
|
||||
@@ -4557,17 +4592,17 @@ pub const Package = extern struct {
|
||||
});
|
||||
}
|
||||
|
||||
break :brk !diff.hasDiffs();
|
||||
} else false,
|
||||
else => true,
|
||||
summary.satisfied_versions += diff.satisfied_versions;
|
||||
|
||||
break :update_mapping true;
|
||||
}
|
||||
};
|
||||
|
||||
if (update_mapping) {
|
||||
mapping[to_i] = @truncate(i);
|
||||
try dep_map.appendNTimes(invalid_dependency_id, (to_dep_id + 1) -| dep_map.items.len);
|
||||
dep_map.items[to_dep_id] = from_dep_id;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4578,16 +4613,18 @@ pub const Package = extern struct {
|
||||
// Use saturating arithmetic here because a migrated
|
||||
// package-lock.json could be out of sync with the package.json, so the
|
||||
// number of from_deps could be greater than to_deps.
|
||||
summary.add = @truncate((to_deps.len) -| (from_deps.len -| summary.remove));
|
||||
summary.add = @truncate((to_deps_len) -| (from_deps.len -| summary.remove));
|
||||
|
||||
if (from.resolution.tag != .root) {
|
||||
if (from_pkg_id == 0) {
|
||||
const to_scripts = to_lockfile.packages.items(.scripts)[to_pkg_id];
|
||||
const from_scripts = from_pkg_scripts[from_pkg_id];
|
||||
inline for (Lockfile.Scripts.names) |hook| {
|
||||
if (!@field(to.scripts, hook).eql(
|
||||
@field(from.scripts, hook),
|
||||
if (!@field(to_scripts, hook).eql(
|
||||
@field(from_scripts, hook),
|
||||
to_lockfile.buffers.string_bytes.items,
|
||||
from_lockfile.buffers.string_bytes.items,
|
||||
)) {
|
||||
// We found a changed life-cycle script
|
||||
// We found a changes life-cycle script
|
||||
summary.update += 1;
|
||||
}
|
||||
}
|
||||
@@ -4637,7 +4674,6 @@ pub const Package = extern struct {
|
||||
|
||||
fn parseDependency(
|
||||
lockfile: *Lockfile,
|
||||
pm: *PackageManager,
|
||||
allocator: Allocator,
|
||||
log: *logger.Log,
|
||||
source: logger.Source,
|
||||
@@ -4687,7 +4723,6 @@ pub const Package = extern struct {
|
||||
tag,
|
||||
&sliced,
|
||||
log,
|
||||
pm,
|
||||
) orelse Dependency.Version{};
|
||||
var workspace_range: ?Semver.Query.Group = null;
|
||||
const name_hash = switch (dependency_version.tag) {
|
||||
@@ -4698,14 +4733,14 @@ pub const Package = extern struct {
|
||||
if (trimmed.len != 1 or (trimmed[0] != '*' and trimmed[0] != '^' and trimmed[0] != '~')) {
|
||||
const at = strings.lastIndexOfChar(input, '@') orelse 0;
|
||||
if (at > 0) {
|
||||
workspace_range = Semver.Query.parse(allocator, input[at + 1 ..], sliced) catch |err| {
|
||||
workspace_range = Semver.Query.parse(allocator, sliced.sub(input[at + 1 ..])) catch |err| {
|
||||
switch (err) {
|
||||
error.OutOfMemory => bun.outOfMemory(),
|
||||
}
|
||||
};
|
||||
break :brk String.Builder.stringHash(input[0..at]);
|
||||
}
|
||||
workspace_range = Semver.Query.parse(allocator, input, sliced) catch |err| {
|
||||
workspace_range = Semver.Query.parse(allocator, sliced.sub(input)) catch |err| {
|
||||
switch (err) {
|
||||
error.OutOfMemory => bun.outOfMemory(),
|
||||
}
|
||||
@@ -4756,7 +4791,6 @@ pub const Package = extern struct {
|
||||
.workspace,
|
||||
&path,
|
||||
log,
|
||||
pm,
|
||||
)) |dep| {
|
||||
dependency_version.tag = dep.tag;
|
||||
dependency_version.value = dep.value;
|
||||
@@ -4788,7 +4822,8 @@ pub const Package = extern struct {
|
||||
}
|
||||
|
||||
// important to trim before len == 0 check. `workspace:foo@ ` should install successfully
|
||||
const version_literal = strings.trim(range.input, &strings.whitespace_chars);
|
||||
const range_input = range.input.slice(lockfile.buffers.string_bytes.items);
|
||||
const version_literal = strings.trim(range_input, &strings.whitespace_chars);
|
||||
if (version_literal.len == 0 or range.@"is *"() or Semver.Version.isTaggedVersionOnly(version_literal)) {
|
||||
dependency_version.value.workspace = path;
|
||||
break :workspace;
|
||||
@@ -5860,7 +5895,6 @@ pub const Package = extern struct {
|
||||
|
||||
if (try parseDependency(
|
||||
lockfile,
|
||||
pm,
|
||||
allocator,
|
||||
log,
|
||||
source,
|
||||
@@ -5903,7 +5937,6 @@ pub const Package = extern struct {
|
||||
|
||||
if (try parseDependency(
|
||||
lockfile,
|
||||
pm,
|
||||
allocator,
|
||||
log,
|
||||
source,
|
||||
@@ -5960,7 +5993,7 @@ pub const Package = extern struct {
|
||||
|
||||
// This function depends on package.dependencies being set, so it is done at the very end.
|
||||
if (comptime features.is_main) {
|
||||
try lockfile.overrides.parseAppend(pm, lockfile, package, log, source, json, &string_builder);
|
||||
try lockfile.overrides.parseAppend(lockfile, package, log, source, json, &string_builder);
|
||||
}
|
||||
|
||||
string_builder.clamp();
|
||||
@@ -6565,7 +6598,6 @@ const Buffers = struct {
|
||||
.log = log,
|
||||
.allocator = allocator,
|
||||
.buffer = string_buf,
|
||||
.package_manager = pm_,
|
||||
};
|
||||
|
||||
this.dependencies.expandToCapacity();
|
||||
@@ -6961,7 +6993,6 @@ pub const Serializer = struct {
|
||||
.allocator = allocator,
|
||||
.log = log,
|
||||
.buffer = lockfile.buffers.string_bytes.items,
|
||||
.package_manager = manager,
|
||||
};
|
||||
for (overrides_name_hashes.items, override_versions_external.items) |name, value| {
|
||||
map.putAssumeCapacity(name, Dependency.toDependency(value, context));
|
||||
|
||||
@@ -719,7 +719,6 @@ pub fn migrateNPMLockfile(
|
||||
sliced.slice,
|
||||
&sliced,
|
||||
log,
|
||||
manager,
|
||||
) orelse {
|
||||
return error.InvalidNPMLockfile;
|
||||
};
|
||||
@@ -802,7 +801,6 @@ pub fn migrateNPMLockfile(
|
||||
tag,
|
||||
&dep_resolved_sliced,
|
||||
log,
|
||||
manager,
|
||||
) orelse return error.InvalidNPMLockfile;
|
||||
|
||||
break :dep_resolved dep_resolved;
|
||||
@@ -1010,7 +1008,7 @@ pub fn migrateNPMLockfile(
|
||||
// but after we write all the data, there is no excuse for this to fail.
|
||||
//
|
||||
// If this is hit, it means getOrPutID was not called on this package id. Look for where 'resolution[i]' is set
|
||||
bun.assert(this.getPackageID(this.packages.items(.name_hash)[i], null, &r) != null);
|
||||
bun.assert(this.getPackageID(this.packages.items(.name_hash)[i], &r) != null);
|
||||
}
|
||||
}
|
||||
if (is_missing_resolutions) {
|
||||
|
||||
@@ -169,8 +169,8 @@ pub const FolderResolution = union(Tag) {
|
||||
|
||||
fn readPackageJSONFromDisk(
|
||||
manager: *PackageManager,
|
||||
lockfile: *Lockfile,
|
||||
abs: stringZ,
|
||||
version: Dependency.Version,
|
||||
comptime features: Features,
|
||||
comptime ResolverType: type,
|
||||
resolver: *ResolverType,
|
||||
@@ -184,7 +184,7 @@ pub const FolderResolution = union(Tag) {
|
||||
const json = try manager.workspace_package_json_cache.getWithPath(manager.allocator, manager.log, abs, .{}).unwrap();
|
||||
|
||||
try package.parseWithJSON(
|
||||
manager.lockfile,
|
||||
lockfile,
|
||||
manager,
|
||||
manager.allocator,
|
||||
manager.log,
|
||||
@@ -215,7 +215,7 @@ pub const FolderResolution = union(Tag) {
|
||||
};
|
||||
|
||||
try package.parse(
|
||||
manager.lockfile,
|
||||
lockfile,
|
||||
manager,
|
||||
manager.allocator,
|
||||
manager.log,
|
||||
@@ -238,13 +238,13 @@ pub const FolderResolution = union(Tag) {
|
||||
|
||||
package.meta.setHasInstallScript(has_scripts);
|
||||
|
||||
if (manager.lockfile.getPackageID(package.name_hash, version, &package.resolution)) |existing_id| {
|
||||
if (lockfile.getPackageID(package.name_hash, &package.resolution)) |existing_id| {
|
||||
package.meta.id = existing_id;
|
||||
manager.lockfile.packages.set(existing_id, package);
|
||||
return manager.lockfile.packages.get(existing_id);
|
||||
}
|
||||
|
||||
return manager.lockfile.appendPackage(package);
|
||||
return lockfile.appendPackage(package);
|
||||
}
|
||||
|
||||
pub const GlobalOrRelative = union(enum) {
|
||||
@@ -253,7 +253,7 @@ pub const FolderResolution = union(Tag) {
|
||||
cache_folder: []const u8,
|
||||
};
|
||||
|
||||
pub fn getOrPut(global_or_relative: GlobalOrRelative, version: Dependency.Version, non_normalized_path: string, manager: *PackageManager) FolderResolution {
|
||||
pub fn getOrPut(global_or_relative: GlobalOrRelative, version: Dependency.Version, non_normalized_path: string, manager: *PackageManager, lockfile: *Lockfile) FolderResolution {
|
||||
var joined: bun.PathBuffer = undefined;
|
||||
const paths = normalizePackageJSONPath(global_or_relative, &joined, non_normalized_path);
|
||||
const abs = paths.abs;
|
||||
@@ -266,7 +266,7 @@ pub const FolderResolution = union(Tag) {
|
||||
}
|
||||
const abs_hash = hash(abs);
|
||||
|
||||
const entry = manager.folders.getOrPut(manager.allocator, abs_hash) catch unreachable;
|
||||
const entry = lockfile.folder_resolutions.getOrPut(lockfile.allocator, abs_hash) catch unreachable;
|
||||
if (entry.found_existing) return entry.value_ptr.*;
|
||||
|
||||
const package: Lockfile.Package = switch (global_or_relative) {
|
||||
@@ -278,8 +278,8 @@ pub const FolderResolution = union(Tag) {
|
||||
};
|
||||
break :global readPackageJSONFromDisk(
|
||||
manager,
|
||||
lockfile,
|
||||
abs,
|
||||
version,
|
||||
Features.link,
|
||||
SymlinkResolver,
|
||||
&resolver,
|
||||
@@ -292,8 +292,8 @@ pub const FolderResolution = union(Tag) {
|
||||
};
|
||||
break :folder readPackageJSONFromDisk(
|
||||
manager,
|
||||
lockfile,
|
||||
abs,
|
||||
version,
|
||||
Features.folder,
|
||||
Resolver,
|
||||
&resolver,
|
||||
@@ -305,8 +305,8 @@ pub const FolderResolution = union(Tag) {
|
||||
};
|
||||
break :workspace readPackageJSONFromDisk(
|
||||
manager,
|
||||
lockfile,
|
||||
abs,
|
||||
version,
|
||||
Features.workspace,
|
||||
WorkspaceResolver,
|
||||
&resolver,
|
||||
@@ -320,8 +320,8 @@ pub const FolderResolution = union(Tag) {
|
||||
};
|
||||
break :cache_folder readPackageJSONFromDisk(
|
||||
manager,
|
||||
lockfile,
|
||||
abs,
|
||||
version,
|
||||
Features.npm,
|
||||
CacheFolderResolver,
|
||||
&resolver,
|
||||
|
||||
@@ -2111,7 +2111,7 @@ pub const Query = struct {
|
||||
head: List = List{},
|
||||
tail: ?*List = null,
|
||||
allocator: Allocator,
|
||||
input: string = "",
|
||||
input: String = .{},
|
||||
|
||||
flags: FlagsBitSet = FlagsBitSet.initEmpty(),
|
||||
pub const Flags = struct {
|
||||
@@ -2537,14 +2537,14 @@ pub const Query = struct {
|
||||
|
||||
pub fn parse(
|
||||
allocator: Allocator,
|
||||
input: string,
|
||||
sliced: SlicedString,
|
||||
) bun.OOM!Group {
|
||||
var i: usize = 0;
|
||||
var list = Group{
|
||||
.allocator = allocator,
|
||||
.input = input,
|
||||
.input = sliced.value(),
|
||||
};
|
||||
const input = sliced.slice;
|
||||
|
||||
var token = Token{};
|
||||
var prev_token = Token{};
|
||||
@@ -2871,7 +2871,6 @@ pub const SemverObject = struct {
|
||||
|
||||
const right_group = try Query.parse(
|
||||
allocator,
|
||||
right.slice(),
|
||||
SlicedString.init(right.slice(), right.slice()),
|
||||
);
|
||||
defer right_group.deinit();
|
||||
|
||||
@@ -857,7 +857,6 @@ pub const PackageJSON = struct {
|
||||
.npm,
|
||||
&sliced,
|
||||
r.log,
|
||||
pm,
|
||||
)) |dependency_version| {
|
||||
if (dependency_version.value.npm.version.isExact()) {
|
||||
if (pm.lockfile.resolvePackageFromNameAndVersion(package_json.name, dependency_version)) |resolved| {
|
||||
@@ -979,7 +978,6 @@ pub const PackageJSON = struct {
|
||||
version_str,
|
||||
&sliced_str,
|
||||
r.log,
|
||||
r.package_manager,
|
||||
)) |dependency_version| {
|
||||
const dependency = Dependency{
|
||||
.name = name,
|
||||
|
||||
@@ -1891,7 +1891,6 @@ pub const Resolver = struct {
|
||||
esm.version,
|
||||
&sliced_string,
|
||||
r.log,
|
||||
manager,
|
||||
) orelse break :load_module_from_cache;
|
||||
}
|
||||
|
||||
@@ -2216,7 +2215,6 @@ pub const Resolver = struct {
|
||||
if (package_json_) |package_json| {
|
||||
package = Package.fromPackageJSON(
|
||||
pm.lockfile,
|
||||
pm,
|
||||
package_json,
|
||||
Install.Features{
|
||||
.dev_dependencies = true,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -11,7 +11,6 @@ import {
|
||||
mergeWindowEnvs,
|
||||
runBunInstall,
|
||||
runBunUpdate,
|
||||
pack,
|
||||
tempDirWithFiles,
|
||||
tmpdirSync,
|
||||
toBeValidBin,
|
||||
@@ -20,8 +19,6 @@ import {
|
||||
writeShebangScript,
|
||||
stderrForInstall,
|
||||
tls,
|
||||
isFlaky,
|
||||
isMacOS,
|
||||
readdirSorted,
|
||||
VerdaccioRegistry,
|
||||
} from "harness";
|
||||
@@ -42,8 +39,6 @@ var packageDir: string;
|
||||
/** packageJson = join(packageDir, "package.json"); */
|
||||
var packageJson: string;
|
||||
|
||||
let users: Record<string, string> = {};
|
||||
|
||||
beforeAll(async () => {
|
||||
setDefaultTimeout(1000 * 60 * 5);
|
||||
verdaccio = new VerdaccioRegistry();
|
||||
@@ -52,15 +47,11 @@ beforeAll(async () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await Bun.$`rm -f ${import.meta.dir}/htpasswd`.throws(false);
|
||||
verdaccio.stop();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
({ packageDir, packageJson } = await verdaccio.createTestDir({ saveTextLockfile: false }));
|
||||
await Bun.$`rm -f ${import.meta.dir}/htpasswd`.throws(false);
|
||||
await Bun.$`rm -rf ${import.meta.dir}/packages/private-pkg-dont-touch`.throws(false);
|
||||
users = {};
|
||||
env.BUN_INSTALL_CACHE_DIR = join(packageDir, ".bun-cache");
|
||||
env.BUN_TMPDIR = env.TMPDIR = env.TEMP = join(packageDir, ".bun-tmp");
|
||||
});
|
||||
@@ -69,37 +60,6 @@ function registryUrl() {
|
||||
return verdaccio.registryUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns auth token
|
||||
*/
|
||||
async function generateRegistryUser(username: string, password: string): Promise<string> {
|
||||
if (users[username]) {
|
||||
throw new Error("that user already exists");
|
||||
} else users[username] = password;
|
||||
|
||||
const url = `http://localhost:${port}/-/user/org.couchdb.user:${username}`;
|
||||
const user = {
|
||||
name: username,
|
||||
password: password,
|
||||
email: `${username}@example.com`,
|
||||
};
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(user),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
return data.token;
|
||||
} else {
|
||||
throw new Error("Failed to create user:", response.statusText);
|
||||
}
|
||||
}
|
||||
|
||||
describe("npmrc", async () => {
|
||||
const isBase64Encoded = (opt: string) => opt === "_auth" || opt === "_password";
|
||||
|
||||
@@ -330,7 +290,7 @@ ${iniInner.join("\n")}
|
||||
const ini = /* ini */ `
|
||||
registry = http://localhost:${port}/
|
||||
@needs-auth:registry=http://localhost:${port}/
|
||||
//localhost:${port}/:_authToken=${await generateRegistryUser("bilbo_swaggins", "verysecure")}
|
||||
//localhost:${port}/:_authToken=${await verdaccio.generateUser("bilbo_swaggins", "verysecure")}
|
||||
`;
|
||||
|
||||
await Bun.$`echo ${ini} > ${packageDir}/.npmrc`;
|
||||
@@ -415,21 +375,21 @@ ${Object.keys(opts)
|
||||
}
|
||||
|
||||
registryConfigOptionTest("_authToken", async () => ({
|
||||
"_authToken": await generateRegistryUser("bilbo_baggins", "verysecure"),
|
||||
"_authToken": await verdaccio.generateUser("bilbo_baggins", "verysecure"),
|
||||
}));
|
||||
registryConfigOptionTest(
|
||||
"_authToken with env variable value",
|
||||
async () => ({ _authToken: "${SUPER_SECRET_TOKEN}" }),
|
||||
async () => ({ SUPER_SECRET_TOKEN: await generateRegistryUser("bilbo_baggins420", "verysecure") }),
|
||||
async () => ({ SUPER_SECRET_TOKEN: await verdaccio.generateUser("bilbo_baggins420", "verysecure") }),
|
||||
);
|
||||
registryConfigOptionTest("username and password", async () => {
|
||||
await generateRegistryUser("gandalf429", "verysecure");
|
||||
await verdaccio.generateUser("gandalf429", "verysecure");
|
||||
return { username: "gandalf429", _password: "verysecure" };
|
||||
});
|
||||
registryConfigOptionTest(
|
||||
"username and password with env variable password",
|
||||
async () => {
|
||||
await generateRegistryUser("gandalf422", "verysecure");
|
||||
await verdaccio.generateUser("gandalf422", "verysecure");
|
||||
return { username: "gandalf422", _password: "${SUPER_SECRET_PASSWORD}" };
|
||||
},
|
||||
{
|
||||
@@ -439,7 +399,7 @@ ${Object.keys(opts)
|
||||
registryConfigOptionTest(
|
||||
"username and password with .env variable password",
|
||||
async () => {
|
||||
await generateRegistryUser("gandalf421", "verysecure");
|
||||
await verdaccio.generateUser("gandalf421", "verysecure");
|
||||
return { username: "gandalf421", _password: "${SUPER_SECRET_PASSWORD}" };
|
||||
},
|
||||
{
|
||||
@@ -448,7 +408,7 @@ ${Object.keys(opts)
|
||||
);
|
||||
|
||||
registryConfigOptionTest("_auth", async () => {
|
||||
await generateRegistryUser("linus", "verysecure");
|
||||
await verdaccio.generateUser("linus", "verysecure");
|
||||
const _auth = "linus:verysecure";
|
||||
return { _auth };
|
||||
});
|
||||
@@ -456,7 +416,7 @@ ${Object.keys(opts)
|
||||
registryConfigOptionTest(
|
||||
"_auth from .env variable",
|
||||
async () => {
|
||||
await generateRegistryUser("zack", "verysecure");
|
||||
await verdaccio.generateUser("zack", "verysecure");
|
||||
return { _auth: "${SECRET_AUTH}" };
|
||||
},
|
||||
{
|
||||
@@ -467,7 +427,7 @@ ${Object.keys(opts)
|
||||
registryConfigOptionTest(
|
||||
"_auth from .env variable with no value",
|
||||
async () => {
|
||||
await generateRegistryUser("zack420", "verysecure");
|
||||
await verdaccio.generateUser("zack420", "verysecure");
|
||||
return { _auth: "${SECRET_AUTH}" };
|
||||
},
|
||||
{
|
||||
@@ -742,155 +702,6 @@ ljelkjwelkgjw;lekj;lkejflkj
|
||||
});
|
||||
});
|
||||
|
||||
describe("whoami", async () => {
|
||||
test("can get username", async () => {
|
||||
const bunfig = await verdaccio.authBunfig("whoami");
|
||||
await Promise.all([
|
||||
write(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
name: "whoami-pkg",
|
||||
version: "1.1.1",
|
||||
}),
|
||||
),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
]);
|
||||
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("username from .npmrc", async () => {
|
||||
// It should report the username from npmrc, even without an account
|
||||
const bunfig = `
|
||||
[install]
|
||||
cache = false
|
||||
registry = "http://localhost:${port}/"`;
|
||||
const npmrc = `
|
||||
//localhost:${port}/:username=whoami-npmrc
|
||||
//localhost:${port}/:_password=123456
|
||||
`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
write(join(packageDir, ".npmrc"), npmrc),
|
||||
]);
|
||||
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("only .npmrc", async () => {
|
||||
const token = await generateRegistryUser("whoami-npmrc", "whoami-npmrc");
|
||||
const npmrc = `
|
||||
//localhost:${port}/:_authToken=${token}
|
||||
registry=http://localhost:${port}/`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, ".npmrc"), npmrc),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("two .npmrc", async () => {
|
||||
const token = await generateRegistryUser("whoami-two-npmrc", "whoami-two-npmrc");
|
||||
const packageNpmrc = `registry=http://localhost:${port}/`;
|
||||
const homeNpmrc = `//localhost:${port}/:_authToken=${token}`;
|
||||
const homeDir = `${packageDir}/home_dir`;
|
||||
await Bun.$`mkdir -p ${homeDir}`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, ".npmrc"), packageNpmrc),
|
||||
write(join(homeDir, ".npmrc"), homeNpmrc),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env: {
|
||||
...env,
|
||||
XDG_CONFIG_HOME: `${homeDir}`,
|
||||
},
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-two-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("not logged in", async () => {
|
||||
await write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" }));
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBeEmpty();
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).toBe("error: missing authentication (run `bunx npm login`)\n");
|
||||
expect(await exited).toBe(1);
|
||||
});
|
||||
test("invalid token", async () => {
|
||||
// create the user and provide an invalid token
|
||||
const token = await generateRegistryUser("invalid-token", "invalid-token");
|
||||
const bunfig = `
|
||||
[install]
|
||||
cache = false
|
||||
registry = { url = "http://localhost:${port}/", token = "1234567" }`;
|
||||
await rm(join(packageDir, "bunfig.toml"));
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBeEmpty();
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).toBe(`error: failed to authenticate with registry 'http://localhost:${port}/'\n`);
|
||||
expect(await exited).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("package.json indentation", async () => {
|
||||
test("works for root and workspace packages", async () => {
|
||||
await Promise.all([
|
||||
@@ -2573,19 +2384,15 @@ test("package added after install", async () => {
|
||||
"",
|
||||
expect.stringContaining("+ no-deps@1.0.0"),
|
||||
"",
|
||||
"2 packages installed",
|
||||
"1 package installed",
|
||||
]);
|
||||
expect(await file(join(packageDir, "node_modules", "no-deps", "package.json")).json()).toEqual({
|
||||
name: "no-deps",
|
||||
version: "1.0.0",
|
||||
} as any);
|
||||
expect(
|
||||
await file(join(packageDir, "node_modules", "one-range-dep", "node_modules", "no-deps", "package.json")).json(),
|
||||
).toEqual({
|
||||
name: "no-deps",
|
||||
version: "1.1.0",
|
||||
} as any);
|
||||
expect(await exited).toBe(0);
|
||||
expect(
|
||||
await Promise.all([
|
||||
file(join(packageDir, "node_modules", "no-deps", "package.json")).json(),
|
||||
exists(join(packageDir, "node_modules", "one-range-dep", "node_modules")),
|
||||
]),
|
||||
).toEqual([{ name: "no-deps", version: "1.0.0" }, false]);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
|
||||
await rm(join(packageDir, "node_modules"), { recursive: true, force: true });
|
||||
@@ -2610,7 +2417,7 @@ test("package added after install", async () => {
|
||||
expect.stringContaining("+ no-deps@1.0.0"),
|
||||
"+ one-range-dep@1.0.0",
|
||||
"",
|
||||
"3 packages installed",
|
||||
"2 packages installed",
|
||||
]);
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
@@ -4006,87 +3813,84 @@ describe("hoisting", async () => {
|
||||
},
|
||||
];
|
||||
for (const { dependencies, expected, situation } of peerTests) {
|
||||
test.todoIf(isFlaky && isMacOS && situation === "peer ^1.0.2")(
|
||||
`it should hoist ${expected} when ${situation}`,
|
||||
async () => {
|
||||
await writeFile(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
name: "foo",
|
||||
dependencies,
|
||||
}),
|
||||
);
|
||||
test(`it should hoist ${expected} when ${situation}`, async () => {
|
||||
await writeFile(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
name: "foo",
|
||||
dependencies,
|
||||
}),
|
||||
);
|
||||
|
||||
var { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
var { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
|
||||
var err = await new Response(stderr).text();
|
||||
var out = await new Response(stdout).text();
|
||||
expect(err).toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
for (const dep of Object.keys(dependencies)) {
|
||||
expect(out).toContain(`+ ${dep}@${dependencies[dep]}`);
|
||||
}
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
var err = await new Response(stderr).text();
|
||||
var out = await new Response(stdout).text();
|
||||
expect(err).toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
for (const dep of Object.keys(dependencies)) {
|
||||
expect(out).toContain(`+ ${dep}@${dependencies[dep]}`);
|
||||
}
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
|
||||
await rm(join(packageDir, "bun.lockb"));
|
||||
await rm(join(packageDir, "bun.lockb"));
|
||||
|
||||
({ stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
}));
|
||||
({ stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
}));
|
||||
|
||||
err = await new Response(stderr).text();
|
||||
out = await new Response(stdout).text();
|
||||
expect(err).toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
if (out.includes("installed")) {
|
||||
console.log("stdout:", out);
|
||||
}
|
||||
expect(out).not.toContain("package installed");
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
err = await new Response(stderr).text();
|
||||
out = await new Response(stdout).text();
|
||||
expect(err).toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
if (out.includes("installed")) {
|
||||
console.log("stdout:", out);
|
||||
}
|
||||
expect(out).not.toContain("package installed");
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
|
||||
await rm(join(packageDir, "node_modules"), { recursive: true, force: true });
|
||||
await rm(join(packageDir, "node_modules"), { recursive: true, force: true });
|
||||
|
||||
({ stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
}));
|
||||
({ stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stdin: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
}));
|
||||
|
||||
err = await new Response(stderr).text();
|
||||
out = await new Response(stdout).text();
|
||||
expect(err).not.toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
expect(out).not.toContain("package installed");
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
err = await new Response(stderr).text();
|
||||
out = await new Response(stdout).text();
|
||||
expect(err).not.toContain("Saved lockfile");
|
||||
expect(err).not.toContain("not found");
|
||||
expect(err).not.toContain("error:");
|
||||
expect(out).not.toContain("package installed");
|
||||
expect(await exited).toBe(0);
|
||||
assertManifestsPopulated(join(packageDir, ".bun-cache"), registryUrl());
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
},
|
||||
);
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).text()).toContain(expected);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5017,7 +4821,11 @@ describe("transitive file dependencies", () => {
|
||||
"",
|
||||
"+ @another-scope/file-dep@1.0.0",
|
||||
"+ @scoped/file-dep@1.0.0",
|
||||
"+ aliased-file-dep@1.0.1",
|
||||
// 'aliased-file-dep' is hoisted to the root, because
|
||||
// it coming from the registry, and since this
|
||||
// install is from the workspace, it won't be included
|
||||
// in the terminal output
|
||||
// "+ aliased-file-dep@1.0.1",
|
||||
"+ dep-file-dep@1.0.0",
|
||||
expect.stringContaining("+ file-dep@1.0.0"),
|
||||
"+ missing-file-dep@1.0.0",
|
||||
@@ -5048,7 +4856,7 @@ describe("transitive file dependencies", () => {
|
||||
"",
|
||||
"+ @another-scope/file-dep@1.0.0",
|
||||
"+ @scoped/file-dep@1.0.0",
|
||||
"+ aliased-file-dep@1.0.1",
|
||||
// "+ aliased-file-dep@1.0.1",
|
||||
"+ dep-file-dep@1.0.0",
|
||||
expect.stringContaining("+ file-dep@1.0.0"),
|
||||
"+ missing-file-dep@1.0.0",
|
||||
@@ -6193,6 +6001,40 @@ describe("update", () => {
|
||||
|
||||
expect(files).toMatchObject([{ version: "2.0.0" }, { dependencies: { "no-deps": "2.0.0" } }]);
|
||||
});
|
||||
|
||||
test("updating a dependency will deduplicate it if possible", async () => {
|
||||
await write(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
name: "foo",
|
||||
dependencies: {
|
||||
"zzz-1": "1.0.89",
|
||||
"zzz-2": "1.0.89",
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const { exited } = spawn({
|
||||
cmd: [bunExe(), "install", "--save-text-lockfile"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
});
|
||||
expect(await exited).toBe(0);
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "zzz-1", "package.json")).json()).toEqual({
|
||||
name: "zzz-1",
|
||||
version: "1.0.89",
|
||||
});
|
||||
|
||||
await runBunUpdate(env, packageDir, ["--latest"]);
|
||||
|
||||
expect(
|
||||
await Promise.all([
|
||||
file(join(packageDir, "node_modules", "zzz-1", "package.json")).json(),
|
||||
exists(join(packageDir, "node_modules", "zzz-2", "node_modules")),
|
||||
]),
|
||||
).toEqual([{ name: "zzz-1", version: "1.0.90" }, false]);
|
||||
});
|
||||
});
|
||||
|
||||
test("packages dependening on each other with aliases does not infinitely loop", async () => {
|
||||
|
||||
@@ -2978,8 +2978,13 @@ it("should get npm alias with matching version", async () => {
|
||||
"2 packages installed",
|
||||
]);
|
||||
expect(await exited).toBe(0);
|
||||
expect(urls.sort()).toEqual([`${root_url}/baz`, `${root_url}/baz-0.0.5.tgz`]);
|
||||
expect(requested).toBe(2);
|
||||
expect(urls.sort()).toEqual([
|
||||
`${root_url}/baz`,
|
||||
`${root_url}/baz-0.0.5.tgz`,
|
||||
`${root_url}/boba`,
|
||||
`${root_url}/boba-0.0.5.tgz`,
|
||||
]);
|
||||
expect(requested).toBe(4);
|
||||
expect(await readdirSorted(join(package_dir, "node_modules"))).toEqual([".cache", "boba", "moo"]);
|
||||
expect(await file(join(package_dir, "node_modules", "boba", "package.json")).json()).toEqual({
|
||||
name: "baz",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { spawn, write, file } from "bun";
|
||||
import { expect, it, beforeAll, afterAll } from "bun:test";
|
||||
import { expect, it, beforeAll, afterAll, beforeEach } from "bun:test";
|
||||
import { access, copyFile, open, writeFile, exists, cp } from "fs/promises";
|
||||
import { bunExe, bunEnv as env, isWindows, VerdaccioRegistry, runBunInstall } from "harness";
|
||||
import { join } from "path";
|
||||
|
||||
var registry = new VerdaccioRegistry();
|
||||
const registry = new VerdaccioRegistry();
|
||||
|
||||
beforeAll(async () => {
|
||||
await registry.start();
|
||||
@@ -14,6 +14,109 @@ afterAll(() => {
|
||||
registry.stop();
|
||||
});
|
||||
|
||||
it("should update dependency version literal when no updates are necessary", async () => {
|
||||
const { packageDir, packageJson } = await registry.createTestDir();
|
||||
await Promise.all([
|
||||
write(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
workspaces: ["packages/*"],
|
||||
dependencies: {
|
||||
"no-deps": "1.0.0",
|
||||
},
|
||||
}),
|
||||
),
|
||||
write(
|
||||
join(packageDir, "packages", "pkg1", "package.json"),
|
||||
JSON.stringify({
|
||||
name: "pkg1",
|
||||
dependencies: {
|
||||
"a-dep": "1.0.1",
|
||||
},
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
let { exited } = spawn({
|
||||
cmd: [bunExe(), "install", "--save-text-lockfile"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
});
|
||||
|
||||
expect(await exited).toBe(0);
|
||||
|
||||
const firstLockfile = (await file(join(packageDir, "bun.lock")).text()).replaceAll(
|
||||
/localhost:\d+/g,
|
||||
"localhost:1234",
|
||||
);
|
||||
expect(firstLockfile).toMatchSnapshot();
|
||||
|
||||
// "no-deps" is updated, but the version still satisfies the resolved
|
||||
// package in the lockfile. no install should happen, but the dependency
|
||||
// string in the lockfile should be updated.
|
||||
await write(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
workspaces: ["packages/*"],
|
||||
dependencies: {
|
||||
"no-deps": "^1.0.0",
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
({ exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
}));
|
||||
|
||||
expect(await exited).toBe(0);
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "no-deps", "package.json")).json()).toEqual({
|
||||
name: "no-deps",
|
||||
version: "1.0.0",
|
||||
});
|
||||
|
||||
const secondLockfile = (await file(join(packageDir, "bun.lock")).text()).replaceAll(
|
||||
/localhost:\d+/g,
|
||||
"localhost:1234",
|
||||
);
|
||||
expect(firstLockfile).not.toBe(secondLockfile);
|
||||
expect(secondLockfile).toMatchSnapshot();
|
||||
|
||||
// now the same with "a-dep" in the workspace
|
||||
await write(
|
||||
join(packageDir, "packages", "pkg1", "package.json"),
|
||||
JSON.stringify({
|
||||
name: "pkg1",
|
||||
dependencies: {
|
||||
"a-dep": "^1.0.1",
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
({ exited } = spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
}));
|
||||
|
||||
expect(await exited).toBe(0);
|
||||
|
||||
expect(await file(join(packageDir, "node_modules", "a-dep", "package.json")).json()).toEqual({
|
||||
name: "a-dep",
|
||||
version: "1.0.1",
|
||||
});
|
||||
|
||||
const thirdLockfile = (await file(join(packageDir, "bun.lock")).text()).replaceAll(
|
||||
/localhost:\d+/g,
|
||||
"localhost:1234",
|
||||
);
|
||||
expect(thirdLockfile).not.toBe(secondLockfile);
|
||||
expect(thirdLockfile).not.toBe(firstLockfile);
|
||||
expect(thirdLockfile).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should write plaintext lockfiles", async () => {
|
||||
const { packageDir, packageJson } = await registry.createTestDir();
|
||||
// copy bar-0.0.2.tgz to package_dir
|
||||
|
||||
169
test/cli/install/bun-whoami.test.ts
Normal file
169
test/cli/install/bun-whoami.test.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import { test, expect, beforeAll, beforeEach, afterAll } from "bun:test";
|
||||
import { join } from "path";
|
||||
import { bunExe, bunEnv as env, VerdaccioRegistry } from "harness";
|
||||
import { spawn, write } from "bun";
|
||||
|
||||
var verdaccio: VerdaccioRegistry;
|
||||
var packageDir: string;
|
||||
var packageJson: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
verdaccio = new VerdaccioRegistry();
|
||||
await verdaccio.start();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
verdaccio.stop();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
({ packageDir, packageJson } = await verdaccio.createTestDir());
|
||||
env.BUN_INSTALL_CACHE_DIR = join(packageDir, ".bun-cache");
|
||||
env.BUN_TMPDIR = env.TMPDIR = env.TEMP = join(packageDir, ".bun-tmp");
|
||||
});
|
||||
|
||||
test("can get username", async () => {
|
||||
const bunfig = await verdaccio.authBunfig("whoami");
|
||||
await Promise.all([
|
||||
write(
|
||||
packageJson,
|
||||
JSON.stringify({
|
||||
name: "whoami-pkg",
|
||||
version: "1.1.1",
|
||||
}),
|
||||
),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
]);
|
||||
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("username from .npmrc", async () => {
|
||||
// It should report the username from npmrc, even without an account
|
||||
const bunfig = `
|
||||
[install]
|
||||
cache = false
|
||||
registry = "http://localhost:${verdaccio.port}/"`;
|
||||
const npmrc = `
|
||||
//localhost:${verdaccio.port}/:username=whoami-npmrc
|
||||
//localhost:${verdaccio.port}/:_password=123456
|
||||
`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
write(join(packageDir, ".npmrc"), npmrc),
|
||||
]);
|
||||
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("only .npmrc", async () => {
|
||||
const token = await verdaccio.generateUser("whoami-npmrc", "whoami-npmrc");
|
||||
const npmrc = `
|
||||
//localhost:${verdaccio.port}/:_authToken=${token}
|
||||
registry=http://localhost:${verdaccio.port}/`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, ".npmrc"), npmrc),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env,
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("two .npmrc", async () => {
|
||||
const token = await verdaccio.generateUser("whoami-two-npmrc", "whoami-two-npmrc");
|
||||
const packageNpmrc = `registry=http://localhost:${verdaccio.port}/`;
|
||||
const homeNpmrc = `//localhost:${verdaccio.port}/:_authToken=${token}`;
|
||||
const homeDir = `${packageDir}/home_dir`;
|
||||
await Bun.$`mkdir -p ${homeDir}`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, ".npmrc"), packageNpmrc),
|
||||
write(join(homeDir, ".npmrc"), homeNpmrc),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env: {
|
||||
...env,
|
||||
XDG_CONFIG_HOME: `${homeDir}`,
|
||||
},
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBe("whoami-two-npmrc\n");
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).not.toContain("error:");
|
||||
expect(await exited).toBe(0);
|
||||
});
|
||||
test("not logged in", async () => {
|
||||
await write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" }));
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBeEmpty();
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).toBe("error: missing authentication (run `bunx npm login`)\n");
|
||||
expect(await exited).toBe(1);
|
||||
});
|
||||
test("invalid token", async () => {
|
||||
// create the user and provide an invalid token
|
||||
const token = await verdaccio.generateUser("invalid-token", "invalid-token");
|
||||
const bunfig = `
|
||||
[install]
|
||||
cache = false
|
||||
registry = { url = "http://localhost:${verdaccio.port}/", token = "1234567" }`;
|
||||
await Promise.all([
|
||||
write(packageJson, JSON.stringify({ name: "whoami-pkg", version: "1.1.1" })),
|
||||
write(join(packageDir, "bunfig.toml"), bunfig),
|
||||
]);
|
||||
const { stdout, stderr, exited } = spawn({
|
||||
cmd: [bunExe(), "pm", "whoami"],
|
||||
cwd: packageDir,
|
||||
env,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const out = await Bun.readableStreamToText(stdout);
|
||||
expect(out).toBeEmpty();
|
||||
const err = await Bun.readableStreamToText(stderr);
|
||||
expect(err).toBe(`error: failed to authenticate with registry 'http://localhost:${verdaccio.port}/'\n`);
|
||||
expect(await exited).toBe(1);
|
||||
});
|
||||
56
test/cli/install/registry/packages/zzz-1/package.json
Normal file
56
test/cli/install/registry/packages/zzz-1/package.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "zzz-1",
|
||||
"versions": {
|
||||
"1.0.89": {
|
||||
"name": "zzz-1",
|
||||
"version": "1.0.89",
|
||||
"_id": "zzz-1@1.0.89",
|
||||
"_nodeVersion": "23.5.0",
|
||||
"_npmVersion": "10.9.2",
|
||||
"dist": {
|
||||
"integrity": "sha512-EPmDE1AhS+Dfwa/KYhcIqkBF66nrEA8qQI924xddQOaRvqZGkBqk4AXHG0gIe8KNqllVYFhs5exY5tKi/MaCDQ==",
|
||||
"shasum": "ea3eba357864416df74721d989750ce112c4b112",
|
||||
"tarball": "http://localhost:4873/zzz-1/-/zzz-1-1.0.89.tgz"
|
||||
},
|
||||
"contributors": []
|
||||
},
|
||||
"1.0.90": {
|
||||
"name": "zzz-1",
|
||||
"version": "1.0.90",
|
||||
"_id": "zzz-1@1.0.90",
|
||||
"_nodeVersion": "23.5.0",
|
||||
"_npmVersion": "10.9.2",
|
||||
"dist": {
|
||||
"integrity": "sha512-UaWGWc1xwYMtgxAdZbS2jj5s2UWwdcgEzYT0kAlTQR2pHPi48bmrI6ZKRySEEROcHh1sD1HWqqopg1HRIcWXKw==",
|
||||
"shasum": "65bfff389d760c43a339f34499fb3bc52fcf345e",
|
||||
"tarball": "http://localhost:4873/zzz-1/-/zzz-1-1.0.90.tgz"
|
||||
},
|
||||
"contributors": []
|
||||
}
|
||||
},
|
||||
"time": {
|
||||
"modified": "2025-01-09T00:53:52.021Z",
|
||||
"created": "2025-01-09T00:50:38.582Z",
|
||||
"1.0.89": "2025-01-09T00:50:38.582Z",
|
||||
"1.0.90": "2025-01-09T00:53:52.021Z"
|
||||
},
|
||||
"users": {},
|
||||
"dist-tags": {
|
||||
"latest": "1.0.90"
|
||||
},
|
||||
"_uplinks": {},
|
||||
"_distfiles": {},
|
||||
"_attachments": {
|
||||
"zzz-1-1.0.89.tgz": {
|
||||
"shasum": "ea3eba357864416df74721d989750ce112c4b112",
|
||||
"version": "1.0.89"
|
||||
},
|
||||
"zzz-1-1.0.90.tgz": {
|
||||
"shasum": "65bfff389d760c43a339f34499fb3bc52fcf345e",
|
||||
"version": "1.0.90"
|
||||
}
|
||||
},
|
||||
"_rev": "",
|
||||
"_id": "zzz-1",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
BIN
test/cli/install/registry/packages/zzz-1/zzz-1-1.0.89.tgz
Normal file
BIN
test/cli/install/registry/packages/zzz-1/zzz-1-1.0.89.tgz
Normal file
Binary file not shown.
BIN
test/cli/install/registry/packages/zzz-1/zzz-1-1.0.90.tgz
Normal file
BIN
test/cli/install/registry/packages/zzz-1/zzz-1-1.0.90.tgz
Normal file
Binary file not shown.
41
test/cli/install/registry/packages/zzz-2/package.json
Normal file
41
test/cli/install/registry/packages/zzz-2/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "zzz-2",
|
||||
"versions": {
|
||||
"1.0.89": {
|
||||
"name": "zzz-2",
|
||||
"version": "1.0.89",
|
||||
"dependencies": {
|
||||
"zzz-1": "^1.0.89"
|
||||
},
|
||||
"_id": "zzz-2@1.0.89",
|
||||
"_nodeVersion": "23.5.0",
|
||||
"_npmVersion": "10.9.2",
|
||||
"dist": {
|
||||
"integrity": "sha512-AiBHP+QdotgUq83hsFKLYIu33c9rUP2tXaCZs66QqrkoSO/X09I6RRRV0IUzMlemBCp+WedWvLSOVs8E7DgIag==",
|
||||
"shasum": "69dbe7e7dd5c3b465977ded8864f34e6539b7468",
|
||||
"tarball": "http://localhost:4873/zzz-2/-/zzz-2-1.0.89.tgz"
|
||||
},
|
||||
"contributors": []
|
||||
}
|
||||
},
|
||||
"time": {
|
||||
"modified": "2025-01-09T00:51:28.532Z",
|
||||
"created": "2025-01-09T00:51:28.532Z",
|
||||
"1.0.89": "2025-01-09T00:51:28.532Z"
|
||||
},
|
||||
"users": {},
|
||||
"dist-tags": {
|
||||
"latest": "1.0.89"
|
||||
},
|
||||
"_uplinks": {},
|
||||
"_distfiles": {},
|
||||
"_attachments": {
|
||||
"zzz-2-1.0.89.tgz": {
|
||||
"shasum": "69dbe7e7dd5c3b465977ded8864f34e6539b7468",
|
||||
"version": "1.0.89"
|
||||
}
|
||||
},
|
||||
"_rev": "",
|
||||
"_id": "zzz-2",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
BIN
test/cli/install/registry/packages/zzz-2/zzz-2-1.0.89.tgz
Normal file
BIN
test/cli/install/registry/packages/zzz-2/zzz-2-1.0.89.tgz
Normal file
Binary file not shown.
@@ -577,12 +577,7 @@ Received ${JSON.stringify({ name: onDisk.name, version: onDisk.version })}`,
|
||||
case "npm":
|
||||
const name = dep.is_alias ? dep.npm.name : dep.name;
|
||||
if (!Bun.deepMatch({ name, version: pkg.resolution.value }, resolved)) {
|
||||
if (dep.literal === "*") {
|
||||
// allow any version, just needs to be resolvable
|
||||
continue;
|
||||
}
|
||||
if (dep.behavior.peer && dep.npm) {
|
||||
// allow peer dependencies to not match exactly, but still satisfy
|
||||
if (dep.npm) {
|
||||
if (Bun.semver.satisfies(pkg.resolution.value, dep.npm.version)) continue;
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -22464,17 +22464,6 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
"id": 2,
|
||||
"path": "node_modules/next/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 64,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 3,
|
||||
"path": "node_modules/@types/ws/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -22483,7 +22472,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 4,
|
||||
"id": 3,
|
||||
"path": "node_modules/eslint-import-resolver-node/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22498,7 +22487,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 5,
|
||||
"id": 4,
|
||||
"path": "node_modules/eslint-plugin-import/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22513,7 +22502,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 6,
|
||||
"id": 5,
|
||||
"path": "node_modules/eslint-plugin-react/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22528,7 +22517,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 7,
|
||||
"id": 6,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22539,7 +22528,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 8,
|
||||
"id": 7,
|
||||
"path": "node_modules/chokidar/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22550,7 +22539,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 9,
|
||||
"id": 8,
|
||||
"path": "node_modules/fast-glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22561,7 +22550,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 10,
|
||||
"id": 9,
|
||||
"path": "node_modules/postcss-load-config/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22572,7 +22561,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 11,
|
||||
"id": 10,
|
||||
"path": "node_modules/glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22587,7 +22576,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 12,
|
||||
"id": 11,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22598,7 +22587,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 13,
|
||||
"id": 12,
|
||||
"path": "node_modules/eslint-module-utils/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22609,7 +22598,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 14,
|
||||
"id": 13,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22620,7 +22609,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 15,
|
||||
"id": 14,
|
||||
"path": "node_modules/rimraf/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22631,7 +22620,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 16,
|
||||
"id": 15,
|
||||
"path": "node_modules/glob/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22642,7 +22631,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 17,
|
||||
"id": 16,
|
||||
"path": "node_modules/path-scurry/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22653,7 +22642,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 18,
|
||||
"id": 17,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22664,20 +22653,9 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 19,
|
||||
"id": 18,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 65,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 20,
|
||||
"path": "node_modules/@types/yauzl/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
@@ -22686,7 +22664,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 21,
|
||||
"id": 19,
|
||||
"path": "node_modules/string-width/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22705,7 +22683,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 22,
|
||||
"id": 20,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22716,7 +22694,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 23,
|
||||
"id": 21,
|
||||
"path": "node_modules/@babel/highlight/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22727,7 +22705,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 24,
|
||||
"id": 22,
|
||||
"path": "node_modules/string-width-cjs/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22738,7 +22716,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 25,
|
||||
"id": 23,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/strip-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22749,7 +22727,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 26,
|
||||
"id": 24,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/wrap-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22768,7 +22746,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 27,
|
||||
"id": 25,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22779,7 +22757,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 28,
|
||||
"id": 26,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22790,7 +22768,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 29,
|
||||
"id": 27,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/supports-color/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22801,7 +22779,7 @@ exports[`ssr works for 100-ish requests 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 4,
|
||||
"id": 30,
|
||||
"id": 28,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules/color-convert/node_modules",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -22464,17 +22464,6 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
"id": 2,
|
||||
"path": "node_modules/next/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 64,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 3,
|
||||
"path": "node_modules/@types/ws/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -22483,7 +22472,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 4,
|
||||
"id": 3,
|
||||
"path": "node_modules/eslint-import-resolver-node/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22498,7 +22487,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 5,
|
||||
"id": 4,
|
||||
"path": "node_modules/eslint-plugin-import/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22513,7 +22502,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 6,
|
||||
"id": 5,
|
||||
"path": "node_modules/eslint-plugin-react/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22528,7 +22517,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 7,
|
||||
"id": 6,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22539,7 +22528,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 8,
|
||||
"id": 7,
|
||||
"path": "node_modules/chokidar/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22550,7 +22539,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 9,
|
||||
"id": 8,
|
||||
"path": "node_modules/fast-glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22561,7 +22550,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 10,
|
||||
"id": 9,
|
||||
"path": "node_modules/postcss-load-config/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22572,7 +22561,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 11,
|
||||
"id": 10,
|
||||
"path": "node_modules/glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22587,7 +22576,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 12,
|
||||
"id": 11,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22598,7 +22587,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 13,
|
||||
"id": 12,
|
||||
"path": "node_modules/eslint-module-utils/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22609,7 +22598,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 14,
|
||||
"id": 13,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22620,7 +22609,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 15,
|
||||
"id": 14,
|
||||
"path": "node_modules/rimraf/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22631,7 +22620,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 16,
|
||||
"id": 15,
|
||||
"path": "node_modules/glob/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22642,7 +22631,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 17,
|
||||
"id": 16,
|
||||
"path": "node_modules/path-scurry/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22653,7 +22642,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 18,
|
||||
"id": 17,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22664,20 +22653,9 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 19,
|
||||
"id": 18,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 65,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 20,
|
||||
"path": "node_modules/@types/yauzl/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
@@ -22686,7 +22664,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 21,
|
||||
"id": 19,
|
||||
"path": "node_modules/string-width/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22705,7 +22683,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 22,
|
||||
"id": 20,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22716,7 +22694,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 23,
|
||||
"id": 21,
|
||||
"path": "node_modules/@babel/highlight/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22727,7 +22705,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 24,
|
||||
"id": 22,
|
||||
"path": "node_modules/string-width-cjs/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22738,7 +22716,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 25,
|
||||
"id": 23,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/strip-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22749,7 +22727,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 26,
|
||||
"id": 24,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/wrap-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22768,7 +22746,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 27,
|
||||
"id": 25,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22779,7 +22757,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 28,
|
||||
"id": 26,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22790,7 +22768,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 29,
|
||||
"id": 27,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/supports-color/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22801,7 +22779,7 @@ exports[`hot reloading works on the client (+ tailwind hmr) 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 4,
|
||||
"id": 30,
|
||||
"id": 28,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules/color-convert/node_modules",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -22464,17 +22464,6 @@ exports[`next build works: bun 1`] = `
|
||||
"id": 2,
|
||||
"path": "node_modules/next/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 64,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 3,
|
||||
"path": "node_modules/@types/ws/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -22483,7 +22472,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 4,
|
||||
"id": 3,
|
||||
"path": "node_modules/eslint-import-resolver-node/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22498,7 +22487,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 5,
|
||||
"id": 4,
|
||||
"path": "node_modules/eslint-plugin-import/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22513,7 +22502,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 6,
|
||||
"id": 5,
|
||||
"path": "node_modules/eslint-plugin-react/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22528,7 +22517,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 7,
|
||||
"id": 6,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22539,7 +22528,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 8,
|
||||
"id": 7,
|
||||
"path": "node_modules/chokidar/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22550,7 +22539,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 9,
|
||||
"id": 8,
|
||||
"path": "node_modules/fast-glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22561,7 +22550,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 10,
|
||||
"id": 9,
|
||||
"path": "node_modules/postcss-load-config/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22572,7 +22561,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 11,
|
||||
"id": 10,
|
||||
"path": "node_modules/glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22587,7 +22576,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 12,
|
||||
"id": 11,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22598,7 +22587,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 13,
|
||||
"id": 12,
|
||||
"path": "node_modules/eslint-module-utils/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22609,7 +22598,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 14,
|
||||
"id": 13,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22620,7 +22609,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 15,
|
||||
"id": 14,
|
||||
"path": "node_modules/rimraf/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22631,7 +22620,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 16,
|
||||
"id": 15,
|
||||
"path": "node_modules/glob/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22642,7 +22631,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 17,
|
||||
"id": 16,
|
||||
"path": "node_modules/path-scurry/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22653,7 +22642,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 18,
|
||||
"id": 17,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22664,20 +22653,9 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 19,
|
||||
"id": 18,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 65,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 20,
|
||||
"path": "node_modules/@types/yauzl/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
@@ -22686,7 +22664,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 21,
|
||||
"id": 19,
|
||||
"path": "node_modules/string-width/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22705,7 +22683,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 22,
|
||||
"id": 20,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22716,7 +22694,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 23,
|
||||
"id": 21,
|
||||
"path": "node_modules/@babel/highlight/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22727,7 +22705,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 24,
|
||||
"id": 22,
|
||||
"path": "node_modules/string-width-cjs/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22738,7 +22716,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 25,
|
||||
"id": 23,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/strip-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22749,7 +22727,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 26,
|
||||
"id": 24,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/wrap-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22768,7 +22746,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 27,
|
||||
"id": 25,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22779,7 +22757,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 28,
|
||||
"id": 26,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22790,7 +22768,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 29,
|
||||
"id": 27,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/supports-color/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -22801,7 +22779,7 @@ exports[`next build works: bun 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 4,
|
||||
"id": 30,
|
||||
"id": 28,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules/color-convert/node_modules",
|
||||
},
|
||||
],
|
||||
@@ -45274,17 +45252,6 @@ exports[`next build works: node 1`] = `
|
||||
"id": 2,
|
||||
"path": "node_modules/next/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 64,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 3,
|
||||
"path": "node_modules/@types/ws/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -45293,7 +45260,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 4,
|
||||
"id": 3,
|
||||
"path": "node_modules/eslint-import-resolver-node/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45308,7 +45275,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 5,
|
||||
"id": 4,
|
||||
"path": "node_modules/eslint-plugin-import/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45323,7 +45290,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 6,
|
||||
"id": 5,
|
||||
"path": "node_modules/eslint-plugin-react/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45338,7 +45305,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 7,
|
||||
"id": 6,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45349,7 +45316,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 8,
|
||||
"id": 7,
|
||||
"path": "node_modules/chokidar/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45360,7 +45327,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 9,
|
||||
"id": 8,
|
||||
"path": "node_modules/fast-glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45371,7 +45338,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 10,
|
||||
"id": 9,
|
||||
"path": "node_modules/postcss-load-config/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45382,7 +45349,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 11,
|
||||
"id": 10,
|
||||
"path": "node_modules/glob/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45397,7 +45364,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 12,
|
||||
"id": 11,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45408,7 +45375,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 13,
|
||||
"id": 12,
|
||||
"path": "node_modules/eslint-module-utils/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45419,7 +45386,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 14,
|
||||
"id": 13,
|
||||
"path": "node_modules/@puppeteer/browsers/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45430,7 +45397,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 15,
|
||||
"id": 14,
|
||||
"path": "node_modules/rimraf/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45441,7 +45408,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 16,
|
||||
"id": 15,
|
||||
"path": "node_modules/glob/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45452,7 +45419,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 17,
|
||||
"id": 16,
|
||||
"path": "node_modules/path-scurry/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45463,7 +45430,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 18,
|
||||
"id": 17,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45474,20 +45441,9 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 19,
|
||||
"id": 18,
|
||||
"path": "node_modules/@typescript-eslint/typescript-estree/node_modules/semver/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"id": 65,
|
||||
"package_id": 431,
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 20,
|
||||
"path": "node_modules/@types/yauzl/node_modules",
|
||||
},
|
||||
{
|
||||
"dependencies": {
|
||||
"emoji-regex": {
|
||||
@@ -45496,7 +45452,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 21,
|
||||
"id": 19,
|
||||
"path": "node_modules/string-width/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45515,7 +45471,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 22,
|
||||
"id": 20,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45526,7 +45482,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 23,
|
||||
"id": 21,
|
||||
"path": "node_modules/@babel/highlight/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45537,7 +45493,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 1,
|
||||
"id": 24,
|
||||
"id": 22,
|
||||
"path": "node_modules/string-width-cjs/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45548,7 +45504,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 25,
|
||||
"id": 23,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/strip-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45559,7 +45515,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 26,
|
||||
"id": 24,
|
||||
"path": "node_modules/@isaacs/cliui/node_modules/wrap-ansi/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45578,7 +45534,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 2,
|
||||
"id": 27,
|
||||
"id": 25,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45589,7 +45545,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 28,
|
||||
"id": 26,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45600,7 +45556,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 3,
|
||||
"id": 29,
|
||||
"id": 27,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/supports-color/node_modules",
|
||||
},
|
||||
{
|
||||
@@ -45611,7 +45567,7 @@ exports[`next build works: node 1`] = `
|
||||
},
|
||||
},
|
||||
"depth": 4,
|
||||
"id": 30,
|
||||
"id": 28,
|
||||
"path": "node_modules/@babel/highlight/node_modules/chalk/node_modules/ansi-styles/node_modules/color-convert/node_modules",
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user