@enke.dev/bumper 0.0.6 → 0.0.8

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +53 -12
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -2147,6 +2147,19 @@ function detectVersionManager() {
2147
2147
  // src/context/detectors/workspace.detector.ts
2148
2148
  import { readFile as readFile3 } from "node:fs/promises";
2149
2149
  import { dirname, join as join5, matchesGlob, relative } from "node:path";
2150
+ async function withoutIgnored(cwd, dirs, run2 = exec) {
2151
+ if (dirs.length === 0) {
2152
+ return dirs;
2153
+ }
2154
+ const manifestOf = (dir) => join5(dir, "package.json");
2155
+ const { exitCode, stdout } = await run2(["git", "check-ignore", ...dirs.map(manifestOf)], { cwd });
2156
+ if (exitCode !== 0 && exitCode !== 1) {
2157
+ return dirs;
2158
+ }
2159
+ const ignored = new Set(stdout.split(`
2160
+ `).map((line) => line.trim()).filter(Boolean));
2161
+ return dirs.filter((dir) => !ignored.has(manifestOf(dir)));
2162
+ }
2150
2163
  function parsePnpmPackages(yaml) {
2151
2164
  return yaml.split(`
2152
2165
  `).reduce((state, raw) => {
@@ -2183,7 +2196,7 @@ async function readWorkspaceGlobs(cwd, pm) {
2183
2196
  }
2184
2197
  return [];
2185
2198
  }
2186
- async function detectWorkspaces(cwd, pm) {
2199
+ async function detectWorkspaces(cwd, pm, run2 = exec) {
2187
2200
  const globs = await readWorkspaceGlobs(cwd, pm);
2188
2201
  const positives = globs.filter((g) => !g.startsWith("!"));
2189
2202
  const negatives = globs.filter((g) => g.startsWith("!")).map((g) => g.slice(1));
@@ -2192,7 +2205,7 @@ async function detectWorkspaces(cwd, pm) {
2192
2205
  }
2193
2206
  const matches = await Promise.all(positives.map((pattern) => globFiles(cwd, `${pattern}/package.json`)));
2194
2207
  const found = new Set(matches.flat().map((match) => dirname(match)).filter((dir) => !negatives.some((neg) => matchesGlob(relative(cwd, dir), neg))));
2195
- const members = [...found].sort();
2208
+ const members = await withoutIgnored(cwd, [...found].sort(), run2);
2196
2209
  return { isMonorepo: members.length > 0, workspaces: [cwd, ...members] };
2197
2210
  }
2198
2211
 
@@ -2253,6 +2266,7 @@ import { readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises
2253
2266
  import { relative as relative2 } from "node:path";
2254
2267
 
2255
2268
  // src/utils/npm-registry.utils.ts
2269
+ var import_semver = __toESM(require_semver2(), 1);
2256
2270
  async function curlJson(url, run2 = execOk) {
2257
2271
  const { stdout } = await run2(["curl", "-sSL", "--fail", "--connect-timeout", "20", url]);
2258
2272
  return JSON.parse(stdout);
@@ -2300,6 +2314,27 @@ async function latestVersionInRange(pkg, range, tool, cwd, run2 = exec) {
2300
2314
  return null;
2301
2315
  }
2302
2316
  }
2317
+ async function maxSatisfyingRanges(pkg, ranges, tool, cwd, run2 = exec) {
2318
+ if (ranges.length === 0) {
2319
+ return null;
2320
+ }
2321
+ try {
2322
+ const { exitCode, stdout } = await run2([tool, "view", pkg, "versions", "--json"], { cwd });
2323
+ if (exitCode !== 0) {
2324
+ return null;
2325
+ }
2326
+ const trimmed = stdout.trim();
2327
+ if (!trimmed) {
2328
+ return null;
2329
+ }
2330
+ const parsed = JSON.parse(trimmed);
2331
+ const versions = Array.isArray(parsed) ? parsed : typeof parsed === "string" ? [parsed] : [];
2332
+ const match = versions.filter((v) => import_semver.default.valid(v) && import_semver.default.prerelease(v) === null).filter((v) => ranges.every((range) => import_semver.default.satisfies(v, range))).sort(import_semver.default.rcompare)[0];
2333
+ return match ?? null;
2334
+ } catch {
2335
+ return null;
2336
+ }
2337
+ }
2303
2338
 
2304
2339
  // src/modules/runtimes/node/node-lts.utils.ts
2305
2340
  var DIST_INDEX = "https://nodejs.org/dist/index.json";
@@ -2384,9 +2419,9 @@ var githubActionsFeature = {
2384
2419
  import { relative as relative3 } from "node:path";
2385
2420
 
2386
2421
  // src/utils/spec.utils.ts
2387
- var import_semver = __toESM(require_semver2(), 1);
2422
+ var import_semver2 = __toESM(require_semver2(), 1);
2388
2423
  function isPinnable(spec) {
2389
- return import_semver.default.valid(spec.replace(/^[\^~]/, "")) !== null;
2424
+ return import_semver2.default.valid(spec.replace(/^[\^~]/, "")) !== null;
2390
2425
  }
2391
2426
  function operatorOf(spec) {
2392
2427
  return spec.startsWith("^") ? "^" : spec.startsWith("~") ? "~" : "";
@@ -2503,6 +2538,7 @@ async function selfUpdate(ctx, cmd) {
2503
2538
  }
2504
2539
 
2505
2540
  // src/utils/upgrade.utils.ts
2541
+ var import_semver3 = __toESM(require_semver2(), 1);
2506
2542
  import { join as join8 } from "node:path";
2507
2543
  var BUCKETS2 = [
2508
2544
  "dependencies",
@@ -2513,7 +2549,7 @@ var BUCKETS2 = [
2513
2549
  var CONCURRENCY = 8;
2514
2550
  var defaultLookups = {
2515
2551
  latestVersion,
2516
- latestVersionInRange,
2552
+ maxSatisfyingRanges,
2517
2553
  peerDependencies: peerDependenciesOf
2518
2554
  };
2519
2555
  async function collectPackages(ctx) {
@@ -2548,7 +2584,7 @@ async function collectPeerCaps(cwd, depNames, latest, managed, tool, lookups) {
2548
2584
  (collected.get(peer) ?? collected.set(peer, new Set).get(peer))?.add(range);
2549
2585
  });
2550
2586
  }));
2551
- return new Map([...collected].map(([peer, ranges]) => [peer, [...ranges].join(" ")]));
2587
+ return new Map([...collected].map(([peer, ranges]) => [peer, [...ranges]]));
2552
2588
  }
2553
2589
  async function resolveLatest(names, tool, cwd, lookups) {
2554
2590
  const resolved = [];
@@ -2610,15 +2646,15 @@ function cappedRanges(pkg, managed) {
2610
2646
  }
2611
2647
  async function rewriteSpecs(pkg, managed, latest, peerCaps, tool, cwd, lookups) {
2612
2648
  const present = allDependencies(pkg);
2613
- const caps = cappedRanges(pkg, managed);
2614
- peerCaps.forEach((range, name) => {
2649
+ const capRanges = new Map;
2650
+ cappedRanges(pkg, managed).forEach((range, name) => capRanges.set(name, [range]));
2651
+ peerCaps.forEach((ranges, name) => {
2615
2652
  if (!(name in present)) {
2616
2653
  return;
2617
2654
  }
2618
- const own = caps.get(name);
2619
- caps.set(name, own ? `${own} ${range}` : range);
2655
+ capRanges.set(name, [...new Set([...capRanges.get(name) ?? [], ...ranges])]);
2620
2656
  });
2621
- const capped = new Map(await Promise.all([...caps].map(async ([name, range]) => [name, await lookups.latestVersionInRange(name, range, tool, cwd)])));
2657
+ const capped = new Map(await Promise.all([...capRanges].map(async ([name, ranges]) => [name, await lookups.maxSatisfyingRanges(name, ranges, tool, cwd)])));
2622
2658
  return BUCKETS2.reduce((bucketChanged, bucket) => {
2623
2659
  const deps = pkg[bucket];
2624
2660
  if (!deps) {
@@ -2628,10 +2664,15 @@ async function rewriteSpecs(pkg, managed, latest, peerCaps, tool, cwd, lookups)
2628
2664
  if (managed.has(name) || !isPinnable(spec)) {
2629
2665
  return acc;
2630
2666
  }
2631
- const version = caps.has(name) ? capped.get(name) : latest.get(name);
2667
+ const capped_ = capRanges.has(name);
2668
+ const version = capped_ ? capped.get(name) : latest.get(name);
2632
2669
  if (!version) {
2633
2670
  return acc;
2634
2671
  }
2672
+ const current = spec.replace(/^[\^~]/, "");
2673
+ if (!capped_ && import_semver3.default.valid(current) && import_semver3.default.lt(version, current)) {
2674
+ return acc;
2675
+ }
2635
2676
  const next = `${operatorOf(spec)}${version}`;
2636
2677
  if (next === spec) {
2637
2678
  return acc;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enke.dev/bumper",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",