mirror of
https://github.com/oven-sh/bun
synced 2026-02-25 11:07:19 +01:00
Compare commits
29 Commits
claude/exp
...
claude/fet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e53f8e1c8a | ||
|
|
4dcbfb9e1b | ||
|
|
ebabf5af23 | ||
|
|
06b902763a | ||
|
|
09ea5790bb | ||
|
|
f2ec66faf9 | ||
|
|
acf740ce37 | ||
|
|
f224e8af42 | ||
|
|
9fd0d3ceac | ||
|
|
86dde5d33e | ||
|
|
6606eb5c2c | ||
|
|
491e3a8d8b | ||
|
|
a04b3a9656 | ||
|
|
f6e128f385 | ||
|
|
ace1f408ae | ||
|
|
e4f9697492 | ||
|
|
636e88b84e | ||
|
|
e8eeb8de18 | ||
|
|
9299d9322a | ||
|
|
7da9bac480 | ||
|
|
8edeaeed77 | ||
|
|
918e0b6716 | ||
|
|
932af0971b | ||
|
|
cc05b8c56f | ||
|
|
1f5ea66e34 | ||
|
|
2dbcd5eb5c | ||
|
|
946470dcd7 | ||
|
|
d76fad3618 | ||
|
|
bdaab89253 |
@@ -444,10 +444,6 @@ pub const JSBundler = struct {
|
||||
this.code_splitting = hot;
|
||||
}
|
||||
|
||||
if (try config.getBooleanLoose(globalThis, "cssChunking")) |css_chunking| {
|
||||
this.css_chunking = css_chunking;
|
||||
}
|
||||
|
||||
if (try config.getTruthy(globalThis, "minify")) |minify| {
|
||||
if (minify.isBoolean()) {
|
||||
const value = minify.toBoolean();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2367
src/bun.js/webcore/fetch/FetchTasklet.zig
Normal file
2367
src/bun.js/webcore/fetch/FetchTasklet.zig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -96,19 +96,24 @@ pub const UpdateInteractiveCommand = struct {
|
||||
};
|
||||
|
||||
const new_package_json_source = try manager.allocator.dupe(u8, package_json_writer.ctx.writtenWithoutTrailingZero());
|
||||
defer manager.allocator.free(new_package_json_source);
|
||||
|
||||
// Write the updated package.json
|
||||
const write_file = std.fs.cwd().createFile(package_json_path, .{}) catch |err| {
|
||||
manager.allocator.free(new_package_json_source);
|
||||
Output.errGeneric("Failed to write package.json at {s}: {s}", .{ package_json_path, @errorName(err) });
|
||||
return err;
|
||||
};
|
||||
defer write_file.close();
|
||||
|
||||
write_file.writeAll(new_package_json_source) catch |err| {
|
||||
manager.allocator.free(new_package_json_source);
|
||||
Output.errGeneric("Failed to write package.json at {s}: {s}", .{ package_json_path, @errorName(err) });
|
||||
return err;
|
||||
};
|
||||
|
||||
// Update the cache so installWithManager sees the new package.json
|
||||
// This is critical - without this, installWithManager will use the cached old version
|
||||
package_json.*.source.contents = new_package_json_source;
|
||||
}
|
||||
|
||||
pub fn exec(ctx: Command.Context) !void {
|
||||
@@ -1976,11 +1981,40 @@ fn updateNamedCatalog(
|
||||
}
|
||||
|
||||
fn preserveVersionPrefix(original_version: string, new_version: string, allocator: std.mem.Allocator) !string {
|
||||
if (original_version.len > 0) {
|
||||
const first_char = original_version[0];
|
||||
if (original_version.len > 1) {
|
||||
var orig_version = original_version;
|
||||
var alias: ?string = null;
|
||||
|
||||
// Preserve npm: prefix
|
||||
if (strings.withoutPrefixIfPossibleComptime(original_version, "npm:")) |after_npm| {
|
||||
if (strings.lastIndexOfChar(after_npm, '@')) |i| {
|
||||
alias = after_npm[0..i];
|
||||
if (i + 2 < after_npm.len) {
|
||||
orig_version = after_npm[i + 1 ..];
|
||||
}
|
||||
} else {
|
||||
alias = after_npm;
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve other version prefixes
|
||||
const first_char = orig_version[0];
|
||||
if (first_char == '^' or first_char == '~' or first_char == '>' or first_char == '<' or first_char == '=') {
|
||||
const second_char = orig_version[1];
|
||||
if ((first_char == '>' or first_char == '<') and second_char == '=') {
|
||||
if (alias) |a| {
|
||||
return try std.fmt.allocPrint(allocator, "npm:{s}@{c}={s}", .{ a, first_char, new_version });
|
||||
}
|
||||
return try std.fmt.allocPrint(allocator, "{c}={s}", .{ first_char, new_version });
|
||||
}
|
||||
if (alias) |a| {
|
||||
return try std.fmt.allocPrint(allocator, "npm:{s}@{c}{s}", .{ a, first_char, new_version });
|
||||
}
|
||||
return try std.fmt.allocPrint(allocator, "{c}{s}", .{ first_char, new_version });
|
||||
}
|
||||
if (alias) |a| {
|
||||
return try std.fmt.allocPrint(allocator, "npm:{s}@{s}", .{ a, new_version });
|
||||
}
|
||||
}
|
||||
return try allocator.dupe(u8, new_version);
|
||||
}
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readdirSync, readFileSync } from "fs";
|
||||
import { bunEnv, bunExe, tempDir } from "harness";
|
||||
import { join } from "path";
|
||||
|
||||
describe("CSS Chunking", () => {
|
||||
test("cssChunking reduces duplicate CSS when multiple JS entry points import the same CSS", async () => {
|
||||
using dir = tempDir("css-chunking-test", {
|
||||
"shared.css": `body { background: black; }`,
|
||||
"utils.css": `@import "./shared.css";\n.util { margin: 0; }`,
|
||||
"page-a.js": `import "./utils.css";\nconsole.log("Page A");`,
|
||||
"page-b.js": `import "./utils.css";\nconsole.log("Page B");`,
|
||||
"page-c.js": `import "./utils.css";\nconsole.log("Page C");`,
|
||||
});
|
||||
|
||||
// Test with cssChunking: true
|
||||
await using proc1 = Bun.spawn({
|
||||
cmd: [
|
||||
bunExe(),
|
||||
"build",
|
||||
"--splitting",
|
||||
"--css-chunking",
|
||||
"--outdir",
|
||||
join(String(dir), "out-with-chunking"),
|
||||
join(String(dir), "page-a.js"),
|
||||
join(String(dir), "page-b.js"),
|
||||
join(String(dir), "page-c.js"),
|
||||
],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stdout1, stderr1, exitCode1] = await Promise.all([proc1.stdout.text(), proc1.stderr.text(), proc1.exited]);
|
||||
|
||||
expect(exitCode1).toBe(0);
|
||||
|
||||
const withChunkingFiles = readdirSync(join(String(dir), "out-with-chunking")).filter(f => f.endsWith(".css"));
|
||||
|
||||
// Test without cssChunking (default)
|
||||
await using proc2 = Bun.spawn({
|
||||
cmd: [
|
||||
bunExe(),
|
||||
"build",
|
||||
"--splitting",
|
||||
"--outdir",
|
||||
join(String(dir), "out-without-chunking"),
|
||||
join(String(dir), "page-a.js"),
|
||||
join(String(dir), "page-b.js"),
|
||||
join(String(dir), "page-c.js"),
|
||||
],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stdout2, stderr2, exitCode2] = await Promise.all([proc2.stdout.text(), proc2.stderr.text(), proc2.exited]);
|
||||
|
||||
expect(exitCode2).toBe(0);
|
||||
|
||||
const withoutChunkingFiles = readdirSync(join(String(dir), "out-without-chunking")).filter(f => f.endsWith(".css"));
|
||||
|
||||
// With CSS chunking, should create only 1 shared CSS file
|
||||
expect(withChunkingFiles.length).toBe(1);
|
||||
|
||||
// Without CSS chunking, should create 3 separate CSS files (one per entry point)
|
||||
expect(withoutChunkingFiles.length).toBe(3);
|
||||
|
||||
// Verify the shared CSS file contains the expected content
|
||||
const sharedCssContent = readFileSync(join(String(dir), "out-with-chunking", withChunkingFiles[0]), "utf-8");
|
||||
expect(sharedCssContent).toContain("background: #000");
|
||||
expect(sharedCssContent).toContain("margin: 0");
|
||||
});
|
||||
|
||||
test("cssChunking: true via bun.build API", async () => {
|
||||
using dir = tempDir("css-chunking-api-test", {
|
||||
"shared.css": `body { background: black; }`,
|
||||
"utils.css": `@import "./shared.css";\n.util { padding: 0; }`,
|
||||
"entry-a.js": `import "./utils.css";\nexport const a = "a";`,
|
||||
"entry-b.js": `import "./utils.css";\nexport const b = "b";`,
|
||||
});
|
||||
|
||||
// Build with cssChunking: true
|
||||
const result = await Bun.build({
|
||||
entrypoints: [join(String(dir), "entry-a.js"), join(String(dir), "entry-b.js")],
|
||||
outdir: join(String(dir), "out"),
|
||||
splitting: true,
|
||||
cssChunking: true,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const cssOutputs = result.outputs.filter(o => o.path.endsWith(".css"));
|
||||
|
||||
// Should create only 1 shared CSS chunk
|
||||
expect(cssOutputs.length).toBe(1);
|
||||
|
||||
const cssContent = await cssOutputs[0].text();
|
||||
expect(cssContent).toContain("background: #000");
|
||||
expect(cssContent).toContain("padding: 0");
|
||||
});
|
||||
|
||||
test("cssChunking: false creates separate CSS files per entry point", async () => {
|
||||
using dir = tempDir("css-no-chunking-api-test", {
|
||||
"shared.css": `body { color: red; }`,
|
||||
"entry-1.js": `import "./shared.css";\nexport const x = 1;`,
|
||||
"entry-2.js": `import "./shared.css";\nexport const y = 2;`,
|
||||
});
|
||||
|
||||
// Build with cssChunking: false
|
||||
const result = await Bun.build({
|
||||
entrypoints: [join(String(dir), "entry-1.js"), join(String(dir), "entry-2.js")],
|
||||
outdir: join(String(dir), "out"),
|
||||
splitting: true,
|
||||
cssChunking: false,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const cssOutputs = result.outputs.filter(o => o.path.endsWith(".css"));
|
||||
|
||||
// Should create 2 separate CSS files (one per entry point)
|
||||
expect(cssOutputs.length).toBe(2);
|
||||
});
|
||||
|
||||
test("cssChunking works with nested CSS imports", async () => {
|
||||
using dir = tempDir("css-chunking-nested", {
|
||||
"base.css": `.base { font-family: sans-serif; }`,
|
||||
"theme.css": `@import "./base.css";\n.theme { color: blue; }`,
|
||||
"utils.css": `@import "./theme.css";\n.utils { margin: 10px; }`,
|
||||
"app-a.js": `import "./utils.css";\nconsole.log("App A");`,
|
||||
"app-b.js": `import "./utils.css";\nconsole.log("App B");`,
|
||||
});
|
||||
|
||||
const result = await Bun.build({
|
||||
entrypoints: [join(String(dir), "app-a.js"), join(String(dir), "app-b.js")],
|
||||
outdir: join(String(dir), "dist"),
|
||||
splitting: true,
|
||||
cssChunking: true,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const cssOutputs = result.outputs.filter(o => o.path.endsWith(".css"));
|
||||
|
||||
// Should deduplicate all the nested CSS imports into one chunk
|
||||
expect(cssOutputs.length).toBe(1);
|
||||
|
||||
const cssContent = await cssOutputs[0].text();
|
||||
expect(cssContent).toContain("font-family: sans-serif");
|
||||
expect(cssContent).toContain("#00f"); // minified "blue"
|
||||
expect(cssContent).toContain("margin: 10px");
|
||||
});
|
||||
|
||||
test("cssChunking: true with different CSS per entry creates separate chunks", async () => {
|
||||
using dir = tempDir("css-chunking-different", {
|
||||
"shared.css": `body { margin: 0; }`,
|
||||
"red.css": `@import "./shared.css";\n.red { color: red; }`,
|
||||
"blue.css": `@import "./shared.css";\n.blue { color: blue; }`,
|
||||
"page-red.js": `import "./red.css";\nconsole.log("red");`,
|
||||
"page-blue.js": `import "./blue.css";\nconsole.log("blue");`,
|
||||
});
|
||||
|
||||
const result = await Bun.build({
|
||||
entrypoints: [join(String(dir), "page-red.js"), join(String(dir), "page-blue.js")],
|
||||
outdir: join(String(dir), "out"),
|
||||
splitting: true,
|
||||
cssChunking: true,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
const cssOutputs = result.outputs.filter(o => o.path.endsWith(".css"));
|
||||
|
||||
// Should create 2 CSS files because red.css and blue.css are different
|
||||
expect(cssOutputs.length).toBe(2);
|
||||
|
||||
const contents = await Promise.all(cssOutputs.map(o => o.text()));
|
||||
|
||||
// One should have red styles, the other blue
|
||||
const hasRed = contents.some(c => c.includes("red") || c.includes("#f00"));
|
||||
const hasBlue = contents.some(c => c.includes("blue") || c.includes("#00f"));
|
||||
|
||||
expect(hasRed).toBe(true);
|
||||
expect(hasBlue).toBe(true);
|
||||
|
||||
// Both should include the shared styles
|
||||
expect(contents.every(c => c.includes("margin: 0"))).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1861,6 +1861,51 @@ registry = "${registryUrl}"
|
||||
expect(packageJson.dependencies["dep-with-tags"]).toBe("1.0.0");
|
||||
});
|
||||
|
||||
it("should preserve npm: alias prefix when updating packages", async () => {
|
||||
const dir = tempDirWithFiles("update-interactive-npm-alias", {
|
||||
"bunfig.toml": `[install]
|
||||
cache = false
|
||||
registry = "${registryUrl}"
|
||||
`,
|
||||
"package.json": JSON.stringify({
|
||||
name: "test-project",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"my-alias": "npm:no-deps@1.0.0",
|
||||
"@my/alias": "npm:@types/no-deps@^1.0.0",
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
await using install = Bun.spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: dir,
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
expect(await install.exited).toBe(0);
|
||||
|
||||
await using update = Bun.spawn({
|
||||
cmd: [bunExe(), "update", "-i", "--latest"],
|
||||
cwd: dir,
|
||||
env: bunEnv,
|
||||
stdin: "pipe",
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
update.stdin.write("a\n");
|
||||
update.stdin.end();
|
||||
|
||||
const exitCode = await update.exited;
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const packageJson = await Bun.file(join(dir, "package.json")).json();
|
||||
expect(packageJson.dependencies["my-alias"]).toBe("npm:no-deps@2.0.0");
|
||||
expect(packageJson.dependencies["@my/alias"]).toBe("npm:@types/no-deps@^2.0.0");
|
||||
});
|
||||
|
||||
it("interactive update with mixed dependency types", async () => {
|
||||
const dir = tempDirWithFiles("update-interactive-mixed", {
|
||||
"bunfig.toml": `[install]
|
||||
@@ -1891,7 +1936,7 @@ registry = "${registryUrl}"
|
||||
name: "@test/workspace1",
|
||||
dependencies: {
|
||||
"a-dep": "catalog:",
|
||||
"@test/workspace2": "workspace:*", // Workspace dependency
|
||||
"@test/workspace2": "workspace:*",
|
||||
},
|
||||
devDependencies: {
|
||||
"no-deps": "^1.0.0",
|
||||
|
||||
182
test/cli/update_interactive_install.test.ts
Normal file
182
test/cli/update_interactive_install.test.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { bunEnv, bunExe, tempDir } from "harness";
|
||||
import { join } from "path";
|
||||
|
||||
describe.concurrent("bun update --interactive actually installs packages", () => {
|
||||
test("should update package.json AND install packages", async () => {
|
||||
using dir = tempDir("update-interactive-install", {
|
||||
"package.json": JSON.stringify({
|
||||
name: "test-project",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
// Use a very old version that definitely has updates available
|
||||
"is-even": "0.1.0",
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
// First, run bun install to create initial node_modules
|
||||
await using installProc = Bun.spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const installExitCode = await installProc.exited;
|
||||
expect(installExitCode).toBe(0);
|
||||
|
||||
// Verify initial installation
|
||||
const initialPackageJson = JSON.parse(readFileSync(join(String(dir), "package.json"), "utf8"));
|
||||
expect(initialPackageJson.dependencies["is-even"]).toBe("0.1.0");
|
||||
|
||||
// Check that node_modules was created
|
||||
expect(existsSync(join(String(dir), "node_modules"))).toBe(true);
|
||||
expect(existsSync(join(String(dir), "node_modules", "is-even"))).toBe(true);
|
||||
|
||||
// Read the initial installed version from package.json in node_modules
|
||||
const initialInstalledPkgJson = JSON.parse(
|
||||
readFileSync(join(String(dir), "node_modules", "is-even", "package.json"), "utf8"),
|
||||
);
|
||||
const initialVersion = initialInstalledPkgJson.version;
|
||||
expect(initialVersion).toBe("0.1.0");
|
||||
|
||||
// Now run update --interactive with automatic selection
|
||||
await using updateProc = Bun.spawn({
|
||||
cmd: [bunExe(), "update", "--interactive"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdin: "pipe",
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
try {
|
||||
// Select first package and confirm
|
||||
updateProc.stdin.write(" "); // space to select
|
||||
updateProc.stdin.write("\r"); // enter to confirm
|
||||
updateProc.stdin.end();
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([
|
||||
updateProc.stdout.text(),
|
||||
updateProc.stderr.text(),
|
||||
updateProc.exited,
|
||||
]);
|
||||
|
||||
// Debug output if test fails
|
||||
if (exitCode !== 0) {
|
||||
console.log("STDOUT:", stdout);
|
||||
console.log("STDERR:", stderr);
|
||||
}
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
// Check that package.json was updated
|
||||
const updatedPackageJson = JSON.parse(readFileSync(join(String(dir), "package.json"), "utf8"));
|
||||
const updatedVersion = updatedPackageJson.dependencies["is-even"];
|
||||
|
||||
// The version should have changed from "0.1.0"
|
||||
expect(updatedVersion).not.toBe("0.1.0");
|
||||
|
||||
// Most importantly: verify that node_modules was actually updated!
|
||||
// This is the bug - previously only package.json changed but not node_modules
|
||||
const installedPkgJson = JSON.parse(
|
||||
readFileSync(join(String(dir), "node_modules", "is-even", "package.json"), "utf8"),
|
||||
);
|
||||
const installedVersion = installedPkgJson.version;
|
||||
|
||||
// The installed version should match what's in package.json
|
||||
// Extract version number from potentially semver-prefixed string (e.g., "^1.1.0" -> "1.1.0")
|
||||
const expectedVersion = updatedVersion.replace(/^[\^~]/, "");
|
||||
|
||||
// The installed version should NOT be the old version
|
||||
expect(installedVersion).not.toBe("0.1.0");
|
||||
expect(Bun.semver.satisfies(installedVersion, ">0.1.0")).toBe(true);
|
||||
|
||||
// And ideally should match the expected version (or at least be compatible)
|
||||
// We check that it starts with the expected major.minor
|
||||
const [expectedMajor, expectedMinor] = expectedVersion.split(".");
|
||||
expect(installedVersion).toContain(`${expectedMajor}.${expectedMinor}`);
|
||||
} catch (err) {
|
||||
// Ensure cleanup on failure
|
||||
updateProc.stdin.end();
|
||||
updateProc.kill();
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
test("should work with --latest flag", async () => {
|
||||
using dir = tempDir("update-interactive-latest", {
|
||||
"package.json": JSON.stringify({
|
||||
name: "test-project",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"is-odd": "0.1.0", // Use old version of is-odd
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
// Initial install
|
||||
await using installProc = Bun.spawn({
|
||||
cmd: [bunExe(), "install"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
await installProc.exited;
|
||||
|
||||
// Verify initial version
|
||||
const initialPkgJson = JSON.parse(
|
||||
readFileSync(join(String(dir), "node_modules", "is-odd", "package.json"), "utf8"),
|
||||
);
|
||||
expect(initialPkgJson.version).toBe("0.1.0");
|
||||
|
||||
// Run update --interactive with 'l' to toggle latest, then select and confirm
|
||||
await using updateProc = Bun.spawn({
|
||||
cmd: [bunExe(), "update", "--interactive"],
|
||||
cwd: String(dir),
|
||||
env: bunEnv,
|
||||
stdin: "pipe",
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
try {
|
||||
updateProc.stdin.write("l"); // toggle latest
|
||||
updateProc.stdin.write(" "); // select
|
||||
updateProc.stdin.write("\r"); // confirm
|
||||
updateProc.stdin.end();
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([
|
||||
updateProc.stdout.text(),
|
||||
updateProc.stderr.text(),
|
||||
updateProc.exited,
|
||||
]);
|
||||
|
||||
if (exitCode !== 0) {
|
||||
console.log("STDOUT:", stdout);
|
||||
console.log("STDERR:", stderr);
|
||||
}
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
// Verify node_modules was updated
|
||||
const updatedPkgJson = JSON.parse(
|
||||
readFileSync(join(String(dir), "node_modules", "is-odd", "package.json"), "utf8"),
|
||||
);
|
||||
|
||||
// Should be newer than 0.1.0
|
||||
expect(updatedPkgJson.version).not.toBe("0.1.0");
|
||||
expect(Bun.semver.satisfies(updatedPkgJson.version, ">0.1.0")).toBe(true);
|
||||
} catch (err) {
|
||||
// Ensure cleanup on failure
|
||||
updateProc.stdin.end();
|
||||
updateProc.kill();
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,7 @@
|
||||
".stdDir()": 42,
|
||||
".stdFile()": 16,
|
||||
"// autofix": 164,
|
||||
": [^=]+= undefined,$": 255,
|
||||
": [^=]+= undefined,$": 251,
|
||||
"== alloc.ptr": 0,
|
||||
"== allocator.ptr": 0,
|
||||
"@import(\"bun\").": 0,
|
||||
|
||||
Reference in New Issue
Block a user