tegami 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { k as Draft, p as Tegami, t as Awaitable, y as PublishPlan } from "../types-DHddSAez.js";
1
+ import { k as Draft, p as Tegami, t as Awaitable, y as PublishPlan } from "../types-BoQR7Hlg.js";
2
2
 
3
3
  //#region src/cli/index.d.ts
4
4
  interface TegamiCLIOptions {
@@ -87,18 +87,33 @@ function parseChangelogFile(filename, content) {
87
87
  };
88
88
  return entry;
89
89
  }
90
+ function formatReplayCondition(condition) {
91
+ switch (condition.on) {
92
+ case "exit-prerelease": return `exit-prerelease(${condition.name})`;
93
+ case "enter-prerelease": return `prerelease(${condition.name})`;
94
+ case "version": return `${condition.name}@${condition.version}`;
95
+ }
96
+ }
90
97
  function parseReplayCondition(condition) {
91
- if (condition.startsWith("exit prerelease:")) return {
92
- type: "on-exit-prerelease",
93
- name: condition.slice(16).trimStart()
98
+ let match;
99
+ if (match = /^exit-prerelease\((.+)\)$/.exec(condition)) return {
100
+ on: "exit-prerelease",
101
+ name: match[1]
94
102
  };
95
- const idx = condition.lastIndexOf("@");
96
- if (idx <= 0) return null;
97
- return {
98
- type: "on-version",
99
- name: condition.slice(0, idx),
100
- version: condition.slice(idx + 1)
103
+ if (match = /^prerelease\((.+)\)$/.exec(condition)) return {
104
+ on: "enter-prerelease",
105
+ name: match[1]
106
+ };
107
+ if (match = /^exit prerelease:\s*(.+)$/.exec(condition)) return {
108
+ on: "exit-prerelease",
109
+ name: match[1]
110
+ };
111
+ if (match = /^(.+)@([^@]+)$/.exec(condition)) return {
112
+ on: "version",
113
+ name: match[1],
114
+ version: match[2]
101
115
  };
116
+ return null;
102
117
  }
103
118
  function parseMarkdownSections(markdown) {
104
119
  const sections = [];
@@ -205,12 +220,12 @@ function parsePublishLock(content) {
205
220
  }
206
221
  //#endregion
207
222
  //#region src/plans/policy.ts
208
- function groupPolicy({ graph }) {
223
+ function groupPolicy(_ctx) {
209
224
  return {
210
225
  id: "group",
211
226
  onUpdate({ pkg, packageDraft }) {
212
227
  if (!packageDraft.type) return;
213
- const group = graph.getPackageGroup(pkg.id);
228
+ const group = pkg.group;
214
229
  if (!group || !group.options.syncBump) return;
215
230
  for (const member of group.packages) {
216
231
  if (member === pkg) continue;
@@ -279,7 +294,7 @@ var Draft = class {
279
294
  const existing = this.packages.get(pkg.id);
280
295
  if (existing) return existing;
281
296
  this.packages.set(pkg.id, pkg.initDraft());
282
- return this.dispatchPackage(pkg, (draft) => pkg.configureDraft(draft, this.context.graph.getPackageGroup(pkg.id)), (draft) => {
297
+ return this.dispatchPackage(pkg, (draft) => pkg.configureDraft({ draft }), (draft) => {
283
298
  (draft.bumpReasons ??= /* @__PURE__ */ new Set()).add("align with script-level configs");
284
299
  });
285
300
  }
@@ -387,15 +402,26 @@ var Draft = class {
387
402
  const { graph } = this.context;
388
403
  const defaultReplays = (name) => {
389
404
  const replay = [];
390
- for (const pkg of graph.getByName(name)) if (this.packages.get(pkg.id)?.prerelease) replay.push(`exit prerelease: ${pkg.id}`);
405
+ for (const pkg of graph.getByName(name)) if (this.packages.get(pkg.id)?.prerelease) replay.push(formatReplayCondition({
406
+ on: "exit-prerelease",
407
+ name: pkg.id
408
+ }));
391
409
  return replay;
392
410
  };
393
411
  const isMatch = (condition) => {
394
- if (condition.type === "on-exit-prerelease") return graph.getByName(condition.name).some((pkg) => {
395
- const previous = snapshots.get(pkg.id);
396
- return previous?.version && semver$1.inc(previous.version, "release") === pkg.version;
397
- });
398
- return graph.getByName(condition.name).some((pkg) => pkg.version === condition.version);
412
+ switch (condition.on) {
413
+ case "enter-prerelease": return graph.getByName(condition.name).some((pkg) => {
414
+ const previous = snapshots.get(pkg.id);
415
+ if (!pkg.version || !previous?.version) return false;
416
+ return !semver$1.prerelease(previous.version) && semver$1.prerelease(pkg.version);
417
+ });
418
+ case "exit-prerelease": return graph.getByName(condition.name).some((pkg) => {
419
+ const previous = snapshots.get(pkg.id);
420
+ if (!pkg.version || !previous?.version) return false;
421
+ return semver$1.inc(previous.version, "release") === pkg.version;
422
+ });
423
+ case "version": return graph.getByName(condition.name).some((pkg) => pkg.version === condition.version);
424
+ }
399
425
  };
400
426
  for (const entry of this.changelogs.values()) {
401
427
  const updatedPackages = /* @__PURE__ */ new Map();
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-DHddSAez.js";
1
+ import { r as LogGenerator } from "../types-BoQR7Hlg.js";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
@@ -2,17 +2,13 @@ import { n as bumpVersion } from "./semver-EKJ8yK5U.js";
2
2
  //#region src/graph.ts
3
3
  /** Package discovered in the workspace. */
4
4
  var WorkspacePackage = class {
5
+ /** note: this will only be available after package graph is resolved */
6
+ group;
7
+ /** note: this will only be available after package graph is resolved */
8
+ options = {};
5
9
  get id() {
6
10
  return `${this.manager}:${this.name}`;
7
11
  }
8
- opts = {};
9
- /** note: this will only be available after package graph is resolved */
10
- getPackageOptions() {
11
- return this.opts;
12
- }
13
- setPackageOptions(options) {
14
- this.opts = options;
15
- }
16
12
  /** create the initial draft. */
17
13
  initDraft() {
18
14
  return { bumpVersion(pkg) {
@@ -21,12 +17,17 @@ var WorkspacePackage = class {
21
17
  } };
22
18
  }
23
19
  /** configure an initial draft to match script-level configs. */
24
- configureDraft(draft, group) {
25
- const { prerelease = group?.options?.prerelease } = this.opts;
20
+ configureDraft({ draft }) {
21
+ const { prerelease = this.group?.options?.prerelease } = this.options;
26
22
  if (prerelease !== void 0) draft.prerelease = prerelease;
27
23
  }
28
24
  };
29
- /** Dependency graph for discovered workspace packages. */
25
+ /**
26
+ * Unified graph for discovered workspace packages.
27
+ *
28
+ * This is only used as a storage for all indexed packages.
29
+ * For registry-specific relationships (e.g. virtual workspaces), they are stored in the provider plugin internally.
30
+ */
30
31
  var PackageGraph = class {
31
32
  packages = /* @__PURE__ */ new Map();
32
33
  groups = /* @__PURE__ */ new Map();
@@ -34,27 +35,25 @@ var PackageGraph = class {
34
35
  for (const pkg of packages) this.add(pkg);
35
36
  }
36
37
  getPackages() {
37
- const out = [];
38
- for (const pkg of this.packages.values()) out.push(pkg.value);
39
- return out;
38
+ return Array.from(this.packages.values());
40
39
  }
41
40
  /** Get a package by exact id. */
42
41
  get(id) {
43
- return this.packages.get(id)?.value;
42
+ return this.packages.get(id);
44
43
  }
45
44
  /** Get packages by id, `group:name`, or every package matching a name. */
46
45
  getByName(nameOrId) {
47
46
  const exact = this.packages.get(nameOrId);
48
- if (exact) return [exact.value];
47
+ if (exact) return [exact];
49
48
  if (nameOrId.startsWith("group:")) return this.getGroup(nameOrId.slice(6))?.packages ?? [];
50
49
  const out = [];
51
- for (const { value } of this.packages.values()) if (value.name === nameOrId) out.push(value);
50
+ for (const value of this.packages.values()) if (value.name === nameOrId) out.push(value);
52
51
  return out;
53
52
  }
54
53
  /** scan package into graph, if the package id already exists, replace the existing one in graph */
55
54
  add(pkg) {
56
55
  this.delete(pkg.id);
57
- this.packages.set(pkg.id, { value: pkg });
56
+ this.packages.set(pkg.id, pkg);
58
57
  }
59
58
  delete(id) {
60
59
  this.packages.delete(id);
@@ -91,7 +90,7 @@ var PackageGraph = class {
91
90
  const pkg = this.packages.get(id);
92
91
  if (!group || !pkg || pkg.group) return;
93
92
  pkg.group = group;
94
- group.packages.push(pkg.value);
93
+ group.packages.push(pkg);
95
94
  }
96
95
  removeGroupMember(group, id) {
97
96
  const entry = this.groups.get(group);
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as DraftPolicy, D as PackageGroup, E as PackageGraph, M as BumpType, O as WorkspacePackage, _ as PackagePublishResult, a as PublishPreflight, b as CommitChangelog, c as TegamiPluginOption, f as GenerateChangelogOptions, g as PackagePublishPlan, h as PublishLock, i as PackageOptions, j as PackageDraft, k as Draft, m as tegami, n as GroupOptions, o as TegamiOptions, p as Tegami, r as LogGenerator, s as TegamiPlugin, v as PublishOptions, x as TegamiContext, y as PublishPlan } from "./types-DHddSAez.js";
1
+ import { A as DraftPolicy, D as PackageGroup, E as PackageGraph, M as BumpType, O as WorkspacePackage, _ as PackagePublishResult, a as PublishPreflight, b as CommitChangelog, c as TegamiPluginOption, f as GenerateChangelogOptions, g as PackagePublishPlan, h as PublishLock, i as PackageOptions, j as PackageDraft, k as Draft, m as tegami, n as GroupOptions, o as TegamiOptions, p as Tegami, r as LogGenerator, s as TegamiPlugin, v as PublishOptions, x as TegamiContext, y as PublishPlan } from "./types-BoQR7Hlg.js";
2
2
  export { type BumpType, type CommitChangelog, type Draft, type DraftPolicy, GenerateChangelogOptions, type GroupOptions, type LogGenerator, type PackageDraft, PackageGraph, type PackageGroup, type PackageOptions, type PackagePublishPlan, type PackagePublishResult, type PublishLock, type PublishOptions, type PublishPlan, type PublishPreflight, Tegami, type TegamiContext, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { n as generateFromCommits } from "./generate-Rvz4Lu98.js";
2
2
  import { r as handlePluginError } from "./error-BhMYq9iW.js";
3
- import { a as runPreflights, i as publishPlanStatus, n as npm, o as runPublishPlan, r as initPublishPlan } from "./npm-5cG02krT.js";
4
- import { n as WorkspacePackage, t as PackageGraph } from "./graph-gThXu8Cz.js";
5
- import { a as parseChangelogFile, n as createDraft, o as readChangelogEntries } from "./draft-BqHcSCeX.js";
3
+ import { a as runPreflights, i as publishPlanStatus, n as npm, o as runPublishPlan, r as initPublishPlan } from "./npm-Cj685Ddn.js";
4
+ import { n as WorkspacePackage, t as PackageGraph } from "./graph-BmXTJZxx.js";
5
+ import { a as parseChangelogFile, n as createDraft, o as readChangelogEntries } from "./draft-BLbt4bSG.js";
6
6
  import { mkdir, rm, writeFile } from "node:fs/promises";
7
7
  import path, { join } from "node:path";
8
8
  //#region src/context.ts
@@ -41,7 +41,7 @@ async function resolveGraph(ctx) {
41
41
  }
42
42
  const packageOptions = getPackageOptions?.(pkg);
43
43
  if (!packageOptions) continue;
44
- pkg.setPackageOptions(packageOptions);
44
+ pkg.options = packageOptions;
45
45
  if (packageOptions.group) graph.addGroupMember(packageOptions.group, pkg.id);
46
46
  }
47
47
  }
@@ -1,6 +1,6 @@
1
1
  import { c as somePromise, i as isNodeError, n as execFailure, r as handlePluginError, s as joinPath } from "./error-BhMYq9iW.js";
2
- import { n as WorkspacePackage } from "./graph-gThXu8Cz.js";
3
- import { a as parseChangelogFile, i as parsePublishLock, r as packageStoreSchema, t as changelogStoreSchema } from "./draft-BqHcSCeX.js";
2
+ import { n as WorkspacePackage } from "./graph-BmXTJZxx.js";
3
+ import { a as parseChangelogFile, i as parsePublishLock, r as packageStoreSchema, t as changelogStoreSchema } from "./draft-BLbt4bSG.js";
4
4
  import fs, { readFile, writeFile } from "node:fs/promises";
5
5
  import path, { join } from "node:path";
6
6
  import { x } from "tinyexec";
@@ -327,9 +327,9 @@ var NpmPackage = class extends WorkspacePackage {
327
327
  getRegistry() {
328
328
  return this.manifest.publishConfig?.registry ?? "https://registry.npmjs.org";
329
329
  }
330
- configureDraft(draft, group) {
331
- super.configureDraft(draft, group);
332
- const { distTag = group?.options?.npm?.distTag } = this.getPackageOptions().npm ?? {};
330
+ configureDraft({ draft }) {
331
+ super.configureDraft({ draft });
332
+ const { distTag = this.group?.options?.npm?.distTag } = this.options.npm ?? {};
333
333
  if (distTag) {
334
334
  draft.npm ??= {};
335
335
  draft.npm.distTag = distTag;
@@ -568,11 +568,10 @@ function depsPolicy(context, getBumpDepType) {
568
568
  if (!(pkg instanceof NpmPackage)) return;
569
569
  const deps = dependentMap.get(pkg.id);
570
570
  if (!deps) return;
571
- const group = graph.getPackageGroup(pkg.id);
572
571
  const bumped = plan.bumpVersion(pkg);
573
572
  if (!bumped) return;
574
573
  for (const dep of deps) {
575
- if (group?.options.syncBump && graph.getPackageGroup(dep.dependent.id) === group) continue;
574
+ if (pkg.group?.options.syncBump && dep.dependent.group === pkg.group) continue;
576
575
  if (!needsUpdate(dep.spec, bumped)) continue;
577
576
  const bumpType = getBumpDepType(dep);
578
577
  if (bumpType === false) continue;
@@ -1,2 +1,2 @@
1
- import { C as CargoPackage, S as CargoGraph, T as cargo, w as CargoPluginOptions } from "../types-DHddSAez.js";
1
+ import { C as CargoPackage, S as CargoGraph, T as cargo, w as CargoPluginOptions } from "../types-BoQR7Hlg.js";
2
2
  export { CargoGraph, CargoPackage, CargoPluginOptions, cargo };
@@ -1,5 +1,5 @@
1
1
  import { n as execFailure } from "../error-BhMYq9iW.js";
2
- import { n as WorkspacePackage } from "../graph-gThXu8Cz.js";
2
+ import { n as WorkspacePackage } from "../graph-BmXTJZxx.js";
3
3
  import { readFile, writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { x } from "tinyexec";
@@ -79,17 +79,33 @@ const DEP_FIELDS = [
79
79
  "dev-dependencies",
80
80
  "build-dependencies"
81
81
  ];
82
+ var CargoToml = class {
83
+ path;
84
+ content;
85
+ data;
86
+ dependencies;
87
+ workspace;
88
+ constructor(path, content, data) {
89
+ this.path = path;
90
+ this.content = content;
91
+ this.data = data;
92
+ }
93
+ listDependencies(graph) {
94
+ return this.dependencies ??= listDependencies(graph, this);
95
+ }
96
+ patch(path, value) {
97
+ this.content = edit(this.content, path, value);
98
+ }
99
+ };
82
100
  var CargoPackage = class extends WorkspacePackage {
83
101
  path;
84
102
  file;
85
- workspaceFile;
86
103
  manager = "cargo";
87
104
  manifest;
88
- constructor(path, file, workspaceFile) {
105
+ constructor(path, file) {
89
106
  super();
90
107
  this.path = path;
91
108
  this.file = file;
92
- this.workspaceFile = workspaceFile;
93
109
  this.manifest = file.data;
94
110
  }
95
111
  get name() {
@@ -98,7 +114,7 @@ var CargoPackage = class extends WorkspacePackage {
98
114
  get version() {
99
115
  const packageVersion = this.manifest.package.version;
100
116
  if (typeof packageVersion === "string") return packageVersion;
101
- const inherited = this.workspaceFile?.data.workspace.package;
117
+ const inherited = this.file.workspace?.data.workspace.package;
102
118
  if (packageVersion.workspace && inherited?.version) return inherited.version;
103
119
  throw new Error(`Invalid Cargo.toml in "${this.path}".`);
104
120
  }
@@ -106,20 +122,17 @@ var CargoPackage = class extends WorkspacePackage {
106
122
  const packageInfo = this.manifest.package;
107
123
  if (typeof packageInfo.version === "string") {
108
124
  packageInfo.version = version;
109
- patchFile(this.file, "package.version", version);
125
+ this.file.patch("package.version", version);
110
126
  return;
111
127
  }
112
- if (packageInfo.version.workspace && this.workspaceFile?.data.workspace.package) {
113
- this.workspaceFile.data.workspace.package.version = version;
114
- patchFile(this.workspaceFile, "workspace.package.version", version);
128
+ if (packageInfo.version.workspace && this.file.workspace?.data.workspace.package) {
129
+ this.file.workspace.data.workspace.package.version = version;
130
+ this.file.workspace.patch("workspace.package.version", version);
115
131
  return;
116
132
  }
117
133
  throw new Error(`Invalid Cargo.toml in "${this.path}".`);
118
134
  }
119
135
  };
120
- function patchFile(file, path, value) {
121
- file.content = edit(file.content, path, value);
122
- }
123
136
  function cargo({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
124
137
  return {
125
138
  name: "cargo",
@@ -141,13 +154,9 @@ function cargo({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
141
154
  if (!(pkg instanceof CargoPackage) || !this.cargo) return;
142
155
  let shouldPublish = true;
143
156
  if (typeof pkg.manifest.package.publish === "boolean") shouldPublish = pkg.manifest.package.publish;
144
- else if (pkg.manifest.package.publish?.workspace) shouldPublish = pkg.workspaceFile?.data.workspace?.package?.publish ?? shouldPublish;
157
+ else if (pkg.manifest.package.publish?.workspace) shouldPublish = pkg.file.workspace?.data.workspace?.package?.publish ?? shouldPublish;
145
158
  const wait = [];
146
- for (const { table, tablePath } of dependencyTables(pkg.manifest)) for (const [rawName, spec] of Object.entries(table)) {
147
- const resolved = resolveLinkedDep(pkg.workspaceFile, pkg.file, this.cargo.graph, tablePath, rawName, spec);
148
- if (!resolved) continue;
149
- wait.push(resolved.linked.id);
150
- }
159
+ for (const { resolved } of pkg.file.listDependencies(this.cargo.graph)) if (resolved) wait.push(resolved.id);
151
160
  return {
152
161
  shouldPublish,
153
162
  wait
@@ -181,14 +190,13 @@ function cargo({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
181
190
  const bumped = draft.getPackageDraft(pkg.id)?.bumpVersion(pkg);
182
191
  if (bumped) pkg.setVersion(bumped);
183
192
  }
184
- for (const pkg of graph.packages.values()) for (const { table, tablePath } of dependencyTables(pkg.manifest)) for (const [rawName, spec] of Object.entries(table)) {
185
- const resolved = resolveLinkedDep(pkg.workspaceFile, pkg.file, graph, tablePath, rawName, spec);
186
- if (!resolved || !resolved.range || !resolved.setRange || semver$1.satisfies(resolved.linked.version, resolved.range)) continue;
193
+ for (const file of graph.files.values()) for (const { range, resolved, setRange } of file.listDependencies(graph)) {
194
+ if (!resolved || !range || !setRange || semver$1.satisfies(resolved.version, range)) continue;
187
195
  let updatedRange;
188
- if (resolved.range.startsWith("^")) updatedRange = `^${resolved.linked.version}`;
189
- else if (resolved.range.startsWith("~")) updatedRange = `~${resolved.linked.version}`;
190
- else updatedRange = resolved.linked.version;
191
- table[rawName] = resolved.setRange(updatedRange);
196
+ if (range.startsWith("^")) updatedRange = `^${resolved.version}`;
197
+ else if (range.startsWith("~")) updatedRange = `~${resolved.version}`;
198
+ else updatedRange = resolved.version;
199
+ setRange(updatedRange);
192
200
  }
193
201
  await Promise.all(Array.from(graph.files.values(), (file) => writeFile(file.path, file.content + "\n")));
194
202
  },
@@ -199,7 +207,7 @@ function cargo({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
199
207
  }
200
208
  };
201
209
  }
202
- function depsPolicy({ graph, cargo }, getBumpDepType = ({ kind }) => {
210
+ function depsPolicy({ cargo }, getBumpDepType = ({ kind }) => {
203
211
  switch (kind) {
204
212
  case "dependencies": return "patch";
205
213
  case "build-dependencies":
@@ -208,25 +216,24 @@ function depsPolicy({ graph, cargo }, getBumpDepType = ({ kind }) => {
208
216
  }) {
209
217
  const cargoGraph = cargo.graph;
210
218
  const dependentMap = /* @__PURE__ */ new Map();
211
- for (const pkg of cargoGraph.packages.values()) for (const { table, tablePath } of dependencyTables(pkg.manifest)) for (const [name, spec] of Object.entries(table)) {
212
- const resolved = resolveLinkedDep(pkg.workspaceFile, pkg.file, cargoGraph, tablePath, name, spec);
219
+ for (const pkg of cargoGraph.packages.values()) for (const { resolved, path, spec, range } of pkg.file.listDependencies(cargoGraph)) {
213
220
  if (!resolved) continue;
214
- const id = resolved.linked.id;
215
- const refs = dependentMap.get(id);
216
- const kind = tablePath.at(-1);
221
+ const refs = dependentMap.get(resolved.id);
222
+ const kind = path[path.length - 2];
223
+ const name = path[path.length - 1];
217
224
  if (refs) refs.push({
218
225
  dependent: pkg,
219
226
  kind,
220
227
  name,
221
228
  spec,
222
- version: resolved.range
229
+ version: range
223
230
  });
224
- else dependentMap.set(id, [{
231
+ else dependentMap.set(resolved.id, [{
225
232
  dependent: pkg,
226
233
  kind,
227
234
  name,
228
235
  spec,
229
- version: resolved.range
236
+ version: range
230
237
  }]);
231
238
  }
232
239
  return {
@@ -235,11 +242,10 @@ function depsPolicy({ graph, cargo }, getBumpDepType = ({ kind }) => {
235
242
  if (!(pkg instanceof CargoPackage)) return;
236
243
  const deps = dependentMap.get(pkg.id);
237
244
  if (!deps) return;
238
- const group = graph.getPackageGroup(pkg.id);
239
245
  const bumped = plan.bumpVersion(pkg);
240
246
  if (!bumped) return;
241
247
  for (const dep of deps) {
242
- if (group?.options.syncBump && graph.getPackageGroup(dep.dependent.id) === group) continue;
248
+ if (pkg.group?.options.syncBump && dep.dependent.group === pkg.group) continue;
243
249
  if (dep.version && semver$1.satisfies(bumped, dep.version)) continue;
244
250
  const bumpType = getBumpDepType(dep);
245
251
  if (bumpType === false) continue;
@@ -261,11 +267,7 @@ async function buildEntry(dir) {
261
267
  try {
262
268
  const filePath = path.join(dir, "Cargo.toml");
263
269
  const content = await readFile(filePath, "utf8");
264
- return {
265
- path: filePath,
266
- data: cargoManifestSchema.parse(parse$1(content)),
267
- content
268
- };
270
+ return new CargoToml(filePath, content, cargoManifestSchema.parse(parse$1(content)));
269
271
  } catch {
270
272
  return;
271
273
  }
@@ -277,21 +279,23 @@ async function resolveCargoGraph(cwd) {
277
279
  };
278
280
  const root = await buildEntry(cwd);
279
281
  if (!root) return out;
280
- const rootWorkspace = root.data.workspace;
281
282
  out.files.set(root.path, root);
282
283
  if (root.data.package) {
283
- const pkg = new CargoPackage(cwd, root, rootWorkspace ? root : void 0);
284
+ const pkg = new CargoPackage(cwd, root);
284
285
  out.packages.set(pkg.name, pkg);
285
286
  }
286
- if (!rootWorkspace || !rootWorkspace.members) return out;
287
- const dirs = await expandWorkspaceMembers(cwd, rootWorkspace.members, rootWorkspace.exclude);
288
- await Promise.all(dirs.map(async (dir) => {
289
- const entry = await buildEntry(dir);
290
- if (!entry || !entry.data.package) return;
291
- const pkg = new CargoPackage(dir, entry, root);
292
- out.files.set(entry.path, entry);
293
- out.packages.set(pkg.name, pkg);
294
- }));
287
+ if (root.data.workspace?.members) {
288
+ root.workspace = root;
289
+ const dirs = await expandWorkspaceMembers(cwd, root.data.workspace.members, root.data.workspace.exclude);
290
+ await Promise.all(dirs.map(async (dir) => {
291
+ const entry = await buildEntry(dir);
292
+ if (!entry || !entry.data.package) return;
293
+ entry.workspace = root;
294
+ const pkg = new CargoPackage(dir, entry);
295
+ out.files.set(entry.path, entry);
296
+ out.packages.set(pkg.name, pkg);
297
+ }));
298
+ }
295
299
  return out;
296
300
  }
297
301
  async function expandWorkspaceMembers(cwd, members, exclude = []) {
@@ -307,41 +311,41 @@ async function expandWorkspaceMembers(cwd, members, exclude = []) {
307
311
  return item.endsWith(path.sep) ? item.slice(0, -1) : item;
308
312
  });
309
313
  }
310
- function dependencyTables(manifest, prefix = []) {
311
- const tables = [];
312
- for (const field of DEP_FIELDS) {
313
- const table = manifest[field];
314
- if (!table) continue;
315
- tables.push({
316
- table,
317
- tablePath: [...prefix, field]
318
- });
319
- }
320
- const target = manifest.target;
321
- if (target) for (const [targetKey, targetConfig] of Object.entries(target)) for (const field of DEP_FIELDS) {
322
- const table = targetConfig[field];
323
- if (!table) continue;
324
- tables.push({
325
- table,
326
- tablePath: [
327
- ...prefix,
328
- "target",
329
- targetKey,
330
- field
331
- ]
332
- });
314
+ function listDependencies(graph, file) {
315
+ const out = [];
316
+ function scan(obj, prefix = []) {
317
+ for (const field of DEP_FIELDS) {
318
+ const table = obj[field];
319
+ if (!table) continue;
320
+ const tablePath = [...prefix, field];
321
+ for (const [key, spec] of Object.entries(table)) {
322
+ const { linked, range, setRange } = resolveLinkedDep(file, graph, tablePath, key, spec) ?? {};
323
+ out.push({
324
+ path: [...tablePath, key],
325
+ spec,
326
+ resolved: linked,
327
+ range,
328
+ setRange: setRange && ((v) => {
329
+ table[key] = setRange(v);
330
+ })
331
+ });
332
+ }
333
+ }
333
334
  }
334
- return tables;
335
+ scan(file.data);
336
+ if (file.data.target) for (const [key, config] of Object.entries(file.data.target)) scan(config, ["target", key]);
337
+ if (file.data.workspace) scan(file.data.workspace);
338
+ return out;
335
339
  }
336
- function resolveLinkedDep(workspaceFile, file, graph, tablePath, rawName, spec) {
340
+ function resolveLinkedDep(file, graph, tablePath, key, spec) {
337
341
  if (typeof spec === "string") {
338
- const linked = graph.packages.get(rawName);
342
+ const linked = graph.packages.get(key);
339
343
  if (!linked) return;
340
344
  return {
341
345
  linked,
342
346
  range: spec,
343
347
  setRange(v) {
344
- patchFile(file, [...tablePath, rawName].join("."), v);
348
+ file.patch([...tablePath, key].join("."), v);
345
349
  return v;
346
350
  }
347
351
  };
@@ -349,17 +353,12 @@ function resolveLinkedDep(workspaceFile, file, graph, tablePath, rawName, spec)
349
353
  if ("git" in spec) return;
350
354
  if ("workspace" in spec) {
351
355
  const kind = tablePath[tablePath.length - 1];
352
- const entry = workspaceFile?.data.workspace?.[kind]?.[rawName];
356
+ const entry = file.workspace?.data.workspace?.[kind]?.[key];
353
357
  if (!entry) return;
354
- const resolved = resolveLinkedDep(void 0, workspaceFile, graph, ["workspace", kind], rawName, entry);
355
- if (!resolved || !resolved.setRange) return resolved;
356
- return {
357
- ...resolved,
358
- setRange(v) {
359
- workspaceFile.data.workspace[kind][rawName] = resolved.setRange(v);
360
- return spec;
361
- }
362
- };
358
+ const resolved = resolveLinkedDep(file.workspace, graph, ["workspace", kind], key, entry);
359
+ if (!resolved) return;
360
+ delete resolved.setRange;
361
+ return resolved;
363
362
  }
364
363
  if ("path" in spec) {
365
364
  const pkgPath = path.resolve(path.dirname(file.path), spec.path);
@@ -369,9 +368,9 @@ function resolveLinkedDep(workspaceFile, file, graph, tablePath, rawName, spec)
369
368
  linked: pkg,
370
369
  range: spec.version,
371
370
  setRange(v) {
372
- patchFile(file, [
371
+ file.patch([
373
372
  ...tablePath,
374
- rawName,
373
+ key,
375
374
  "version"
376
375
  ].join("."), v);
377
376
  return {
@@ -383,15 +382,15 @@ function resolveLinkedDep(workspaceFile, file, graph, tablePath, rawName, spec)
383
382
  }
384
383
  return;
385
384
  }
386
- const linked = graph.packages.get(spec.package ?? rawName);
385
+ const linked = graph.packages.get(spec.package ?? key);
387
386
  if (!linked) return;
388
387
  return {
389
388
  linked,
390
389
  range: spec.version,
391
390
  setRange(v) {
392
- patchFile(file, [
391
+ file.patch([
393
392
  ...tablePath,
394
- rawName,
393
+ key,
395
394
  "version"
396
395
  ].join("."), v);
397
396
  return {
@@ -1,4 +1,4 @@
1
- import { s as TegamiPlugin } from "../types-DHddSAez.js";
1
+ import { s as TegamiPlugin } from "../types-BoQR7Hlg.js";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
@@ -43,9 +43,8 @@ function git(options = {}) {
43
43
  const { graph } = this;
44
44
  for (const [id, packagePlan] of plan.packages) {
45
45
  const pkg = graph.get(id);
46
- const group = graph.getPackageGroup(pkg.id);
47
46
  packagePlan.git ??= {};
48
- if (group?.options.syncGitTag && pkg.version) packagePlan.git.tag = `${group.name}@${pkg.version}`;
47
+ if (pkg.group?.options.syncGitTag && pkg.version) packagePlan.git.tag = `${pkg.group.name}@${pkg.version}`;
49
48
  else if (pkg.version) packagePlan.git.tag = `${pkg.name}@${pkg.version}`;
50
49
  }
51
50
  },
@@ -1,4 +1,4 @@
1
- import { O as WorkspacePackage, k as Draft, s as TegamiPlugin, t as Awaitable, x as TegamiContext, y as PublishPlan } from "../types-DHddSAez.js";
1
+ import { O as WorkspacePackage, k as Draft, s as TegamiPlugin, t as Awaitable, x as TegamiContext, y as PublishPlan } from "../types-BoQR7Hlg.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
3
 
4
4
  //#region src/plugins/github.d.ts
@@ -1,7 +1,7 @@
1
1
  import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-EKJ8yK5U.js";
2
2
  import { t as changelogFilename } from "../generate-Rvz4Lu98.js";
3
3
  import { a as cached, n as execFailure, o as isCI } from "../error-BhMYq9iW.js";
4
- import { n as createDraft, o as readChangelogEntries } from "../draft-BqHcSCeX.js";
4
+ import { n as createDraft, o as readChangelogEntries } from "../draft-BLbt4bSG.js";
5
5
  import { git } from "./git.js";
6
6
  import { n as createVersionRequestBody, r as hasGitChanges, t as commitVersionBranchChanges } from "../version-request-oxy16TJ1.js";
7
7
  import { readFile, writeFile } from "node:fs/promises";
@@ -1,4 +1,4 @@
1
- import { O as WorkspacePackage, k as Draft, s as TegamiPlugin, t as Awaitable, x as TegamiContext, y as PublishPlan } from "../types-DHddSAez.js";
1
+ import { O as WorkspacePackage, k as Draft, s as TegamiPlugin, t as Awaitable, x as TegamiContext, y as PublishPlan } from "../types-BoQR7Hlg.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
3
 
4
4
  //#region src/plugins/gitlab.d.ts
@@ -1,7 +1,7 @@
1
1
  import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-EKJ8yK5U.js";
2
2
  import { t as changelogFilename } from "../generate-Rvz4Lu98.js";
3
3
  import { a as cached, n as execFailure, o as isCI, s as joinPath } from "../error-BhMYq9iW.js";
4
- import { n as createDraft, o as readChangelogEntries } from "../draft-BqHcSCeX.js";
4
+ import { n as createDraft, o as readChangelogEntries } from "../draft-BLbt4bSG.js";
5
5
  import { git } from "./git.js";
6
6
  import { n as createVersionRequestBody, r as hasGitChanges, t as commitVersionBranchChanges } from "../version-request-oxy16TJ1.js";
7
7
  import { readFile, writeFile } from "node:fs/promises";
@@ -1,4 +1,4 @@
1
- import { M as BumpType, O as WorkspacePackage, s as TegamiPlugin } from "../types-DHddSAez.js";
1
+ import { M as BumpType, O as WorkspacePackage, s as TegamiPlugin } from "../types-BoQR7Hlg.js";
2
2
 
3
3
  //#region src/plugins/go.d.ts
4
4
  interface GoModFile {
@@ -1,5 +1,5 @@
1
1
  import { i as isNodeError, n as execFailure } from "../error-BhMYq9iW.js";
2
- import { n as WorkspacePackage } from "../graph-gThXu8Cz.js";
2
+ import { n as WorkspacePackage } from "../graph-BmXTJZxx.js";
3
3
  import { relative, resolve } from "node:path";
4
4
  import { x } from "tinyexec";
5
5
  import * as semver$1 from "semver";
@@ -135,7 +135,7 @@ function go({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
135
135
  },
136
136
  async publishPreflight({ pkg }) {
137
137
  if (!(pkg instanceof GoPackage)) return;
138
- const shouldPublish = pkg.getPackageOptions().go?.publish ?? this.graph.getPackageGroup(pkg.id)?.options?.go?.publish ?? true;
138
+ const shouldPublish = pkg.options.go?.publish ?? pkg.group?.options?.go?.publish ?? true;
139
139
  const wait = [];
140
140
  for (const [moduleName] of pkg.mod.requires) {
141
141
  const linked = this.graph.get(`go:${moduleName}`);
@@ -205,11 +205,10 @@ function depsPolicy({ graph }, getBumpDepType = () => "patch") {
205
205
  if (!(pkg instanceof GoPackage)) return;
206
206
  const deps = dependentMap.get(pkg.id);
207
207
  if (!deps) return;
208
- const group = graph.getPackageGroup(pkg.id);
209
208
  const bumped = plan.bumpVersion(pkg);
210
209
  if (!bumped) return;
211
210
  for (const dep of deps) {
212
- if (group?.options.syncBump && graph.getPackageGroup(dep.dependent.id) === group) continue;
211
+ if (pkg.group?.options.syncBump && dep.dependent.group === pkg.group) continue;
213
212
  if (semver$1.satisfies(bumped, stripGoVersion(dep.version))) continue;
214
213
  const bumpType = getBumpDepType?.(dep);
215
214
  if (bumpType === false) continue;
@@ -1,2 +1,2 @@
1
- import { d as npm, l as NpmPackage, u as NpmPluginOptions } from "../types-DHddSAez.js";
1
+ import { d as npm, l as NpmPackage, u as NpmPluginOptions } from "../types-BoQR7Hlg.js";
2
2
  export { NpmPackage, NpmPluginOptions, npm };
@@ -1,2 +1,2 @@
1
- import { n as npm, t as NpmPackage } from "../npm-5cG02krT.js";
1
+ import { n as npm, t as NpmPackage } from "../npm-Cj685Ddn.js";
2
2
  export { NpmPackage, npm };
@@ -101,22 +101,31 @@ declare abstract class WorkspacePackage {
101
101
  abstract readonly path: string;
102
102
  abstract readonly manager: string;
103
103
  abstract readonly version: string | undefined;
104
- get id(): string;
105
- private opts;
106
104
  /** note: this will only be available after package graph is resolved */
107
- getPackageOptions(): PackageOptions;
108
- setPackageOptions(options: PackageOptions): void;
105
+ group?: PackageGroup;
106
+ /** note: this will only be available after package graph is resolved */
107
+ options: PackageOptions;
108
+ get id(): string;
109
109
  /** create the initial draft. */
110
110
  initDraft(): PackageDraft;
111
111
  /** configure an initial draft to match script-level configs. */
112
- configureDraft(draft: PackageDraft, group?: PackageGroup): void;
112
+ configureDraft({
113
+ draft
114
+ }: {
115
+ draft: PackageDraft;
116
+ }): void;
113
117
  }
114
118
  interface PackageGroup {
115
119
  name: string;
116
120
  options: GroupOptions;
117
121
  packages: WorkspacePackage[];
118
122
  }
119
- /** Dependency graph for discovered workspace packages. */
123
+ /**
124
+ * Unified graph for discovered workspace packages.
125
+ *
126
+ * This is only used as a storage for all indexed packages.
127
+ * For registry-specific relationships (e.g. virtual workspaces), they are stored in the provider plugin internally.
128
+ */
120
129
  declare class PackageGraph {
121
130
  private readonly packages;
122
131
  private readonly groups;
@@ -484,28 +493,40 @@ type CargoManifest = z.infer<typeof cargoManifestSchema>;
484
493
  //#endregion
485
494
  //#region src/plugins/cargo.d.ts
486
495
  declare const DEP_FIELDS$1: readonly ["dependencies", "dev-dependencies", "build-dependencies"];
487
- interface CargoToml<Data extends CargoManifest = CargoManifest> {
496
+ type DepKind = (typeof DEP_FIELDS$1)[number];
497
+ declare class CargoToml<Data extends CargoManifest = CargoManifest> {
488
498
  path: string;
489
499
  content: string;
490
500
  data: Data;
501
+ private dependencies;
502
+ workspace?: CargoToml<RequireFields<CargoManifest, "workspace">>;
503
+ constructor(path: string, content: string, data: Data);
504
+ listDependencies(graph: CargoGraph): ResolvedDependency[];
505
+ patch(path: string, value: unknown): void;
506
+ }
507
+ interface ResolvedDependency {
508
+ path: [...string[], kind: DepKind, key: string];
509
+ spec: CargoDependency;
510
+ resolved?: CargoPackage;
511
+ range?: string;
512
+ setRange?: (v: string) => void;
491
513
  }
492
514
  declare class CargoPackage extends WorkspacePackage {
493
515
  readonly path: string;
494
516
  /** a crate must have `package` field defined, otherwise it is merely a virutal workspace file, and Tegami should not include it. */
495
517
  readonly file: CargoToml<RequireFields<CargoManifest, "package">>;
496
- readonly workspaceFile?: CargoToml<RequireFields<CargoManifest, "workspace">> | undefined;
497
518
  readonly manager = "cargo";
498
519
  readonly manifest: RequireFields<CargoManifest, "package">;
499
520
  constructor(path: string, /** a crate must have `package` field defined, otherwise it is merely a virutal workspace file, and Tegami should not include it. */
500
521
 
501
- file: CargoToml<RequireFields<CargoManifest, "package">>, workspaceFile?: CargoToml<RequireFields<CargoManifest, "workspace">> | undefined);
522
+ file: CargoToml<RequireFields<CargoManifest, "package">>);
502
523
  get name(): string;
503
524
  get version(): string;
504
525
  setVersion(version: string): void;
505
526
  }
506
527
  interface DependentRef$1 {
507
528
  dependent: CargoPackage;
508
- kind: (typeof DEP_FIELDS$1)[number];
529
+ kind: DepKind;
509
530
  name: string;
510
531
  spec: CargoDependency;
511
532
  version?: string;
@@ -751,7 +772,11 @@ declare class NpmPackage extends WorkspacePackage {
751
772
  write(): Promise<void>;
752
773
  initDraft(): PackageDraft;
753
774
  getRegistry(): string;
754
- configureDraft(draft: PackageDraft, group?: PackageGroup): void;
775
+ configureDraft({
776
+ draft
777
+ }: {
778
+ draft: PackageDraft;
779
+ }): void;
755
780
  }
756
781
  type DependencySpec = {
757
782
  protocol: "npm";
@@ -3,4 +3,8 @@ import { Result } from "tinyexec";
3
3
  //#region src/utils/error.d.ts
4
4
  declare function execFailure(context: string, result: Awaited<Result>): Error;
5
5
  //#endregion
6
- export { execFailure };
6
+ //#region src/utils/common.d.ts
7
+ declare const isCI: () => boolean;
8
+ declare function joinPath(...paths: string[]): string;
9
+ //#endregion
10
+ export { execFailure, isCI, joinPath };
@@ -1,2 +1,2 @@
1
- import { n as execFailure } from "../error-BhMYq9iW.js";
2
- export { execFailure };
1
+ import { n as execFailure, o as isCI, s as joinPath } from "../error-BhMYq9iW.js";
2
+ export { execFailure, isCI, joinPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Utility for package versioning & publish",
5
5
  "license": "MIT",
6
6
  "author": "Fuma Nama",