@varlock/bumpy 1.6.0 → 1.7.0

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 (30) hide show
  1. package/dist/{add-u3h5BH8e.mjs → add-Dr1vFn9b.mjs} +9 -10
  2. package/dist/{ai-C66IfTzs.mjs → ai-BHoKuvHn.mjs} +2 -2
  3. package/dist/{apply-release-plan-DNpoi7cS.mjs → apply-release-plan-BRN29C3D.mjs} +3 -3
  4. package/dist/{bump-file-CoaSxqne.mjs → bump-file-4cnuDyfW.mjs} +110 -6
  5. package/dist/{changelog-_gBjowzN.mjs → changelog-C9JXdwaj.mjs} +3 -3
  6. package/dist/{changelog-github-B_e9JWku.mjs → changelog-github-CZcW184H.mjs} +2 -2
  7. package/dist/{check-B3M2S2wx.mjs → check-Dqm9ZU8T.mjs} +9 -6
  8. package/dist/{ci-h8s-soA6.mjs → ci-E1QXDnB_.mjs} +102 -16
  9. package/dist/{ci-setup-DWxrdSK6.mjs → ci-setup-Bbf96usW.mjs} +4 -4
  10. package/dist/{clack-CJT1JFFa.mjs → clack-CehaQZU6.mjs} +1 -1
  11. package/dist/cli.mjs +20 -16
  12. package/dist/{config-D13G4-R8.mjs → config-BcmlSJJd.mjs} +2 -2
  13. package/dist/{fs-DnDogVn-.mjs → fs-CBXKZhoU.mjs} +1 -1
  14. package/dist/{generate-CxKXOBNP.mjs → generate-0a_KR7tn.mjs} +7 -8
  15. package/dist/{git-ukq7VTuZ.mjs → git-DE46Je5V.mjs} +1 -1
  16. package/dist/index.mjs +6 -8
  17. package/dist/{init-CUIw0jg8.mjs → init-CY7OVZCX.mjs} +5 -5
  18. package/dist/{logger-C2dEe5Su.mjs → logger-BgksGFuf.mjs} +3 -1
  19. package/dist/{package-manager-CClZtIHP.mjs → package-manager-BQPwXwu5.mjs} +1 -1
  20. package/dist/{publish-CXJ0Ggkq.mjs → publish-D5OcYhC_.mjs} +74 -12
  21. package/dist/{publish-pipeline-C1slMaJV.mjs → publish-pipeline-ChiL1eRQ.mjs} +6 -6
  22. package/dist/{semver-DfQyVLM_.mjs → release-plan-M9TGZn2W.mjs} +249 -2
  23. package/dist/{shell-u3bYGxNy.mjs → shell-C8KgKnMQ.mjs} +1 -1
  24. package/dist/{status-lS56U6F_.mjs → status-CapkBv6n.mjs} +8 -9
  25. package/dist/{version-BjjnO2ii.mjs → version-Cz-p96lm.mjs} +8 -9
  26. package/package.json +1 -1
  27. package/dist/release-plan-C1Lz9rl_.mjs +0 -249
  28. package/dist/workspace-Yt7qwsML.mjs +0 -109
  29. /package/dist/{commit-message-3e4KhzFV.mjs → commit-message-BA1w19wq.mjs} +0 -0
  30. /package/dist/{names-CBy7d8K_.mjs → names-C-TuOPbd.mjs} +0 -0
@@ -1,3 +1,4 @@
1
+ import { createRequire } from "node:module";
1
2
  //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -29,6 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
30
  value: mod,
30
31
  enumerable: true
31
32
  }) : target, mod));
33
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
32
34
  //#endregion
33
35
  //#region ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
34
36
  var require_picocolors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -132,4 +134,4 @@ function colorize(text, color) {
132
134
  return import_picocolors.default[color](text);
133
135
  }
134
136
  //#endregion
135
- export { __exportAll as a, __commonJSMin as i, log as n, __toESM as o, require_picocolors as r, colorize as t };
137
+ export { __exportAll as a, __commonJSMin as i, log as n, __require as o, require_picocolors as r, __toESM as s, colorize as t };
@@ -1,4 +1,4 @@
1
- import { a as readJson, n as exists, s as readText } from "./fs-DnDogVn-.mjs";
1
+ import { a as readJson, n as exists, s as readText } from "./fs-CBXKZhoU.mjs";
2
2
  import { resolve } from "node:path";
3
3
  //#region ../../node_modules/.bun/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs
4
4
  /*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
@@ -1,12 +1,13 @@
1
- import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as loadConfig } from "./config-D13G4-R8.mjs";
3
- import { n as detectWorkspaces } from "./package-manager-CClZtIHP.mjs";
4
- import { n as discoverWorkspace } from "./workspace-Yt7qwsML.mjs";
1
+ import { n as log, o as __require, t as colorize } from "./logger-BgksGFuf.mjs";
2
+ import { a as loadConfig } from "./config-BcmlSJJd.mjs";
3
+ import { n as detectWorkspaces } from "./package-manager-BQPwXwu5.mjs";
4
+ import { o as discoverWorkspace } from "./bump-file-4cnuDyfW.mjs";
5
5
  import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
6
- import { r as runArgsAsync, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
7
- import { i as loadFormatter, n as generateChangelogEntry } from "./changelog-_gBjowzN.mjs";
8
- import { c as listTags, l as pushWithTags, s as hasUncommittedChanges } from "./git-ukq7VTuZ.mjs";
9
- import { t as publishPackages } from "./publish-pipeline-C1slMaJV.mjs";
6
+ import { r as runArgsAsync, s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
7
+ import { i as loadFormatter, n as generateChangelogEntry } from "./changelog-C9JXdwaj.mjs";
8
+ import { c as listTags, l as pushWithTags, s as hasUncommittedChanges } from "./git-DE46Je5V.mjs";
9
+ import { t as publishPackages } from "./publish-pipeline-ChiL1eRQ.mjs";
10
+ import { CI_PLAN_CACHE_PATH } from "./ci-E1QXDnB_.mjs";
10
11
  //#region src/core/github-release.ts
11
12
  /** Get the current HEAD commit SHA */
12
13
  function getHeadSha(rootDir) {
@@ -194,9 +195,9 @@ async function publishCommand(rootDir, opts) {
194
195
  log.warn("You have uncommitted changes. Commit or stash them before publishing.");
195
196
  process.exit(1);
196
197
  }
197
- let toPublish = await findUnpublishedPackages(packages, config);
198
+ let toPublish = await findUnpublishedWithCache(rootDir, packages, config);
198
199
  if (opts.filter) {
199
- const { matchGlob } = await import("./config-D13G4-R8.mjs").then((n) => n.t);
200
+ const { matchGlob } = await import("./config-BcmlSJJd.mjs").then((n) => n.t);
200
201
  const patterns = opts.filter.split(",").map((p) => p.trim());
201
202
  toPublish = toPublish.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
202
203
  }
@@ -248,6 +249,67 @@ async function publishCommand(rootDir, opts) {
248
249
  }
249
250
  }
250
251
  /**
252
+ * Try to load cached plan from `ci plan`. Returns the unpublished package names
253
+ * if the cache is valid, or null to fall back to registry lookups.
254
+ *
255
+ * Validates that every cached package exists in the workspace with the same version,
256
+ * so the cache can only filter — never fabricate — the set of packages.
257
+ */
258
+ function loadCachedPlan(rootDir, packages) {
259
+ const cachePath = `${rootDir}/${CI_PLAN_CACHE_PATH}`;
260
+ let raw;
261
+ try {
262
+ raw = __require("node:fs").readFileSync(cachePath, "utf-8");
263
+ __require("node:fs").unlinkSync(cachePath);
264
+ } catch {
265
+ return null;
266
+ }
267
+ try {
268
+ const cached = JSON.parse(raw);
269
+ if (cached?.mode !== "publish" || !Array.isArray(cached.releases)) return null;
270
+ const names = /* @__PURE__ */ new Set();
271
+ for (const r of cached.releases) {
272
+ if (typeof r.name !== "string" || typeof r.newVersion !== "string") return null;
273
+ const pkg = packages.get(r.name);
274
+ if (!pkg || pkg.version !== r.newVersion) {
275
+ log.dim(" ci plan cache is stale — falling back to registry lookups");
276
+ return null;
277
+ }
278
+ names.add(r.name);
279
+ }
280
+ log.dim(" Using cached plan from ci plan");
281
+ return names;
282
+ } catch {
283
+ return null;
284
+ }
285
+ }
286
+ /**
287
+ * Find unpublished packages, using the ci plan cache if available.
288
+ * Falls back to registry lookups if no cache or cache is invalid.
289
+ */
290
+ async function findUnpublishedWithCache(rootDir, packages, config) {
291
+ const cachedNames = loadCachedPlan(rootDir, packages);
292
+ if (cachedNames) {
293
+ const unpublished = [];
294
+ for (const name of cachedNames) {
295
+ const pkg = packages.get(name);
296
+ unpublished.push({
297
+ name,
298
+ type: "patch",
299
+ oldVersion: pkg.version,
300
+ newVersion: pkg.version,
301
+ bumpFiles: [],
302
+ isDependencyBump: false,
303
+ isCascadeBump: false,
304
+ isGroupBump: false,
305
+ bumpSources: []
306
+ });
307
+ }
308
+ return unpublished;
309
+ }
310
+ return findUnpublishedPackages(packages, config);
311
+ }
312
+ /**
251
313
  * Find packages whose current version is not yet published.
252
314
  *
253
315
  * Detection strategy (per package):
@@ -275,7 +337,7 @@ async function findUnpublishedPackages(packages, _config) {
275
337
  return unpublished;
276
338
  }
277
339
  async function checkIfPublished(name, version, pkgConfig) {
278
- const { runAsync, runArgsAsync, tryRunArgs } = await import("./shell-u3bYGxNy.mjs").then((n) => n.a);
340
+ const { runAsync, runArgsAsync, tryRunArgs } = await import("./shell-C8KgKnMQ.mjs").then((n) => n.a);
279
341
  if (pkgConfig?.checkPublished) try {
280
342
  return (await runAsync(pkgConfig.checkPublished)).trim() === version;
281
343
  } catch {
@@ -304,4 +366,4 @@ async function checkIfPublished(name, version, pkgConfig) {
304
366
  }
305
367
  }
306
368
  //#endregion
307
- export { publishCommand };
369
+ export { findUnpublishedPackages, publishCommand };
@@ -1,9 +1,9 @@
1
- import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as readJson, u as updateJsonNestedField } from "./fs-DnDogVn-.mjs";
3
- import { r as resolveCatalogDep } from "./package-manager-CClZtIHP.mjs";
4
- import { i as runAsync, o as sq, r as runArgsAsync, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
5
- import { r as stripProtocol } from "./semver-DfQyVLM_.mjs";
6
- import { t as createTag, u as tagExists } from "./git-ukq7VTuZ.mjs";
1
+ import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
2
+ import { a as readJson, u as updateJsonNestedField } from "./fs-CBXKZhoU.mjs";
3
+ import { r as resolveCatalogDep } from "./package-manager-BQPwXwu5.mjs";
4
+ import { i as runAsync, o as sq, r as runArgsAsync, s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
5
+ import { i as stripProtocol } from "./release-plan-M9TGZn2W.mjs";
6
+ import { t as createTag, u as tagExists } from "./git-DE46Je5V.mjs";
7
7
  import { resolve } from "node:path";
8
8
  import { unlink } from "node:fs/promises";
9
9
  import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
@@ -1,4 +1,6 @@
1
- import { i as __commonJSMin, o as __toESM } from "./logger-C2dEe5Su.mjs";
1
+ import { i as __commonJSMin, s as __toESM } from "./logger-BgksGFuf.mjs";
2
+ import { c as maxBump, n as DEFAULT_BUMP_RULES, o as bumpLevel, s as hasCascade } from "./types-BX4pfmKh.mjs";
3
+ import { s as matchGlob } from "./config-BcmlSJJd.mjs";
2
4
  //#region ../../node_modules/.bun/semver@7.7.4/node_modules/semver/internal/constants.js
3
5
  var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
6
  const SEMVER_SPEC_VERSION = "2.0.0";
@@ -1367,4 +1369,249 @@ function stripProtocol(range) {
1367
1369
  return range.replace(/^workspace:/, "");
1368
1370
  }
1369
1371
  //#endregion
1370
- export { satisfies as n, stripProtocol as r, bumpVersion as t };
1372
+ //#region src/core/release-plan.ts
1373
+ /**
1374
+ * Build a release plan from pending bump files, the dependency graph, and config.
1375
+ * This is the core algorithm of bumpy.
1376
+ *
1377
+ * The propagation loop runs three phases until stable:
1378
+ * Phase A — fix out-of-range dependencies (always runs)
1379
+ * Phase B — enforce fixed/linked group constraints
1380
+ * Phase C — apply cascades and proactive propagation rules
1381
+ */
1382
+ function assembleReleasePlan(bumpFiles, packages, depGraph, config) {
1383
+ if (bumpFiles.length === 0) return {
1384
+ bumpFiles: [],
1385
+ releases: [],
1386
+ warnings: []
1387
+ };
1388
+ const planned = /* @__PURE__ */ new Map();
1389
+ const warnings = [];
1390
+ const cascadeOverrides = /* @__PURE__ */ new Map();
1391
+ for (const bf of bumpFiles) for (const release of bf.releases) {
1392
+ if (!packages.has(release.name)) continue;
1393
+ const bump = release.type;
1394
+ if (bump === "none") continue;
1395
+ const existing = planned.get(release.name);
1396
+ if (existing) {
1397
+ existing.type = maxBump(existing.type, bump);
1398
+ existing.bumpFiles.add(bf.id);
1399
+ } else planned.set(release.name, {
1400
+ type: bump,
1401
+ isDependencyBump: false,
1402
+ isCascadeBump: false,
1403
+ isGroupBump: false,
1404
+ bumpFiles: new Set([bf.id]),
1405
+ bumpSources: /* @__PURE__ */ new Map()
1406
+ });
1407
+ if (hasCascade(release)) {
1408
+ if (!cascadeOverrides.has(release.name)) cascadeOverrides.set(release.name, /* @__PURE__ */ new Map());
1409
+ const overrides = cascadeOverrides.get(release.name);
1410
+ for (const [pattern, bumpType] of Object.entries(release.cascade)) {
1411
+ const existing = overrides.get(pattern);
1412
+ overrides.set(pattern, maxBump(existing, bumpType));
1413
+ }
1414
+ }
1415
+ }
1416
+ let changed = true;
1417
+ let iterations = 0;
1418
+ const MAX_ITERATIONS = 100;
1419
+ while (changed && iterations < MAX_ITERATIONS) {
1420
+ changed = false;
1421
+ iterations++;
1422
+ for (const [pkgName, bump] of planned) {
1423
+ const pkg = packages.get(pkgName);
1424
+ const newVersion = bumpVersion(pkg.version, bump.type);
1425
+ const dependents = depGraph.getDependents(pkgName);
1426
+ for (const dep of dependents) {
1427
+ if (dep.depType === "devDependencies") continue;
1428
+ const currentVersion = pkg.version;
1429
+ if (satisfies(newVersion, dep.versionRange, currentVersion)) continue;
1430
+ let depBump;
1431
+ if (dep.depType === "peerDependencies") depBump = bump.type;
1432
+ else depBump = "patch";
1433
+ if (dep.depType === "peerDependencies" && depBump !== "patch" && bump.type !== "major") {
1434
+ let resolvedRange = dep.versionRange.replace(/^workspace:/, "");
1435
+ if (resolvedRange === "^" || resolvedRange === "~") resolvedRange = `${resolvedRange}${pkg.version}`;
1436
+ if (/^\^0(\.|$)/.test(resolvedRange)) warnings.push(`${dep.name} gets a ${depBump} bump because ${pkgName}@${newVersion} is out of range for its peer dep "${dep.versionRange}" (resolves to ${resolvedRange}). npm treats ^ on 0.x as minor-breaking. Consider using >=0.x ranges for pre-1.0 peer deps.`);
1437
+ }
1438
+ if (applyBump(planned, dep.name, depBump, true, false, pkgName)) changed = true;
1439
+ }
1440
+ }
1441
+ for (const group of config.fixed) {
1442
+ let groupBump;
1443
+ const groupSources = [];
1444
+ for (const nameOrGlob of group) for (const [name, bump] of planned) if (matchGlob(name, nameOrGlob)) {
1445
+ if (!groupBump || bumpLevel(bump.type) > bumpLevel(groupBump)) {
1446
+ groupBump = bump.type;
1447
+ groupSources.length = 0;
1448
+ groupSources.push(name);
1449
+ } else if (bump.type === groupBump) groupSources.push(name);
1450
+ }
1451
+ if (!groupBump) continue;
1452
+ for (const nameOrGlob of group) for (const [name] of packages) {
1453
+ if (!matchGlob(name, nameOrGlob)) continue;
1454
+ const existing = planned.get(name);
1455
+ if (existing) {
1456
+ const newType = maxBump(existing.type, groupBump);
1457
+ if (newType !== existing.type) {
1458
+ existing.type = newType;
1459
+ existing.isGroupBump = true;
1460
+ for (const src of groupSources) if (src !== name) existing.bumpSources.set(src, groupBump);
1461
+ changed = true;
1462
+ }
1463
+ } else {
1464
+ planned.set(name, {
1465
+ type: groupBump,
1466
+ isDependencyBump: false,
1467
+ isCascadeBump: false,
1468
+ isGroupBump: true,
1469
+ bumpFiles: /* @__PURE__ */ new Set(),
1470
+ bumpSources: new Map(groupSources.filter((s) => s !== name).map((s) => [s, groupBump]))
1471
+ });
1472
+ changed = true;
1473
+ }
1474
+ }
1475
+ }
1476
+ for (const group of config.linked) {
1477
+ let groupBump;
1478
+ const groupSources = [];
1479
+ for (const nameOrGlob of group) for (const [name, bump] of planned) if (matchGlob(name, nameOrGlob)) {
1480
+ if (!groupBump || bumpLevel(bump.type) > bumpLevel(groupBump)) {
1481
+ groupBump = bump.type;
1482
+ groupSources.length = 0;
1483
+ groupSources.push(name);
1484
+ } else if (bump.type === groupBump) groupSources.push(name);
1485
+ }
1486
+ if (!groupBump) continue;
1487
+ for (const nameOrGlob of group) for (const [name] of packages) {
1488
+ if (!matchGlob(name, nameOrGlob)) continue;
1489
+ const existing = planned.get(name);
1490
+ if (!existing) continue;
1491
+ const newType = maxBump(existing.type, groupBump);
1492
+ if (newType !== existing.type) {
1493
+ existing.type = newType;
1494
+ existing.isGroupBump = true;
1495
+ for (const src of groupSources) if (src !== name) existing.bumpSources.set(src, groupBump);
1496
+ changed = true;
1497
+ }
1498
+ }
1499
+ }
1500
+ if (config.updateInternalDependencies !== "out-of-range") for (const [pkgName, bump] of planned) {
1501
+ if (config.updateInternalDependencies === "minor" && bumpLevel(bump.type) < bumpLevel("minor")) continue;
1502
+ const bfOverrides = cascadeOverrides.get(pkgName);
1503
+ if (bfOverrides) for (const [pattern, cascadeBumpType] of bfOverrides) for (const [targetName] of packages) {
1504
+ if (!matchGlob(targetName, pattern)) continue;
1505
+ if (applyBump(planned, targetName, cascadeBumpType, false, true, pkgName)) changed = true;
1506
+ }
1507
+ const cascadeTo = packages.get(pkgName)?.bumpy?.cascadeTo;
1508
+ if (cascadeTo) for (const [pattern, rule] of Object.entries(cascadeTo)) {
1509
+ if (!shouldTrigger(bump.type, rule.trigger)) continue;
1510
+ const cascadeBump = rule.bumpAs === "match" ? bump.type : rule.bumpAs;
1511
+ for (const [targetName] of packages) {
1512
+ if (!matchGlob(targetName, pattern)) continue;
1513
+ if (applyBump(planned, targetName, cascadeBump, false, true, pkgName)) changed = true;
1514
+ }
1515
+ }
1516
+ const dependents = depGraph.getDependents(pkgName);
1517
+ for (const dep of dependents) {
1518
+ const rule = resolveRule(dep.name, dep.depType, packages, config);
1519
+ if (!rule) continue;
1520
+ if (!shouldTrigger(bump.type, rule.trigger)) continue;
1521
+ const depBump = rule.bumpAs === "match" ? bump.type : rule.bumpAs;
1522
+ if (applyBump(planned, dep.name, depBump, true, false, pkgName)) changed = true;
1523
+ }
1524
+ }
1525
+ else for (const [pkgName, bump] of planned) {
1526
+ const bfOverrides = cascadeOverrides.get(pkgName);
1527
+ if (bfOverrides) for (const [pattern, cascadeBumpType] of bfOverrides) for (const [targetName] of packages) {
1528
+ if (!matchGlob(targetName, pattern)) continue;
1529
+ if (applyBump(planned, targetName, cascadeBumpType, false, true, pkgName)) changed = true;
1530
+ }
1531
+ const cascadeTo = packages.get(pkgName)?.bumpy?.cascadeTo;
1532
+ if (cascadeTo) for (const [pattern, rule] of Object.entries(cascadeTo)) {
1533
+ if (!shouldTrigger(bump.type, rule.trigger)) continue;
1534
+ const cascadeBump = rule.bumpAs === "match" ? bump.type : rule.bumpAs;
1535
+ for (const [targetName] of packages) {
1536
+ if (!matchGlob(targetName, pattern)) continue;
1537
+ if (applyBump(planned, targetName, cascadeBump, false, true, pkgName)) changed = true;
1538
+ }
1539
+ }
1540
+ }
1541
+ }
1542
+ const releases = [];
1543
+ for (const [name, bump] of planned) {
1544
+ const pkg = packages.get(name);
1545
+ if (!pkg) continue;
1546
+ const newVersion = bumpVersion(pkg.version, bump.type);
1547
+ releases.push({
1548
+ name,
1549
+ type: bump.type,
1550
+ oldVersion: pkg.version,
1551
+ newVersion,
1552
+ bumpFiles: [...bump.bumpFiles],
1553
+ isDependencyBump: bump.isDependencyBump,
1554
+ isCascadeBump: bump.isCascadeBump,
1555
+ isGroupBump: bump.isGroupBump,
1556
+ bumpSources: [...bump.bumpSources].map(([srcName, contributedType]) => {
1557
+ const srcBump = planned.get(srcName);
1558
+ const srcPkg = packages.get(srcName);
1559
+ return {
1560
+ name: srcName,
1561
+ newVersion: srcPkg && srcBump ? bumpVersion(srcPkg.version, srcBump.type) : "unknown",
1562
+ bumpType: contributedType
1563
+ };
1564
+ })
1565
+ });
1566
+ }
1567
+ releases.sort((a, b) => a.name.localeCompare(b.name));
1568
+ for (const [name, pkg] of packages) for (const [depName, range] of Object.entries(pkg.peerDependencies)) if (range === "workspace:*" && packages.has(depName)) warnings.push(`${name} has peer dep "${depName}": "workspace:*" — this will be published as a fixed range which may not match your intent. Consider using "workspace:^" instead.`);
1569
+ return {
1570
+ bumpFiles,
1571
+ releases,
1572
+ warnings
1573
+ };
1574
+ }
1575
+ /** Apply a bump to a package, upgrading if already planned. Returns true if anything changed. */
1576
+ function applyBump(planned, name, type, isDependencyBump, isCascadeBump, sourcePackageName) {
1577
+ const existing = planned.get(name);
1578
+ if (existing) {
1579
+ const newType = maxBump(existing.type, type);
1580
+ if (newType === existing.type) return false;
1581
+ existing.type = newType;
1582
+ if (isDependencyBump) existing.isDependencyBump = true;
1583
+ if (isCascadeBump) existing.isCascadeBump = true;
1584
+ existing.bumpSources.set(sourcePackageName, type);
1585
+ return true;
1586
+ }
1587
+ planned.set(name, {
1588
+ type,
1589
+ isDependencyBump,
1590
+ isCascadeBump,
1591
+ isGroupBump: false,
1592
+ bumpFiles: /* @__PURE__ */ new Set(),
1593
+ bumpSources: new Map([[sourcePackageName, type]])
1594
+ });
1595
+ return true;
1596
+ }
1597
+ /** Check if a bump level meets the trigger threshold */
1598
+ function shouldTrigger(bumpType, trigger) {
1599
+ return bumpLevel(bumpType) >= bumpLevel(trigger);
1600
+ }
1601
+ /**
1602
+ * Resolve the dependency bump rule for a specific dependent + dep type.
1603
+ * Priority: per-package depType rules > global depType rules > defaults
1604
+ * Returns false if the rule is disabled.
1605
+ */
1606
+ function resolveRule(dependentName, depType, packages, config) {
1607
+ const dependent = packages.get(dependentName);
1608
+ if (dependent?.bumpy?.dependencyBumpRules && depType in dependent.bumpy.dependencyBumpRules) return dependent.bumpy.dependencyBumpRules[depType];
1609
+ if (depType in config.dependencyBumpRules) return config.dependencyBumpRules[depType];
1610
+ const defaultRule = DEFAULT_BUMP_RULES[depType];
1611
+ return defaultRule !== void 0 ? defaultRule : {
1612
+ trigger: "patch",
1613
+ bumpAs: "patch"
1614
+ };
1615
+ }
1616
+ //#endregion
1617
+ export { stripProtocol as i, bumpVersion as n, satisfies as r, assembleReleasePlan as t };
@@ -1,4 +1,4 @@
1
- import { a as __exportAll } from "./logger-C2dEe5Su.mjs";
1
+ import { a as __exportAll } from "./logger-BgksGFuf.mjs";
2
2
  import { exec, execFile, execFileSync, execSync } from "node:child_process";
3
3
  //#region src/utils/shell.ts
4
4
  var shell_exports = /* @__PURE__ */ __exportAll({
@@ -1,10 +1,9 @@
1
- import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as loadConfig } from "./config-D13G4-R8.mjs";
3
- import { t as discoverPackages } from "./workspace-Yt7qwsML.mjs";
1
+ import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
2
+ import { a as loadConfig } from "./config-BcmlSJJd.mjs";
3
+ import { a as discoverPackages, r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-4cnuDyfW.mjs";
4
4
  import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
5
- import { r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-CoaSxqne.mjs";
6
- import { t as assembleReleasePlan } from "./release-plan-C1Lz9rl_.mjs";
7
- import { i as getCurrentBranch, r as getChangedFiles } from "./git-ukq7VTuZ.mjs";
5
+ import { t as assembleReleasePlan } from "./release-plan-M9TGZn2W.mjs";
6
+ import { i as getCurrentBranch, r as getChangedFiles } from "./git-DE46Je5V.mjs";
8
7
  //#region src/commands/status.ts
9
8
  async function statusCommand(rootDir, opts) {
10
9
  const config = await loadConfig(rootDir);
@@ -31,7 +30,7 @@ async function statusCommand(rootDir, opts) {
31
30
  releases = releases.filter((r) => types.includes(r.type));
32
31
  }
33
32
  if (opts.filter) {
34
- const { matchGlob } = await import("./config-D13G4-R8.mjs").then((n) => n.t);
33
+ const { matchGlob } = await import("./config-BcmlSJJd.mjs").then((n) => n.t);
35
34
  const patterns = opts.filter.split(",").map((p) => p.trim());
36
35
  releases = releases.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
37
36
  }
@@ -123,8 +122,8 @@ function getPublishTargets(pkg, pkgConfig, _config) {
123
122
  if (!pkg) return [];
124
123
  if (pkg.private && !pkgConfig.publishCommand) return [];
125
124
  const targets = [];
126
- if (pkgConfig.publishCommand) targets.push("custom");
127
- if (!pkgConfig.publishCommand && !pkgConfig.skipNpmPublish) targets.push("npm");
125
+ if (pkgConfig.publishCommand) targets.push({ type: "custom" });
126
+ if (!pkgConfig.publishCommand && !pkgConfig.skipNpmPublish) targets.push({ type: "npm" });
128
127
  return targets;
129
128
  }
130
129
  //#endregion
@@ -1,13 +1,12 @@
1
- import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as loadConfig } from "./config-D13G4-R8.mjs";
3
- import { n as detectWorkspaces } from "./package-manager-CClZtIHP.mjs";
4
- import { t as discoverPackages } from "./workspace-Yt7qwsML.mjs";
1
+ import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
2
+ import { a as loadConfig } from "./config-BcmlSJJd.mjs";
3
+ import { n as detectWorkspaces } from "./package-manager-BQPwXwu5.mjs";
4
+ import { a as discoverPackages, r as readBumpFiles } from "./bump-file-4cnuDyfW.mjs";
5
5
  import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
6
- import { n as runArgs, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
7
- import { r as readBumpFiles } from "./bump-file-CoaSxqne.mjs";
8
- import { t as assembleReleasePlan } from "./release-plan-C1Lz9rl_.mjs";
9
- import { t as applyReleasePlan } from "./apply-release-plan-DNpoi7cS.mjs";
10
- import { t as resolveCommitMessage } from "./commit-message-3e4KhzFV.mjs";
6
+ import { n as runArgs, s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
7
+ import { t as assembleReleasePlan } from "./release-plan-M9TGZn2W.mjs";
8
+ import { t as applyReleasePlan } from "./apply-release-plan-BRN29C3D.mjs";
9
+ import { t as resolveCommitMessage } from "./commit-message-BA1w19wq.mjs";
11
10
  //#region src/commands/version.ts
12
11
  async function versionCommand(rootDir, opts = {}) {
13
12
  const config = await loadConfig(rootDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varlock/bumpy",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Modern monorepo versioning and changelog tool",
5
5
  "keywords": [
6
6
  "bump",