@effected/workspaces 0.30.4 → 0.31.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/DependencyGraph.js +17 -7
- package/DuplicateCheck.js +8 -7
- package/LayerPolicy.js +1 -1
- package/LockfileReader.js +4 -1
- package/PackageManagerName.js +3 -4
- package/PeerCheck.js +6 -2
- package/Publishability.js +10 -14
- package/README.md +4 -4
- package/ReleaseTag.js +6 -5
- package/SourceBoundary.js +1 -1
- package/VersioningStrategy.js +14 -4
- package/WorkspaceCatalogs.js +3 -4
- package/WorkspaceDiscovery.js +7 -7
- package/WorkspacePackage.js +16 -12
- package/WorkspaceRoot.js +4 -6
- package/WorkspaceSnapshots.js +4 -1
- package/WorkspaceStateSnapshot.js +10 -16
- package/Workspaces.js +13 -17
- package/WorkspacesSync.js +1 -3
- package/index.d.ts +152 -146
- package/internal/importerVersions.js +1 -1
- package/node-sync.d.ts +2 -0
- package/package.json +12 -12
- package/testing.d.ts +41 -40
package/index.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ interface DependencyDiff {
|
|
|
52
52
|
readonly added: Record<string, string>;
|
|
53
53
|
/** Present in the other, absent from the receiver. */
|
|
54
54
|
readonly removed: Record<string, string>;
|
|
55
|
-
/** Present in both at different specifiers. */
|
|
55
|
+
/** Present in both at different specifiers: `from` is the other package's, `to` the receiver's. */
|
|
56
56
|
readonly changed: Record<string, {
|
|
57
57
|
readonly from: string;
|
|
58
58
|
readonly to: string;
|
|
@@ -112,13 +112,9 @@ declare const WorkspacePackage_base: Schema.Class<WorkspacePackage, Schema.Struc
|
|
|
112
112
|
* Absolute path to the workspace root this package was discovered under.
|
|
113
113
|
*
|
|
114
114
|
* @remarks
|
|
115
|
-
* Carried, not derived
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* root arithmetic (counting `relativePath` segments and re-ascending that
|
|
119
|
-
* many `..`). That reconstruction is exact only while `path` and
|
|
120
|
-
* `relativePath` agree, and it re-derives something the kit never had to
|
|
121
|
-
* lose.
|
|
115
|
+
* Carried, not derived: `WorkspaceDiscovery` resolves the root before
|
|
116
|
+
* enumerating, so every package arrives with it and consumers need no
|
|
117
|
+
* per-package root arithmetic over `relativePath`.
|
|
122
118
|
*
|
|
123
119
|
* For the root package this equals `path`, and `relativePath` is `"."`.
|
|
124
120
|
*/
|
|
@@ -145,8 +141,7 @@ declare const WorkspacePackage_base: Schema.Class<WorkspacePackage, Schema.Struc
|
|
|
145
141
|
* validated beyond being a record. For the strict typed model use
|
|
146
142
|
* `manifest()`, which deliberately **re-reads** the file — a point-in-time
|
|
147
143
|
* refresh this captured record cannot provide. Defaults to `{}` for
|
|
148
|
-
*
|
|
149
|
-
* field.
|
|
144
|
+
* values constructed or decoded without the field.
|
|
150
145
|
*/
|
|
151
146
|
readonly manifestRecord: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.Unknown>, never>>;
|
|
152
147
|
}>, {}>;
|
|
@@ -209,8 +204,8 @@ export declare class WorkspacePackage extends WorkspacePackage_base {
|
|
|
209
204
|
/** The declared specifier for `name`, searched across all four kinds. */
|
|
210
205
|
dependencyVersion(name: string): Option.Option<string>;
|
|
211
206
|
/**
|
|
212
|
-
* Whether any dependency name
|
|
213
|
-
*
|
|
207
|
+
* Whether any dependency name (across all four kinds) matches the glob
|
|
208
|
+
* `pattern`, using `@effected/glob`.
|
|
214
209
|
*
|
|
215
210
|
* @remarks
|
|
216
211
|
* A `GlobPattern` is total and free to test. A `string` is compiled on every
|
|
@@ -223,7 +218,12 @@ export declare class WorkspacePackage extends WorkspacePackage_base {
|
|
|
223
218
|
* @param pattern - A compiled pattern, or a source string to compile.
|
|
224
219
|
*/
|
|
225
220
|
matchesDependency(pattern: GlobPattern | string): boolean;
|
|
226
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Compare this package's dependencies against `other`'s, treating `other` as
|
|
223
|
+
* the baseline: what this package added, removed or re-specified.
|
|
224
|
+
*
|
|
225
|
+
* @param other - The package to compare against.
|
|
226
|
+
*/
|
|
227
227
|
dependencyDiff(other: WorkspacePackage): DependencyDiff;
|
|
228
228
|
/**
|
|
229
229
|
* Project to `@effected/lockfiles`' `WorkspaceManifest` — the input shape of
|
|
@@ -234,6 +234,10 @@ export declare class WorkspacePackage extends WorkspacePackage_base {
|
|
|
234
234
|
* Read and decode this package's `package.json` into the strict
|
|
235
235
|
* `@effected/package-json` `Package` model — the bridge from the
|
|
236
236
|
* tolerant discovery projection to the fully typed manifest.
|
|
237
|
+
*
|
|
238
|
+
* @remarks
|
|
239
|
+
* Fails with {@link WorkspaceManifestError} (`kind: "read"` or `"decode"`) and
|
|
240
|
+
* requires core `FileSystem`.
|
|
237
241
|
*/
|
|
238
242
|
static readonly manifest: (self: WorkspacePackage) => Effect.Effect<Package, WorkspaceManifestError, FileSystem.FileSystem>;
|
|
239
243
|
/** Instance form of `WorkspacePackage.manifest`. */
|
|
@@ -370,12 +374,10 @@ export declare class WorkspaceRoot extends WorkspaceRoot_base {
|
|
|
370
374
|
* A test double resolving every `find` to `root`, with no filesystem.
|
|
371
375
|
*
|
|
372
376
|
* @remarks
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
* call pass under test and fail against the live service, which is the
|
|
378
|
-
* failure mode the option exists to catch. A `root` above the ceiling fails
|
|
377
|
+
* Stands in for a hand-written `Layer.succeed` over a `find` that ignores its
|
|
378
|
+
* arguments. Unlike that, this double **honours `stopAt`**: a `find` that
|
|
379
|
+
* ignores the ceiling makes a bounded call pass under test and fail against
|
|
380
|
+
* the live service, which is the failure mode the option exists to catch. A `root` above the ceiling fails
|
|
379
381
|
* here exactly as it would live, with the same
|
|
380
382
|
* {@link WorkspaceRootNotFoundError}.
|
|
381
383
|
*
|
|
@@ -449,7 +451,7 @@ declare const WorkspaceDiscoveryError_base: Schema.Class<WorkspaceDiscoveryError
|
|
|
449
451
|
* A manifest with no `version` is NOT a failure: pnpm accepts a version-less
|
|
450
452
|
* private package and a private monorepo root without one is the ordinary
|
|
451
453
|
* shape, so the member is discovered with `WorkspacePackage.version` absent.
|
|
452
|
-
*
|
|
454
|
+
* Only ABSENCE is tolerated: a
|
|
453
455
|
* `version` that is present but not a string — or present and `""`, which pnpm
|
|
454
456
|
* never wrote and which would resolve `workspace:^` to a bare `"^"` — is the
|
|
455
457
|
* manifest's shape being wrong and reports `invalidShape`.
|
|
@@ -558,11 +560,10 @@ interface WorkspaceDiscoveryOptions {
|
|
|
558
560
|
* `importerMap`, `getPackage`, `resolveFile`, `resolveFiles`). The per-call
|
|
559
561
|
* `infoIn`, `listPackagesIn` and `refreshIn` resolve from an arbitrary
|
|
560
562
|
* directory the caller names, which a single layer-level ceiling cannot
|
|
561
|
-
* sensibly bound, so they ascend unbounded
|
|
563
|
+
* sensibly bound, so they ascend unbounded.
|
|
562
564
|
*
|
|
563
565
|
* `LockfileReader`, `WorkspaceCatalogs` and `WorkspaceSnapshots` each
|
|
564
|
-
* take the same option; give them the same
|
|
565
|
-
* value when wiring by hand, or let a `Workspaces.*` composite forward one
|
|
566
|
+
* take the same option; give them the same value when wiring by hand, or let a `Workspaces.*` composite forward one
|
|
566
567
|
* `stopAt` to all of them, so no service adopts a root another refused.
|
|
567
568
|
*
|
|
568
569
|
* @defaultValue no ceiling — the ascent runs to the filesystem root.
|
|
@@ -659,11 +660,9 @@ declare const WorkspaceDiscovery_base: Context.ServiceClass<WorkspaceDiscovery,
|
|
|
659
660
|
* the lifetime of the layer. A Vitest reporter that builds the layer per call
|
|
660
661
|
* site and never queries it pays nothing.
|
|
661
662
|
*
|
|
662
|
-
* The memo is **success-only
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
* channel. A failure or interrupt is therefore retried on the next call, which
|
|
666
|
-
* is a deliberate behaviour change from the v3 library.
|
|
663
|
+
* The memo is **success-only**: a failure or interrupt is not cached, so an
|
|
664
|
+
* init interrupted by an unrelated timeout cannot brick the layer, and the next
|
|
665
|
+
* call retries.
|
|
667
666
|
*
|
|
668
667
|
* @example
|
|
669
668
|
* ```ts
|
|
@@ -686,12 +685,14 @@ export declare class WorkspaceDiscovery extends WorkspaceDiscovery_base {
|
|
|
686
685
|
*/
|
|
687
686
|
static readonly make: (options?: WorkspaceDiscoveryOptions) => Effect.Effect<WorkspaceDiscoveryShape, never, WorkspaceRoot | FileSystem.FileSystem | Path.Path>;
|
|
688
687
|
/**
|
|
689
|
-
* The live layer.
|
|
688
|
+
* The live layer, discovering the workspace from `options.cwd`.
|
|
690
689
|
*
|
|
691
690
|
* @remarks
|
|
692
691
|
* A parameterized layer factory mints a **fresh reference per call**, and
|
|
693
692
|
* layers memoize by reference — bind the result to a `const` and reuse it
|
|
694
693
|
* rather than calling `layer(...)` at each composition site.
|
|
694
|
+
*
|
|
695
|
+
* @param options - Root resolution and enumeration bounds.
|
|
695
696
|
*/
|
|
696
697
|
static readonly layer: (options?: WorkspaceDiscoveryOptions) => Layer.Layer<WorkspaceDiscovery, never, WorkspaceRoot | FileSystem.FileSystem | Path.Path>;
|
|
697
698
|
/**
|
|
@@ -917,21 +918,19 @@ export declare class ChangeDetector extends ChangeDetector_base {
|
|
|
917
918
|
* **after** computing peer violations, in pnpm's own shape.
|
|
918
919
|
*
|
|
919
920
|
* @remarks
|
|
920
|
-
* The shape is pnpm's
|
|
921
|
-
*
|
|
922
|
-
*
|
|
923
|
-
*
|
|
924
|
-
*
|
|
925
|
-
*
|
|
926
|
-
* against `pnpm peers check` with a firing control. `ignoreMissing` and
|
|
927
|
-
* `allowAny` are lists of **peer-name patterns** in pnpm's `@pnpm/matcher`
|
|
921
|
+
* The shape is pnpm's own, because that is what comes back off the threaded
|
|
922
|
+
* config: a replayed hook returns `{ allowedVersions, ignoreMissing, allowAny }`
|
|
923
|
+
* intact, needing no reshaping.
|
|
924
|
+
*
|
|
925
|
+
* All three axes are consumed by `PeerCheck`, matching `pnpm peers check`.
|
|
926
|
+
* `ignoreMissing` and `allowAny` are lists of **peer-name patterns** in pnpm's `@pnpm/matcher`
|
|
928
927
|
* grammar (`*` wildcard, leading `!` negation) — not `parent>peer` keys, which
|
|
929
928
|
* match nothing on those two axes. `ignoreMissing` hides only a required peer
|
|
930
929
|
* that resolved to nothing; `allowAny` hides only a peer that resolved outside
|
|
931
930
|
* its wanted range; the two never cross.
|
|
932
931
|
*
|
|
933
932
|
* `allowedVersions` keys come in two spellings in the wild, and both must be
|
|
934
|
-
* handled: parent-versioned (`"@effect/ai-anthropic@4.0.0
|
|
933
|
+
* handled: parent-versioned (`"@effect/ai-anthropic@4.0.0>effect"`, as
|
|
935
934
|
* `pnpm:export` materializes them into `pnpm-workspace.yaml`) and unversioned
|
|
936
935
|
* (`"@effect/vitest>vitest"`, as a config-dependency plugin injects them).
|
|
937
936
|
*
|
|
@@ -1047,15 +1046,11 @@ interface HookInjection {
|
|
|
1047
1046
|
* @remarks
|
|
1048
1047
|
* Effective rather than hook-only because the rules are **seeded** into the
|
|
1049
1048
|
* threaded config and the hooks merge onto them, exactly as pnpm seeds its
|
|
1050
|
-
* own config and takes back what the hooks return
|
|
1051
|
-
*
|
|
1052
|
-
* seam already enforces, and the two would drift the first time pnpm changed
|
|
1053
|
-
* its threading.
|
|
1049
|
+
* own config and takes back what the hooks return, so there is no second
|
|
1050
|
+
* merge implementation to drift from pnpm's threading.
|
|
1054
1051
|
*
|
|
1055
|
-
*
|
|
1056
|
-
* onto
|
|
1057
|
-
* that is pnpm's own behaviour reproduced — a hook that overwrites
|
|
1058
|
-
* overwrites for pnpm too — so do not "repair" it into a merger.
|
|
1052
|
+
* A plugin whose hook *overwrites* the seeded rules rather than merging
|
|
1053
|
+
* onto them replaces them here exactly as it does under pnpm.
|
|
1059
1054
|
*/
|
|
1060
1055
|
readonly peerDependencyRules: PeerDependencyRules;
|
|
1061
1056
|
/**
|
|
@@ -1489,8 +1484,9 @@ declare const DependencyGraph_base: Schema.Class<DependencyGraph, Schema.Struct<
|
|
|
1489
1484
|
* `dependencies`, `devDependencies`, `peerDependencies` and
|
|
1490
1485
|
* `optionalDependencies`; a self-edge is dropped.
|
|
1491
1486
|
*
|
|
1492
|
-
* Total accessors never fail
|
|
1493
|
-
*
|
|
1487
|
+
* Total accessors never fail. The lookups fail with `PackageNotFoundError` for
|
|
1488
|
+
* an unknown name, and the ordering operations (`levels`, `sort`, `sortSubset`)
|
|
1489
|
+
* fail with {@link CyclicDependencyError} when the graph has a cycle.
|
|
1494
1490
|
*
|
|
1495
1491
|
* @example
|
|
1496
1492
|
* ```ts
|
|
@@ -1525,8 +1521,11 @@ export declare class DependencyGraph extends DependencyGraph_base {
|
|
|
1525
1521
|
/** The workspace packages that depend on `name`, sorted. */
|
|
1526
1522
|
readonly dependentsOf: (name: string) => Effect.Effect<readonly string[], PackageNotFoundError, never>;
|
|
1527
1523
|
/**
|
|
1528
|
-
* `
|
|
1529
|
-
* radius of a change. Sorted;
|
|
1524
|
+
* Each of `names` plus every package that transitively depends on any of
|
|
1525
|
+
* them — the blast radius of a change. Sorted and de-duplicated; the given
|
|
1526
|
+
* names are included, whether or not the graph knows them.
|
|
1527
|
+
*
|
|
1528
|
+
* @param names - The changed package names.
|
|
1530
1529
|
*/
|
|
1531
1530
|
readonly affectedBy: (names: readonly string[]) => Effect.Effect<readonly string[], never, never>;
|
|
1532
1531
|
/**
|
|
@@ -1534,9 +1533,8 @@ export declare class DependencyGraph extends DependencyGraph_base {
|
|
|
1534
1533
|
* the workspace, level *n* depends only on levels below it.
|
|
1535
1534
|
*
|
|
1536
1535
|
* @remarks
|
|
1537
|
-
* Kahn's algorithm over the reverse-edge index
|
|
1538
|
-
*
|
|
1539
|
-
* lexicographically, so the output is deterministic.
|
|
1536
|
+
* Kahn's algorithm over the reverse-edge index, linear in the edge count.
|
|
1537
|
+
* Each level is sorted lexicographically, so the output is deterministic.
|
|
1540
1538
|
*/
|
|
1541
1539
|
readonly levels: () => Effect.Effect<readonly (readonly string[])[], CyclicDependencyError, never>;
|
|
1542
1540
|
/** The flattened topological order — `levels()` concatenated. */
|
|
@@ -1544,6 +1542,13 @@ export declare class DependencyGraph extends DependencyGraph_base {
|
|
|
1544
1542
|
/**
|
|
1545
1543
|
* A topological order over `names` plus their transitive workspace
|
|
1546
1544
|
* dependencies — the build order for a subset.
|
|
1545
|
+
*
|
|
1546
|
+
* @remarks
|
|
1547
|
+
* Fails with `PackageNotFoundError` for a name the graph does not contain,
|
|
1548
|
+
* and with {@link CyclicDependencyError} when the subset's closure has a
|
|
1549
|
+
* cycle.
|
|
1550
|
+
*
|
|
1551
|
+
* @param names - The packages to build; each must be a workspace package.
|
|
1547
1552
|
*/
|
|
1548
1553
|
readonly sortSubset: (names: readonly string[]) => Effect.Effect<readonly string[], CyclicDependencyError | PackageNotFoundError, never>;
|
|
1549
1554
|
/**
|
|
@@ -1680,8 +1685,8 @@ declare const DuplicateCheck_base: Schema.Class<DuplicateCheck, Schema.Struct<{
|
|
|
1680
1685
|
* In practice this is the **root importer under npm and bun**: neither
|
|
1681
1686
|
* records a resolved version per importer dependency, and neither emits a
|
|
1682
1687
|
* package row for the root, so there is nothing to join on. pnpm records a
|
|
1683
|
-
* version per importer dependency and is unaffected.
|
|
1684
|
-
*
|
|
1688
|
+
* version per importer dependency and is unaffected. `PeerCheck` reports the
|
|
1689
|
+
* same limitation.
|
|
1685
1690
|
*
|
|
1686
1691
|
* Reported rather than silently skipped: a gate that sees no duplicates is
|
|
1687
1692
|
* entitled to know whether that means "clean" or "not looked at".
|
|
@@ -1702,10 +1707,12 @@ declare const DuplicateCheck_base: Schema.Class<DuplicateCheck, Schema.Struct<{
|
|
|
1702
1707
|
*
|
|
1703
1708
|
* @example
|
|
1704
1709
|
* ```ts
|
|
1705
|
-
* import { DuplicateCheck } from "@effected/workspaces";
|
|
1706
1710
|
* import { Lockfile } from "@effected/lockfiles";
|
|
1711
|
+
* import { DuplicateCheck } from "@effected/workspaces";
|
|
1707
1712
|
* import { Effect } from "effect";
|
|
1708
1713
|
*
|
|
1714
|
+
* declare const text: string; // the text of a pnpm-lock.yaml
|
|
1715
|
+
*
|
|
1709
1716
|
* const program = Effect.gen(function* () {
|
|
1710
1717
|
* const lockfile = yield* Lockfile.parse(text, { format: "pnpm" });
|
|
1711
1718
|
* const report = DuplicateCheck.run(lockfile, { names: DuplicateCheck.kit });
|
|
@@ -1741,8 +1748,7 @@ export declare class DuplicateCheck extends DuplicateCheck_base {
|
|
|
1741
1748
|
* Exactly those — not `@effect/*`, and not names merely starting with
|
|
1742
1749
|
* `effect`. A duplicated kit package presents as a `Layer` requirement that
|
|
1743
1750
|
* looks provided yet cannot be satisfied, at the entry point, naming neither
|
|
1744
|
-
* the package nor the skew
|
|
1745
|
-
* names both.
|
|
1751
|
+
* the package nor the skew; this predicate is the check that names both.
|
|
1746
1752
|
*
|
|
1747
1753
|
* @param name - a package name
|
|
1748
1754
|
* @returns whether the name belongs to the kit
|
|
@@ -1946,8 +1952,7 @@ export declare class PackageManagerDetector extends PackageManagerDetector_base
|
|
|
1946
1952
|
* `WorkspaceDiscovery.info` posture, for the same reason. A stand-in that
|
|
1947
1953
|
* answered `"pnpm"` would hand a consumer a fact nothing established, and it
|
|
1948
1954
|
* would contradict the very service it stands in for: the live detector's
|
|
1949
|
-
* defining property is that it
|
|
1950
|
-
* guess](https://github.com/spencerbeggs/effected) when no evidence matches.
|
|
1955
|
+
* defining property is that it refuses to guess when no evidence matches.
|
|
1951
1956
|
* A double that guesses is worse than no double.
|
|
1952
1957
|
*
|
|
1953
1958
|
* Failing typed would be the subtler mistake: `PackageManagerDetectionError`
|
|
@@ -2017,8 +2022,7 @@ export declare class LockfileReadError extends LockfileReadError_base {
|
|
|
2017
2022
|
get message(): string;
|
|
2018
2023
|
}
|
|
2019
2024
|
/**
|
|
2020
|
-
* Every failure the lockfile methods can surface
|
|
2021
|
-
* union the review named best-in-class DX.
|
|
2025
|
+
* Every failure the lockfile methods can surface.
|
|
2022
2026
|
*
|
|
2023
2027
|
* @remarks
|
|
2024
2028
|
* Layer construction does no IO, so every member surfaces from the *methods*
|
|
@@ -2044,9 +2048,7 @@ interface LockfileReaderShape {
|
|
|
2044
2048
|
* @remarks
|
|
2045
2049
|
* A name can resolve at **several versions** in one lockfile (two members
|
|
2046
2050
|
* depending on different majors of the same package). This returns the
|
|
2047
|
-
* **first** entry in lockfile order and does not
|
|
2048
|
-
* is no single "the" version to return, and picking the highest semver would
|
|
2049
|
-
* imply a resolution decision this reader is not entitled to make. Callers
|
|
2051
|
+
* **first** entry in lockfile order and does not rank them. Callers
|
|
2050
2052
|
* that must see every resolution should read `lockfile.packagesNamed(name)`
|
|
2051
2053
|
* off `read()` directly.
|
|
2052
2054
|
*/
|
|
@@ -2114,11 +2116,14 @@ export declare class LockfileReader extends LockfileReader_base {
|
|
|
2114
2116
|
/** Builds the service. */
|
|
2115
2117
|
static readonly make: (options?: LockfileReaderOptions) => Effect.Effect<LockfileReaderShape, never, WorkspaceRoot | PackageManagerDetector | WorkspaceDiscovery | FileSystem.FileSystem | Path.Path>;
|
|
2116
2118
|
/**
|
|
2117
|
-
* The live layer
|
|
2119
|
+
* The live layer: reads the lockfile of the detected package manager at the
|
|
2120
|
+
* workspace root.
|
|
2118
2121
|
*
|
|
2119
2122
|
* @remarks
|
|
2120
2123
|
* Parameterized, so it mints a fresh reference per call — bind it to a
|
|
2121
2124
|
* `const` and reuse it.
|
|
2125
|
+
*
|
|
2126
|
+
* @param options - Root resolution (`cwd`, `stopAt`).
|
|
2122
2127
|
*/
|
|
2123
2128
|
static readonly layer: (options?: LockfileReaderOptions) => Layer.Layer<LockfileReader, never, WorkspaceRoot | PackageManagerDetector | WorkspaceDiscovery | FileSystem.FileSystem | Path.Path>;
|
|
2124
2129
|
/**
|
|
@@ -2585,10 +2590,9 @@ export declare class WorkspaceCatalogs extends WorkspaceCatalogs_base {
|
|
|
2585
2590
|
* `rangeOf` returns `Option.none()` for a dependency no catalog declares, per
|
|
2586
2591
|
* the contract's convention. A failed catalog *assembly* — an unreadable or
|
|
2587
2592
|
* malformed `pnpm-workspace.yaml`, a broken config-dependency hook — passes
|
|
2588
|
-
* through **typed** as the contract's `CatalogAssemblyError
|
|
2589
|
-
*
|
|
2590
|
-
*
|
|
2591
|
-
* an unfindable workspace root, is wrapped as `DependencyResolutionError`.
|
|
2593
|
+
* through **typed** as the contract's `CatalogAssemblyError`; only the
|
|
2594
|
+
* remaining mechanism failure, an unfindable workspace root, is wrapped as
|
|
2595
|
+
* `DependencyResolutionError`.
|
|
2592
2596
|
*/
|
|
2593
2597
|
static readonly catalogResolver: Layer.Layer<CatalogResolver, never, WorkspaceCatalogs>;
|
|
2594
2598
|
}
|
|
@@ -2598,7 +2602,7 @@ export declare class WorkspaceCatalogs extends WorkspaceCatalogs_base {
|
|
|
2598
2602
|
* Why a report is not a complete answer.
|
|
2599
2603
|
*
|
|
2600
2604
|
* @remarks
|
|
2601
|
-
* Closed at exactly four
|
|
2605
|
+
* Closed at exactly four:
|
|
2602
2606
|
*
|
|
2603
2607
|
* - `"peerRulesNotApplied"` — the effective suppression policy was not applied,
|
|
2604
2608
|
* so pnpm's post-hoc suppression could not be replicated and some reported
|
|
@@ -2606,7 +2610,7 @@ export declare class WorkspaceCatalogs extends WorkspaceCatalogs_base {
|
|
|
2606
2610
|
* because "nobody looked" and "I looked and there are none" are different
|
|
2607
2611
|
* facts. Supplied rules never produce it: all three axes —
|
|
2608
2612
|
* `allowedVersions`, `ignoreMissing` and `allowAny` — are applied with
|
|
2609
|
-
* pnpm's
|
|
2613
|
+
* pnpm's semantics.
|
|
2610
2614
|
* - `"unresolvedEdge"` — some instance records an edge this model could not
|
|
2611
2615
|
* name (`ResolvedPackage.unresolvedEdges`), or an importer dependency
|
|
2612
2616
|
* resolved through `link:` whose target the caller did not supply, so its
|
|
@@ -2663,8 +2667,8 @@ type UnverifiedReason = "peerRulesNotApplied" | "unresolvedEdge" | "peerRangeUnr
|
|
|
2663
2667
|
* different results, because a gate must be able to tell "clean" from
|
|
2664
2668
|
* "unchecked".
|
|
2665
2669
|
*
|
|
2666
|
-
* **All three axes of the supplied rules are applied**, each with
|
|
2667
|
-
* semantics
|
|
2670
|
+
* **All three axes of the supplied rules are applied**, each with pnpm's
|
|
2671
|
+
* semantics (see {@link PeerCheck.run}): `allowedVersions`
|
|
2668
2672
|
* permits a resolved version by range, `ignoreMissing` hides a required peer
|
|
2669
2673
|
* nothing resolved for, and `allowAny` hides a peer that resolved outside its
|
|
2670
2674
|
* range. The two list axes are name patterns, never `parent>peer` keys.
|
|
@@ -2833,10 +2837,12 @@ declare const PeerCheck_base: Schema.Class<PeerCheck, Schema.Struct<{
|
|
|
2833
2837
|
*
|
|
2834
2838
|
* @example
|
|
2835
2839
|
* ```ts
|
|
2836
|
-
* import { PeerCheck } from "@effected/workspaces";
|
|
2837
2840
|
* import { Lockfile } from "@effected/lockfiles";
|
|
2841
|
+
* import { PeerCheck } from "@effected/workspaces";
|
|
2838
2842
|
* import { Effect } from "effect";
|
|
2839
2843
|
*
|
|
2844
|
+
* declare const text: string; // the text of a pnpm-lock.yaml
|
|
2845
|
+
*
|
|
2840
2846
|
* const program = Effect.gen(function* () {
|
|
2841
2847
|
* const lockfile = yield* Lockfile.parse(text, { format: "pnpm" });
|
|
2842
2848
|
* const report = PeerCheck.run(lockfile);
|
|
@@ -2895,7 +2901,7 @@ export declare class PeerCheck extends PeerCheck_base {
|
|
|
2895
2901
|
* `pnpm peers check` DOES report the linked parent's peers (it reads the
|
|
2896
2902
|
* manifest on disk): every `link:` edge whose target the caller did not
|
|
2897
2903
|
* supply therefore fails the report closed rather than letting the
|
|
2898
|
-
* invisible parent pass as checked
|
|
2904
|
+
* invisible parent pass as checked.
|
|
2899
2905
|
*
|
|
2900
2906
|
* Supplying {@link PeerCheckOptions.workspacePackages} closes that gap for
|
|
2901
2907
|
* every `link:` target the set covers — the root importer's included,
|
|
@@ -2930,6 +2936,8 @@ export declare class PeerCheck extends PeerCheck_base {
|
|
|
2930
2936
|
* version check, and a plain unparseable version is still skipped.
|
|
2931
2937
|
*
|
|
2932
2938
|
* @param lockfile - a lockfile parsed by `@effected/lockfiles`
|
|
2939
|
+
* @param options - the workspace's effective rules, manifests and catalogs; see
|
|
2940
|
+
* {@link PeerCheckOptions}
|
|
2933
2941
|
* @returns the report; never fails
|
|
2934
2942
|
*/
|
|
2935
2943
|
static run(lockfile: Lockfile, options?: PeerCheckOptions): PeerCheck;
|
|
@@ -3050,16 +3058,13 @@ declare const PublishabilityDetector_base: Context.ServiceClass<PublishabilityDe
|
|
|
3050
3058
|
export declare class PublishabilityDetector extends PublishabilityDetector_base {
|
|
3051
3059
|
/**
|
|
3052
3060
|
* Standard npm publishing semantics, **as a value**. Pure — no filesystem,
|
|
3053
|
-
* no platform services.
|
|
3061
|
+
* no platform services. Never publishes with provenance (`provenance: false`).
|
|
3054
3062
|
*
|
|
3055
3063
|
* @remarks
|
|
3056
3064
|
* Exposed as a shape and not only as a layer, because a consumer composing
|
|
3057
|
-
* *around* these rules cannot reach them through a layer without
|
|
3058
|
-
* the very tag it is replacing.
|
|
3059
|
-
* `
|
|
3060
|
-
* **inside its own implementation of that tag** to get at this function for
|
|
3061
|
-
* its pass-through branch; with the value exposed that becomes
|
|
3062
|
-
* `PublishabilityDetector.npm.detect(pkg)`.
|
|
3065
|
+
* *around* these rules cannot reach them through a layer without
|
|
3066
|
+
* re-entering the very tag it is replacing. A custom detector's pass-through
|
|
3067
|
+
* branch calls `PublishabilityDetector.npm.detect(pkg)` directly.
|
|
3063
3068
|
*
|
|
3064
3069
|
* @example
|
|
3065
3070
|
* ```ts
|
|
@@ -3083,13 +3088,12 @@ export declare class PublishabilityDetector extends PublishabilityDetector_base
|
|
|
3083
3088
|
*
|
|
3084
3089
|
* @remarks
|
|
3085
3090
|
* Named for its policy rather than called `layer`, deliberately. **No
|
|
3086
|
-
* composite in this package provides a publishability detector**:
|
|
3087
|
-
*
|
|
3088
|
-
*
|
|
3089
|
-
*
|
|
3090
|
-
*
|
|
3091
|
-
*
|
|
3092
|
-
* the worst available failure.
|
|
3091
|
+
* composite in this package provides a publishability detector**: one that
|
|
3092
|
+
* quietly supplied npm semantics would hide the choice and, because
|
|
3093
|
+
* `Layer.mergeAll` is last-wins, would let a naively-ordered override such
|
|
3094
|
+
* as `Layer.mergeAll(myDetector, Workspaces.layer())` lose to the default in
|
|
3095
|
+
* silence. For a service that decides whether a package publishes and to
|
|
3096
|
+
* which registry, that silent revert is the worst available failure.
|
|
3093
3097
|
*
|
|
3094
3098
|
* The composites do not *require* a detector either — nothing inside them
|
|
3095
3099
|
* asks a publishability question, so their `R` stays `FileSystem | Path`.
|
|
@@ -3297,11 +3301,11 @@ declare const ReleaseTag_base: Schema.Class<ReleaseTag, Schema.Struct<{
|
|
|
3297
3301
|
* even when `value` carries a prefix, so a consumer comparing versions never
|
|
3298
3302
|
* has to strip one back off.
|
|
3299
3303
|
*
|
|
3300
|
-
* Formatting
|
|
3301
|
-
*
|
|
3302
|
-
*
|
|
3303
|
-
*
|
|
3304
|
-
*
|
|
3304
|
+
* Formatting has **no error channel**: an empty version is rejected by
|
|
3305
|
+
* `Schema.NonEmptyString` when the value is constructed. A bad version
|
|
3306
|
+
* reaching these statics is developer wiring rather than untrusted input, so it
|
|
3307
|
+
* dies as a defect, the same posture as an uncompilable glob literal in
|
|
3308
|
+
* `WorkspacePackage.matchesDependency`.
|
|
3305
3309
|
*
|
|
3306
3310
|
* @example
|
|
3307
3311
|
* ```ts
|
|
@@ -3321,6 +3325,7 @@ export declare class ReleaseTag extends ReleaseTag_base {
|
|
|
3321
3325
|
*
|
|
3322
3326
|
* @param version - The version being released. Must not be empty.
|
|
3323
3327
|
* @param options - Formatting overrides.
|
|
3328
|
+
* @returns the single-style {@link ReleaseTag}.
|
|
3324
3329
|
*/
|
|
3325
3330
|
static single(version: string, options?: TagFormatOptions): ReleaseTag;
|
|
3326
3331
|
/**
|
|
@@ -3419,13 +3424,13 @@ declare const VersioningStrategy_base: Schema.Class<VersioningStrategy, Schema.S
|
|
|
3419
3424
|
*
|
|
3420
3425
|
* @example
|
|
3421
3426
|
* ```ts
|
|
3422
|
-
* import { VersioningStrategy } from "@effected/workspaces";
|
|
3427
|
+
* import { PublishabilityDetector, VersioningStrategy } from "@effected/workspaces";
|
|
3423
3428
|
* import { Effect } from "effect";
|
|
3424
3429
|
*
|
|
3425
3430
|
* const program = Effect.gen(function* () {
|
|
3426
|
-
* const strategy = yield* VersioningStrategy.detect({ fixedGroups });
|
|
3427
|
-
* return strategy.tagsFor(
|
|
3428
|
-
* });
|
|
3431
|
+
* const strategy = yield* VersioningStrategy.detect({ fixedGroups: [["@acme/a", "@acme/b"]] });
|
|
3432
|
+
* return strategy.tagsFor([{ name: "@acme/a", version: "1.2.3" }]).map((tag) => tag.value);
|
|
3433
|
+
* }).pipe(Effect.provide(PublishabilityDetector.layerNpm));
|
|
3429
3434
|
* ```
|
|
3430
3435
|
*
|
|
3431
3436
|
* @public
|
|
@@ -3444,6 +3449,9 @@ export declare class VersioningStrategy extends VersioningStrategy_base {
|
|
|
3444
3449
|
* Pure and total — no IO, no error channel. `packages` is sorted and
|
|
3445
3450
|
* de-duplicated first, so a name listed twice cannot inflate a one-package
|
|
3446
3451
|
* repo into an independent one.
|
|
3452
|
+
*
|
|
3453
|
+
* @param options - The publishable package names and any fixed groups.
|
|
3454
|
+
* @returns the classified {@link VersioningStrategy}.
|
|
3447
3455
|
*/
|
|
3448
3456
|
static classify(options: ClassifyOptions): VersioningStrategy;
|
|
3449
3457
|
/**
|
|
@@ -3454,6 +3462,10 @@ export declare class VersioningStrategy extends VersioningStrategy_base {
|
|
|
3454
3462
|
* The publishability question is asked through the service precisely so a
|
|
3455
3463
|
* consumer with its own rules — honouring a release tool's ignore list, say —
|
|
3456
3464
|
* swaps the layer instead of filtering afterwards.
|
|
3465
|
+
*
|
|
3466
|
+
* Requires `WorkspaceDiscovery` and `PublishabilityDetector` (for example
|
|
3467
|
+
* `PublishabilityDetector.layerNpm`) in `R`, and fails with
|
|
3468
|
+
* `WorkspaceDiscoveryFailure` when discovery does.
|
|
3457
3469
|
*/
|
|
3458
3470
|
static readonly detect: (options?: VersioningDetectOptions | undefined) => Effect.Effect<VersioningStrategy, WorkspaceDiscoveryFailure, PublishabilityDetector | WorkspaceDiscovery>;
|
|
3459
3471
|
/**
|
|
@@ -3469,6 +3481,9 @@ export declare class VersioningStrategy extends VersioningStrategy_base {
|
|
|
3469
3481
|
* one-line check rather than a field here.
|
|
3470
3482
|
*
|
|
3471
3483
|
* An empty batch produces no tags under either style.
|
|
3484
|
+
*
|
|
3485
|
+
* @param releases - The packages released and their versions.
|
|
3486
|
+
* @param options - Tag formatting overrides, such as `versionPrefix`.
|
|
3472
3487
|
*/
|
|
3473
3488
|
tagsFor(releases: ReadonlyArray<PackageRelease>, options?: TagFormatOptions): ReadonlyArray<ReleaseTag>;
|
|
3474
3489
|
}
|
|
@@ -3486,8 +3501,7 @@ declare const PackageStateSnapshot_base: Schema.Class<PackageStateSnapshot, Sche
|
|
|
3486
3501
|
* an ordinary pnpm shape. Both capture paths — `WorkspaceSnapshots.at(ref)`
|
|
3487
3502
|
* and `WorkspaceSnapshots.worktree()` — omit the key for such a member, so
|
|
3488
3503
|
* the two sides of a diff agree without a placeholder. Never `""`: `make`
|
|
3489
|
-
* rejects it, and a
|
|
3490
|
-
* sentinel decodes to the absent key.
|
|
3504
|
+
* rejects it, and a stored `""` decodes to the absent key.
|
|
3491
3505
|
*
|
|
3492
3506
|
* A version-less member is still a member: it appears in `packages` and
|
|
3493
3507
|
* answers {@link WorkspaceStateSnapshot.package}, but is absent from
|
|
@@ -3542,11 +3556,9 @@ declare const WorkspaceStateSnapshot_base: Schema.Class<WorkspaceStateSnapshot,
|
|
|
3542
3556
|
* lockfile recorded it at this moment.
|
|
3543
3557
|
*
|
|
3544
3558
|
* @remarks
|
|
3545
|
-
* Defaults to `{}
|
|
3546
|
-
*
|
|
3547
|
-
*
|
|
3548
|
-
* the behavior those older values were captured under. Only pnpm records
|
|
3549
|
-
* importer versions; bun and npm yield an empty index.
|
|
3559
|
+
* Defaults to `{}` when absent from a stored value; an empty index makes the
|
|
3560
|
+
* `catalog:` fallback in {@link WorkspaceStateSnapshot.resolve} inert. Only
|
|
3561
|
+
* pnpm records importer versions; bun and npm yield an empty index.
|
|
3550
3562
|
*/
|
|
3551
3563
|
readonly importerVersions: Schema.optionalKey<Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.String>>>;
|
|
3552
3564
|
/**
|
|
@@ -3560,9 +3572,8 @@ declare const WorkspaceStateSnapshot_base: Schema.Class<WorkspaceStateSnapshot,
|
|
|
3560
3572
|
* diagnostic and off this serializable value. Every fresh read sets the
|
|
3561
3573
|
* field: `{}` under the no-op layer, which resolves nothing, when the file
|
|
3562
3574
|
* declares no config dependencies, or on the bun / `package.json` path,
|
|
3563
|
-
* where config dependencies do not exist. Absent only when decoding a
|
|
3564
|
-
*
|
|
3565
|
-
* readable. Carried through `withSeededCatalogs` and `crossSeed`
|
|
3575
|
+
* where config dependencies do not exist. Absent only when decoding a stored
|
|
3576
|
+
* value that omits it. Carried through `withSeededCatalogs` and `crossSeed`
|
|
3566
3577
|
* unchanged, like `importerVersions`.
|
|
3567
3578
|
*/
|
|
3568
3579
|
readonly hookReplays: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
|
|
@@ -3588,8 +3599,7 @@ declare const WorkspaceStateSnapshot_base: Schema.Class<WorkspaceStateSnapshot,
|
|
|
3588
3599
|
* replays the ref's own pinned hook and the seed answers only what neither
|
|
3589
3600
|
* source declared.
|
|
3590
3601
|
*
|
|
3591
|
-
* Defaults to absent, which makes the seed inert
|
|
3592
|
-
* every snapshot captured before this field existed.
|
|
3602
|
+
* Defaults to absent, which makes the seed inert.
|
|
3593
3603
|
*/
|
|
3594
3604
|
readonly seededCatalogs: Schema.optionalKey<typeof CatalogSet>;
|
|
3595
3605
|
}>, {}>;
|
|
@@ -3898,8 +3908,7 @@ interface WorkspaceSnapshotsOptions {
|
|
|
3898
3908
|
* hook-injected catalogs at full precedence, so the seed answers nothing the
|
|
3899
3909
|
* snapshot could not answer itself.
|
|
3900
3910
|
*
|
|
3901
|
-
* @defaultValue absent — no seed
|
|
3902
|
-
* this option existed.
|
|
3911
|
+
* @defaultValue absent — no seed.
|
|
3903
3912
|
*/
|
|
3904
3913
|
readonly seedCatalogs?: CatalogSet;
|
|
3905
3914
|
}
|
|
@@ -3964,11 +3973,14 @@ export declare class WorkspaceSnapshots extends WorkspaceSnapshots_base {
|
|
|
3964
3973
|
*/
|
|
3965
3974
|
static readonly make: (options?: WorkspaceSnapshotsOptions) => Effect.Effect<WorkspaceSnapshotsShape, never, Git | WorkspaceRoot | WorkspaceDiscovery | WorkspaceCatalogs | ConfigDependencyHooks>;
|
|
3966
3975
|
/**
|
|
3967
|
-
* The live layer
|
|
3976
|
+
* The live layer, reading workspace state at a git ref or from the live
|
|
3977
|
+
* worktree.
|
|
3968
3978
|
*
|
|
3969
3979
|
* @remarks
|
|
3970
3980
|
* Parameterized, so it mints a fresh reference per call — bind it to a
|
|
3971
3981
|
* `const` and reuse it, or layer memoization does not apply.
|
|
3982
|
+
*
|
|
3983
|
+
* @param options - Root resolution and the optional `seedCatalogs`.
|
|
3972
3984
|
*/
|
|
3973
3985
|
static readonly layer: (options?: WorkspaceSnapshotsOptions) => Layer.Layer<WorkspaceSnapshots, never, Git | WorkspaceRoot | WorkspaceDiscovery | WorkspaceCatalogs | ConfigDependencyHooks>;
|
|
3974
3986
|
/**
|
|
@@ -4113,10 +4125,9 @@ export declare class Workspaces {
|
|
|
4113
4125
|
* `@effected/memfs` volume).
|
|
4114
4126
|
*
|
|
4115
4127
|
* **`PublishabilityDetector` is neither provided nor required here.** The
|
|
4116
|
-
* composite
|
|
4117
|
-
*
|
|
4118
|
-
*
|
|
4119
|
-
* `R` either. The requirement surfaces in the `R` of each operation that
|
|
4128
|
+
* composite supplies no default policy, and — because nothing inside it asks
|
|
4129
|
+
* a publishability question — it does not require one in `R` either. The
|
|
4130
|
+
* requirement surfaces in the `R` of each operation that
|
|
4120
4131
|
* asks (`VersioningStrategy.detect`, e.g.), so a program that asks and never
|
|
4121
4132
|
* wires a detector fails to compile at that operation, and a program that
|
|
4122
4133
|
* never asks never supplies a publish policy. Wire one explicitly where
|
|
@@ -4197,10 +4208,9 @@ export declare class Workspaces {
|
|
|
4197
4208
|
* `pnpmfile.cjs` hooks**.
|
|
4198
4209
|
*
|
|
4199
4210
|
* @remarks
|
|
4200
|
-
*
|
|
4201
|
-
*
|
|
4202
|
-
*
|
|
4203
|
-
* `@savvy-web/silk-effects` did, and the copy this static deletes.
|
|
4211
|
+
* `layerWithGit` wires the no-op catalogs layer, so this is the composite to
|
|
4212
|
+
* reach for when you want snapshots, git and hook replay together without
|
|
4213
|
+
* assembling the service graph by hand.
|
|
4204
4214
|
*
|
|
4205
4215
|
* Requirements are unchanged from {@link Workspaces.layerWithGit}: a
|
|
4206
4216
|
* filesystem, a path service, and core's `ChildProcessSpawner` (behind
|
|
@@ -4263,8 +4273,7 @@ export declare class Workspaces {
|
|
|
4263
4273
|
* and {@link ConfigDependencyHooks.layerSubprocess}. It exists for the fourth
|
|
4264
4274
|
* policy: {@link ConfigDependencyHooks.layerFrom}, the hermetic seam, which a
|
|
4265
4275
|
* snapshot-backed test otherwise cannot reach without rebuilding the whole
|
|
4266
|
-
* git graph by hand
|
|
4267
|
-
* to delete. The ONE hooks reference is handed to both `WorkspaceCatalogs`
|
|
4276
|
+
* git graph by hand. The ONE hooks reference is handed to both `WorkspaceCatalogs`
|
|
4268
4277
|
* and `WorkspaceSnapshots`, so `at(ref)` and `worktree()` cannot drift on
|
|
4269
4278
|
* which policy they replay. A hooks layer carrying its own requirement (the
|
|
4270
4279
|
* subprocess variant's `ChildProcessSpawner`) threads it through to the
|
|
@@ -4294,13 +4303,11 @@ export declare class Workspaces {
|
|
|
4294
4303
|
* contract: how to run a project-local binary here.
|
|
4295
4304
|
*
|
|
4296
4305
|
* @remarks
|
|
4297
|
-
* **An inverted contract,
|
|
4298
|
-
*
|
|
4299
|
-
*
|
|
4300
|
-
*
|
|
4301
|
-
* package
|
|
4302
|
-
* would drag `npm`, `lockfiles` (pure!) and `package-json` up a tier with
|
|
4303
|
-
* it. So `commands` declares the narrow contract and we ship the layer.
|
|
4306
|
+
* **An inverted contract, like `@effected/npm`'s `CatalogResolver`.** Tool
|
|
4307
|
+
* discovery needs package-manager detection and workspace-root resolution,
|
|
4308
|
+
* both of which live here, but `@effected/commands` must not depend on this
|
|
4309
|
+
* package. So `commands` declares the narrow `LocalExec` contract and this
|
|
4310
|
+
* package ships the layer.
|
|
4304
4311
|
*
|
|
4305
4312
|
* **The argv knowledge is not duplicated.** `LocalExec.prefixes(name)` is
|
|
4306
4313
|
* the one home of the four managers' `exec`/`dlx`/script-runner prefixes;
|
|
@@ -4334,6 +4341,7 @@ export declare class Workspaces {
|
|
|
4334
4341
|
*
|
|
4335
4342
|
* @example
|
|
4336
4343
|
* ```ts
|
|
4344
|
+
* import { NodeServices } from "@effect/platform-node";
|
|
4337
4345
|
* import { ToolDiscovery } from "@effected/commands";
|
|
4338
4346
|
* import { Workspaces } from "@effected/workspaces";
|
|
4339
4347
|
* import { Layer } from "effect";
|
|
@@ -4531,7 +4539,9 @@ interface SyncDirectoryEntry {
|
|
|
4531
4539
|
* satisfies it verbatim:
|
|
4532
4540
|
*
|
|
4533
4541
|
* ```ts
|
|
4542
|
+
* import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
4534
4543
|
* import * as path from "node:path";
|
|
4544
|
+
* import type { WorkspacesSyncOptions } from "@effected/workspaces";
|
|
4535
4545
|
*
|
|
4536
4546
|
* const options: WorkspacesSyncOptions = {
|
|
4537
4547
|
* fileSystem: { exists: existsSync, readFile: (p) => readFileSync(p, "utf8"), readDirectory: (p) => readdirSync(p), isDirectory: (p) => statSync(p).isDirectory() },
|
|
@@ -4577,8 +4587,8 @@ interface WorkspacesSyncOptions {
|
|
|
4577
4587
|
* The same vocabulary the Effect surface fails with, deliberately: a member the
|
|
4578
4588
|
* async `listPackages()` rejects as `missingName` is the member the sync facade
|
|
4579
4589
|
* reports as `missingName`. `invalidYaml` is excluded because it describes the
|
|
4580
|
-
* `pnpm-workspace.yaml` read, not a manifest.
|
|
4581
|
-
*
|
|
4590
|
+
* `pnpm-workspace.yaml` read, not a manifest. A version-less manifest is a
|
|
4591
|
+
* member on both surfaces.
|
|
4582
4592
|
*
|
|
4583
4593
|
* The vocabulary is shared; the CHECKS are shared only as far as this list.
|
|
4584
4594
|
* Both surfaces perform the same five: the file read (`read`), `JSON.parse`
|
|
@@ -4599,10 +4609,10 @@ type WorkspaceDiscoverySkipKind = Exclude<WorkspaceDiscoveryError["kind"], "inva
|
|
|
4599
4609
|
*
|
|
4600
4610
|
* @remarks
|
|
4601
4611
|
* The sync facade is total, so it cannot fail the way `WorkspaceDiscovery`
|
|
4602
|
-
* does — but a skipped member must still be observable.
|
|
4603
|
-
*
|
|
4604
|
-
*
|
|
4605
|
-
*
|
|
4612
|
+
* does — but a skipped member must still be observable. Without a report, a
|
|
4613
|
+
* hand-written fixture with one unusable manifest would enumerate as a
|
|
4614
|
+
* plausible empty array indistinguishable from "no workspaces configured". The
|
|
4615
|
+
* fields mirror
|
|
4606
4616
|
* `WorkspaceDiscoveryError`: `root`, `path`, `kind`, and on `cause` either the
|
|
4607
4617
|
* caught throwable (`read` / `invalidJson`) or an `Error` carrying the same
|
|
4608
4618
|
* sentence the Effect surface fails with (`invalidShape`). Only `missingName`
|
|
@@ -4664,9 +4674,7 @@ interface FindWorkspaceRootSyncOptions extends WorkspacesSyncOptions {
|
|
|
4664
4674
|
* The signature is path-first, options second — the same shape as
|
|
4665
4675
|
* {@link getWorkspacePackagesSync} and the rest of the kit's sync facades
|
|
4666
4676
|
* (`TsconfigLoaderSync.load(configPath, options)`). `cwd` is required and
|
|
4667
|
-
* positional
|
|
4668
|
-
* `process.cwd()` read, which both broke the symmetry with its sibling and
|
|
4669
|
-
* was the module's one platform assumption.
|
|
4677
|
+
* positional, so the function reads no ambient `process.cwd()`.
|
|
4670
4678
|
*
|
|
4671
4679
|
* Markers match the async service exactly: a `pnpm-workspace.yaml`, or a
|
|
4672
4680
|
* `package.json` carrying a `workspaces` field.
|
|
@@ -4723,12 +4731,10 @@ interface GetWorkspacePackagesSyncOptions extends WorkspacesSyncOptions {
|
|
|
4723
4731
|
* though this function is total and has no error channel to raise it on.
|
|
4724
4732
|
*
|
|
4725
4733
|
* @remarks
|
|
4726
|
-
* Omit it and skips are simply not reported
|
|
4727
|
-
*
|
|
4728
|
-
*
|
|
4729
|
-
*
|
|
4730
|
-
* returned first. Its
|
|
4731
|
-
* result is discarded, and a throw from it propagates: the facade is total
|
|
4734
|
+
* Omit it and skips are simply not reported; nothing is logged in its
|
|
4735
|
+
* place. The callback is invoked synchronously, before the result is
|
|
4736
|
+
* returned, in enumeration order — members first, then the root, which is
|
|
4737
|
+
* read last even though it is returned first. Its result is discarded, and a throw from it propagates: the facade is total
|
|
4732
4738
|
* over *data*, not over caller mistakes, exactly as a bad `maxDepth` is.
|
|
4733
4739
|
*/
|
|
4734
4740
|
readonly onSkip?: ((skip: WorkspaceDiscoverySkip) => void) | undefined;
|