rolldown-pnpm-config 0.3.0 → 0.4.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.
@@ -3,8 +3,8 @@ import { exportCommand } from "../cli/commands/export.js";
3
3
  import { previewCommand } from "../cli/commands/preview.js";
4
4
  import { upgradeCommand } from "../cli/commands/upgrade.js";
5
5
  import { Effect } from "effect";
6
- import { Command } from "@effect/cli";
7
- import { NodeContext, NodeRuntime } from "@effect/platform-node";
6
+ import { NodeRuntime, NodeServices } from "@effect/platform-node";
7
+ import { Command } from "effect/unstable/cli";
8
8
 
9
9
  //#region src/cli/bin.ts
10
10
  const root = Command.make("rolldown-pnpm-config").pipe(Command.withSubcommands([
@@ -12,10 +12,7 @@ const root = Command.make("rolldown-pnpm-config").pipe(Command.withSubcommands([
12
12
  exportCommand,
13
13
  previewCommand
14
14
  ]));
15
- Command.run(root, {
16
- name: "rolldown-pnpm-config",
17
- version: "0.3.0"
18
- })(process.argv).pipe(Effect.provide(NodeContext.layer), NodeRuntime.runMain);
15
+ Command.run(root, { version: "0.4.0" }).pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
19
16
 
20
17
  //#endregion
21
18
  export { };
@@ -16,7 +16,7 @@ import { overlayWorkspace } from "../workspace-overlay.js";
16
16
  import { Data, Effect, Option } from "effect";
17
17
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
18
18
  import { dirname, join, relative } from "node:path";
19
- import { Args, Command, Options } from "@effect/cli";
19
+ import { Argument, Command, Flag } from "effect/unstable/cli";
20
20
 
21
21
  //#region src/cli/commands/export.ts
22
22
  /**
@@ -110,9 +110,9 @@ function runExport(opts) {
110
110
  };
111
111
  });
112
112
  }
113
- const pathArg = Args.file({ name: "path" }).pipe(Args.optional);
114
- const dryRunFlag = Options.boolean("dry-run").pipe(Options.withDefault(false));
115
- const fullFlag = Options.boolean("full").pipe(Options.withDefault(false));
113
+ const pathArg = Argument.file("path").pipe(Argument.optional);
114
+ const dryRunFlag = Flag.boolean("dry-run").pipe(Flag.withDefault(false));
115
+ const fullFlag = Flag.boolean("full").pipe(Flag.withDefault(false));
116
116
  /**
117
117
  * The "export" command. Materializes the plugin config into pnpm-workspace.yaml.
118
118
  * An optional path argument overrides the auto-detected workspace file. --dry-run
@@ -11,7 +11,7 @@ import { runPreview } from "../ui/run-preview.js";
11
11
  import { Data, Effect, Option } from "effect";
12
12
  import { existsSync, readFileSync } from "node:fs";
13
13
  import { dirname, join } from "node:path";
14
- import { Args, Command } from "@effect/cli";
14
+ import { Argument, Command } from "effect/unstable/cli";
15
15
 
16
16
  //#region src/cli/commands/preview.ts
17
17
  /** Typed failure for the preview run. @internal */
@@ -48,7 +48,7 @@ function runPreviewViews(opts) {
48
48
  });
49
49
  });
50
50
  }
51
- const pathArg = Args.file({ name: "path" }).pipe(Args.optional);
51
+ const pathArg = Argument.file("path").pipe(Argument.optional);
52
52
  /**
53
53
  * The "preview" command: interactive ink-tab explorer of the export diff
54
54
  * (Changes / Full / Simulated). Falls back to printing the Changes view when
@@ -14,10 +14,10 @@ import { renderSummary } from "../summary.js";
14
14
  import { runWalk } from "../ui/run-walk.js";
15
15
  import { validateEdits } from "../validate.js";
16
16
  import { buildWalkItems } from "../walk-plan.js";
17
- import { Data, Effect, Option } from "effect";
17
+ import { Data, Effect, Option, Result } from "effect";
18
18
  import { readFileSync, writeFileSync } from "node:fs";
19
- import { Args, Command, Options } from "@effect/cli";
20
- import { NodeContext } from "@effect/platform-node";
19
+ import { NodeServices } from "@effect/platform-node";
20
+ import { Argument, Command, Flag } from "effect/unstable/cli";
21
21
 
22
22
  //#region src/cli/commands/upgrade.ts
23
23
  /**
@@ -29,9 +29,9 @@ var UpgradeError = class extends Data.TaggedError("UpgradeError") {};
29
29
  /** Combine the config-declared and pnpm-resolved release-age gates (strictest of both). @internal */
30
30
  function computeGate(source, file, resolver) {
31
31
  return Effect.gen(function* () {
32
- const { config } = yield* Effect.try(() => evaluatePluginConfig(source, file)).pipe(Effect.catchAll(() => Effect.succeed({ config: null })));
32
+ const { config } = yield* Effect.try(() => evaluatePluginConfig(source, file)).pipe(Effect.catch(() => Effect.succeed({ config: null })));
33
33
  const cfg = readConfigReleaseAge(config);
34
- const [age, exc] = yield* Effect.all([resolver.pnpmConfig("minimumReleaseAge").pipe(Effect.catchAll(() => Effect.succeed(null))), resolver.pnpmConfig("minimumReleaseAgeExclude").pipe(Effect.catchAll(() => Effect.succeed(null)))], { concurrency: "unbounded" });
34
+ const [age, exc] = yield* Effect.all([resolver.pnpmConfig("minimumReleaseAge").pipe(Effect.catch(() => Effect.succeed(null))), resolver.pnpmConfig("minimumReleaseAgeExclude").pipe(Effect.catch(() => Effect.succeed(null)))], { concurrency: "unbounded" });
35
35
  return combineReleaseAge(cfg, parsePnpmGate(age, exc));
36
36
  });
37
37
  }
@@ -52,8 +52,8 @@ function resolveGatedVersions(entries, resolver, gate, now, onProgress) {
52
52
  let resolved = 0;
53
53
  onProgress?.(0, total);
54
54
  return Effect.forEach(uniquePkgs, (pkg) => Effect.gen(function* () {
55
- const vr = yield* resolver.versions(pkg).pipe(Effect.either);
56
- if (vr._tag === "Left") {
55
+ const vr = yield* resolver.versions(pkg).pipe(Effect.result);
56
+ if (Result.isFailure(vr)) {
57
57
  onProgress?.(++resolved, total);
58
58
  return [
59
59
  pkg,
@@ -61,12 +61,12 @@ function resolveGatedVersions(entries, resolver, gate, now, onProgress) {
61
61
  []
62
62
  ];
63
63
  }
64
- const times = gate.ageMinutes > 0 ? yield* resolver.times(pkg).pipe(Effect.catchAll(() => Effect.succeed({}))) : {};
64
+ const times = gate.ageMinutes > 0 ? yield* resolver.times(pkg).pipe(Effect.catch(() => Effect.succeed({}))) : {};
65
65
  onProgress?.(++resolved, total);
66
66
  return [
67
67
  pkg,
68
- filterByReleaseAge(vr.right, times, gate, pkg, now),
69
- vr.right
68
+ filterByReleaseAge(vr.success, times, gate, pkg, now),
69
+ vr.success
70
70
  ];
71
71
  }), { concurrency: 12 }).pipe(Effect.map((triples) => ({
72
72
  gated: new Map(triples.map(([pkg, gated]) => [pkg, gated])),
@@ -148,12 +148,12 @@ function runUpgrade(opts) {
148
148
  kind: "peer",
149
149
  value
150
150
  });
151
- const derived = entry.strategy ? yield* derivePeerRange(entry.currentRange, entry.strategy).pipe(Effect.catchAll(() => Effect.succeed(null))) : null;
151
+ const derived = entry.strategy ? yield* derivePeerRange(entry.currentRange, entry.strategy).pipe(Effect.catch(() => Effect.succeed(null))) : null;
152
152
  if (derived?.warning) warnings.push(`${entry.pkg}: ${derived.warning.message}`);
153
153
  if (versions.length === 0) {
154
154
  const at = entry.rangeSpan[1];
155
155
  if (entry.peer && entry.strategy) {
156
- const expected = yield* detectPeerDrift(entry).pipe(Effect.catchAll(() => Effect.succeed(null)));
156
+ const expected = yield* detectPeerDrift(entry).pipe(Effect.catch(() => Effect.succeed(null)));
157
157
  if (expected !== null) {
158
158
  edits.push(peerEdit(entry.peer.span, expected));
159
159
  changedSpans.add(entry.rangeSpan[0]);
@@ -167,7 +167,7 @@ function runUpgrade(opts) {
167
167
  skipped.push(`${entry.catalog}.${entry.pkg}`);
168
168
  continue;
169
169
  }
170
- const inRange = (yield* planEntry(entry, versions).pipe(Effect.catchAll(() => Effect.succeed([])))).find((c) => c.kind === "in-range");
170
+ const inRange = (yield* planEntry(entry, versions).pipe(Effect.catch(() => Effect.succeed([])))).find((c) => c.kind === "in-range");
171
171
  const at = entry.rangeSpan[1];
172
172
  if (inRange) {
173
173
  edits.push(rangeEdit(entry.rangeSpan, inRange.range));
@@ -178,7 +178,7 @@ function runUpgrade(opts) {
178
178
  edits.push(peerInsert(at, derived.range));
179
179
  changedSpans.add(entry.rangeSpan[0]);
180
180
  } else if (entry.peer && entry.strategy) {
181
- const expected = yield* detectPeerDrift(entry).pipe(Effect.catchAll(() => Effect.succeed(null)));
181
+ const expected = yield* detectPeerDrift(entry).pipe(Effect.catch(() => Effect.succeed(null)));
182
182
  if (expected !== null) {
183
183
  edits.push(peerEdit(entry.peer.span, expected));
184
184
  changedSpans.add(entry.rangeSpan[0]);
@@ -197,7 +197,7 @@ function runUpgrade(opts) {
197
197
  const members = [];
198
198
  for (const e of group) {
199
199
  const versions = versionsByPkg.gated.get(e.pkg) ?? [];
200
- const inRange = (yield* planEntry(e, versions).pipe(Effect.catchAll(() => Effect.succeed([])))).find((c) => c.kind === "in-range");
200
+ const inRange = (yield* planEntry(e, versions).pipe(Effect.catch(() => Effect.succeed([])))).find((c) => c.kind === "in-range");
201
201
  const ceiling = inRange ? inRange.version : e.currentRange.replace(/^[\^~]/, "");
202
202
  members.push({
203
203
  pkg: e.pkg,
@@ -334,7 +334,7 @@ function runUpgradePreview(opts) {
334
334
  });
335
335
  const gate = yield* computeGate(source, opts.file, opts.resolver);
336
336
  const versions = yield* resolveGatedVersions(discovered.entries, opts.resolver, gate, Date.now());
337
- const text = renderSummary(projectDecisions(yield* buildWalkItems(discovered.entries, versions.gated).pipe(Effect.catchAll((e) => Effect.fail(new UpgradeError({ message: e.message })))), opts.full), void 0, { color: opts.color ?? false });
337
+ const text = renderSummary(projectDecisions(yield* buildWalkItems(discovered.entries, versions.gated).pipe(Effect.catch((e) => Effect.fail(new UpgradeError({ message: e.message })))), opts.full), void 0, { color: opts.color ?? false });
338
338
  return versions.unresolved.length > 0 ? `${text}\n⚠ ${unresolvedMessage(versions.unresolved)}` : text;
339
339
  });
340
340
  }
@@ -352,15 +352,12 @@ function resolveTargetFile(fileOpt) {
352
352
  return picked.file;
353
353
  });
354
354
  }
355
- const fileArg = Args.file({
356
- name: "file",
357
- exists: "yes"
358
- }).pipe(Args.optional);
359
- const yesFlag = Options.boolean("yes").pipe(Options.withAlias("y"), Options.withDefault(false));
360
- const dryRunFlag = Options.boolean("dry-run").pipe(Options.withDefault(false));
361
- const catalogOption = Options.text("catalog").pipe(Options.optional);
362
- const previewFlag = Options.boolean("preview").pipe(Options.withDefault(false));
363
- const fullFlag = Options.boolean("full").pipe(Options.withDefault(false));
355
+ const fileArg = Argument.file("file", { mustExist: true }).pipe(Argument.optional);
356
+ const yesFlag = Flag.boolean("yes").pipe(Flag.withAlias("y"), Flag.withDefault(false));
357
+ const dryRunFlag = Flag.boolean("dry-run").pipe(Flag.withDefault(false));
358
+ const catalogOption = Flag.string("catalog").pipe(Flag.optional);
359
+ const previewFlag = Flag.boolean("preview").pipe(Flag.withDefault(false));
360
+ const fullFlag = Flag.boolean("full").pipe(Flag.withDefault(false));
364
361
  /**
365
362
  * The "upgrade" command. The default path runs the interactive table;
366
363
  * --yes applies latest-in-range non-interactively; --dry-run runs the identical
@@ -415,7 +412,7 @@ const upgradeCommand = Command.make("upgrade", {
415
412
  const catalogName = Option.getOrUndefined(catalog);
416
413
  const entries = filterEntriesByCatalog(discovered.entries, catalogName);
417
414
  const versions = yield* resolveGatedVersions(entries, resolver, yield* computeGate(source, file, resolver), Date.now(), caps.interactive ? writeResolveProgress : void 0);
418
- const items = yield* buildWalkItems(entries, versions.gated).pipe(Effect.catchAll((e) => Effect.fail(new UpgradeError({ message: e.message }))));
415
+ const items = yield* buildWalkItems(entries, versions.gated).pipe(Effect.catch((e) => Effect.fail(new UpgradeError({ message: e.message }))));
419
416
  if (!caps.interactive) {
420
417
  const text = renderSummary(projectDecisions(items, full), void 0, { color: caps.color });
421
418
  const note = dryRun ? "(dry run — nothing written)" : "(non-interactive terminal — run with --yes to apply, or in a TTY to choose)";
@@ -466,7 +463,7 @@ const upgradeCommand = Command.make("upgrade", {
466
463
  const all = versions.gated.get(rc.pkg) ?? [];
467
464
  cappedVersions.set(rc.pkg, rc.cap === null ? all : yield* capVersions(all, rc.cap));
468
465
  }
469
- const reDecisions = yield* runWalk(yield* buildWalkItems(capEntries, cappedVersions).pipe(Effect.catchAll((err) => Effect.fail(new UpgradeError({ message: err.message })))));
466
+ const reDecisions = yield* runWalk(yield* buildWalkItems(capEntries, cappedVersions).pipe(Effect.catch((err) => Effect.fail(new UpgradeError({ message: err.message })))));
470
467
  const before = new Map(members.map((m) => [m.pkg, m.ceiling]));
471
468
  members = members.map((m) => {
472
469
  const rd = reDecisions.find((d) => d.item.entry.pkg === m.pkg);
@@ -504,7 +501,7 @@ const upgradeCommand = Command.make("upgrade", {
504
501
  const changed = countChangedDecisions(nonInteropDecisions.filter((d) => acceptedPkgs.has(d.item.entry.pkg))) + interopChanged;
505
502
  yield* Effect.sync(() => process.stdout.write(dryRun ? `Dry run — no changes written. ${changed} change(s) would be applied.\n` : `Applied ${changed} change(s).\n`));
506
503
  if (versions.unresolved.length > 0) yield* Effect.sync(() => process.stdout.write(`\n⚠ ${unresolvedMessage(versions.unresolved)}\n`));
507
- }).pipe(Effect.provide(RegistryResolverLive), Effect.provide(NodeContext.layer))).pipe(Command.withDescription("Upgrade catalog versions in a config file"));
504
+ }).pipe(Effect.provide(RegistryResolverLive), Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Upgrade catalog versions in a config file"));
508
505
 
509
506
  //#endregion
510
507
  export { UpgradeError, actionableWalkItems, applyInteropAndDecisions, computeGate, countChangedDecisions, nothingToUpgradeMessage, projectDecisions, resolveGatedVersions, resolveTargetFile, runUpgrade, runUpgradePreview, unresolvedMessage, upgradeCommand, writeResolveProgress };
package/cli/interop.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import { Range, SemVer } from "semver-effect";
2
+ import { Range, SemVer } from "@effected/semver";
3
3
 
4
4
  //#region src/cli/interop.ts
5
5
  /** Maximum number of concurrent peerDependencies fetches inside runInterop. @internal */
@@ -34,7 +34,7 @@ function deriveFloors(resolved, fetchPeer) {
34
34
  const valid = (yield* Effect.forEach(declared, (f) => SemVer.parse(f).pipe(Effect.map((sv) => ({
35
35
  f,
36
36
  sv
37
- })), Effect.catchAll(() => Effect.succeed(null))))).filter((x) => x !== null);
37
+ })), Effect.catch(() => Effect.succeed(null))))).filter((x) => x !== null);
38
38
  valid.sort((a, b) => a.sv.compare(b.sv));
39
39
  out.set(pkg, `^${valid[0]?.f ?? version}`);
40
40
  } else out.set(pkg, `^${version}`);
@@ -45,9 +45,9 @@ function deriveFloors(resolved, fetchPeer) {
45
45
  /** Does `version` satisfy `range`? Unparseable input is treated as not-satisfied. */
46
46
  function satisfies(version, range) {
47
47
  return Effect.gen(function* () {
48
- const r = yield* Range.parse(range).pipe(Effect.catchAll(() => Effect.succeed(null)));
48
+ const r = yield* Range.parse(range).pipe(Effect.catch(() => Effect.succeed(null)));
49
49
  if (!r) return false;
50
- const v = yield* SemVer.parse(version).pipe(Effect.catchAll(() => Effect.succeed(null)));
50
+ const v = yield* SemVer.parse(version).pipe(Effect.catch(() => Effect.succeed(null)));
51
51
  return v ? r.test(v) : false;
52
52
  });
53
53
  }
@@ -81,8 +81,8 @@ function resolveGroup(members, fetchPeer) {
81
81
  const resolved = new Map(members.map((m) => [m.pkg, m.ceiling]));
82
82
  const ceilingOf = new Map(members.map((m) => [m.pkg, m.ceiling]));
83
83
  const leq = (a, b) => Effect.gen(function* () {
84
- const av = yield* SemVer.parse(a).pipe(Effect.catchAll(() => Effect.succeed(null)));
85
- const bv = yield* SemVer.parse(b).pipe(Effect.catchAll(() => Effect.succeed(null)));
84
+ const av = yield* SemVer.parse(a).pipe(Effect.catch(() => Effect.succeed(null)));
85
+ const bv = yield* SemVer.parse(b).pipe(Effect.catch(() => Effect.succeed(null)));
86
86
  return av && bv ? av.compare(bv) <= 0 : false;
87
87
  });
88
88
  const maxIter = members.reduce((n, m) => n + m.candidates.length, 0) + members.length + 1;
@@ -130,7 +130,7 @@ function sortDesc(versions) {
130
130
  const parsed = yield* Effect.forEach(versions, (v) => SemVer.parse(v).pipe(Effect.map((sv) => ({
131
131
  v,
132
132
  sv
133
- })), Effect.catchAll(() => Effect.succeed({
133
+ })), Effect.catch(() => Effect.succeed({
134
134
  v,
135
135
  sv: null
136
136
  }))));
@@ -165,7 +165,7 @@ function runInterop(members, resolver, cache = /* @__PURE__ */ new Map()) {
165
165
  const k = key(pkg, v);
166
166
  const cached = cache.get(k);
167
167
  if (cached !== void 0) return Effect.succeed(cached);
168
- return resolver.peerDependencies(pkg, v).pipe(Effect.catchAll(() => Effect.succeed({}))).pipe(Effect.map((deps) => {
168
+ return resolver.peerDependencies(pkg, v).pipe(Effect.catch(() => Effect.succeed({}))).pipe(Effect.map((deps) => {
169
169
  cache.set(k, deps);
170
170
  return deps;
171
171
  }));
@@ -270,11 +270,11 @@ function buildInteropEdits(entries, result) {
270
270
  */
271
271
  function capVersions(list, max) {
272
272
  return Effect.gen(function* () {
273
- const mv = yield* SemVer.parse(max).pipe(Effect.catchAll(() => Effect.succeed(null)));
273
+ const mv = yield* SemVer.parse(max).pipe(Effect.catch(() => Effect.succeed(null)));
274
274
  if (!mv) return [...list];
275
275
  const out = [];
276
276
  for (const v of list) {
277
- const sv = yield* SemVer.parse(v).pipe(Effect.catchAll(() => Effect.succeed(null)));
277
+ const sv = yield* SemVer.parse(v).pipe(Effect.catch(() => Effect.succeed(null)));
278
278
  if (sv && sv.compare(mv) <= 0) out.push(v);
279
279
  }
280
280
  return out;
package/cli/peer-range.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Data, Effect } from "effect";
2
- import { SemVer } from "semver-effect";
2
+ import { SemVer } from "@effected/semver";
3
3
 
4
4
  //#region src/cli/peer-range.ts
5
5
  /**
package/cli/plan.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { derivePeerRange } from "./peer-range.js";
2
2
  import { Effect } from "effect";
3
- import { Range, SemVer } from "semver-effect";
3
+ import { Range, SemVer } from "@effected/semver";
4
4
 
5
5
  //#region src/cli/plan.ts
6
6
  /** Parse a version, returning null instead of failing (filters junk tags). */
7
- const parseOrNull = (v) => SemVer.parse(v).pipe(Effect.catchAll(() => Effect.succeed(null)));
7
+ const parseOrNull = (v) => SemVer.parse(v).pipe(Effect.catch(() => Effect.succeed(null)));
8
8
  /**
9
9
  * Compute the candidate versions for one catalog entry against the list of
10
10
  * published versions. Order: latest in-range (when newer than current), latest
@@ -16,7 +16,7 @@ const parseOrNull = (v) => SemVer.parse(v).pipe(Effect.catchAll(() => Effect.suc
16
16
  */
17
17
  function planEntry(entry, versions) {
18
18
  return Effect.gen(function* () {
19
- const range = yield* Range.parse(entry.currentRange).pipe(Effect.catchAll(() => Effect.succeed(null)));
19
+ const range = yield* Range.parse(entry.currentRange).pipe(Effect.catch(() => Effect.succeed(null)));
20
20
  const currentStripped = entry.currentRange.replace(/^[\^~]/, "");
21
21
  const current = yield* parseOrNull(currentStripped);
22
22
  const currentMajor = current?.major ?? 0;
package/cli/resolve.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { Context, Data, Effect, Layer } from "effect";
2
- import { Command, CommandExecutor } from "@effect/platform";
2
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
3
3
 
4
4
  //#region src/cli/resolve.ts
5
+ const Spawner = ChildProcessSpawner.ChildProcessSpawner;
5
6
  /**
6
7
  * Typed failure raised when a package's versions cannot be resolved.
7
8
  *
@@ -15,7 +16,7 @@ var ResolveError = class extends Data.TaggedError("ResolveError") {};
15
16
  *
16
17
  * @internal
17
18
  */
18
- var RegistryResolver = class extends Context.Tag("RegistryResolver")() {};
19
+ var RegistryResolver = class extends Context.Service()("RegistryResolver") {};
19
20
  /** Parse `pnpm view ... versions --json` stdout: a JSON array, or a single JSON string. */
20
21
  function parseVersions(pkg, stdout) {
21
22
  return Effect.try({
@@ -75,32 +76,51 @@ function parsePeerDeps(pkg, stdout) {
75
76
  * @internal
76
77
  */
77
78
  const RegistryResolverLive = Layer.effect(RegistryResolver, Effect.gen(function* () {
78
- const executor = yield* CommandExecutor.CommandExecutor;
79
+ const spawner = yield* Spawner;
79
80
  return {
80
81
  versions: (pkg) => Effect.gen(function* () {
81
- const cmd = Command.make("pnpm", "view", pkg, "versions", "--json");
82
- return yield* parseVersions(pkg, yield* executor.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
82
+ const cmd = ChildProcess.make("pnpm", [
83
+ "view",
84
+ pkg,
85
+ "versions",
86
+ "--json"
87
+ ]);
88
+ return yield* parseVersions(pkg, yield* spawner.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
83
89
  pkg,
84
90
  message: String(e)
85
91
  }))));
86
92
  }),
87
93
  times: (pkg) => Effect.gen(function* () {
88
- const cmd = Command.make("pnpm", "view", pkg, "time", "--json");
89
- return yield* parseTimes(pkg, yield* executor.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
94
+ const cmd = ChildProcess.make("pnpm", [
95
+ "view",
96
+ pkg,
97
+ "time",
98
+ "--json"
99
+ ]);
100
+ return yield* parseTimes(pkg, yield* spawner.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
90
101
  pkg,
91
102
  message: String(e)
92
103
  }))));
93
104
  }),
94
105
  peerDependencies: (pkg, version) => Effect.gen(function* () {
95
- const cmd = Command.make("pnpm", "view", `${pkg}@${version}`, "peerDependencies", "--json");
96
- return yield* parsePeerDeps(pkg, yield* executor.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
106
+ const cmd = ChildProcess.make("pnpm", [
107
+ "view",
108
+ `${pkg}@${version}`,
109
+ "peerDependencies",
110
+ "--json"
111
+ ]);
112
+ return yield* parsePeerDeps(pkg, yield* spawner.string(cmd).pipe(Effect.mapError((e) => new ResolveError({
97
113
  pkg,
98
114
  message: String(e)
99
115
  }))));
100
116
  }),
101
117
  pnpmConfig: (key) => Effect.gen(function* () {
102
- const cmd = Command.make("pnpm", "config", "get", key);
103
- return yield* executor.string(cmd).pipe(Effect.map((s) => s.trim()), Effect.catchAll(() => Effect.succeed(null)));
118
+ const cmd = ChildProcess.make("pnpm", [
119
+ "config",
120
+ "get",
121
+ key
122
+ ]);
123
+ return yield* spawner.string(cmd).pipe(Effect.map((s) => s.trim()), Effect.catch(() => Effect.succeed(null)));
104
124
  })
105
125
  };
106
126
  }));
@@ -11,7 +11,7 @@ import { createElement } from "react";
11
11
  * @internal
12
12
  */
13
13
  function runPreview(views) {
14
- return Effect.async((resume) => {
14
+ return Effect.callback((resume) => {
15
15
  render(createElement(Preview, {
16
16
  views,
17
17
  onExit: () => {}
@@ -12,7 +12,7 @@ import { createElement } from "react";
12
12
  * @internal
13
13
  */
14
14
  function runWalk(items, dryRun = false, unresolved = []) {
15
- return Effect.async((resume) => {
15
+ return Effect.callback((resume) => {
16
16
  let collected = [];
17
17
  render(createElement(Walk, {
18
18
  items,
package/cli/validate.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import { Range, SemVer } from "semver-effect";
2
+ import { Range, SemVer } from "@effected/semver";
3
3
 
4
4
  //#region src/cli/validate.ts
5
5
  /**
@@ -21,10 +21,10 @@ import { Range, SemVer } from "semver-effect";
21
21
  function rangeIsSatisfiable(range, versions) {
22
22
  return Effect.gen(function* () {
23
23
  if (versions.length === 0) return true;
24
- const parsedRange = yield* Range.parse(range).pipe(Effect.catchAll(() => Effect.succeed(null)));
24
+ const parsedRange = yield* Range.parse(range).pipe(Effect.catch(() => Effect.succeed(null)));
25
25
  if (parsedRange === null) return true;
26
26
  for (const v of versions) {
27
- const sv = yield* SemVer.parse(v).pipe(Effect.catchAll(() => Effect.succeed(null)));
27
+ const sv = yield* SemVer.parse(v).pipe(Effect.catch(() => Effect.succeed(null)));
28
28
  if (sv && parsedRange.test(sv)) return true;
29
29
  }
30
30
  return false;
@@ -1,14 +1,14 @@
1
+ import { Effect } from "effect";
1
2
  import { existsSync } from "node:fs";
2
3
  import { dirname, join } from "node:path";
3
- import { parse, stringify } from "yaml";
4
+ import { Yaml, YamlStringifyOptions } from "@effected/yaml";
4
5
 
5
6
  //#region src/cli/workspace-file.ts
6
7
  const FILENAME = "pnpm-workspace.yaml";
7
- const STRINGIFY_OPTIONS = {
8
+ const STRINGIFY_OPTIONS = YamlStringifyOptions.make({
8
9
  indent: 2,
9
- lineWidth: 0,
10
- singleQuote: false
11
- };
10
+ lineWidth: 0
11
+ });
12
12
  /** True when every element is a string/number/boolean (safe to sort). */
13
13
  function allPrimitive(arr) {
14
14
  return arr.every((v) => v === null || typeof v !== "object" && typeof v !== "function");
@@ -46,12 +46,12 @@ function findWorkspaceFile(startDir) {
46
46
  }
47
47
  /** Parse pnpm-workspace.yaml source; empty/whitespace yields an empty object. @internal */
48
48
  function parseWorkspace(source) {
49
- const parsed = parse(source);
49
+ const parsed = Effect.runSync(Yaml.parse(source));
50
50
  return parsed && typeof parsed === "object" ? parsed : {};
51
51
  }
52
52
  /** Render a workspace object: deterministic key sort + yaml.stringify. @internal */
53
53
  function renderWorkspace(obj) {
54
- return stringify(canonicalize(obj), STRINGIFY_OPTIONS);
54
+ return Effect.runSync(Yaml.stringify(canonicalize(obj), STRINGIFY_OPTIONS));
55
55
  }
56
56
 
57
57
  //#endregion
@@ -104,7 +104,12 @@ const build = {
104
104
  anchor: "nodeoptions"
105
105
  },
106
106
  verifyDepsBeforeRun: {
107
- schema: Schema.Union(Schema.Literal("install", "warn", "error", "prompt"), Schema.Boolean),
107
+ schema: Schema.Union([Schema.Literals([
108
+ "install",
109
+ "warn",
110
+ "error",
111
+ "prompt"
112
+ ]), Schema.Boolean]),
108
113
  kind: "union",
109
114
  strategy: "scalar",
110
115
  enforcement: "absent",
@@ -41,7 +41,11 @@ const hoisting = {
41
41
  anchor: "shamefullyhoist"
42
42
  },
43
43
  hoistingLimits: {
44
- schema: Schema.Literal("none", "workspaces", "dependencies"),
44
+ schema: Schema.Literals([
45
+ "none",
46
+ "workspaces",
47
+ "dependencies"
48
+ ]),
45
49
  kind: "enum",
46
50
  strategy: "scalar",
47
51
  enforcement: "absent",
@@ -63,7 +67,11 @@ const hoisting = {
63
67
  anchor: "modulesdir"
64
68
  },
65
69
  nodeLinker: {
66
- schema: Schema.Literal("isolated", "hoisted", "pnp"),
70
+ schema: Schema.Literals([
71
+ "isolated",
72
+ "hoisted",
73
+ "pnp"
74
+ ]),
67
75
  kind: "enum",
68
76
  strategy: "scalar",
69
77
  enforcement: "absent",
@@ -121,7 +129,13 @@ const hoisting = {
121
129
  anchor: "virtualstoreonly"
122
130
  },
123
131
  packageImportMethod: {
124
- schema: Schema.Literal("auto", "hardlink", "copy", "clone", "clone-or-copy"),
132
+ schema: Schema.Literals([
133
+ "auto",
134
+ "hardlink",
135
+ "copy",
136
+ "clone",
137
+ "clone-or-copy"
138
+ ]),
125
139
  kind: "enum",
126
140
  strategy: "scalar",
127
141
  enforcement: "absent",
@@ -5,7 +5,11 @@ import { Schema } from "effect";
5
5
  /** The 14 resolution/misc preference fields. @internal */
6
6
  const misc = {
7
7
  resolutionMode: {
8
- schema: Schema.Literal("highest", "time-based", "lowest-direct"),
8
+ schema: Schema.Literals([
9
+ "highest",
10
+ "time-based",
11
+ "lowest-direct"
12
+ ]),
9
13
  kind: "enum",
10
14
  strategy: "scalar",
11
15
  enforcement: "absent",
@@ -18,7 +22,11 @@ const misc = {
18
22
  }
19
23
  },
20
24
  savePrefix: {
21
- schema: Schema.Literal("^", "~", ""),
25
+ schema: Schema.Literals([
26
+ "^",
27
+ "~",
28
+ ""
29
+ ]),
22
30
  kind: "enum",
23
31
  strategy: "scalar",
24
32
  enforcement: "absent",
@@ -19,10 +19,7 @@ const PeerRulesSchema = Schema.Struct({
19
19
  */
20
20
  const resolution = {
21
21
  catalogs: {
22
- schema: Schema.Record({
23
- key: Str,
24
- value: StringRecord
25
- }),
22
+ schema: Schema.Record(Str, StringRecord),
26
23
  kind: "object",
27
24
  strategy: "catalogs",
28
25
  enforcement: "warn",
@@ -205,7 +202,7 @@ const resolution = {
205
202
  anchor: "minimumreleaseageignoremissingtime"
206
203
  },
207
204
  trustPolicy: {
208
- schema: Schema.Literal("off", "no-downgrade"),
205
+ schema: Schema.Literals(["off", "no-downgrade"]),
209
206
  kind: "enum",
210
207
  strategy: "scalar",
211
208
  enforcement: "warn",
@@ -32,7 +32,12 @@ const runtimeCfg = {
32
32
  anchor: "managepackagemanagerversions"
33
33
  },
34
34
  pmOnFail: {
35
- schema: Schema.Literal("download", "error", "warn", "ignore"),
35
+ schema: Schema.Literals([
36
+ "download",
37
+ "error",
38
+ "warn",
39
+ "ignore"
40
+ ]),
36
41
  kind: "enum",
37
42
  strategy: "scalar",
38
43
  enforcement: "absent",
@@ -45,7 +50,12 @@ const runtimeCfg = {
45
50
  }
46
51
  },
47
52
  runtimeOnFail: {
48
- schema: Schema.Literal("download", "error", "warn", "ignore"),
53
+ schema: Schema.Literals([
54
+ "download",
55
+ "error",
56
+ "warn",
57
+ "ignore"
58
+ ]),
49
59
  kind: "enum",
50
60
  strategy: "scalar",
51
61
  enforcement: "absent",
@@ -5,22 +5,10 @@ import { Schema } from "effect";
5
5
  /** @internal */ const Num = Schema.Number;
6
6
  /** @internal */ const Str = Schema.String;
7
7
  /** @internal */ const StringArray = Schema.Array(Schema.String);
8
- /** @internal */ const StringRecord = Schema.Record({
9
- key: Schema.String,
10
- value: Schema.String
11
- });
12
- /** @internal */ const BooleanRecord = Schema.Record({
13
- key: Schema.String,
14
- value: Schema.Boolean
15
- });
16
- /** @internal */ const UnknownRecord = Schema.Record({
17
- key: Schema.String,
18
- value: Schema.Unknown
19
- });
20
- /** @internal */ const StringArrayRecord = Schema.Record({
21
- key: Schema.String,
22
- value: StringArray
23
- });
8
+ /** @internal */ const StringRecord = Schema.Record(Schema.String, Schema.String);
9
+ /** @internal */ const BooleanRecord = Schema.Record(Schema.String, Schema.Boolean);
10
+ /** @internal */ const UnknownRecord = Schema.Record(Schema.String, Schema.Unknown);
11
+ /** @internal */ const StringArrayRecord = Schema.Record(Schema.String, StringArray);
24
12
 
25
13
  //#endregion
26
14
  export { Bool, BooleanRecord, Num, Str, StringArray, StringArrayRecord, StringRecord, UnknownRecord };
@@ -5,7 +5,11 @@ import { Schema } from "effect";
5
5
  /** The 10 catalog + workspace + audit fields. @internal */
6
6
  const workspace = {
7
7
  catalogMode: {
8
- schema: Schema.Literal("strict", "prefer", "manual"),
8
+ schema: Schema.Literals([
9
+ "strict",
10
+ "prefer",
11
+ "manual"
12
+ ]),
9
13
  kind: "enum",
10
14
  strategy: "scalar",
11
15
  enforcement: "absent",
@@ -27,7 +31,7 @@ const workspace = {
27
31
  anchor: "cleanupunusedcatalogs"
28
32
  },
29
33
  linkWorkspacePackages: {
30
- schema: Schema.Union(Schema.Boolean, Schema.Literal("deep")),
34
+ schema: Schema.Union([Schema.Boolean, Schema.Literals(["deep"])]),
31
35
  kind: "union",
32
36
  strategy: "scalar",
33
37
  enforcement: "absent",
@@ -49,7 +53,7 @@ const workspace = {
49
53
  anchor: "preferworkspacepackages"
50
54
  },
51
55
  saveWorkspaceProtocol: {
52
- schema: Schema.Union(Schema.Boolean, Schema.Literal("rolling")),
56
+ schema: Schema.Union([Schema.Boolean, Schema.Literals(["rolling"])]),
53
57
  kind: "union",
54
58
  strategy: "scalar",
55
59
  enforcement: "absent",
@@ -98,7 +102,12 @@ const workspace = {
98
102
  anchor: "workspaceconcurrency"
99
103
  },
100
104
  auditLevel: {
101
- schema: Schema.Literal("low", "moderate", "high", "critical"),
105
+ schema: Schema.Literals([
106
+ "low",
107
+ "moderate",
108
+ "high",
109
+ "critical"
110
+ ]),
102
111
  kind: "enum",
103
112
  strategy: "scalar",
104
113
  enforcement: "absent",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rolldown-pnpm-config",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "description": "A dogfooding example of our plugin",
6
6
  "repository": {
@@ -33,26 +33,16 @@
33
33
  "rolldown-pnpm-config": "bin/rolldown-pnpm-config.js"
34
34
  },
35
35
  "dependencies": {
36
- "@effect/cli": "^0.75.2",
37
- "@effect/cluster": "^0.59.0",
38
- "@effect/experimental": "^0.60.0",
39
- "@effect/platform": "^0.96.2",
40
- "@effect/platform-node": "^0.107.0",
41
- "@effect/printer": "^0.49.0",
42
- "@effect/printer-ansi": "^0.49.0",
43
- "@effect/rpc": "^0.75.1",
44
- "@effect/sql": "^0.51.1",
45
- "@effect/typeclass": "^0.40.0",
46
- "@effect/workflow": "^0.18.2",
47
- "effect": "^3.21.4",
36
+ "@effect/platform-node": "4.0.0-beta.98",
37
+ "@effected/semver": "^0.1.0",
38
+ "@effected/yaml": "^0.1.0",
39
+ "effect": "4.0.0-beta.98",
48
40
  "ink": "^7.1.0",
49
41
  "ink-tab": "^5.2.0",
50
42
  "oxc-parser": "^0.140.0",
51
43
  "react": "^19.2.7",
52
- "semver-effect": "^0.3.1",
53
44
  "std-env": "^4.2.0",
54
- "std-osc8": "^0.2.0",
55
- "yaml": "^2.9.0"
45
+ "std-osc8": "^0.2.0"
56
46
  },
57
47
  "peerDependencies": {
58
48
  "rolldown": "^1.1.0"
package/plugin/freeze.js CHANGED
@@ -48,7 +48,7 @@ function freeze(config) {
48
48
  return Effect.gen(function* () {
49
49
  const base = {};
50
50
  const manifest = {};
51
- base.catalogs = yield* Schema.decodeUnknown(CatalogsSchema)(normalizeCatalogs(config.catalogs)).pipe(Effect.mapError((error) => new ConfigError({ message: `Invalid catalogs: ${String(error)}` })));
51
+ base.catalogs = yield* Schema.decodeUnknownEffect(CatalogsSchema)(normalizeCatalogs(config.catalogs)).pipe(Effect.mapError((error) => new ConfigError({ message: `Invalid catalogs: ${String(error)}` })));
52
52
  manifest.catalogs = {
53
53
  strategy: "catalogs",
54
54
  enforcement: "warn"
@@ -60,7 +60,7 @@ function freeze(config) {
60
60
  if (raw === void 0) continue;
61
61
  const decl = normalizeField(raw);
62
62
  const schema = FIELD_SCHEMAS[field];
63
- base[field] = schema ? yield* Schema.decodeUnknown(schema)(decl.value).pipe(Effect.mapError((error) => new ConfigError({ message: `Invalid ${field}: ${String(error)}` }))) : decl.value;
63
+ base[field] = schema ? yield* Schema.decodeUnknownEffect(schema)(decl.value).pipe(Effect.mapError((error) => new ConfigError({ message: `Invalid ${field}: ${String(error)}` }))) : decl.value;
64
64
  manifest[field] = {
65
65
  strategy: reg.strategy,
66
66
  enforcement: decl.enforcement ?? reg.enforcement,
package/virtual.d.ts CHANGED
@@ -9,8 +9,18 @@
9
9
  // per-module boilerplate.
10
10
 
11
11
  declare module "rolldown-pnpm-config/virtual/pnpmfile" {
12
- import type { PnpmHooks } from "rolldown-pnpm-config/runtime";
13
- export const hooks: PnpmHooks;
12
+ // Inlined rather than imported from "rolldown-pnpm-config/runtime": this file is
13
+ // shipped byte-for-byte (never compiled), so any cross-module import here resolves
14
+ // against this package's own *source* `exports` map during the build's declaration
15
+ // pass and pulls a raw .ts file into API Extractor's analysis (ae-wrong-input-file-type).
16
+ // Keep this shape in sync with `PnpmConfig`/`PnpmHooks` in `src/runtime/types.ts`.
17
+ interface PnpmConfig {
18
+ catalogs?: Record<string, Record<string, string>>;
19
+ [key: string]: unknown;
20
+ }
21
+ export const hooks: {
22
+ updateConfig(config: PnpmConfig): PnpmConfig;
23
+ };
14
24
  }
15
25
 
16
26
  declare module "rolldown-pnpm-config/virtual/catalogs" {