@enke.dev/bumper 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,12 +19,15 @@ Dependencies are bumped by resolving each package's latest version via the repo'
19
19
  manager (`pnpm view` / `npm view`, so private scoped registries + `.npmrc` auth just work),
20
20
  rewriting `package.json` specs (preserving `^`/`~`), then letting the package manager reinstall.
21
21
 
22
- Bumps are **peer-aware**: before rewriting, bumper reads the `peerDependencies` of every
23
- installed dependency (from `node_modules`) and caps each shared dependency to the newest version
24
- still satisfying every declared peer range. So a preset that peer-pins `typescript` to `6.0.3`
22
+ Bumps are **peer-aware**: before rewriting, bumper reads the `peerDependencies` of every direct
23
+ dependency for the version it's about to bump _to_, resolved from the registry rather than the
24
+ stale one in `node_modules` and caps each shared dependency to the newest version still
25
+ satisfying every declared peer range. So a preset that peer-pins `typescript` to `6.0.3`
25
26
  (e.g. [`@enke.dev/lint`](https://www.npmjs.com/package/@enke.dev/lint)) holds `typescript` at
26
27
  `6.0.3` instead of jumping to a newer major that would break the preset — no per-repo config
27
- needed, the declaration lives in the dependency itself.
28
+ needed, the declaration lives in the dependency itself. Because the peers are read for the target
29
+ version, a peer newly introduced (or changed) by that bump is honored in the **same run** — no
30
+ second pass needed to converge.
28
31
 
29
32
  > **Note** — network runs through subprocesses (`curl` for the Node dist index, `pnpm`/`npm view`
30
33
  > for versions, `actions-up` via `bunx`), so private-registry auth is handled by the tools that
package/dist/cli.mjs CHANGED
@@ -2273,6 +2273,19 @@ async function latestVersion(pkg, tool, cwd, run2 = exec) {
2273
2273
  return null;
2274
2274
  }
2275
2275
  }
2276
+ async function peerDependenciesOf(pkg, version, tool, cwd, run2 = exec) {
2277
+ try {
2278
+ const { exitCode, stdout } = await run2([tool, "view", `${pkg}@${version}`, "peerDependencies", "--json"], { cwd });
2279
+ const trimmed = stdout.trim();
2280
+ if (exitCode !== 0 || !trimmed) {
2281
+ return {};
2282
+ }
2283
+ const parsed = JSON.parse(trimmed);
2284
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
2285
+ } catch {
2286
+ return {};
2287
+ }
2288
+ }
2276
2289
  async function latestVersionInRange(pkg, range, tool, cwd, run2 = exec) {
2277
2290
  try {
2278
2291
  const { exitCode, stdout } = await run2([tool, "view", `${pkg}@${range}`, "version"], { cwd });
@@ -2459,13 +2472,20 @@ import { join as join9 } from "node:path";
2459
2472
  // src/utils/deps.utils.ts
2460
2473
  import { rm } from "node:fs/promises";
2461
2474
  import { join as join7 } from "node:path";
2475
+ var LOCKFILES = {
2476
+ ["npm" /* Npm */]: ["package-lock.json", "npm-shrinkwrap.json"],
2477
+ ["pnpm" /* Pnpm */]: ["pnpm-lock.yaml"],
2478
+ ["bun" /* Bun */]: ["bun.lock", "bun.lockb"]
2479
+ };
2462
2480
  async function cleanInstall(ctx, installCmd) {
2481
+ const lockfiles = LOCKFILES[ctx.packageManager] ?? [];
2463
2482
  if (ctx.dryRun) {
2464
- planLine("rm -rf node_modules");
2483
+ planLine(["rm -rf", "node_modules", ...lockfiles].join(" "));
2465
2484
  planLine(installCmd.join(" "));
2466
2485
  return;
2467
2486
  }
2468
2487
  await rm(join7(ctx.cwd, "node_modules"), { recursive: true, force: true });
2488
+ await Promise.all(lockfiles.map((file) => rm(join7(ctx.cwd, file), { force: true })));
2469
2489
  await execOk(installCmd, { cwd: ctx.cwd });
2470
2490
  }
2471
2491
  async function selfUpdate(ctx, cmd) {
@@ -2491,7 +2511,11 @@ var BUCKETS2 = [
2491
2511
  "peerDependencies"
2492
2512
  ];
2493
2513
  var CONCURRENCY = 8;
2494
- var defaultLookups = { latestVersion, latestVersionInRange };
2514
+ var defaultLookups = {
2515
+ latestVersion,
2516
+ latestVersionInRange,
2517
+ peerDependencies: peerDependenciesOf
2518
+ };
2495
2519
  async function collectPackages(ctx) {
2496
2520
  const entries = await Promise.all(ctx.workspaces.map(async (dir) => [dir, await readPackageJson(dir)]));
2497
2521
  return new Map(entries.filter((entry) => entry[1] !== null));
@@ -2503,13 +2527,20 @@ function collectNames(pkgs, managed) {
2503
2527
  function collectDependencyNames(pkgs) {
2504
2528
  return [...new Set([...pkgs.values()].flatMap((pkg) => Object.keys(allDependencies(pkg))))];
2505
2529
  }
2506
- async function collectPeerCaps(cwd, depNames, managed) {
2530
+ async function targetVersion(cwd, dep, latest) {
2531
+ if (latest.has(dep)) {
2532
+ return latest.get(dep) ?? null;
2533
+ }
2534
+ return (await readPackageJson(join8(cwd, "node_modules", dep)))?.version ?? null;
2535
+ }
2536
+ async function collectPeerCaps(cwd, depNames, latest, managed, tool, lookups) {
2507
2537
  const collected = new Map;
2508
2538
  await Promise.all(depNames.map(async (dep) => {
2509
- const peers = (await readPackageJson(join8(cwd, "node_modules", dep)))?.peerDependencies;
2510
- if (!peers) {
2539
+ const version = await targetVersion(cwd, dep, latest);
2540
+ if (!version) {
2511
2541
  return;
2512
2542
  }
2543
+ const peers = await lookups.peerDependencies(dep, version, tool, cwd);
2513
2544
  Object.entries(peers).forEach(([peer, range]) => {
2514
2545
  if (managed.has(peer) || !isPinnable(range) && !isVersionRange(range)) {
2515
2546
  return;
@@ -2553,10 +2584,8 @@ async function upgradeAllWorkspaces(ctx, lookups = defaultLookups) {
2553
2584
  return;
2554
2585
  }
2555
2586
  const tool = viewTool(ctx.packageManager);
2556
- const [latest, peerCaps] = await Promise.all([
2557
- resolveLatest(names, tool, ctx.cwd, lookups),
2558
- collectPeerCaps(ctx.cwd, collectDependencyNames(pkgs), managed)
2559
- ]);
2587
+ const latest = await resolveLatest(names, tool, ctx.cwd, lookups);
2588
+ const peerCaps = await collectPeerCaps(ctx.cwd, collectDependencyNames(pkgs), latest, managed, tool, lookups);
2560
2589
  await Promise.all([...pkgs].map(async ([dir, pkg]) => {
2561
2590
  if (await rewriteSpecs(pkg, managed, latest, peerCaps, tool, ctx.cwd, lookups)) {
2562
2591
  await writePackageJson(dir, pkg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enke.dev/bumper",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",