tegami 0.2.0 → 1.0.0-beta.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.
@@ -0,0 +1,291 @@
1
+ import { i as isNodeError, n as execFailure } from "../error-DNy8R5ue.js";
2
+ import { n as WorkspacePackage } from "../graph-OnX9ncdQ.js";
3
+ import { relative, resolve } from "node:path";
4
+ import { x } from "tinyexec";
5
+ import * as semver from "semver";
6
+ import z from "zod";
7
+ //#region src/plugins/go.ts
8
+ const goWorkJsonSchema = z.object({ Use: z.array(z.object({
9
+ DiskPath: z.string(),
10
+ ModulePath: z.string().optional()
11
+ })).optional() });
12
+ const goModJsonSchema = z.object({
13
+ Module: z.object({ Path: z.string() }),
14
+ Require: z.array(z.object({
15
+ Path: z.string(),
16
+ Version: z.string().optional()
17
+ })).optional(),
18
+ Replace: z.array(z.object({
19
+ Old: z.object({
20
+ Path: z.string(),
21
+ Version: z.string().optional()
22
+ }),
23
+ New: z.object({
24
+ Path: z.string(),
25
+ Version: z.string().optional()
26
+ })
27
+ })).optional()
28
+ });
29
+ var GoPackage = class extends WorkspacePackage {
30
+ path;
31
+ mod;
32
+ manager = "go";
33
+ versionValue;
34
+ pendingRequires = /* @__PURE__ */ new Map();
35
+ constructor(path, mod, version) {
36
+ super();
37
+ this.path = path;
38
+ this.mod = mod;
39
+ this.versionValue = version;
40
+ }
41
+ get name() {
42
+ return this.mod.module;
43
+ }
44
+ get version() {
45
+ return this.versionValue;
46
+ }
47
+ setVersion(version) {
48
+ this.versionValue = version;
49
+ }
50
+ setRequire(module, version) {
51
+ const formatted = formatGoVersion(version);
52
+ this.mod.requires.set(module, formatted);
53
+ this.pendingRequires.set(module, formatted);
54
+ }
55
+ async write() {
56
+ if (this.pendingRequires.size === 0) return;
57
+ const args = ["mod", "edit"];
58
+ for (const [module, version] of this.pendingRequires) args.push(`-require=${module}@${version}`);
59
+ const result = await x("go", args, { nodeOptions: { cwd: this.path } });
60
+ if (result.exitCode !== 0) throw execFailure(`Failed to update go.mod requires in ${this.path}.`, result);
61
+ this.pendingRequires.clear();
62
+ }
63
+ };
64
+ const packageLockSchema = z.object({
65
+ id: z.string(),
66
+ version: z.string()
67
+ });
68
+ /**
69
+ * Experimental plugin for Golang, the release flow of Golang is pretty special, there's some exceptions for it:
70
+ *
71
+ * - Version is stored in lock file, normally, it should prefer to store versions in a file like `package.json` & `Cargo.toml`, but for Golang, there is no such file.
72
+ * - Publishing is handed to Git plugin, because Golang uses Git tag for publishing.
73
+ */
74
+ function go({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
75
+ let active = false;
76
+ return {
77
+ name: "go",
78
+ enforce: "post",
79
+ async resolve() {
80
+ await discoverGoPackages(this.cwd, (pkg) => this.graph.add(pkg));
81
+ active = this.graph.getPackages().some((pkg) => pkg instanceof GoPackage);
82
+ if (active && !this.plugins.some((plugin) => plugin.name === "git")) throw new Error("The go plugin requires the git plugin. Add git() from \"tegami/plugins/git\" to your plugins array.");
83
+ },
84
+ initDraft(plan) {
85
+ if (!active) return;
86
+ plan.addPolicy(depsPolicy(this, getBumpDepType));
87
+ },
88
+ async applyDraft(draft) {
89
+ if (!active) return;
90
+ const { graph } = this;
91
+ const writes = [];
92
+ for (const pkg of graph.getPackages()) {
93
+ if (!(pkg instanceof GoPackage)) continue;
94
+ const plan = draft.getPackageDraft(pkg.id);
95
+ if (plan) pkg.setVersion(plan.bumpVersion(pkg));
96
+ }
97
+ for (const pkg of graph.getPackages()) {
98
+ if (!(pkg instanceof GoPackage)) continue;
99
+ for (const [moduleName, requireVersion] of pkg.mod.requires) {
100
+ const linked = graph.get(`go:${moduleName}`);
101
+ if (!linked || !(linked instanceof GoPackage)) continue;
102
+ if (semver.satisfies(linked.version, stripGoVersion(requireVersion))) continue;
103
+ pkg.setRequire(moduleName, linked.version);
104
+ }
105
+ writes.push(pkg.write());
106
+ }
107
+ await Promise.all(writes);
108
+ },
109
+ initPublishLock({ lock, draft }) {
110
+ if (!active) return;
111
+ for (const [id, packageDraft] of draft.getPackageDrafts()) {
112
+ const pkg = this.graph.get(id);
113
+ if (!(pkg instanceof GoPackage) || !packageDraft.type) continue;
114
+ lock.write("go:packages", {
115
+ id,
116
+ version: pkg.version
117
+ });
118
+ }
119
+ },
120
+ initPublishPlan({ lock, plan }) {
121
+ if (!active) return;
122
+ let data;
123
+ while (data = lock.read("go:packages")) {
124
+ const parsed = packageLockSchema.safeParse(data).data;
125
+ if (!parsed) continue;
126
+ const pkg = this.graph.get(parsed.id);
127
+ if (pkg instanceof GoPackage) pkg.setVersion(parsed.version);
128
+ }
129
+ for (const [id, packagePlan] of plan.packages) {
130
+ const pkg = this.graph.get(id);
131
+ if (!(pkg instanceof GoPackage)) continue;
132
+ packagePlan.git = { tag: formatGoTag(this.cwd, pkg.path, pkg.version) };
133
+ }
134
+ },
135
+ async publishPreflight({ pkg }) {
136
+ if (!(pkg instanceof GoPackage)) return;
137
+ const wait = [];
138
+ for (const [moduleName] of pkg.mod.requires) {
139
+ const linked = this.graph.get(`go:${moduleName}`);
140
+ if (linked instanceof GoPackage) wait.push(linked.id);
141
+ }
142
+ for (const replace of pkg.mod.replaces.values()) {
143
+ if (!replace.path) continue;
144
+ const linked = findLocalModule(this.graph, pkg.path, replace.path);
145
+ if (!linked) continue;
146
+ wait.push(linked.id);
147
+ }
148
+ return {
149
+ publish: !await isModulePublished(pkg.name, pkg.version),
150
+ wait
151
+ };
152
+ },
153
+ async publish({ pkg }) {
154
+ if (!(pkg instanceof GoPackage)) return;
155
+ return { type: "published" };
156
+ },
157
+ cli: { async draftApplied() {
158
+ if (!active || !updateLockFile) return;
159
+ if (await listGoWorkUsePaths(this.cwd)) {
160
+ const result = await x("go", ["work", "sync"], { nodeOptions: { cwd: this.cwd } });
161
+ if (result.exitCode !== 0) throw execFailure("Failed to run `go work sync`.", result);
162
+ return;
163
+ }
164
+ await Promise.all(this.graph.getPackages().map(async (pkg) => {
165
+ if (!(pkg instanceof GoPackage)) return;
166
+ const result = await x("go", ["mod", "tidy"], { nodeOptions: { cwd: pkg.path } });
167
+ if (result.exitCode !== 0) throw execFailure(`Failed to run \`go mod tidy\` in ${pkg.path}.`, result);
168
+ }));
169
+ } }
170
+ };
171
+ }
172
+ function depsPolicy({ graph }, getBumpDepType = () => "patch") {
173
+ return {
174
+ id: "go:deps",
175
+ onUpdate({ pkg, packageDraft: plan }) {
176
+ if (!(pkg instanceof GoPackage)) return;
177
+ const group = graph.getPackageGroup(pkg.id);
178
+ for (const dependent of graph.getPackages()) {
179
+ if (!(dependent instanceof GoPackage)) continue;
180
+ for (const [moduleName, requireVersion] of dependent.mod.requires) {
181
+ if (pkg.id !== `go:${moduleName}`) continue;
182
+ if (group?.options.syncBump && graph.getPackageGroup(dependent.id) === group) continue;
183
+ if (semver.satisfies(plan.bumpVersion(pkg), stripGoVersion(requireVersion))) continue;
184
+ const bumpType = getBumpDepType?.({
185
+ name: pkg.name,
186
+ dependent,
187
+ version: requireVersion
188
+ });
189
+ if (bumpType === false) continue;
190
+ this.bumpPackage(dependent, {
191
+ type: bumpType,
192
+ reason: `update require "${moduleName}"`
193
+ });
194
+ }
195
+ }
196
+ }
197
+ };
198
+ }
199
+ async function discoverGoPackages(cwd, add) {
200
+ const modulePaths = await listModulePaths(cwd);
201
+ await Promise.all(modulePaths.map(async (modulePath) => {
202
+ const mod = await readGoMod(modulePath).catch((error) => {
203
+ if (isNodeError(error) && error.code === "ENOENT") return void 0;
204
+ throw error;
205
+ });
206
+ if (!mod) return;
207
+ add(new GoPackage(modulePath, mod, await readLatestVersion(cwd, modulePath)));
208
+ }));
209
+ }
210
+ async function listModulePaths(cwd) {
211
+ const workPaths = await listGoWorkUsePaths(cwd);
212
+ if (workPaths) return workPaths;
213
+ if (await readGoMod(cwd)) return [cwd];
214
+ return [];
215
+ }
216
+ async function listGoWorkUsePaths(cwd) {
217
+ const result = await x("go", [
218
+ "work",
219
+ "edit",
220
+ "-json"
221
+ ], { nodeOptions: { cwd } });
222
+ if (result.exitCode !== 0) return void 0;
223
+ const data = goWorkJsonSchema.safeParse(JSON.parse(result.stdout)).data;
224
+ if (!data?.Use?.length) return [cwd];
225
+ return data.Use.map((use) => resolve(cwd, use.DiskPath));
226
+ }
227
+ async function readGoMod(path) {
228
+ const result = await x("go", [
229
+ "mod",
230
+ "edit",
231
+ "-json"
232
+ ], { nodeOptions: { cwd: path } });
233
+ if (result.exitCode !== 0) return;
234
+ const data = goModJsonSchema.safeParse(JSON.parse(result.stdout)).data;
235
+ if (!data) return;
236
+ const requires = /* @__PURE__ */ new Map();
237
+ for (const req of data.Require ?? []) if (req.Version) requires.set(req.Path, req.Version);
238
+ const replaces = /* @__PURE__ */ new Map();
239
+ for (const rep of data.Replace ?? []) replaces.set(rep.Old.Path, {
240
+ module: rep.New.Path,
241
+ path: rep.New.Version ? void 0 : rep.New.Path,
242
+ version: rep.New.Version
243
+ });
244
+ return {
245
+ module: data.Module.Path,
246
+ requires,
247
+ replaces
248
+ };
249
+ }
250
+ function findLocalModule(graph, modulePath, replacePath) {
251
+ const absolute = resolve(modulePath, replacePath);
252
+ return graph.getPackages().find((pkg) => pkg instanceof GoPackage && pkg.path === absolute);
253
+ }
254
+ async function readLatestVersion(cwd, modulePath) {
255
+ const result = await x("git", [
256
+ "tag",
257
+ "--list",
258
+ formatGoTag(cwd, modulePath, "v*"),
259
+ "--sort=-v:refname"
260
+ ], { nodeOptions: { cwd } });
261
+ if (result.exitCode !== 0) return "0.0.0";
262
+ for (const tag of result.stdout.split("\n")) {
263
+ const version = parseTagVersion(tag.trim());
264
+ if (version) return version;
265
+ }
266
+ return "0.0.0";
267
+ }
268
+ function parseTagVersion(tag) {
269
+ const version = stripGoVersion(tag.slice(tag.lastIndexOf("/") + 1));
270
+ if (semver.valid(version)) return version;
271
+ }
272
+ function formatGoTag(cwd, modulePath, version) {
273
+ const relativeDir = relative(cwd, modulePath).replaceAll("\\", "/");
274
+ if (relativeDir === "") return formatGoVersion(version);
275
+ return `${relativeDir}/${formatGoVersion(version)}`;
276
+ }
277
+ function formatGoVersion(version) {
278
+ return version.startsWith("v") ? version : `v${version}`;
279
+ }
280
+ function stripGoVersion(version) {
281
+ return version.startsWith("v") ? version.slice(1) : version;
282
+ }
283
+ async function isModulePublished(module, version) {
284
+ const formatted = formatGoVersion(version);
285
+ const response = await fetch(`https://proxy.golang.org/${encodeURIComponent(module)}/@v/${formatted}.info`);
286
+ if (response.status === 200) return true;
287
+ if (response.status === 404) return false;
288
+ throw new Error(`Unable to validate ${module}@${formatted} against proxy.golang.org: ${await response.text()}`);
289
+ }
290
+ //#endregion
291
+ export { GoPackage, go };
@@ -1,2 +1,2 @@
1
- import { d as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-CurHqnWl.js";
1
+ import { g as cargo, h as CargoPluginOptions, m as CargoPackage } from "../types-DnCUr2dB.js";
2
2
  export { CargoPackage, CargoPluginOptions, cargo };
@@ -1,5 +1,5 @@
1
1
  import { i as isNodeError, n as execFailure } from "../error-DNy8R5ue.js";
2
- import { n as WorkspacePackage } from "../graph-DrzluXw8.js";
2
+ import { n as WorkspacePackage } from "../graph-OnX9ncdQ.js";
3
3
  import { readFile, writeFile } from "node:fs/promises";
4
4
  import { join, normalize } from "node:path";
5
5
  import { x } from "tinyexec";
@@ -147,6 +147,7 @@ function depsPolicy({ graph }, getBumpDepType = ({ kind }) => {
147
147
  if (semver.satisfies(plan.bumpVersion(pkg), spec.version)) continue;
148
148
  const bumpType = getBumpDepType({
149
149
  kind,
150
+ dependent,
150
151
  name: pkg.name,
151
152
  version: spec.version
152
153
  });
@@ -185,10 +186,7 @@ async function discoverCargoPackages(cwd, add) {
185
186
  for (const entry of manifests) if (entry) addCargoPackage(entry.path, entry.manifest.manifest, entry.manifest.content, root.manifest, add);
186
187
  }
187
188
  function addCargoPackage(path, manifest, content, workspaceManifest, add) {
188
- const packageInfo = tableValue(manifest.package);
189
- const workspacePackage = tableValue(workspaceManifest.workspace)?.package;
190
- if (!packageInfo?.name) return;
191
- if (!packageInfo.version && !tableValue(workspacePackage)?.version) return;
189
+ if (!tableValue(manifest.package)?.name) return;
192
190
  add(new CargoPackage(path, manifest, content, workspaceManifest));
193
191
  }
194
192
  async function expandWorkspaceMembers(cwd, members, exclude) {
@@ -1,2 +1,2 @@
1
- import { f as NpmPackage, m as npm, p as NpmPluginOptions } from "../types-CurHqnWl.js";
1
+ import { _ as NpmPackage, v as NpmPluginOptions, y as npm } from "../types-DnCUr2dB.js";
2
2
  export { NpmPackage, NpmPluginOptions, npm };
@@ -1,317 +1,2 @@
1
- import { i as isNodeError, n as execFailure } from "../error-DNy8R5ue.js";
2
- import { n as packageManifestSchema, r as pnpmWorkspaceSchema } from "../schemas-B7N6EE2k.js";
3
- import { n as WorkspacePackage } from "../graph-DrzluXw8.js";
4
- import { readFile, writeFile } from "node:fs/promises";
5
- import path from "node:path";
6
- import { x } from "tinyexec";
7
- import * as semver from "semver";
8
- import z from "zod";
9
- import { load } from "js-yaml";
10
- import { glob } from "tinyglobby";
11
- import { detect } from "package-manager-detector";
12
- //#region src/providers/npm.ts
13
- const DEP_FIELDS = [
14
- "dependencies",
15
- "devDependencies",
16
- "peerDependencies",
17
- "optionalDependencies"
18
- ];
19
- var NpmPackage = class extends WorkspacePackage {
20
- path;
21
- manifest;
22
- manager = "npm";
23
- constructor(path, manifest) {
24
- super();
25
- this.path = path;
26
- this.manifest = manifest;
27
- }
28
- get name() {
29
- return this.manifest.name;
30
- }
31
- get version() {
32
- return this.manifest.version ?? "0.0.0";
33
- }
34
- async write() {
35
- await writeFile(path.join(this.path, "package.json"), `${JSON.stringify(this.manifest, null, 2)}\n`);
36
- }
37
- initDraft() {
38
- const defaults = super.initDraft();
39
- if (this.manifest.publishConfig?.tag) {
40
- defaults.npm ??= {};
41
- defaults.npm.distTag ??= this.manifest.publishConfig.tag;
42
- }
43
- return defaults;
44
- }
45
- };
46
- function parseDependencySpec(context, dependent, name, range) {
47
- const { graph } = context;
48
- if (range.startsWith("workspace:")) return {
49
- range: range.slice(10),
50
- linked: graph.get(`npm:${name}`),
51
- protocol: "workspace"
52
- };
53
- if (range.startsWith("file:")) {
54
- let target = path.resolve(dependent.path, range.slice(5));
55
- if (path.basename(target) === "package.json") target = path.dirname(target);
56
- return {
57
- protocol: "file",
58
- raw: range,
59
- linked: graph.getPackages().find((pkg) => pkg instanceof NpmPackage && pkg.path === target)
60
- };
61
- }
62
- if (range.startsWith("npm:")) {
63
- const spec = range.slice(4);
64
- const separator = spec.lastIndexOf("@");
65
- if (separator <= 0) return;
66
- const alias = spec.slice(0, separator);
67
- return {
68
- alias,
69
- linked: graph.get(`npm:${alias}`),
70
- range: spec.slice(separator + 1),
71
- protocol: "npm"
72
- };
73
- }
74
- return {
75
- linked: graph.get(`npm:${name}`),
76
- range
77
- };
78
- }
79
- function formatDependencySpec(spec) {
80
- if (spec.protocol === "workspace") return `workspace:${spec.range}`;
81
- if (spec.protocol === "file") return spec.raw;
82
- if (spec.protocol === "npm") return `npm:${spec.alias}@${spec.range}`;
83
- return spec.range;
84
- }
85
- const packageLockSchema = z.object({
86
- id: z.string(),
87
- distTag: z.string().optional()
88
- });
89
- function npm({ client: defaultClient, onBreakPeerDep = "set", updateLockFile = true, bumpDep: getBumpDepType = ({ kind }) => {
90
- switch (kind) {
91
- case "dependencies":
92
- case "optionalDependencies": return "patch";
93
- case "devDependencies": return false;
94
- case "peerDependencies":
95
- if (onBreakPeerDep === "ignore") return false;
96
- return "major";
97
- }
98
- } } = {}) {
99
- let active = false;
100
- let client;
101
- return {
102
- name: "npm",
103
- enforce: "pre",
104
- async init() {
105
- if (defaultClient) client = defaultClient;
106
- else client = (await detect({ cwd: this.cwd }))?.name ?? "npm";
107
- this.npm = { client };
108
- },
109
- async resolve() {
110
- await discoverNpmPackages(this.cwd, (pkg) => this.graph.add(pkg));
111
- active = this.graph.getPackages().some((pkg) => pkg instanceof NpmPackage);
112
- },
113
- async publishPreflight({ pkg }) {
114
- if (!(pkg instanceof NpmPackage)) return;
115
- if (pkg.manifest.private === true) return { publish: false };
116
- const registry = pkg.manifest.publishConfig?.registry;
117
- const base = (registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
118
- const response = await fetch(`${base}/${pkg.name}/${pkg.version}`, { headers: { Accept: "application/json" } });
119
- if (response.status === 404) return { publish: true };
120
- if (!response.ok) throw new Error(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}.`);
121
- return { publish: false };
122
- },
123
- initPublishLock({ lock, draft }) {
124
- for (const [id, pkg] of draft.getPackageDrafts()) {
125
- if (!pkg.npm) continue;
126
- lock.write("npm:packages", {
127
- id,
128
- distTag: pkg.npm.distTag
129
- });
130
- }
131
- },
132
- initPublishPlan({ lock, plan }) {
133
- let data;
134
- while (data = lock.read("npm:packages")) {
135
- const parsed = packageLockSchema.safeParse(data).data;
136
- if (!parsed) continue;
137
- const packagePlan = plan.packages.get(parsed.id);
138
- if (!packagePlan) continue;
139
- packagePlan.npm = { distTag: parsed.distTag };
140
- }
141
- },
142
- async publish({ pkg, plan }) {
143
- if (!(pkg instanceof NpmPackage)) return;
144
- const distTag = plan.packages.get(pkg.id).npm?.distTag;
145
- if (client === "bun") {
146
- const tarballPath = path.resolve(pkg.path, "pkg.tgz");
147
- const packResult = await x("bun", [
148
- "pm",
149
- "pack",
150
- "--filename",
151
- tarballPath
152
- ], { nodeOptions: { cwd: pkg.path } });
153
- if (packResult.exitCode !== 0) return {
154
- type: "failed",
155
- error: execFailure(`Failed to pack ${pkg.name}@${pkg.version}.`, packResult).message
156
- };
157
- const publishArgs = ["publish", tarballPath];
158
- if (distTag) publishArgs.push("--tag", distTag);
159
- const publishResult = await x("npm", publishArgs, { nodeOptions: { cwd: pkg.path } });
160
- if (publishResult.exitCode !== 0) return {
161
- type: "failed",
162
- error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, publishResult).message
163
- };
164
- return { type: "published" };
165
- }
166
- let command;
167
- const args = ["publish"];
168
- if (distTag) args.push("--tag", distTag);
169
- if (client === "pnpm") {
170
- command = "pnpm";
171
- args.push("--no-git-checks");
172
- } else if (client === "yarn") command = "yarn";
173
- else command = "npm";
174
- const result = await x(command, args, { nodeOptions: { cwd: pkg.path } });
175
- if (result.exitCode !== 0) return {
176
- type: "failed",
177
- error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}${distTag ? ` with dist-tag "${distTag}"` : ""}.`, result).message
178
- };
179
- return { type: "published" };
180
- },
181
- initDraft(plan) {
182
- if (!active) return;
183
- plan.addPolicy(depsPolicy(this, getBumpDepType));
184
- },
185
- async applyDraft(draft) {
186
- if (!active) return;
187
- const { graph } = this;
188
- const writes = [];
189
- for (const pkg of graph.getPackages()) {
190
- if (!(pkg instanceof NpmPackage)) continue;
191
- const plan = draft.getPackageDraft(pkg.id);
192
- if (plan) pkg.manifest.version = plan.bumpVersion(pkg);
193
- }
194
- for (const pkg of graph.getPackages()) {
195
- if (!(pkg instanceof NpmPackage)) continue;
196
- for (const field of DEP_FIELDS) {
197
- const dependencies = pkg.manifest[field];
198
- if (!dependencies) continue;
199
- for (const [k, v] of Object.entries(dependencies)) {
200
- const spec = parseDependencySpec(this, pkg, k, v);
201
- if (!spec?.linked || spec.protocol === "workspace" || spec.protocol === "file") continue;
202
- if (!semver.validRange(spec.range)) continue;
203
- if (semver.satisfies(spec.linked.version, spec.range)) continue;
204
- let updatedRange;
205
- const isPeer = field === "peerDependencies";
206
- if (isPeer && onBreakPeerDep === "ignore") continue;
207
- else if (isPeer && onBreakPeerDep === "set") updatedRange = spec.linked.version;
208
- else if (isPeer && onBreakPeerDep === "error") throw new Error(`[Tegami] the version of "${spec.linked.name}" is beyond its peer dependency constraint "${v}" in package "${pkg.name}", please update the constraint to satisfy.`);
209
- else if (spec.range.startsWith("^")) updatedRange = `^${spec.linked.version}`;
210
- else if (spec.range.startsWith("~")) updatedRange = `~${spec.linked.version}`;
211
- else updatedRange = spec.linked.version;
212
- dependencies[k] = formatDependencySpec({
213
- ...spec,
214
- range: updatedRange
215
- });
216
- }
217
- }
218
- writes.push(pkg.write());
219
- }
220
- await Promise.all(writes);
221
- },
222
- cli: { async draftApplied() {
223
- if (!active || !updateLockFile) return;
224
- let args;
225
- if (client === "npm") args = ["ci"];
226
- else if (client === "yarn") args = ["install", "--immutable"];
227
- else if (client === "bun") args = ["install", "--frozen-lockfile"];
228
- else args = ["install", "--frozen-lockfile"];
229
- const result = await x(client, args, { nodeOptions: { cwd: this.cwd } });
230
- if (result.exitCode !== 0) throw execFailure("Failed to update lockfile.", result);
231
- } }
232
- };
233
- }
234
- function depsPolicy(context, getBumpDepType) {
235
- const { graph } = context;
236
- function needsUpdate(spec, target) {
237
- if (spec.linked && spec.protocol === "workspace") switch (spec.range) {
238
- case "":
239
- case "*": return true;
240
- case "^":
241
- case "~": return !semver.satisfies(target, `${spec.range}${spec.linked.version}`);
242
- }
243
- if (spec.linked && spec.protocol === "file") return true;
244
- if (spec.protocol === "file" || !semver.validRange(spec.range)) return false;
245
- return !semver.satisfies(target, spec.range);
246
- }
247
- return {
248
- id: "npm:deps",
249
- onUpdate({ pkg, packageDraft: plan }) {
250
- if (!(pkg instanceof NpmPackage)) return;
251
- const group = graph.getPackageGroup(pkg.id);
252
- for (const dependent of graph.getPackages()) {
253
- if (!(dependent instanceof NpmPackage)) continue;
254
- for (const field of DEP_FIELDS) {
255
- const dependencies = dependent.manifest[field];
256
- if (!dependencies) continue;
257
- for (const [k, v] of Object.entries(dependencies)) {
258
- const spec = parseDependencySpec(context, dependent, k, v);
259
- if (!spec || spec.linked !== pkg) continue;
260
- if (group?.options.syncBump && graph.getPackageGroup(dependent.id) === group) continue;
261
- if (!needsUpdate(spec, plan.bumpVersion(pkg))) continue;
262
- const bumpType = getBumpDepType({
263
- kind: field,
264
- spec,
265
- name: k
266
- });
267
- if (bumpType === false) continue;
268
- this.bumpPackage(dependent, {
269
- type: bumpType,
270
- reason: `update dependency "${k}"`
271
- });
272
- }
273
- }
274
- }
275
- }
276
- };
277
- }
278
- async function discoverNpmPackages(cwd, add) {
279
- let patterns;
280
- const rootManifest = await readManifest(cwd).catch(() => void 0);
281
- const pnpmPatterns = await readFile(path.join(cwd, "pnpm-workspace.yaml"), "utf8").then((content) => pnpmWorkspaceSchema.parse(load(content) ?? {})).catch((error) => {
282
- if (isNodeError(error) && error.code === "ENOENT") return void 0;
283
- throw error;
284
- });
285
- if (pnpmPatterns) patterns = pnpmPatterns.packages ?? [];
286
- else patterns = rootManifest?.workspaces ?? [];
287
- const candidatePaths = await expandWorkspacePatterns(cwd, patterns);
288
- const manifests = await Promise.all(candidatePaths.map((path) => readManifest(path).then((manifest) => ({
289
- path,
290
- manifest
291
- })).catch(() => void 0)));
292
- if (rootManifest?.version) add(new NpmPackage(cwd, rootManifest));
293
- for (const entry of manifests) {
294
- if (!entry?.manifest.version) continue;
295
- add(new NpmPackage(entry.path, entry.manifest));
296
- }
297
- }
298
- async function expandWorkspacePatterns(cwd, patterns) {
299
- if (patterns.length === 0) return [];
300
- return (await glob(patterns, {
301
- absolute: true,
302
- cwd,
303
- ignore: ["**/node_modules/**", "**/dist/**"],
304
- onlyDirectories: true,
305
- onlyFiles: false
306
- })).map((item) => {
307
- return item.endsWith(path.sep) ? item.slice(0, -1) : item;
308
- });
309
- }
310
- async function readManifest(packagePath) {
311
- const content = await readFile(path.join(packagePath, "package.json"), "utf8");
312
- const parsed = JSON.parse(content);
313
- packageManifestSchema.parse(parsed);
314
- return parsed;
315
- }
316
- //#endregion
1
+ import { n as npm, t as NpmPackage } from "../npm-Q0qvAkIu.js";
317
2
  export { NpmPackage, npm };
@@ -33,7 +33,8 @@ function bumpVersion(version, type, prerelease) {
33
33
  const parsed = parse(version);
34
34
  if (!parsed) next = null;
35
35
  else if (prerelease) {
36
- if (parsed.prerelease[0] === prerelease && type) next = inc(parsed, "prerelease", prerelease);
36
+ if (parsed.prerelease[0] === prerelease) next = type ? inc(parsed, "prerelease", prerelease) : version;
37
+ else if (parsed.prerelease[0]) next = inc(parsed, "prerelease", prerelease);
37
38
  else if (type) next = inc(parsed, PRE[type], prerelease);
38
39
  } else if (type) next = inc(parsed, type);
39
40
  else if (parsed.prerelease.length > 0) next = inc(parsed, "release");