pubm 0.0.4 → 0.1.2

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/dist/index.js CHANGED
@@ -711,7 +711,7 @@ var init_mjs = __esm({
711
711
  "node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js"() {
712
712
  "use strict";
713
713
  init_signals();
714
- processOk = (process11) => !!process11 && typeof process11 === "object" && typeof process11.removeListener === "function" && typeof process11.emit === "function" && typeof process11.reallyExit === "function" && typeof process11.listeners === "function" && typeof process11.kill === "function" && typeof process11.pid === "number" && typeof process11.on === "function";
714
+ processOk = (process16) => !!process16 && typeof process16 === "object" && typeof process16.removeListener === "function" && typeof process16.emit === "function" && typeof process16.reallyExit === "function" && typeof process16.listeners === "function" && typeof process16.kill === "function" && typeof process16.pid === "number" && typeof process16.on === "function";
715
715
  kExitEmitter = Symbol.for("signal-exit emitter");
716
716
  global = globalThis;
717
717
  ObjectDefineProperty = Object.defineProperty.bind(Object);
@@ -793,7 +793,7 @@ var init_mjs = __esm({
793
793
  }
794
794
  };
795
795
  SignalExit = class extends SignalExitBase {
796
- constructor(process11) {
796
+ constructor(process16) {
797
797
  super();
798
798
  __privateAdd(this, _SignalExit_instances);
799
799
  // "SIGHUP" throws an `ENOSYS` error on Windows,
@@ -807,13 +807,13 @@ var init_mjs = __esm({
807
807
  __privateAdd(this, _originalProcessReallyExit);
808
808
  __privateAdd(this, _sigListeners, {});
809
809
  __privateAdd(this, _loaded, false);
810
- __privateSet(this, _process, process11);
810
+ __privateSet(this, _process, process16);
811
811
  __privateSet(this, _sigListeners, {});
812
812
  for (const sig of signals) {
813
813
  __privateGet(this, _sigListeners)[sig] = () => {
814
814
  const listeners = __privateGet(this, _process).listeners(sig);
815
815
  let { count } = __privateGet(this, _emitter);
816
- const p = process11;
816
+ const p = process16;
817
817
  if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
818
818
  count += p.__signal_exit_emitter__.count;
819
819
  }
@@ -822,12 +822,12 @@ var init_mjs = __esm({
822
822
  const ret = __privateGet(this, _emitter).emit("exit", null, sig);
823
823
  const s = sig === "SIGHUP" ? __privateGet(this, _hupSig) : sig;
824
824
  if (!ret)
825
- process11.kill(process11.pid, s);
825
+ process16.kill(process16.pid, s);
826
826
  }
827
827
  };
828
828
  }
829
- __privateSet(this, _originalProcessReallyExit, process11.reallyExit);
830
- __privateSet(this, _originalProcessEmit, process11.emit);
829
+ __privateSet(this, _originalProcessReallyExit, process16.reallyExit);
830
+ __privateSet(this, _originalProcessEmit, process16.emit);
831
831
  }
832
832
  onExit(cb, opts) {
833
833
  if (!processOk(__privateGet(this, _process))) {
@@ -4376,7 +4376,7 @@ var Listr = (_a23 = class {
4376
4376
  // src/tasks/runner.ts
4377
4377
  import SemVer from "semver";
4378
4378
  import { isCI as isCI2 } from "std-env";
4379
- import { exec as exec6 } from "tinyexec";
4379
+ import { exec as exec7 } from "tinyexec";
4380
4380
 
4381
4381
  // src/error.ts
4382
4382
  var AbstractError = class extends Error {
@@ -4391,10 +4391,13 @@ function replaceCode(code) {
4391
4391
  }
4392
4392
  function formatError(error) {
4393
4393
  if (!(error instanceof Error)) return `${error}`;
4394
- const message = typeof error.message === "string" ? replaceCode(error.message) : formatError(error);
4394
+ const message = typeof error.message === "string" ? replaceCode(error.message) : (
4395
+ /* v8 ignore next */
4396
+ formatError(error)
4397
+ );
4395
4398
  let stringifyError = `${color.bgRed(` ${error.name} `)}${color.reset("")} ${message}
4396
4399
  `;
4397
- stringifyError += error.stack?.split("\n").slice(1).join("\n").replace(/at/g, color.dim("at")).replace(/\(([^\(].+)\)/g, `(${color.blue("$1")})`);
4400
+ stringifyError += error.stack?.split("\n").slice(1).join("\n").replace(/at/g, color.dim("at")).replace(/\(([^(].+)\)/g, `(${color.blue("$1")})`);
4398
4401
  if (error.cause) {
4399
4402
  stringifyError += "\n\nCaused: ";
4400
4403
  stringifyError += formatError(error.cause);
@@ -4425,8 +4428,7 @@ var GitError = class extends AbstractError {
4425
4428
  };
4426
4429
  var Git = class {
4427
4430
  async git(args) {
4428
- const { stdout, stderr } = await exec2("git", args);
4429
- if (stderr) throw stderr;
4431
+ const { stdout } = await exec2("git", args, { throwOnError: true });
4430
4432
  return stdout;
4431
4433
  }
4432
4434
  async userName() {
@@ -4447,7 +4449,7 @@ var Git = class {
4447
4449
  }
4448
4450
  async tags() {
4449
4451
  try {
4450
- return (await this.git(["tag", "-l"])).trim().split("\n").map((v) => v.slice(1)).sort(semver.compareIdentifiers);
4452
+ return (await this.git(["tag", "-l"])).trim().split("\n").sort(semver.compareIdentifiers);
4451
4453
  } catch (error) {
4452
4454
  throw new GitError("Failed to run `git config --get user.name`", {
4453
4455
  cause: error
@@ -4457,7 +4459,8 @@ var Git = class {
4457
4459
  async previousTag(tag) {
4458
4460
  try {
4459
4461
  const tags = await this.tags();
4460
- return tags.at(tags.findIndex((t) => t === tag) - 1) ?? null;
4462
+ const strip = (t) => t.replace(/^v/, "");
4463
+ return tags.at(tags.findIndex((t) => strip(t) === strip(tag)) - 1) ?? null;
4461
4464
  } catch {
4462
4465
  return null;
4463
4466
  }
@@ -4562,13 +4565,8 @@ var Git = class {
4562
4565
  async checkTagExist(tag) {
4563
4566
  try {
4564
4567
  return (await this.git(["rev-parse", "-q", "--verify", `refs/tags/${tag}`])).trim() !== "";
4565
- } catch (error) {
4566
- throw new GitError(
4567
- `Failed to run \`git rev-parse -q --verify refs/tags/${tag}\``,
4568
- {
4569
- cause: error
4570
- }
4571
- );
4568
+ } catch {
4569
+ return false;
4572
4570
  }
4573
4571
  }
4574
4572
  async deleteTag(tag) {
@@ -4919,17 +4917,222 @@ async function getPackageManager() {
4919
4917
  return "npm";
4920
4918
  }
4921
4919
 
4920
+ // src/ecosystem/rust.ts
4921
+ import { readFile as readFile2, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
4922
+ import path2 from "node:path";
4923
+ import { parse, stringify } from "smol-toml";
4924
+
4925
+ // src/ecosystem/ecosystem.ts
4926
+ var Ecosystem = class {
4927
+ constructor(packagePath) {
4928
+ this.packagePath = packagePath;
4929
+ }
4930
+ };
4931
+
4932
+ // src/ecosystem/rust.ts
4933
+ var RustEcosystem = class extends Ecosystem {
4934
+ static async detect(packagePath) {
4935
+ try {
4936
+ return (await stat2(path2.join(packagePath, "Cargo.toml"))).isFile();
4937
+ } catch {
4938
+ return false;
4939
+ }
4940
+ }
4941
+ async readCargoToml() {
4942
+ const raw = await readFile2(
4943
+ path2.join(this.packagePath, "Cargo.toml"),
4944
+ "utf-8"
4945
+ );
4946
+ return parse(raw);
4947
+ }
4948
+ async packageName() {
4949
+ const cargo = await this.readCargoToml();
4950
+ const pkg = cargo.package;
4951
+ return pkg.name;
4952
+ }
4953
+ async readVersion() {
4954
+ const cargo = await this.readCargoToml();
4955
+ const pkg = cargo.package;
4956
+ return pkg.version;
4957
+ }
4958
+ async writeVersion(newVersion) {
4959
+ const filePath = path2.join(this.packagePath, "Cargo.toml");
4960
+ const raw = await readFile2(filePath, "utf-8");
4961
+ const cargo = parse(raw);
4962
+ const pkg = cargo.package;
4963
+ pkg.version = newVersion;
4964
+ await writeFile2(filePath, stringify(cargo));
4965
+ }
4966
+ manifestFiles() {
4967
+ return ["Cargo.toml"];
4968
+ }
4969
+ defaultTestCommand() {
4970
+ return "cargo test";
4971
+ }
4972
+ defaultBuildCommand() {
4973
+ return "cargo build --release";
4974
+ }
4975
+ supportedRegistries() {
4976
+ return ["crates"];
4977
+ }
4978
+ };
4979
+
4980
+ // src/registry/crates.ts
4981
+ import { exec as exec3 } from "tinyexec";
4982
+
4983
+ // src/registry/registry.ts
4984
+ var Registry = class {
4985
+ constructor(packageName, registry) {
4986
+ this.packageName = packageName;
4987
+ this.registry = registry;
4988
+ }
4989
+ };
4990
+
4991
+ // src/registry/crates.ts
4992
+ var CratesError = class extends AbstractError {
4993
+ constructor() {
4994
+ super(...arguments);
4995
+ __publicField(this, "name", "crates.io Error");
4996
+ }
4997
+ };
4998
+ var USER_AGENT = "pubm (https://github.com/syi0808/pubm)";
4999
+ var CratesRegistry = class extends Registry {
5000
+ constructor() {
5001
+ super(...arguments);
5002
+ __publicField(this, "registry", "https://crates.io");
5003
+ }
5004
+ get headers() {
5005
+ return { "User-Agent": USER_AGENT };
5006
+ }
5007
+ async ping() {
5008
+ try {
5009
+ const response = await fetch(`${this.registry}/api/v1`, {
5010
+ headers: this.headers
5011
+ });
5012
+ return response.ok;
5013
+ } catch (error) {
5014
+ throw new CratesError("Failed to ping crates.io", { cause: error });
5015
+ }
5016
+ }
5017
+ async isInstalled() {
5018
+ try {
5019
+ await exec3("cargo", ["--version"]);
5020
+ return true;
5021
+ } catch {
5022
+ return false;
5023
+ }
5024
+ }
5025
+ async distTags() {
5026
+ return [];
5027
+ }
5028
+ async version() {
5029
+ try {
5030
+ const response = await fetch(
5031
+ `${this.registry}/api/v1/crates/${this.packageName}`,
5032
+ { headers: this.headers }
5033
+ );
5034
+ if (!response.ok) {
5035
+ throw new Error(`Crate '${this.packageName}' not found`);
5036
+ }
5037
+ const data = await response.json();
5038
+ return data.crate.max_version;
5039
+ } catch (error) {
5040
+ throw new CratesError(
5041
+ `Failed to fetch version for crate '${this.packageName}'`,
5042
+ { cause: error }
5043
+ );
5044
+ }
5045
+ }
5046
+ async publish() {
5047
+ try {
5048
+ await exec3("cargo", ["publish"], { throwOnError: true });
5049
+ return true;
5050
+ } catch (error) {
5051
+ throw new CratesError("Failed to run `cargo publish`", {
5052
+ cause: error
5053
+ });
5054
+ }
5055
+ }
5056
+ async isPublished() {
5057
+ try {
5058
+ const response = await fetch(
5059
+ `${this.registry}/api/v1/crates/${this.packageName}`,
5060
+ { headers: this.headers }
5061
+ );
5062
+ return response.ok;
5063
+ } catch {
5064
+ return false;
5065
+ }
5066
+ }
5067
+ async hasPermission() {
5068
+ if (process.env.CARGO_REGISTRY_TOKEN) return true;
5069
+ return this.isInstalled();
5070
+ }
5071
+ async isPackageNameAvaliable() {
5072
+ try {
5073
+ const response = await fetch(
5074
+ `${this.registry}/api/v1/crates/${this.packageName}`,
5075
+ { headers: this.headers }
5076
+ );
5077
+ return !response.ok;
5078
+ } catch {
5079
+ return true;
5080
+ }
5081
+ }
5082
+ };
5083
+ async function cratesRegistry(packageName) {
5084
+ return new CratesRegistry(packageName);
5085
+ }
5086
+
5087
+ // src/tasks/crates.ts
5088
+ var CratesError2 = class extends AbstractError {
5089
+ constructor(message, { cause } = {}) {
5090
+ super(message, { cause });
5091
+ __publicField(this, "name", "crates.io Error");
5092
+ this.stack = "";
5093
+ }
5094
+ };
5095
+ async function getCrateName() {
5096
+ const eco = new RustEcosystem(process.cwd());
5097
+ return await eco.packageName();
5098
+ }
5099
+ var cratesAvailableCheckTasks = {
5100
+ title: "Checking crates.io availability",
5101
+ task: async () => {
5102
+ const packageName = await getCrateName();
5103
+ const registry = new CratesRegistry(packageName);
5104
+ if (!await registry.isInstalled()) {
5105
+ throw new CratesError2(
5106
+ "cargo is not installed. Please install Rust toolchain to proceed."
5107
+ );
5108
+ }
5109
+ if (!await registry.hasPermission()) {
5110
+ throw new CratesError2(
5111
+ "No crates.io credentials found. Run `cargo login` or set CARGO_REGISTRY_TOKEN."
5112
+ );
5113
+ }
5114
+ }
5115
+ };
5116
+ var cratesPublishTasks = {
5117
+ title: "Publishing to crates.io",
5118
+ task: async () => {
5119
+ const packageName = await getCrateName();
5120
+ const registry = new CratesRegistry(packageName);
5121
+ await registry.publish();
5122
+ }
5123
+ };
5124
+
4922
5125
  // src/tasks/jsr.ts
4923
5126
  import process8 from "node:process";
4924
5127
  import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
4925
5128
 
4926
5129
  // src/registry/jsr.ts
4927
- import { exec as exec3 } from "tinyexec";
5130
+ import { NonZeroExitError, exec as exec4 } from "tinyexec";
4928
5131
 
4929
5132
  // src/utils/db.ts
4930
5133
  import { createCipheriv, createDecipheriv, createHash } from "node:crypto";
4931
5134
  import { mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
4932
- import path2 from "node:path";
5135
+ import path3 from "node:path";
4933
5136
  var a = "aes-256-cbc";
4934
5137
  var n = statSync(import.meta.dirname);
4935
5138
  var k = `${n.rdev}${n.birthtimeMs}${n.nlink}${n.gid}`;
@@ -4944,7 +5147,7 @@ function d(g, h) {
4944
5147
  }
4945
5148
  var Db = class {
4946
5149
  constructor() {
4947
- __publicField(this, "path", path2.resolve(import.meta.dirname, ".pubm"));
5150
+ __publicField(this, "path", path3.resolve(import.meta.dirname, ".pubm"));
4948
5151
  try {
4949
5152
  if (!statSync(this.path).isDirectory()) {
4950
5153
  mkdirSync(this.path);
@@ -4955,7 +5158,7 @@ var Db = class {
4955
5158
  }
4956
5159
  set(field, value) {
4957
5160
  writeFileSync(
4958
- path2.resolve(this.path, Buffer.from(e(field, field)).toString("base64")),
5161
+ path3.resolve(this.path, Buffer.from(e(field, field)).toString("base64")),
4959
5162
  Buffer.from(e(`${value}`, field)),
4960
5163
  { encoding: "binary" }
4961
5164
  );
@@ -4965,7 +5168,7 @@ var Db = class {
4965
5168
  return d(
4966
5169
  Buffer.from(
4967
5170
  readFileSync(
4968
- path2.resolve(
5171
+ path3.resolve(
4969
5172
  this.path,
4970
5173
  Buffer.from(e(field, field)).toString("base64")
4971
5174
  )
@@ -5020,14 +5223,6 @@ function isValidPackageName(packageName) {
5020
5223
  return true;
5021
5224
  }
5022
5225
 
5023
- // src/registry/registry.ts
5024
- var Registry = class {
5025
- constructor(packageName, registry) {
5026
- this.packageName = packageName;
5027
- this.registry = registry;
5028
- }
5029
- };
5030
-
5031
5226
  // src/registry/jsr.ts
5032
5227
  var JsrError = class extends AbstractError {
5033
5228
  constructor() {
@@ -5048,13 +5243,12 @@ var JsrRegisry = class extends Registry {
5048
5243
  this.client = new JsrClient(getApiEndpoint(this.registry));
5049
5244
  }
5050
5245
  async jsr(args) {
5051
- const { stdout, stderr } = await exec3("jsr", args);
5052
- if (stderr) throw stderr;
5246
+ const { stdout } = await exec4("jsr", args, { throwOnError: true });
5053
5247
  return stdout;
5054
5248
  }
5055
5249
  async isInstalled() {
5056
5250
  try {
5057
- await this.jsr(["--help"]);
5251
+ await this.jsr(["--version"]);
5058
5252
  return true;
5059
5253
  } catch {
5060
5254
  return false;
@@ -5065,12 +5259,11 @@ var JsrRegisry = class extends Registry {
5065
5259
  }
5066
5260
  async ping() {
5067
5261
  try {
5068
- const { stdout, stderr } = await exec3("ping", [
5069
- new URL(this.registry).hostname,
5070
- "-c",
5071
- "1"
5072
- ]);
5073
- if (stderr) throw stderr;
5262
+ const { stdout } = await exec4(
5263
+ "ping",
5264
+ [new URL(this.registry).hostname, "-c", "1"],
5265
+ { throwOnError: true }
5266
+ );
5074
5267
  return stdout.includes("1 packets transmitted");
5075
5268
  } catch (error) {
5076
5269
  throw new JsrError(
@@ -5081,7 +5274,7 @@ var JsrRegisry = class extends Registry {
5081
5274
  }
5082
5275
  async publish() {
5083
5276
  try {
5084
- await exec3(
5277
+ await exec4(
5085
5278
  "jsr",
5086
5279
  ["publish", "--allow-dirty", "--token", `${JsrClient.token}`],
5087
5280
  {
@@ -5090,8 +5283,10 @@ var JsrRegisry = class extends Registry {
5090
5283
  );
5091
5284
  return true;
5092
5285
  } catch (error) {
5286
+ const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
5093
5287
  throw new JsrError(
5094
- "Failed to run `jsr publish --allow-dirty --token ***`",
5288
+ `Failed to run \`jsr publish --allow-dirty --token ***\`${stderr ? `
5289
+ ${stderr}` : ""}`,
5095
5290
  {
5096
5291
  cause: error
5097
5292
  }
@@ -5272,7 +5467,7 @@ async function jsrRegistry() {
5272
5467
  }
5273
5468
 
5274
5469
  // src/registry/npm.ts
5275
- import { exec as exec4 } from "tinyexec";
5470
+ import { NonZeroExitError as NonZeroExitError2, exec as exec5 } from "tinyexec";
5276
5471
  var NpmError = class extends AbstractError {
5277
5472
  constructor() {
5278
5473
  super(...arguments);
@@ -5285,13 +5480,12 @@ var NpmRegistry = class extends Registry {
5285
5480
  __publicField(this, "registry", "https://registry.npmjs.org");
5286
5481
  }
5287
5482
  async npm(args) {
5288
- const { stdout, stderr } = await exec4("npm", args);
5289
- if (stderr) throw stderr;
5483
+ const { stdout } = await exec5("npm", args, { throwOnError: true });
5290
5484
  return stdout;
5291
5485
  }
5292
5486
  async isInstalled() {
5293
5487
  try {
5294
- await this.npm(["--help"]);
5488
+ await this.npm(["--version"]);
5295
5489
  return true;
5296
5490
  } catch {
5297
5491
  return false;
@@ -5330,7 +5524,7 @@ var NpmRegistry = class extends Registry {
5330
5524
  await this.npm(["whoami"]);
5331
5525
  return true;
5332
5526
  } catch (error) {
5333
- if (`${error}`.includes("ENEEDAUTH")) {
5527
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("ENEEDAUTH")) {
5334
5528
  return false;
5335
5529
  }
5336
5530
  throw new NpmError("Failed to run `npm whoami`", { cause: error });
@@ -5382,7 +5576,7 @@ var NpmRegistry = class extends Registry {
5382
5576
  }
5383
5577
  async ping() {
5384
5578
  try {
5385
- await exec4("npm", ["ping"], { throwOnError: true });
5579
+ await exec5("npm", ["ping"], { throwOnError: true });
5386
5580
  return true;
5387
5581
  } catch (error) {
5388
5582
  throw new NpmError("Failed to run `npm ping`", { cause: error });
@@ -5390,15 +5584,12 @@ var NpmRegistry = class extends Registry {
5390
5584
  }
5391
5585
  async publishProvenance() {
5392
5586
  try {
5393
- try {
5394
- await this.npm(["publish", "--provenance", "--access", "public"]);
5395
- } catch (error) {
5396
- if (`${error}`.includes("EOTP")) {
5397
- return false;
5398
- }
5399
- }
5587
+ await this.npm(["publish", "--provenance", "--access", "public"]);
5400
5588
  return true;
5401
5589
  } catch (error) {
5590
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("EOTP")) {
5591
+ return false;
5592
+ }
5402
5593
  throw new NpmError(
5403
5594
  "Failed to run `npm publish --provenance --access public`",
5404
5595
  {
@@ -5410,15 +5601,12 @@ var NpmRegistry = class extends Registry {
5410
5601
  async publish(otp) {
5411
5602
  const args = otp ? ["publish", "--otp", otp] : ["publish"];
5412
5603
  try {
5413
- try {
5414
- await this.npm(args);
5415
- } catch (error) {
5416
- if (`${error}`.includes("EOTP")) {
5417
- return false;
5418
- }
5419
- }
5604
+ await this.npm(args);
5420
5605
  return true;
5421
5606
  } catch (error) {
5607
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("EOTP")) {
5608
+ return false;
5609
+ }
5422
5610
  throw new NpmError(`Failed to run \`npm ${args.join(" ")}\``, {
5423
5611
  cause: error
5424
5612
  });
@@ -5826,14 +6014,14 @@ var prerequisitesCheckTask = (options) => {
5826
6014
  import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter4 } from "@listr2/prompt-adapter-enquirer";
5827
6015
 
5828
6016
  // src/registry/custom-registry.ts
5829
- import { exec as exec5 } from "tinyexec";
6017
+ import { exec as exec6 } from "tinyexec";
5830
6018
  var CustomRegistry = class extends NpmRegistry {
5831
6019
  async npm(args) {
5832
- const { stdout, stderr } = await exec5(
6020
+ const { stdout } = await exec6(
5833
6021
  "npm",
5834
- args.concat("--registry", this.registry)
6022
+ args.concat("--registry", this.registry),
6023
+ { throwOnError: true }
5835
6024
  );
5836
- if (stderr) throw stderr;
5837
6025
  return stdout;
5838
6026
  }
5839
6027
  };
@@ -5847,7 +6035,10 @@ var registryMap = {
5847
6035
  npm: npmRegistry,
5848
6036
  jsr: jsrRegistry
5849
6037
  };
5850
- async function getRegistry(registryKey) {
6038
+ async function getRegistry(registryKey, packageName) {
6039
+ if (registryKey === "crates") {
6040
+ return await cratesRegistry(packageName ?? "unknown");
6041
+ }
5851
6042
  const registry = registryMap[registryKey];
5852
6043
  if (!registry) {
5853
6044
  return await customRegistry();
@@ -5977,6 +6168,8 @@ var requiredConditionsCheckTask = (options) => createListr({
5977
6168
  return npmAvailableCheckTasks;
5978
6169
  case "jsr":
5979
6170
  return jsrAvailableCheckTasks;
6171
+ case "crates":
6172
+ return cratesAvailableCheckTasks;
5980
6173
  default:
5981
6174
  return npmAvailableCheckTasks;
5982
6175
  }
@@ -6023,6 +6216,8 @@ async function run(options) {
6023
6216
  return npmPublishTasks;
6024
6217
  case "jsr":
6025
6218
  return jsrPublishTasks;
6219
+ case "crates":
6220
+ return cratesPublishTasks;
6026
6221
  default:
6027
6222
  return npmPublishTasks;
6028
6223
  }
@@ -6035,16 +6230,9 @@ async function run(options) {
6035
6230
  title: "Running tests",
6036
6231
  task: async (ctx2) => {
6037
6232
  const packageManager = await getPackageManager();
6038
- const { stderr } = await exec6(packageManager, [
6039
- "run",
6040
- ctx2.testScript
6041
- ]);
6042
- if (stderr) {
6043
- throw new AbstractError(
6044
- `Failed to run \`${packageManager} run ${ctx2.testScript}\``,
6045
- { cause: stderr }
6046
- );
6047
- }
6233
+ await exec7(packageManager, ["run", ctx2.testScript], {
6234
+ throwOnError: true
6235
+ });
6048
6236
  }
6049
6237
  },
6050
6238
  {
@@ -6053,7 +6241,7 @@ async function run(options) {
6053
6241
  task: async (ctx2) => {
6054
6242
  const packageManager = await getPackageManager();
6055
6243
  try {
6056
- await exec6(packageManager, ["run", ctx2.buildScript], {
6244
+ await exec7(packageManager, ["run", ctx2.buildScript], {
6057
6245
  throwOnError: true
6058
6246
  });
6059
6247
  } catch (error) {
@@ -6107,6 +6295,8 @@ async function run(options) {
6107
6295
  return npmPublishTasks;
6108
6296
  case "jsr":
6109
6297
  return jsrPublishTasks;
6298
+ case "crates":
6299
+ return cratesPublishTasks;
6110
6300
  default:
6111
6301
  return npmPublishTasks;
6112
6302
  }
@@ -6172,11 +6362,719 @@ ${repositoryUrl}/compare/${lastRev}...${latestTag}`;
6172
6362
  }
6173
6363
  }
6174
6364
 
6365
+ // src/changeset/bump-utils.ts
6366
+ var BUMP_ORDER = {
6367
+ patch: 0,
6368
+ minor: 1,
6369
+ major: 2
6370
+ };
6371
+ function maxBump(a2, b) {
6372
+ return BUMP_ORDER[a2] >= BUMP_ORDER[b] ? a2 : b;
6373
+ }
6374
+
6375
+ // src/changeset/changelog.ts
6376
+ var SECTION_ORDER = [
6377
+ { type: "major", heading: "Major Changes" },
6378
+ { type: "minor", heading: "Minor Changes" },
6379
+ { type: "patch", heading: "Patch Changes" }
6380
+ ];
6381
+ function generateChangelog(version2, entries, depUpdates) {
6382
+ const lines = [`## ${version2}`];
6383
+ for (const section of SECTION_ORDER) {
6384
+ const sectionEntries = entries.filter((e2) => e2.type === section.type);
6385
+ if (sectionEntries.length === 0) continue;
6386
+ lines.push("");
6387
+ lines.push(`### ${section.heading}`);
6388
+ lines.push("");
6389
+ for (const entry of sectionEntries) {
6390
+ lines.push(`- ${entry.summary}`);
6391
+ }
6392
+ }
6393
+ if (depUpdates && depUpdates.length > 0) {
6394
+ lines.push("");
6395
+ lines.push("### Dependency Updates");
6396
+ lines.push("");
6397
+ for (const dep of depUpdates) {
6398
+ lines.push(`- Updated \`${dep.name}\` to ${dep.version}`);
6399
+ }
6400
+ }
6401
+ return `${lines.join("\n")}
6402
+ `;
6403
+ }
6404
+
6405
+ // src/changeset/migrate.ts
6406
+ import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readdirSync } from "node:fs";
6407
+ import path4 from "node:path";
6408
+ import process11 from "node:process";
6409
+ var SKIPPED_FILES = /* @__PURE__ */ new Set(["config.json", "README.md"]);
6410
+ function migrateFromChangesets(cwd = process11.cwd()) {
6411
+ const changesetDir = path4.join(cwd, ".changeset");
6412
+ if (!existsSync(changesetDir)) {
6413
+ return {
6414
+ success: false,
6415
+ error: ".changeset/ directory not found",
6416
+ migratedFiles: [],
6417
+ configMigrated: false
6418
+ };
6419
+ }
6420
+ const pubmDir = path4.join(cwd, ".pubm", "changesets");
6421
+ mkdirSync2(pubmDir, { recursive: true });
6422
+ const files = readdirSync(changesetDir);
6423
+ const migratedFiles = [];
6424
+ let configMigrated = false;
6425
+ for (const file of files) {
6426
+ if (file === "config.json") {
6427
+ configMigrated = true;
6428
+ continue;
6429
+ }
6430
+ if (SKIPPED_FILES.has(file)) {
6431
+ continue;
6432
+ }
6433
+ if (file === "pre.json") {
6434
+ copyFileSync(
6435
+ path4.join(changesetDir, file),
6436
+ path4.resolve(cwd, ".pubm", "pre.json")
6437
+ );
6438
+ migratedFiles.push(file);
6439
+ continue;
6440
+ }
6441
+ if (file.endsWith(".md")) {
6442
+ const src = path4.join(changesetDir, file);
6443
+ const dest = path4.join(pubmDir, file);
6444
+ copyFileSync(src, dest);
6445
+ migratedFiles.push(file);
6446
+ }
6447
+ }
6448
+ return {
6449
+ success: true,
6450
+ migratedFiles,
6451
+ configMigrated
6452
+ };
6453
+ }
6454
+
6455
+ // src/changeset/parser.ts
6456
+ import { parse as parseYaml } from "yaml";
6457
+ var VALID_BUMP_TYPES = /* @__PURE__ */ new Set(["patch", "minor", "major"]);
6458
+ function parseChangeset(content, fileName) {
6459
+ const frontmatterRegex = /^---\n([\s\S]*?)---/;
6460
+ const match = content.match(frontmatterRegex);
6461
+ if (!match) {
6462
+ throw new Error(
6463
+ `Invalid changeset format in "${fileName}": missing frontmatter`
6464
+ );
6465
+ }
6466
+ const yamlContent = match[1];
6467
+ const body = content.slice(match[0].length).trim();
6468
+ const parsed = parseYaml(yamlContent);
6469
+ const releases = [];
6470
+ if (parsed) {
6471
+ for (const [name, type] of Object.entries(parsed)) {
6472
+ if (!VALID_BUMP_TYPES.has(type)) {
6473
+ throw new Error(
6474
+ `Invalid bump type "${type}" for package "${name}" in "${fileName}". Expected: patch, minor, or major.`
6475
+ );
6476
+ }
6477
+ releases.push({ name, type });
6478
+ }
6479
+ }
6480
+ const id = fileName.replace(/\.md$/, "");
6481
+ return {
6482
+ id,
6483
+ summary: body,
6484
+ releases
6485
+ };
6486
+ }
6487
+
6488
+ // src/changeset/reader.ts
6489
+ import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
6490
+ import path5 from "node:path";
6491
+ import process12 from "node:process";
6492
+ function readChangesets(cwd = process12.cwd()) {
6493
+ const changesetsDir = path5.join(cwd, ".pubm", "changesets");
6494
+ if (!existsSync2(changesetsDir)) {
6495
+ return [];
6496
+ }
6497
+ const files = readdirSync2(changesetsDir);
6498
+ const changesets = [];
6499
+ for (const file of files) {
6500
+ if (!file.endsWith(".md") || file === "README.md") {
6501
+ continue;
6502
+ }
6503
+ const filePath = path5.join(changesetsDir, file);
6504
+ const content = readFileSync2(filePath, "utf-8");
6505
+ changesets.push(parseChangeset(content, file));
6506
+ }
6507
+ return changesets;
6508
+ }
6509
+
6510
+ // src/changeset/status.ts
6511
+ import process13 from "node:process";
6512
+ function getStatus(cwd = process13.cwd()) {
6513
+ const changesets = readChangesets(cwd);
6514
+ const packages = /* @__PURE__ */ new Map();
6515
+ for (const changeset of changesets) {
6516
+ for (const release of changeset.releases) {
6517
+ const existing = packages.get(release.name);
6518
+ if (existing) {
6519
+ existing.bumpType = maxBump(existing.bumpType, release.type);
6520
+ existing.changesetCount += 1;
6521
+ existing.summaries.push(changeset.summary);
6522
+ } else {
6523
+ packages.set(release.name, {
6524
+ bumpType: release.type,
6525
+ changesetCount: 1,
6526
+ summaries: [changeset.summary]
6527
+ });
6528
+ }
6529
+ }
6530
+ }
6531
+ return {
6532
+ packages,
6533
+ changesets,
6534
+ hasChangesets: changesets.length > 0
6535
+ };
6536
+ }
6537
+
6538
+ // src/changeset/version.ts
6539
+ import process14 from "node:process";
6540
+ import { inc } from "semver";
6541
+ function calculateVersionBumps(currentVersions, cwd = process14.cwd()) {
6542
+ const changesets = readChangesets(cwd);
6543
+ const bumpTypes = /* @__PURE__ */ new Map();
6544
+ for (const changeset of changesets) {
6545
+ for (const release of changeset.releases) {
6546
+ if (!currentVersions.has(release.name)) continue;
6547
+ const existing = bumpTypes.get(release.name);
6548
+ if (existing) {
6549
+ bumpTypes.set(release.name, maxBump(existing, release.type));
6550
+ } else {
6551
+ bumpTypes.set(release.name, release.type);
6552
+ }
6553
+ }
6554
+ }
6555
+ const result = /* @__PURE__ */ new Map();
6556
+ for (const [name, bumpType] of bumpTypes) {
6557
+ const currentVersion = currentVersions.get(name);
6558
+ if (!currentVersion) continue;
6559
+ const newVersion = inc(currentVersion, bumpType);
6560
+ if (newVersion) {
6561
+ result.set(name, {
6562
+ currentVersion,
6563
+ newVersion,
6564
+ bumpType
6565
+ });
6566
+ }
6567
+ }
6568
+ return result;
6569
+ }
6570
+
6571
+ // src/changeset/writer.ts
6572
+ import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync2 } from "node:fs";
6573
+ import path6 from "node:path";
6574
+ import process15 from "node:process";
6575
+ import { stringify as stringifyYaml } from "yaml";
6576
+ var adjectives = [
6577
+ "brave",
6578
+ "calm",
6579
+ "dark",
6580
+ "eager",
6581
+ "fair",
6582
+ "glad",
6583
+ "happy",
6584
+ "idle",
6585
+ "jolly",
6586
+ "keen",
6587
+ "lame",
6588
+ "mild",
6589
+ "neat",
6590
+ "odd",
6591
+ "pale",
6592
+ "quick",
6593
+ "rare",
6594
+ "safe",
6595
+ "tall",
6596
+ "ugly",
6597
+ "vast",
6598
+ "warm",
6599
+ "young",
6600
+ "zany",
6601
+ "bold",
6602
+ "cool",
6603
+ "dry",
6604
+ "fast",
6605
+ "good",
6606
+ "hot",
6607
+ "icy",
6608
+ "loud"
6609
+ ];
6610
+ var nouns = [
6611
+ "ant",
6612
+ "bear",
6613
+ "cat",
6614
+ "dog",
6615
+ "elk",
6616
+ "fox",
6617
+ "goat",
6618
+ "hawk",
6619
+ "ibis",
6620
+ "jay",
6621
+ "kite",
6622
+ "lion",
6623
+ "mole",
6624
+ "newt",
6625
+ "owl",
6626
+ "puma",
6627
+ "quail",
6628
+ "ram",
6629
+ "seal",
6630
+ "toad",
6631
+ "urchin",
6632
+ "vole",
6633
+ "wolf",
6634
+ "yak",
6635
+ "zebra",
6636
+ "ape",
6637
+ "bat",
6638
+ "cow",
6639
+ "deer",
6640
+ "emu",
6641
+ "frog",
6642
+ "gull"
6643
+ ];
6644
+ function generateChangesetId() {
6645
+ const adjective = adjectives[Math.floor(Math.random() * adjectives.length)];
6646
+ const noun = nouns[Math.floor(Math.random() * nouns.length)];
6647
+ const suffix = Math.random().toString(36).slice(2, 6);
6648
+ return `${adjective}-${noun}-${suffix}`;
6649
+ }
6650
+ function generateChangesetContent(releases, summary) {
6651
+ let content = "---\n";
6652
+ if (releases.length > 0) {
6653
+ const yamlObj = {};
6654
+ for (const release of releases) {
6655
+ yamlObj[release.name] = release.type;
6656
+ }
6657
+ content += stringifyYaml(yamlObj);
6658
+ }
6659
+ content += "---\n";
6660
+ if (summary) {
6661
+ content += `
6662
+ ${summary}
6663
+ `;
6664
+ }
6665
+ return content;
6666
+ }
6667
+ function writeChangeset(releases, summary, cwd = process15.cwd()) {
6668
+ const changesetsDir = path6.join(cwd, ".pubm", "changesets");
6669
+ mkdirSync3(changesetsDir, { recursive: true });
6670
+ const id = generateChangesetId();
6671
+ const fileName = `${id}.md`;
6672
+ const filePath = path6.join(changesetsDir, fileName);
6673
+ const content = generateChangesetContent(releases, summary);
6674
+ writeFileSync2(filePath, content, "utf-8");
6675
+ return filePath;
6676
+ }
6677
+
6678
+ // src/config/defaults.ts
6679
+ var defaultValidate = {
6680
+ cleanInstall: true,
6681
+ entryPoints: true,
6682
+ extraneousFiles: true
6683
+ };
6684
+ var defaultSnapshot = {
6685
+ useCalculatedVersion: false,
6686
+ prereleaseTemplate: "{tag}-{timestamp}"
6687
+ };
6688
+ var defaultConfig = {
6689
+ versioning: "independent",
6690
+ branch: "main",
6691
+ changelog: true,
6692
+ changelogFormat: "default",
6693
+ commit: false,
6694
+ access: "public",
6695
+ fixed: [],
6696
+ linked: [],
6697
+ updateInternalDependencies: "patch",
6698
+ ignore: [],
6699
+ tag: "latest",
6700
+ contents: ".",
6701
+ saveToken: true,
6702
+ releaseDraft: true,
6703
+ releaseNotes: true,
6704
+ registries: ["npm", "jsr"],
6705
+ rollbackStrategy: "individual"
6706
+ };
6707
+ function resolveConfig(config) {
6708
+ const packages = config.packages ?? [
6709
+ { path: ".", registries: ["npm", "jsr"] }
6710
+ ];
6711
+ return {
6712
+ ...defaultConfig,
6713
+ ...config,
6714
+ packages,
6715
+ validate: { ...defaultValidate, ...config.validate },
6716
+ snapshot: { ...defaultSnapshot, ...config.snapshot }
6717
+ };
6718
+ }
6719
+
6720
+ // src/config/loader.ts
6721
+ import { stat as stat3 } from "node:fs/promises";
6722
+ import path7 from "node:path";
6723
+ var CONFIG_FILES = [
6724
+ "pubm.config.ts",
6725
+ "pubm.config.mts",
6726
+ "pubm.config.cts",
6727
+ "pubm.config.js",
6728
+ "pubm.config.mjs",
6729
+ "pubm.config.cjs"
6730
+ ];
6731
+ async function findConfigFile(cwd) {
6732
+ for (const file of CONFIG_FILES) {
6733
+ const filePath = path7.join(cwd, file);
6734
+ try {
6735
+ if ((await stat3(filePath)).isFile()) {
6736
+ return filePath;
6737
+ }
6738
+ } catch {
6739
+ }
6740
+ }
6741
+ return null;
6742
+ }
6743
+ async function loadConfig(cwd = process.cwd()) {
6744
+ const configPath = await findConfigFile(cwd);
6745
+ if (!configPath) return null;
6746
+ const { createJiti } = await import("jiti");
6747
+ const jiti = createJiti(cwd, { interopDefault: true });
6748
+ const mod = await jiti.import(configPath);
6749
+ return mod.default ?? mod;
6750
+ }
6751
+
6752
+ // src/config/types.ts
6753
+ function defineConfig(config) {
6754
+ return config;
6755
+ }
6756
+
6757
+ // src/monorepo/dependency-graph.ts
6758
+ function buildDependencyGraph(packages) {
6759
+ const packageNames = new Set(packages.map((pkg) => pkg.name));
6760
+ const graph = /* @__PURE__ */ new Map();
6761
+ for (const pkg of packages) {
6762
+ const internalDeps = Object.keys(pkg.dependencies).filter(
6763
+ (dep) => packageNames.has(dep)
6764
+ );
6765
+ graph.set(pkg.name, internalDeps);
6766
+ }
6767
+ return graph;
6768
+ }
6769
+ function topologicalSort(graph) {
6770
+ const inDegree = /* @__PURE__ */ new Map();
6771
+ for (const name of graph.keys()) {
6772
+ inDegree.set(name, 0);
6773
+ }
6774
+ for (const [, deps] of graph) {
6775
+ for (const dep of deps) {
6776
+ inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
6777
+ }
6778
+ }
6779
+ const queue = [];
6780
+ for (const [name, degree] of inDegree) {
6781
+ if (degree === 0) {
6782
+ queue.push(name);
6783
+ }
6784
+ }
6785
+ const sorted = [];
6786
+ while (queue.length > 0) {
6787
+ const node = queue.shift();
6788
+ sorted.push(node);
6789
+ for (const dep of graph.get(node) ?? []) {
6790
+ const newDegree = (inDegree.get(dep) ?? 0) - 1;
6791
+ inDegree.set(dep, newDegree);
6792
+ if (newDegree === 0) {
6793
+ queue.push(dep);
6794
+ }
6795
+ }
6796
+ }
6797
+ if (sorted.length !== graph.size) {
6798
+ throw new Error("Circular dependency detected");
6799
+ }
6800
+ return sorted.reverse();
6801
+ }
6802
+
6803
+ // src/monorepo/groups.ts
6804
+ import micromatch from "micromatch";
6805
+ function resolveGroups(groups, allPackages) {
6806
+ return groups.map((group) => {
6807
+ const resolved = /* @__PURE__ */ new Set();
6808
+ for (const pattern of group) {
6809
+ const matches = micromatch(allPackages, pattern);
6810
+ for (const match of matches) {
6811
+ resolved.add(match);
6812
+ }
6813
+ }
6814
+ return [...resolved];
6815
+ });
6816
+ }
6817
+ function applyFixedGroup(bumps, group) {
6818
+ let max = null;
6819
+ for (const pkg of group) {
6820
+ const bump = bumps.get(pkg);
6821
+ if (bump) {
6822
+ max = max ? maxBump(max, bump) : bump;
6823
+ }
6824
+ }
6825
+ if (!max) return;
6826
+ for (const pkg of group) {
6827
+ bumps.set(pkg, max);
6828
+ }
6829
+ }
6830
+ function applyLinkedGroup(bumps, group) {
6831
+ let max = null;
6832
+ for (const pkg of group) {
6833
+ const bump = bumps.get(pkg);
6834
+ if (bump) {
6835
+ max = max ? maxBump(max, bump) : bump;
6836
+ }
6837
+ }
6838
+ if (!max) return;
6839
+ for (const pkg of group) {
6840
+ if (bumps.has(pkg)) {
6841
+ bumps.set(pkg, max);
6842
+ }
6843
+ }
6844
+ }
6845
+
6846
+ // src/monorepo/workspace.ts
6847
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
6848
+ import { join } from "node:path";
6849
+ import { parse as parse2 } from "yaml";
6850
+ function detectWorkspace(cwd) {
6851
+ const root = cwd ?? process.cwd();
6852
+ const pnpmWorkspacePath = join(root, "pnpm-workspace.yaml");
6853
+ if (existsSync3(pnpmWorkspacePath)) {
6854
+ const content = readFileSync3(pnpmWorkspacePath, "utf-8");
6855
+ const parsed = parse2(content);
6856
+ const packages = parsed?.packages ?? [];
6857
+ return { type: "pnpm", patterns: packages };
6858
+ }
6859
+ const packageJsonPath = join(root, "package.json");
6860
+ if (existsSync3(packageJsonPath)) {
6861
+ const content = readFileSync3(packageJsonPath, "utf-8");
6862
+ const pkg = JSON.parse(content);
6863
+ if (pkg.workspaces) {
6864
+ if (Array.isArray(pkg.workspaces)) {
6865
+ return { type: "npm", patterns: pkg.workspaces };
6866
+ }
6867
+ if (typeof pkg.workspaces === "object" && Array.isArray(pkg.workspaces.packages)) {
6868
+ return { type: "yarn", patterns: pkg.workspaces.packages };
6869
+ }
6870
+ }
6871
+ }
6872
+ return null;
6873
+ }
6874
+
6875
+ // src/prerelease/pre.ts
6876
+ import {
6877
+ existsSync as existsSync4,
6878
+ mkdirSync as mkdirSync4,
6879
+ readFileSync as readFileSync4,
6880
+ rmSync,
6881
+ writeFileSync as writeFileSync3
6882
+ } from "node:fs";
6883
+ import path8 from "node:path";
6884
+ function getPreStatePath(cwd) {
6885
+ return path8.resolve(cwd ?? process.cwd(), ".pubm", "pre.json");
6886
+ }
6887
+ function readPreState(cwd) {
6888
+ const filePath = getPreStatePath(cwd);
6889
+ if (!existsSync4(filePath)) {
6890
+ return null;
6891
+ }
6892
+ const content = readFileSync4(filePath, "utf-8");
6893
+ return JSON.parse(content);
6894
+ }
6895
+ function enterPreMode(tag, cwd) {
6896
+ const filePath = getPreStatePath(cwd);
6897
+ if (existsSync4(filePath)) {
6898
+ throw new Error(
6899
+ "Already in pre mode. Exit pre mode first before entering a new one."
6900
+ );
6901
+ }
6902
+ const dir = path8.dirname(filePath);
6903
+ if (!existsSync4(dir)) {
6904
+ mkdirSync4(dir, { recursive: true });
6905
+ }
6906
+ const state = {
6907
+ mode: "pre",
6908
+ tag,
6909
+ packages: {}
6910
+ };
6911
+ writeFileSync3(filePath, JSON.stringify(state, null, 2), "utf-8");
6912
+ }
6913
+ function exitPreMode(cwd) {
6914
+ const filePath = getPreStatePath(cwd);
6915
+ if (!existsSync4(filePath)) {
6916
+ throw new Error("Not in pre mode. Enter pre mode first before exiting.");
6917
+ }
6918
+ rmSync(filePath);
6919
+ }
6920
+
6921
+ // src/prerelease/snapshot.ts
6922
+ function formatTimestamp(date) {
6923
+ const year = date.getUTCFullYear();
6924
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
6925
+ const day = String(date.getUTCDate()).padStart(2, "0");
6926
+ const hours = String(date.getUTCHours()).padStart(2, "0");
6927
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
6928
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
6929
+ return `${year}${month}${day}T${hours}${minutes}${seconds}`;
6930
+ }
6931
+ function generateSnapshotVersion(options) {
6932
+ const tag = options.tag ?? "snapshot";
6933
+ const base = options.useCalculatedVersion && options.baseVersion ? options.baseVersion : "0.0.0";
6934
+ const now = /* @__PURE__ */ new Date();
6935
+ const timestamp = formatTimestamp(now);
6936
+ if (options.template) {
6937
+ return options.template.replace(/\{base\}/g, base).replace(/\{tag\}/g, tag).replace(/\{timestamp\}/g, timestamp).replace(/\{commit\}/g, options.commit ?? "").replace(/\{datetime\}/g, timestamp);
6938
+ }
6939
+ return `${base}-${tag}-${timestamp}`;
6940
+ }
6941
+
6942
+ // src/validate/entry-points.ts
6943
+ import { existsSync as existsSync5 } from "node:fs";
6944
+ import path9 from "node:path";
6945
+ var SIMPLE_FIELDS = ["main", "module", "types", "typings"];
6946
+ function checkPath(filePath, cwd) {
6947
+ return existsSync5(path9.resolve(cwd, filePath));
6948
+ }
6949
+ function validateExports(exports, cwd, prefix = "exports") {
6950
+ const errors = [];
6951
+ if (typeof exports === "string") {
6952
+ if (!checkPath(exports, cwd)) {
6953
+ errors.push({ field: prefix, path: exports });
6954
+ }
6955
+ return errors;
6956
+ }
6957
+ if (typeof exports === "object" && exports !== null) {
6958
+ for (const [key, value] of Object.entries(exports)) {
6959
+ if (typeof value === "string") {
6960
+ if (!checkPath(value, cwd)) {
6961
+ errors.push({ field: `${prefix}["${key}"]`, path: value });
6962
+ }
6963
+ } else if (typeof value === "object" && value !== null) {
6964
+ errors.push(...validateExports(value, cwd, `${prefix}["${key}"]`));
6965
+ }
6966
+ }
6967
+ }
6968
+ return errors;
6969
+ }
6970
+ function validateEntryPoints(pkg, cwd) {
6971
+ const errors = [];
6972
+ for (const field of SIMPLE_FIELDS) {
6973
+ const value = pkg[field];
6974
+ if (typeof value === "string" && !checkPath(value, cwd)) {
6975
+ errors.push({ field, path: value });
6976
+ }
6977
+ }
6978
+ if (pkg.exports !== void 0) {
6979
+ errors.push(...validateExports(pkg.exports, cwd));
6980
+ }
6981
+ if (pkg.bin !== void 0) {
6982
+ if (typeof pkg.bin === "string") {
6983
+ if (!checkPath(pkg.bin, cwd)) {
6984
+ errors.push({ field: "bin", path: pkg.bin });
6985
+ }
6986
+ } else if (typeof pkg.bin === "object" && pkg.bin !== null) {
6987
+ for (const [name, binPath] of Object.entries(
6988
+ pkg.bin
6989
+ )) {
6990
+ if (!checkPath(binPath, cwd)) {
6991
+ errors.push({ field: `bin.${name}`, path: binPath });
6992
+ }
6993
+ }
6994
+ }
6995
+ }
6996
+ return errors;
6997
+ }
6998
+
6999
+ // src/validate/extraneous-files.ts
7000
+ import micromatch2 from "micromatch";
7001
+ var PATTERNS = [
7002
+ {
7003
+ pattern: [".env", ".env.*"],
7004
+ reason: "potentially contains secrets",
7005
+ basename: true
7006
+ },
7007
+ {
7008
+ pattern: ["*.test.*", "*.spec.*"],
7009
+ reason: "test file",
7010
+ basename: true
7011
+ },
7012
+ {
7013
+ pattern: ["**/__tests__/**"],
7014
+ reason: "test file"
7015
+ },
7016
+ { pattern: ["*.map"], reason: "source map", basename: true },
7017
+ {
7018
+ pattern: [
7019
+ ".eslintrc*",
7020
+ ".prettierrc*",
7021
+ "tsconfig.json",
7022
+ "tsconfig.*.json",
7023
+ ".babelrc*",
7024
+ "jest.config.*",
7025
+ "vitest.config.*",
7026
+ ".editorconfig",
7027
+ "biome.json"
7028
+ ],
7029
+ reason: "development config file",
7030
+ basename: true
7031
+ }
7032
+ ];
7033
+ function detectExtraneousFiles(files) {
7034
+ const result = [];
7035
+ const seen = /* @__PURE__ */ new Set();
7036
+ for (const { pattern, reason, basename } of PATTERNS) {
7037
+ const options = basename ? { basename: true } : {};
7038
+ const matched = micromatch2(files, pattern, options);
7039
+ for (const file of matched) {
7040
+ if (!seen.has(file)) {
7041
+ seen.add(file);
7042
+ result.push({ file, reason });
7043
+ }
7044
+ }
7045
+ }
7046
+ return result;
7047
+ }
7048
+
6175
7049
  // src/index.ts
6176
7050
  async function pubm(options) {
6177
7051
  const resolvedOptions = resolveOptions({ ...options });
6178
7052
  await run(resolvedOptions);
6179
7053
  }
6180
7054
  export {
6181
- pubm
7055
+ applyFixedGroup,
7056
+ applyLinkedGroup,
7057
+ buildDependencyGraph,
7058
+ calculateVersionBumps,
7059
+ defineConfig,
7060
+ detectExtraneousFiles,
7061
+ detectWorkspace,
7062
+ enterPreMode,
7063
+ exitPreMode,
7064
+ generateChangelog,
7065
+ generateChangesetContent,
7066
+ generateChangesetId,
7067
+ generateSnapshotVersion,
7068
+ getStatus,
7069
+ loadConfig,
7070
+ migrateFromChangesets,
7071
+ parseChangeset,
7072
+ pubm,
7073
+ readChangesets,
7074
+ readPreState,
7075
+ resolveConfig,
7076
+ resolveGroups,
7077
+ topologicalSort,
7078
+ validateEntryPoints,
7079
+ writeChangeset
6182
7080
  };