tegami 0.1.1 → 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.
@@ -1,5 +1,5 @@
1
- import { t as execFailure } from "../error-BaOQJtvf.js";
2
- import { n as formatNpmDistTag, r as formatPackageVersion } from "../semver-mWK2Khi2.js";
1
+ import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-cnZp9koa.js";
2
+ import { n as execFailure } from "../error-qpTCB2ld.js";
3
3
  import { t as isCI } from "../constants-B9qjNfvr.js";
4
4
  import { git } from "./git.js";
5
5
  import { join, relative } from "node:path";
@@ -8,7 +8,8 @@ import { prerelease } from "semver";
8
8
  //#region src/plugins/github.ts
9
9
  /** Create GitHub releases for successfully published packages after the whole plan succeeds. */
10
10
  function github(options = {}) {
11
- async function runGithubRelease(gitTag, title, notes, prerelease) {
11
+ const { eagerRelease = false, onCreateGroupedRelease, onCreateRelease, onCreateVersionPullRequest, cli: cliOptions = {} } = options;
12
+ async function runGithubRelease(gitTag, title, notes, prerelease, repo) {
12
13
  const args = [
13
14
  "release",
14
15
  "create",
@@ -18,26 +19,27 @@ function github(options = {}) {
18
19
  "--notes",
19
20
  notes
20
21
  ];
21
- if (options.repo) args.push("--repo", options.repo);
22
+ if (repo) args.push("--repo", repo);
22
23
  if (prerelease) args.push("--prerelease");
23
24
  const result = await x("gh", args);
24
25
  if (result.exitCode !== 0) throw execFailure(`Failed to create GitHub release for ${gitTag}.`, result);
25
26
  }
26
27
  async function createRelease(context, pkg) {
27
- if (!pkg.gitTag) return;
28
- const release = await options.onCreateRelease?.call(context, pkg) ?? {};
28
+ if (!pkg.gitTag || pkg.state === "failed") return;
29
+ const release = await onCreateRelease?.call(context, pkg) ?? {};
29
30
  if (release === false) return;
30
- await runGithubRelease(pkg.gitTag, release.title ?? defaultTitle(pkg), release.notes ?? await defaultNotes(context, pkg), release.prerelease ?? prerelease(pkg.version) !== null);
31
+ await runGithubRelease(pkg.gitTag, release.title ?? defaultTitle(pkg), release.notes ?? await defaultNotes(context, pkg), release.prerelease ?? prerelease(pkg.version) !== null, context.github?.repo);
31
32
  }
32
33
  async function createGroupedRelease(context, packages) {
33
34
  const primary = packages[0];
34
35
  if (!primary?.gitTag) return;
35
- const release = await options.onCreateGroupedRelease?.call(context, packages) ?? {};
36
+ if (packages.some((member) => member.state === "failed")) return;
37
+ const release = await onCreateGroupedRelease?.call(context, packages) ?? {};
36
38
  if (release === false) return;
37
- await runGithubRelease(primary.gitTag, release.title ?? defaultGroupedTitle(packages), release.notes ?? await defaultGroupedNotes(context, packages), release.prerelease ?? packages.some((pkg) => prerelease(pkg.version) !== null));
39
+ await runGithubRelease(primary.gitTag, release.title ?? defaultGroupedTitle(packages), release.notes ?? await defaultGroupedNotes(context, packages), release.prerelease ?? packages.some((pkg) => prerelease(pkg.version) !== null), context.github?.repo);
38
40
  }
39
41
  function resolvePROptions() {
40
- const setting = options.cli?.versionPr ?? isCI();
42
+ const setting = cliOptions.versionPr ?? isCI();
41
43
  if (setting === false) return [false];
42
44
  if (setting === true) return [true, {}];
43
45
  if (setting.forceCreate || isCI()) return [true, setting];
@@ -77,24 +79,21 @@ function github(options = {}) {
77
79
  return [git(options), {
78
80
  name: "github",
79
81
  init() {
80
- const repository = options.repo ?? process.env.GITHUB_REPOSITORY;
81
- const token = options.token ?? process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
82
82
  this.github = {
83
- repo: repository,
84
- token
83
+ repo: options.repo ?? process.env.GITHUB_REPOSITORY,
84
+ token: options.token ?? process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN
85
85
  };
86
86
  },
87
87
  cli: {
88
88
  async init() {
89
89
  if (!isCI()) return;
90
- const repository = this.github?.repo;
91
- const token = this.github?.token;
92
- if (!token || !repository) return;
90
+ const { repo, token } = this.github ?? {};
91
+ if (!token || !repo) return;
93
92
  const result = await x("git", [
94
93
  "remote",
95
94
  "set-url",
96
95
  "origin",
97
- `https://x-access-token:${token}@github.com/${repository}.git`
96
+ `https://x-access-token:${token}@github.com/${repo}.git`
98
97
  ], { nodeOptions: { cwd: this.cwd } });
99
98
  if (result.exitCode !== 0) throw execFailure("Failed to configure git remote for GitHub Actions.", result);
100
99
  },
@@ -104,9 +103,10 @@ function github(options = {}) {
104
103
  async publishPlanApplied(draft) {
105
104
  const { cwd } = this;
106
105
  const [enabled, config] = resolvePROptions();
106
+ const repo = this.github?.repo;
107
107
  if (!enabled || !await hasGitChanges(cwd)) return;
108
108
  const { branch = "tegami/version-packages", base = "main" } = config;
109
- const basePR = await options.onCreateVersionPullRequest?.call(this, draft);
109
+ const basePR = await onCreateVersionPullRequest?.call(this, draft);
110
110
  if (basePR === false) return;
111
111
  const pr = {
112
112
  title: basePR?.title ?? "Version Packages",
@@ -135,7 +135,7 @@ function github(options = {}) {
135
135
  branch
136
136
  ], gitOptions);
137
137
  if (result.exitCode !== 0) throw execFailure("Failed to push the version branch to origin. Ensure `origin` is configured and you have push access.", result);
138
- const openPr = await findOpenPullRequest(branch, options.repo);
138
+ const openPr = await findOpenPullRequest(branch, repo);
139
139
  if (openPr !== void 0) {
140
140
  const editArgs = [
141
141
  "pr",
@@ -146,7 +146,7 @@ function github(options = {}) {
146
146
  "--body",
147
147
  pr.body
148
148
  ];
149
- if (options.repo) editArgs.push("--repo", options.repo);
149
+ if (repo) editArgs.push("--repo", repo);
150
150
  const editResult = await x("gh", editArgs);
151
151
  if (editResult.exitCode !== 0) throw execFailure("Failed to update the version pull request.", editResult);
152
152
  return;
@@ -163,13 +163,14 @@ function github(options = {}) {
163
163
  "--base",
164
164
  base
165
165
  ];
166
- if (options.repo) args.push("--repo", options.repo);
166
+ if (repo) args.push("--repo", repo);
167
167
  const prResult = await x("gh", args);
168
168
  if (prResult.exitCode !== 0) throw execFailure("Failed to create the version pull request.", prResult);
169
169
  }
170
170
  },
171
171
  async afterPublishAll(result) {
172
- if (result.state !== "created") return;
172
+ if (!eagerRelease && result.state === "failed") return;
173
+ if (result.state === "skipped") return;
173
174
  for (const packages of groupPackagesByGitTag(result.packages).values()) if (packages.length > 1) await createGroupedRelease(this, packages);
174
175
  else await createRelease(this, packages[0]);
175
176
  }
@@ -1,2 +1,2 @@
1
- import { d as CargoPluginOptions, f as CargoRegistryClient, p as cargo, u as CargoPackage } from "../types-Diwnh8Tn.js";
1
+ import { d as CargoPluginOptions, f as CargoRegistryClient, p as cargo, u as CargoPackage } from "../types-Di--A9X1.js";
2
2
  export { CargoPackage, CargoPluginOptions, CargoRegistryClient, cargo };
@@ -1,10 +1,10 @@
1
- import { r as isNodeError, t as execFailure } from "../error-BaOQJtvf.js";
2
- import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
1
+ import { i as isNodeError, n as execFailure } from "../error-qpTCB2ld.js";
2
+ import { n as WorkspacePackage } from "../graph-hBQUWKQA.js";
3
3
  import { readFile, writeFile } from "node:fs/promises";
4
4
  import { join, normalize } from "node:path";
5
5
  import { x } from "tinyexec";
6
- import initToml, { edit, parse } from "@rainbowatcher/toml-edit-js";
7
6
  import * as semver from "semver";
7
+ import initToml, { edit, parse as parse$1 } from "@rainbowatcher/toml-edit-js";
8
8
  import { glob } from "tinyglobby";
9
9
  //#region src/providers/cargo.ts
10
10
  const DEP_FIELDS = [
@@ -31,8 +31,8 @@ var CargoPackage = class extends WorkspacePackage {
31
31
  get version() {
32
32
  return stringValue(this.packageInfo.version) ?? this.workspaceVersion ?? "0.0.0";
33
33
  }
34
- onPlan(context) {
35
- const defaults = super.onPlan(context);
34
+ initPlan() {
35
+ const defaults = super.initPlan();
36
36
  defaults.publish ??= this.packageInfo.publish !== false;
37
37
  return defaults;
38
38
  }
@@ -267,7 +267,7 @@ function parseSpec(v) {
267
267
  async function readCargoManifest(path) {
268
268
  const content = await readFile(join(path, "Cargo.toml"), "utf8");
269
269
  return {
270
- manifest: parse(content),
270
+ manifest: parse$1(content),
271
271
  content
272
272
  };
273
273
  }
@@ -1,2 +1,2 @@
1
- import { _ as npm, g as NpmRegistryClient, h as NpmPluginOptions, m as NpmPackage } from "../types-Diwnh8Tn.js";
1
+ import { _ as npm, g as NpmRegistryClient, h as NpmPluginOptions, m as NpmPackage } from "../types-Di--A9X1.js";
2
2
  export { NpmPackage, NpmPluginOptions, NpmRegistryClient, npm };
@@ -1,12 +1,12 @@
1
- import { r as isNodeError, t as execFailure } from "../error-BaOQJtvf.js";
2
- import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
1
+ import { i as isNodeError, n as execFailure } from "../error-qpTCB2ld.js";
3
2
  import { i as pnpmWorkspaceSchema, r as packageManifestSchema } from "../schemas-CurBAaW5.js";
3
+ import { n as WorkspacePackage } from "../graph-hBQUWKQA.js";
4
4
  import { readFile, writeFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  import { x } from "tinyexec";
7
7
  import * as semver from "semver";
8
- import { glob } from "tinyglobby";
9
8
  import { load } from "js-yaml";
9
+ import { glob } from "tinyglobby";
10
10
  import { detect } from "package-manager-detector";
11
11
  //#region src/providers/npm.ts
12
12
  const DEP_FIELDS = [
@@ -33,8 +33,8 @@ var NpmPackage = class extends WorkspacePackage {
33
33
  async write() {
34
34
  await writeFile(path.join(this.path, "package.json"), `${JSON.stringify(this.manifest, null, 2)}\n`);
35
35
  }
36
- onPlan(context) {
37
- const defaults = super.onPlan(context);
36
+ initPlan() {
37
+ const defaults = super.initPlan();
38
38
  defaults.publish ??= this.manifest.private !== true;
39
39
  if (this.manifest.publishConfig?.tag) {
40
40
  defaults.npm ??= {};
@@ -70,7 +70,7 @@ var NpmRegistryClient = class {
70
70
  if (registry) args.push("--registry", registry);
71
71
  const result = await x(this.client === "pnpm" ? "pnpm" : "npm", args, { nodeOptions: { cwd: this.cwd } });
72
72
  if (result.exitCode === 0) return true;
73
- if (isMissingRegistryEntry(commandOutput(result))) return false;
73
+ if (isMissingRegistryEntry(result.stderr) || isMissingRegistryEntry(result.stdout)) return false;
74
74
  throw execFailure(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}.`, result);
75
75
  };
76
76
  info = run();
@@ -79,18 +79,34 @@ var NpmRegistryClient = class {
79
79
  return info;
80
80
  }
81
81
  async publish(pkg, { packageStore }) {
82
- const args = ["publish"];
83
82
  const distTag = packageStore.npm?.distTag;
83
+ if (this.client === "bun") {
84
+ const tarball = "pkg.tgz";
85
+ const packResult = await x("bun", [
86
+ "pm",
87
+ "pack",
88
+ "--filename",
89
+ tarball
90
+ ], { nodeOptions: { cwd: pkg.path } });
91
+ if (packResult.exitCode !== 0) throw execFailure(`Failed to pack ${pkg.name}@${pkg.version}.`, packResult);
92
+ const publishArgs = ["publish", tarball];
93
+ if (distTag) publishArgs.push("--tag", distTag);
94
+ const publishResult = await x("npm", publishArgs, { nodeOptions: { cwd: pkg.path } });
95
+ if (publishResult.exitCode !== 0) throw execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, publishResult);
96
+ return;
97
+ }
98
+ const args = ["publish"];
84
99
  if (distTag) args.push("--tag", distTag);
85
- const client = this.client === "pnpm" ? "pnpm" : "npm";
86
- if (client === "pnpm") args.push("--no-git-checks");
100
+ let client;
101
+ if (this.client === "pnpm") {
102
+ client = "pnpm";
103
+ args.push("--no-git-checks");
104
+ } else if (this.client === "yarn") client = "yarn";
105
+ else client = "npm";
87
106
  const result = await x(client, args, { nodeOptions: { cwd: pkg.path } });
88
107
  if (result.exitCode !== 0) throw execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, result);
89
108
  }
90
109
  };
91
- function commandOutput(result) {
92
- return [result.stdout, result.stderr].filter(Boolean).join("\n");
93
- }
94
110
  function isMissingRegistryEntry(output) {
95
111
  const normalized = output.toLowerCase();
96
112
  return normalized.includes("e404") || normalized.includes("404") || normalized.includes("no match") || normalized.includes("no matching version") || normalized.includes("not found");
@@ -199,8 +215,7 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = f
199
215
  client = defaultClient;
200
216
  return;
201
217
  }
202
- if ((await detect({ cwd: this.cwd }))?.name === "pnpm") client = "pnpm";
203
- else client = "npm";
218
+ client = (await detect({ cwd: this.cwd }))?.name ?? "npm";
204
219
  },
205
220
  async resolve() {
206
221
  await discoverNpmPackages(this.cwd, (pkg) => this.graph.add(pkg));
@@ -252,6 +267,7 @@ function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = f
252
267
  let args;
253
268
  if (client === "npm") args = ["ci"];
254
269
  else if (client === "yarn") args = ["install", "--immutable"];
270
+ else if (client === "bun") args = ["install", "--frozen-lockfile"];
255
271
  else args = ["install", "--frozen-lockfile"];
256
272
  const result = await x(client, args, { nodeOptions: { cwd: this.cwd } });
257
273
  if (result.exitCode !== 0) throw execFailure("Failed to update lockfile.", result);
@@ -272,9 +288,9 @@ async function discoverNpmPackages(cwd, add) {
272
288
  path,
273
289
  manifest
274
290
  })).catch(() => void 0)));
275
- if (rootManifest) add(new NpmPackage(cwd, rootManifest));
291
+ if (rootManifest?.version) add(new NpmPackage(cwd, rootManifest));
276
292
  for (const entry of manifests) {
277
- if (!entry?.manifest) continue;
293
+ if (!entry?.manifest.version) continue;
278
294
  add(new NpmPackage(entry.path, entry.manifest));
279
295
  }
280
296
  }
@@ -11,6 +11,11 @@ const WEIGHTS = {
11
11
  minor: 2,
12
12
  patch: 1
13
13
  };
14
+ const DEPTH = {
15
+ major: 1,
16
+ minor: 2,
17
+ patch: 3
18
+ };
14
19
  const PRE = {
15
20
  major: "premajor",
16
21
  minor: "preminor",
@@ -20,14 +25,20 @@ function maxBump(a, b) {
20
25
  if (WEIGHTS[a] > WEIGHTS[b]) return a;
21
26
  return b;
22
27
  }
28
+ function bumpDepth(type) {
29
+ return DEPTH[type];
30
+ }
23
31
  function bumpVersion(version, type, prerelease) {
24
32
  let next = version;
25
- if (prerelease) {
26
- if (parse(version)?.prerelease[0] === prerelease) next = inc(version, "prerelease", prerelease);
27
- else if (type) next = inc(version, PRE[type], prerelease);
28
- } else if (type) next = inc(version, type);
33
+ const parsed = parse(version);
34
+ if (!parsed) next = null;
35
+ else if (prerelease) {
36
+ if (parsed.prerelease[0] === prerelease) next = inc(parsed, "prerelease", prerelease);
37
+ else if (type) next = inc(parsed, PRE[type], prerelease);
38
+ } else if (type) next = inc(parsed, type);
39
+ else if (parsed.prerelease.length > 0) next = inc(parsed, "release");
29
40
  if (!next) throw new Error(`Invalid semver version: ${version}`);
30
41
  return next;
31
42
  }
32
43
  //#endregion
33
- export { maxBump as i, formatNpmDistTag as n, formatPackageVersion as r, bumpVersion as t };
44
+ export { maxBump as a, formatPackageVersion as i, bumpVersion as n, formatNpmDistTag as r, bumpDepth as t };
@@ -4,19 +4,31 @@ import { AgentName } from "package-manager-detector";
4
4
  //#region src/utils/semver.d.ts
5
5
  type BumpType = "major" | "minor" | "patch";
6
6
  //#endregion
7
+ //#region src/changelog/shared.d.ts
8
+ declare const changelogPackageConfigSchema: z$1.ZodObject<{
9
+ type: z$1.ZodOptional<z$1.ZodEnum<{
10
+ major: "major";
11
+ minor: "minor";
12
+ patch: "patch";
13
+ }>>;
14
+ replay: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
15
+ }, z$1.core.$strip>;
16
+ type ChangelogPackageConfig = z$1.output<typeof changelogPackageConfigSchema>;
17
+ //#endregion
7
18
  //#region src/changelog/parse.d.ts
8
19
  interface ChangelogEntry {
9
20
  id: string;
10
21
  /** file name like `my-change.md` */
11
22
  filename: string;
12
23
  subject?: string;
13
- packages: Map<string, BumpType>;
24
+ packages: Map<string, ChangelogPackageConfig>;
14
25
  /** will not be empty */
15
26
  sections: {
16
27
  depth: number;
17
28
  title: string;
18
29
  content: string;
19
30
  }[];
31
+ getRawContent: () => string;
20
32
  }
21
33
  //#endregion
22
34
  //#region src/plans/draft.d.ts
@@ -48,17 +60,20 @@ declare class DraftPlan {
48
60
  type: BumpType;
49
61
  reason?: string;
50
62
  }): PackagePlan;
63
+ dispatchPackage(pkg: WorkspacePackage, dispatch: (plan: PackagePlan) => void, onUpdate?: (plan: PackagePlan) => void): PackagePlan;
64
+ private getOrInitPackage;
51
65
  hasPending(): boolean;
52
66
  getChangelogs(): ChangelogEntry[];
53
67
  getChangelog(id: string): ChangelogEntry | undefined;
54
68
  addChangelog(entry: ChangelogEntry): void;
55
69
  deleteChangelog(id: string): boolean;
56
- private initPackagePlan;
57
70
  /** Apply the publish plan: update package versions, write the plan file, and consume changelog files. */
58
71
  applyPlan(): Promise<void>;
59
72
  addPolicy(policy: PlanPolicy): void;
60
73
  removePolicy(policy: PlanPolicy): void;
61
74
  canApply(): boolean;
75
+ /** Attach replaying changelog entries to packages (already bumped), and return the updated changelog entries. */
76
+ private applyReplays;
62
77
  private appendChangelog;
63
78
  /** {@link applyPlan} but for `await using` syntax */
64
79
  [Symbol.asyncDispose](): Promise<void>;
@@ -89,8 +104,10 @@ declare abstract class WorkspacePackage {
89
104
  /** note: this will only be available after package graph is resolved */
90
105
  getPackageOptions(): PackageOptions;
91
106
  setPackageOptions(options: PackageOptions): void;
92
- /** create an empty draft plan. */
93
- onPlan(_context: TegamiContext): PackagePlan;
107
+ /** create the initial draft plan. */
108
+ initPlan(): PackagePlan;
109
+ /** configure an initial draft plan to match script-level configs. */
110
+ configurePlan(plan: PackagePlan): void;
94
111
  }
95
112
  interface PackageGroup {
96
113
  name: string;
@@ -160,17 +177,7 @@ declare const planStoreSchema: z$1.ZodCodec<z$1.ZodString, z$1.ZodObject<{
160
177
  version: z$1.ZodDefault<z$1.ZodLiteral<"0.0.0">>;
161
178
  changelogs: z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
162
179
  filename: z$1.ZodString;
163
- subject: z$1.ZodOptional<z$1.ZodString>;
164
- packages: z$1.ZodRecord<z$1.ZodString, z$1.ZodEnum<{
165
- major: "major";
166
- minor: "minor";
167
- patch: "patch";
168
- }>>;
169
- sections: z$1.ZodArray<z$1.ZodObject<{
170
- depth: z$1.ZodNumber;
171
- title: z$1.ZodString;
172
- content: z$1.ZodString;
173
- }, z$1.core.$strip>>;
180
+ content: z$1.ZodString;
174
181
  }, z$1.core.$strip>>;
175
182
  packages: z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
176
183
  type: z$1.ZodOptional<z$1.ZodEnum<{
@@ -228,12 +235,26 @@ interface CreateChangelogOptions {
228
235
  from?: string;
229
236
  /** End revision. Defaults to HEAD. */
230
237
  to?: string;
238
+ /**
239
+ * Write changelog files to disk.
240
+ *
241
+ * @default true
242
+ */
243
+ write?: boolean;
231
244
  }
232
245
  interface CreatedChangelog {
233
246
  filename: string;
234
- path: string;
247
+ content: string;
248
+ packages: Record<string, BumpType | ChangelogPackageConfig>;
249
+ changes: CommitChange[];
250
+ }
251
+ interface CommitChange {
252
+ hash: string;
253
+ subject: string;
254
+ body: string;
235
255
  packages: string[];
236
- changes: number;
256
+ type: BumpType;
257
+ title: string;
237
258
  }
238
259
  //#endregion
239
260
  //#region src/index.d.ts
@@ -287,7 +308,7 @@ declare class NpmPackage extends WorkspacePackage {
287
308
  get name(): string;
288
309
  get version(): string;
289
310
  write(): Promise<void>;
290
- onPlan(context: TegamiContext): PackagePlan;
311
+ initPlan(): PackagePlan;
291
312
  }
292
313
  declare class NpmRegistryClient implements RegistryClient {
293
314
  #private;
@@ -368,7 +389,7 @@ declare class CargoPackage extends WorkspacePackage {
368
389
  constructor(path: string, manifest: TomlTable, content: string, workspaceManifest?: TomlTable | undefined);
369
390
  get name(): string;
370
391
  get version(): string;
371
- onPlan(context: TegamiContext): PackagePlan;
392
+ initPlan(): PackagePlan;
372
393
  setVersion(version: string): void;
373
394
  write(): Promise<void>;
374
395
  patch(path: string, value: unknown): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Utility for package versioning & publish",
5
5
  "license": "MIT",
6
6
  "author": "Fuma Nama",
@@ -1,98 +0,0 @@
1
- import { n as handlePluginError } from "./error-BaOQJtvf.js";
2
- import { n as jsonCodec, t as bumpTypeSchema } from "./schemas-CurBAaW5.js";
3
- import z$1 from "zod";
4
- import { readFile } from "fs/promises";
5
- //#region src/utils/changelog.ts
6
- function changelogFilename(disambiguator = 0) {
7
- const date = /* @__PURE__ */ new Date();
8
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}-${(Date.now() + disambiguator).toString(36)}.md`;
9
- }
10
- //#endregion
11
- //#region src/plans/store.ts
12
- const packagePlanStoreSchema = z$1.object({
13
- type: bumpTypeSchema.optional(),
14
- changelogIds: z$1.array(z$1.string()).optional(),
15
- bumpReasons: z$1.array(z$1.string()).optional(),
16
- npm: z$1.object({ distTag: z$1.string().optional() }).optional(),
17
- publish: z$1.boolean()
18
- });
19
- /** the persisted plan data for actual publishing */
20
- const planStoreSchema = jsonCodec(z$1.object({
21
- id: z$1.string(),
22
- createdAt: z$1.iso.datetime(),
23
- version: z$1.literal("0.0.0").default("0.0.0"),
24
- /** release note entries */
25
- changelogs: z$1.record(z$1.string(), z$1.object({
26
- filename: z$1.string(),
27
- subject: z$1.string().optional(),
28
- packages: z$1.record(z$1.string(), bumpTypeSchema),
29
- sections: z$1.array(z$1.object({
30
- depth: z$1.number(),
31
- title: z$1.string(),
32
- content: z$1.string()
33
- }))
34
- })),
35
- /** package id -> package info */
36
- packages: z$1.record(z$1.string(), packagePlanStoreSchema)
37
- }));
38
- function createPlanStore(draft, context) {
39
- const store = {
40
- version: "0.0.0",
41
- id: `tegami-${Date.now().toString(36)}`,
42
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
43
- changelogs: {},
44
- packages: {}
45
- };
46
- for (const entry of draft.getChangelogs()) store.changelogs[entry.id] = {
47
- filename: entry.filename,
48
- subject: entry.subject,
49
- packages: Object.fromEntries(entry.packages.entries()),
50
- sections: entry.sections
51
- };
52
- for (const pkg of context.graph.getPackages()) {
53
- const plan = draft.getPackagePlan(pkg.id);
54
- if (plan) store.packages[pkg.id] = {
55
- publish: plan.publish ?? false,
56
- type: plan.type,
57
- npm: plan.npm,
58
- changelogIds: plan.changelogs?.map((entry) => entry.id),
59
- bumpReasons: plan.bumpReasons ? Array.from(plan.bumpReasons) : void 0
60
- };
61
- }
62
- return planStoreSchema.encode(store);
63
- }
64
- async function readPlanStore(context) {
65
- try {
66
- return planStoreSchema.decode(await readFile(context.planPath, "utf8"));
67
- } catch {}
68
- }
69
- //#endregion
70
- //#region src/plans/checks.ts
71
- async function publishPlanStatus(store, context) {
72
- async function defaultStatus() {
73
- try {
74
- await Promise.all(Object.entries(store.packages).map(async ([id, plan]) => {
75
- const pkg = context.graph.get(id);
76
- if (!pkg || !plan.publish) return;
77
- if (!await context.getRegistryClient(pkg).isPackagePublished(pkg)) throw "pending";
78
- }));
79
- return { state: "success" };
80
- } catch (err) {
81
- if (err === "pending") return { state: "pending" };
82
- throw err;
83
- }
84
- }
85
- let status = await defaultStatus();
86
- for (const plugin of context.plugins) {
87
- const resolved = await handlePluginError(plugin, "resolvePlanStatus", () => plugin.resolvePlanStatus?.call(context, status, { plan: store }));
88
- if (resolved) status = resolved;
89
- }
90
- return status;
91
- }
92
- async function assertPublishPlanFinished(context) {
93
- const store = await readPlanStore(context);
94
- if (!store) return;
95
- if ((await publishPlanStatus(store, context)).state === "pending") throw new Error(`Publish plan already exists at ${context.planPath} and is pending. Publish it before applying a new plan.`);
96
- }
97
- //#endregion
98
- export { changelogFilename as a, readPlanStore as i, publishPlanStatus as n, createPlanStore as r, assertPublishPlanFinished as t };