pubm 0.0.5 → 0.1.3

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 { exec as exec4, NonZeroExitError } 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
  }
@@ -5138,6 +5333,11 @@ var _JsrClient = class _JsrClient {
5138
5333
  try {
5139
5334
  const response = await this.fetch("/user");
5140
5335
  if (response.status === 401) return null;
5336
+ if (!response.ok) {
5337
+ throw new Error(
5338
+ `HTTP ${response.status}: ${response.statusText}`
5339
+ );
5340
+ }
5141
5341
  return await response.json();
5142
5342
  } catch (error) {
5143
5343
  throw new JsrError(`Failed to fetch \`${this.apiEndpoint}/user\``, {
@@ -5149,6 +5349,11 @@ var _JsrClient = class _JsrClient {
5149
5349
  try {
5150
5350
  const response = await this.fetch(`/user/member/${scope}`);
5151
5351
  if (response.status === 401) return null;
5352
+ if (!response.ok) {
5353
+ throw new Error(
5354
+ `HTTP ${response.status}: ${response.statusText}`
5355
+ );
5356
+ }
5152
5357
  return await response.json();
5153
5358
  } catch (error) {
5154
5359
  throw new JsrError(
@@ -5163,9 +5368,18 @@ var _JsrClient = class _JsrClient {
5163
5368
  try {
5164
5369
  const response = await this.fetch("/user/scopes");
5165
5370
  if (response.status === 401) return [];
5166
- return (await response.json()).map(
5167
- ({ scope }) => scope
5168
- );
5371
+ if (!response.ok) {
5372
+ throw new Error(
5373
+ `HTTP ${response.status}: ${response.statusText}`
5374
+ );
5375
+ }
5376
+ const body = await response.json();
5377
+ if (!Array.isArray(body)) {
5378
+ throw new Error(
5379
+ `Expected array response but got ${typeof body}`
5380
+ );
5381
+ }
5382
+ return body.map(({ scope }) => scope);
5169
5383
  } catch (error) {
5170
5384
  throw new JsrError(
5171
5385
  `Failed to fetch \`${this.apiEndpoint}/user/scopes\``,
@@ -5179,10 +5393,11 @@ var _JsrClient = class _JsrClient {
5179
5393
  const [scope, name] = getScopeAndName(packageName);
5180
5394
  try {
5181
5395
  const response = await this.fetch(`/scopes/${scope}/packages/${name}`);
5396
+ if (!response.ok) return null;
5182
5397
  return await response.json();
5183
5398
  } catch (error) {
5184
5399
  throw new JsrError(
5185
- `Failed to fetch \`${this.apiEndpoint}/user/scopes\``,
5400
+ `Failed to fetch \`${this.apiEndpoint}/scopes/${scope}/packages/${name}\``,
5186
5401
  {
5187
5402
  cause: error
5188
5403
  }
@@ -5253,6 +5468,11 @@ var _JsrClient = class _JsrClient {
5253
5468
  async searchPackage(query) {
5254
5469
  try {
5255
5470
  const response = await this.fetch(`/packages?query=${query}`);
5471
+ if (!response.ok) {
5472
+ throw new Error(
5473
+ `HTTP ${response.status}: ${response.statusText}`
5474
+ );
5475
+ }
5256
5476
  return await response.json();
5257
5477
  } catch (error) {
5258
5478
  throw new JsrError(
@@ -5272,7 +5492,7 @@ async function jsrRegistry() {
5272
5492
  }
5273
5493
 
5274
5494
  // src/registry/npm.ts
5275
- import { exec as exec4 } from "tinyexec";
5495
+ import { exec as exec5, NonZeroExitError as NonZeroExitError2 } from "tinyexec";
5276
5496
  var NpmError = class extends AbstractError {
5277
5497
  constructor() {
5278
5498
  super(...arguments);
@@ -5285,13 +5505,12 @@ var NpmRegistry = class extends Registry {
5285
5505
  __publicField(this, "registry", "https://registry.npmjs.org");
5286
5506
  }
5287
5507
  async npm(args) {
5288
- const { stdout, stderr } = await exec4("npm", args);
5289
- if (stderr) throw stderr;
5508
+ const { stdout } = await exec5("npm", args, { throwOnError: true });
5290
5509
  return stdout;
5291
5510
  }
5292
5511
  async isInstalled() {
5293
5512
  try {
5294
- await this.npm(["--help"]);
5513
+ await this.npm(["--version"]);
5295
5514
  return true;
5296
5515
  } catch {
5297
5516
  return false;
@@ -5330,7 +5549,7 @@ var NpmRegistry = class extends Registry {
5330
5549
  await this.npm(["whoami"]);
5331
5550
  return true;
5332
5551
  } catch (error) {
5333
- if (`${error}`.includes("ENEEDAUTH")) {
5552
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("ENEEDAUTH")) {
5334
5553
  return false;
5335
5554
  }
5336
5555
  throw new NpmError("Failed to run `npm whoami`", { cause: error });
@@ -5382,7 +5601,7 @@ var NpmRegistry = class extends Registry {
5382
5601
  }
5383
5602
  async ping() {
5384
5603
  try {
5385
- await exec4("npm", ["ping"], { throwOnError: true });
5604
+ await exec5("npm", ["ping"], { throwOnError: true });
5386
5605
  return true;
5387
5606
  } catch (error) {
5388
5607
  throw new NpmError("Failed to run `npm ping`", { cause: error });
@@ -5390,15 +5609,12 @@ var NpmRegistry = class extends Registry {
5390
5609
  }
5391
5610
  async publishProvenance() {
5392
5611
  try {
5393
- try {
5394
- await this.npm(["publish", "--provenance", "--access", "public"]);
5395
- } catch (error) {
5396
- if (`${error}`.includes("EOTP")) {
5397
- return false;
5398
- }
5399
- }
5612
+ await this.npm(["publish", "--provenance", "--access", "public"]);
5400
5613
  return true;
5401
5614
  } catch (error) {
5615
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("EOTP")) {
5616
+ return false;
5617
+ }
5402
5618
  throw new NpmError(
5403
5619
  "Failed to run `npm publish --provenance --access public`",
5404
5620
  {
@@ -5410,15 +5626,12 @@ var NpmRegistry = class extends Registry {
5410
5626
  async publish(otp) {
5411
5627
  const args = otp ? ["publish", "--otp", otp] : ["publish"];
5412
5628
  try {
5413
- try {
5414
- await this.npm(args);
5415
- } catch (error) {
5416
- if (`${error}`.includes("EOTP")) {
5417
- return false;
5418
- }
5419
- }
5629
+ await this.npm(args);
5420
5630
  return true;
5421
5631
  } catch (error) {
5632
+ if (error instanceof NonZeroExitError2 && error.output?.stderr.includes("EOTP")) {
5633
+ return false;
5634
+ }
5422
5635
  throw new NpmError(`Failed to run \`npm ${args.join(" ")}\``, {
5423
5636
  cause: error
5424
5637
  });
@@ -5491,7 +5704,7 @@ Generate a token from ${color.bold(link2("jsr.io", "https://jsr.io/account/token
5491
5704
  scopes.map(
5492
5705
  (scope2) => jsr.client.package(`@${scope2}/${jsr.packageName}`)
5493
5706
  )
5494
- )).filter((v) => v);
5707
+ )).filter((v) => v !== null);
5495
5708
  if (searchResults.length > 0) {
5496
5709
  jsrName = await task.prompt(ListrEnquirerPromptAdapter).run({
5497
5710
  type: "select",
@@ -5826,14 +6039,14 @@ var prerequisitesCheckTask = (options) => {
5826
6039
  import { ListrEnquirerPromptAdapter as ListrEnquirerPromptAdapter4 } from "@listr2/prompt-adapter-enquirer";
5827
6040
 
5828
6041
  // src/registry/custom-registry.ts
5829
- import { exec as exec5 } from "tinyexec";
6042
+ import { exec as exec6 } from "tinyexec";
5830
6043
  var CustomRegistry = class extends NpmRegistry {
5831
6044
  async npm(args) {
5832
- const { stdout, stderr } = await exec5(
6045
+ const { stdout } = await exec6(
5833
6046
  "npm",
5834
- args.concat("--registry", this.registry)
6047
+ args.concat("--registry", this.registry),
6048
+ { throwOnError: true }
5835
6049
  );
5836
- if (stderr) throw stderr;
5837
6050
  return stdout;
5838
6051
  }
5839
6052
  };
@@ -5847,7 +6060,10 @@ var registryMap = {
5847
6060
  npm: npmRegistry,
5848
6061
  jsr: jsrRegistry
5849
6062
  };
5850
- async function getRegistry(registryKey) {
6063
+ async function getRegistry(registryKey, packageName) {
6064
+ if (registryKey === "crates") {
6065
+ return await cratesRegistry(packageName ?? "unknown");
6066
+ }
5851
6067
  const registry = registryMap[registryKey];
5852
6068
  if (!registry) {
5853
6069
  return await customRegistry();
@@ -5977,6 +6193,8 @@ var requiredConditionsCheckTask = (options) => createListr({
5977
6193
  return npmAvailableCheckTasks;
5978
6194
  case "jsr":
5979
6195
  return jsrAvailableCheckTasks;
6196
+ case "crates":
6197
+ return cratesAvailableCheckTasks;
5980
6198
  default:
5981
6199
  return npmAvailableCheckTasks;
5982
6200
  }
@@ -6023,6 +6241,8 @@ async function run(options) {
6023
6241
  return npmPublishTasks;
6024
6242
  case "jsr":
6025
6243
  return jsrPublishTasks;
6244
+ case "crates":
6245
+ return cratesPublishTasks;
6026
6246
  default:
6027
6247
  return npmPublishTasks;
6028
6248
  }
@@ -6035,16 +6255,9 @@ async function run(options) {
6035
6255
  title: "Running tests",
6036
6256
  task: async (ctx2) => {
6037
6257
  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
- }
6258
+ await exec7(packageManager, ["run", ctx2.testScript], {
6259
+ throwOnError: true
6260
+ });
6048
6261
  }
6049
6262
  },
6050
6263
  {
@@ -6053,7 +6266,7 @@ async function run(options) {
6053
6266
  task: async (ctx2) => {
6054
6267
  const packageManager = await getPackageManager();
6055
6268
  try {
6056
- await exec6(packageManager, ["run", ctx2.buildScript], {
6269
+ await exec7(packageManager, ["run", ctx2.buildScript], {
6057
6270
  throwOnError: true
6058
6271
  });
6059
6272
  } catch (error) {
@@ -6107,6 +6320,8 @@ async function run(options) {
6107
6320
  return npmPublishTasks;
6108
6321
  case "jsr":
6109
6322
  return jsrPublishTasks;
6323
+ case "crates":
6324
+ return cratesPublishTasks;
6110
6325
  default:
6111
6326
  return npmPublishTasks;
6112
6327
  }
@@ -6172,11 +6387,719 @@ ${repositoryUrl}/compare/${lastRev}...${latestTag}`;
6172
6387
  }
6173
6388
  }
6174
6389
 
6390
+ // src/changeset/bump-utils.ts
6391
+ var BUMP_ORDER = {
6392
+ patch: 0,
6393
+ minor: 1,
6394
+ major: 2
6395
+ };
6396
+ function maxBump(a2, b) {
6397
+ return BUMP_ORDER[a2] >= BUMP_ORDER[b] ? a2 : b;
6398
+ }
6399
+
6400
+ // src/changeset/changelog.ts
6401
+ var SECTION_ORDER = [
6402
+ { type: "major", heading: "Major Changes" },
6403
+ { type: "minor", heading: "Minor Changes" },
6404
+ { type: "patch", heading: "Patch Changes" }
6405
+ ];
6406
+ function generateChangelog(version2, entries, depUpdates) {
6407
+ const lines = [`## ${version2}`];
6408
+ for (const section of SECTION_ORDER) {
6409
+ const sectionEntries = entries.filter((e2) => e2.type === section.type);
6410
+ if (sectionEntries.length === 0) continue;
6411
+ lines.push("");
6412
+ lines.push(`### ${section.heading}`);
6413
+ lines.push("");
6414
+ for (const entry of sectionEntries) {
6415
+ lines.push(`- ${entry.summary}`);
6416
+ }
6417
+ }
6418
+ if (depUpdates && depUpdates.length > 0) {
6419
+ lines.push("");
6420
+ lines.push("### Dependency Updates");
6421
+ lines.push("");
6422
+ for (const dep of depUpdates) {
6423
+ lines.push(`- Updated \`${dep.name}\` to ${dep.version}`);
6424
+ }
6425
+ }
6426
+ return `${lines.join("\n")}
6427
+ `;
6428
+ }
6429
+
6430
+ // src/changeset/migrate.ts
6431
+ import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readdirSync } from "node:fs";
6432
+ import path4 from "node:path";
6433
+ import process11 from "node:process";
6434
+ var SKIPPED_FILES = /* @__PURE__ */ new Set(["config.json", "README.md"]);
6435
+ function migrateFromChangesets(cwd = process11.cwd()) {
6436
+ const changesetDir = path4.join(cwd, ".changeset");
6437
+ if (!existsSync(changesetDir)) {
6438
+ return {
6439
+ success: false,
6440
+ error: ".changeset/ directory not found",
6441
+ migratedFiles: [],
6442
+ configMigrated: false
6443
+ };
6444
+ }
6445
+ const pubmDir = path4.join(cwd, ".pubm", "changesets");
6446
+ mkdirSync2(pubmDir, { recursive: true });
6447
+ const files = readdirSync(changesetDir);
6448
+ const migratedFiles = [];
6449
+ let configMigrated = false;
6450
+ for (const file of files) {
6451
+ if (file === "config.json") {
6452
+ configMigrated = true;
6453
+ continue;
6454
+ }
6455
+ if (SKIPPED_FILES.has(file)) {
6456
+ continue;
6457
+ }
6458
+ if (file === "pre.json") {
6459
+ copyFileSync(
6460
+ path4.join(changesetDir, file),
6461
+ path4.resolve(cwd, ".pubm", "pre.json")
6462
+ );
6463
+ migratedFiles.push(file);
6464
+ continue;
6465
+ }
6466
+ if (file.endsWith(".md")) {
6467
+ const src = path4.join(changesetDir, file);
6468
+ const dest = path4.join(pubmDir, file);
6469
+ copyFileSync(src, dest);
6470
+ migratedFiles.push(file);
6471
+ }
6472
+ }
6473
+ return {
6474
+ success: true,
6475
+ migratedFiles,
6476
+ configMigrated
6477
+ };
6478
+ }
6479
+
6480
+ // src/changeset/parser.ts
6481
+ import { parse as parseYaml } from "yaml";
6482
+ var VALID_BUMP_TYPES = /* @__PURE__ */ new Set(["patch", "minor", "major"]);
6483
+ function parseChangeset(content, fileName) {
6484
+ const frontmatterRegex = /^---\n([\s\S]*?)---/;
6485
+ const match = content.match(frontmatterRegex);
6486
+ if (!match) {
6487
+ throw new Error(
6488
+ `Invalid changeset format in "${fileName}": missing frontmatter`
6489
+ );
6490
+ }
6491
+ const yamlContent = match[1];
6492
+ const body = content.slice(match[0].length).trim();
6493
+ const parsed = parseYaml(yamlContent);
6494
+ const releases = [];
6495
+ if (parsed) {
6496
+ for (const [name, type] of Object.entries(parsed)) {
6497
+ if (!VALID_BUMP_TYPES.has(type)) {
6498
+ throw new Error(
6499
+ `Invalid bump type "${type}" for package "${name}" in "${fileName}". Expected: patch, minor, or major.`
6500
+ );
6501
+ }
6502
+ releases.push({ name, type });
6503
+ }
6504
+ }
6505
+ const id = fileName.replace(/\.md$/, "");
6506
+ return {
6507
+ id,
6508
+ summary: body,
6509
+ releases
6510
+ };
6511
+ }
6512
+
6513
+ // src/changeset/reader.ts
6514
+ import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
6515
+ import path5 from "node:path";
6516
+ import process12 from "node:process";
6517
+ function readChangesets(cwd = process12.cwd()) {
6518
+ const changesetsDir = path5.join(cwd, ".pubm", "changesets");
6519
+ if (!existsSync2(changesetsDir)) {
6520
+ return [];
6521
+ }
6522
+ const files = readdirSync2(changesetsDir);
6523
+ const changesets = [];
6524
+ for (const file of files) {
6525
+ if (!file.endsWith(".md") || file === "README.md") {
6526
+ continue;
6527
+ }
6528
+ const filePath = path5.join(changesetsDir, file);
6529
+ const content = readFileSync2(filePath, "utf-8");
6530
+ changesets.push(parseChangeset(content, file));
6531
+ }
6532
+ return changesets;
6533
+ }
6534
+
6535
+ // src/changeset/status.ts
6536
+ import process13 from "node:process";
6537
+ function getStatus(cwd = process13.cwd()) {
6538
+ const changesets = readChangesets(cwd);
6539
+ const packages = /* @__PURE__ */ new Map();
6540
+ for (const changeset of changesets) {
6541
+ for (const release of changeset.releases) {
6542
+ const existing = packages.get(release.name);
6543
+ if (existing) {
6544
+ existing.bumpType = maxBump(existing.bumpType, release.type);
6545
+ existing.changesetCount += 1;
6546
+ existing.summaries.push(changeset.summary);
6547
+ } else {
6548
+ packages.set(release.name, {
6549
+ bumpType: release.type,
6550
+ changesetCount: 1,
6551
+ summaries: [changeset.summary]
6552
+ });
6553
+ }
6554
+ }
6555
+ }
6556
+ return {
6557
+ packages,
6558
+ changesets,
6559
+ hasChangesets: changesets.length > 0
6560
+ };
6561
+ }
6562
+
6563
+ // src/changeset/version.ts
6564
+ import process14 from "node:process";
6565
+ import { inc } from "semver";
6566
+ function calculateVersionBumps(currentVersions, cwd = process14.cwd()) {
6567
+ const changesets = readChangesets(cwd);
6568
+ const bumpTypes = /* @__PURE__ */ new Map();
6569
+ for (const changeset of changesets) {
6570
+ for (const release of changeset.releases) {
6571
+ if (!currentVersions.has(release.name)) continue;
6572
+ const existing = bumpTypes.get(release.name);
6573
+ if (existing) {
6574
+ bumpTypes.set(release.name, maxBump(existing, release.type));
6575
+ } else {
6576
+ bumpTypes.set(release.name, release.type);
6577
+ }
6578
+ }
6579
+ }
6580
+ const result = /* @__PURE__ */ new Map();
6581
+ for (const [name, bumpType] of bumpTypes) {
6582
+ const currentVersion = currentVersions.get(name);
6583
+ if (!currentVersion) continue;
6584
+ const newVersion = inc(currentVersion, bumpType);
6585
+ if (newVersion) {
6586
+ result.set(name, {
6587
+ currentVersion,
6588
+ newVersion,
6589
+ bumpType
6590
+ });
6591
+ }
6592
+ }
6593
+ return result;
6594
+ }
6595
+
6596
+ // src/changeset/writer.ts
6597
+ import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync2 } from "node:fs";
6598
+ import path6 from "node:path";
6599
+ import process15 from "node:process";
6600
+ import { stringify as stringifyYaml } from "yaml";
6601
+ var adjectives = [
6602
+ "brave",
6603
+ "calm",
6604
+ "dark",
6605
+ "eager",
6606
+ "fair",
6607
+ "glad",
6608
+ "happy",
6609
+ "idle",
6610
+ "jolly",
6611
+ "keen",
6612
+ "lame",
6613
+ "mild",
6614
+ "neat",
6615
+ "odd",
6616
+ "pale",
6617
+ "quick",
6618
+ "rare",
6619
+ "safe",
6620
+ "tall",
6621
+ "ugly",
6622
+ "vast",
6623
+ "warm",
6624
+ "young",
6625
+ "zany",
6626
+ "bold",
6627
+ "cool",
6628
+ "dry",
6629
+ "fast",
6630
+ "good",
6631
+ "hot",
6632
+ "icy",
6633
+ "loud"
6634
+ ];
6635
+ var nouns = [
6636
+ "ant",
6637
+ "bear",
6638
+ "cat",
6639
+ "dog",
6640
+ "elk",
6641
+ "fox",
6642
+ "goat",
6643
+ "hawk",
6644
+ "ibis",
6645
+ "jay",
6646
+ "kite",
6647
+ "lion",
6648
+ "mole",
6649
+ "newt",
6650
+ "owl",
6651
+ "puma",
6652
+ "quail",
6653
+ "ram",
6654
+ "seal",
6655
+ "toad",
6656
+ "urchin",
6657
+ "vole",
6658
+ "wolf",
6659
+ "yak",
6660
+ "zebra",
6661
+ "ape",
6662
+ "bat",
6663
+ "cow",
6664
+ "deer",
6665
+ "emu",
6666
+ "frog",
6667
+ "gull"
6668
+ ];
6669
+ function generateChangesetId() {
6670
+ const adjective = adjectives[Math.floor(Math.random() * adjectives.length)];
6671
+ const noun = nouns[Math.floor(Math.random() * nouns.length)];
6672
+ const suffix = Math.random().toString(36).slice(2, 6);
6673
+ return `${adjective}-${noun}-${suffix}`;
6674
+ }
6675
+ function generateChangesetContent(releases, summary) {
6676
+ let content = "---\n";
6677
+ if (releases.length > 0) {
6678
+ const yamlObj = {};
6679
+ for (const release of releases) {
6680
+ yamlObj[release.name] = release.type;
6681
+ }
6682
+ content += stringifyYaml(yamlObj);
6683
+ }
6684
+ content += "---\n";
6685
+ if (summary) {
6686
+ content += `
6687
+ ${summary}
6688
+ `;
6689
+ }
6690
+ return content;
6691
+ }
6692
+ function writeChangeset(releases, summary, cwd = process15.cwd()) {
6693
+ const changesetsDir = path6.join(cwd, ".pubm", "changesets");
6694
+ mkdirSync3(changesetsDir, { recursive: true });
6695
+ const id = generateChangesetId();
6696
+ const fileName = `${id}.md`;
6697
+ const filePath = path6.join(changesetsDir, fileName);
6698
+ const content = generateChangesetContent(releases, summary);
6699
+ writeFileSync2(filePath, content, "utf-8");
6700
+ return filePath;
6701
+ }
6702
+
6703
+ // src/config/defaults.ts
6704
+ var defaultValidate = {
6705
+ cleanInstall: true,
6706
+ entryPoints: true,
6707
+ extraneousFiles: true
6708
+ };
6709
+ var defaultSnapshot = {
6710
+ useCalculatedVersion: false,
6711
+ prereleaseTemplate: "{tag}-{timestamp}"
6712
+ };
6713
+ var defaultConfig = {
6714
+ versioning: "independent",
6715
+ branch: "main",
6716
+ changelog: true,
6717
+ changelogFormat: "default",
6718
+ commit: false,
6719
+ access: "public",
6720
+ fixed: [],
6721
+ linked: [],
6722
+ updateInternalDependencies: "patch",
6723
+ ignore: [],
6724
+ tag: "latest",
6725
+ contents: ".",
6726
+ saveToken: true,
6727
+ releaseDraft: true,
6728
+ releaseNotes: true,
6729
+ registries: ["npm", "jsr"],
6730
+ rollbackStrategy: "individual"
6731
+ };
6732
+ function resolveConfig(config) {
6733
+ const packages = config.packages ?? [
6734
+ { path: ".", registries: ["npm", "jsr"] }
6735
+ ];
6736
+ return {
6737
+ ...defaultConfig,
6738
+ ...config,
6739
+ packages,
6740
+ validate: { ...defaultValidate, ...config.validate },
6741
+ snapshot: { ...defaultSnapshot, ...config.snapshot }
6742
+ };
6743
+ }
6744
+
6745
+ // src/config/loader.ts
6746
+ import { stat as stat3 } from "node:fs/promises";
6747
+ import path7 from "node:path";
6748
+ var CONFIG_FILES = [
6749
+ "pubm.config.ts",
6750
+ "pubm.config.mts",
6751
+ "pubm.config.cts",
6752
+ "pubm.config.js",
6753
+ "pubm.config.mjs",
6754
+ "pubm.config.cjs"
6755
+ ];
6756
+ async function findConfigFile(cwd) {
6757
+ for (const file of CONFIG_FILES) {
6758
+ const filePath = path7.join(cwd, file);
6759
+ try {
6760
+ if ((await stat3(filePath)).isFile()) {
6761
+ return filePath;
6762
+ }
6763
+ } catch {
6764
+ }
6765
+ }
6766
+ return null;
6767
+ }
6768
+ async function loadConfig(cwd = process.cwd()) {
6769
+ const configPath = await findConfigFile(cwd);
6770
+ if (!configPath) return null;
6771
+ const { createJiti } = await import("jiti");
6772
+ const jiti = createJiti(cwd, { interopDefault: true });
6773
+ const mod = await jiti.import(configPath);
6774
+ return mod.default ?? mod;
6775
+ }
6776
+
6777
+ // src/config/types.ts
6778
+ function defineConfig(config) {
6779
+ return config;
6780
+ }
6781
+
6782
+ // src/monorepo/dependency-graph.ts
6783
+ function buildDependencyGraph(packages) {
6784
+ const packageNames = new Set(packages.map((pkg) => pkg.name));
6785
+ const graph = /* @__PURE__ */ new Map();
6786
+ for (const pkg of packages) {
6787
+ const internalDeps = Object.keys(pkg.dependencies).filter(
6788
+ (dep) => packageNames.has(dep)
6789
+ );
6790
+ graph.set(pkg.name, internalDeps);
6791
+ }
6792
+ return graph;
6793
+ }
6794
+ function topologicalSort(graph) {
6795
+ const inDegree = /* @__PURE__ */ new Map();
6796
+ for (const name of graph.keys()) {
6797
+ inDegree.set(name, 0);
6798
+ }
6799
+ for (const [, deps] of graph) {
6800
+ for (const dep of deps) {
6801
+ inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
6802
+ }
6803
+ }
6804
+ const queue = [];
6805
+ for (const [name, degree] of inDegree) {
6806
+ if (degree === 0) {
6807
+ queue.push(name);
6808
+ }
6809
+ }
6810
+ const sorted = [];
6811
+ while (queue.length > 0) {
6812
+ const node = queue.shift();
6813
+ sorted.push(node);
6814
+ for (const dep of graph.get(node) ?? []) {
6815
+ const newDegree = (inDegree.get(dep) ?? 0) - 1;
6816
+ inDegree.set(dep, newDegree);
6817
+ if (newDegree === 0) {
6818
+ queue.push(dep);
6819
+ }
6820
+ }
6821
+ }
6822
+ if (sorted.length !== graph.size) {
6823
+ throw new Error("Circular dependency detected");
6824
+ }
6825
+ return sorted.reverse();
6826
+ }
6827
+
6828
+ // src/monorepo/groups.ts
6829
+ import micromatch from "micromatch";
6830
+ function resolveGroups(groups, allPackages) {
6831
+ return groups.map((group) => {
6832
+ const resolved = /* @__PURE__ */ new Set();
6833
+ for (const pattern of group) {
6834
+ const matches = micromatch(allPackages, pattern);
6835
+ for (const match of matches) {
6836
+ resolved.add(match);
6837
+ }
6838
+ }
6839
+ return [...resolved];
6840
+ });
6841
+ }
6842
+ function applyFixedGroup(bumps, group) {
6843
+ let max = null;
6844
+ for (const pkg of group) {
6845
+ const bump = bumps.get(pkg);
6846
+ if (bump) {
6847
+ max = max ? maxBump(max, bump) : bump;
6848
+ }
6849
+ }
6850
+ if (!max) return;
6851
+ for (const pkg of group) {
6852
+ bumps.set(pkg, max);
6853
+ }
6854
+ }
6855
+ function applyLinkedGroup(bumps, group) {
6856
+ let max = null;
6857
+ for (const pkg of group) {
6858
+ const bump = bumps.get(pkg);
6859
+ if (bump) {
6860
+ max = max ? maxBump(max, bump) : bump;
6861
+ }
6862
+ }
6863
+ if (!max) return;
6864
+ for (const pkg of group) {
6865
+ if (bumps.has(pkg)) {
6866
+ bumps.set(pkg, max);
6867
+ }
6868
+ }
6869
+ }
6870
+
6871
+ // src/monorepo/workspace.ts
6872
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
6873
+ import { join } from "node:path";
6874
+ import { parse as parse2 } from "yaml";
6875
+ function detectWorkspace(cwd) {
6876
+ const root = cwd ?? process.cwd();
6877
+ const pnpmWorkspacePath = join(root, "pnpm-workspace.yaml");
6878
+ if (existsSync3(pnpmWorkspacePath)) {
6879
+ const content = readFileSync3(pnpmWorkspacePath, "utf-8");
6880
+ const parsed = parse2(content);
6881
+ const packages = parsed?.packages ?? [];
6882
+ return { type: "pnpm", patterns: packages };
6883
+ }
6884
+ const packageJsonPath = join(root, "package.json");
6885
+ if (existsSync3(packageJsonPath)) {
6886
+ const content = readFileSync3(packageJsonPath, "utf-8");
6887
+ const pkg = JSON.parse(content);
6888
+ if (pkg.workspaces) {
6889
+ if (Array.isArray(pkg.workspaces)) {
6890
+ return { type: "npm", patterns: pkg.workspaces };
6891
+ }
6892
+ if (typeof pkg.workspaces === "object" && Array.isArray(pkg.workspaces.packages)) {
6893
+ return { type: "yarn", patterns: pkg.workspaces.packages };
6894
+ }
6895
+ }
6896
+ }
6897
+ return null;
6898
+ }
6899
+
6900
+ // src/prerelease/pre.ts
6901
+ import {
6902
+ existsSync as existsSync4,
6903
+ mkdirSync as mkdirSync4,
6904
+ readFileSync as readFileSync4,
6905
+ rmSync,
6906
+ writeFileSync as writeFileSync3
6907
+ } from "node:fs";
6908
+ import path8 from "node:path";
6909
+ function getPreStatePath(cwd) {
6910
+ return path8.resolve(cwd ?? process.cwd(), ".pubm", "pre.json");
6911
+ }
6912
+ function readPreState(cwd) {
6913
+ const filePath = getPreStatePath(cwd);
6914
+ if (!existsSync4(filePath)) {
6915
+ return null;
6916
+ }
6917
+ const content = readFileSync4(filePath, "utf-8");
6918
+ return JSON.parse(content);
6919
+ }
6920
+ function enterPreMode(tag, cwd) {
6921
+ const filePath = getPreStatePath(cwd);
6922
+ if (existsSync4(filePath)) {
6923
+ throw new Error(
6924
+ "Already in pre mode. Exit pre mode first before entering a new one."
6925
+ );
6926
+ }
6927
+ const dir = path8.dirname(filePath);
6928
+ if (!existsSync4(dir)) {
6929
+ mkdirSync4(dir, { recursive: true });
6930
+ }
6931
+ const state = {
6932
+ mode: "pre",
6933
+ tag,
6934
+ packages: {}
6935
+ };
6936
+ writeFileSync3(filePath, JSON.stringify(state, null, 2), "utf-8");
6937
+ }
6938
+ function exitPreMode(cwd) {
6939
+ const filePath = getPreStatePath(cwd);
6940
+ if (!existsSync4(filePath)) {
6941
+ throw new Error("Not in pre mode. Enter pre mode first before exiting.");
6942
+ }
6943
+ rmSync(filePath);
6944
+ }
6945
+
6946
+ // src/prerelease/snapshot.ts
6947
+ function formatTimestamp(date) {
6948
+ const year = date.getUTCFullYear();
6949
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
6950
+ const day = String(date.getUTCDate()).padStart(2, "0");
6951
+ const hours = String(date.getUTCHours()).padStart(2, "0");
6952
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
6953
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
6954
+ return `${year}${month}${day}T${hours}${minutes}${seconds}`;
6955
+ }
6956
+ function generateSnapshotVersion(options) {
6957
+ const tag = options.tag ?? "snapshot";
6958
+ const base = options.useCalculatedVersion && options.baseVersion ? options.baseVersion : "0.0.0";
6959
+ const now = /* @__PURE__ */ new Date();
6960
+ const timestamp = formatTimestamp(now);
6961
+ if (options.template) {
6962
+ return options.template.replace(/\{base\}/g, base).replace(/\{tag\}/g, tag).replace(/\{timestamp\}/g, timestamp).replace(/\{commit\}/g, options.commit ?? "").replace(/\{datetime\}/g, timestamp);
6963
+ }
6964
+ return `${base}-${tag}-${timestamp}`;
6965
+ }
6966
+
6967
+ // src/validate/entry-points.ts
6968
+ import { existsSync as existsSync5 } from "node:fs";
6969
+ import path9 from "node:path";
6970
+ var SIMPLE_FIELDS = ["main", "module", "types", "typings"];
6971
+ function checkPath(filePath, cwd) {
6972
+ return existsSync5(path9.resolve(cwd, filePath));
6973
+ }
6974
+ function validateExports(exports, cwd, prefix = "exports") {
6975
+ const errors = [];
6976
+ if (typeof exports === "string") {
6977
+ if (!checkPath(exports, cwd)) {
6978
+ errors.push({ field: prefix, path: exports });
6979
+ }
6980
+ return errors;
6981
+ }
6982
+ if (typeof exports === "object" && exports !== null) {
6983
+ for (const [key, value] of Object.entries(exports)) {
6984
+ if (typeof value === "string") {
6985
+ if (!checkPath(value, cwd)) {
6986
+ errors.push({ field: `${prefix}["${key}"]`, path: value });
6987
+ }
6988
+ } else if (typeof value === "object" && value !== null) {
6989
+ errors.push(...validateExports(value, cwd, `${prefix}["${key}"]`));
6990
+ }
6991
+ }
6992
+ }
6993
+ return errors;
6994
+ }
6995
+ function validateEntryPoints(pkg, cwd) {
6996
+ const errors = [];
6997
+ for (const field of SIMPLE_FIELDS) {
6998
+ const value = pkg[field];
6999
+ if (typeof value === "string" && !checkPath(value, cwd)) {
7000
+ errors.push({ field, path: value });
7001
+ }
7002
+ }
7003
+ if (pkg.exports !== void 0) {
7004
+ errors.push(...validateExports(pkg.exports, cwd));
7005
+ }
7006
+ if (pkg.bin !== void 0) {
7007
+ if (typeof pkg.bin === "string") {
7008
+ if (!checkPath(pkg.bin, cwd)) {
7009
+ errors.push({ field: "bin", path: pkg.bin });
7010
+ }
7011
+ } else if (typeof pkg.bin === "object" && pkg.bin !== null) {
7012
+ for (const [name, binPath] of Object.entries(
7013
+ pkg.bin
7014
+ )) {
7015
+ if (!checkPath(binPath, cwd)) {
7016
+ errors.push({ field: `bin.${name}`, path: binPath });
7017
+ }
7018
+ }
7019
+ }
7020
+ }
7021
+ return errors;
7022
+ }
7023
+
7024
+ // src/validate/extraneous-files.ts
7025
+ import micromatch2 from "micromatch";
7026
+ var PATTERNS = [
7027
+ {
7028
+ pattern: [".env", ".env.*"],
7029
+ reason: "potentially contains secrets",
7030
+ basename: true
7031
+ },
7032
+ {
7033
+ pattern: ["*.test.*", "*.spec.*"],
7034
+ reason: "test file",
7035
+ basename: true
7036
+ },
7037
+ {
7038
+ pattern: ["**/__tests__/**"],
7039
+ reason: "test file"
7040
+ },
7041
+ { pattern: ["*.map"], reason: "source map", basename: true },
7042
+ {
7043
+ pattern: [
7044
+ ".eslintrc*",
7045
+ ".prettierrc*",
7046
+ "tsconfig.json",
7047
+ "tsconfig.*.json",
7048
+ ".babelrc*",
7049
+ "jest.config.*",
7050
+ "vitest.config.*",
7051
+ ".editorconfig",
7052
+ "biome.json"
7053
+ ],
7054
+ reason: "development config file",
7055
+ basename: true
7056
+ }
7057
+ ];
7058
+ function detectExtraneousFiles(files) {
7059
+ const result = [];
7060
+ const seen = /* @__PURE__ */ new Set();
7061
+ for (const { pattern, reason, basename } of PATTERNS) {
7062
+ const options = basename ? { basename: true } : {};
7063
+ const matched = micromatch2(files, pattern, options);
7064
+ for (const file of matched) {
7065
+ if (!seen.has(file)) {
7066
+ seen.add(file);
7067
+ result.push({ file, reason });
7068
+ }
7069
+ }
7070
+ }
7071
+ return result;
7072
+ }
7073
+
6175
7074
  // src/index.ts
6176
7075
  async function pubm(options) {
6177
7076
  const resolvedOptions = resolveOptions({ ...options });
6178
7077
  await run(resolvedOptions);
6179
7078
  }
6180
7079
  export {
6181
- pubm
7080
+ applyFixedGroup,
7081
+ applyLinkedGroup,
7082
+ buildDependencyGraph,
7083
+ calculateVersionBumps,
7084
+ defineConfig,
7085
+ detectExtraneousFiles,
7086
+ detectWorkspace,
7087
+ enterPreMode,
7088
+ exitPreMode,
7089
+ generateChangelog,
7090
+ generateChangesetContent,
7091
+ generateChangesetId,
7092
+ generateSnapshotVersion,
7093
+ getStatus,
7094
+ loadConfig,
7095
+ migrateFromChangesets,
7096
+ parseChangeset,
7097
+ pubm,
7098
+ readChangesets,
7099
+ readPreState,
7100
+ resolveConfig,
7101
+ resolveGroups,
7102
+ topologicalSort,
7103
+ validateEntryPoints,
7104
+ writeChangeset
6182
7105
  };