@nasti-toolchain/nasti 2.4.3 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,10 +10,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
10
10
  if (typeof require !== "undefined") return require.apply(this, arguments);
11
11
  throw Error('Dynamic require of "' + x + '" is not supported');
12
12
  });
13
- var __glob = (map) => (path19) => {
14
- var fn = map[path19];
13
+ var __glob = (map) => (path20) => {
14
+ var fn = map[path20];
15
15
  if (fn) return fn();
16
- throw new Error("Module not found in bundle: " + path19);
16
+ throw new Error("Module not found in bundle: " + path20);
17
17
  };
18
18
  var __esm = (fn, res) => function __init() {
19
19
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -876,27 +876,27 @@ var require_process = __commonJS({
876
876
  var require_filesystem = __commonJS({
877
877
  "node_modules/detect-libc/lib/filesystem.js"(exports, module) {
878
878
  "use strict";
879
- var fs14 = __require("fs");
879
+ var fs15 = __require("fs");
880
880
  var LDD_PATH = "/usr/bin/ldd";
881
881
  var SELF_PATH = "/proc/self/exe";
882
882
  var MAX_LENGTH = 2048;
883
- var readFileSync = (path19) => {
884
- const fd = fs14.openSync(path19, "r");
883
+ var readFileSync = (path20) => {
884
+ const fd = fs15.openSync(path20, "r");
885
885
  const buffer = Buffer.alloc(MAX_LENGTH);
886
- const bytesRead = fs14.readSync(fd, buffer, 0, MAX_LENGTH, 0);
887
- fs14.close(fd, () => {
886
+ const bytesRead = fs15.readSync(fd, buffer, 0, MAX_LENGTH, 0);
887
+ fs15.close(fd, () => {
888
888
  });
889
889
  return buffer.subarray(0, bytesRead);
890
890
  };
891
- var readFile = (path19) => new Promise((resolve, reject) => {
892
- fs14.open(path19, "r", (err, fd) => {
891
+ var readFile = (path20) => new Promise((resolve, reject) => {
892
+ fs15.open(path20, "r", (err, fd) => {
893
893
  if (err) {
894
894
  reject(err);
895
895
  } else {
896
896
  const buffer = Buffer.alloc(MAX_LENGTH);
897
- fs14.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
897
+ fs15.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
898
898
  resolve(buffer.subarray(0, bytesRead));
899
- fs14.close(fd, () => {
899
+ fs15.close(fd, () => {
900
900
  });
901
901
  });
902
902
  }
@@ -1008,11 +1008,11 @@ var require_detect_libc = __commonJS({
1008
1008
  }
1009
1009
  return null;
1010
1010
  };
1011
- var familyFromInterpreterPath = (path19) => {
1012
- if (path19) {
1013
- if (path19.includes("/ld-musl-")) {
1011
+ var familyFromInterpreterPath = (path20) => {
1012
+ if (path20) {
1013
+ if (path20.includes("/ld-musl-")) {
1014
1014
  return MUSL;
1015
- } else if (path19.includes("/ld-linux-")) {
1015
+ } else if (path20.includes("/ld-linux-")) {
1016
1016
  return GLIBC;
1017
1017
  }
1018
1018
  }
@@ -1059,8 +1059,8 @@ var require_detect_libc = __commonJS({
1059
1059
  cachedFamilyInterpreter = null;
1060
1060
  try {
1061
1061
  const selfContent = await readFile(SELF_PATH);
1062
- const path19 = interpreterPath(selfContent);
1063
- cachedFamilyInterpreter = familyFromInterpreterPath(path19);
1062
+ const path20 = interpreterPath(selfContent);
1063
+ cachedFamilyInterpreter = familyFromInterpreterPath(path20);
1064
1064
  } catch (e) {
1065
1065
  }
1066
1066
  return cachedFamilyInterpreter;
@@ -1072,8 +1072,8 @@ var require_detect_libc = __commonJS({
1072
1072
  cachedFamilyInterpreter = null;
1073
1073
  try {
1074
1074
  const selfContent = readFileSync(SELF_PATH);
1075
- const path19 = interpreterPath(selfContent);
1076
- cachedFamilyInterpreter = familyFromInterpreterPath(path19);
1075
+ const path20 = interpreterPath(selfContent);
1076
+ cachedFamilyInterpreter = familyFromInterpreterPath(path20);
1077
1077
  } catch (e) {
1078
1078
  }
1079
1079
  return cachedFamilyInterpreter;
@@ -2226,8 +2226,8 @@ function vuePlugin(config, environmentName = "client") {
2226
2226
  let cached2 = descriptorCache.get(filePath);
2227
2227
  if (!cached2) {
2228
2228
  try {
2229
- const fs14 = await import("fs");
2230
- const rawSource = fs14.readFileSync(filePath, "utf-8");
2229
+ const fs15 = await import("fs");
2230
+ const rawSource = fs15.readFileSync(filePath, "utf-8");
2231
2231
  const transformedSfc = await applySourceTransform(
2232
2232
  vueOptions.transformSfc,
2233
2233
  rawSource,
@@ -2893,6 +2893,24 @@ var init_module_graph = __esm({
2893
2893
  getModulesByFile(file) {
2894
2894
  return this.fileToModulesMap.get(file);
2895
2895
  }
2896
+ /**
2897
+ * Modules whose registered entry file lives under `dir` (inclusive).
2898
+ * Used when a non-entry source inside a prebundled workspace package changes:
2899
+ * only the package entry was registered, so getModulesByFile(changedFile)
2900
+ * misses — we invalidate every /@modules entry rooted in that package.
2901
+ */
2902
+ getModulesWithFileUnder(dir) {
2903
+ const result = /* @__PURE__ */ new Set();
2904
+ const normDir = dir.replace(/\\/g, "/");
2905
+ const normPrefix = normDir.endsWith("/") ? normDir : normDir + "/";
2906
+ for (const [file, mods] of this.fileToModulesMap) {
2907
+ const normFile = file.replace(/\\/g, "/");
2908
+ if (normFile === normDir || normFile.startsWith(normPrefix)) {
2909
+ for (const m of mods) result.add(m);
2910
+ }
2911
+ }
2912
+ return result;
2913
+ }
2896
2914
  async ensureEntryFromUrl(url) {
2897
2915
  const normalizedUrl = removeTimestampQuery(url);
2898
2916
  let mod = this.urlToModuleMap.get(normalizedUrl);
@@ -3866,7 +3884,7 @@ async function build(inlineConfig = {}) {
3866
3884
  const startTime = performance.now();
3867
3885
  logger.info(
3868
3886
  pc4.cyan(`
3869
- nasti v${"2.4.3"} `) + pc4.green(`building for ${config.mode}...`)
3887
+ nasti v${"2.4.4"} `) + pc4.green(`building for ${config.mode}...`)
3870
3888
  );
3871
3889
  debug5?.(`root: ${config.root}`);
3872
3890
  const buildableNames = Object.keys(config.environments).filter((name) => {
@@ -4203,10 +4221,124 @@ var init_ws = __esm({
4203
4221
  }
4204
4222
  });
4205
4223
 
4206
- // src/server/middleware.ts
4207
- import path12 from "path";
4224
+ // src/server/fs-allow.ts
4208
4225
  import fs9 from "fs";
4209
- import { createRequire as createRequire3 } from "module";
4226
+ import path12 from "path";
4227
+ function isUnderRoot(abs, root) {
4228
+ const rel = path12.relative(root, abs);
4229
+ return !!rel && !rel.startsWith("..") && !path12.isAbsolute(rel);
4230
+ }
4231
+ function discoverLinkedPackageRoots(projectRoot, maxDepth = 4) {
4232
+ const results = [];
4233
+ const seenReal = /* @__PURE__ */ new Set();
4234
+ const queued = /* @__PURE__ */ new Set([projectRoot]);
4235
+ const queue = [projectRoot];
4236
+ for (let depth = 0; depth < maxDepth && queue.length > 0; depth++) {
4237
+ const levelCount = queue.length;
4238
+ for (let i = 0; i < levelCount; i++) {
4239
+ const dir = queue.shift();
4240
+ const nm = path12.join(dir, "node_modules");
4241
+ let entries;
4242
+ try {
4243
+ entries = fs9.readdirSync(nm, { withFileTypes: true });
4244
+ } catch {
4245
+ continue;
4246
+ }
4247
+ for (const ent of entries) {
4248
+ if (ent.name.startsWith(".") || ent.name === "node_modules") continue;
4249
+ const pkgNames = ent.name.startsWith("@") ? listScopedPackages(nm, ent.name) : [ent.name];
4250
+ for (const pkgName of pkgNames) {
4251
+ const pkgPath = path12.join(nm, pkgName);
4252
+ let real;
4253
+ try {
4254
+ real = fs9.realpathSync(pkgPath);
4255
+ } catch {
4256
+ continue;
4257
+ }
4258
+ if (seenReal.has(real)) continue;
4259
+ seenReal.add(real);
4260
+ if (!queued.has(real)) {
4261
+ queued.add(real);
4262
+ queue.push(real);
4263
+ }
4264
+ if (real !== projectRoot && !isUnderRoot(real, projectRoot) && !real.includes(NM)) {
4265
+ results.push(real);
4266
+ }
4267
+ }
4268
+ }
4269
+ }
4270
+ }
4271
+ return results;
4272
+ }
4273
+ function listScopedPackages(nm, scope) {
4274
+ try {
4275
+ return fs9.readdirSync(path12.join(nm, scope)).filter((name) => !name.startsWith(".")).map((name) => path12.join(scope, name));
4276
+ } catch {
4277
+ return [];
4278
+ }
4279
+ }
4280
+ function getLinkedPackageRoots(projectRoot) {
4281
+ let mtimeMs = 0;
4282
+ try {
4283
+ mtimeMs = fs9.statSync(path12.join(projectRoot, "node_modules")).mtimeMs;
4284
+ } catch {
4285
+ mtimeMs = 0;
4286
+ }
4287
+ const cached2 = linkedRootsCache.get(projectRoot);
4288
+ if (cached2 && cached2.mtimeMs === mtimeMs) {
4289
+ return cached2.roots;
4290
+ }
4291
+ const roots = discoverLinkedPackageRoots(projectRoot);
4292
+ linkedRootsCache.set(projectRoot, { roots, mtimeMs });
4293
+ return roots;
4294
+ }
4295
+ function clearLinkedPackageRootsCache() {
4296
+ linkedRootsCache.clear();
4297
+ }
4298
+ function isAllowedDevModulePath(realId, projectRoot) {
4299
+ if (realId === projectRoot || isUnderRoot(realId, projectRoot)) return true;
4300
+ for (const pkgRoot of getLinkedPackageRoots(projectRoot)) {
4301
+ if (realId === pkgRoot || realId.startsWith(pkgRoot + path12.sep)) return true;
4302
+ }
4303
+ let dir = projectRoot;
4304
+ for (; ; ) {
4305
+ const nm = path12.join(dir, "node_modules");
4306
+ if (realId === nm || realId.startsWith(nm + path12.sep)) return true;
4307
+ const parent = path12.dirname(dir);
4308
+ if (parent === dir) break;
4309
+ dir = parent;
4310
+ }
4311
+ return false;
4312
+ }
4313
+ function findNearestPackageRoot(file) {
4314
+ let dir = path12.dirname(file);
4315
+ for (; ; ) {
4316
+ const pkgJson = path12.join(dir, "package.json");
4317
+ if (fs9.existsSync(pkgJson)) {
4318
+ try {
4319
+ const pkg = JSON.parse(fs9.readFileSync(pkgJson, "utf-8"));
4320
+ if (typeof pkg?.name === "string" && pkg.name) return dir;
4321
+ } catch {
4322
+ }
4323
+ }
4324
+ const parent = path12.dirname(dir);
4325
+ if (parent === dir) return null;
4326
+ dir = parent;
4327
+ }
4328
+ }
4329
+ var NM, linkedRootsCache;
4330
+ var init_fs_allow = __esm({
4331
+ "src/server/fs-allow.ts"() {
4332
+ "use strict";
4333
+ NM = `${path12.sep}node_modules${path12.sep}`;
4334
+ linkedRootsCache = /* @__PURE__ */ new Map();
4335
+ }
4336
+ });
4337
+
4338
+ // src/server/middleware.ts
4339
+ import path13 from "path";
4340
+ import fs10 from "fs";
4341
+ import { createRequire as createRequire4 } from "module";
4210
4342
  import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "url";
4211
4343
  import pc6 from "picocolors";
4212
4344
  function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
@@ -4216,10 +4348,10 @@ function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
4216
4348
  let cjsPath;
4217
4349
  try {
4218
4350
  const pkgPath = __require2.resolve("react-refresh/package.json");
4219
- cjsPath = path12.join(path12.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
4351
+ cjsPath = path13.join(path13.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
4220
4352
  } catch (err) {
4221
- cjsPath = path12.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
4222
- if (!fs9.existsSync(cjsPath)) {
4353
+ cjsPath = path13.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
4354
+ if (!fs10.existsSync(cjsPath)) {
4223
4355
  const origMsg = err instanceof Error ? err.message : String(err);
4224
4356
  throw new Error(
4225
4357
  `[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
@@ -4227,7 +4359,7 @@ Original resolve error: ${origMsg}`
4227
4359
  );
4228
4360
  }
4229
4361
  }
4230
- const cjsSource = fs9.readFileSync(cjsPath, "utf-8");
4362
+ const cjsSource = fs10.readFileSync(cjsPath, "utf-8");
4231
4363
  __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
4232
4364
  const exports = {};
4233
4365
  const module = { exports };
@@ -4398,8 +4530,8 @@ async function transformRequest(url, ctx) {
4398
4530
  let realIdValid = false;
4399
4531
  try {
4400
4532
  if (idParam) {
4401
- realId = fs9.realpathSync(idParam);
4402
- realIdValid = fs9.statSync(realId).isFile() && (realId.includes(`${path12.sep}node_modules${path12.sep}`) || isUnderRoot(realId, config.root));
4533
+ realId = fs10.realpathSync(idParam);
4534
+ realIdValid = fs10.statSync(realId).isFile() && isAllowedDevModulePath(realId, config.root);
4403
4535
  }
4404
4536
  } catch {
4405
4537
  realId = null;
@@ -4466,7 +4598,7 @@ async function transformRequest(url, ctx) {
4466
4598
  }
4467
4599
  }
4468
4600
  const filePath = resolveUrlToFile(url, config.root);
4469
- if (!filePath || !fs9.existsSync(filePath)) return null;
4601
+ if (!filePath || !fs10.existsSync(filePath)) return null;
4470
4602
  const mod = await moduleGraph.ensureEntryFromUrl(url);
4471
4603
  moduleGraph.registerModule(mod, filePath);
4472
4604
  const transformVersion = mod.invalidationVersion;
@@ -4477,7 +4609,7 @@ async function transformRequest(url, ctx) {
4477
4609
  return transformResult2;
4478
4610
  }
4479
4611
  const loaded = await pluginContainer.load(filePath);
4480
- let code = loaded == null ? fs9.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
4612
+ let code = loaded == null ? fs10.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
4481
4613
  let map = loaded && typeof loaded !== "string" ? loaded.map : void 0;
4482
4614
  const pluginResult = await pluginContainer.transform(code, filePath);
4483
4615
  if (pluginResult) {
@@ -4535,7 +4667,7 @@ async function loadVirtualModule(spec, ctx) {
4535
4667
  const resolved = await pluginContainer.resolveId(spec);
4536
4668
  if (resolved == null) return null;
4537
4669
  const resolvedId = typeof resolved === "string" ? resolved : resolved.id;
4538
- const looksVirtual = resolvedId.startsWith("\0") || !fs9.existsSync(resolvedId);
4670
+ const looksVirtual = resolvedId.startsWith("\0") || !fs10.existsSync(resolvedId);
4539
4671
  if (!looksVirtual) return null;
4540
4672
  const loadResult = await pluginContainer.load(resolvedId);
4541
4673
  if (loadResult == null) return null;
@@ -4549,7 +4681,7 @@ async function loadVirtualModule(spec, ctx) {
4549
4681
  config.mode,
4550
4682
  ssrDefineOverrides(ctx.environment?.consumer ?? "client")
4551
4683
  ));
4552
- const anchor = path12.join(config.root, "__nasti_virtual__.ts");
4684
+ const anchor = path13.join(config.root, "__nasti_virtual__.ts");
4553
4685
  code = rewriteImports(code, config, anchor);
4554
4686
  return { id: resolvedId, result: { code } };
4555
4687
  }
@@ -4575,7 +4707,7 @@ async function doBundlePackage(entryFile, root) {
4575
4707
  await bundle2.close();
4576
4708
  let code = result.output[0].code;
4577
4709
  code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
4578
- const externalBaseDir = path12.dirname(entryFile);
4710
+ const externalBaseDir = path13.dirname(entryFile);
4579
4711
  code = code.replace(
4580
4712
  /^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
4581
4713
  (_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`
@@ -4593,16 +4725,16 @@ async function doBundlePackage(entryFile, root) {
4593
4725
  return code;
4594
4726
  }
4595
4727
  async function tryGenerateSubpathShim(entryFile, root) {
4596
- const NM = `${path12.sep}node_modules${path12.sep}`;
4597
- if (!entryFile.includes(NM)) return null;
4728
+ const NM2 = `${path13.sep}node_modules${path13.sep}`;
4729
+ if (!entryFile.includes(NM2)) return null;
4598
4730
  let pkgDir = null;
4599
4731
  let pkgName = null;
4600
- let dir = path12.dirname(entryFile);
4732
+ let dir = path13.dirname(entryFile);
4601
4733
  while (true) {
4602
- const pkgJsonPath = path12.join(dir, "package.json");
4603
- if (fs9.existsSync(pkgJsonPath)) {
4734
+ const pkgJsonPath = path13.join(dir, "package.json");
4735
+ if (fs10.existsSync(pkgJsonPath)) {
4604
4736
  try {
4605
- const pkg = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
4737
+ const pkg = JSON.parse(fs10.readFileSync(pkgJsonPath, "utf-8"));
4606
4738
  if (typeof pkg?.name === "string" && pkg.name) {
4607
4739
  pkgDir = dir;
4608
4740
  pkgName = pkg.name;
@@ -4611,16 +4743,16 @@ async function tryGenerateSubpathShim(entryFile, root) {
4611
4743
  } catch {
4612
4744
  }
4613
4745
  }
4614
- const parent = path12.dirname(dir);
4746
+ const parent = path13.dirname(dir);
4615
4747
  if (parent === dir) return null;
4616
4748
  dir = parent;
4617
- if (!dir.includes(NM)) return null;
4749
+ if (!dir.includes(NM2)) return null;
4618
4750
  }
4619
4751
  if (!pkgDir || !pkgName) return null;
4620
- const entryExt = path12.extname(entryFile);
4752
+ const entryExt = path13.extname(entryFile);
4621
4753
  const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
4622
4754
  if (!mainEntry) return null;
4623
- if (path12.resolve(mainEntry) === path12.resolve(entryFile)) return null;
4755
+ if (path13.resolve(mainEntry) === path13.resolve(entryFile)) return null;
4624
4756
  let mainNs;
4625
4757
  let subNs;
4626
4758
  try {
@@ -4644,7 +4776,7 @@ async function tryGenerateSubpathShim(entryFile, root) {
4644
4776
  if (mainNs["default"] !== subNs["default"]) return null;
4645
4777
  }
4646
4778
  const rootMain = resolveNodeModule(root, pkgName);
4647
- const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + path12.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
4779
+ const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + path13.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
4648
4780
  const lines = [
4649
4781
  `// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
4650
4782
  `import * as __pkg from "${mainEntryUrl}";`
@@ -4658,10 +4790,10 @@ async function tryGenerateSubpathShim(entryFile, root) {
4658
4790
  return lines.join("\n") + "\n";
4659
4791
  }
4660
4792
  function pickMainEntryByExtension(pkgDir, preferredExt) {
4661
- const pkgJsonPath = path12.join(pkgDir, "package.json");
4793
+ const pkgJsonPath = path13.join(pkgDir, "package.json");
4662
4794
  let pkg;
4663
4795
  try {
4664
- pkg = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
4796
+ pkg = JSON.parse(fs10.readFileSync(pkgJsonPath, "utf-8"));
4665
4797
  } catch {
4666
4798
  return null;
4667
4799
  }
@@ -4680,14 +4812,14 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
4680
4812
  if (typeof pkg.module === "string") candidates.push(pkg.module);
4681
4813
  if (typeof pkg.main === "string") candidates.push(pkg.main);
4682
4814
  for (const cand of candidates) {
4683
- if (path12.extname(cand) === preferredExt) {
4684
- const full = path12.resolve(pkgDir, cand);
4685
- if (fs9.existsSync(full)) return full;
4815
+ if (path13.extname(cand) === preferredExt) {
4816
+ const full = path13.resolve(pkgDir, cand);
4817
+ if (fs10.existsSync(full)) return full;
4686
4818
  }
4687
4819
  }
4688
4820
  for (const cand of candidates) {
4689
- const full = path12.resolve(pkgDir, cand);
4690
- if (fs9.existsSync(full)) return full;
4821
+ const full = path13.resolve(pkgDir, cand);
4822
+ if (fs10.existsSync(full)) return full;
4691
4823
  }
4692
4824
  return null;
4693
4825
  }
@@ -4712,8 +4844,8 @@ function rewriteExternalRequires(code, baseDir, root) {
4712
4844
  }
4713
4845
  async function injectCjsNamedExports(code, entryFile) {
4714
4846
  try {
4715
- const { createRequire: createRequire7 } = await import("module");
4716
- const req = createRequire7(entryFile);
4847
+ const { createRequire: createRequire8 } = await import("module");
4848
+ const req = createRequire8(entryFile);
4717
4849
  const cjsExports = req(entryFile);
4718
4850
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
4719
4851
  const namedKeys = Object.keys(cjsExports).filter(
@@ -4754,11 +4886,22 @@ function rewriteImports(code, config, filePath, importedUrls, moduleGraph) {
4754
4886
  }
4755
4887
  function createModuleSpecifierResolver(config, filePath) {
4756
4888
  const root = config.root;
4757
- const fileDir = path12.dirname(filePath);
4889
+ const fileDir = path13.dirname(filePath);
4758
4890
  const aliasEntries = Object.entries(config.resolve.alias).sort(
4759
4891
  ([a], [b]) => b.length - a.length
4760
4892
  );
4761
- const toRootUrl = (abs) => "/" + path12.relative(root, abs).replace(/\\/g, "/");
4893
+ const toServableUrl = (abs) => {
4894
+ if (isUnderRoot(abs, root)) {
4895
+ return "/" + path13.relative(root, abs).replace(/\\/g, "/");
4896
+ }
4897
+ for (const pkgRoot of getLinkedPackageRoots(root)) {
4898
+ if (abs === pkgRoot || abs.startsWith(pkgRoot + path13.sep)) {
4899
+ const normalized = abs.replace(/\\/g, "/");
4900
+ return "/@fs/" + (normalized.startsWith("/") ? normalized.slice(1) : normalized);
4901
+ }
4902
+ }
4903
+ return null;
4904
+ };
4762
4905
  return (specifier) => {
4763
4906
  const suffixMatch = specifier.match(/[?#].*$/);
4764
4907
  const suffix = suffixMatch ? suffixMatch[0] : "";
@@ -4767,18 +4910,21 @@ function createModuleSpecifierResolver(config, filePath) {
4767
4910
  if (baseSpec === key || baseSpec.startsWith(key + "/")) {
4768
4911
  const aliasBase = resolveAliasTarget2(value, root);
4769
4912
  const sub = baseSpec.slice(key.length).replace(/^\//, "");
4770
- const target = sub ? path12.join(aliasBase, sub) : aliasBase;
4913
+ const target = sub ? path13.join(aliasBase, sub) : aliasBase;
4771
4914
  const resolved = tryResolveDiskPath(target);
4772
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
4915
+ const url = resolved ? toServableUrl(resolved) : null;
4916
+ return url ? url + suffix : specifier;
4773
4917
  }
4774
4918
  }
4775
4919
  if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
4776
- const resolved = tryResolveDiskPath(path12.resolve(fileDir, baseSpec));
4777
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
4920
+ const resolved = tryResolveDiskPath(path13.resolve(fileDir, baseSpec));
4921
+ const url = resolved ? toServableUrl(resolved) : null;
4922
+ return url ? url + suffix : specifier;
4778
4923
  }
4779
4924
  if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
4780
- const resolved = tryResolveDiskPath(path12.join(root, baseSpec.replace(/^\//, "")));
4781
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
4925
+ const resolved = tryResolveDiskPath(path13.join(root, baseSpec.replace(/^\//, "")));
4926
+ const url = resolved ? toServableUrl(resolved) : null;
4927
+ return url ? url + suffix : specifier;
4782
4928
  }
4783
4929
  if (baseSpec.startsWith("/")) return specifier;
4784
4930
  return `/@modules/${specifier}`;
@@ -4931,28 +5077,24 @@ function maskStringsAndComments(code) {
4931
5077
  return masked.join("");
4932
5078
  }
4933
5079
  function resolveAliasTarget2(value, root) {
4934
- if (path12.isAbsolute(value) && fs9.existsSync(value)) return value;
4935
- if (value.startsWith("/")) return path12.join(root, value.slice(1));
4936
- return path12.resolve(root, value);
5080
+ if (path13.isAbsolute(value) && fs10.existsSync(value)) return value;
5081
+ if (value.startsWith("/")) return path13.join(root, value.slice(1));
5082
+ return path13.resolve(root, value);
4937
5083
  }
4938
5084
  function tryResolveDiskPath(target) {
4939
- if (fs9.existsSync(target) && fs9.statSync(target).isFile()) return target;
5085
+ if (fs10.existsSync(target) && fs10.statSync(target).isFile()) return target;
4940
5086
  for (const ext of RESOLVE_EXTENSIONS) {
4941
5087
  const withExt = target + ext;
4942
- if (fs9.existsSync(withExt) && fs9.statSync(withExt).isFile()) return withExt;
5088
+ if (fs10.existsSync(withExt) && fs10.statSync(withExt).isFile()) return withExt;
4943
5089
  }
4944
- if (fs9.existsSync(target) && fs9.statSync(target).isDirectory()) {
5090
+ if (fs10.existsSync(target) && fs10.statSync(target).isDirectory()) {
4945
5091
  for (const ext of RESOLVE_EXTENSIONS) {
4946
- const idx = path12.join(target, "index" + ext);
4947
- if (fs9.existsSync(idx) && fs9.statSync(idx).isFile()) return idx;
5092
+ const idx = path13.join(target, "index" + ext);
5093
+ if (fs10.existsSync(idx) && fs10.statSync(idx).isFile()) return idx;
4948
5094
  }
4949
5095
  }
4950
5096
  return null;
4951
5097
  }
4952
- function isUnderRoot(abs, root) {
4953
- const rel = path12.relative(root, abs);
4954
- return !!rel && !rel.startsWith("..") && !path12.isAbsolute(rel);
4955
- }
4956
5098
  function appendTimestampQuery(url, timestamp) {
4957
5099
  const hashIndex = url.indexOf("#");
4958
5100
  const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
@@ -4970,7 +5112,7 @@ function resolveNodeModule(baseDir, moduleName) {
4970
5112
  const resolved = resolveNodeModuleEntry(baseDir, moduleName);
4971
5113
  if (!resolved) return null;
4972
5114
  try {
4973
- return fs9.realpathSync(resolved);
5115
+ return fs10.realpathSync(resolved);
4974
5116
  } catch {
4975
5117
  return resolved;
4976
5118
  }
@@ -4990,21 +5132,21 @@ function resolveNodeModuleEntry(root, moduleName) {
4990
5132
  let pkgDir = null;
4991
5133
  let dir = root;
4992
5134
  for (; ; ) {
4993
- const candidate = path12.join(dir, "node_modules", pkgName);
4994
- if (fs9.existsSync(candidate)) {
5135
+ const candidate = path13.join(dir, "node_modules", pkgName);
5136
+ if (fs10.existsSync(candidate)) {
4995
5137
  pkgDir = candidate;
4996
5138
  break;
4997
5139
  }
4998
- const parent = path12.dirname(dir);
5140
+ const parent = path13.dirname(dir);
4999
5141
  if (parent === dir) break;
5000
5142
  dir = parent;
5001
5143
  }
5002
5144
  if (!pkgDir) return null;
5003
- const pkgJsonPath = path12.join(pkgDir, "package.json");
5004
- if (!fs9.existsSync(pkgJsonPath)) return null;
5145
+ const pkgJsonPath = path13.join(pkgDir, "package.json");
5146
+ if (!fs10.existsSync(pkgJsonPath)) return null;
5005
5147
  let pkg;
5006
5148
  try {
5007
- pkg = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
5149
+ pkg = JSON.parse(fs10.readFileSync(pkgJsonPath, "utf-8"));
5008
5150
  } catch {
5009
5151
  return null;
5010
5152
  }
@@ -5017,32 +5159,32 @@ function resolveNodeModuleEntry(root, moduleName) {
5017
5159
  const subDirs = [""];
5018
5160
  for (const field of ["module", "main"]) {
5019
5161
  if (typeof pkg[field] === "string") {
5020
- const dir2 = path12.dirname(pkg[field]);
5162
+ const dir2 = path13.dirname(pkg[field]);
5021
5163
  if (dir2 && dir2 !== "." && !subDirs.includes(dir2)) subDirs.push(dir2);
5022
5164
  }
5023
5165
  }
5024
5166
  for (const dir2 of subDirs) {
5025
- const direct = path12.join(pkgDir, dir2, subpath);
5026
- if (fs9.existsSync(direct) && fs9.statSync(direct).isFile()) return direct;
5167
+ const direct = path13.join(pkgDir, dir2, subpath);
5168
+ if (fs10.existsSync(direct) && fs10.statSync(direct).isFile()) return direct;
5027
5169
  for (const ext of RESOLVE_EXTENSIONS) {
5028
- if (fs9.existsSync(direct + ext)) return direct + ext;
5170
+ if (fs10.existsSync(direct + ext)) return direct + ext;
5029
5171
  }
5030
5172
  }
5031
5173
  return null;
5032
5174
  }
5033
5175
  for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
5034
5176
  if (typeof pkg[field] === "string") {
5035
- const entry = path12.join(pkgDir, pkg[field]);
5036
- if (fs9.existsSync(entry)) return entry;
5177
+ const entry = path13.join(pkgDir, pkg[field]);
5178
+ if (fs10.existsSync(entry)) return entry;
5037
5179
  }
5038
5180
  }
5039
- const indexFallback = path12.join(pkgDir, "index.js");
5040
- if (fs9.existsSync(indexFallback)) return indexFallback;
5181
+ const indexFallback = path13.join(pkgDir, "index.js");
5182
+ if (fs10.existsSync(indexFallback)) return indexFallback;
5041
5183
  return null;
5042
5184
  }
5043
5185
  function resolvePackageExports(exports, key, pkgDir) {
5044
5186
  if (typeof exports === "string") {
5045
- return key === "." ? path12.join(pkgDir, exports) : null;
5187
+ return key === "." ? path13.join(pkgDir, exports) : null;
5046
5188
  }
5047
5189
  const entry = exports[key];
5048
5190
  if (entry === void 0) {
@@ -5054,7 +5196,7 @@ function resolvePackageExports(exports, key, pkgDir) {
5054
5196
  return resolveExportValue(entry, pkgDir);
5055
5197
  }
5056
5198
  function resolveExportValue(value, pkgDir) {
5057
- if (typeof value === "string") return path12.join(pkgDir, value);
5199
+ if (typeof value === "string") return path13.join(pkgDir, value);
5058
5200
  if (Array.isArray(value)) {
5059
5201
  for (const item of value) {
5060
5202
  const r = resolveExportValue(item, pkgDir);
@@ -5073,35 +5215,54 @@ function resolveExportValue(value, pkgDir) {
5073
5215
  return null;
5074
5216
  }
5075
5217
  function resolveUrlToFile(url, root) {
5076
- const cleanUrl = url.split("?")[0];
5218
+ const cleanUrl = url.split(/[?#]/)[0];
5077
5219
  if (cleanUrl.startsWith("/@modules/")) {
5078
5220
  const moduleName = cleanUrl.slice("/@modules/".length);
5079
5221
  return resolveNodeModule(root, moduleName);
5080
5222
  }
5081
- const filePath = path12.resolve(root, cleanUrl.replace(/^\//, ""));
5082
- if (fs9.existsSync(filePath) && fs9.statSync(filePath).isFile()) {
5223
+ if (cleanUrl.startsWith("/@fs/")) {
5224
+ let abs = cleanUrl.slice("/@fs/".length);
5225
+ if (process.platform === "win32") {
5226
+ abs = abs.replace(/\//g, path13.sep);
5227
+ } else if (!abs.startsWith("/")) {
5228
+ abs = "/" + abs;
5229
+ }
5230
+ try {
5231
+ const real = fs10.realpathSync(abs);
5232
+ if (fs10.statSync(real).isFile() && isAllowedDevModulePath(real, root)) return real;
5233
+ } catch {
5234
+ return null;
5235
+ }
5236
+ return null;
5237
+ }
5238
+ const filePath = path13.resolve(root, cleanUrl.replace(/^\//, ""));
5239
+ if (fs10.existsSync(filePath) && fs10.statSync(filePath).isFile()) {
5083
5240
  return filePath;
5084
5241
  }
5085
5242
  for (const ext of RESOLVE_EXTENSIONS) {
5086
5243
  const withExt = filePath + ext;
5087
- if (fs9.existsSync(withExt)) return withExt;
5244
+ if (fs10.existsSync(withExt)) return withExt;
5088
5245
  }
5089
5246
  for (const ext of RESOLVE_EXTENSIONS) {
5090
- const indexFile = path12.join(filePath, "index" + ext);
5091
- if (fs9.existsSync(indexFile)) return indexFile;
5247
+ const indexFile = path13.join(filePath, "index" + ext);
5248
+ if (fs10.existsSync(indexFile)) return indexFile;
5092
5249
  }
5093
5250
  return null;
5094
5251
  }
5095
5252
  function isModuleRequest(url, destination) {
5096
- const cleanUrl = url.split("?")[0];
5253
+ const cleanUrl = url.split(/[?#]/)[0];
5097
5254
  if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
5098
5255
  if (cleanUrl.startsWith("/@modules/")) return true;
5256
+ if (cleanUrl.startsWith("/@fs/")) return true;
5099
5257
  if (isAssetFile(cleanUrl)) {
5100
- const query = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
5258
+ const qIdx = url.indexOf("?");
5259
+ const hIdx = url.indexOf("#");
5260
+ const queryEnd = hIdx === -1 ? url.length : hIdx;
5261
+ const query = qIdx === -1 || qIdx > queryEnd ? "" : url.slice(qIdx + 1, queryEnd);
5101
5262
  const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query);
5102
5263
  return isExplicitAssetModule || destination === "script";
5103
5264
  }
5104
- if (!path12.extname(cleanUrl)) return true;
5265
+ if (!path13.extname(cleanUrl)) return true;
5105
5266
  return false;
5106
5267
  }
5107
5268
  function getHmrClientCode() {
@@ -5340,8 +5501,9 @@ var init_middleware = __esm({
5340
5501
  init_env();
5341
5502
  init_url();
5342
5503
  init_assets();
5343
- __dirname_esm = path12.dirname(fileURLToPath(import.meta.url));
5344
- __require2 = createRequire3(import.meta.url);
5504
+ init_fs_allow();
5505
+ __dirname_esm = path13.dirname(fileURLToPath(import.meta.url));
5506
+ __require2 = createRequire4(import.meta.url);
5345
5507
  __refreshRuntimeCache = null;
5346
5508
  REACT_REFRESH_BOUNDARY_HELPERS = `
5347
5509
  function __nastiIsPlainObject(obj) {
@@ -5421,8 +5583,8 @@ window.__vite_plugin_react_preamble_installed__ = true;
5421
5583
  });
5422
5584
 
5423
5585
  // src/server/hmr.ts
5424
- import path13 from "path";
5425
- import fs10 from "fs";
5586
+ import path14 from "path";
5587
+ import fs11 from "fs";
5426
5588
  import pc7 from "picocolors";
5427
5589
  async function handleFileChange(file, server, environmentName = "client", timestamp = Date.now()) {
5428
5590
  const { config } = server;
@@ -5432,9 +5594,26 @@ async function handleFileChange(file, server, environmentName = "client", timest
5432
5594
  }
5433
5595
  const moduleGraph = environment.moduleGraph;
5434
5596
  const logger = config.logger;
5435
- const relativePath = "/" + path13.relative(config.root, file);
5436
- const shortFile = path13.relative(config.root, file);
5437
- const mods = moduleGraph.getModulesByFile(file);
5597
+ const relativePath = "/" + path14.relative(config.root, file);
5598
+ const shortFile = path14.relative(config.root, file);
5599
+ let mods = moduleGraph.getModulesByFile(file);
5600
+ if (!mods || mods.size === 0) {
5601
+ try {
5602
+ const real = fs11.realpathSync(file);
5603
+ if (real !== file) mods = moduleGraph.getModulesByFile(real);
5604
+ if (mods && mods.size > 0) file = real;
5605
+ } catch {
5606
+ }
5607
+ }
5608
+ if (!mods || mods.size === 0) {
5609
+ const packageRoot = findNearestPackageRoot(file);
5610
+ if (packageRoot && getLinkedPackageRoots(config.root).some(
5611
+ (r) => packageRoot === r || packageRoot.startsWith(r + path14.sep)
5612
+ )) {
5613
+ const under = moduleGraph.getModulesWithFileUnder(packageRoot);
5614
+ if (under.size > 0) mods = under;
5615
+ }
5616
+ }
5438
5617
  if (!mods || mods.size === 0) {
5439
5618
  return null;
5440
5619
  }
@@ -5449,7 +5628,7 @@ async function handleFileChange(file, server, environmentName = "client", timest
5449
5628
  file,
5450
5629
  timestamp,
5451
5630
  modules: [mod],
5452
- read: () => fs10.readFileSync(file, "utf-8"),
5631
+ read: () => fs11.readFileSync(file, "utf-8"),
5453
5632
  server,
5454
5633
  environment
5455
5634
  };
@@ -5513,6 +5692,7 @@ async function handleFileChange(file, server, environmentName = "client", timest
5513
5692
  var init_hmr = __esm({
5514
5693
  "src/server/hmr.ts"() {
5515
5694
  "use strict";
5695
+ init_fs_allow();
5516
5696
  }
5517
5697
  });
5518
5698
 
@@ -5522,9 +5702,9 @@ __export(runnable_environment_exports, {
5522
5702
  NastiModuleRunner: () => NastiModuleRunner,
5523
5703
  createModuleRunner: () => createModuleRunner
5524
5704
  });
5525
- import path14 from "path";
5526
- import fs11 from "fs";
5527
- import { builtinModules as builtinModules3, createRequire as createRequire4 } from "module";
5705
+ import path15 from "path";
5706
+ import fs12 from "fs";
5707
+ import { builtinModules as builtinModules3, createRequire as createRequire5 } from "module";
5528
5708
  import { pathToFileURL as pathToFileURL4 } from "url";
5529
5709
  function createModuleRunner(environment) {
5530
5710
  if (environment.consumer !== "server") {
@@ -5557,7 +5737,7 @@ var init_runnable_environment = __esm({
5557
5737
  this.config.mode,
5558
5738
  ssrDefineOverrides(environment.consumer)
5559
5739
  );
5560
- this.require = createRequire4(path14.join(this.config.root, "package.json"));
5740
+ this.require = createRequire5(path15.join(this.config.root, "package.json"));
5561
5741
  const handlers = {
5562
5742
  fetchModule: async (id, importer) => this.fetchModule(id, importer),
5563
5743
  getBuiltins: () => [/^node:/, ...builtinModules3]
@@ -5581,9 +5761,9 @@ var init_runnable_environment = __esm({
5581
5761
  this.cache.clear();
5582
5762
  }
5583
5763
  resolveToId(rawUrl) {
5584
- if (path14.isAbsolute(rawUrl) && fs11.existsSync(rawUrl.split("?")[0])) return rawUrl;
5764
+ if (path15.isAbsolute(rawUrl) && fs12.existsSync(rawUrl.split("?")[0])) return rawUrl;
5585
5765
  const clean = rawUrl.replace(/^\//, "");
5586
- return path14.resolve(this.config.root, clean);
5766
+ return path15.resolve(this.config.root, clean);
5587
5767
  }
5588
5768
  /**
5589
5769
  * fetchModule(invoke 契约方法):环境管线产出 runner 可执行代码。
@@ -5592,14 +5772,14 @@ var init_runnable_environment = __esm({
5592
5772
  */
5593
5773
  async fetchModule(id, importer) {
5594
5774
  if (NODE_BUILTINS3.has(id)) return { externalize: id };
5595
- if (!id.startsWith(".") && !path14.isAbsolute(id) && !id.startsWith("\0")) {
5775
+ if (!id.startsWith(".") && !path15.isAbsolute(id) && !id.startsWith("\0")) {
5596
5776
  return { externalize: id };
5597
5777
  }
5598
5778
  const container = this.environment.pluginContainer;
5599
5779
  let resolvedId = id;
5600
5780
  if (id.startsWith(".") && importer) {
5601
5781
  const resolved = await container.resolveId(id, importer);
5602
- resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : path14.resolve(path14.dirname(importer.split("?")[0]), id);
5782
+ resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : path15.resolve(path15.dirname(importer.split("?")[0]), id);
5603
5783
  }
5604
5784
  resolvedId = this.completeExtension(resolvedId);
5605
5785
  const cleanId = resolvedId.split("?")[0];
@@ -5607,8 +5787,8 @@ var init_runnable_environment = __esm({
5607
5787
  const loaded = await container.load(resolvedId);
5608
5788
  if (loaded != null) {
5609
5789
  code = typeof loaded === "string" ? loaded : loaded.code;
5610
- } else if (fs11.existsSync(cleanId)) {
5611
- code = fs11.readFileSync(cleanId, "utf-8");
5790
+ } else if (fs12.existsSync(cleanId)) {
5791
+ code = fs12.readFileSync(cleanId, "utf-8");
5612
5792
  } else {
5613
5793
  throw new Error(`[nasti:ssr] cannot load module: ${resolvedId}`);
5614
5794
  }
@@ -5642,19 +5822,19 @@ var init_runnable_environment = __esm({
5642
5822
  completeExtension(id) {
5643
5823
  const clean = id.split("?")[0];
5644
5824
  const query = id.includes("?") ? id.slice(id.indexOf("?")) : "";
5645
- if (fs11.existsSync(clean) && fs11.statSync(clean).isFile()) return id;
5825
+ if (fs12.existsSync(clean) && fs12.statSync(clean).isFile()) return id;
5646
5826
  const jsMatch = clean.match(/^(.*)\.([mc]?)jsx?$/);
5647
5827
  if (jsMatch) {
5648
5828
  for (const tsExt of [`.${jsMatch[2]}ts`, `.${jsMatch[2]}tsx`]) {
5649
- if (fs11.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
5829
+ if (fs12.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
5650
5830
  }
5651
5831
  }
5652
5832
  for (const ext of this.config.resolve.extensions) {
5653
- if (fs11.existsSync(clean + ext)) return clean + ext + query;
5833
+ if (fs12.existsSync(clean + ext)) return clean + ext + query;
5654
5834
  }
5655
5835
  for (const ext of this.config.resolve.extensions) {
5656
- const indexPath = path14.join(clean, `index${ext}`);
5657
- if (fs11.existsSync(indexPath)) return indexPath;
5836
+ const indexPath = path15.join(clean, `index${ext}`);
5837
+ if (fs12.existsSync(indexPath)) return indexPath;
5658
5838
  }
5659
5839
  return id;
5660
5840
  }
@@ -5681,10 +5861,10 @@ var init_runnable_environment = __esm({
5681
5861
  return;
5682
5862
  }
5683
5863
  const ssrImport = async (dep) => {
5684
- if (NODE_BUILTINS3.has(dep) || !dep.startsWith(".") && !path14.isAbsolute(dep) && !dep.startsWith("\0")) {
5864
+ if (NODE_BUILTINS3.has(dep) || !dep.startsWith(".") && !path15.isAbsolute(dep) && !dep.startsWith("\0")) {
5685
5865
  return this.importExternal(dep);
5686
5866
  }
5687
- const depId = dep.startsWith(".") ? this.completeExtension(path14.resolve(path14.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
5867
+ const depId = dep.startsWith(".") ? this.completeExtension(path15.resolve(path15.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
5688
5868
  return this.instantiate(depId);
5689
5869
  };
5690
5870
  const ssrExportAll = (sourceModule) => {
@@ -5716,7 +5896,7 @@ var init_runnable_environment = __esm({
5716
5896
  }
5717
5897
  async importExternal(spec) {
5718
5898
  try {
5719
- return await (spec.startsWith("node:") || !path14.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import(pathToFileURL4(spec).href));
5899
+ return await (spec.startsWith("node:") || !path15.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import(pathToFileURL4(spec).href));
5720
5900
  } catch (err) {
5721
5901
  throw new Error(`[nasti:ssr] failed to import external "${spec}": ${err.message}`);
5722
5902
  }
@@ -5742,7 +5922,7 @@ var dev_engine_exports = {};
5742
5922
  __export(dev_engine_exports, {
5743
5923
  createBundledDevServer: () => createBundledDevServer
5744
5924
  });
5745
- import path15 from "path";
5925
+ import path16 from "path";
5746
5926
  import crypto3 from "crypto";
5747
5927
  import { WebSocketServer as WsServer2 } from "ws";
5748
5928
  import pc8 from "picocolors";
@@ -5827,7 +6007,7 @@ async function createBundledDevServer(opts) {
5827
6007
  }
5828
6008
  const url = `/${patchPath}`;
5829
6009
  logger.info(
5830
- pc8.green("hmr update ") + pc8.dim(changedFiles.map((f) => path15.relative(config.root, f)).join(", ")),
6010
+ pc8.green("hmr update ") + pc8.dim(changedFiles.map((f) => path16.relative(config.root, f)).join(", ")),
5831
6011
  { timestamp: true }
5832
6012
  );
5833
6013
  sendTo(clientId, { type: "hmr:update", path: url, url });
@@ -5982,7 +6162,7 @@ async function createBundledDevServer(opts) {
5982
6162
  return;
5983
6163
  }
5984
6164
  res.setHeader("ETag", hit.etag);
5985
- res.setHeader("Content-Type", MIME_TYPES[path15.extname(fileName)] ?? "application/octet-stream");
6165
+ res.setHeader("Content-Type", MIME_TYPES[path16.extname(fileName)] ?? "application/octet-stream");
5986
6166
  res.setHeader("Cache-Control", "no-cache");
5987
6167
  res.once("finish", () => {
5988
6168
  void engine.notifyPayloadDelivered(fileName).catch(
@@ -6023,7 +6203,7 @@ function stripCatchAllLoad(plugins) {
6023
6203
  );
6024
6204
  }
6025
6205
  function createReactRefreshRuntimePlugin(entryPoints) {
6026
- const entryIds = new Set(entryPoints.map((p) => path15.resolve(p)));
6206
+ const entryIds = new Set(entryPoints.map((p) => path16.resolve(p)));
6027
6207
  return {
6028
6208
  name: "nasti:bundled-react-refresh",
6029
6209
  resolveId(source) {
@@ -6041,7 +6221,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
6041
6221
  return null;
6042
6222
  },
6043
6223
  transform(code, id) {
6044
- if (!entryIds.has(path15.resolve(id.split("?")[0]))) return null;
6224
+ if (!entryIds.has(path16.resolve(id.split("?")[0]))) return null;
6045
6225
  return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
6046
6226
  ${code}`, map: null };
6047
6227
  }
@@ -6212,7 +6392,7 @@ __export(server_exports, {
6212
6392
  createServer: () => createServer
6213
6393
  });
6214
6394
  import http from "http";
6215
- import path16 from "path";
6395
+ import path17 from "path";
6216
6396
  import os from "os";
6217
6397
  import connect from "connect";
6218
6398
  import sirv from "sirv";
@@ -6305,20 +6485,39 @@ async function createServer(inlineConfig = {}) {
6305
6485
  app.use(bundledServer.middleware);
6306
6486
  }
6307
6487
  const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
6308
- const outDirAbs = path16.resolve(config.root, config.build.outDir);
6309
- const watcher = watch(config.root, {
6488
+ const outDirAbs = path17.resolve(config.root, config.build.outDir);
6489
+ const linkedPackageRoots = getLinkedPackageRoots(config.root).filter(
6490
+ (r) => r !== config.root && !isUnderRoot(config.root, r)
6491
+ );
6492
+ const watchTargets = [config.root, ...linkedPackageRoots];
6493
+ const watcher = watch(watchTargets, {
6310
6494
  ignored: (filePath) => {
6311
- if (filePath === config.root) return false;
6312
- if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path16.sep)) return true;
6313
- const rel = path16.relative(config.root, filePath);
6314
- if (!rel || rel.startsWith("..") || path16.isAbsolute(rel)) return false;
6315
- for (const seg of rel.split(path16.sep)) {
6316
- if (ignoredSegments.has(seg)) return true;
6495
+ if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path17.sep)) return true;
6496
+ for (const watchRoot of watchTargets) {
6497
+ if (filePath === watchRoot) return false;
6498
+ const rel = path17.relative(watchRoot, filePath);
6499
+ if (!rel || rel.startsWith("..") || path17.isAbsolute(rel)) continue;
6500
+ for (const seg of rel.split(path17.sep)) {
6501
+ if (ignoredSegments.has(seg)) return true;
6502
+ }
6503
+ return false;
6317
6504
  }
6318
6505
  return false;
6319
6506
  },
6320
6507
  ignoreInitial: true
6321
6508
  });
6509
+ await new Promise((resolve, reject) => {
6510
+ const onReady = () => {
6511
+ watcher.off("error", onError);
6512
+ resolve();
6513
+ };
6514
+ const onError = (err) => {
6515
+ watcher.off("ready", onReady);
6516
+ reject(err);
6517
+ };
6518
+ watcher.once("ready", onReady);
6519
+ watcher.once("error", onError);
6520
+ });
6322
6521
  let server;
6323
6522
  const environmentServices = {};
6324
6523
  let environmentDriversStarted = false;
@@ -6430,16 +6629,25 @@ async function createServer(inlineConfig = {}) {
6430
6629
  });
6431
6630
  };
6432
6631
  watcher.on("change", (file) => {
6632
+ if (file.includes(`${path17.sep}node_modules${path17.sep}`) || file.endsWith(`${path17.sep}node_modules`)) {
6633
+ clearLinkedPackageRootsCache();
6634
+ }
6433
6635
  ssrRunner?.invalidateFile(file);
6434
6636
  queueClientEnvironmentUpdate(file);
6435
6637
  notifyEnvironmentDrivers(file, "change");
6436
6638
  });
6437
6639
  watcher.on("add", (file) => {
6640
+ if (file.includes(`${path17.sep}node_modules${path17.sep}`) || file.endsWith(`${path17.sep}node_modules`)) {
6641
+ clearLinkedPackageRootsCache();
6642
+ }
6438
6643
  ssrRunner?.invalidateFile(file);
6439
6644
  queueClientEnvironmentUpdate(file);
6440
6645
  notifyEnvironmentDrivers(file, "add");
6441
6646
  });
6442
6647
  watcher.on("unlink", (file) => {
6648
+ if (file.includes(`${path17.sep}node_modules${path17.sep}`) || file.endsWith(`${path17.sep}node_modules`)) {
6649
+ clearLinkedPackageRootsCache();
6650
+ }
6443
6651
  ssrRunner?.invalidateFile(file);
6444
6652
  notifyEnvironmentDrivers(file, "unlink");
6445
6653
  });
@@ -6469,7 +6677,7 @@ async function createServer(inlineConfig = {}) {
6469
6677
  const readyIn = Math.ceil(performance.now() - startTime);
6470
6678
  logger.info(
6471
6679
  `
6472
- ${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.3"}`)} ${pc9.dim("ready in")} ${pc9.bold(readyIn)} ${pc9.dim("ms")}
6680
+ ${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.4"}`)} ${pc9.dim("ready in")} ${pc9.bold(readyIn)} ${pc9.dim("ms")}
6473
6681
  `
6474
6682
  );
6475
6683
  printServerUrls(
@@ -6566,7 +6774,7 @@ async function createServer(inlineConfig = {}) {
6566
6774
  throw error;
6567
6775
  }
6568
6776
  app.use(transformMiddleware(transformContexts.get("client")));
6569
- const publicDir = path16.resolve(config.root, "public");
6777
+ const publicDir = path17.resolve(config.root, "public");
6570
6778
  app.use(sirv(publicDir, { dev: true, etag: true }));
6571
6779
  app.use(sirv(config.root, { dev: true, etag: true }));
6572
6780
  const postMiddlewares = [];
@@ -6605,6 +6813,7 @@ var init_server = __esm({
6605
6813
  init_builtins();
6606
6814
  init_plugin_api();
6607
6815
  init_env();
6816
+ init_fs_allow();
6608
6817
  }
6609
6818
  });
6610
6819
 
@@ -6617,6 +6826,7 @@ init_config();
6617
6826
  init_resolve();
6618
6827
  import path11 from "path";
6619
6828
  import fs8 from "fs";
6829
+ import { createRequire as createRequire3 } from "module";
6620
6830
  import { rolldown as rolldown2 } from "rolldown";
6621
6831
  import pc5 from "picocolors";
6622
6832
 
@@ -6660,7 +6870,7 @@ async function buildElectron(inlineConfig = {}) {
6660
6870
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
6661
6871
  const startTime = performance.now();
6662
6872
  assertElectronVersion(config);
6663
- console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.3"}`));
6873
+ console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.4"}`));
6664
6874
  console.log(pc5.dim(` root: ${config.root}`));
6665
6875
  console.log(pc5.dim(` mode: ${config.mode}`));
6666
6876
  console.log(pc5.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -6804,13 +7014,21 @@ function assertElectronVersion(config) {
6804
7014
  }
6805
7015
  function detectInstalledElectron(root) {
6806
7016
  try {
6807
- const pkgPath = path11.resolve(root, "node_modules/electron/package.json");
6808
- if (!fs8.existsSync(pkgPath)) return null;
7017
+ const require2 = createRequire3(path11.resolve(root, "package.json"));
7018
+ const pkgPath = require2.resolve("electron/package.json");
6809
7019
  const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf-8"));
6810
7020
  const major = parseInt(String(pkg.version).split(".")[0], 10);
6811
7021
  return Number.isFinite(major) ? major : null;
6812
7022
  } catch {
6813
- return null;
7023
+ try {
7024
+ const pkgPath = path11.resolve(root, "node_modules/electron/package.json");
7025
+ if (!fs8.existsSync(pkgPath)) return null;
7026
+ const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf-8"));
7027
+ const major = parseInt(String(pkg.version).split(".")[0], 10);
7028
+ return Number.isFinite(major) ? major : null;
7029
+ } catch {
7030
+ return null;
7031
+ }
6814
7032
  }
6815
7033
  }
6816
7034
 
@@ -6819,9 +7037,9 @@ init_server();
6819
7037
 
6820
7038
  // src/server/electron-dev.ts
6821
7039
  init_config();
6822
- import path17 from "path";
6823
- import fs12 from "fs";
6824
- import { createRequire as createRequire5 } from "module";
7040
+ import path18 from "path";
7041
+ import fs13 from "fs";
7042
+ import { createRequire as createRequire6 } from "module";
6825
7043
  import { spawn } from "child_process";
6826
7044
  import chokidar from "chokidar";
6827
7045
  import pc10 from "picocolors";
@@ -6833,7 +7051,7 @@ async function startElectronDev(inlineConfig = {}) {
6833
7051
  const { noSpawn, ...rest } = inlineConfig;
6834
7052
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
6835
7053
  warnElectronVersion(config);
6836
- console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.3"}`));
7054
+ console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.4"}`));
6837
7055
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
6838
7056
  const server = await createServer2({
6839
7057
  ...rest,
@@ -6843,11 +7061,11 @@ async function startElectronDev(inlineConfig = {}) {
6843
7061
  await server.listen();
6844
7062
  const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
6845
7063
  console.log(pc10.dim(` renderer: ${devUrl}`));
6846
- const stageDir = path17.resolve(config.root, ".nasti");
6847
- fs12.mkdirSync(stageDir, { recursive: true });
6848
- const mainEntry = path17.resolve(config.root, config.electron.main);
7064
+ const stageDir = path18.resolve(config.root, ".nasti");
7065
+ fs13.mkdirSync(stageDir, { recursive: true });
7066
+ const mainEntry = path18.resolve(config.root, config.electron.main);
6849
7067
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
6850
- const builtMainFile = path17.join(stageDir, "main" + extFor(config.electron.mainFormat));
7068
+ const builtMainFile = path18.join(stageDir, "main" + extFor(config.electron.mainFormat));
6851
7069
  const builtPreloadFiles = [];
6852
7070
  const compileAll = async () => {
6853
7071
  await compileNode(config, mainEntry, {
@@ -6857,9 +7075,9 @@ async function startElectronDev(inlineConfig = {}) {
6857
7075
  });
6858
7076
  builtPreloadFiles.length = 0;
6859
7077
  for (const entry of preloadEntries) {
6860
- if (!fs12.existsSync(entry)) continue;
6861
- const base = path17.basename(entry).replace(/\.[^.]+$/, "");
6862
- const out = path17.join(stageDir, base + extFor(config.electron.preloadFormat));
7078
+ if (!fs13.existsSync(entry)) continue;
7079
+ const base = path18.basename(entry).replace(/\.[^.]+$/, "");
7080
+ const out = path18.join(stageDir, base + extFor(config.electron.preloadFormat));
6863
7081
  await compileNode(config, entry, {
6864
7082
  outFile: out,
6865
7083
  format: config.electron.preloadFormat,
@@ -6898,7 +7116,7 @@ async function startElectronDev(inlineConfig = {}) {
6898
7116
  };
6899
7117
  spawnElectron();
6900
7118
  if (config.electron.autoRestart) {
6901
- const watchTargets = [mainEntry, ...preloadEntries].filter(fs12.existsSync);
7119
+ const watchTargets = [mainEntry, ...preloadEntries].filter(fs13.existsSync);
6902
7120
  const watcher = chokidar.watch(watchTargets, { ignoreInitial: true });
6903
7121
  let restarting = null;
6904
7122
  let pending = false;
@@ -6978,7 +7196,7 @@ async function compileNode(config, entry, opts) {
6978
7196
  platform: "node",
6979
7197
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
6980
7198
  });
6981
- fs12.mkdirSync(path17.dirname(opts.outFile), { recursive: true });
7199
+ fs13.mkdirSync(path18.dirname(opts.outFile), { recursive: true });
6982
7200
  await bundle2.write({
6983
7201
  file: opts.outFile,
6984
7202
  format: opts.format === "cjs" ? "cjs" : "esm",
@@ -6991,18 +7209,18 @@ async function compileNode(config, entry, opts) {
6991
7209
  await bundle2.close();
6992
7210
  }
6993
7211
  function electronRendererDevPath(renderer) {
6994
- const normalized = renderer.split(path17.sep).join("/").replace(/^\.?\//, "");
7212
+ const normalized = renderer.split(path18.sep).join("/").replace(/^\.?\//, "");
6995
7213
  return normalized === "index.html" ? "/" : `/${normalized}`;
6996
7214
  }
6997
7215
  function resolveElectronBinary(config) {
6998
- if (config.electron.electronPath && fs12.existsSync(config.electron.electronPath)) {
7216
+ if (config.electron.electronPath && fs13.existsSync(config.electron.electronPath)) {
6999
7217
  return config.electron.electronPath;
7000
7218
  }
7001
7219
  try {
7002
- const require2 = createRequire5(path17.resolve(config.root, "package.json"));
7220
+ const require2 = createRequire6(path18.resolve(config.root, "package.json"));
7003
7221
  const pathFile = require2.resolve("electron");
7004
7222
  const electronModule = require2(pathFile);
7005
- if (typeof electronModule === "string" && fs12.existsSync(electronModule)) {
7223
+ if (typeof electronModule === "string" && fs13.existsSync(electronModule)) {
7006
7224
  return electronModule;
7007
7225
  }
7008
7226
  } catch {
@@ -7029,10 +7247,10 @@ function warnElectronVersion(config) {
7029
7247
  }
7030
7248
 
7031
7249
  // src/plugins/monaco-editor.ts
7032
- import path18 from "path";
7033
- import fs13 from "fs";
7250
+ import path19 from "path";
7251
+ import fs14 from "fs";
7034
7252
  import crypto4 from "crypto";
7035
- import { createRequire as createRequire6 } from "module";
7253
+ import { createRequire as createRequire7 } from "module";
7036
7254
  var DEFAULT_WORKERS = {
7037
7255
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
7038
7256
  css: "monaco-editor/esm/vs/language/css/css.worker",
@@ -7051,9 +7269,9 @@ function normalizePublicPath(p) {
7051
7269
  }
7052
7270
  function readMonacoVersion(root) {
7053
7271
  try {
7054
- const require2 = createRequire6(path18.resolve(root, "package.json"));
7272
+ const require2 = createRequire7(path19.resolve(root, "package.json"));
7055
7273
  const pkgJsonPath = require2.resolve("monaco-editor/package.json", { paths: [root] });
7056
- const pkg = JSON.parse(fs13.readFileSync(pkgJsonPath, "utf-8"));
7274
+ const pkg = JSON.parse(fs14.readFileSync(pkgJsonPath, "utf-8"));
7057
7275
  return typeof pkg.version === "string" ? pkg.version : "unknown";
7058
7276
  } catch {
7059
7277
  return "unknown";
@@ -7073,20 +7291,20 @@ function monacoEditorPlugin(options = {}) {
7073
7291
  let cacheDir = "";
7074
7292
  const building = /* @__PURE__ */ new Map();
7075
7293
  async function buildWorker(worker) {
7076
- const cacheFile = path18.join(cacheDir, `${worker.label}.worker.js`);
7077
- if (fs13.existsSync(cacheFile)) return cacheFile;
7294
+ const cacheFile = path19.join(cacheDir, `${worker.label}.worker.js`);
7295
+ if (fs14.existsSync(cacheFile)) return cacheFile;
7078
7296
  const existing = building.get(worker.label);
7079
7297
  if (existing) return existing;
7080
7298
  const task = (async () => {
7081
7299
  const { rolldown: rolldown4 } = await import("rolldown");
7082
- const require2 = createRequire6(path18.resolve(resolvedConfig.root, "package.json"));
7300
+ const require2 = createRequire7(path19.resolve(resolvedConfig.root, "package.json"));
7083
7301
  let entry;
7084
7302
  try {
7085
7303
  entry = require2.resolve(worker.entry, { paths: [resolvedConfig.root] });
7086
7304
  } catch {
7087
7305
  entry = require2.resolve(worker.entry + ".js", { paths: [resolvedConfig.root] });
7088
7306
  }
7089
- fs13.mkdirSync(cacheDir, { recursive: true });
7307
+ fs14.mkdirSync(cacheDir, { recursive: true });
7090
7308
  const bundle2 = await rolldown4({
7091
7309
  input: entry,
7092
7310
  platform: "browser"
@@ -7146,16 +7364,23 @@ function monacoEditorPlugin(options = {}) {
7146
7364
  resolvedConfig = config;
7147
7365
  const version = readMonacoVersion(config.root);
7148
7366
  const key = crypto4.createHash("sha1").update(version + "|" + publicPath).digest("hex").slice(0, 8);
7149
- cacheDir = path18.resolve(config.root, "node_modules/.nasti/monaco", key);
7367
+ cacheDir = path19.resolve(config.root, "node_modules/.nasti/monaco", key);
7150
7368
  },
7151
7369
  async configureServer(server) {
7152
7370
  const shouldBuild = !isCDN(publicPath) || forceBuildCDN;
7153
7371
  const watcher = server.watcher;
7154
- const monacoDir = path18.resolve(resolvedConfig.root, "node_modules/monaco-editor");
7372
+ const monacoLogical = path19.resolve(resolvedConfig.root, "node_modules/monaco-editor");
7373
+ const monacoPaths = /* @__PURE__ */ new Set([monacoLogical]);
7155
7374
  try {
7156
- watcher?.unwatch?.(monacoDir);
7375
+ monacoPaths.add(fs14.realpathSync(monacoLogical));
7157
7376
  } catch {
7158
7377
  }
7378
+ for (const monacoDir of monacoPaths) {
7379
+ try {
7380
+ watcher?.unwatch?.(monacoDir);
7381
+ } catch {
7382
+ }
7383
+ }
7159
7384
  if (!shouldBuild) return;
7160
7385
  void Promise.all(
7161
7386
  workers.map(
@@ -7181,7 +7406,7 @@ function monacoEditorPlugin(options = {}) {
7181
7406
  const file = await buildWorker(worker);
7182
7407
  res.setHeader("Content-Type", "application/javascript; charset=utf-8");
7183
7408
  res.setHeader("Cache-Control", "public, max-age=604800, immutable");
7184
- fs13.createReadStream(file).pipe(res);
7409
+ fs14.createReadStream(file).pipe(res);
7185
7410
  } catch (e) {
7186
7411
  res.statusCode = 500;
7187
7412
  res.end(`Monaco worker build failed: ${e.message}`);
@@ -7216,16 +7441,16 @@ self.monaco = monaco;`,
7216
7441
  resolvedConfig.root,
7217
7442
  resolvedConfig.build.outDir,
7218
7443
  resolvedConfig.base
7219
- ) : isCDN(publicPath) ? path18.resolve(resolvedConfig.root, resolvedConfig.build.outDir, "monaco") : path18.resolve(
7444
+ ) : isCDN(publicPath) ? path19.resolve(resolvedConfig.root, resolvedConfig.build.outDir, "monaco") : path19.resolve(
7220
7445
  resolvedConfig.root,
7221
7446
  resolvedConfig.build.outDir,
7222
7447
  publicPath.replace(/^\//, "")
7223
7448
  );
7224
- fs13.mkdirSync(outDir, { recursive: true });
7449
+ fs14.mkdirSync(outDir, { recursive: true });
7225
7450
  for (const worker of workers) {
7226
7451
  try {
7227
7452
  const cacheFile = await buildWorker(worker);
7228
- fs13.copyFileSync(cacheFile, path18.join(outDir, `${worker.label}.worker.js`));
7453
+ fs14.copyFileSync(cacheFile, path19.join(outDir, `${worker.label}.worker.js`));
7229
7454
  } catch (e) {
7230
7455
  throw new Error(
7231
7456
  `[nasti:monaco-editor] worker build failed for "${worker.label}": ${e.message}