@savvy-web/silk 3.8.0 → 3.8.2

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.
@@ -2353,7 +2353,7 @@ var GlobSet = class GlobSet extends Schema.Class("GlobSet")(Schema.Struct({ patt
2353
2353
  };
2354
2354
 
2355
2355
  //#endregion
2356
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/BunExtension.js
2356
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/BunExtension.js
2357
2357
  /**
2358
2358
  * Extension data specific to bun lockfiles, attached to `Lockfile.extension`
2359
2359
  * when the format is `"bun"`.
@@ -4170,7 +4170,7 @@ input: Schema.String }) {
4170
4170
  }
4171
4171
  };
4172
4172
  const CATALOG_PREFIX = "catalog:";
4173
- const WORKSPACE_PREFIX = "workspace:";
4173
+ const WORKSPACE_PREFIX$1 = "workspace:";
4174
4174
  const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4175
4175
  const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4176
4176
  const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
@@ -4178,7 +4178,7 @@ const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:"
4178
4178
  const isLink = (value) => value.startsWith("link:");
4179
4179
  const isPortal = (value) => value.startsWith("portal:");
4180
4180
  const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
4181
- const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
4181
+ const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX$1);
4182
4182
  const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
4183
4183
  const parseRange = (value) => {
4184
4184
  const exit = Schema.decodeUnknownExit(Range$1.FromString)(value);
@@ -4187,7 +4187,7 @@ const parseRange = (value) => {
4187
4187
  const isRange = (value) => Option.isSome(parseRange(value));
4188
4188
  const protocolOf = (value) => {
4189
4189
  if (value.startsWith(CATALOG_PREFIX)) return "catalog";
4190
- if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
4190
+ if (value.startsWith(WORKSPACE_PREFIX$1)) return "workspace";
4191
4191
  if (value.startsWith("link:")) return "link";
4192
4192
  if (value.startsWith("portal:")) return "portal";
4193
4193
  if (value.startsWith("file:") || isBarePath(value)) return "file";
@@ -5621,7 +5621,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends Schema.Class("ReleaseAgeGate")
5621
5621
  };
5622
5622
 
5623
5623
  //#endregion
5624
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/ImporterDependency.js
5624
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/ImporterDependency.js
5625
5625
  /**
5626
5626
  * One declared dependency of one workspace importer, as the lockfile records it.
5627
5627
  *
@@ -5660,7 +5660,7 @@ var ImporterDependency = class extends Schema.Class("ImporterDependency")({
5660
5660
  }) {};
5661
5661
 
5662
5662
  //#endregion
5663
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileImporter.js
5663
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/LockfileImporter.js
5664
5664
  /**
5665
5665
  * One workspace importer's declared dependencies, as the lockfile records them.
5666
5666
  *
@@ -5685,14 +5685,23 @@ var LockfileImporter = class extends Schema.Class("LockfileImporter")({
5685
5685
  }) {};
5686
5686
 
5687
5687
  //#endregion
5688
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/ResolvedPackage.js
5688
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/ResolvedPackage.js
5689
5689
  const EMPTY_DEPENDENCIES = {};
5690
+ const EMPTY_PEER_META = {};
5691
+ const EMPTY_EDGE_NAMES = [];
5690
5692
  /**
5691
5693
  * A package resolved from a lockfile.
5692
5694
  *
5693
5695
  * @remarks
5694
5696
  * The common shape every format's entries normalize into:
5695
5697
  *
5698
+ * - `instanceId` — the lockfile-native identity of this *instance*, verbatim:
5699
+ * pnpm's snapshot key (`react-dom@18.3.1(react@17.0.2)`), npm's full entry
5700
+ * key (`node_modules/express/node_modules/debug`), bun's `packages` key
5701
+ * (`@acme/lib/react-dom`) or yarn's locator (`react-dom@npm:18.3.1`). It is
5702
+ * **opaque** — no scheme is synthesized and none should be parsed by a
5703
+ * consumer; it exists so `resolved` can name an instance, and so two
5704
+ * peer-resolved variants of one `name@version` stay distinguishable.
5696
5705
  * - `name` — the resolved package name. For pnpm *workspace* packages
5697
5706
  * straight out of `Lockfile.parse` this is the importer path until
5698
5707
  * `Lockfile#withImporterNames` rewrites it.
@@ -5708,20 +5717,66 @@ const EMPTY_DEPENDENCIES = {};
5708
5717
  * packages, when the lockfile records one.
5709
5718
  * - `dependencies` — the package's own dependency map, defaulting to `{}`
5710
5719
  * both at construction and when decoding serialized data.
5720
+ * - `peerDependencies` — the package's *declared* peer ranges, keyed by peer
5721
+ * name. Every format records them (pnpm and npm as their own section, bun
5722
+ * inline in the package tuple's info object, yarn Berry as an entry
5723
+ * section), so this is populated across all four. Declarations only: what
5724
+ * the package *asks for*, never what actually resolved.
5725
+ * - `peerDependenciesMeta` — the per-peer flags, normalized to
5726
+ * `{ optional: boolean }`. bun spells optional peers as an `optionalPeers`
5727
+ * array of names rather than a meta object; that spelling is normalized
5728
+ * into this shape so one consumer algorithm serves every format. A peer
5729
+ * with no meta entry is required.
5730
+ * - `resolved` — this instance's *outgoing edges*: dependency (and, where the
5731
+ * format records it, peer) name → the `instanceId` that name actually
5732
+ * resolved to in this instance's context. This is the answer to "which
5733
+ * concrete version of P did X get", which `peerDependencies` deliberately
5734
+ * does not answer.
5735
+ *
5736
+ * Every entry is **verified**: an edge is emitted only when the composed or
5737
+ * walked-up identity matches a real instance in the same lockfile. An edge
5738
+ * that cannot be resolved honestly is *omitted*, never guessed — a wrong
5739
+ * resolved edge is a silent wrong answer, an absent one is a visible gap.
5740
+ * yarn records peer resolution virtually and is therefore dependency-edges
5741
+ * only.
5742
+ *
5743
+ * - `unresolvedEdges` — dependency names whose edge the lockfile **records**
5744
+ * but this model could not name: a `link:` target that is not a workspace
5745
+ * importer, a composed identity matching no instance. It is the companion
5746
+ * `resolved` needs to be honest, because an absent key in `resolved` would
5747
+ * otherwise mean two different things — "nothing is there" and "something is
5748
+ * there that I could not name" — and a consumer reading the first meaning
5749
+ * for the second turns this package's gap into its own false positive.
5750
+ *
5751
+ * A dependency the lockfile simply does not record is **not** an unresolved
5752
+ * edge; it is an absence, and must not appear here. npm and bun contribute
5753
+ * nothing at all: their sections are *declarations* resolved positionally, so
5754
+ * "the walk found nothing" is genuine absence. A fail-closed signal that is
5755
+ * always on is a signal nobody reads.
5756
+ *
5757
+ * All four record fields — `dependencies`, `peerDependencies`,
5758
+ * `peerDependenciesMeta` and `resolved` — default to `{}` at construction and
5759
+ * when decoding, and `unresolvedEdges` defaults to `[]`. An absent section is
5760
+ * therefore an empty collection, never `undefined`.
5711
5761
  *
5712
5762
  * @public
5713
5763
  */
5714
5764
  var ResolvedPackage = class extends Schema.Class("ResolvedPackage")({
5715
5765
  name: Schema.NonEmptyString,
5716
5766
  version: Schema.String,
5767
+ instanceId: Schema.NonEmptyString,
5717
5768
  integrity: Schema.optionalKey(IntegrityHash),
5718
5769
  isWorkspace: Schema.Boolean,
5719
5770
  relativePath: Schema.optionalKey(Schema.String),
5720
- dependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES)))
5771
+ dependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5772
+ peerDependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5773
+ peerDependenciesMeta: Schema.Record(Schema.String, Schema.Struct({ optional: Schema.Boolean })).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_PEER_META)), Schema.withConstructorDefault(Effect.succeed(EMPTY_PEER_META))),
5774
+ resolved: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5775
+ unresolvedEdges: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_EDGE_NAMES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_EDGE_NAMES)))
5721
5776
  }) {};
5722
5777
 
5723
5778
  //#endregion
5724
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/WorkspaceDependency.js
5779
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/WorkspaceDependency.js
5725
5780
  /**
5726
5781
  * A directed dependency edge between two workspace packages as recorded in
5727
5782
  * the lockfile.
@@ -5744,7 +5799,7 @@ var WorkspaceDependency = class extends Schema.Class("WorkspaceDependency")({
5744
5799
  }) {};
5745
5800
 
5746
5801
  //#endregion
5747
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/PnpmExtension.js
5802
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/PnpmExtension.js
5748
5803
  /**
5749
5804
  * Extension data specific to pnpm lockfiles, attached to `Lockfile.extension`
5750
5805
  * when the format is `"pnpm"`.
@@ -5770,10 +5825,10 @@ var PnpmExtension = class extends Schema.Class("PnpmExtension")({
5770
5825
  }) {};
5771
5826
 
5772
5827
  //#endregion
5773
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileFormat.js
5828
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/LockfileFormat.js
5774
5829
  /**
5775
5830
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
5776
- * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5831
+ * `package-lock.json` (JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5777
5832
  * `yarn.lock` (both YAML).
5778
5833
  *
5779
5834
  * @remarks
@@ -5782,6 +5837,10 @@ var PnpmExtension = class extends Schema.Class("PnpmExtension")({
5782
5837
  * Berry only; classic (v1) `yarn.lock` is not YAML and fails
5783
5838
  * `Lockfile.parse` with a typed `LockfileParseError`.
5784
5839
  *
5840
+ * The format literal says nothing about which *versions* of that format are
5841
+ * supported: pnpm `lockfileVersion` 9+ and npm `lockfileVersion` 3+ parse,
5842
+ * and older ones fail typed. See `Lockfile.parse`.
5843
+ *
5785
5844
  * @public
5786
5845
  */
5787
5846
  const LockfileFormat = Schema.Literals([
@@ -5809,7 +5868,7 @@ const FILENAMES = {
5809
5868
  const filenameFor = (format) => FILENAMES[format][0];
5810
5869
 
5811
5870
  //#endregion
5812
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/shared.js
5871
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/shared.js
5813
5872
  /**
5814
5873
  * The four dependency sections of a manifest, in a stable order — the shared
5815
5874
  * dependency-sections table (v3's `DEP_SECTIONS`). Each entry is both the
@@ -5920,6 +5979,79 @@ const importerDependencies = (entry, read) => {
5920
5979
  }
5921
5980
  return deps;
5922
5981
  };
5982
+ const EMPTY_PEERS = {
5983
+ peerDependencies: {},
5984
+ peerDependenciesMeta: {}
5985
+ };
5986
+ /**
5987
+ * Normalize one format's peer declarations into the unified pair.
5988
+ *
5989
+ * Every format records the ranges the same way (a name→range map), but the
5990
+ * optional flag has two spellings: a `peerDependenciesMeta` object (pnpm, npm,
5991
+ * yarn Berry) and bun's `optionalPeers` array of names. Both are accepted and
5992
+ * collapse to `{ optional: boolean }` per peer, so a consumer reads one shape
5993
+ * regardless of which manager wrote the lockfile.
5994
+ *
5995
+ * Absence yields empty records, never `undefined` — an absent section means
5996
+ * "declares no peers", which is a fact, not a gap. Records are built with
5997
+ * `Object.fromEntries` (own-property semantics), so a `__proto__` peer name
5998
+ * neither pollutes nor drops.
5999
+ *
6000
+ * @internal
6001
+ */
6002
+ const peerDeclarations = (peers, meta, optionalPeers) => {
6003
+ if (peers === void 0 && meta === void 0 && optionalPeers === void 0) return EMPTY_PEERS;
6004
+ const flags = /* @__PURE__ */ new Map();
6005
+ if (meta !== void 0) for (const [name, value] of Object.entries(meta)) flags.set(name, value?.optional === true);
6006
+ if (optionalPeers !== void 0) for (const name of optionalPeers) flags.set(name, true);
6007
+ return {
6008
+ peerDependencies: peers === void 0 ? {} : Object.fromEntries(Object.entries(peers)),
6009
+ peerDependenciesMeta: Object.fromEntries([...flags].map(([name, optional]) => [name, { optional }]))
6010
+ };
6011
+ };
6012
+ /**
6013
+ * The minimum lockfile-format version each gated format is parsed at.
6014
+ *
6015
+ * This is a deliberate narrowing of the supported input domain, not an
6016
+ * implementation detail: an older lockfile fails typed rather than parsing
6017
+ * into a model that cannot answer resolution questions. Note the gate is on
6018
+ * the **lockfile format version**, which is the only version a lockfile
6019
+ * records — the writing package manager's version is not recoverable from the
6020
+ * file, so no manager-version claim could be enforced here.
6021
+ *
6022
+ * @internal
6023
+ */
6024
+ const MINIMUM_LOCKFILE_VERSION = {
6025
+ pnpm: 9,
6026
+ npm: 3
6027
+ };
6028
+ /**
6029
+ * Fail typed when a lockfile predates the supported format version.
6030
+ *
6031
+ * Routed through {@link validationFailure} rather than {@link framingFailure}:
6032
+ * the document was located perfectly well, so this is a shape judgement about
6033
+ * a located document, not a framing problem. The cause is a structured record
6034
+ * rather than an engine error, so a consumer can tell "your lockfile is too
6035
+ * old" from "your lockfile is malformed" without parsing a message.
6036
+ *
6037
+ * A version that is not a number at all (`lockfileVersion: "next"`) is not a
6038
+ * supported version either, and fails the same way.
6039
+ *
6040
+ * @internal
6041
+ */
6042
+ const requireLockfileVersion = (format, raw) => {
6043
+ const minimum = MINIMUM_LOCKFILE_VERSION[format];
6044
+ const parsed = typeof raw === "number" ? raw : Number.parseFloat(raw);
6045
+ if (Number.isFinite(parsed) && parsed >= minimum) return Effect.void;
6046
+ const cause = {
6047
+ _tag: "UnsupportedLockfileVersion",
6048
+ format,
6049
+ lockfileVersion: raw,
6050
+ minimumSupported: minimum,
6051
+ message: `${format} lockfileVersion ${JSON.stringify(raw)} is not supported: @effected/lockfiles parses ${format} lockfileVersion ${minimum} and newer`
6052
+ };
6053
+ return Effect.fail(validationFailure(cause));
6054
+ };
5923
6055
  /** @internal */
5924
6056
  const syntaxFailure = (cause) => ({
5925
6057
  stage: "syntax",
@@ -7781,16 +7913,38 @@ var JsoncModifier = class {
7781
7913
  };
7782
7914
 
7783
7915
  //#endregion
7784
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/bun.js
7916
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/bun.js
7785
7917
  const DepRecord$2 = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
7918
+ const OptionalPeers = Schema.optionalKey(Schema.Array(Schema.String));
7786
7919
  const BunWorkspaceEntry = Schema.Struct({
7787
7920
  name: Schema.optionalKey(Schema.String),
7788
7921
  version: Schema.optionalKey(Schema.String),
7789
7922
  dependencies: DepRecord$2,
7790
7923
  devDependencies: DepRecord$2,
7791
7924
  peerDependencies: DepRecord$2,
7792
- optionalDependencies: DepRecord$2
7925
+ optionalDependencies: DepRecord$2,
7926
+ optionalPeers: OptionalPeers
7927
+ });
7928
+ /**
7929
+ * The info object at package-tuple index 2. bun's tuple shape is
7930
+ * under-documented upstream, so it is read permissively and *out of band*: a
7931
+ * shape that does not decode is skipped (the package still lands, with no
7932
+ * peers) rather than failing the whole parse.
7933
+ *
7934
+ * @internal
7935
+ */
7936
+ const BunPackageInfo = Schema.Struct({
7937
+ dependencies: DepRecord$2,
7938
+ devDependencies: DepRecord$2,
7939
+ optionalDependencies: DepRecord$2,
7940
+ peerDependencies: DepRecord$2,
7941
+ optionalPeers: OptionalPeers
7793
7942
  });
7943
+ const decodeBunPackageInfo = Schema.decodeUnknownExit(BunPackageInfo);
7944
+ const readBunPackageInfo = (value) => {
7945
+ const exit = decodeBunPackageInfo(value);
7946
+ return Exit.isSuccess(exit) ? exit.value : void 0;
7947
+ };
7794
7948
  const BunLockfileRaw = Schema.Struct({
7795
7949
  lockfileVersion: Schema.Number,
7796
7950
  workspaces: Schema.optionalKey(Schema.Record(Schema.String, BunWorkspaceEntry)),
@@ -7813,8 +7967,60 @@ const parseBun = (content) => Effect.gen(function* () {
7813
7967
  const validated = yield* Schema.decodeUnknownEffect(BunLockfileRaw)(parsed).pipe(Effect.mapError(validationFailure));
7814
7968
  return yield* toFields$3(validated);
7815
7969
  });
7970
+ /**
7971
+ * Resolve one entry's outgoing edges by replaying bun's own key scheme.
7972
+ *
7973
+ * bun encodes install position in the `packages` key: a nested install is
7974
+ * keyed `<parent-key>/<name>`, so `"react-dom/react"` is literally "the react
7975
+ * react-dom got". Package names are themselves slash-bearing when scoped, so
7976
+ * the parent chain is **not** computed by splitting on `/` — it is read off
7977
+ * the key space, taking those prefixes of the key that are themselves keys,
7978
+ * longest first. Deepest wins; the root (`<name>` alone) is tried last.
7979
+ *
7980
+ * Only keys that exist are emitted, so an edge bun did not record is omitted
7981
+ * rather than invented.
7982
+ *
7983
+ * @internal
7984
+ */
7985
+ const resolveBunEdges = (key, sections, keys) => {
7986
+ const names = /* @__PURE__ */ new Set();
7987
+ for (const section of sections) {
7988
+ if (!section) continue;
7989
+ for (const name of Object.keys(section)) if (name !== "") names.add(name);
7990
+ }
7991
+ if (names.size === 0) return {};
7992
+ const prefixes = [key];
7993
+ for (let i = key.indexOf("/"); i !== -1; i = key.indexOf("/", i + 1)) {
7994
+ const candidate = key.slice(0, i);
7995
+ if (keys.has(candidate)) prefixes.push(candidate);
7996
+ }
7997
+ prefixes.sort((a, b) => b.length - a.length);
7998
+ prefixes.push("");
7999
+ const edges = /* @__PURE__ */ new Map();
8000
+ for (const name of names) for (const prefix of prefixes) {
8001
+ const candidate = prefix === "" ? name : `${prefix}/${name}`;
8002
+ if (keys.has(candidate)) {
8003
+ edges.set(name, candidate);
8004
+ break;
8005
+ }
8006
+ }
8007
+ return Object.fromEntries(edges);
8008
+ };
8009
+ const infoSections = (info) => [
8010
+ info?.dependencies,
8011
+ info?.devDependencies,
8012
+ info?.optionalDependencies,
8013
+ info?.peerDependencies
8014
+ ];
8015
+ const workspaceSections = (entry) => [
8016
+ entry.dependencies,
8017
+ entry.devDependencies,
8018
+ entry.optionalDependencies,
8019
+ entry.peerDependencies
8020
+ ];
7816
8021
  const toFields$3 = (raw) => Effect.gen(function* () {
7817
8022
  const packages = [];
8023
+ const keys = new Set(raw.packages ? Object.keys(raw.packages) : []);
7818
8024
  const workspaceNames = /* @__PURE__ */ new Set();
7819
8025
  const workspaceEntries = /* @__PURE__ */ new Map();
7820
8026
  const importers = [];
@@ -7827,11 +8033,16 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7827
8033
  if (wsPath === "") continue;
7828
8034
  const name = wsEntry.name === void 0 || wsEntry.name === "" ? wsPath : wsEntry.name;
7829
8035
  workspaceNames.add(name);
8036
+ const instanceId = keys.has(name) ? name : wsPath;
8037
+ if (instanceId === "") continue;
7830
8038
  packages.push(ResolvedPackage.make({
7831
8039
  name,
7832
8040
  version: wsEntry.version ?? "0.0.0",
8041
+ instanceId,
7833
8042
  isWorkspace: true,
7834
- relativePath: wsPath
8043
+ relativePath: wsPath,
8044
+ ...peerDeclarations(wsEntry.peerDependencies, void 0, wsEntry.optionalPeers),
8045
+ resolved: resolveBunEdges(instanceId, workspaceSections(wsEntry), keys)
7835
8046
  }));
7836
8047
  workspaceEntries.set(name, {
7837
8048
  ...wsEntry.dependencies ? { dependencies: wsEntry.dependencies } : {},
@@ -7841,7 +8052,8 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7841
8052
  });
7842
8053
  }
7843
8054
  }
7844
- if (raw.packages) for (const tuple of Object.values(raw.packages)) {
8055
+ if (raw.packages) for (const [key, tuple] of Object.entries(raw.packages)) {
8056
+ if (key === "") continue;
7845
8057
  if (tuple.length < 1) continue;
7846
8058
  const first = tuple[0];
7847
8059
  if (typeof first !== "string") continue;
@@ -7851,11 +8063,15 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7851
8063
  const version = first.slice(atIdx + 1);
7852
8064
  if (workspaceNames.has(name)) continue;
7853
8065
  const integrity = yield* toIntegrityHash(tuple.length >= 4 && typeof tuple[3] === "string" ? tuple[3] : void 0);
8066
+ const info = tuple.length >= 3 ? readBunPackageInfo(tuple[2]) : void 0;
7854
8067
  packages.push(ResolvedPackage.make({
7855
8068
  name,
7856
8069
  version,
8070
+ instanceId: key,
7857
8071
  ...integrity !== void 0 ? { integrity } : {},
7858
- isWorkspace: false
8072
+ isWorkspace: false,
8073
+ ...peerDeclarations(info?.peerDependencies, void 0, info?.optionalPeers),
8074
+ resolved: resolveBunEdges(key, infoSections(info), keys)
7859
8075
  }));
7860
8076
  }
7861
8077
  const workspaceDependencies = extractWorkspaceDeps(workspaceEntries, workspaceNames);
@@ -7875,8 +8091,9 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7875
8091
  });
7876
8092
 
7877
8093
  //#endregion
7878
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/npm.js
8094
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/npm.js
7879
8095
  const DepRecord$1 = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
8096
+ const PeerMetaRecord = Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) })));
7880
8097
  const NpmPackageEntry = Schema.Struct({
7881
8098
  name: Schema.optionalKey(Schema.String),
7882
8099
  version: Schema.optionalKey(Schema.String),
@@ -7887,8 +8104,22 @@ const NpmPackageEntry = Schema.Struct({
7887
8104
  dependencies: DepRecord$1,
7888
8105
  devDependencies: DepRecord$1,
7889
8106
  peerDependencies: DepRecord$1,
8107
+ peerDependenciesMeta: PeerMetaRecord,
7890
8108
  optionalDependencies: DepRecord$1
7891
8109
  });
8110
+ /**
8111
+ * The version gate's own input: `lockfileVersion` and nothing else.
8112
+ *
8113
+ * The gate has to read the version *before* the shape decode, because the
8114
+ * shape it would decode against is the shape of a supported version. `packages`
8115
+ * is a required key here and a v1 tree does not have one, so a shape-first
8116
+ * order reports npm v1 as **malformed** rather than as **too old** — losing
8117
+ * exactly the distinction the `UnsupportedLockfileVersion` cause exists to
8118
+ * carry.
8119
+ *
8120
+ * @internal
8121
+ */
8122
+ const NpmVersionProbe = Schema.Struct({ lockfileVersion: Schema.Union([Schema.Number, Schema.String]) });
7892
8123
  const NpmLockfileRaw = Schema.Struct({
7893
8124
  name: Schema.optionalKey(Schema.String),
7894
8125
  version: Schema.optionalKey(Schema.String),
@@ -7897,10 +8128,73 @@ const NpmLockfileRaw = Schema.Struct({
7897
8128
  packages: Schema.Record(Schema.String, NpmPackageEntry)
7898
8129
  });
7899
8130
  const NODE_MODULES_PREFIX = "node_modules/";
8131
+ const NESTED_NODE_MODULES = "/node_modules/";
7900
8132
  /**
7901
- * Parse npm `package-lock.json` (v2/v3) content into the unified field
7902
- * bundle. Native `JSON.parse` inside `Effect.try` — its throw on hostile
7903
- * input (including V8's `RangeError` on pathological depth) lands typed as
8133
+ * Where a `packages` key's package name starts: after the **last**
8134
+ * `node_modules/` segment, not the first.
8135
+ *
8136
+ * npm encodes the whole install position in the key, so
8137
+ * `node_modules/express/node_modules/debug` is *debug*, nested under express —
8138
+ * and `packages/lib/node_modules/react` is *react*, nested under a workspace
8139
+ * directory and carrying no `node_modules/` prefix at all. Returns `-1` for a
8140
+ * key that is not a package position (the root `""` entry, a workspace path
8141
+ * entry), which the caller skips.
8142
+ *
8143
+ * @internal
8144
+ */
8145
+ const packageNameIndex = (key) => {
8146
+ const nested = key.lastIndexOf(NESTED_NODE_MODULES);
8147
+ if (nested !== -1) return nested + 14;
8148
+ return key.startsWith(NODE_MODULES_PREFIX) ? 13 : -1;
8149
+ };
8150
+ /**
8151
+ * Resolve one entry's outgoing edges by replaying node resolution over the key
8152
+ * space: from the depending package's own directory, try
8153
+ * `<prefix>/node_modules/<name>`, then strip one path segment and try again,
8154
+ * out to the root — **deepest first**, first hit wins. That order is the whole
8155
+ * algorithm: outermost-first would return the hoisted copy and silently
8156
+ * mis-report every shadowed dependency.
8157
+ *
8158
+ * Only keys that actually exist in the lockfile are emitted, so an edge npm
8159
+ * did not record is omitted rather than invented.
8160
+ *
8161
+ * @internal
8162
+ */
8163
+ const resolveNpmEdges = (start, sections, packages) => {
8164
+ const names = /* @__PURE__ */ new Set();
8165
+ for (const section of sections) {
8166
+ if (!section) continue;
8167
+ for (const name of Object.keys(section)) if (name !== "") names.add(name);
8168
+ }
8169
+ if (names.size === 0) return {};
8170
+ const prefixes = [];
8171
+ for (let prefix = start;;) {
8172
+ prefixes.push(prefix);
8173
+ if (prefix === "") break;
8174
+ const slash = prefix.lastIndexOf("/");
8175
+ prefix = slash === -1 ? "" : prefix.slice(0, slash);
8176
+ }
8177
+ const edges = /* @__PURE__ */ new Map();
8178
+ for (const name of names) for (const prefix of prefixes) {
8179
+ const candidate = prefix === "" ? `${NODE_MODULES_PREFIX}${name}` : `${prefix}${NESTED_NODE_MODULES}${name}`;
8180
+ if (Object.hasOwn(packages, candidate)) {
8181
+ edges.set(name, candidate);
8182
+ break;
8183
+ }
8184
+ }
8185
+ return Object.fromEntries(edges);
8186
+ };
8187
+ const entrySections = (entry) => [
8188
+ entry?.dependencies,
8189
+ entry?.devDependencies,
8190
+ entry?.optionalDependencies,
8191
+ entry?.peerDependencies
8192
+ ];
8193
+ /**
8194
+ * Parse npm `package-lock.json` content into the unified field bundle —
8195
+ * `lockfileVersion` 3 and newer; v2 and older fail typed at validation.
8196
+ * Native `JSON.parse` inside `Effect.try` — its throw on hostile input
8197
+ * (including V8's `RangeError` on pathological depth) lands typed as
7904
8198
  * `stage: "syntax"`.
7905
8199
  *
7906
8200
  * @internal
@@ -7910,6 +8204,8 @@ const parseNpm = (content) => Effect.gen(function* () {
7910
8204
  try: () => JSON.parse(content),
7911
8205
  catch: syntaxFailure
7912
8206
  });
8207
+ const probe = yield* Schema.decodeUnknownEffect(NpmVersionProbe)(raw).pipe(Effect.mapError(validationFailure));
8208
+ yield* requireLockfileVersion("npm", probe.lockfileVersion);
7913
8209
  const validated = yield* Schema.decodeUnknownEffect(NpmLockfileRaw)(raw).pipe(Effect.mapError(validationFailure));
7914
8210
  return yield* toFields$2(validated);
7915
8211
  });
@@ -7923,22 +8219,30 @@ const toFields$2 = (raw) => Effect.gen(function* () {
7923
8219
  path: ".",
7924
8220
  dependencies: importerDependencies(rootEntry, (s) => ({ specifier: s }))
7925
8221
  }));
7926
- for (const [key, entry] of Object.entries(raw.packages)) if (key.startsWith(NODE_MODULES_PREFIX) && entry.link === true) {
7927
- const name = (entry.resolved !== void 0 ? raw.packages[entry.resolved] : void 0)?.name ?? entry.name ?? key.slice(13);
7928
- if (name !== "") workspaceNames.add(name);
8222
+ for (const [key, entry] of Object.entries(raw.packages)) {
8223
+ const nameIndex = packageNameIndex(key);
8224
+ if (nameIndex !== -1 && entry.link === true) {
8225
+ const name = (entry.resolved !== void 0 ? raw.packages[entry.resolved] : void 0)?.name ?? entry.name ?? key.slice(nameIndex);
8226
+ if (name !== "") workspaceNames.add(name);
8227
+ }
7929
8228
  }
7930
8229
  for (const [key, entry] of Object.entries(raw.packages)) {
7931
8230
  if (key === "") continue;
7932
- if (key.startsWith(NODE_MODULES_PREFIX) && entry.link === true) {
8231
+ const nameIndex = packageNameIndex(key);
8232
+ if (nameIndex === -1) continue;
8233
+ if (entry.link === true) {
7933
8234
  const resolved = entry.resolved;
7934
8235
  const wsEntry = resolved !== void 0 ? raw.packages[resolved] : void 0;
7935
- const name = wsEntry?.name ?? entry.name ?? key.slice(13);
8236
+ const name = wsEntry?.name ?? entry.name ?? key.slice(nameIndex);
7936
8237
  if (name === "") continue;
7937
8238
  packages.push(ResolvedPackage.make({
7938
8239
  name,
7939
8240
  version: wsEntry?.version ?? "0.0.0",
8241
+ instanceId: key,
7940
8242
  isWorkspace: true,
7941
- ...resolved !== void 0 ? { relativePath: resolved } : {}
8243
+ ...resolved !== void 0 ? { relativePath: resolved } : {},
8244
+ ...peerDeclarations(wsEntry?.peerDependencies, wsEntry?.peerDependenciesMeta),
8245
+ resolved: resolveNpmEdges(resolved !== void 0 && resolved !== "" ? resolved : key, entrySections(wsEntry), raw.packages)
7942
8246
  }));
7943
8247
  if (wsEntry) workspaceEntries.set(name, {
7944
8248
  ...wsEntry.dependencies ? { dependencies: wsEntry.dependencies } : {},
@@ -7950,16 +8254,19 @@ const toFields$2 = (raw) => Effect.gen(function* () {
7950
8254
  path: resolved,
7951
8255
  dependencies: wsEntry ? importerDependencies(wsEntry, (s) => ({ specifier: s })) : []
7952
8256
  }));
7953
- } else if (key.startsWith(NODE_MODULES_PREFIX)) {
7954
- const name = key.slice(13);
8257
+ } else {
8258
+ const name = key.slice(nameIndex);
7955
8259
  if (name !== "" && entry.version !== void 0) {
7956
8260
  const integrity = yield* toIntegrityHash(entry.integrity);
7957
8261
  packages.push(ResolvedPackage.make({
7958
8262
  name,
7959
8263
  version: entry.version,
8264
+ instanceId: key,
7960
8265
  ...integrity !== void 0 ? { integrity } : {},
7961
8266
  isWorkspace: false,
7962
- dependencies: entry.dependencies ?? {}
8267
+ dependencies: entry.dependencies ?? {},
8268
+ ...peerDeclarations(entry.peerDependencies, entry.peerDependenciesMeta),
8269
+ resolved: resolveNpmEdges(key, entrySections(entry), raw.packages)
7963
8270
  }));
7964
8271
  }
7965
8272
  }
@@ -15757,7 +16064,7 @@ function deepEqualValues(a, b) {
15757
16064
  }
15758
16065
 
15759
16066
  //#endregion
15760
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/documents.js
16067
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/documents.js
15761
16068
  /**
15762
16069
  * An empty YAML document composes to `null` (`Yaml.parseAll("")` is `[null]`,
15763
16070
  * and the trailing document of an env-only `pnpm-lock.yaml` is `null` too).
@@ -15828,7 +16135,7 @@ const selectSoleDocument = (content) => Effect.gen(function* () {
15828
16135
  });
15829
16136
 
15830
16137
  //#endregion
15831
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/pnpm.js
16138
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/pnpm.js
15832
16139
  const PnpmImporterDeps = Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
15833
16140
  specifier: Schema.String,
15834
16141
  version: Schema.String
@@ -15839,6 +16146,18 @@ const PnpmImporter = Schema.Struct({
15839
16146
  peerDependencies: PnpmImporterDeps,
15840
16147
  optionalDependencies: PnpmImporterDeps
15841
16148
  });
16149
+ /**
16150
+ * The version gate's own input: `lockfileVersion` and nothing else.
16151
+ *
16152
+ * The gate has to read the version *before* the shape decode, because the
16153
+ * shape it decodes against is the shape of a supported version. `importers` is
16154
+ * a required key here and a pre-v9 single-project lockfile has none — it
16155
+ * records its dependencies at the top level — so a shape-first order reports a
16156
+ * lockfile we reject for being too old as merely malformed instead.
16157
+ *
16158
+ * @internal
16159
+ */
16160
+ const PnpmVersionProbe = Schema.Struct({ lockfileVersion: Schema.Union([Schema.String, Schema.Number]) });
15842
16161
  const PnpmLockfileRaw = Schema.Struct({
15843
16162
  lockfileVersion: Schema.Union([Schema.String, Schema.Number]),
15844
16163
  settings: Schema.optionalKey(Schema.Struct({
@@ -15851,7 +16170,17 @@ const PnpmLockfileRaw = Schema.Struct({
15851
16170
  version: Schema.String
15852
16171
  })])))),
15853
16172
  importers: Schema.Record(Schema.String, PnpmImporter),
15854
- packages: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ resolution: Schema.optionalKey(Schema.Struct({ integrity: Schema.optionalKey(Schema.String) })) })))
16173
+ packages: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
16174
+ resolution: Schema.optionalKey(Schema.Struct({ integrity: Schema.optionalKey(Schema.String) })),
16175
+ peerDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16176
+ peerDependenciesMeta: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) }))),
16177
+ dependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16178
+ optionalDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String))
16179
+ }))),
16180
+ snapshots: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
16181
+ dependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16182
+ optionalDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String))
16183
+ })))
15855
16184
  });
15856
16185
  /**
15857
16186
  * Parse pnpm `pnpm-lock.yaml` content into the unified field bundle.
@@ -15871,10 +16200,142 @@ const PnpmLockfileRaw = Schema.Struct({
15871
16200
  */
15872
16201
  const parsePnpm = (content) => Effect.gen(function* () {
15873
16202
  const { document, documents } = yield* selectPnpmDocument(content);
16203
+ const probe = yield* Schema.decodeUnknownEffect(PnpmVersionProbe)(document).pipe(Effect.mapError(validationFailure));
16204
+ yield* requireLockfileVersion("pnpm", probe.lockfileVersion);
15874
16205
  const validated = yield* Schema.decodeUnknownEffect(PnpmLockfileRaw)(document).pipe(Effect.mapError(validationFailure));
15875
16206
  if (Object.keys(validated.importers).length === 0) return yield* Effect.fail(framingFailure("noImporters", documents));
15876
16207
  return yield* toFields$1(validated);
15877
16208
  });
16209
+ /**
16210
+ * Resolve one instance's outgoing edges to instance ids.
16211
+ *
16212
+ * pnpm names a resolved dependency as `name` → `version`, where the version may
16213
+ * itself carry a peer suffix (`1.6.0(react@17.0.2)`); the referenced instance's
16214
+ * key is those two composed back together. The composition is *verified*
16215
+ * against the lockfile's own key set rather than trusted — the composed key is
16216
+ * v9's bare `name@version` and nothing else, because the format gate admits no
16217
+ * lockfile that spells keys the pre-v9 leading-slash way — and an edge that
16218
+ * matches nothing is **omitted**. That is what keeps a `link:`/`file:`
16219
+ * resolution, which names no instance in this lockfile, from becoming a
16220
+ * plausible lie.
16221
+ *
16222
+ * @internal
16223
+ */
16224
+ const resolveEdges = (sections, instanceIds) => {
16225
+ const edges = /* @__PURE__ */ new Map();
16226
+ const unnameable = /* @__PURE__ */ new Set();
16227
+ for (const section of sections) {
16228
+ if (!section) continue;
16229
+ for (const [name, version] of Object.entries(section)) {
16230
+ if (name === "") continue;
16231
+ if (version.startsWith(LINK_PREFIX)) {
16232
+ const target = resolveLinkTarget("", version.slice(LINK_PREFIX.length));
16233
+ if (target !== void 0 && instanceIds.has(target)) edges.set(name, target);
16234
+ else unnameable.add(name);
16235
+ continue;
16236
+ }
16237
+ const bare = `${name}@${version}`;
16238
+ if (instanceIds.has(bare)) edges.set(name, bare);
16239
+ else unnameable.add(name);
16240
+ }
16241
+ }
16242
+ return {
16243
+ resolved: Object.fromEntries(edges),
16244
+ unresolvedEdges: [...unnameable].sort()
16245
+ };
16246
+ };
16247
+ /** The protocol pnpm records a workspace-directory resolution under. @internal */
16248
+ const LINK_PREFIX = "link:";
16249
+ /**
16250
+ * Normalize a `link:` target against the linking importer's path, so a
16251
+ * workspace edge can name the workspace importer's instance id.
16252
+ * Total: a target that walks above the root yields `undefined`.
16253
+ *
16254
+ * @internal
16255
+ */
16256
+ const resolveLinkTarget = (importerPath, target) => {
16257
+ const segments = [];
16258
+ for (const segment of `${importerPath}/${target}`.split("/")) {
16259
+ if (segment === "" || segment === ".") continue;
16260
+ if (segment === "..") {
16261
+ if (segments.pop() === void 0) return void 0;
16262
+ continue;
16263
+ }
16264
+ segments.push(segment);
16265
+ }
16266
+ return segments.length === 0 ? void 0 : segments.join("/");
16267
+ };
16268
+ /** The specifier protocol pnpm resolves through the workspace itself. @internal */
16269
+ const WORKSPACE_PREFIX = "workspace:";
16270
+ /**
16271
+ * The importer a `link:` target lands INSIDE, longest path first.
16272
+ *
16273
+ * pnpm's `publishConfig.linkDirectory` makes a workspace link point at the
16274
+ * package's publish directory rather than its root — `link:../bundler/dist/dev/pkg`
16275
+ * where `packages/bundler` is the importer — so the target itself is a build
16276
+ * output that is no importer and never will be. The owning importer is the
16277
+ * longest ancestor of the target that IS one; longest-first so a nested importer
16278
+ * beats its parent.
16279
+ *
16280
+ * The root importer (`"."`) is deliberately unreachable here: it is an ancestor
16281
+ * of every path in the workspace, so admitting it would resolve every stray link
16282
+ * to the root rather than leaving it unnamed.
16283
+ *
16284
+ * @internal
16285
+ */
16286
+ const owningImporter = (target, importerPaths) => {
16287
+ const segments = target.split("/");
16288
+ for (let end = segments.length - 1; end > 0; end--) {
16289
+ const candidate = segments.slice(0, end).join("/");
16290
+ if (importerPaths.has(candidate)) return candidate;
16291
+ }
16292
+ };
16293
+ /**
16294
+ * Resolve one importer's outgoing edges. pnpm records `{ specifier, version }`
16295
+ * per importer dependency, where the version is either a registry version (the
16296
+ * instance-id composition {@link resolveEdges} performs) or a `link:` target
16297
+ * naming another importer — normalized against this importer's own path. Both
16298
+ * are checked against the lockfile's instance ids before being emitted.
16299
+ *
16300
+ * A `link:` target that is no importer gets one further chance, and only under
16301
+ * a `workspace:` SPECIFIER: pnpm resolved that edge through the workspace, so
16302
+ * the target directory is known to belong to a workspace package, and
16303
+ * {@link owningImporter} names it. The specifier is what makes this a
16304
+ * resolution rather than a guess — a hand-written `link:../vendor/stub`
16305
+ * specifier names a directory pnpm never claimed was a workspace package, and
16306
+ * attributing it to whichever importer happens to contain it would answer with
16307
+ * the wrong package's peers instead of admitting it could not name the edge.
16308
+ *
16309
+ * The snapshot path ({@link resolveEdges}) deliberately does NOT do this: a
16310
+ * snapshot body records `name: link:<path>` with no specifier beside it, so the
16311
+ * evidence this rule turns on is not available there.
16312
+ *
16313
+ * @internal
16314
+ */
16315
+ const resolveImporterEdges = (importer, importerPath, instanceIds, importerPaths) => {
16316
+ const edges = /* @__PURE__ */ new Map();
16317
+ const unnameable = /* @__PURE__ */ new Set();
16318
+ for (const group of importerDepGroups(importer)) {
16319
+ if (!group) continue;
16320
+ for (const [name, info] of Object.entries(group)) {
16321
+ if (name === "") continue;
16322
+ if (info.version.startsWith(LINK_PREFIX)) {
16323
+ const target = resolveLinkTarget(importerPath, info.version.slice(5));
16324
+ const owner = target === void 0 ? void 0 : instanceIds.has(target) ? target : info.specifier.startsWith(WORKSPACE_PREFIX) ? owningImporter(target, importerPaths) : void 0;
16325
+ if (owner !== void 0) edges.set(name, owner);
16326
+ else unnameable.add(name);
16327
+ continue;
16328
+ }
16329
+ const bare = `${name}@${info.version}`;
16330
+ if (instanceIds.has(bare)) edges.set(name, bare);
16331
+ else unnameable.add(name);
16332
+ }
16333
+ }
16334
+ return {
16335
+ resolved: Object.fromEntries(edges),
16336
+ unresolvedEdges: [...unnameable].sort()
16337
+ };
16338
+ };
15878
16339
  const toVersionMap = (deps) => {
15879
16340
  if (!deps) return void 0;
15880
16341
  return Object.fromEntries(Object.entries(deps).map(([name, info]) => [name, info.specifier]));
@@ -15915,28 +16376,51 @@ const toFields$1 = (raw) => Effect.gen(function* () {
15915
16376
  }
15916
16377
  for (const path of Object.keys(raw.importers)) if (path !== "." && path !== "") workspaceNames.add(path);
15917
16378
  const packages = [];
15918
- for (const importerPath of Object.keys(raw.importers)) {
16379
+ const snapshots = raw.snapshots;
16380
+ const instanceIds = /* @__PURE__ */ new Set([
16381
+ ...snapshots ? Object.keys(snapshots) : [],
16382
+ ...raw.packages ? Object.keys(raw.packages) : [],
16383
+ ...Object.keys(raw.importers)
16384
+ ]);
16385
+ const importerPaths = new Set(Object.keys(raw.importers).filter((path) => path !== "." && path !== ""));
16386
+ const emitted = /* @__PURE__ */ new Set();
16387
+ for (const [importerPath, importer] of Object.entries(raw.importers)) {
15919
16388
  if (importerPath === "." || importerPath === "") continue;
15920
16389
  packages.push(ResolvedPackage.make({
15921
16390
  name: importerPath,
15922
16391
  version: "0.0.0",
16392
+ instanceId: importerPath,
15923
16393
  isWorkspace: true,
15924
- relativePath: importerPath
16394
+ relativePath: importerPath,
16395
+ ...resolveImporterEdges(importer, importerPath, instanceIds, importerPaths)
15925
16396
  }));
15926
16397
  }
15927
- if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
15928
- const { plain: bare } = splitPeerSuffix(key);
16398
+ const emit = (instanceId, meta, edges) => Effect.gen(function* () {
16399
+ const { plain: bare } = splitPeerSuffix(instanceId);
15929
16400
  const atIndex = bare.lastIndexOf("@");
15930
- if (atIndex <= 0) continue;
16401
+ if (atIndex <= 0) return;
15931
16402
  const name = bare.slice(0, atIndex);
15932
16403
  const version = bare.slice(atIndex + 1);
15933
- const integrity = yield* toIntegrityHash(pkg.resolution?.integrity);
16404
+ const integrity = yield* toIntegrityHash(meta?.resolution?.integrity);
16405
+ emitted.add(instanceId);
15934
16406
  packages.push(ResolvedPackage.make({
15935
16407
  name,
15936
16408
  version,
16409
+ instanceId,
15937
16410
  ...integrity !== void 0 ? { integrity } : {},
15938
- isWorkspace: false
16411
+ isWorkspace: false,
16412
+ ...peerDeclarations(meta?.peerDependencies, meta?.peerDependenciesMeta),
16413
+ ...resolveEdges(edges, instanceIds)
15939
16414
  }));
16415
+ });
16416
+ if (snapshots) for (const [key, snapshot] of Object.entries(snapshots)) {
16417
+ const plain = splitPeerSuffix(key).plain;
16418
+ yield* emit(key, raw.packages !== void 0 && Object.hasOwn(raw.packages, plain) ? raw.packages[plain] : void 0, [snapshot.dependencies, snapshot.optionalDependencies]);
16419
+ }
16420
+ const covered = new Set([...emitted].map((key) => splitPeerSuffix(key).plain));
16421
+ if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
16422
+ if (covered.has(key)) continue;
16423
+ yield* emit(key, pkg, [pkg.dependencies, pkg.optionalDependencies]);
15940
16424
  }
15941
16425
  const workspaceDependencies = extractWorkspaceDeps(workspaceEntries, workspaceNames);
15942
16426
  const extension = PnpmExtension.make({
@@ -15954,7 +16438,7 @@ const toFields$1 = (raw) => Effect.gen(function* () {
15954
16438
  });
15955
16439
 
15956
16440
  //#endregion
15957
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/yarn.js
16441
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/internal/yarn.js
15958
16442
  const YarnLockfileRaw = Schema.Record(Schema.String, Schema.Unknown);
15959
16443
  const DepRecord = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
15960
16444
  const YarnEntry = Schema.Struct({
@@ -15963,6 +16447,7 @@ const YarnEntry = Schema.Struct({
15963
16447
  dependencies: DepRecord,
15964
16448
  devDependencies: DepRecord,
15965
16449
  peerDependencies: DepRecord,
16450
+ peerDependenciesMeta: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) }))),
15966
16451
  optionalDependencies: DepRecord,
15967
16452
  checksum: Schema.optionalKey(Schema.String),
15968
16453
  languageName: Schema.optionalKey(Schema.String),
@@ -15996,6 +16481,13 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
15996
16481
  const packages = [];
15997
16482
  const workspaceNames = /* @__PURE__ */ new Set();
15998
16483
  const workspaceEntries = /* @__PURE__ */ new Map();
16484
+ const locators = /* @__PURE__ */ new Map();
16485
+ for (const [key, entry] of decoded) {
16486
+ const descriptors = key.split(", ");
16487
+ const locator = entry.resolution ?? descriptors[0];
16488
+ if (locator === void 0 || locator === "") continue;
16489
+ for (const descriptor of descriptors) if (descriptor !== "") locators.set(descriptor, locator);
16490
+ }
15999
16491
  for (const [key, entry] of decoded) if (entry.linkType === "soft") {
16000
16492
  const name = extractYarnPackageName(key);
16001
16493
  if (name !== void 0) workspaceNames.add(name);
@@ -16006,12 +16498,17 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
16006
16498
  const isWorkspace = entry.linkType === "soft";
16007
16499
  const relativePath = isWorkspace ? extractYarnWorkspacePath(key) : void 0;
16008
16500
  const integrity = yield* toIntegrityHash(entry.checksum);
16501
+ const instanceId = entry.resolution ?? key.split(", ")[0] ?? "";
16502
+ if (instanceId === "") continue;
16009
16503
  packages.push(ResolvedPackage.make({
16010
16504
  name,
16011
16505
  version: entry.version ?? "0.0.0",
16506
+ instanceId,
16012
16507
  ...integrity !== void 0 ? { integrity } : {},
16013
16508
  isWorkspace,
16014
- ...relativePath !== void 0 ? { relativePath } : {}
16509
+ ...relativePath !== void 0 ? { relativePath } : {},
16510
+ ...peerDeclarations(entry.peerDependencies, entry.peerDependenciesMeta),
16511
+ ...resolveYarnEdges(entry, locators)
16015
16512
  }));
16016
16513
  if (isWorkspace) {
16017
16514
  const deps = cleanYarnDeps(entry.dependencies);
@@ -16034,6 +16531,46 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
16034
16531
  };
16035
16532
  });
16036
16533
  /**
16534
+ * Resolve one entry's outgoing edges through the descriptor→locator index.
16535
+ *
16536
+ * A yarn dependency value is a *descriptor* range (`"npm:5.3.0"`), and the
16537
+ * lockfile keys enumerate exactly which descriptors resolve to which locator,
16538
+ * so the lookup is exact rather than reconstructed.
16539
+ *
16540
+ * **`devDependencies` is not a section a Berry lockfile has.** yarn folds a
16541
+ * workspace's dev declarations into the entry's `dependencies` map — the
16542
+ * lockfile a project produces is byte-identical whether a dependency is
16543
+ * declared under `dependencies` or `devDependencies` (probed against yarn
16544
+ * 4.9.1). Dev edges are therefore already resolved here; iterating
16545
+ * `entry.devDependencies` would be dead code, and the schema keeps the field
16546
+ * only as permissive scaffolding for hand-edited input.
16547
+ *
16548
+ * **Dependency edges only.** yarn resolves peers virtually — a peer-bearing
16549
+ * package gets a `@virtual:` locator per consumer, and this lockfile shape does
16550
+ * not record which one satisfied which peer. Emitting a peer edge here would
16551
+ * mean guessing, so peers are left out: an absent edge is a true statement, a
16552
+ * plausible one would not be.
16553
+ *
16554
+ * @internal
16555
+ */
16556
+ const resolveYarnEdges = (entry, locators) => {
16557
+ const edges = /* @__PURE__ */ new Map();
16558
+ const unnameable = /* @__PURE__ */ new Set();
16559
+ for (const section of [entry.dependencies, entry.optionalDependencies]) {
16560
+ if (!section) continue;
16561
+ for (const [name, range] of Object.entries(section)) {
16562
+ if (name === "") continue;
16563
+ const locator = locators.get(`${name}@${range}`);
16564
+ if (locator !== void 0) edges.set(name, locator);
16565
+ else unnameable.add(name);
16566
+ }
16567
+ }
16568
+ return {
16569
+ resolved: Object.fromEntries(edges),
16570
+ unresolvedEdges: [...unnameable].sort()
16571
+ };
16572
+ };
16573
+ /**
16037
16574
  * Extract the package name from a yarn lockfile key. Handles compound keys
16038
16575
  * (`"a@workspace:*, a@workspace:packages/a"`) via the first descriptor and
16039
16576
  * `@patch:` descriptors (which embed `@npm:` inside). Total: malformed keys
@@ -16078,7 +16615,7 @@ const cleanYarnDeps = (deps) => {
16078
16615
  };
16079
16616
 
16080
16617
  //#endregion
16081
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/Lockfile.js
16618
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/Lockfile.js
16082
16619
  const EMPTY_IMPORTERS = [];
16083
16620
  /**
16084
16621
  * Failure of `Lockfile.parse`: the given content is not a valid lockfile of
@@ -16250,10 +16787,15 @@ var Lockfile = class Lockfile extends Schema.Class("Lockfile")({
16250
16787
  return ResolvedPackage.make({
16251
16788
  name: realName,
16252
16789
  version: pkg.version,
16790
+ instanceId: pkg.instanceId,
16253
16791
  ...pkg.integrity !== void 0 ? { integrity: pkg.integrity } : {},
16254
16792
  isWorkspace: pkg.isWorkspace,
16255
16793
  relativePath: pkg.relativePath,
16256
- dependencies: pkg.dependencies
16794
+ dependencies: pkg.dependencies,
16795
+ peerDependencies: pkg.peerDependencies,
16796
+ peerDependenciesMeta: pkg.peerDependenciesMeta,
16797
+ resolved: pkg.resolved,
16798
+ unresolvedEdges: pkg.unresolvedEdges
16257
16799
  });
16258
16800
  });
16259
16801
  const workspaceDependencies = this.workspaceDependencies.map((dep) => {
@@ -16323,7 +16865,7 @@ var Lockfile = class Lockfile extends Schema.Class("Lockfile")({
16323
16865
  };
16324
16866
 
16325
16867
  //#endregion
16326
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileIntegrity.js
16868
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/LockfileIntegrity.js
16327
16869
  /**
16328
16870
  * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
16329
16871
  * lockfile against: a package name plus the four optional dependency maps.
@@ -19199,7 +19741,7 @@ var Package = class Package extends Schema.Class("Package")({
19199
19741
  };
19200
19742
 
19201
19743
  //#endregion
19202
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspacePackage.js
19744
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspacePackage.js
19203
19745
  const EMPTY$1 = Object.freeze(Object.create(null));
19204
19746
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
19205
19747
  /**
@@ -19801,7 +20343,7 @@ var Walker$1 = class {
19801
20343
  };
19802
20344
 
19803
20345
  //#endregion
19804
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceRoot.js
20346
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceRoot.js
19805
20347
  /**
19806
20348
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
19807
20349
  *
@@ -19989,7 +20531,7 @@ var WorkspaceRoot = class WorkspaceRoot extends Context.Service()("@effected/wor
19989
20531
  };
19990
20532
 
19991
20533
  //#endregion
19992
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/limits.js
20534
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/limits.js
19993
20535
  /**
19994
20536
  * Hard ceiling on directories the enumerator will visit for one pattern set.
19995
20537
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -20008,7 +20550,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
20008
20550
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
20009
20551
 
20010
20552
  //#endregion
20011
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/traverse.js
20553
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/traverse.js
20012
20554
  /** Directory names never descended into. */
20013
20555
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
20014
20556
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -20099,7 +20641,7 @@ var Traversal = class {
20099
20641
  };
20100
20642
 
20101
20643
  //#endregion
20102
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/enumerate.js
20644
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/enumerate.js
20103
20645
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
20104
20646
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
20105
20647
  /**
@@ -20116,6 +20658,8 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20116
20658
  if (!isValidMaxDepth(maxDepth)) return yield* Effect.die(/* @__PURE__ */ new Error(`enumerate: ${badMaxDepthMessage(maxDepth)}`));
20117
20659
  const isPackage = (absolute) => fs.exists(path.join(absolute, "package.json")).pipe(Effect.orElseSucceed(() => false));
20118
20660
  const isDirectory = (absolute) => fs.stat(absolute).pipe(Effect.map((info) => info.type === "Directory"), Effect.orElseSucceed(() => false));
20661
+ const excludes = globs.excludes;
20662
+ const isExcluded = excludes.length === 0 ? (_) => false : (relative) => excludes.some((exclude) => exclude.matches(relative));
20119
20663
  const included = /* @__PURE__ */ new Map();
20120
20664
  /** A shared-traversal stop, materialized as this module's failure record. */
20121
20665
  const failureOf = (stop, pattern) => ({
@@ -20124,6 +20668,7 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20124
20668
  detail: stop.detail
20125
20669
  });
20126
20670
  for (const literal of globs.literals) {
20671
+ if (isExcluded(literal)) continue;
20127
20672
  const absolute = path.join(root, literal);
20128
20673
  if (yield* isPackage(absolute)) included.set(literal, absolute);
20129
20674
  }
@@ -20151,26 +20696,23 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20151
20696
  const absolute = path.join(frame.absolute, entry);
20152
20697
  if (!(yield* isDirectory(absolute))) continue;
20153
20698
  if (wildcard.crossesSegments && !traversal.admits(frame)) return yield* Effect.fail(failureOf(traversal.depthStop(), wildcard.source));
20154
- if (wildcard.matches(relative) && (yield* isPackage(absolute))) included.set(relative, absolute);
20699
+ if (wildcard.matches(relative) && !isExcluded(relative) && (yield* isPackage(absolute))) included.set(relative, absolute);
20155
20700
  if (!wildcard.crossesSegments) continue;
20156
20701
  traversal.push(frame, relative, absolute);
20157
20702
  }
20158
20703
  }
20159
20704
  }
20160
20705
  const results = [];
20161
- for (const [relativePath, absolute] of included) {
20162
- if (globs.excludes.some((exclude) => exclude.matches(relativePath))) continue;
20163
- results.push({
20164
- relativePath,
20165
- path: absolute
20166
- });
20167
- }
20706
+ for (const [relativePath, absolute] of included) results.push({
20707
+ relativePath,
20708
+ path: absolute
20709
+ });
20168
20710
  results.sort((a, b) => a.relativePath < b.relativePath ? -1 : a.relativePath > b.relativePath ? 1 : 0);
20169
20711
  return results;
20170
20712
  });
20171
20713
 
20172
20714
  //#endregion
20173
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/patterns.js
20715
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/patterns.js
20174
20716
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
20175
20717
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
20176
20718
  const pnpmPatternsOf = (document) => {
@@ -20228,7 +20770,7 @@ const readPatterns = (root) => Effect.gen(function* () {
20228
20770
  });
20229
20771
 
20230
20772
  //#endregion
20231
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceDiscovery.js
20773
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceDiscovery.js
20232
20774
  /**
20233
20775
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
20234
20776
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -20685,7 +21227,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends Context.Service()("@ef
20685
21227
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
20686
21228
 
20687
21229
  //#endregion
20688
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/DependencyGraph.js
21230
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/DependencyGraph.js
20689
21231
  /**
20690
21232
  * Raised when the workspace dependency graph cannot be topologically ordered
20691
21233
  * because it contains a cycle.
@@ -24385,7 +24927,7 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
24385
24927
  };
24386
24928
 
24387
24929
  //#endregion
24388
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ChangeDetector.js
24930
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ChangeDetector.js
24389
24931
  /**
24390
24932
  * Which git refs to compare, and whether to fold in the working tree.
24391
24933
  *
@@ -24685,7 +25227,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
24685
25227
  }
24686
25228
 
24687
25229
  //#endregion
24688
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/catalogs.js
25230
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/catalogs.js
24689
25231
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
24690
25232
  const inlineCatalogs = (manifest) => {
24691
25233
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -24751,7 +25293,28 @@ const rangeOf = (catalogs, dependency, specifier) => {
24751
25293
  };
24752
25294
 
24753
25295
  //#endregion
24754
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ConfigDependencyHooks.js
25296
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ConfigDependencyHooks.js
25297
+ /**
25298
+ * The empty {@link PeerDependencyRules}: every axis present and empty.
25299
+ *
25300
+ * @remarks
25301
+ * Exported so that "I assert this workspace's rules are empty" is **one token**
25302
+ * rather than three hand-written empty axes. That matters where the distinction
25303
+ * is load-bearing — supplying rules asserts they were looked up, while omitting
25304
+ * them asserts nothing — and a caller spelling the object out by hand will
25305
+ * eventually fill two of the three axes and mean the third.
25306
+ *
25307
+ * Frozen, since it is shared.
25308
+ *
25309
+ * @public
25310
+ */
25311
+ const NoPeerDependencyRules = Object.freeze({
25312
+ allowedVersions: Object.freeze({}),
25313
+ ignoreMissing: Object.freeze([]),
25314
+ allowAny: Object.freeze([])
25315
+ });
25316
+ /** Internal alias, kept short at the many call sites in this module. */
25317
+ const NO_PEER_RULES = NoPeerDependencyRules;
24755
25318
  /** Whether `value` is a non-null, non-array object. */
24756
25319
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24757
25320
  /**
@@ -24779,7 +25342,7 @@ const moduleNotFoundUrl = (cause) => isObject$2(cause) && cause.code === "ERR_MO
24779
25342
  */
24780
25343
  const hasTraversalSegment = (name) => name.split(/[/\\]/).includes("..");
24781
25344
  /** Turn the seed record into the pnpm hook config, with the default catalog split out under `catalog`. */
24782
- const seedToConfig = (seed) => {
25345
+ const seedToConfig = (seed, rules) => {
24783
25346
  const catalogs = {};
24784
25347
  let catalog = {};
24785
25348
  for (const [name, entries] of Object.entries(seed)) if (name === "default") catalog = { ...entries };
@@ -24788,7 +25351,8 @@ const seedToConfig = (seed) => {
24788
25351
  catalog,
24789
25352
  catalogs,
24790
25353
  minimumReleaseAge: void 0,
24791
- minimumReleaseAgeExclude: void 0
25354
+ minimumReleaseAgeExclude: void 0,
25355
+ peerDependencyRules: rules
24792
25356
  };
24793
25357
  };
24794
25358
  /** A finite number if `value` is one, else the prior threaded value — a garbage age is dropped, not fatal. */
@@ -24813,10 +25377,33 @@ const configOf = (value, fallback) => {
24813
25377
  catalog: isObject$2(value.catalog) ? value.catalog : fallback.catalog,
24814
25378
  catalogs: isObject$2(value.catalogs) ? value.catalogs : fallback.catalogs,
24815
25379
  minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
24816
- minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude)
25380
+ minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
25381
+ peerDependencyRules: peerRulesOr(value.peerDependencyRules, fallback.peerDependencyRules)
24817
25382
  };
24818
25383
  };
24819
25384
  /**
25385
+ * A peer-rules block if `value` is one, else the prior threaded value — a
25386
+ * malformed block is dropped, not fatal, matching the other slices.
25387
+ *
25388
+ * Each axis is normalized independently: a hook that rewrites `allowedVersions`
25389
+ * and leaves `ignoreMissing` alone must not blank the latter.
25390
+ */
25391
+ const stringRecordOr = (value, fallback) => isObject$2(value) && Object.values(value).every((entry) => typeof entry === "string") ? value : fallback;
25392
+ const peerRulesOr = (value, fallback) => {
25393
+ if (!isObject$2(value)) return fallback;
25394
+ const allowed = stringRecordOr(value.allowedVersions, fallback?.allowedVersions);
25395
+ const ignoreMissing = stringArrayOr(value.ignoreMissing, fallback?.ignoreMissing);
25396
+ const allowAny = stringArrayOr(value.allowAny, fallback?.allowAny);
25397
+ if (allowed === void 0 && ignoreMissing === void 0 && allowAny === void 0) return fallback;
25398
+ return {
25399
+ allowedVersions: allowed ?? {},
25400
+ ignoreMissing: ignoreMissing ?? [],
25401
+ allowAny: allowAny ?? []
25402
+ };
25403
+ };
25404
+ /** Project the threaded config's rules into the slice, defaulting every axis to empty. */
25405
+ const peerRulesOf = (config) => config.peerDependencyRules ?? NO_PEER_RULES;
25406
+ /**
24820
25407
  * Project the threaded config's release-age keys into a partial gate
24821
25408
  * contribution, omitting a key the hooks never set (never an explicit
24822
25409
  * `undefined` — the fields are `optionalKey`).
@@ -24869,13 +25456,23 @@ const updateConfigOf = (mod) => {
24869
25456
  * noise on stdout.
24870
25457
  */
24871
25458
  const REPLAY_SCRIPT = `
24872
- const [root, seedJson, ...names] = process.argv.slice(1);
25459
+ const [root, seedJson, rulesJson, ...names] = process.argv.slice(1);
24873
25460
  const { pathToFileURL } = await import("node:url");
24874
25461
  const { join } = await import("node:path");
24875
25462
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24876
25463
  const finiteNumberOr = (value, fallback) => (typeof value === "number" && Number.isFinite(value) ? value : fallback);
24877
25464
  const stringArrayOr = (value, fallback) =>
24878
25465
  Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : fallback;
25466
+ const stringRecordOr = (value, fallback) =>
25467
+ isObject(value) && Object.values(value).every((entry) => typeof entry === "string") ? value : fallback;
25468
+ const peerRulesOr = (value, fallback) => {
25469
+ if (!isObject(value)) return fallback;
25470
+ const allowed = stringRecordOr(value.allowedVersions, fallback && fallback.allowedVersions);
25471
+ const ignoreMissing = stringArrayOr(value.ignoreMissing, fallback && fallback.ignoreMissing);
25472
+ const allowAny = stringArrayOr(value.allowAny, fallback && fallback.allowAny);
25473
+ if (allowed === undefined && ignoreMissing === undefined && allowAny === undefined) return fallback;
25474
+ return { allowedVersions: allowed || {}, ignoreMissing: ignoreMissing || [], allowAny: allowAny || [] };
25475
+ };
24879
25476
  const configOf = (value, fallback) =>
24880
25477
  isObject(value)
24881
25478
  ? {
@@ -24883,6 +25480,7 @@ const configOf = (value, fallback) =>
24883
25480
  catalogs: isObject(value.catalogs) ? value.catalogs : fallback.catalogs,
24884
25481
  minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
24885
25482
  minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
25483
+ peerDependencyRules: peerRulesOr(value.peerDependencyRules, fallback.peerDependencyRules),
24886
25484
  }
24887
25485
  : fallback;
24888
25486
  const failure = (name, cause) => ({
@@ -24898,7 +25496,13 @@ const replay = async () => {
24898
25496
  if (name === "default") catalog = { ...entries };
24899
25497
  else catalogs[name] = { ...entries };
24900
25498
  }
24901
- let config = { catalog, catalogs, minimumReleaseAge: undefined, minimumReleaseAgeExclude: undefined };
25499
+ let config = {
25500
+ catalog,
25501
+ catalogs,
25502
+ minimumReleaseAge: undefined,
25503
+ minimumReleaseAgeExclude: undefined,
25504
+ peerDependencyRules: JSON.parse(rulesJson),
25505
+ };
24902
25506
  for (const name of names) {
24903
25507
  let loaded;
24904
25508
  let found = false;
@@ -24999,9 +25603,10 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
24999
25603
  * config dependency. The default {@link WorkspaceCatalogs} layer wires this, so
25000
25604
  * the default catalog path provably executes no config-dependency code.
25001
25605
  */
25002
- static layerNoop = Layer.succeed(ConfigDependencyHooks, { inject: (_root, _configDependencies, seed) => Effect.succeed({
25606
+ static layerNoop = Layer.succeed(ConfigDependencyHooks, { inject: (_root, _configDependencies, seed, rules) => Effect.succeed({
25003
25607
  catalogs: seed,
25004
- releaseAge: {}
25608
+ releaseAge: {},
25609
+ peerDependencyRules: rules ?? NO_PEER_RULES
25005
25610
  }) });
25006
25611
  /**
25007
25612
  * The live layer: dynamically imports each config dependency's `pnpmfile.cjs`
@@ -25019,13 +25624,14 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25019
25624
  * import, so this layer runs on either runtime. Only ever wired by
25020
25625
  * `WorkspaceCatalogs.layerWithConfigDependencies`.
25021
25626
  */
25022
- static layerLive = Layer.succeed(ConfigDependencyHooks, { inject: (root, configDependencies, seed) => Effect.gen(function* () {
25627
+ static layerLive = Layer.succeed(ConfigDependencyHooks, { inject: (root, configDependencies, seed, rules) => Effect.gen(function* () {
25023
25628
  const names = Object.keys(configDependencies);
25024
25629
  if (names.length === 0) return {
25025
25630
  catalogs: seed,
25026
- releaseAge: {}
25631
+ releaseAge: {},
25632
+ peerDependencyRules: rules ?? NO_PEER_RULES
25027
25633
  };
25028
- let config = seedToConfig(seed);
25634
+ let config = seedToConfig(seed, rules);
25029
25635
  for (const name of names) {
25030
25636
  if (hasTraversalSegment(name)) return yield* Effect.fail(new CatalogAssemblyError({
25031
25637
  source: "hooks",
@@ -25071,7 +25677,8 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25071
25677
  }
25072
25678
  return {
25073
25679
  catalogs: configToEntries(config),
25074
- releaseAge: releaseAgeOf(config)
25680
+ releaseAge: releaseAgeOf(config),
25681
+ peerDependencyRules: peerRulesOf(config)
25075
25682
  };
25076
25683
  }) });
25077
25684
  /**
@@ -25127,11 +25734,12 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25127
25734
  */
25128
25735
  static layerSubprocess = Layer.effect(ConfigDependencyHooks, Effect.gen(function* () {
25129
25736
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
25130
- return { inject: (root, configDependencies, seed) => Effect.gen(function* () {
25737
+ return { inject: (root, configDependencies, seed, rules) => Effect.gen(function* () {
25131
25738
  const names = Object.keys(configDependencies);
25132
25739
  if (names.length === 0) return {
25133
25740
  catalogs: seed,
25134
- releaseAge: {}
25741
+ releaseAge: {},
25742
+ peerDependencyRules: rules ?? NO_PEER_RULES
25135
25743
  };
25136
25744
  for (const name of names) if (hasTraversalSegment(name)) return yield* Effect.fail(new CatalogAssemblyError({
25137
25745
  source: "hooks",
@@ -25144,6 +25752,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25144
25752
  REPLAY_SCRIPT,
25145
25753
  root,
25146
25754
  JSON.stringify(seed),
25755
+ JSON.stringify(rules ?? NO_PEER_RULES),
25147
25756
  ...names
25148
25757
  ]);
25149
25758
  const payload = yield* Run.jsonLine(command, ReplayPayload, { timeout: REPLAY_TIMEOUT }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.catch((cause) => Effect.fail(new CatalogAssemblyError({
@@ -25156,17 +25765,18 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25156
25765
  path: payload.name ?? root,
25157
25766
  cause: replayFailureCause(payload)
25158
25767
  }));
25159
- const config = configOf(payload.config, seedToConfig(seed));
25768
+ const config = configOf(payload.config, seedToConfig(seed, rules));
25160
25769
  return {
25161
25770
  catalogs: configToEntries(config),
25162
- releaseAge: releaseAgeOf(config)
25771
+ releaseAge: releaseAgeOf(config),
25772
+ peerDependencyRules: peerRulesOf(config)
25163
25773
  };
25164
25774
  }) };
25165
25775
  }));
25166
25776
  };
25167
25777
 
25168
25778
  //#endregion
25169
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/PackageManagerName.js
25779
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/PackageManagerName.js
25170
25780
  /**
25171
25781
  * The four package managers this package understands.
25172
25782
  *
@@ -25542,7 +26152,7 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
25542
26152
  };
25543
26153
 
25544
26154
  //#endregion
25545
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/LockfileReader.js
26155
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/LockfileReader.js
25546
26156
  /**
25547
26157
  * Raised when the workspace's lockfile cannot be read off disk.
25548
26158
  *
@@ -25723,7 +26333,7 @@ var LockfileReader = class LockfileReader extends Context.Service()("@effected/w
25723
26333
  };
25724
26334
 
25725
26335
  //#endregion
25726
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Publishability.js
26336
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Publishability.js
25727
26337
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
25728
26338
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
25729
26339
  /**
@@ -25883,7 +26493,7 @@ var PublishabilityDetector = class extends Context.Service()("@effected/workspac
25883
26493
  };
25884
26494
 
25885
26495
  //#endregion
25886
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/importerVersions.js
26496
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/importerVersions.js
25887
26497
  /**
25888
26498
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
25889
26499
  *
@@ -25970,7 +26580,7 @@ const unanimousVersionOf = (index, dependency) => {
25970
26580
  };
25971
26581
 
25972
26582
  //#endregion
25973
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceCatalogs.js
26583
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceCatalogs.js
25974
26584
  /**
25975
26585
  * An immutable, fully-normalized catalog collection — the one catalog
25976
26586
  * resolution semantic in the package.
@@ -26174,6 +26784,41 @@ const inlineReleaseAge = (document) => {
26174
26784
  cause
26175
26785
  })));
26176
26786
  };
26787
+ /**
26788
+ * The `peerDependencyRules` a `pnpm-workspace.yaml` declares inline — the half
26789
+ * `pnpm:export` materializes into the file, as opposed to the half a config
26790
+ * dependency injects at replay time.
26791
+ *
26792
+ * @remarks
26793
+ * **Tolerant, unlike the catalog blocks**, and the asymmetry is deliberate: a
26794
+ * malformed catalog block must hard-fail because a silently-empty catalog makes
26795
+ * every dependency look newly added, whereas a malformed rules block costs only
26796
+ * suppression — the failure mode is reporting a peer pnpm would have hidden,
26797
+ * which is visible and safe. Failing the whole assembly over it would take the
26798
+ * catalogs down with it.
26799
+ *
26800
+ * Every axis is read independently, so a malformed `ignoreMissing` does not
26801
+ * discard a well-formed `allowedVersions`.
26802
+ */
26803
+ const EMPTY_PEER_RULES = {
26804
+ allowedVersions: {},
26805
+ ignoreMissing: [],
26806
+ allowAny: []
26807
+ };
26808
+ const inlinePeerDependencyRules = (document) => {
26809
+ if (!isObject$1(document) || !isObject$1(document.peerDependencyRules)) return EMPTY_PEER_RULES;
26810
+ const block = document.peerDependencyRules;
26811
+ const allowedVersions = {};
26812
+ if (isObject$1(block.allowedVersions)) {
26813
+ for (const [key, value] of Object.entries(block.allowedVersions)) if (typeof value === "string") allowedVersions[key] = value;
26814
+ }
26815
+ const strings = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
26816
+ return {
26817
+ allowedVersions,
26818
+ ignoreMissing: strings(block.ignoreMissing),
26819
+ allowAny: strings(block.allowAny)
26820
+ };
26821
+ };
26177
26822
  /** A hard-fail catalog-assembly failure naming the malformed part of a `workspaces` field. */
26178
26823
  const malformed = (source, path, detail) => new CatalogAssemblyError({
26179
26824
  source,
@@ -26306,6 +26951,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26306
26951
  let injected;
26307
26952
  let inlineGate = {};
26308
26953
  let hookGate = {};
26954
+ let peerDependencyRules = EMPTY_PEER_RULES;
26309
26955
  if (hasPnpmWorkspace) {
26310
26956
  const text = yield* fs.readFileString(workspaceYaml).pipe(Effect.mapError((cause) => new CatalogAssemblyError({
26311
26957
  source: "manifest",
@@ -26320,15 +26966,17 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26320
26966
  yield* validatePnpmWorkspaceCatalogs(document);
26321
26967
  inline = CatalogSet.fromCatalogs(inlineCatalogs(catalogBlocksOf(document)));
26322
26968
  inlineGate = yield* inlineReleaseAge(document);
26323
- const injection = yield* hooks.inject(root, configDependenciesOf(document), inline.entries);
26969
+ const injection = yield* hooks.inject(root, configDependenciesOf(document), inline.entries, inlinePeerDependencyRules(document));
26324
26970
  injected = CatalogSet.fromCatalogs(injection.catalogs);
26325
26971
  hookGate = injection.releaseAge;
26972
+ peerDependencyRules = injection.peerDependencyRules;
26326
26973
  } else {
26327
26974
  const manifestPath = path.join(root, "package.json");
26328
26975
  if (!(yield* probeExists(manifestPath))) return {
26329
26976
  catalogs: fromLockfile,
26330
26977
  releaseAgeGate: ReleaseAgeGate.combine(),
26331
- importerVersions
26978
+ importerVersions,
26979
+ peerDependencyRules: EMPTY_PEER_RULES
26332
26980
  };
26333
26981
  const text = yield* fs.readFileString(manifestPath).pipe(Effect.mapError((cause) => new CatalogAssemblyError({
26334
26982
  source: "manifest",
@@ -26348,7 +26996,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26348
26996
  return {
26349
26997
  catalogs: assembled,
26350
26998
  releaseAgeGate,
26351
- importerVersions
26999
+ importerVersions,
27000
+ peerDependencyRules
26352
27001
  };
26353
27002
  });
26354
27003
  const [resolveOnce, invalidate] = yield* Effect.cachedInvalidateWithTTL(assemble, Duration.infinity);
@@ -26360,6 +27009,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26360
27009
  resolveSpecifier: Effect.fn("WorkspaceCatalogs.resolveSpecifier")(function* (dependency, specifier) {
26361
27010
  return (yield* memo).catalogs.resolveSpecifier(dependency, specifier);
26362
27011
  }),
27012
+ peerDependencyRules: Effect.fn("WorkspaceCatalogs.peerDependencyRules")(function* () {
27013
+ return (yield* memo).peerDependencyRules;
27014
+ }),
26363
27015
  releaseAgeGate: Effect.fn("WorkspaceCatalogs.releaseAgeGate")(function* () {
26364
27016
  return (yield* memo).releaseAgeGate;
26365
27017
  }),
@@ -26446,6 +27098,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26446
27098
  return {
26447
27099
  set: () => unstubbed$1("set"),
26448
27100
  resolveSpecifier: set !== void 0 ? (dependency, specifier) => Effect.map(set(), (catalogs) => catalogs.resolveSpecifier(dependency, specifier)) : () => unstubbed$1("resolveSpecifier"),
27101
+ peerDependencyRules: () => unstubbed$1("peerDependencyRules"),
26449
27102
  releaseAgeGate: () => unstubbed$1("releaseAgeGate"),
26450
27103
  importerVersions: () => unstubbed$1("importerVersions"),
26451
27104
  ...overrides
@@ -26498,7 +27151,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26498
27151
  };
26499
27152
 
26500
27153
  //#endregion
26501
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
27154
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
26502
27155
  const EMPTY = Object.freeze(Object.create(null));
26503
27156
  const DependencyMap = Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY)), Schema.withConstructorDefault(Effect.succeed(EMPTY)));
26504
27157
  /**
@@ -26722,7 +27375,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
26722
27375
  };
26723
27376
 
26724
27377
  //#endregion
26725
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceSnapshots.js
27378
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceSnapshots.js
26726
27379
  /** Whether `value` is a non-null, non-array object. */
26727
27380
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26728
27381
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -27000,7 +27653,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends Context.Service()("@ef
27000
27653
  };
27001
27654
 
27002
27655
  //#endregion
27003
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Workspaces.js
27656
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Workspaces.js
27004
27657
  const compose = (options, catalogsFactory) => {
27005
27658
  const roots = WorkspaceRoot.layer;
27006
27659
  const detector = PackageManagerDetector.layer;