@effected/workspaces 0.7.0 → 0.8.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.
package/LockfileReader.js CHANGED
@@ -27,6 +27,8 @@ var LockfileReadError = class extends Schema.TaggedErrorClass()("LockfileReadErr
27
27
  return `Cannot read ${this.format} lockfile at ${this.lockfilePath}`;
28
28
  }
29
29
  };
30
+ /** A defect naming the unstubbed test-double method — a test-wiring mistake, not a typed failure. */
31
+ const unstubbed = (method) => Effect.die(/* @__PURE__ */ new Error(`LockfileReader.makeTest: ${method}() was called but not stubbed — pass a \`${method}\` override.`));
30
32
  /**
31
33
  * Reads and parses the workspace's lockfile.
32
34
  *
@@ -112,6 +114,74 @@ var LockfileReader = class LockfileReader extends Context.Service()("@effected/w
112
114
  * `const` and reuse it.
113
115
  */
114
116
  static layer = (options) => Layer.effect(LockfileReader, LockfileReader.make(options));
117
+ /**
118
+ * A test double satisfying the full {@link LockfileReaderShape} with no
119
+ * filesystem, root walk, or package-manager detection.
120
+ *
121
+ * @remarks
122
+ * There is **no honest default lockfile**: an empty one that looks like a
123
+ * legitimate answer is indistinguishable from "this workspace resolves
124
+ * nothing" — the silent-empty failure class this package documents on the
125
+ * live paths — so `read` **dies** with an instructive defect until stubbed.
126
+ *
127
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
128
+ * derived-from-the-primary rule: when a `read` override is supplied,
129
+ * `resolvedVersion` answers as the live service does — the **first** entry
130
+ * of `lockfile.packagesNamed(name)` in lockfile order, `Option.none()` on a
131
+ * miss — so the two stay consistent by construction. `integrity` is **not**
132
+ * derivable: the live method compares the lockfile against the workspace
133
+ * manifests discovery enumerates, and the double has no discovery to ask, so
134
+ * it dies unless stubbed.
135
+ *
136
+ * `refresh` defaults to `Effect.void` honestly: the live contract is "drop
137
+ * the memoized read so the next call re-reads", and this double memoizes
138
+ * nothing — every `read()` call re-invokes the override — so there is
139
+ * nothing to drop and the no-op is truthful, the same reasoning as
140
+ * `WorkspaceDiscovery.makeTest`'s `refresh`.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * import { Lockfile } from "@effected/lockfiles";
145
+ * import { LockfileReader } from "@effected/workspaces";
146
+ * import { Effect } from "effect";
147
+ *
148
+ * const double = LockfileReader.makeTest({
149
+ * read: () =>
150
+ * Effect.succeed(
151
+ * Lockfile.make({ format: "pnpm", lockfileVersion: "9.0", packages: [], workspaceDependencies: [] }),
152
+ * ),
153
+ * });
154
+ * // `resolvedVersion` now answers consistently from that lockfile.
155
+ * ```
156
+ */
157
+ static makeTest = (overrides = {}) => {
158
+ const read = overrides.read;
159
+ return {
160
+ read: () => unstubbed("read"),
161
+ resolvedVersion: read !== void 0 ? (packageName) => Effect.map(read(), (lockfile) => Option.fromUndefinedOr(lockfile.packagesNamed(packageName)[0])) : () => unstubbed("resolvedVersion"),
162
+ integrity: () => unstubbed("integrity"),
163
+ refresh: () => Effect.void,
164
+ ...overrides
165
+ };
166
+ };
167
+ /**
168
+ * The test layer: {@link LockfileReader.makeTest} behind `Layer.succeed`, so
169
+ * a suite provides only the methods it exercises.
170
+ *
171
+ * @remarks
172
+ * A parameterized layer factory mints a **fresh reference per call**, and
173
+ * layers memoize by reference — bind the result to a `const` and reuse it
174
+ * rather than calling `layerTest(...)` at each composition site.
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * import { LockfileReader } from "@effected/workspaces";
179
+ *
180
+ * const TestLockfiles = LockfileReader.layerTest();
181
+ * // program.pipe(Effect.provide(TestLockfiles)) — dies loudly if touched.
182
+ * ```
183
+ */
184
+ static layerTest = (overrides = {}) => Layer.succeed(LockfileReader, LockfileReader.makeTest(overrides));
115
185
  };
116
186
 
117
187
  //#endregion
package/README.md CHANGED
@@ -134,7 +134,21 @@ A specifier the workspace cannot answer fails typed as `UnresolvedDependencyErro
134
134
 
135
135
  ## The synchronous escape hatch
136
136
 
137
- Vitest's config-time project discovery cannot await. Two functions exist for exactly that case, and they run synchronously over file and path operations you supply the module itself imports nothing platform-shaped, and Node's built-ins satisfy the operations one-liner each:
137
+ Vitest's config-time project discovery cannot await. Two functions exist for exactly that case, and they run synchronously over file and path operations you supply. On Node you do not have to write them: the `@effected/workspaces/node-sync` subpath exports `nodeSyncOps`, the ready-made `node:fs` and `node:path` bindings, so adopting the sync path is one extra import.
138
+
139
+ ```ts
140
+ import { findWorkspaceRootSync, getWorkspacePackagesSync } from "@effected/workspaces";
141
+ import { nodeSyncOps } from "@effected/workspaces/node-sync";
142
+
143
+ const root = findWorkspaceRootSync(process.cwd(), nodeSyncOps);
144
+ const packages = root === null ? [] : getWorkspacePackagesSync(root, nodeSyncOps);
145
+ // root: the workspace root path, or null when none is found above the cwd
146
+ // packages: the discovered workspace packages, empty when there is no root
147
+ ```
148
+
149
+ Both entry points take their path positionally, so the bag usually passes through verbatim; spread it to add `getWorkspacePackagesSync`'s traversal extras — `{ ...nodeSyncOps, maxDepth }`. The bindings are a separate subpath deliberately: the main entry imports nothing platform-shaped, and re-exporting them from it would drag `node:*` into every consumer, including the ones supplying their own operations. `nodePath` is the running platform's `node:path`, so on Windows the paths handed back are win32 paths.
150
+
151
+ Write the operations yourself when Node's built-ins are not the platform you mean — a Bun or Deno binding, a test fake, or `node:path/win32` to pin a dialect rather than follow the running platform. Each one is a one-liner:
138
152
 
139
153
  ```ts
140
154
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
@@ -157,7 +171,7 @@ const packages = root === null ? [] : getWorkspacePackagesSync(root, options);
157
171
  // packages: the discovered workspace packages, empty when there is no root
158
172
  ```
159
173
 
160
- Windows correctness is the operations you pass `node:path` on Windows is already win32-appropriate. Both entry points drive one traversal state machine (the same dequeue order, depth rule, visit budget and `node_modules` prune), so the sync and Effect surfaces can never disagree about what a pattern means. The one deliberate difference is at a bound: the Effect enumerator fails typed, the sync one truncates. Prefer the Effect API everywhere you can run one.
174
+ Windows correctness is therefore the operations you pass, and nothing else. Both entry points drive one traversal state machine (the same dequeue order, depth rule, visit budget and `node_modules` prune), so the sync and Effect surfaces can never disagree about what a pattern means. The one deliberate difference is at a bound: the Effect enumerator fails typed, the sync one truncates. Prefer the Effect API everywhere you can run one.
161
175
 
162
176
  ## Error handling
163
177
 
@@ -220,6 +234,7 @@ A name miss in the derived `getPackage` fails with the service's own typed `Pack
220
234
  - `ChangeDetector` — git-range change detection over `@effected/git`'s `Git` service; swap the layer to mock it with no repository.
221
235
  - `PublishabilityDetector` — whether a package publishes and to where, as a `PublishTarget` (registry, directory, access, provenance). The default layer implements npm's semantics; swap the layer if yours differ.
222
236
  - `findWorkspaceRootSync` / `getWorkspacePackagesSync` — the synchronous escape hatch for config-time callers that cannot await, over file and path operations you supply.
237
+ - `@effected/workspaces/node-sync` — a second entry point holding the Node bindings for those operations (`nodeFileSystem`, `nodePath` and the `nodeSyncOps` bag), kept off the main entry so `node:*` never reaches a consumer that supplies its own.
223
238
 
224
239
  ## License
225
240
 
@@ -283,6 +283,8 @@ const validatePnpmWorkspaceCatalogs = (document) => {
283
283
  catalogs: "catalogs"
284
284
  }));
285
285
  };
286
+ /** A defect naming the unstubbed test-double method — a test-wiring mistake, not a typed failure. */
287
+ const unstubbed = (method) => Effect.die(/* @__PURE__ */ new Error(`WorkspaceCatalogs.makeTest: ${method}() was called but not stubbed — pass a \`${method}\` override.`));
286
288
  /**
287
289
  * Assembles a workspace's catalogs, package-manager-aware.
288
290
  *
@@ -426,6 +428,70 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
426
428
  */
427
429
  static layerWithConfigDependencies = (options) => Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(Layer.provide(ConfigDependencyHooks.layerLive));
428
430
  /**
431
+ * A test double satisfying the full {@link WorkspaceCatalogsShape} with no
432
+ * filesystem, lockfile read, or hook replay.
433
+ *
434
+ * @remarks
435
+ * There is **no honest default catalog set**: an empty `CatalogSet` that
436
+ * looks like a legitimate answer is the "every dependency looks newly added"
437
+ * failure class the live assembler hard-fails to prevent, so every method
438
+ * **dies** with an instructive defect until stubbed — a test-wiring mistake
439
+ * fails loudly as a defect rather than succeeding with a lie or failing with
440
+ * a dishonest typed error.
441
+ *
442
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
443
+ * derived-from-the-primary rule: when a `set` override is supplied,
444
+ * `resolveSpecifier` answers from that `CatalogSet`'s own
445
+ * {@link CatalogSet.resolveSpecifier} — exactly what the live service runs
446
+ * over its assembled set — so the two stay consistent by construction.
447
+ * `releaseAgeGate` and `importerVersions` are **not** derivable from a
448
+ * catalog set (the gate comes from release-age keys and hook contributions,
449
+ * the importer index from the lockfile's importer blocks — neither is in a
450
+ * `CatalogSet`) and always die unless stubbed.
451
+ *
452
+ * @example
453
+ * ```ts
454
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
455
+ * import { Effect } from "effect";
456
+ *
457
+ * const double = WorkspaceCatalogs.makeTest({
458
+ * set: () => Effect.succeed(CatalogSet.fromCatalogs({ default: { effect: "4.0.0" } })),
459
+ * });
460
+ * // `resolveSpecifier` now answers consistently from that set.
461
+ * ```
462
+ */
463
+ static makeTest = (overrides = {}) => {
464
+ const set = overrides.set;
465
+ return {
466
+ set: () => unstubbed("set"),
467
+ resolveSpecifier: set !== void 0 ? (dependency, specifier) => Effect.map(set(), (catalogs) => catalogs.resolveSpecifier(dependency, specifier)) : () => unstubbed("resolveSpecifier"),
468
+ releaseAgeGate: () => unstubbed("releaseAgeGate"),
469
+ importerVersions: () => unstubbed("importerVersions"),
470
+ ...overrides
471
+ };
472
+ };
473
+ /**
474
+ * The test layer: {@link WorkspaceCatalogs.makeTest} behind `Layer.succeed`,
475
+ * so a suite provides only the methods it exercises.
476
+ *
477
+ * @remarks
478
+ * A parameterized layer factory mints a **fresh reference per call**, and
479
+ * layers memoize by reference — bind the result to a `const` and reuse it
480
+ * rather than calling `layerTest(...)` at each composition site.
481
+ *
482
+ * @example
483
+ * ```ts
484
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
485
+ * import { Effect } from "effect";
486
+ *
487
+ * const TestCatalogs = WorkspaceCatalogs.layerTest({
488
+ * set: () => Effect.succeed(CatalogSet.empty()),
489
+ * });
490
+ * // program.pipe(Effect.provide(TestCatalogs))
491
+ * ```
492
+ */
493
+ static layerTest = (overrides = {}) => Layer.succeed(WorkspaceCatalogs, WorkspaceCatalogs.makeTest(overrides));
494
+ /**
429
495
  * The real implementation of `@effected/npm`'s `CatalogResolver` contract —
430
496
  * the one `@effected/package-json` declares but cannot fill.
431
497
  *
Binary file
package/index.d.ts CHANGED
@@ -1212,6 +1212,65 @@ declare class LockfileReader extends LockfileReader_base {
1212
1212
  * `const` and reuse it.
1213
1213
  */
1214
1214
  static readonly layer: (options?: LockfileReaderOptions) => Layer.Layer<LockfileReader, never, WorkspaceRoot | PackageManagerDetector | WorkspaceDiscovery | FileSystem.FileSystem | Path.Path>;
1215
+ /**
1216
+ * A test double satisfying the full {@link LockfileReaderShape} with no
1217
+ * filesystem, root walk, or package-manager detection.
1218
+ *
1219
+ * @remarks
1220
+ * There is **no honest default lockfile**: an empty one that looks like a
1221
+ * legitimate answer is indistinguishable from "this workspace resolves
1222
+ * nothing" — the silent-empty failure class this package documents on the
1223
+ * live paths — so `read` **dies** with an instructive defect until stubbed.
1224
+ *
1225
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
1226
+ * derived-from-the-primary rule: when a `read` override is supplied,
1227
+ * `resolvedVersion` answers as the live service does — the **first** entry
1228
+ * of `lockfile.packagesNamed(name)` in lockfile order, `Option.none()` on a
1229
+ * miss — so the two stay consistent by construction. `integrity` is **not**
1230
+ * derivable: the live method compares the lockfile against the workspace
1231
+ * manifests discovery enumerates, and the double has no discovery to ask, so
1232
+ * it dies unless stubbed.
1233
+ *
1234
+ * `refresh` defaults to `Effect.void` honestly: the live contract is "drop
1235
+ * the memoized read so the next call re-reads", and this double memoizes
1236
+ * nothing — every `read()` call re-invokes the override — so there is
1237
+ * nothing to drop and the no-op is truthful, the same reasoning as
1238
+ * `WorkspaceDiscovery.makeTest`'s `refresh`.
1239
+ *
1240
+ * @example
1241
+ * ```ts
1242
+ * import { Lockfile } from "@effected/lockfiles";
1243
+ * import { LockfileReader } from "@effected/workspaces";
1244
+ * import { Effect } from "effect";
1245
+ *
1246
+ * const double = LockfileReader.makeTest({
1247
+ * read: () =>
1248
+ * Effect.succeed(
1249
+ * Lockfile.make({ format: "pnpm", lockfileVersion: "9.0", packages: [], workspaceDependencies: [] }),
1250
+ * ),
1251
+ * });
1252
+ * // `resolvedVersion` now answers consistently from that lockfile.
1253
+ * ```
1254
+ */
1255
+ static readonly makeTest: (overrides?: Partial<LockfileReaderShape>) => LockfileReaderShape;
1256
+ /**
1257
+ * The test layer: {@link LockfileReader.makeTest} behind `Layer.succeed`, so
1258
+ * a suite provides only the methods it exercises.
1259
+ *
1260
+ * @remarks
1261
+ * A parameterized layer factory mints a **fresh reference per call**, and
1262
+ * layers memoize by reference — bind the result to a `const` and reuse it
1263
+ * rather than calling `layerTest(...)` at each composition site.
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * import { LockfileReader } from "@effected/workspaces";
1268
+ *
1269
+ * const TestLockfiles = LockfileReader.layerTest();
1270
+ * // program.pipe(Effect.provide(TestLockfiles)) — dies loudly if touched.
1271
+ * ```
1272
+ */
1273
+ static readonly layerTest: (overrides?: Partial<LockfileReaderShape>) => Layer.Layer<LockfileReader>;
1215
1274
  }
1216
1275
  //#endregion
1217
1276
  //#region src/Publishability.d.ts
@@ -1553,6 +1612,61 @@ declare class WorkspaceCatalogs extends WorkspaceCatalogs_base {
1553
1612
  * Parameterized, so bind it to a `const` and reuse it.
1554
1613
  */
1555
1614
  static readonly layerWithConfigDependencies: (options?: WorkspaceCatalogsOptions) => Layer.Layer<WorkspaceCatalogs, never, WorkspaceRoot | LockfileReader | FileSystem.FileSystem | Path.Path>;
1615
+ /**
1616
+ * A test double satisfying the full {@link WorkspaceCatalogsShape} with no
1617
+ * filesystem, lockfile read, or hook replay.
1618
+ *
1619
+ * @remarks
1620
+ * There is **no honest default catalog set**: an empty `CatalogSet` that
1621
+ * looks like a legitimate answer is the "every dependency looks newly added"
1622
+ * failure class the live assembler hard-fails to prevent, so every method
1623
+ * **dies** with an instructive defect until stubbed — a test-wiring mistake
1624
+ * fails loudly as a defect rather than succeeding with a lie or failing with
1625
+ * a dishonest typed error.
1626
+ *
1627
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
1628
+ * derived-from-the-primary rule: when a `set` override is supplied,
1629
+ * `resolveSpecifier` answers from that `CatalogSet`'s own
1630
+ * {@link CatalogSet.resolveSpecifier} — exactly what the live service runs
1631
+ * over its assembled set — so the two stay consistent by construction.
1632
+ * `releaseAgeGate` and `importerVersions` are **not** derivable from a
1633
+ * catalog set (the gate comes from release-age keys and hook contributions,
1634
+ * the importer index from the lockfile's importer blocks — neither is in a
1635
+ * `CatalogSet`) and always die unless stubbed.
1636
+ *
1637
+ * @example
1638
+ * ```ts
1639
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
1640
+ * import { Effect } from "effect";
1641
+ *
1642
+ * const double = WorkspaceCatalogs.makeTest({
1643
+ * set: () => Effect.succeed(CatalogSet.fromCatalogs({ default: { effect: "4.0.0" } })),
1644
+ * });
1645
+ * // `resolveSpecifier` now answers consistently from that set.
1646
+ * ```
1647
+ */
1648
+ static readonly makeTest: (overrides?: Partial<WorkspaceCatalogsShape>) => WorkspaceCatalogsShape;
1649
+ /**
1650
+ * The test layer: {@link WorkspaceCatalogs.makeTest} behind `Layer.succeed`,
1651
+ * so a suite provides only the methods it exercises.
1652
+ *
1653
+ * @remarks
1654
+ * A parameterized layer factory mints a **fresh reference per call**, and
1655
+ * layers memoize by reference — bind the result to a `const` and reuse it
1656
+ * rather than calling `layerTest(...)` at each composition site.
1657
+ *
1658
+ * @example
1659
+ * ```ts
1660
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
1661
+ * import { Effect } from "effect";
1662
+ *
1663
+ * const TestCatalogs = WorkspaceCatalogs.layerTest({
1664
+ * set: () => Effect.succeed(CatalogSet.empty()),
1665
+ * });
1666
+ * // program.pipe(Effect.provide(TestCatalogs))
1667
+ * ```
1668
+ */
1669
+ static readonly layerTest: (overrides?: Partial<WorkspaceCatalogsShape>) => Layer.Layer<WorkspaceCatalogs>;
1556
1670
  /**
1557
1671
  * The real implementation of `@effected/npm`'s `CatalogResolver` contract —
1558
1672
  * the one `@effected/package-json` declares but cannot fill.
@@ -1828,6 +1942,62 @@ declare class WorkspaceSnapshots extends WorkspaceSnapshots_base {
1828
1942
  * `const` and reuse it, or layer memoization does not apply.
1829
1943
  */
1830
1944
  static readonly layer: (options?: WorkspaceSnapshotsOptions) => Layer.Layer<WorkspaceSnapshots, never, Git | WorkspaceRoot | WorkspaceDiscovery | WorkspaceCatalogs>;
1945
+ /**
1946
+ * A test double satisfying the full {@link WorkspaceSnapshotsShape} with no
1947
+ * git, filesystem, discovery, or catalog assembly.
1948
+ *
1949
+ * @remarks
1950
+ * There are **no honest defaults and no derivations** here: `at(ref)` and
1951
+ * `worktree()` are two independent reads of two different sources (a git ref
1952
+ * vs. the live tree), so neither can be honestly derived from the other, and
1953
+ * a fabricated empty {@link WorkspaceStateSnapshot} on either side of a
1954
+ * before/after diff reads as every dependency newly added or removed — the
1955
+ * exact silent-empty failure class this package documents on the live paths.
1956
+ * Both methods therefore **die** with an instructive defect until stubbed; a
1957
+ * test-wiring mistake fails loudly as a defect rather than succeeding with a
1958
+ * lie.
1959
+ *
1960
+ * @example
1961
+ * ```ts
1962
+ * import { CatalogSet, WorkspaceSnapshots, WorkspaceStateSnapshot } from "@effected/workspaces";
1963
+ * import { Effect } from "effect";
1964
+ *
1965
+ * const empty = WorkspaceStateSnapshot.make({
1966
+ * packages: [],
1967
+ * catalogs: CatalogSet.empty(),
1968
+ * importerVersions: {},
1969
+ * });
1970
+ * const double = WorkspaceSnapshots.makeTest({
1971
+ * at: () => Effect.succeed(empty),
1972
+ * worktree: () => Effect.succeed(empty),
1973
+ * });
1974
+ * ```
1975
+ */
1976
+ static readonly makeTest: (overrides?: Partial<WorkspaceSnapshotsShape>) => WorkspaceSnapshotsShape;
1977
+ /**
1978
+ * The test layer: {@link WorkspaceSnapshots.makeTest} behind `Layer.succeed`,
1979
+ * so a suite provides only the methods it exercises.
1980
+ *
1981
+ * @remarks
1982
+ * A parameterized layer factory mints a **fresh reference per call**, and
1983
+ * layers memoize by reference — bind the result to a `const` and reuse it
1984
+ * rather than calling `layerTest(...)` at each composition site.
1985
+ *
1986
+ * @example
1987
+ * ```ts
1988
+ * import { CatalogSet, WorkspaceSnapshots, WorkspaceStateSnapshot } from "@effected/workspaces";
1989
+ * import { Effect } from "effect";
1990
+ *
1991
+ * const TestSnapshots = WorkspaceSnapshots.layerTest({
1992
+ * worktree: () =>
1993
+ * Effect.succeed(
1994
+ * WorkspaceStateSnapshot.make({ packages: [], catalogs: CatalogSet.empty(), importerVersions: {} }),
1995
+ * ),
1996
+ * });
1997
+ * // program.pipe(Effect.provide(TestSnapshots))
1998
+ * ```
1999
+ */
2000
+ static readonly layerTest: (overrides?: Partial<WorkspaceSnapshotsShape>) => Layer.Layer<WorkspaceSnapshots>;
1831
2001
  }
1832
2002
  //#endregion
1833
2003
  //#region src/Workspaces.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/workspaces",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "description": "Monorepo workspace tooling as Effect services — root discovery, package enumeration, the dependency graph, package-manager detection, pnpm catalog resolution, lockfile IO and git-based change detection.",
6
6
  "keywords": [
@@ -46,14 +46,14 @@
46
46
  "./package.json": "./package.json"
47
47
  },
48
48
  "dependencies": {
49
- "@effected/git": "~0.4.2",
49
+ "@effected/git": "~0.5.0",
50
50
  "@effected/glob": "~0.2.1",
51
- "@effected/lockfiles": "~0.1.10",
52
- "@effected/npm": "~0.3.1",
53
- "@effected/package-json": "~0.5.1",
51
+ "@effected/lockfiles": "~0.2.0",
52
+ "@effected/npm": "~0.4.0",
53
+ "@effected/package-json": "~0.5.2",
54
54
  "@effected/semver": "~0.2.1",
55
55
  "@effected/walker": "~0.3.2",
56
- "@effected/yaml": "~0.5.1",
56
+ "@effected/yaml": "~0.6.0",
57
57
  "@pnpm/catalogs.config": "^1100.0.0",
58
58
  "@pnpm/catalogs.protocol-parser": "^1100.0.0",
59
59
  "@pnpm/catalogs.resolver": "^1100.0.0",