@vltpkg/cli-js 1.5.0 → 1.6.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.
Files changed (98) hide show
  1. package/{access-QPX4QXV4.js → access-AJ654YKY.js} +8 -8
  2. package/{bugs-TLOECXEM.js → bugs-N73DVYHD.js} +23 -19
  3. package/{build-IQOS3LKO.js → build-VZ3EZKMM.js} +49 -14
  4. package/{cache-O5IBYYSB.js → cache-VROEWG2C.js} +16 -13
  5. package/cache-unzip-src-unzip.js +23 -4
  6. package/{chunk-7UWRR6EE.js → chunk-22LZBDEC.js} +1 -1
  7. package/{chunk-4UH3KMTD.js → chunk-36UIE654.js} +252 -448
  8. package/{chunk-43EJ4Q42.js → chunk-3JIN46K5.js} +1 -1
  9. package/{chunk-35EG6T3J.js → chunk-44AWMA4F.js} +21 -9
  10. package/chunk-4E65BBTM.js +77 -0
  11. package/{chunk-5KW6AOTT.js → chunk-4GMNWW4C.js} +1 -1
  12. package/{chunk-LUVDMEW4.js → chunk-6D3QAFNZ.js} +1 -1
  13. package/{chunk-6W5XMVIZ.js → chunk-75HGJVNG.js} +7 -7
  14. package/{chunk-UZ6ICZE3.js → chunk-7M2VTFLP.js} +12 -1
  15. package/{chunk-XCSNI6AO.js → chunk-ANW36H4T.js} +4 -4
  16. package/{chunk-6LZM3I4Q.js → chunk-BF5DRGRZ.js} +25 -4
  17. package/chunk-BH5CVXNY.js +115 -0
  18. package/{chunk-F7NPYSI2.js → chunk-CAV7FKWQ.js} +2 -2
  19. package/{chunk-MYX4JCIJ.js → chunk-CYK6I4M6.js} +1 -1
  20. package/chunk-DXED4ARV.js +436 -0
  21. package/chunk-E74WGW5C.js +49 -0
  22. package/{chunk-CMLDLZZ3.js → chunk-EFHOWRKU.js} +56 -0
  23. package/{chunk-IFEZ6BFV.js → chunk-EMTGRCSE.js} +2 -2
  24. package/{chunk-4TSHLSRK.js → chunk-EYGOEAJM.js} +1 -1
  25. package/{chunk-2U4PVHP4.js → chunk-F5LZMLAQ.js} +123 -40
  26. package/{chunk-Z5D5KODU.js → chunk-FXD3IV2S.js} +4 -2
  27. package/chunk-GCTREKA4.js +115 -0
  28. package/{chunk-G3FZ2ZJK.js → chunk-GEQFMH5M.js} +1 -1
  29. package/{chunk-CS6AYPY5.js → chunk-GZVI75KX.js} +6 -13
  30. package/{chunk-CW56EJIL.js → chunk-HT6FS4VB.js} +1 -1
  31. package/{chunk-LH7J5BDU.js → chunk-IXAMCWIT.js} +3 -3
  32. package/{chunk-ARE7FKDG.js → chunk-JCNI6ZHH.js} +5 -5
  33. package/chunk-JV5XR5JQ.js +349 -0
  34. package/{chunk-IJUVVD7E.js → chunk-KD5ZK72K.js} +1 -1
  35. package/{chunk-WHWPAYZY.js → chunk-KVWGMSPW.js} +26 -6
  36. package/{chunk-VR7NRWAD.js → chunk-LCLRP64K.js} +8 -8
  37. package/{chunk-X6JKMIOU.js → chunk-LGQVZTYR.js} +4 -36
  38. package/{chunk-XCQCYB6G.js → chunk-LP3ORD3D.js} +142 -16
  39. package/chunk-MCDLJZXT.js +82 -0
  40. package/{chunk-ISAMD2FE.js → chunk-N6HV7JWC.js} +1 -1
  41. package/chunk-O6MQ7NN6.js +1155 -0
  42. package/{chunk-3S3W7QEM.js → chunk-PC2HOBAQ.js} +3 -3
  43. package/{chunk-GUP55DM6.js → chunk-RBQO54TG.js} +2 -2
  44. package/{chunk-C6ZVVEFV.js → chunk-TQQO2F56.js} +4 -3
  45. package/{chunk-XD5KUDXX.js → chunk-TWDSXQPN.js} +10 -8
  46. package/{chunk-T5EP7QEF.js → chunk-VLVMLSIF.js} +2 -2
  47. package/{chunk-SMXXFQPI.js → chunk-YTDABXPD.js} +3 -3
  48. package/{ci-ESVUMOZO.js → ci-3BVMVQIT.js} +21 -17
  49. package/cli-package.json +3 -1
  50. package/{config-ZVVLFKR7.js → config-2KQV7N5A.js} +12 -11
  51. package/{config-TMB2X6DW.js → config-EKHBW6I5.js} +10 -9
  52. package/{create-BLTNKSBQ.js → create-QVHNOIV3.js} +28 -24
  53. package/{deprecate-VA6PGHYL.js → deprecate-E254QBH6.js} +12 -12
  54. package/{dist-tag-OYJREFO2.js → dist-tag-SITRFD7O.js} +8 -8
  55. package/{docs-6OC3OQNM.js → docs-IDL2P7CA.js} +23 -19
  56. package/{exec-AZPGFVRY.js → exec-7BK2W2WL.js} +28 -24
  57. package/{exec-cache-D75UY2WI.js → exec-cache-VY46L7DR.js} +24 -20
  58. package/{exec-local-E2JKB4X4.js → exec-local-D7R5T3DF.js} +22 -18
  59. package/{help-UPW77X5N.js → help-RMRIEJQL.js} +5 -4
  60. package/{init-SNO6QL7C.js → init-BGW4HJ6V.js} +13 -12
  61. package/{install-TEJM2YVX.js → install-U5GATZ2N.js} +108 -52
  62. package/{list-NHCC2RNB.js → list-3VG4M2XL.js} +29 -22
  63. package/{login-XNZXCGFD.js → login-PHQWI6S6.js} +14 -13
  64. package/{logout-YCM7O36Q.js → logout-DJCOGRFF.js} +8 -8
  65. package/{outdated-4LA7N63W.js → outdated-JH3O6R3Y.js} +18 -17
  66. package/{pack-RC4CZSWF.js → pack-U5W5YWHK.js} +15 -14
  67. package/package.json +1 -1
  68. package/{ping-RLVAZGDL.js → ping-EKX43AOW.js} +8 -8
  69. package/{pkg-FED5C6TP.js → pkg-SW5GMERT.js} +15 -14
  70. package/{profile-DJZNLQPG.js → profile-UGDRDMQ6.js} +8 -8
  71. package/{publish-54AMVMTQ.js → publish-HTWKK3NN.js} +24 -20
  72. package/{query-ZQLMSJ7O.js → query-YE3FUVGG.js} +29 -22
  73. package/{registry-6HKQYSZX.js → registry-ZGGWVLBM.js} +5 -5
  74. package/registry-client-src-revalidate.js +41 -11
  75. package/{repo-ITA4BLZ4.js → repo-WDOCU6SE.js} +23 -19
  76. package/{reporter-UYVR2WMB.js → reporter-N5PAXB26.js} +61 -15
  77. package/{run-TP2HTJRN.js → run-IPARVIIQ.js} +22 -18
  78. package/{run-exec-UGCC53DV.js → run-exec-C4RTREEW.js} +22 -18
  79. package/security-archive-src-update-expired.js +24 -5
  80. package/{setup-XPAM5U3Z.js → setup-SYYUEHZL.js} +206 -27
  81. package/{skills-YD2TB2VD.js → skills-KA2VR5Q5.js} +41 -56
  82. package/{skills-LR6GXW3X.js → skills-UBBMSBDQ.js} +24 -21
  83. package/{src-34D4DOOH.js → src-FUSTSM4J.js} +25 -19
  84. package/{src-H6DFCAPH.js → src-QO5G2S4O.js} +6 -4
  85. package/{src-LHDC4NJO.js → src-W2VQULRG.js} +2 -2
  86. package/{token-OF63PFTQ.js → token-UQNABECH.js} +10 -9
  87. package/{uninstall-B54FQ5KQ.js → uninstall-FHBJ3OUV.js} +53 -17
  88. package/{unpublish-CSHIGMDQ.js → unpublish-APJTEUBA.js} +8 -8
  89. package/{update-HS4VJ5ZG.js → update-NWZTL4S7.js} +19 -17
  90. package/{version-L7S3DHUS.js → version-EMKKTL77.js} +14 -13
  91. package/{view-NWKKWFVA.js → view-BUUI33RV.js} +12 -12
  92. package/vlr.js +1 -1
  93. package/vlrx.js +1 -1
  94. package/vlt.js +1 -1
  95. package/vlx.js +1 -1
  96. package/vlxl.js +1 -1
  97. package/{whoami-65K35VGW.js → whoami-F6BSXGQ2.js} +8 -8
  98. package/chunk-T2VBCUF5.js +0 -77
@@ -51,20 +51,25 @@ import {
51
51
  shouldInstallDepType,
52
52
  symlinkSyncMkdirp,
53
53
  unshare
54
- } from "./chunk-2U4PVHP4.js";
54
+ } from "./chunk-F5LZMLAQ.js";
55
55
  import {
56
56
  SecurityArchive,
57
57
  usesNpmRegistry
58
- } from "./chunk-SMXXFQPI.js";
58
+ } from "./chunk-YTDABXPD.js";
59
+ import {
60
+ RollbackRemove,
61
+ cmdShimIfExists,
62
+ readCmdShimIfExists
63
+ } from "./chunk-JV5XR5JQ.js";
59
64
  import {
60
65
  detectLibc,
61
66
  getUser,
62
67
  platformCheck
63
- } from "./chunk-IFEZ6BFV.js";
68
+ } from "./chunk-EMTGRCSE.js";
64
69
  import {
65
70
  Monorepo,
66
71
  PackageJson
67
- } from "./chunk-C6ZVVEFV.js";
72
+ } from "./chunk-TQQO2F56.js";
68
73
  import {
69
74
  baseDepID,
70
75
  getTuple,
@@ -73,17 +78,17 @@ import {
73
78
  joinDepIDTuple,
74
79
  joinExtra,
75
80
  splitDepID
76
- } from "./chunk-F7NPYSI2.js";
81
+ } from "./chunk-CAV7FKWQ.js";
77
82
  import {
78
83
  Spec as Spec2
79
- } from "./chunk-LUVDMEW4.js";
84
+ } from "./chunk-6D3QAFNZ.js";
80
85
  import {
81
86
  load,
82
87
  walkUp
83
88
  } from "./chunk-HTOTG4TS.js";
84
89
  import {
85
90
  userAgent
86
- } from "./chunk-G3FZ2ZJK.js";
91
+ } from "./chunk-GEQFMH5M.js";
87
92
  import {
88
93
  promiseSpawn
89
94
  } from "./chunk-SUU2WETN.js";
@@ -93,9 +98,6 @@ import {
93
98
  import {
94
99
  XDG
95
100
  } from "./chunk-XNLSTHDK.js";
96
- import {
97
- rimraf
98
- } from "./chunk-PDWPFR5T.js";
99
101
  import {
100
102
  Spec,
101
103
  Version,
@@ -108,7 +110,7 @@ import {
108
110
  longDependencyTypes,
109
111
  normalizeManifest,
110
112
  parse
111
- } from "./chunk-6LZM3I4Q.js";
113
+ } from "./chunk-BF5DRGRZ.js";
112
114
  import {
113
115
  error
114
116
  } from "./chunk-WZWDS3W4.js";
@@ -141,15 +143,15 @@ var require_windows = __commonJS({
141
143
  }
142
144
  return false;
143
145
  }
144
- function checkStat(stat3, path, options) {
145
- if (!stat3.isSymbolicLink() && !stat3.isFile()) {
146
+ function checkStat(stat2, path, options) {
147
+ if (!stat2.isSymbolicLink() && !stat2.isFile()) {
146
148
  return false;
147
149
  }
148
150
  return checkPathExt(path, options);
149
151
  }
150
152
  function isexe(path, options, cb) {
151
- fs.stat(path, function(er, stat3) {
152
- cb(er, er ? false : checkStat(stat3, path, options));
153
+ fs.stat(path, function(er, stat2) {
154
+ cb(er, er ? false : checkStat(stat2, path, options));
153
155
  });
154
156
  }
155
157
  function sync(path, options) {
@@ -165,20 +167,20 @@ var require_mode = __commonJS({
165
167
  isexe.sync = sync;
166
168
  var fs = __require("node:fs");
167
169
  function isexe(path, options, cb) {
168
- fs.stat(path, function(er, stat3) {
169
- cb(er, er ? false : checkStat(stat3, options));
170
+ fs.stat(path, function(er, stat2) {
171
+ cb(er, er ? false : checkStat(stat2, options));
170
172
  });
171
173
  }
172
174
  function sync(path, options) {
173
175
  return checkStat(fs.statSync(path), options);
174
176
  }
175
- function checkStat(stat3, options) {
176
- return stat3.isFile() && checkMode(stat3, options);
177
+ function checkStat(stat2, options) {
178
+ return stat2.isFile() && checkMode(stat2, options);
177
179
  }
178
- function checkMode(stat3, options) {
179
- var mod = stat3.mode;
180
- var uid = stat3.uid;
181
- var gid = stat3.gid;
180
+ function checkMode(stat2, options) {
181
+ var mod = stat2.mode;
182
+ var uid = stat2.uid;
183
+ var gid = stat2.gid;
182
184
  var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
183
185
  var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
184
186
  var u = parseInt("100", 8);
@@ -212,12 +214,12 @@ var require_isexe = __commonJS({
212
214
  if (typeof Promise !== "function") {
213
215
  throw new TypeError("callback not provided");
214
216
  }
215
- return new Promise(function(resolve10, reject) {
217
+ return new Promise(function(resolve9, reject) {
216
218
  isexe(path, options || {}, function(er, is) {
217
219
  if (er) {
218
220
  reject(er);
219
221
  } else {
220
- resolve10(is);
222
+ resolve9(is);
221
223
  }
222
224
  });
223
225
  });
@@ -283,27 +285,27 @@ var require_which = __commonJS({
283
285
  opt = {};
284
286
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
285
287
  const found = [];
286
- const step = (i) => new Promise((resolve10, reject) => {
288
+ const step = (i) => new Promise((resolve9, reject) => {
287
289
  if (i === pathEnv.length)
288
- return opt.all && found.length ? resolve10(found) : reject(getNotFoundError(cmd));
290
+ return opt.all && found.length ? resolve9(found) : reject(getNotFoundError(cmd));
289
291
  const ppRaw = pathEnv[i];
290
292
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
291
293
  const pCmd = path.join(pathPart, cmd);
292
294
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
293
- resolve10(subStep(p, i, 0));
295
+ resolve9(subStep(p, i, 0));
294
296
  });
295
- const subStep = (p, i, ii) => new Promise((resolve10, reject) => {
297
+ const subStep = (p, i, ii) => new Promise((resolve9, reject) => {
296
298
  if (ii === pathExt.length)
297
- return resolve10(step(i + 1));
299
+ return resolve9(step(i + 1));
298
300
  const ext = pathExt[ii];
299
301
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
300
302
  if (!er && is) {
301
303
  if (opt.all)
302
304
  found.push(p + ext);
303
305
  else
304
- return resolve10(p + ext);
306
+ return resolve9(p + ext);
305
307
  }
306
- return resolve10(subStep(p, i, ii + 1));
308
+ return resolve9(subStep(p, i, ii + 1));
307
309
  });
308
310
  });
309
311
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -595,7 +597,7 @@ var require_cross_spawn = __commonJS({
595
597
  var cp = __require("node:child_process");
596
598
  var parse3 = require_parse();
597
599
  var enoent = require_enoent();
598
- function spawn4(command, args, options) {
600
+ function spawn3(command, args, options) {
599
601
  const parsed = parse3(command, args, options);
600
602
  const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
601
603
  enoent.hookChildProcess(spawned, parsed);
@@ -607,8 +609,8 @@ var require_cross_spawn = __commonJS({
607
609
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
608
610
  return result;
609
611
  }
610
- module.exports = spawn4;
611
- module.exports.spawn = spawn4;
612
+ module.exports = spawn3;
613
+ module.exports.spawn = spawn3;
612
614
  module.exports.sync = spawnSync;
613
615
  module.exports._parse = parse3;
614
616
  module.exports._enoent = enoent;
@@ -1094,28 +1096,28 @@ var nmBin = `${sep}node_modules${sep}.bin`;
1094
1096
  var addPaths = async (projectRoot, cwd, env, command) => {
1095
1097
  const { PATH = "" } = env;
1096
1098
  const PATHsplit = PATH.split(delimiter);
1097
- const paths2 = /* @__PURE__ */ new Set();
1099
+ const paths = /* @__PURE__ */ new Set();
1098
1100
  for (const p of PATHsplit) {
1099
1101
  if (p.endsWith(nmBin)) {
1100
- paths2.add(p);
1102
+ paths.add(p);
1101
1103
  }
1102
1104
  }
1103
1105
  for (const p of walkUp(cwd)) {
1104
1106
  const dotBin = resolve(p, "node_modules/.bin");
1105
- if (dirExists(dotBin)) paths2.add(dotBin);
1107
+ if (dirExists(dotBin)) paths.add(dotBin);
1106
1108
  if (p === projectRoot) break;
1107
1109
  }
1108
1110
  for (const p of PATH.split(delimiter)) {
1109
- if (p) paths2.add(p);
1111
+ if (p) paths.add(p);
1110
1112
  }
1111
1113
  if (command && hasNodeGypReference(command)) {
1112
1114
  try {
1113
1115
  const shimDir = await getNodeGypShimDir();
1114
- paths2.add(shimDir);
1116
+ paths.add(shimDir);
1115
1117
  } catch {
1116
1118
  }
1117
1119
  }
1118
- env.PATH = [...paths2].join(delimiter);
1120
+ env.PATH = [...paths].join(delimiter);
1119
1121
  return env;
1120
1122
  };
1121
1123
  var run = async (options) => runImpl(options, exec, "");
@@ -2061,73 +2063,6 @@ function mermaidOutput(options) {
2061
2063
  return "flowchart TD\n" + graphOutput + styleDefinition;
2062
2064
  }
2063
2065
 
2064
- // ../../src/rollback-remove/src/index.ts
2065
- import { spawn as spawn3 } from "node:child_process";
2066
- import { rename } from "node:fs/promises";
2067
- import { basename, dirname as dirname2 } from "node:path";
2068
-
2069
- // ../../src/rollback-remove/src/remove.ts
2070
- import { resolve as resolve2 } from "node:path";
2071
- var __CODE_SPLIT_SCRIPT_NAME = resolve2(import.meta.dirname, "rollback-remove-src-remove.js");
2072
-
2073
- // ../../src/rollback-remove/src/index.ts
2074
- var isDeno = globalThis.Deno != void 0;
2075
- var RollbackRemove = class {
2076
- #key = String(Math.random()).substring(2);
2077
- #paths = /* @__PURE__ */ new Map();
2078
- async rm(path) {
2079
- if (this.#paths.has(path)) return;
2080
- const target = `${dirname2(path)}/.VLT.DELETE.${this.#key}.${basename(path)}`;
2081
- try {
2082
- await rename(path, target);
2083
- } catch (e) {
2084
- if (e instanceof Error && "code" in e && /* c8 ignore start - very spurious weirdness on Windows */
2085
- (e.code === "ENOENT" || e.code === "EPERM")) {
2086
- return;
2087
- }
2088
- throw e;
2089
- }
2090
- this.#paths.set(path, target);
2091
- }
2092
- confirm() {
2093
- if (!this.#paths.size) return;
2094
- const env = { ...process.env };
2095
- const args = [];
2096
- const detached = !(isDeno && process.platform === "win32");
2097
- if (isDeno) {
2098
- args.push(
2099
- "--unstable-node-globals",
2100
- "--unstable-bare-node-builtins"
2101
- );
2102
- }
2103
- args.push(__CODE_SPLIT_SCRIPT_NAME);
2104
- const child = spawn3(process.execPath, args, {
2105
- stdio: ["pipe", "ignore", "ignore"],
2106
- detached,
2107
- env
2108
- });
2109
- for (const path of this.#paths.values()) {
2110
- child.stdin.write(`${path}\0`);
2111
- }
2112
- child.stdin.end();
2113
- if (detached) {
2114
- child.unref();
2115
- }
2116
- this.#paths.clear();
2117
- }
2118
- async rollback() {
2119
- const promises = [];
2120
- for (const [original, moved] of this.#paths) {
2121
- promises.push(
2122
- rimraf(original).catch(() => {
2123
- }).then(() => rename(moved, original))
2124
- );
2125
- }
2126
- await Promise.all(promises);
2127
- this.#paths.clear();
2128
- }
2129
- };
2130
-
2131
2066
  // ../../src/dss-breadcrumb/src/index.ts
2132
2067
  var passthroughComparator = () => () => true;
2133
2068
  var semverComparator = ({ range }) => ({ semver }) => {
@@ -2371,7 +2306,8 @@ var specificitySort = (breadcrumbs) => {
2371
2306
  };
2372
2307
 
2373
2308
  // ../../src/graph/src/modifiers.ts
2374
- var matchesImporter = (item, importer) => item.importer && (item.value === ":project" || item.value === ":root" && importer.mainImporter || item.value === ":workspace" && importer.importer);
2309
+ var matchesImporter = (item, importer) => item.importer && importer.importer && (item.value === ":project" || item.value === ":workspace" || item.value === ":root" && importer.mainImporter);
2310
+ var isWorkspaceTarget = (item) => item.importer && item.value === ":workspace" && !!item.prev?.importer && !item.prev.name && !item.prev.prev;
2375
2311
  var matchesQualifier = (item, spec) => !!item?.comparator({ semver: spec.semver });
2376
2312
  var GraphModifier = class _GraphModifier {
2377
2313
  /** The loaded modifiers configuration */
@@ -2403,6 +2339,14 @@ var GraphModifier = class _GraphModifier {
2403
2339
  activeModifiers = /* @__PURE__ */ new Set();
2404
2340
  /** A set of all modifier string values loaded from vlt.json */
2405
2341
  modifierNames = /* @__PURE__ */ new Set();
2342
+ /** Spec options used when expanding `:workspace` targets */
2343
+ #options = {};
2344
+ /** `<importer> > :workspace` modifiers, expanded once a graph is known */
2345
+ #workspaceTargets = [];
2346
+ /** Graphs whose workspaces were already expanded */
2347
+ #expandedGraphs = /* @__PURE__ */ new WeakSet();
2348
+ /** Workspace names already expanded */
2349
+ #expandedNames = /* @__PURE__ */ new Set();
2406
2350
  constructor(options) {
2407
2351
  this.load(options);
2408
2352
  }
@@ -2424,16 +2368,27 @@ var GraphModifier = class _GraphModifier {
2424
2368
  * root's own b edge is still the manifest's to validate and heal.
2425
2369
  */
2426
2370
  targetsImporterEdge(importer, spec) {
2427
- for (const { breadcrumb } of this.#modifiers) {
2428
- const { last } = breadcrumb;
2371
+ return !!this.importerEdgeModifier(importer, spec);
2372
+ }
2373
+ /**
2374
+ * The modifier governing the direct `importer -> spec.name` edge, see
2375
+ * {@link GraphModifier.targetsImporterEdge}. The most specific one
2376
+ * wins, same as during the graph build.
2377
+ */
2378
+ importerEdgeModifier(importer, spec) {
2379
+ this.#expandWorkspaceTargets(importer);
2380
+ const found = [];
2381
+ for (const mod of this.#modifiers) {
2382
+ const { last } = mod.breadcrumb;
2429
2383
  if (last.name !== spec.name) continue;
2430
2384
  if (!matchesQualifier(last, spec)) continue;
2431
2385
  const { prev } = last;
2432
- if (!prev) return true;
2433
- if (prev.prev) continue;
2434
- if (matchesImporter(prev, importer)) return true;
2386
+ if (!prev || !prev.prev && matchesImporter(prev, importer)) {
2387
+ found.push(mod);
2388
+ }
2435
2389
  }
2436
- return false;
2390
+ const [best] = specificitySort(found.map((m) => m.breadcrumb));
2391
+ return found.find((m) => m.breadcrumb === best);
2437
2392
  }
2438
2393
  /**
2439
2394
  * Selector of the modifier that wins the direct `importer -> spec.name`
@@ -2462,12 +2417,18 @@ var GraphModifier = class _GraphModifier {
2462
2417
  * Loads the modifiers defined in `vlt.json` into memory.
2463
2418
  */
2464
2419
  load(options) {
2420
+ this.#options = options;
2465
2421
  for (const [key, value] of Object.entries(this.config)) {
2466
2422
  this.modifierNames.add(key);
2467
2423
  const breadcrumb = parseBreadcrumb(key);
2468
2424
  if (!breadcrumb.last.name) {
2469
- throw error("Could not find name in breadcrumb", {
2470
- found: key
2425
+ if (isWorkspaceTarget(breadcrumb.last)) {
2426
+ this.#workspaceTargets.push({ query: key, value });
2427
+ continue;
2428
+ }
2429
+ throw error("Invalid modifier selector", {
2430
+ found: key,
2431
+ wanted: "a selector ending in #<name>, or :root, :project or :workspace followed by > :workspace"
2471
2432
  });
2472
2433
  }
2473
2434
  let mod;
@@ -2495,11 +2456,49 @@ var GraphModifier = class _GraphModifier {
2495
2456
  };
2496
2457
  this.#nodeModifiers.add(mod);
2497
2458
  }
2498
- this.#modifiers.add(mod);
2499
- if (breadcrumb.first.name) {
2500
- const initialSet = this.#initialEntries.get(breadcrumb.first.name) ?? /* @__PURE__ */ new Set();
2501
- initialSet.add(mod);
2502
- this.#initialEntries.set(breadcrumb.first.name, initialSet);
2459
+ this.#register(mod);
2460
+ }
2461
+ }
2462
+ /**
2463
+ * Adds a modifier entry to the set of known modifiers.
2464
+ */
2465
+ #register(mod) {
2466
+ this.#modifiers.add(mod);
2467
+ const { name } = mod.breadcrumb.first;
2468
+ if (name) {
2469
+ const initialSet = this.#initialEntries.get(name) ?? /* @__PURE__ */ new Set();
2470
+ initialSet.add(mod);
2471
+ this.#initialEntries.set(name, initialSet);
2472
+ }
2473
+ }
2474
+ /**
2475
+ * Expands `<importer> > :workspace` modifiers into one
2476
+ * `<importer> > #<name>` entry per named workspace of the node's graph.
2477
+ */
2478
+ #expandWorkspaceTargets(node) {
2479
+ if (!this.#workspaceTargets.length) return;
2480
+ const { graph } = node;
2481
+ if (this.#expandedGraphs.has(graph)) return;
2482
+ this.#expandedGraphs.add(graph);
2483
+ for (const importer of graph.importers) {
2484
+ const name = importer.manifest?.name;
2485
+ if (importer.mainImporter || !name || this.#expandedNames.has(name)) {
2486
+ continue;
2487
+ }
2488
+ this.#expandedNames.add(name);
2489
+ for (const { query, value } of this.#workspaceTargets) {
2490
+ const breadcrumb = parseBreadcrumb(query);
2491
+ breadcrumb.last.name = name;
2492
+ const mod = {
2493
+ breadcrumb,
2494
+ query,
2495
+ refs: /* @__PURE__ */ new Set(),
2496
+ spec: Spec2.parse(name, value, this.#options),
2497
+ type: "edge",
2498
+ value
2499
+ };
2500
+ this.#edgeModifiers.add(mod);
2501
+ this.#register(mod);
2503
2502
  }
2504
2503
  }
2505
2504
  }
@@ -2509,6 +2508,7 @@ var GraphModifier = class _GraphModifier {
2509
2508
  * update the active entry to the current importer node.
2510
2509
  */
2511
2510
  tryImporter(importer) {
2511
+ this.#expandWorkspaceTargets(importer);
2512
2512
  for (const modifier of this.#modifiers) {
2513
2513
  if (matchesImporter(modifier.breadcrumb.first, importer)) {
2514
2514
  const active = this.newModifier(importer, modifier);
@@ -2679,7 +2679,7 @@ import {
2679
2679
  readFileSync,
2680
2680
  writeFileSync
2681
2681
  } from "node:fs";
2682
- import { basename as basename2, resolve as resolve3 } from "node:path";
2682
+ import { basename, resolve as resolve2 } from "node:path";
2683
2683
 
2684
2684
  // ../../src/init/src/get-author-from-git-user.ts
2685
2685
  var getAuthorFromGitUser = (user) => {
@@ -2706,7 +2706,7 @@ var template = ({ name, author }) => normalizeManifest({
2706
2706
  var GITIGNORE_ENTRY = "node_modules";
2707
2707
  var NPMIGNORE_ENTRY = "vlt.json";
2708
2708
  var ensureGitignore = (cwd) => {
2709
- const gitignorePath = resolve3(cwd, ".gitignore");
2709
+ const gitignorePath = resolve2(cwd, ".gitignore");
2710
2710
  if (!existsSync(gitignorePath)) {
2711
2711
  writeFileSync(gitignorePath, `${GITIGNORE_ENTRY}
2712
2712
  `, "utf8");
@@ -2727,7 +2727,7 @@ var ensureGitignore = (cwd) => {
2727
2727
  return void 0;
2728
2728
  };
2729
2729
  var ensureNpmignore = (cwd) => {
2730
- const npmignorePath = resolve3(cwd, ".npmignore");
2730
+ const npmignorePath = resolve2(cwd, ".npmignore");
2731
2731
  if (!existsSync(npmignorePath)) {
2732
2732
  writeFileSync(npmignorePath, `${NPMIGNORE_ENTRY}
2733
2733
  `, "utf8");
@@ -2753,7 +2753,7 @@ var init = async ({
2753
2753
  logger = stderr
2754
2754
  } = {}) => {
2755
2755
  const packageJson = new PackageJson();
2756
- const path = resolve3(cwd, "package.json");
2756
+ const path = resolve2(cwd, "package.json");
2757
2757
  let existingData;
2758
2758
  try {
2759
2759
  existingData = packageJson.read(cwd);
@@ -2763,7 +2763,7 @@ var init = async ({
2763
2763
  throw err;
2764
2764
  }
2765
2765
  }
2766
- const name = basename2(cwd);
2766
+ const name = basename(cwd);
2767
2767
  const templateData = template({
2768
2768
  name,
2769
2769
  author: author ?? getAuthorFromGitUser(await getUser().catch(() => void 0))
@@ -2802,14 +2802,23 @@ var removeSatisfiedSpecs = ({
2802
2802
  const edgeIsCatalog = edge.spec.type === "catalog";
2803
2803
  const depIsCatalog = dependency.spec.type === "catalog";
2804
2804
  if (edgeIsCatalog !== depIsCatalog) continue;
2805
+ const mod = modifiers?.importerEdgeModifier(
2806
+ importer,
2807
+ dependency.spec
2808
+ );
2805
2809
  if (satisfies(
2806
2810
  edge.to?.id,
2807
- dependency.spec,
2811
+ mod?.type === "edge" ? mod.spec : dependency.spec,
2808
2812
  edge.from.location,
2809
2813
  graph.projectRoot,
2810
2814
  graph.monorepo
2811
2815
  )) {
2812
- if ((edge.spec.bareSpec !== dependency.spec.bareSpec || dependency.type !== "implicit" && edge.type !== dependency.type) && !modifiers?.targetsImporterEdge(importer, dependency.spec)) {
2816
+ const typeChanged = dependency.type !== "implicit" && edge.type !== dependency.type;
2817
+ if (mod) {
2818
+ if (typeChanged) {
2819
+ staleSpecs.set(edge, { ...dependency, spec: edge.spec });
2820
+ }
2821
+ } else if (edge.spec.bareSpec !== dependency.spec.bareSpec || typeChanged) {
2813
2822
  staleSpecs.set(edge, dependency);
2814
2823
  }
2815
2824
  dependencies.delete(name);
@@ -2900,8 +2909,8 @@ var getImporterSpecs = (options) => {
2900
2909
  if (graph.importers.has(node) || !node.id.startsWith("file"))
2901
2910
  continue;
2902
2911
  const nodePath = options.scurry.cwd.resolve(node.location);
2903
- const stat3 = nodePath.lstatSync();
2904
- if (stat3?.isDirectory()) {
2912
+ const stat2 = nodePath.lstatSync();
2913
+ if (stat2?.isDirectory()) {
2905
2914
  const manifest = options.packageJson.read(nodePath.fullpath());
2906
2915
  node.manifest = manifest;
2907
2916
  const addDeps = /* @__PURE__ */ new Map();
@@ -3341,7 +3350,7 @@ var canonicalizePeerIds = (graph, options = {}) => {
3341
3350
 
3342
3351
  // ../../src/graph/src/ideal/move-peer-store-dirs.ts
3343
3352
  import { existsSync as existsSync2 } from "node:fs";
3344
- import { rename as rename2 } from "node:fs/promises";
3353
+ import { rename } from "node:fs/promises";
3345
3354
  var movePeerStoreDirs = async (moves, {
3346
3355
  scurry,
3347
3356
  remover
@@ -3361,7 +3370,7 @@ var movePeerStoreDirs = async (moves, {
3361
3370
  }
3362
3371
  const tmp = scurry.resolve(store, `.VLT.MOVE.${key}.${to}`);
3363
3372
  try {
3364
- await rename2(src, tmp);
3373
+ await rename(src, tmp);
3365
3374
  } catch {
3366
3375
  node.extracted = false;
3367
3376
  return;
@@ -3375,7 +3384,7 @@ var movePeerStoreDirs = async (moves, {
3375
3384
  const { node, tmp, dest } = s;
3376
3385
  try {
3377
3386
  await remover.rm(dest);
3378
- await rename2(tmp, dest);
3387
+ await rename(tmp, dest);
3379
3388
  } catch {
3380
3389
  node.extracted = false;
3381
3390
  try {
@@ -4446,7 +4455,7 @@ var fetchManifestsForDeps = async (packageInfo, graph, fromNode, deps, scurry, o
4446
4455
  placementTasks.sort(compareByHasPeerDeps);
4447
4456
  return { placementTasks, reuseTasks, forkRequests };
4448
4457
  };
4449
- var processPlacementTasks = async (graph, options, placementTasks, add, modifiers, scurry, packageInfo, extractPromises, actual2, seenExtracted, remover, transientAdd, transientRemove) => {
4458
+ var processPlacementTasks = async (graph, options, placementTasks, add, modifiers, scurry, packageInfo, extractPromises, actual2, seenExtracted, remover, transientAdd, transientRemove, explicit) => {
4450
4459
  const childDepsToProcess = [];
4451
4460
  for (const placementTask of placementTasks) {
4452
4461
  const { fetchTask, manifest } = placementTask;
@@ -4461,12 +4470,22 @@ var processPlacementTasks = async (graph, options, placementTasks, add, modifier
4461
4470
  type
4462
4471
  } = fetchTask;
4463
4472
  const additiveMap = fromNode.importer ? add : transientAdd?.get(fromNode.id);
4473
+ const explicitKeys = explicit?.get(fromNode.id);
4474
+ const wasExplicit = explicitKeys?.has(addKey(spec));
4464
4475
  spec = fixupAddedNames(additiveMap, manifest, options, spec);
4476
+ if (wasExplicit) explicitKeys?.add(spec.name);
4465
4477
  if (!manifest) {
4466
4478
  if (!edgeOptional && fromNode.isOptional()) {
4467
- removeOptionalSubgraph(graph, fromNode);
4479
+ for (const n of removeOptionalSubgraph(graph, fromNode)) {
4480
+ for (const { from, name } of n.edgesIn) {
4481
+ if (from.importer && !explicit?.get(from.id)?.has(name)) {
4482
+ add?.delete(name);
4483
+ }
4484
+ }
4485
+ }
4468
4486
  continue;
4469
4487
  } else if (edgeOptional) {
4488
+ additiveMap?.delete(addKey(spec));
4470
4489
  continue;
4471
4490
  } else {
4472
4491
  throw error("failed to resolve dependency", {
@@ -4731,7 +4750,8 @@ var appendNodes = async (packageInfo, graph, fromNode, deps, scurry, options, se
4731
4750
  seenExtracted,
4732
4751
  remover,
4733
4752
  transientAdd,
4734
- transientRemove
4753
+ transientRemove,
4754
+ explicit
4735
4755
  );
4736
4756
  levelResults.push(placed);
4737
4757
  }
@@ -5047,269 +5067,12 @@ var build3 = async (options) => {
5047
5067
  // ../../src/graph/src/reify/index.ts
5048
5068
  import { availableParallelism } from "node:os";
5049
5069
 
5050
- // ../../src/cmd-shim/src/index.ts
5051
- import {
5052
- chmod as chmod3,
5053
- mkdir as mkdir2,
5054
- readFile as readFile2,
5055
- stat as stat2,
5056
- writeFile as writeFile2
5057
- } from "node:fs/promises";
5058
- import { dirname as dirname4, isAbsolute, relative } from "node:path";
5059
-
5060
- // ../../src/cmd-shim/src/to-batch-syntax.ts
5061
- var convertToSetCommand = (key, value) => convertToSetCommand_(key.trim(), value.trim());
5062
- var convertToSetCommand_ = (key, value) => key && value ? `@SET ${key}=${replaceDollarWithPercentPair(value)}\r
5063
- ` : "";
5064
- var extractVariableValuePairs = (declarations) => declarations.reduce(
5065
- (pairs, declaration) => {
5066
- const [key = "", val = ""] = declaration.split("=");
5067
- pairs[key] = val;
5068
- return pairs;
5069
- },
5070
- {}
5071
- );
5072
- var convertToSetCommands = (variableString) => Object.entries(extractVariableValuePairs(variableString.split(" "))).map(([key, val]) => convertToSetCommand(key, val)).join("");
5073
- var replaceDollarWithPercentPair = (value) => {
5074
- const dollarExpressions = /\$\{?([^$@#?\- \t{}:]+)\}?/g;
5075
- let result = "";
5076
- let startIndex = 0;
5077
- do {
5078
- const match = dollarExpressions.exec(value);
5079
- if (match) {
5080
- const betweenMatches = value.substring(startIndex, match.index) || "";
5081
- result += betweenMatches + "%" + String(match[1]) + "%";
5082
- startIndex = dollarExpressions.lastIndex;
5083
- }
5084
- } while (dollarExpressions.lastIndex > 0);
5085
- result += value.slice(startIndex);
5086
- return result;
5087
- };
5088
-
5089
- // ../../src/cmd-shim/src/read.ts
5090
- import { lstat, readFile, readlink } from "node:fs/promises";
5091
- import { dirname as dirname3, resolve as resolve4 } from "node:path";
5092
-
5093
- // ../../src/cmd-shim/src/paths.ts
5094
- var paths = process.platform === "win32" ? (path) => [
5095
- path + ".cmd",
5096
- path + ".ps1",
5097
- path,
5098
- path + ".pwsh"
5099
- ] : (path) => [path];
5100
-
5101
- // ../../src/cmd-shim/src/read.ts
5102
- var extractPath = (path, cmdshimContents) => {
5103
- if (/\.cmd$/i.test(path)) {
5104
- return extractPathFromCmd(cmdshimContents);
5105
- } else if (/\.(ps1|pwsh)$/i.test(path)) {
5106
- return extractPathFromPowershell(cmdshimContents);
5107
- } else {
5108
- return extractPathFromCygwin(cmdshimContents);
5109
- }
5110
- };
5111
- var extractPathFromPowershell = (cmdshimContents) => {
5112
- const matches = /"[$]basedir\/([^"]+?)"\s+[$]args/.exec(
5113
- cmdshimContents
5114
- );
5115
- return matches?.[1]?.replace(/\\/g, "/");
5116
- };
5117
- var extractPathFromCmd = (cmdshimContents) => {
5118
- const matches = /"%(?:~dp0|dp0%)\\([^"]+?)"\s+%[*]/.exec(
5119
- cmdshimContents
5120
- );
5121
- return matches?.[1]?.replace(/\\/g, "/");
5122
- };
5123
- var extractPathFromCygwin = (cmdshimContents) => {
5124
- const matches = /"[$]basedir\/([^"]+?)"\s+"[$]@"/.exec(
5125
- cmdshimContents
5126
- );
5127
- return matches?.[1]?.replace(/\\/g, "/");
5128
- };
5129
- var findCmdShimIfExists = async (path) => {
5130
- path = path.replace(/\.(cmd|pwsh|ps1)$/i, "");
5131
- for (const p of paths(path)) {
5132
- const result = await readCmdShimIfExists(p);
5133
- if (result) return [p, result];
5134
- }
5135
- };
5136
- var readCmdShimIfExists = async (path) => {
5137
- try {
5138
- const st = await lstat(path);
5139
- if (st.isSymbolicLink()) {
5140
- return resolve4(dirname3(path), await readlink(path));
5141
- }
5142
- const contents = await readFile(path);
5143
- const destination = extractPath(path, contents.toString());
5144
- if (destination) return resolve4(dirname3(path), destination);
5145
- } catch {
5146
- }
5147
- };
5148
-
5149
- // ../../src/cmd-shim/src/index.ts
5150
- var shebangExpr = /^#!\s*(?:\/usr\/bin\/env\s+(?:-S\s+)?((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/;
5151
- var cmdShimIfExists = async (from, to, remover) => {
5152
- try {
5153
- await stat2(from);
5154
- } catch {
5155
- return;
5156
- }
5157
- await writeShim(from, to, remover);
5158
- };
5159
- var cmdShim = async (from, to, remover) => {
5160
- try {
5161
- await stat2(from);
5162
- await writeShim(from, to, remover);
5163
- } catch (er) {
5164
- throw error("Could not shim to executable file", {
5165
- path: from,
5166
- target: to,
5167
- cause: er
5168
- });
5169
- }
5170
- };
5171
- var writeShim = async (from, to, remover) => {
5172
- await Promise.all([
5173
- remover.rm(to),
5174
- remover.rm(to + ".cmd"),
5175
- remover.rm(to + ".ps1"),
5176
- remover.rm(to + ".pwsh")
5177
- ]);
5178
- await mkdir2(dirname4(to), { recursive: true });
5179
- const data = await readFile2(from, "utf8").catch(() => "");
5180
- if (!data) {
5181
- return await writeShim_(from, to);
5182
- }
5183
- const firstLine = data.trim().split(/\r*\n/)[0];
5184
- const shebang = firstLine?.match(shebangExpr) ?? void 0;
5185
- return writeShim_(
5186
- from,
5187
- to,
5188
- shebang?.[2],
5189
- shebang?.[3],
5190
- shebang?.[1]
5191
- );
5192
- };
5193
- var writeShim_ = async (from, to, prog, args, variables) => {
5194
- let shTarget = relative(dirname4(to), from);
5195
- const [dp0, basedir] = isAbsolute(shTarget) ? ["", ""] : ["%dp0%\\", "$basedir/"];
5196
- let target = shTarget.split("/").join("\\");
5197
- let longProg;
5198
- let shProg = prog?.split("\\").join("/");
5199
- let shLongProg;
5200
- let pwshProg = shProg && `"${shProg}$exe"`;
5201
- let pwshLongProg;
5202
- shTarget = shTarget.split("\\").join("/");
5203
- args = args || "";
5204
- variables = variables || "";
5205
- if (!prog) {
5206
- prog = `"${dp0}${target}"`;
5207
- shProg = `"${basedir}${shTarget}"`;
5208
- pwshProg = shProg;
5209
- args = "";
5210
- target = "";
5211
- shTarget = "";
5212
- } else {
5213
- longProg = `"%dp0%\\${prog}.exe"`;
5214
- shLongProg = `"$basedir/${prog}"`;
5215
- pwshLongProg = `"$basedir/${prog}$exe"`;
5216
- target = `"${dp0}${target}"`;
5217
- shTarget = `"${basedir}${shTarget}"`;
5218
- }
5219
- const head = "@ECHO off\r\nGOTO start\r\n:find_dp0\r\nSET dp0=%~dp0\r\nEXIT /b\r\n:start\r\nSETLOCAL\r\nCALL :find_dp0\r\n";
5220
- let cmd;
5221
- if (longProg) {
5222
- shLongProg = (shLongProg ?? "").trim();
5223
- args = args.trim();
5224
- const variablesBatch = convertToSetCommands(variables);
5225
- cmd = `${head}${variablesBatch}\r
5226
- IF EXIST ${longProg} (\r
5227
- SET "_prog=${longProg.replace(/(^")|("$)/g, "")}"\r
5228
- ) ELSE (\r
5229
- SET "_prog=${prog.replace(/(^")|("$)/g, "")}"\r
5230
- SET PATHEXT=%PATHEXT:;.JS;=;%\r
5231
- )\r
5232
- \r
5233
- endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" ${args} ${target} %*\r
5234
- `;
5235
- } else {
5236
- cmd = `${head}${prog} ${args} ${target} %*\r
5237
- `;
5238
- }
5239
- let sh = `#!/bin/sh
5240
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
5241
-
5242
- case \`uname\` in
5243
- *CYGWIN*|*MINGW*|*MSYS*)
5244
- if command -v cygpath > /dev/null 2>&1; then
5245
- basedir=\`cygpath -w "$basedir"\`
5246
- fi
5247
- ;;
5248
- esac
5249
-
5250
- `;
5251
- if (shLongProg) {
5252
- sh += `if [ -x ${shLongProg} ]; then
5253
- exec ${variables}${shLongProg} ${args} ${shTarget} "$@"
5254
- else
5255
- exec ${variables}${shProg} ${args} ${shTarget} "$@"
5256
- fi
5257
- `;
5258
- } else {
5259
- sh += `exec ${shProg} ${args} ${shTarget} "$@"
5260
- `;
5261
- }
5262
- let pwsh = '#!/usr/bin/env pwsh\n$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n\n$exe=""\nif ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {\n # Fix case when both the Windows and Linux builds of Node\n # are installed in the same directory\n $exe=".exe"\n}\n';
5263
- if (shLongProg) {
5264
- pwsh += `$ret=0
5265
- if (Test-Path ${pwshLongProg}) {
5266
- # Support pipeline input
5267
- if ($MyInvocation.ExpectingInput) {
5268
- $input | & ${pwshLongProg} ${args} ${shTarget} $args
5269
- } else {
5270
- & ${pwshLongProg} ${args} ${shTarget} $args
5271
- }
5272
- $ret=$LASTEXITCODE
5273
- } else {
5274
- # Support pipeline input
5275
- if ($MyInvocation.ExpectingInput) {
5276
- $input | & ${pwshProg} ${args} ${shTarget} $args
5277
- } else {
5278
- & ${pwshProg} ${args} ${shTarget} $args
5279
- }
5280
- $ret=$LASTEXITCODE
5281
- }
5282
- exit $ret
5283
- `;
5284
- } else {
5285
- pwsh += `# Support pipeline input
5286
- if ($MyInvocation.ExpectingInput) {
5287
- $input | & ${pwshProg} ${args} ${shTarget} $args
5288
- } else {
5289
- & ${pwshProg} ${args} ${shTarget} $args
5290
- }
5291
- exit $LASTEXITCODE
5292
- `;
5293
- }
5294
- await Promise.all([
5295
- writeFile2(to + ".cmd", cmd, "utf8"),
5296
- writeFile2(to + ".ps1", pwsh, "utf8"),
5297
- writeFile2(to, sh, "utf8")
5298
- ]);
5299
- await chmodShim(to);
5300
- };
5301
- var chmodShim = async (to) => await Promise.all([
5302
- chmod3(to, 493),
5303
- chmod3(to + ".cmd", 493),
5304
- chmod3(to + ".ps1", 493)
5305
- ]);
5306
-
5307
5070
  // ../../src/graph/src/reify/add-edge.ts
5308
5071
  import { symlinkSync } from "node:fs";
5309
- import { dirname as dirname5, relative as relative2, resolve as resolve5 } from "node:path";
5072
+ import { dirname as dirname2, relative, resolve as resolve3 } from "node:path";
5310
5073
  var clobberSymlink = async (target, link, remover, type = "file") => {
5311
5074
  const symlinkType = type === "dir" && process.platform === "win32" ? "junction" : type;
5312
- const symlinkTarget = symlinkType === "junction" ? resolve5(dirname5(link), target) : target;
5075
+ const symlinkTarget = symlinkType === "junction" ? resolve3(dirname2(link), target) : target;
5313
5076
  try {
5314
5077
  symlinkSyncMkdirp(symlinkTarget, link, symlinkType);
5315
5078
  } catch (er) {
@@ -5333,8 +5096,8 @@ var addEdge = async (edge, scurry, remover, bins) => {
5333
5096
  const binRoot = nm + sep2 + ".bin";
5334
5097
  const path = nm + sep2 + edge.spec.name.replace("/", sep2);
5335
5098
  const promises = [];
5336
- const target = relative2(
5337
- dirname5(path),
5099
+ const target = relative(
5100
+ dirname2(path),
5338
5101
  edge.to.resolvedLocation(scurry)
5339
5102
  );
5340
5103
  const p = clobberSymlink(target, path, remover, "dir");
@@ -5342,16 +5105,17 @@ var addEdge = async (edge, scurry, remover, bins) => {
5342
5105
  else promises.push(p);
5343
5106
  if (bins) {
5344
5107
  for (const [key, val] of Object.entries(bins)) {
5345
- const link = resolve5(binRoot, key);
5346
- const absTarget = resolve5(path, val);
5347
- const target2 = relative2(binRoot, absTarget);
5348
- promises.push(
5349
- process.platform === "win32" ? cmdShimIfExists(absTarget, link, remover) : clobberSymlink(target2, link, remover)
5350
- );
5108
+ promises.push(linkBin(path, binRoot, key, val, remover));
5351
5109
  }
5352
5110
  }
5353
5111
  if (promises.length) await Promise.all(promises);
5354
5112
  };
5113
+ var linkBin = (path, binRoot, key, val, remover) => {
5114
+ const link = resolve3(binRoot, key);
5115
+ const absTarget = resolve3(path, val);
5116
+ const target = relative(binRoot, absTarget);
5117
+ return process.platform === "win32" ? cmdShimIfExists(absTarget, link, remover) : clobberSymlink(target, link, remover);
5118
+ };
5355
5119
 
5356
5120
  // ../../src/graph/src/reify/add-edges.ts
5357
5121
  var addEdges = (diff, scurry, remover) => {
@@ -5379,18 +5143,14 @@ var addNodes = (diff, scurry, remover, options, packageInfo) => {
5379
5143
  };
5380
5144
 
5381
5145
  // ../../src/graph/src/reify/delete-edge.ts
5382
- import { resolve as resolve6 } from "node:path";
5383
- var rmBinPosix = (remover, bin) => {
5384
- return [remover.rm(bin)];
5385
- };
5386
- var rmBinWin32 = (remover, bin) => {
5387
- return [
5388
- remover.rm(bin),
5389
- remover.rm(bin + ".cmd"),
5390
- remover.rm(bin + ".ps1")
5391
- ];
5392
- };
5393
- var rmBin = process.platform === "win32" ? rmBinWin32 : rmBinPosix;
5146
+ import { resolve as resolve4 } from "node:path";
5147
+ var binPathsPosix = (bin) => [bin];
5148
+ var binPathsWin32 = (bin) => [
5149
+ bin,
5150
+ bin + ".cmd",
5151
+ bin + ".ps1"
5152
+ ];
5153
+ var binPaths = process.platform === "win32" ? binPathsWin32 : binPathsPosix;
5394
5154
  var deleteEdge = async (edge, scurry, remover) => {
5395
5155
  const {
5396
5156
  spec: { name },
@@ -5404,9 +5164,12 @@ var deleteEdge = async (edge, scurry, remover) => {
5404
5164
  promises.push(remover.rm(path));
5405
5165
  const bins = to?.bins;
5406
5166
  if (bins) {
5407
- for (const key of Object.keys(bins)) {
5408
- const bin = resolve6(binRoot, key);
5409
- promises.push(...rmBin(remover, bin));
5167
+ for (const [key, value] of Object.entries(bins)) {
5168
+ for (const bin of binPaths(resolve4(binRoot, key))) {
5169
+ const target = await readCmdShimIfExists(bin);
5170
+ if (target && target !== resolve4(path, value)) continue;
5171
+ promises.push(remover.rm(bin));
5172
+ }
5410
5173
  }
5411
5174
  }
5412
5175
  await Promise.all(promises);
@@ -5424,6 +5187,37 @@ var deleteEdges = (diff, scurry, remover) => {
5424
5187
  return promises;
5425
5188
  };
5426
5189
 
5190
+ // ../../src/graph/src/reify/relink-bins.ts
5191
+ import { resolve as resolve5 } from "node:path";
5192
+ var relinkBins = (diff, scurry, remover) => {
5193
+ const actions = [];
5194
+ const seen = /* @__PURE__ */ new Set();
5195
+ const { sep: sep2 } = scurry.cwd;
5196
+ for (const deleted of diff.edges.delete) {
5197
+ const node = diff.to.nodes.get(deleted.from.id);
5198
+ const bins = deleted.to?.bins;
5199
+ if (!node || !bins) continue;
5200
+ const nm = node.nodeModules(scurry);
5201
+ const binRoot = nm + sep2 + ".bin";
5202
+ for (const key of Object.keys(bins)) {
5203
+ const link = resolve5(binRoot, key);
5204
+ if (seen.has(link)) continue;
5205
+ seen.add(link);
5206
+ for (const edge of node.edgesOut.values()) {
5207
+ const val = edge.to?.bins?.[key];
5208
+ if (!val) continue;
5209
+ const path = nm + sep2 + edge.spec.name.replace("/", sep2);
5210
+ actions.push(async () => {
5211
+ if (await scurry.lstat(link)) return;
5212
+ await linkBin(path, binRoot, key, val, remover);
5213
+ });
5214
+ break;
5215
+ }
5216
+ }
5217
+ }
5218
+ return actions;
5219
+ };
5220
+
5427
5221
  // ../../src/graph/src/reify/check-needed-build.ts
5428
5222
  var nodeNeedsBuild = (node, scurry, packageJson) => {
5429
5223
  if (node.built) return false;
@@ -5467,13 +5261,15 @@ var carryBuildState = (diff) => {
5467
5261
  };
5468
5262
 
5469
5263
  // ../../src/graph/src/reify/delete-nodes.ts
5470
- var deleteNodes = (diff, remover, scurry) => {
5264
+ var deleteNodes = (diff, remover, scurry, keep) => {
5471
5265
  const store = scurry.resolve("node_modules/.vlt");
5472
5266
  const { sep: sep2 } = scurry.cwd;
5473
5267
  const rmActions = [];
5474
5268
  for (const node of diff.nodes.delete) {
5475
5269
  if (!node.inVltStore()) continue;
5476
- rmActions.push(remover.rm(store + sep2 + node.id));
5270
+ if (!keep?.has(node.id)) {
5271
+ rmActions.push(remover.rm(store + sep2 + node.id));
5272
+ }
5477
5273
  for (const edge of node.edgesIn) {
5478
5274
  rmActions.push(deleteEdge(edge, scurry, remover));
5479
5275
  }
@@ -5482,8 +5278,8 @@ var deleteNodes = (diff, remover, scurry) => {
5482
5278
  };
5483
5279
 
5484
5280
  // ../../src/graph/src/reify/internal-hoist.ts
5485
- import { mkdir as mkdir3 } from "node:fs/promises";
5486
- import { dirname as dirname6, relative as relative3 } from "node:path";
5281
+ import { mkdir as mkdir2 } from "node:fs/promises";
5282
+ import { dirname as dirname3, relative as relative2 } from "node:path";
5487
5283
  var pickNodeToHoist = (nodes) => {
5488
5284
  let pick = void 0;
5489
5285
  let pickNode = void 0;
@@ -5564,7 +5360,7 @@ var internalHoist = async (graph, options, remover) => {
5564
5360
  const hoistDir = scurry.cwd.resolve(
5565
5361
  "node_modules/.vlt/node_modules"
5566
5362
  );
5567
- await mkdir3(hoistDir.fullpath(), { recursive: true });
5363
+ await mkdir2(hoistDir.fullpath(), { recursive: true });
5568
5364
  const removes = [];
5569
5365
  for (const entry of await hoistDir.readdir()) {
5570
5366
  const name = entry.name;
@@ -5598,7 +5394,7 @@ var internalHoist = async (graph, options, remover) => {
5598
5394
  for (const [name, { name: nodeName, id }] of links) {
5599
5395
  const target = vlt + sep2 + id + sep2 + "node_modules" + sep2 + native(nodeName);
5600
5396
  const path = hoistPath + sep2 + native(name);
5601
- symlinkSyncMkdirp(relative3(dirname6(path), target), path, "dir");
5397
+ symlinkSyncMkdirp(relative2(dirname3(path), target), path, "dir");
5602
5398
  }
5603
5399
  };
5604
5400
  var checkExisting = async (name, entry, links, removes, scurry, remover) => {
@@ -5635,7 +5431,7 @@ var rollback = async (remover, diff, scurry) => {
5635
5431
  };
5636
5432
 
5637
5433
  // ../../src/graph/src/reify/update-importers-package-json.ts
5638
- var addOrRemoveDeps = (nodeId, graph, addOrRemove, saveExact, savePrefix) => {
5434
+ var addOrRemoveDeps = (nodeId, graph, addOrRemove, saveExact, savePrefix, modifiers) => {
5639
5435
  const node = graph.nodes.get(nodeId);
5640
5436
  if (!node) {
5641
5437
  throw error("Failed to retrieve node", {
@@ -5680,7 +5476,10 @@ var addOrRemoveDeps = (nodeId, graph, addOrRemove, saveExact, savePrefix) => {
5680
5476
  }
5681
5477
  const edge = node.edgesOut.get(name);
5682
5478
  if (!edge?.to) {
5683
- throw error("Dependency node could not be found");
5479
+ throw error(`Dependency node could not be found: ${name}`, {
5480
+ spec: dep.spec,
5481
+ from: node.location
5482
+ });
5684
5483
  }
5685
5484
  const n = edge.to;
5686
5485
  const [nodeType] = splitDepID(n.id);
@@ -5706,7 +5505,7 @@ var addOrRemoveDeps = (nodeId, graph, addOrRemove, saveExact, savePrefix) => {
5706
5505
  );
5707
5506
  dependencies[name] = saveValue;
5708
5507
  manifestChanged = manifestChanged || saveValue !== existing;
5709
- if (saveValue !== edge.spec.bareSpec) {
5508
+ if (saveValue !== edge.spec.bareSpec && !modifiers?.targetsImporterEdge(node, dep.spec)) {
5710
5509
  edge.spec = Spec2.parse(name, saveValue, dep.spec.options);
5711
5510
  graph.lockfileStale = true;
5712
5511
  }
@@ -5720,7 +5519,8 @@ var updatePackageJson = ({
5720
5519
  packageJson,
5721
5520
  remove,
5722
5521
  saveExact,
5723
- savePrefix
5522
+ savePrefix,
5523
+ modifiers
5724
5524
  }) => {
5725
5525
  const manifestsToUpdate = /* @__PURE__ */ new Set();
5726
5526
  const operations = /* @__PURE__ */ new Set([add, remove]);
@@ -5732,7 +5532,8 @@ var updatePackageJson = ({
5732
5532
  graph,
5733
5533
  operation,
5734
5534
  saveExact,
5735
- savePrefix
5535
+ savePrefix,
5536
+ modifiers
5736
5537
  );
5737
5538
  if (manifest) {
5738
5539
  manifestsToUpdate.add(manifest);
@@ -5768,7 +5569,8 @@ var reify = async (options) => {
5768
5569
  graph,
5769
5570
  packageJson: options.packageJson,
5770
5571
  saveExact: options.saveExact,
5771
- savePrefix: options.savePrefix
5572
+ savePrefix: options.savePrefix,
5573
+ modifiers: options.modifiers
5772
5574
  }) : void 0
5773
5575
  );
5774
5576
  const noModifiedDependencies = !options.add?.modifiedDependencies && !options.remove?.modifiedDependencies;
@@ -5825,6 +5627,8 @@ var reify_ = async (options, diff, remover, saveImportersPackageJson) => {
5825
5627
  if (actions.length) await callLimit(actions, { limit });
5826
5628
  const edgeActions = addEdges(diff, scurry, remover);
5827
5629
  if (edgeActions.length) await callLimit(edgeActions, { limit });
5630
+ const binActions = relinkBins(diff, scurry, remover);
5631
+ if (binActions.length) await callLimit(binActions, { limit });
5828
5632
  await internalHoist(diff.to, options, remover);
5829
5633
  checkNeededBuild({ diff, scurry, packageJson });
5830
5634
  const allowScriptsNodes = await filterNodesByQuery(
@@ -5844,7 +5648,8 @@ var reify_ = async (options, diff, remover, saveImportersPackageJson) => {
5844
5648
  const rmActions = deleteNodes(
5845
5649
  diff,
5846
5650
  remover,
5847
- scurry
5651
+ scurry,
5652
+ options.keepNodes
5848
5653
  );
5849
5654
  if (rmActions.length) await Promise.all(rmActions);
5850
5655
  saveImportersPackageJson?.();
@@ -5866,7 +5671,7 @@ var reify_ = async (options, diff, remover, saveImportersPackageJson) => {
5866
5671
 
5867
5672
  // ../../src/graph/src/install.ts
5868
5673
  import { existsSync as existsSync5, rmSync as rmSync3 } from "node:fs";
5869
- import { resolve as resolve9 } from "node:path";
5674
+ import { resolve as resolve8 } from "node:path";
5870
5675
 
5871
5676
  // ../../src/graph/src/lockfile/format-options-change.ts
5872
5677
  var redactUserinfo = (value) => {
@@ -5886,7 +5691,7 @@ var formatOptionsChange = ({
5886
5691
 
5887
5692
  // ../../src/graph/src/uninstall.ts
5888
5693
  import { existsSync as existsSync3, rmSync } from "node:fs";
5889
- import { resolve as resolve7 } from "node:path";
5694
+ import { resolve as resolve6 } from "node:path";
5890
5695
  var uninstall = async (options, remove) => {
5891
5696
  const allowSkills = options.allowSkills === ":not(*)" ? void 0 : options.allowSkills;
5892
5697
  if (allowSkills) {
@@ -5926,7 +5731,8 @@ var uninstall = async (options, remove) => {
5926
5731
  remove?.modifiedDependencies ? updatePackageJson({
5927
5732
  ...options,
5928
5733
  remove,
5929
- graph
5734
+ graph,
5735
+ modifiers
5930
5736
  }) : void 0
5931
5737
  );
5932
5738
  saveImportersPackageJson?.();
@@ -5947,7 +5753,7 @@ var uninstall = async (options, remove) => {
5947
5753
  await remover.rollback().catch(() => {
5948
5754
  });
5949
5755
  try {
5950
- const hiddenLockfile = resolve7(
5756
+ const hiddenLockfile = resolve6(
5951
5757
  options.projectRoot,
5952
5758
  "node_modules/.vlt-lock.json"
5953
5759
  );
@@ -5959,7 +5765,7 @@ var uninstall = async (options, remove) => {
5959
5765
  throw err;
5960
5766
  }
5961
5767
  if (!allowSkills) return result;
5962
- const { linkSkills: linkSkills2 } = await import("./skills-YD2TB2VD.js");
5768
+ const { linkSkills: linkSkills2 } = await import("./skills-KA2VR5Q5.js");
5963
5769
  result.skills = await linkSkills2({
5964
5770
  ...options,
5965
5771
  graph: result.graph,
@@ -5970,7 +5776,7 @@ var uninstall = async (options, remove) => {
5970
5776
 
5971
5777
  // ../../src/graph/src/update.ts
5972
5778
  import { existsSync as existsSync4, rmSync as rmSync2 } from "node:fs";
5973
- import { resolve as resolve8 } from "node:path";
5779
+ import { resolve as resolve7 } from "node:path";
5974
5780
  var startingGraph = (options, monorepo) => {
5975
5781
  const fresh = () => new Graph({ ...options, monorepo });
5976
5782
  if (!options.monorepo || !monorepo) return fresh();
@@ -6057,7 +5863,7 @@ var update = async (options) => {
6057
5863
  await remover.rollback().catch(() => {
6058
5864
  });
6059
5865
  try {
6060
- const hiddenLockfile = resolve8(
5866
+ const hiddenLockfile = resolve7(
6061
5867
  options.projectRoot,
6062
5868
  "node_modules/.vlt-lock.json"
6063
5869
  );
@@ -6069,7 +5875,7 @@ var update = async (options) => {
6069
5875
  throw err;
6070
5876
  }
6071
5877
  if (!allowSkills) return result;
6072
- const { linkSkills: linkSkills2 } = await import("./skills-YD2TB2VD.js");
5878
+ const { linkSkills: linkSkills2 } = await import("./skills-KA2VR5Q5.js");
6073
5879
  result.skills = await linkSkills2({
6074
5880
  ...options,
6075
5881
  graph: result.graph,
@@ -6169,7 +5975,7 @@ var install = async (options, add) => {
6169
5975
  assertSkillsDirs(options.projectRoot, options.skillsDirs);
6170
5976
  }
6171
5977
  if (options.expectLockfile || options.frozenLockfile) {
6172
- const lockfilePath = resolve9(options.projectRoot, "vlt-lock.json");
5978
+ const lockfilePath = resolve8(options.projectRoot, "vlt-lock.json");
6173
5979
  if (!existsSync5(lockfilePath)) {
6174
5980
  throw error(
6175
5981
  "vlt-lock.json file is required when using --expect-lockfile, --frozen-lockfile, or ci command",
@@ -6293,7 +6099,7 @@ var install = async (options, add) => {
6293
6099
  ` ${edge.from.location}: ${edge.name} is removed by a graph modifier`
6294
6100
  );
6295
6101
  }
6296
- const lockfilePath = resolve9(
6102
+ const lockfilePath = resolve8(
6297
6103
  options.projectRoot,
6298
6104
  "vlt-lock.json"
6299
6105
  );
@@ -6328,7 +6134,7 @@ var install = async (options, add) => {
6328
6134
  }
6329
6135
  const remover = new RollbackRemove();
6330
6136
  if (options.cleanInstall) {
6331
- const nodeModulesPath = resolve9(
6137
+ const nodeModulesPath = resolve8(
6332
6138
  options.projectRoot,
6333
6139
  "node_modules"
6334
6140
  );
@@ -6374,6 +6180,7 @@ var install = async (options, add) => {
6374
6180
  ...options,
6375
6181
  add,
6376
6182
  graph,
6183
+ modifiers,
6377
6184
  remove
6378
6185
  }) : void 0
6379
6186
  );
@@ -6397,7 +6204,7 @@ var install = async (options, add) => {
6397
6204
  await remover.rollback().catch(() => {
6398
6205
  });
6399
6206
  try {
6400
- const hiddenLockfile = resolve9(
6207
+ const hiddenLockfile = resolve8(
6401
6208
  options.projectRoot,
6402
6209
  "node_modules/.vlt-lock.json"
6403
6210
  );
@@ -6409,7 +6216,7 @@ var install = async (options, add) => {
6409
6216
  throw err;
6410
6217
  }
6411
6218
  if (!allowSkills) return result;
6412
- const { linkSkills: linkSkills2 } = await import("./skills-YD2TB2VD.js");
6219
+ const { linkSkills: linkSkills2 } = await import("./skills-KA2VR5Q5.js");
6413
6220
  result.skills = await linkSkills2({
6414
6221
  ...options,
6415
6222
  graph: result.graph,
@@ -6430,9 +6237,6 @@ export {
6430
6237
  jsonOutput,
6431
6238
  humanReadableOutput,
6432
6239
  mermaidOutput,
6433
- findCmdShimIfExists,
6434
- cmdShim,
6435
- RollbackRemove,
6436
6240
  GraphModifier,
6437
6241
  init,
6438
6242
  install,