@effected/workspaces 0.11.2 → 0.13.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/ConfigDependencyHooks.js +4 -1
- package/DependencyGraph.js +74 -8
- package/PackageManagerName.js +74 -27
- package/README.md +12 -2
- package/index.d.ts +60 -5
- package/index.js +2 -2
- package/package.json +3 -3
package/ConfigDependencyHooks.js
CHANGED
|
@@ -293,7 +293,10 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
|
|
|
293
293
|
const candidatePath = join(root, "node_modules", ".pnpm-config", name, filename);
|
|
294
294
|
const candidateUrl = pathToFileURL(candidatePath).href;
|
|
295
295
|
const result = yield* Effect.result(Effect.tryPromise({
|
|
296
|
-
try: () => import(
|
|
296
|
+
try: () => import(
|
|
297
|
+
/* webpackIgnore: true */
|
|
298
|
+
candidateUrl
|
|
299
|
+
),
|
|
297
300
|
catch: (cause) => cause
|
|
298
301
|
}));
|
|
299
302
|
if (Result.isSuccess(result)) {
|
package/DependencyGraph.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WorkspacePackage } from "./WorkspacePackage.js";
|
|
2
2
|
import { PackageNotFoundError } from "./WorkspaceDiscovery.js";
|
|
3
|
-
import { Effect, Schema } from "effect";
|
|
3
|
+
import { Effect, Graph, Schema } from "effect";
|
|
4
4
|
|
|
5
5
|
//#region src/DependencyGraph.ts
|
|
6
6
|
/**
|
|
@@ -8,9 +8,10 @@ import { Effect, Schema } from "effect";
|
|
|
8
8
|
* because it contains a cycle.
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
* `cycle`
|
|
12
|
-
*
|
|
13
|
-
* set to break, not necessarily
|
|
11
|
+
* `cycle` names the actual cycle members — the sorted union of every strongly
|
|
12
|
+
* connected component with more than one package. Packages merely downstream
|
|
13
|
+
* of a cycle are excluded, so it is exactly the set to break, not necessarily
|
|
14
|
+
* a single ordered loop.
|
|
14
15
|
*
|
|
15
16
|
* @public
|
|
16
17
|
*/
|
|
@@ -165,7 +166,11 @@ packages: Schema.Array(WorkspacePackage) }) {
|
|
|
165
166
|
* the whole adjacency map per processed node. Each level is sorted
|
|
166
167
|
* lexicographically, so the output is deterministic.
|
|
167
168
|
*/
|
|
168
|
-
levels = Effect.fn("DependencyGraph.levels")(() => Effect.suspend(() =>
|
|
169
|
+
levels = Effect.fn("DependencyGraph.levels")(() => Effect.suspend(() => {
|
|
170
|
+
const edges = this.#index();
|
|
171
|
+
const result = kahn(edges);
|
|
172
|
+
return result.stalled.length > 0 ? Effect.fail(new CyclicDependencyError({ cycle: cycleMembers(edges) })) : Effect.succeed(result.levels);
|
|
173
|
+
}));
|
|
169
174
|
/** The flattened topological order — `levels()` concatenated. */
|
|
170
175
|
sort = Effect.fn("DependencyGraph.sort")(() => this.levels().pipe(Effect.map((levels) => levels.flat())));
|
|
171
176
|
/**
|
|
@@ -195,17 +200,78 @@ packages: Schema.Array(WorkspacePackage) }) {
|
|
|
195
200
|
subForward.set(node, deps);
|
|
196
201
|
for (const dep of deps) subReverse.get(dep)?.add(node);
|
|
197
202
|
}
|
|
198
|
-
const
|
|
203
|
+
const subEdges = {
|
|
199
204
|
forward: subForward,
|
|
200
205
|
reverse: subReverse
|
|
201
|
-
}
|
|
202
|
-
|
|
206
|
+
};
|
|
207
|
+
const result = kahn(subEdges);
|
|
208
|
+
return result.stalled.length > 0 ? Effect.fail(new CyclicDependencyError({ cycle: cycleMembers(subEdges) })) : Effect.succeed(result.levels.flat());
|
|
203
209
|
}));
|
|
210
|
+
/**
|
|
211
|
+
* The graph rendered as a Mermaid `flowchart TD`. Total.
|
|
212
|
+
*
|
|
213
|
+
* @remarks
|
|
214
|
+
* Renders through core's `Graph.toMermaid` over a transient graph built from
|
|
215
|
+
* the edge index. Node IDs are numeric indexes assigned in sorted-name order
|
|
216
|
+
* and package names appear only inside quoted labels, so scoped names
|
|
217
|
+
* (`@scope/a`) never break Mermaid syntax. Nodes and each node's edges are
|
|
218
|
+
* emitted in sorted order — the output is deterministic regardless of
|
|
219
|
+
* manifest key order.
|
|
220
|
+
*/
|
|
221
|
+
toMermaid() {
|
|
222
|
+
return Graph.toMermaid(materialize(this.#index()).graph, { edgeLabel: () => "" });
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Materializes the forward map into a transient core `Graph`: nodes in
|
|
227
|
+
* sorted-name order (so `NodeIndex` *i* is `names[i]`) and each node's edges
|
|
228
|
+
* in sorted-target order, making the graph — and everything derived from it —
|
|
229
|
+
* deterministic for a given edge index.
|
|
230
|
+
*/
|
|
231
|
+
const materialize = (edges) => {
|
|
232
|
+
const names = [...edges.forward.keys()].sort();
|
|
233
|
+
return {
|
|
234
|
+
graph: Graph.directed((mutable) => {
|
|
235
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
236
|
+
for (const name of names) indexOf.set(name, Graph.addNode(mutable, name));
|
|
237
|
+
for (const name of names) {
|
|
238
|
+
const source = indexOf.get(name);
|
|
239
|
+
if (source === void 0) continue;
|
|
240
|
+
for (const dependency of [...edges.forward.get(name) ?? []].sort()) {
|
|
241
|
+
const target = indexOf.get(dependency);
|
|
242
|
+
if (target !== void 0) Graph.addEdge(mutable, source, target, "");
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}),
|
|
246
|
+
names
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* The packages participating in a dependency cycle — the sorted union of every
|
|
251
|
+
* strongly connected component with more than one member, via core's
|
|
252
|
+
* `Graph.stronglyConnectedComponents`. Self-edges are dropped at index time,
|
|
253
|
+
* so a single-member component is never cyclic here.
|
|
254
|
+
*/
|
|
255
|
+
const cycleMembers = (edges) => {
|
|
256
|
+
const { graph, names } = materialize(edges);
|
|
257
|
+
const members = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const component of Graph.stronglyConnectedComponents(graph)) {
|
|
259
|
+
if (component.length < 2) continue;
|
|
260
|
+
for (const index of component) {
|
|
261
|
+
const name = names[index];
|
|
262
|
+
if (name !== void 0) members.add(name);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return [...members].sort();
|
|
204
266
|
};
|
|
205
267
|
/**
|
|
206
268
|
* Kahn's algorithm. `forward[A] = {B}` reads "A depends on B", so level 0 is
|
|
207
269
|
* the set with an out-degree of zero and each completed level decrements its
|
|
208
270
|
* dependents through the reverse index.
|
|
271
|
+
*
|
|
272
|
+
* A non-empty `stalled` only signals *that* a cycle exists — it holds every
|
|
273
|
+
* unprocessed node, including ones merely downstream of a cycle. The error
|
|
274
|
+
* payload names the actual members via `cycleMembers`.
|
|
209
275
|
*/
|
|
210
276
|
const kahn = (edges) => {
|
|
211
277
|
const remaining = /* @__PURE__ */ new Map();
|
package/PackageManagerName.js
CHANGED
|
@@ -15,6 +15,35 @@ const PackageManagerName = Schema.Literals([
|
|
|
15
15
|
"bun"
|
|
16
16
|
]);
|
|
17
17
|
/**
|
|
18
|
+
* The markers {@link PackageManagerDetector} probes, in the priority order it
|
|
19
|
+
* probes them.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* One vocabulary serves both halves of the detection contract: the failure path
|
|
23
|
+
* reports every member as `PackageManagerDetectionError.checked`, and the
|
|
24
|
+
* success path reports the one that fired as
|
|
25
|
+
* `DetectedPackageManager.evidence`. A closed literal union rather than
|
|
26
|
+
* free text, so a consumer logging *why* a workspace was classified asserts
|
|
27
|
+
* against the kit's vocabulary instead of re-deriving the probe with its own
|
|
28
|
+
* filesystem reads.
|
|
29
|
+
*
|
|
30
|
+
* The `package.json#…` spellings name manifest *fields*; the rest are marker
|
|
31
|
+
* files at the workspace root.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
const PackageManagerEvidence = Schema.Literals([
|
|
36
|
+
"pnpm-workspace.yaml",
|
|
37
|
+
"bun.lock",
|
|
38
|
+
"bun.lockb",
|
|
39
|
+
"yarn.lock",
|
|
40
|
+
"package.json#workspaces",
|
|
41
|
+
"pnpm-lock.yaml",
|
|
42
|
+
"package-lock.json",
|
|
43
|
+
"package.json#devEngines.packageManager",
|
|
44
|
+
"package.json#packageManager"
|
|
45
|
+
]);
|
|
46
|
+
/**
|
|
18
47
|
* The outcome of package-manager detection at a workspace root.
|
|
19
48
|
*
|
|
20
49
|
* @remarks
|
|
@@ -25,6 +54,15 @@ const PackageManagerName = Schema.Literals([
|
|
|
25
54
|
* `devEngines.packageManager`; see {@link PackageManagerDetector} for the
|
|
26
55
|
* precedence between them.
|
|
27
56
|
*
|
|
57
|
+
* `evidence` is the rung of the priority order that decided the **name** — the
|
|
58
|
+
* verdict's provenance, in the same vocabulary the failure path reports as
|
|
59
|
+
* `PackageManagerDetectionError.checked`. For the bun and yarn rungs the
|
|
60
|
+
* lockfile is the recorded signal even though the rung is a conjunction (the
|
|
61
|
+
* lockfile *plus* a manifest field naming the manager): the manifest field alone
|
|
62
|
+
* would have resolved in the declaration tier, so the lockfile is what this rung
|
|
63
|
+
* added. The version's provenance is deliberately not carried — it follows the
|
|
64
|
+
* two-field precedence above, which is a rule, not a probe.
|
|
65
|
+
*
|
|
28
66
|
* @public
|
|
29
67
|
*/
|
|
30
68
|
var DetectedPackageManager = class extends Schema.Class("DetectedPackageManager")({
|
|
@@ -33,7 +71,9 @@ var DetectedPackageManager = class extends Schema.Class("DetectedPackageManager"
|
|
|
33
71
|
/** Its version, when a manifest field agrees on the manager and carries one. */
|
|
34
72
|
version: Schema.Option(Schema.String),
|
|
35
73
|
/** The JavaScript runtime the manager implies. */
|
|
36
|
-
runtime: Schema.Literals(["node", "bun"])
|
|
74
|
+
runtime: Schema.Literals(["node", "bun"]),
|
|
75
|
+
/** The rung of the priority order that decided the name. */
|
|
76
|
+
evidence: PackageManagerEvidence
|
|
37
77
|
}) {};
|
|
38
78
|
/** Whether `value` is a non-null, non-array object — corepack's own shape test. */
|
|
39
79
|
const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -97,18 +137,11 @@ var PackageManagerDetectionError = class extends Schema.TaggedError()("PackageMa
|
|
|
97
137
|
return `No package manager detected at ${this.root} (checked ${this.checked.join(", ")})`;
|
|
98
138
|
}
|
|
99
139
|
};
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"yarn.lock",
|
|
106
|
-
"package.json#workspaces",
|
|
107
|
-
"pnpm-lock.yaml",
|
|
108
|
-
"package-lock.json",
|
|
109
|
-
"package.json#packageManager",
|
|
110
|
-
"package.json#devEngines.packageManager"
|
|
111
|
-
];
|
|
140
|
+
/**
|
|
141
|
+
* The markers probed, in priority order. Derived from the evidence vocabulary so
|
|
142
|
+
* the failure path's `checked` and the success path's `evidence` cannot drift.
|
|
143
|
+
*/
|
|
144
|
+
const CHECKED = PackageManagerEvidence.literals;
|
|
112
145
|
/**
|
|
113
146
|
* Detects which package manager owns a workspace root.
|
|
114
147
|
*
|
|
@@ -219,44 +252,52 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
|
|
|
219
252
|
if (yield* has(root, "pnpm-workspace.yaml")) return DetectedPackageManager.make({
|
|
220
253
|
name: "pnpm",
|
|
221
254
|
version: versionFor(hints, "pnpm"),
|
|
222
|
-
runtime: "node"
|
|
255
|
+
runtime: "node",
|
|
256
|
+
evidence: "pnpm-workspace.yaml"
|
|
223
257
|
});
|
|
224
|
-
const bunLock = (yield* has(root, "bun.lock"))
|
|
225
|
-
if (bunLock && namesManager(hints, "bun")) return DetectedPackageManager.make({
|
|
258
|
+
const bunLock = (yield* has(root, "bun.lock")) ? Option.some("bun.lock") : (yield* has(root, "bun.lockb")) ? Option.some("bun.lockb") : Option.none();
|
|
259
|
+
if (Option.isSome(bunLock) && namesManager(hints, "bun")) return DetectedPackageManager.make({
|
|
226
260
|
name: "bun",
|
|
227
261
|
version: versionFor(hints, "bun"),
|
|
228
|
-
runtime: "bun"
|
|
262
|
+
runtime: "bun",
|
|
263
|
+
evidence: bunLock.value
|
|
229
264
|
});
|
|
230
265
|
if ((yield* has(root, "yarn.lock")) && namesManager(hints, "yarn")) return DetectedPackageManager.make({
|
|
231
266
|
name: "yarn",
|
|
232
267
|
version: versionFor(hints, "yarn"),
|
|
233
|
-
runtime: "node"
|
|
268
|
+
runtime: "node",
|
|
269
|
+
evidence: "yarn.lock"
|
|
234
270
|
});
|
|
235
271
|
const workspaces = Option.map(manifest, (fields) => fields.workspaces);
|
|
236
272
|
if (Option.isSome(workspaces) && workspaces.value !== void 0 && workspaces.value !== null) return DetectedPackageManager.make({
|
|
237
273
|
name: "npm",
|
|
238
274
|
version: versionFor(hints, "npm"),
|
|
239
|
-
runtime: "node"
|
|
275
|
+
runtime: "node",
|
|
276
|
+
evidence: "package.json#workspaces"
|
|
240
277
|
});
|
|
241
278
|
if (yield* has(root, "pnpm-lock.yaml")) return DetectedPackageManager.make({
|
|
242
279
|
name: "pnpm",
|
|
243
280
|
version: versionFor(hints, "pnpm"),
|
|
244
|
-
runtime: "node"
|
|
281
|
+
runtime: "node",
|
|
282
|
+
evidence: "pnpm-lock.yaml"
|
|
245
283
|
});
|
|
246
|
-
if (bunLock && namesManager(hints, "bun")) return DetectedPackageManager.make({
|
|
284
|
+
if (Option.isSome(bunLock) && namesManager(hints, "bun")) return DetectedPackageManager.make({
|
|
247
285
|
name: "bun",
|
|
248
286
|
version: versionFor(hints, "bun"),
|
|
249
|
-
runtime: "bun"
|
|
287
|
+
runtime: "bun",
|
|
288
|
+
evidence: bunLock.value
|
|
250
289
|
});
|
|
251
290
|
if ((yield* has(root, "yarn.lock")) && namesManager(hints, "yarn")) return DetectedPackageManager.make({
|
|
252
291
|
name: "yarn",
|
|
253
292
|
version: versionFor(hints, "yarn"),
|
|
254
|
-
runtime: "node"
|
|
293
|
+
runtime: "node",
|
|
294
|
+
evidence: "yarn.lock"
|
|
255
295
|
});
|
|
256
296
|
if (yield* has(root, "package-lock.json")) return DetectedPackageManager.make({
|
|
257
297
|
name: "npm",
|
|
258
298
|
version: versionFor(hints, "npm"),
|
|
259
|
-
runtime: "node"
|
|
299
|
+
runtime: "node",
|
|
300
|
+
evidence: "package-lock.json"
|
|
260
301
|
});
|
|
261
302
|
const declared = declaredName(hints);
|
|
262
303
|
if (Option.isSome(declared)) {
|
|
@@ -264,7 +305,8 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
|
|
|
264
305
|
if (name === "pnpm" || name === "npm" || name === "yarn" || name === "bun") return DetectedPackageManager.make({
|
|
265
306
|
name,
|
|
266
307
|
version: versionFor(hints, name),
|
|
267
|
-
runtime: name === "bun" ? "bun" : "node"
|
|
308
|
+
runtime: name === "bun" ? "bun" : "node",
|
|
309
|
+
evidence: Option.isSome(hints.devEngines) ? "package.json#devEngines.packageManager" : "package.json#packageManager"
|
|
268
310
|
});
|
|
269
311
|
}
|
|
270
312
|
return yield* Effect.fail(new PackageManagerDetectionError({
|
|
@@ -307,7 +349,12 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
|
|
|
307
349
|
* const TestDetector = PackageManagerDetector.layerTest({
|
|
308
350
|
* detect: () =>
|
|
309
351
|
* Effect.succeed(
|
|
310
|
-
* DetectedPackageManager.make({
|
|
352
|
+
* DetectedPackageManager.make({
|
|
353
|
+
* name: "pnpm",
|
|
354
|
+
* version: Option.none(),
|
|
355
|
+
* runtime: "node",
|
|
356
|
+
* evidence: "pnpm-workspace.yaml",
|
|
357
|
+
* }),
|
|
311
358
|
* ),
|
|
312
359
|
* });
|
|
313
360
|
* ```
|
|
@@ -331,4 +378,4 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
|
|
|
331
378
|
};
|
|
332
379
|
|
|
333
380
|
//#endregion
|
|
334
|
-
export { DetectedPackageManager, PackageManagerDetectionError, PackageManagerDetector, PackageManagerName };
|
|
381
|
+
export { DetectedPackageManager, PackageManagerDetectionError, PackageManagerDetector, PackageManagerEvidence, PackageManagerName };
|
package/README.md
CHANGED
|
@@ -70,7 +70,17 @@ Effect.runPromise(program.pipe(Effect.provide(WorkspacesLayer))).then(console.lo
|
|
|
70
70
|
// [ [ ...names with no workspace dependencies ], [ ...names that depend only on level 0 ], ... ]
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
`DependencyGraph` is a value class, not a service: build it from packages you already have. A cycle fails with `CyclicDependencyError`
|
|
73
|
+
`DependencyGraph` is a value class, not a service: build it from packages you already have. A cycle fails with `CyclicDependencyError`, whose `cycle` field names the packages actually in the cycle — the members of the strongly-connected components — and not the ones merely stalled behind it, which is the difference between a fix list and a suspect list.
|
|
74
|
+
|
|
75
|
+
`toMermaid()` renders the same graph for a job summary, an issue or a design doc. It is total, deterministic (nodes and edges both in sorted order) and safe for scoped names, which appear only inside quoted labels:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
console.log(graph.toMermaid());
|
|
79
|
+
// flowchart TD
|
|
80
|
+
// 0["@acme/app"]
|
|
81
|
+
// 1["@acme/utils"]
|
|
82
|
+
// 0 --> 1
|
|
83
|
+
```
|
|
74
84
|
|
|
75
85
|
## Change detection
|
|
76
86
|
|
|
@@ -228,7 +238,7 @@ A name miss in the derived `getPackage` fails with the service's own typed `Pack
|
|
|
228
238
|
- `WorkspaceRoot` — root discovery from a `cwd`, over `WORKSPACE_MARKERS`.
|
|
229
239
|
- `WorkspaceDiscovery` — package enumeration with a bounded descent for segment-crossing `packages/**` patterns, per-package lookup and the `makeTest` / `layerTest` in-memory test doubles.
|
|
230
240
|
- `WorkspacePackage` — a deliberately tolerant manifest model, so one member with an odd version cannot fail discovery for the whole repo. `manifestRecord` keeps the as-read `package.json` for tolerant access to fields outside the typed slice without a second read; `WorkspacePackage.manifest(pkg)` re-reads and is the opt-in bridge to `@effected/package-json`'s strict `Package`.
|
|
231
|
-
- `DependencyGraph` — a value class over discovered packages: `levels()` for parallel build tiers, the flattened topological order, and `CyclicDependencyError` when there
|
|
241
|
+
- `DependencyGraph` — a value class over discovered packages: `levels()` for parallel build tiers, the flattened topological order, `toMermaid()` for a deterministic Mermaid `flowchart TD` of the whole graph, and `CyclicDependencyError` — naming the cycle's actual members — when there is no order.
|
|
232
242
|
- `PackageManagerDetector` — npm, pnpm, yarn or bun from lockfiles and the `packageManager` field.
|
|
233
243
|
- `WorkspaceCatalogs` — pnpm catalog assembly and `catalog:` resolution, on pnpm's own catalog packages; `releaseAgeGate()` assembles the effective `@effected/npm` `ReleaseAgeGate` from inline `pnpm-workspace.yaml` release-age keys and replayed hook contributions, strictest-wins, in the same pass as the catalogs.
|
|
234
244
|
- `LockfileReader` — locate and parse the workspace's lockfile through `@effected/lockfiles`.
|
package/index.d.ts
CHANGED
|
@@ -960,9 +960,10 @@ declare const CyclicDependencyError_base: Schema.Class<CyclicDependencyError, Sc
|
|
|
960
960
|
* because it contains a cycle.
|
|
961
961
|
*
|
|
962
962
|
* @remarks
|
|
963
|
-
* `cycle`
|
|
964
|
-
*
|
|
965
|
-
* set to break, not necessarily
|
|
963
|
+
* `cycle` names the actual cycle members — the sorted union of every strongly
|
|
964
|
+
* connected component with more than one package. Packages merely downstream
|
|
965
|
+
* of a cycle are excluded, so it is exactly the set to break, not necessarily
|
|
966
|
+
* a single ordered loop.
|
|
966
967
|
*
|
|
967
968
|
* @public
|
|
968
969
|
*/
|
|
@@ -1041,6 +1042,18 @@ declare class DependencyGraph extends DependencyGraph_base {
|
|
|
1041
1042
|
* dependencies — the build order for a subset.
|
|
1042
1043
|
*/
|
|
1043
1044
|
readonly sortSubset: (names: readonly string[]) => Effect.Effect<readonly string[], CyclicDependencyError | PackageNotFoundError, never>;
|
|
1045
|
+
/**
|
|
1046
|
+
* The graph rendered as a Mermaid `flowchart TD`. Total.
|
|
1047
|
+
*
|
|
1048
|
+
* @remarks
|
|
1049
|
+
* Renders through core's `Graph.toMermaid` over a transient graph built from
|
|
1050
|
+
* the edge index. Node IDs are numeric indexes assigned in sorted-name order
|
|
1051
|
+
* and package names appear only inside quoted labels, so scoped names
|
|
1052
|
+
* (`@scope/a`) never break Mermaid syntax. Nodes and each node's edges are
|
|
1053
|
+
* emitted in sorted order — the output is deterministic regardless of
|
|
1054
|
+
* manifest key order.
|
|
1055
|
+
*/
|
|
1056
|
+
toMermaid(): string;
|
|
1044
1057
|
}
|
|
1045
1058
|
//#endregion
|
|
1046
1059
|
//#region src/PackageManagerName.d.ts
|
|
@@ -1056,6 +1069,32 @@ declare const PackageManagerName: Schema.Literals<readonly ["npm", "pnpm", "yarn
|
|
|
1056
1069
|
* @public
|
|
1057
1070
|
*/
|
|
1058
1071
|
type PackageManagerName = typeof PackageManagerName.Type;
|
|
1072
|
+
/**
|
|
1073
|
+
* The markers {@link PackageManagerDetector} probes, in the priority order it
|
|
1074
|
+
* probes them.
|
|
1075
|
+
*
|
|
1076
|
+
* @remarks
|
|
1077
|
+
* One vocabulary serves both halves of the detection contract: the failure path
|
|
1078
|
+
* reports every member as `PackageManagerDetectionError.checked`, and the
|
|
1079
|
+
* success path reports the one that fired as
|
|
1080
|
+
* `DetectedPackageManager.evidence`. A closed literal union rather than
|
|
1081
|
+
* free text, so a consumer logging *why* a workspace was classified asserts
|
|
1082
|
+
* against the kit's vocabulary instead of re-deriving the probe with its own
|
|
1083
|
+
* filesystem reads.
|
|
1084
|
+
*
|
|
1085
|
+
* The `package.json#…` spellings name manifest *fields*; the rest are marker
|
|
1086
|
+
* files at the workspace root.
|
|
1087
|
+
*
|
|
1088
|
+
* @public
|
|
1089
|
+
*/
|
|
1090
|
+
declare const PackageManagerEvidence: Schema.Literals<readonly ["pnpm-workspace.yaml", "bun.lock", "bun.lockb", "yarn.lock", "package.json#workspaces", "pnpm-lock.yaml", "package-lock.json", "package.json#devEngines.packageManager", "package.json#packageManager"]>;
|
|
1091
|
+
/**
|
|
1092
|
+
* The decoded type of {@link (PackageManagerEvidence:variable)}: the marker
|
|
1093
|
+
* that decided a detection.
|
|
1094
|
+
*
|
|
1095
|
+
* @public
|
|
1096
|
+
*/
|
|
1097
|
+
type PackageManagerEvidence = typeof PackageManagerEvidence.Type;
|
|
1059
1098
|
declare const DetectedPackageManager_base: Schema.Class<DetectedPackageManager, Schema.Struct<{
|
|
1060
1099
|
/** The detected manager. */
|
|
1061
1100
|
readonly name: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun"]>;
|
|
@@ -1063,6 +1102,8 @@ declare const DetectedPackageManager_base: Schema.Class<DetectedPackageManager,
|
|
|
1063
1102
|
readonly version: Schema.Option<Schema.String>;
|
|
1064
1103
|
/** The JavaScript runtime the manager implies. */
|
|
1065
1104
|
readonly runtime: Schema.Literals<readonly ["node", "bun"]>;
|
|
1105
|
+
/** The rung of the priority order that decided the name. */
|
|
1106
|
+
readonly evidence: Schema.Literals<readonly ["pnpm-workspace.yaml", "bun.lock", "bun.lockb", "yarn.lock", "package.json#workspaces", "pnpm-lock.yaml", "package-lock.json", "package.json#devEngines.packageManager", "package.json#packageManager"]>;
|
|
1066
1107
|
}>, {}>;
|
|
1067
1108
|
/**
|
|
1068
1109
|
* The outcome of package-manager detection at a workspace root.
|
|
@@ -1075,6 +1116,15 @@ declare const DetectedPackageManager_base: Schema.Class<DetectedPackageManager,
|
|
|
1075
1116
|
* `devEngines.packageManager`; see {@link PackageManagerDetector} for the
|
|
1076
1117
|
* precedence between them.
|
|
1077
1118
|
*
|
|
1119
|
+
* `evidence` is the rung of the priority order that decided the **name** — the
|
|
1120
|
+
* verdict's provenance, in the same vocabulary the failure path reports as
|
|
1121
|
+
* `PackageManagerDetectionError.checked`. For the bun and yarn rungs the
|
|
1122
|
+
* lockfile is the recorded signal even though the rung is a conjunction (the
|
|
1123
|
+
* lockfile *plus* a manifest field naming the manager): the manifest field alone
|
|
1124
|
+
* would have resolved in the declaration tier, so the lockfile is what this rung
|
|
1125
|
+
* added. The version's provenance is deliberately not carried — it follows the
|
|
1126
|
+
* two-field precedence above, which is a rule, not a probe.
|
|
1127
|
+
*
|
|
1078
1128
|
* @public
|
|
1079
1129
|
*/
|
|
1080
1130
|
declare class DetectedPackageManager extends DetectedPackageManager_base {}
|
|
@@ -1196,7 +1246,12 @@ declare class PackageManagerDetector extends PackageManagerDetector_base {
|
|
|
1196
1246
|
* const TestDetector = PackageManagerDetector.layerTest({
|
|
1197
1247
|
* detect: () =>
|
|
1198
1248
|
* Effect.succeed(
|
|
1199
|
-
* DetectedPackageManager.make({
|
|
1249
|
+
* DetectedPackageManager.make({
|
|
1250
|
+
* name: "pnpm",
|
|
1251
|
+
* version: Option.none(),
|
|
1252
|
+
* runtime: "node",
|
|
1253
|
+
* evidence: "pnpm-workspace.yaml",
|
|
1254
|
+
* }),
|
|
1200
1255
|
* ),
|
|
1201
1256
|
* });
|
|
1202
1257
|
* ```
|
|
@@ -3017,5 +3072,5 @@ interface GetWorkspacePackagesSyncOptions extends WorkspacesSyncOptions {
|
|
|
3017
3072
|
*/
|
|
3018
3073
|
declare const getWorkspacePackagesSync: (root: string, options: GetWorkspacePackagesSyncOptions) => ReadonlyArray<WorkspacePackage>;
|
|
3019
3074
|
//#endregion
|
|
3020
|
-
export { type CatalogAssemblyFailure, CatalogSet, ChangeDetectionError, type ChangeDetectionFailure, ChangeDetectionOptions, ChangeDetector, type ChangeDetectorShape, type ClassifyOptions, ConfigDependencyHooks, type ConfigDependencyHooksShape, CyclicDependencyError, type DependencyDiff, DependencyGraph, DetectedPackageManager, type FindWorkspaceRootOptions, type GetWorkspacePackagesSyncOptions, type HookInjection, type ImporterVersions, LockfileReadError, type LockfileReadFailure, LockfileReader, type LockfileReaderOptions, type LockfileReaderShape, PackageManagerDetectionError, type PackageManagerDetectionFailure, PackageManagerDetector, type PackageManagerDetectorShape, PackageManagerName, PackageNotFoundError, type PackageRelease, PackageStateSnapshot, PublishConfig, PublishTarget, PublishabilityDetector, type PublishabilityDetectorShape, ReleaseTag, type SyncFileSystem, type SyncPath, type TagClassification, type TagFormatOptions, TagStyle, TrackingTag, type TrackingTagOptions, type VersioningDetectOptions, VersioningStrategy, VersioningStrategyType, WORKSPACE_MARKERS, WorkspaceCatalogs, type WorkspaceCatalogsOptions, type WorkspaceCatalogsShape, WorkspaceDiscovery, WorkspaceDiscoveryError, type WorkspaceDiscoveryFailure, type WorkspaceDiscoveryOptions, type WorkspaceDiscoveryShape, WorkspaceInfo, type WorkspaceLookupFailure, WorkspaceManifestError, WorkspacePackage, WorkspacePatternError, WorkspaceRoot, WorkspaceRootNotFoundError, type WorkspaceRootShape, type WorkspaceSnapshotAtFailure, type WorkspaceSnapshotWorktreeFailure, WorkspaceSnapshots, type WorkspaceSnapshotsOptions, type WorkspaceSnapshotsShape, WorkspaceStateSnapshot, Workspaces, type WorkspacesOptions, type WorkspacesServices, type WorkspacesSyncOptions, classifyTag, findWorkspaceRootSync, getWorkspacePackagesSync };
|
|
3075
|
+
export { type CatalogAssemblyFailure, CatalogSet, ChangeDetectionError, type ChangeDetectionFailure, ChangeDetectionOptions, ChangeDetector, type ChangeDetectorShape, type ClassifyOptions, ConfigDependencyHooks, type ConfigDependencyHooksShape, CyclicDependencyError, type DependencyDiff, DependencyGraph, DetectedPackageManager, type FindWorkspaceRootOptions, type GetWorkspacePackagesSyncOptions, type HookInjection, type ImporterVersions, LockfileReadError, type LockfileReadFailure, LockfileReader, type LockfileReaderOptions, type LockfileReaderShape, PackageManagerDetectionError, type PackageManagerDetectionFailure, PackageManagerDetector, type PackageManagerDetectorShape, PackageManagerEvidence, PackageManagerName, PackageNotFoundError, type PackageRelease, PackageStateSnapshot, PublishConfig, PublishTarget, PublishabilityDetector, type PublishabilityDetectorShape, ReleaseTag, type SyncFileSystem, type SyncPath, type TagClassification, type TagFormatOptions, TagStyle, TrackingTag, type TrackingTagOptions, type VersioningDetectOptions, VersioningStrategy, VersioningStrategyType, WORKSPACE_MARKERS, WorkspaceCatalogs, type WorkspaceCatalogsOptions, type WorkspaceCatalogsShape, WorkspaceDiscovery, WorkspaceDiscoveryError, type WorkspaceDiscoveryFailure, type WorkspaceDiscoveryOptions, type WorkspaceDiscoveryShape, WorkspaceInfo, type WorkspaceLookupFailure, WorkspaceManifestError, WorkspacePackage, WorkspacePatternError, WorkspaceRoot, WorkspaceRootNotFoundError, type WorkspaceRootShape, type WorkspaceSnapshotAtFailure, type WorkspaceSnapshotWorktreeFailure, WorkspaceSnapshots, type WorkspaceSnapshotsOptions, type WorkspaceSnapshotsShape, WorkspaceStateSnapshot, Workspaces, type WorkspacesOptions, type WorkspacesServices, type WorkspacesSyncOptions, classifyTag, findWorkspaceRootSync, getWorkspacePackagesSync };
|
|
3021
3076
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { PackageNotFoundError, WorkspaceDiscovery, WorkspaceDiscoveryError, Work
|
|
|
4
4
|
import { CyclicDependencyError, DependencyGraph } from "./DependencyGraph.js";
|
|
5
5
|
import { ChangeDetectionError, ChangeDetectionOptions, ChangeDetector } from "./ChangeDetector.js";
|
|
6
6
|
import { ConfigDependencyHooks } from "./ConfigDependencyHooks.js";
|
|
7
|
-
import { DetectedPackageManager, PackageManagerDetectionError, PackageManagerDetector, PackageManagerName } from "./PackageManagerName.js";
|
|
7
|
+
import { DetectedPackageManager, PackageManagerDetectionError, PackageManagerDetector, PackageManagerEvidence, PackageManagerName } from "./PackageManagerName.js";
|
|
8
8
|
import { LockfileReadError, LockfileReader } from "./LockfileReader.js";
|
|
9
9
|
import { PublishTarget, PublishabilityDetector } from "./Publishability.js";
|
|
10
10
|
import { ReleaseTag, TagStyle, TrackingTag, classifyTag } from "./ReleaseTag.js";
|
|
@@ -15,4 +15,4 @@ import { WorkspaceSnapshots } from "./WorkspaceSnapshots.js";
|
|
|
15
15
|
import { Workspaces } from "./Workspaces.js";
|
|
16
16
|
import { findWorkspaceRootSync, getWorkspacePackagesSync } from "./WorkspacesSync.js";
|
|
17
17
|
|
|
18
|
-
export { CatalogSet, ChangeDetectionError, ChangeDetectionOptions, ChangeDetector, ConfigDependencyHooks, CyclicDependencyError, DependencyGraph, DetectedPackageManager, LockfileReadError, LockfileReader, PackageManagerDetectionError, PackageManagerDetector, PackageManagerName, PackageNotFoundError, PackageStateSnapshot, PublishConfig, PublishTarget, PublishabilityDetector, ReleaseTag, TagStyle, TrackingTag, VersioningStrategy, VersioningStrategyType, WORKSPACE_MARKERS, WorkspaceCatalogs, WorkspaceDiscovery, WorkspaceDiscoveryError, WorkspaceInfo, WorkspaceManifestError, WorkspacePackage, WorkspacePatternError, WorkspaceRoot, WorkspaceRootNotFoundError, WorkspaceSnapshots, WorkspaceStateSnapshot, Workspaces, classifyTag, findWorkspaceRootSync, getWorkspacePackagesSync };
|
|
18
|
+
export { CatalogSet, ChangeDetectionError, ChangeDetectionOptions, ChangeDetector, ConfigDependencyHooks, CyclicDependencyError, DependencyGraph, DetectedPackageManager, LockfileReadError, LockfileReader, PackageManagerDetectionError, PackageManagerDetector, PackageManagerEvidence, PackageManagerName, PackageNotFoundError, PackageStateSnapshot, PublishConfig, PublishTarget, PublishabilityDetector, ReleaseTag, TagStyle, TrackingTag, VersioningStrategy, VersioningStrategyType, WORKSPACE_MARKERS, WorkspaceCatalogs, WorkspaceDiscovery, WorkspaceDiscoveryError, WorkspaceInfo, WorkspaceManifestError, WorkspacePackage, WorkspacePatternError, WorkspaceRoot, WorkspaceRootNotFoundError, WorkspaceSnapshots, WorkspaceStateSnapshot, Workspaces, classifyTag, findWorkspaceRootSync, getWorkspacePackagesSync };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/workspaces",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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": [
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@effected/commands": "^0.4.0",
|
|
50
|
-
"@effected/git": "^0.
|
|
50
|
+
"@effected/git": "^0.8.0",
|
|
51
51
|
"@effected/glob": "^0.3.0",
|
|
52
52
|
"@effected/lockfiles": "^0.4.1",
|
|
53
53
|
"@effected/npm": "^0.9.0",
|
|
54
|
-
"@effected/package-json": "^0.
|
|
54
|
+
"@effected/package-json": "^0.9.0",
|
|
55
55
|
"@effected/semver": "^0.4.0",
|
|
56
56
|
"@effected/walker": "^0.4.0",
|
|
57
57
|
"@effected/yaml": "^0.8.0",
|