@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/cli.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) => (path18) => {
14
- var fn = map[path18];
13
+ var __glob = (map) => (path19) => {
14
+ var fn = map[path19];
15
15
  if (fn) return fn();
16
- throw new Error("Module not found in bundle: " + path18);
16
+ throw new Error("Module not found in bundle: " + path19);
17
17
  };
18
18
  var __esm = (fn, res) => function __init() {
19
19
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -856,6 +856,24 @@ var init_module_graph = __esm({
856
856
  getModulesByFile(file) {
857
857
  return this.fileToModulesMap.get(file);
858
858
  }
859
+ /**
860
+ * Modules whose registered entry file lives under `dir` (inclusive).
861
+ * Used when a non-entry source inside a prebundled workspace package changes:
862
+ * only the package entry was registered, so getModulesByFile(changedFile)
863
+ * misses — we invalidate every /@modules entry rooted in that package.
864
+ */
865
+ getModulesWithFileUnder(dir) {
866
+ const result = /* @__PURE__ */ new Set();
867
+ const normDir = dir.replace(/\\/g, "/");
868
+ const normPrefix = normDir.endsWith("/") ? normDir : normDir + "/";
869
+ for (const [file, mods] of this.fileToModulesMap) {
870
+ const normFile = file.replace(/\\/g, "/");
871
+ if (normFile === normDir || normFile.startsWith(normPrefix)) {
872
+ for (const m of mods) result.add(m);
873
+ }
874
+ }
875
+ return result;
876
+ }
859
877
  async ensureEntryFromUrl(url) {
860
878
  const normalizedUrl = removeTimestampQuery(url);
861
879
  let mod = this.urlToModuleMap.get(normalizedUrl);
@@ -1586,9 +1604,123 @@ var init_assets = __esm({
1586
1604
  }
1587
1605
  });
1588
1606
 
1589
- // src/server/middleware.ts
1590
- import path5 from "path";
1607
+ // src/server/fs-allow.ts
1591
1608
  import fs5 from "fs";
1609
+ import path5 from "path";
1610
+ function isUnderRoot(abs, root) {
1611
+ const rel = path5.relative(root, abs);
1612
+ return !!rel && !rel.startsWith("..") && !path5.isAbsolute(rel);
1613
+ }
1614
+ function discoverLinkedPackageRoots(projectRoot, maxDepth = 4) {
1615
+ const results = [];
1616
+ const seenReal = /* @__PURE__ */ new Set();
1617
+ const queued = /* @__PURE__ */ new Set([projectRoot]);
1618
+ const queue = [projectRoot];
1619
+ for (let depth = 0; depth < maxDepth && queue.length > 0; depth++) {
1620
+ const levelCount = queue.length;
1621
+ for (let i = 0; i < levelCount; i++) {
1622
+ const dir = queue.shift();
1623
+ const nm = path5.join(dir, "node_modules");
1624
+ let entries;
1625
+ try {
1626
+ entries = fs5.readdirSync(nm, { withFileTypes: true });
1627
+ } catch {
1628
+ continue;
1629
+ }
1630
+ for (const ent of entries) {
1631
+ if (ent.name.startsWith(".") || ent.name === "node_modules") continue;
1632
+ const pkgNames = ent.name.startsWith("@") ? listScopedPackages(nm, ent.name) : [ent.name];
1633
+ for (const pkgName of pkgNames) {
1634
+ const pkgPath = path5.join(nm, pkgName);
1635
+ let real;
1636
+ try {
1637
+ real = fs5.realpathSync(pkgPath);
1638
+ } catch {
1639
+ continue;
1640
+ }
1641
+ if (seenReal.has(real)) continue;
1642
+ seenReal.add(real);
1643
+ if (!queued.has(real)) {
1644
+ queued.add(real);
1645
+ queue.push(real);
1646
+ }
1647
+ if (real !== projectRoot && !isUnderRoot(real, projectRoot) && !real.includes(NM)) {
1648
+ results.push(real);
1649
+ }
1650
+ }
1651
+ }
1652
+ }
1653
+ }
1654
+ return results;
1655
+ }
1656
+ function listScopedPackages(nm, scope) {
1657
+ try {
1658
+ return fs5.readdirSync(path5.join(nm, scope)).filter((name) => !name.startsWith(".")).map((name) => path5.join(scope, name));
1659
+ } catch {
1660
+ return [];
1661
+ }
1662
+ }
1663
+ function getLinkedPackageRoots(projectRoot) {
1664
+ let mtimeMs = 0;
1665
+ try {
1666
+ mtimeMs = fs5.statSync(path5.join(projectRoot, "node_modules")).mtimeMs;
1667
+ } catch {
1668
+ mtimeMs = 0;
1669
+ }
1670
+ const cached2 = linkedRootsCache.get(projectRoot);
1671
+ if (cached2 && cached2.mtimeMs === mtimeMs) {
1672
+ return cached2.roots;
1673
+ }
1674
+ const roots = discoverLinkedPackageRoots(projectRoot);
1675
+ linkedRootsCache.set(projectRoot, { roots, mtimeMs });
1676
+ return roots;
1677
+ }
1678
+ function clearLinkedPackageRootsCache() {
1679
+ linkedRootsCache.clear();
1680
+ }
1681
+ function isAllowedDevModulePath(realId, projectRoot) {
1682
+ if (realId === projectRoot || isUnderRoot(realId, projectRoot)) return true;
1683
+ for (const pkgRoot of getLinkedPackageRoots(projectRoot)) {
1684
+ if (realId === pkgRoot || realId.startsWith(pkgRoot + path5.sep)) return true;
1685
+ }
1686
+ let dir = projectRoot;
1687
+ for (; ; ) {
1688
+ const nm = path5.join(dir, "node_modules");
1689
+ if (realId === nm || realId.startsWith(nm + path5.sep)) return true;
1690
+ const parent = path5.dirname(dir);
1691
+ if (parent === dir) break;
1692
+ dir = parent;
1693
+ }
1694
+ return false;
1695
+ }
1696
+ function findNearestPackageRoot(file) {
1697
+ let dir = path5.dirname(file);
1698
+ for (; ; ) {
1699
+ const pkgJson = path5.join(dir, "package.json");
1700
+ if (fs5.existsSync(pkgJson)) {
1701
+ try {
1702
+ const pkg = JSON.parse(fs5.readFileSync(pkgJson, "utf-8"));
1703
+ if (typeof pkg?.name === "string" && pkg.name) return dir;
1704
+ } catch {
1705
+ }
1706
+ }
1707
+ const parent = path5.dirname(dir);
1708
+ if (parent === dir) return null;
1709
+ dir = parent;
1710
+ }
1711
+ }
1712
+ var NM, linkedRootsCache;
1713
+ var init_fs_allow = __esm({
1714
+ "src/server/fs-allow.ts"() {
1715
+ "use strict";
1716
+ NM = `${path5.sep}node_modules${path5.sep}`;
1717
+ linkedRootsCache = /* @__PURE__ */ new Map();
1718
+ }
1719
+ });
1720
+
1721
+ // src/server/middleware.ts
1722
+ import path6 from "path";
1723
+ import fs6 from "fs";
1592
1724
  import { createRequire } from "module";
1593
1725
  import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
1594
1726
  import pc3 from "picocolors";
@@ -1599,10 +1731,10 @@ function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
1599
1731
  let cjsPath;
1600
1732
  try {
1601
1733
  const pkgPath = __require2.resolve("react-refresh/package.json");
1602
- cjsPath = path5.join(path5.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1734
+ cjsPath = path6.join(path6.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1603
1735
  } catch (err) {
1604
- cjsPath = path5.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1605
- if (!fs5.existsSync(cjsPath)) {
1736
+ cjsPath = path6.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1737
+ if (!fs6.existsSync(cjsPath)) {
1606
1738
  const origMsg = err instanceof Error ? err.message : String(err);
1607
1739
  throw new Error(
1608
1740
  `[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
@@ -1610,7 +1742,7 @@ Original resolve error: ${origMsg}`
1610
1742
  );
1611
1743
  }
1612
1744
  }
1613
- const cjsSource = fs5.readFileSync(cjsPath, "utf-8");
1745
+ const cjsSource = fs6.readFileSync(cjsPath, "utf-8");
1614
1746
  __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
1615
1747
  const exports = {};
1616
1748
  const module = { exports };
@@ -1781,8 +1913,8 @@ async function transformRequest(url, ctx) {
1781
1913
  let realIdValid = false;
1782
1914
  try {
1783
1915
  if (idParam) {
1784
- realId = fs5.realpathSync(idParam);
1785
- realIdValid = fs5.statSync(realId).isFile() && (realId.includes(`${path5.sep}node_modules${path5.sep}`) || isUnderRoot(realId, config.root));
1916
+ realId = fs6.realpathSync(idParam);
1917
+ realIdValid = fs6.statSync(realId).isFile() && isAllowedDevModulePath(realId, config.root);
1786
1918
  }
1787
1919
  } catch {
1788
1920
  realId = null;
@@ -1849,7 +1981,7 @@ async function transformRequest(url, ctx) {
1849
1981
  }
1850
1982
  }
1851
1983
  const filePath = resolveUrlToFile(url, config.root);
1852
- if (!filePath || !fs5.existsSync(filePath)) return null;
1984
+ if (!filePath || !fs6.existsSync(filePath)) return null;
1853
1985
  const mod = await moduleGraph.ensureEntryFromUrl(url);
1854
1986
  moduleGraph.registerModule(mod, filePath);
1855
1987
  const transformVersion = mod.invalidationVersion;
@@ -1860,7 +1992,7 @@ async function transformRequest(url, ctx) {
1860
1992
  return transformResult2;
1861
1993
  }
1862
1994
  const loaded = await pluginContainer.load(filePath);
1863
- let code = loaded == null ? fs5.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
1995
+ let code = loaded == null ? fs6.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
1864
1996
  let map = loaded && typeof loaded !== "string" ? loaded.map : void 0;
1865
1997
  const pluginResult = await pluginContainer.transform(code, filePath);
1866
1998
  if (pluginResult) {
@@ -1918,7 +2050,7 @@ async function loadVirtualModule(spec, ctx) {
1918
2050
  const resolved = await pluginContainer.resolveId(spec);
1919
2051
  if (resolved == null) return null;
1920
2052
  const resolvedId = typeof resolved === "string" ? resolved : resolved.id;
1921
- const looksVirtual = resolvedId.startsWith("\0") || !fs5.existsSync(resolvedId);
2053
+ const looksVirtual = resolvedId.startsWith("\0") || !fs6.existsSync(resolvedId);
1922
2054
  if (!looksVirtual) return null;
1923
2055
  const loadResult = await pluginContainer.load(resolvedId);
1924
2056
  if (loadResult == null) return null;
@@ -1932,7 +2064,7 @@ async function loadVirtualModule(spec, ctx) {
1932
2064
  config.mode,
1933
2065
  ssrDefineOverrides(ctx.environment?.consumer ?? "client")
1934
2066
  ));
1935
- const anchor = path5.join(config.root, "__nasti_virtual__.ts");
2067
+ const anchor = path6.join(config.root, "__nasti_virtual__.ts");
1936
2068
  code = rewriteImports(code, config, anchor);
1937
2069
  return { id: resolvedId, result: { code } };
1938
2070
  }
@@ -1958,7 +2090,7 @@ async function doBundlePackage(entryFile, root) {
1958
2090
  await bundle2.close();
1959
2091
  let code = result.output[0].code;
1960
2092
  code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
1961
- const externalBaseDir = path5.dirname(entryFile);
2093
+ const externalBaseDir = path6.dirname(entryFile);
1962
2094
  code = code.replace(
1963
2095
  /^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
1964
2096
  (_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`
@@ -1976,16 +2108,16 @@ async function doBundlePackage(entryFile, root) {
1976
2108
  return code;
1977
2109
  }
1978
2110
  async function tryGenerateSubpathShim(entryFile, root) {
1979
- const NM = `${path5.sep}node_modules${path5.sep}`;
1980
- if (!entryFile.includes(NM)) return null;
2111
+ const NM2 = `${path6.sep}node_modules${path6.sep}`;
2112
+ if (!entryFile.includes(NM2)) return null;
1981
2113
  let pkgDir = null;
1982
2114
  let pkgName = null;
1983
- let dir = path5.dirname(entryFile);
2115
+ let dir = path6.dirname(entryFile);
1984
2116
  while (true) {
1985
- const pkgJsonPath = path5.join(dir, "package.json");
1986
- if (fs5.existsSync(pkgJsonPath)) {
2117
+ const pkgJsonPath = path6.join(dir, "package.json");
2118
+ if (fs6.existsSync(pkgJsonPath)) {
1987
2119
  try {
1988
- const pkg = JSON.parse(fs5.readFileSync(pkgJsonPath, "utf-8"));
2120
+ const pkg = JSON.parse(fs6.readFileSync(pkgJsonPath, "utf-8"));
1989
2121
  if (typeof pkg?.name === "string" && pkg.name) {
1990
2122
  pkgDir = dir;
1991
2123
  pkgName = pkg.name;
@@ -1994,16 +2126,16 @@ async function tryGenerateSubpathShim(entryFile, root) {
1994
2126
  } catch {
1995
2127
  }
1996
2128
  }
1997
- const parent = path5.dirname(dir);
2129
+ const parent = path6.dirname(dir);
1998
2130
  if (parent === dir) return null;
1999
2131
  dir = parent;
2000
- if (!dir.includes(NM)) return null;
2132
+ if (!dir.includes(NM2)) return null;
2001
2133
  }
2002
2134
  if (!pkgDir || !pkgName) return null;
2003
- const entryExt = path5.extname(entryFile);
2135
+ const entryExt = path6.extname(entryFile);
2004
2136
  const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
2005
2137
  if (!mainEntry) return null;
2006
- if (path5.resolve(mainEntry) === path5.resolve(entryFile)) return null;
2138
+ if (path6.resolve(mainEntry) === path6.resolve(entryFile)) return null;
2007
2139
  let mainNs;
2008
2140
  let subNs;
2009
2141
  try {
@@ -2027,7 +2159,7 @@ async function tryGenerateSubpathShim(entryFile, root) {
2027
2159
  if (mainNs["default"] !== subNs["default"]) return null;
2028
2160
  }
2029
2161
  const rootMain = resolveNodeModule(root, pkgName);
2030
- const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + path5.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
2162
+ const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + path6.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
2031
2163
  const lines = [
2032
2164
  `// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
2033
2165
  `import * as __pkg from "${mainEntryUrl}";`
@@ -2041,10 +2173,10 @@ async function tryGenerateSubpathShim(entryFile, root) {
2041
2173
  return lines.join("\n") + "\n";
2042
2174
  }
2043
2175
  function pickMainEntryByExtension(pkgDir, preferredExt) {
2044
- const pkgJsonPath = path5.join(pkgDir, "package.json");
2176
+ const pkgJsonPath = path6.join(pkgDir, "package.json");
2045
2177
  let pkg;
2046
2178
  try {
2047
- pkg = JSON.parse(fs5.readFileSync(pkgJsonPath, "utf-8"));
2179
+ pkg = JSON.parse(fs6.readFileSync(pkgJsonPath, "utf-8"));
2048
2180
  } catch {
2049
2181
  return null;
2050
2182
  }
@@ -2063,14 +2195,14 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
2063
2195
  if (typeof pkg.module === "string") candidates.push(pkg.module);
2064
2196
  if (typeof pkg.main === "string") candidates.push(pkg.main);
2065
2197
  for (const cand of candidates) {
2066
- if (path5.extname(cand) === preferredExt) {
2067
- const full = path5.resolve(pkgDir, cand);
2068
- if (fs5.existsSync(full)) return full;
2198
+ if (path6.extname(cand) === preferredExt) {
2199
+ const full = path6.resolve(pkgDir, cand);
2200
+ if (fs6.existsSync(full)) return full;
2069
2201
  }
2070
2202
  }
2071
2203
  for (const cand of candidates) {
2072
- const full = path5.resolve(pkgDir, cand);
2073
- if (fs5.existsSync(full)) return full;
2204
+ const full = path6.resolve(pkgDir, cand);
2205
+ if (fs6.existsSync(full)) return full;
2074
2206
  }
2075
2207
  return null;
2076
2208
  }
@@ -2095,8 +2227,8 @@ function rewriteExternalRequires(code, baseDir, root) {
2095
2227
  }
2096
2228
  async function injectCjsNamedExports(code, entryFile) {
2097
2229
  try {
2098
- const { createRequire: createRequire6 } = await import("module");
2099
- const req = createRequire6(entryFile);
2230
+ const { createRequire: createRequire7 } = await import("module");
2231
+ const req = createRequire7(entryFile);
2100
2232
  const cjsExports = req(entryFile);
2101
2233
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
2102
2234
  const namedKeys = Object.keys(cjsExports).filter(
@@ -2137,11 +2269,22 @@ function rewriteImports(code, config, filePath, importedUrls, moduleGraph) {
2137
2269
  }
2138
2270
  function createModuleSpecifierResolver(config, filePath) {
2139
2271
  const root = config.root;
2140
- const fileDir = path5.dirname(filePath);
2272
+ const fileDir = path6.dirname(filePath);
2141
2273
  const aliasEntries = Object.entries(config.resolve.alias).sort(
2142
2274
  ([a], [b]) => b.length - a.length
2143
2275
  );
2144
- const toRootUrl = (abs) => "/" + path5.relative(root, abs).replace(/\\/g, "/");
2276
+ const toServableUrl = (abs) => {
2277
+ if (isUnderRoot(abs, root)) {
2278
+ return "/" + path6.relative(root, abs).replace(/\\/g, "/");
2279
+ }
2280
+ for (const pkgRoot of getLinkedPackageRoots(root)) {
2281
+ if (abs === pkgRoot || abs.startsWith(pkgRoot + path6.sep)) {
2282
+ const normalized = abs.replace(/\\/g, "/");
2283
+ return "/@fs/" + (normalized.startsWith("/") ? normalized.slice(1) : normalized);
2284
+ }
2285
+ }
2286
+ return null;
2287
+ };
2145
2288
  return (specifier) => {
2146
2289
  const suffixMatch = specifier.match(/[?#].*$/);
2147
2290
  const suffix = suffixMatch ? suffixMatch[0] : "";
@@ -2150,18 +2293,21 @@ function createModuleSpecifierResolver(config, filePath) {
2150
2293
  if (baseSpec === key || baseSpec.startsWith(key + "/")) {
2151
2294
  const aliasBase = resolveAliasTarget(value, root);
2152
2295
  const sub = baseSpec.slice(key.length).replace(/^\//, "");
2153
- const target = sub ? path5.join(aliasBase, sub) : aliasBase;
2296
+ const target = sub ? path6.join(aliasBase, sub) : aliasBase;
2154
2297
  const resolved = tryResolveDiskPath(target);
2155
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
2298
+ const url = resolved ? toServableUrl(resolved) : null;
2299
+ return url ? url + suffix : specifier;
2156
2300
  }
2157
2301
  }
2158
2302
  if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
2159
- const resolved = tryResolveDiskPath(path5.resolve(fileDir, baseSpec));
2160
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
2303
+ const resolved = tryResolveDiskPath(path6.resolve(fileDir, baseSpec));
2304
+ const url = resolved ? toServableUrl(resolved) : null;
2305
+ return url ? url + suffix : specifier;
2161
2306
  }
2162
2307
  if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
2163
- const resolved = tryResolveDiskPath(path5.join(root, baseSpec.replace(/^\//, "")));
2164
- return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
2308
+ const resolved = tryResolveDiskPath(path6.join(root, baseSpec.replace(/^\//, "")));
2309
+ const url = resolved ? toServableUrl(resolved) : null;
2310
+ return url ? url + suffix : specifier;
2165
2311
  }
2166
2312
  if (baseSpec.startsWith("/")) return specifier;
2167
2313
  return `/@modules/${specifier}`;
@@ -2314,28 +2460,24 @@ function maskStringsAndComments(code) {
2314
2460
  return masked.join("");
2315
2461
  }
2316
2462
  function resolveAliasTarget(value, root) {
2317
- if (path5.isAbsolute(value) && fs5.existsSync(value)) return value;
2318
- if (value.startsWith("/")) return path5.join(root, value.slice(1));
2319
- return path5.resolve(root, value);
2463
+ if (path6.isAbsolute(value) && fs6.existsSync(value)) return value;
2464
+ if (value.startsWith("/")) return path6.join(root, value.slice(1));
2465
+ return path6.resolve(root, value);
2320
2466
  }
2321
2467
  function tryResolveDiskPath(target) {
2322
- if (fs5.existsSync(target) && fs5.statSync(target).isFile()) return target;
2468
+ if (fs6.existsSync(target) && fs6.statSync(target).isFile()) return target;
2323
2469
  for (const ext of RESOLVE_EXTENSIONS) {
2324
2470
  const withExt = target + ext;
2325
- if (fs5.existsSync(withExt) && fs5.statSync(withExt).isFile()) return withExt;
2471
+ if (fs6.existsSync(withExt) && fs6.statSync(withExt).isFile()) return withExt;
2326
2472
  }
2327
- if (fs5.existsSync(target) && fs5.statSync(target).isDirectory()) {
2473
+ if (fs6.existsSync(target) && fs6.statSync(target).isDirectory()) {
2328
2474
  for (const ext of RESOLVE_EXTENSIONS) {
2329
- const idx = path5.join(target, "index" + ext);
2330
- if (fs5.existsSync(idx) && fs5.statSync(idx).isFile()) return idx;
2475
+ const idx = path6.join(target, "index" + ext);
2476
+ if (fs6.existsSync(idx) && fs6.statSync(idx).isFile()) return idx;
2331
2477
  }
2332
2478
  }
2333
2479
  return null;
2334
2480
  }
2335
- function isUnderRoot(abs, root) {
2336
- const rel = path5.relative(root, abs);
2337
- return !!rel && !rel.startsWith("..") && !path5.isAbsolute(rel);
2338
- }
2339
2481
  function appendTimestampQuery(url, timestamp) {
2340
2482
  const hashIndex = url.indexOf("#");
2341
2483
  const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
@@ -2353,7 +2495,7 @@ function resolveNodeModule(baseDir, moduleName) {
2353
2495
  const resolved = resolveNodeModuleEntry(baseDir, moduleName);
2354
2496
  if (!resolved) return null;
2355
2497
  try {
2356
- return fs5.realpathSync(resolved);
2498
+ return fs6.realpathSync(resolved);
2357
2499
  } catch {
2358
2500
  return resolved;
2359
2501
  }
@@ -2373,21 +2515,21 @@ function resolveNodeModuleEntry(root, moduleName) {
2373
2515
  let pkgDir = null;
2374
2516
  let dir = root;
2375
2517
  for (; ; ) {
2376
- const candidate = path5.join(dir, "node_modules", pkgName);
2377
- if (fs5.existsSync(candidate)) {
2518
+ const candidate = path6.join(dir, "node_modules", pkgName);
2519
+ if (fs6.existsSync(candidate)) {
2378
2520
  pkgDir = candidate;
2379
2521
  break;
2380
2522
  }
2381
- const parent = path5.dirname(dir);
2523
+ const parent = path6.dirname(dir);
2382
2524
  if (parent === dir) break;
2383
2525
  dir = parent;
2384
2526
  }
2385
2527
  if (!pkgDir) return null;
2386
- const pkgJsonPath = path5.join(pkgDir, "package.json");
2387
- if (!fs5.existsSync(pkgJsonPath)) return null;
2528
+ const pkgJsonPath = path6.join(pkgDir, "package.json");
2529
+ if (!fs6.existsSync(pkgJsonPath)) return null;
2388
2530
  let pkg;
2389
2531
  try {
2390
- pkg = JSON.parse(fs5.readFileSync(pkgJsonPath, "utf-8"));
2532
+ pkg = JSON.parse(fs6.readFileSync(pkgJsonPath, "utf-8"));
2391
2533
  } catch {
2392
2534
  return null;
2393
2535
  }
@@ -2400,32 +2542,32 @@ function resolveNodeModuleEntry(root, moduleName) {
2400
2542
  const subDirs = [""];
2401
2543
  for (const field of ["module", "main"]) {
2402
2544
  if (typeof pkg[field] === "string") {
2403
- const dir2 = path5.dirname(pkg[field]);
2545
+ const dir2 = path6.dirname(pkg[field]);
2404
2546
  if (dir2 && dir2 !== "." && !subDirs.includes(dir2)) subDirs.push(dir2);
2405
2547
  }
2406
2548
  }
2407
2549
  for (const dir2 of subDirs) {
2408
- const direct = path5.join(pkgDir, dir2, subpath);
2409
- if (fs5.existsSync(direct) && fs5.statSync(direct).isFile()) return direct;
2550
+ const direct = path6.join(pkgDir, dir2, subpath);
2551
+ if (fs6.existsSync(direct) && fs6.statSync(direct).isFile()) return direct;
2410
2552
  for (const ext of RESOLVE_EXTENSIONS) {
2411
- if (fs5.existsSync(direct + ext)) return direct + ext;
2553
+ if (fs6.existsSync(direct + ext)) return direct + ext;
2412
2554
  }
2413
2555
  }
2414
2556
  return null;
2415
2557
  }
2416
2558
  for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
2417
2559
  if (typeof pkg[field] === "string") {
2418
- const entry = path5.join(pkgDir, pkg[field]);
2419
- if (fs5.existsSync(entry)) return entry;
2560
+ const entry = path6.join(pkgDir, pkg[field]);
2561
+ if (fs6.existsSync(entry)) return entry;
2420
2562
  }
2421
2563
  }
2422
- const indexFallback = path5.join(pkgDir, "index.js");
2423
- if (fs5.existsSync(indexFallback)) return indexFallback;
2564
+ const indexFallback = path6.join(pkgDir, "index.js");
2565
+ if (fs6.existsSync(indexFallback)) return indexFallback;
2424
2566
  return null;
2425
2567
  }
2426
2568
  function resolvePackageExports(exports, key, pkgDir) {
2427
2569
  if (typeof exports === "string") {
2428
- return key === "." ? path5.join(pkgDir, exports) : null;
2570
+ return key === "." ? path6.join(pkgDir, exports) : null;
2429
2571
  }
2430
2572
  const entry = exports[key];
2431
2573
  if (entry === void 0) {
@@ -2437,7 +2579,7 @@ function resolvePackageExports(exports, key, pkgDir) {
2437
2579
  return resolveExportValue(entry, pkgDir);
2438
2580
  }
2439
2581
  function resolveExportValue(value, pkgDir) {
2440
- if (typeof value === "string") return path5.join(pkgDir, value);
2582
+ if (typeof value === "string") return path6.join(pkgDir, value);
2441
2583
  if (Array.isArray(value)) {
2442
2584
  for (const item of value) {
2443
2585
  const r = resolveExportValue(item, pkgDir);
@@ -2456,35 +2598,54 @@ function resolveExportValue(value, pkgDir) {
2456
2598
  return null;
2457
2599
  }
2458
2600
  function resolveUrlToFile(url, root) {
2459
- const cleanUrl = url.split("?")[0];
2601
+ const cleanUrl = url.split(/[?#]/)[0];
2460
2602
  if (cleanUrl.startsWith("/@modules/")) {
2461
2603
  const moduleName = cleanUrl.slice("/@modules/".length);
2462
2604
  return resolveNodeModule(root, moduleName);
2463
2605
  }
2464
- const filePath = path5.resolve(root, cleanUrl.replace(/^\//, ""));
2465
- if (fs5.existsSync(filePath) && fs5.statSync(filePath).isFile()) {
2606
+ if (cleanUrl.startsWith("/@fs/")) {
2607
+ let abs = cleanUrl.slice("/@fs/".length);
2608
+ if (process.platform === "win32") {
2609
+ abs = abs.replace(/\//g, path6.sep);
2610
+ } else if (!abs.startsWith("/")) {
2611
+ abs = "/" + abs;
2612
+ }
2613
+ try {
2614
+ const real = fs6.realpathSync(abs);
2615
+ if (fs6.statSync(real).isFile() && isAllowedDevModulePath(real, root)) return real;
2616
+ } catch {
2617
+ return null;
2618
+ }
2619
+ return null;
2620
+ }
2621
+ const filePath = path6.resolve(root, cleanUrl.replace(/^\//, ""));
2622
+ if (fs6.existsSync(filePath) && fs6.statSync(filePath).isFile()) {
2466
2623
  return filePath;
2467
2624
  }
2468
2625
  for (const ext of RESOLVE_EXTENSIONS) {
2469
2626
  const withExt = filePath + ext;
2470
- if (fs5.existsSync(withExt)) return withExt;
2627
+ if (fs6.existsSync(withExt)) return withExt;
2471
2628
  }
2472
2629
  for (const ext of RESOLVE_EXTENSIONS) {
2473
- const indexFile = path5.join(filePath, "index" + ext);
2474
- if (fs5.existsSync(indexFile)) return indexFile;
2630
+ const indexFile = path6.join(filePath, "index" + ext);
2631
+ if (fs6.existsSync(indexFile)) return indexFile;
2475
2632
  }
2476
2633
  return null;
2477
2634
  }
2478
2635
  function isModuleRequest(url, destination) {
2479
- const cleanUrl = url.split("?")[0];
2636
+ const cleanUrl = url.split(/[?#]/)[0];
2480
2637
  if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
2481
2638
  if (cleanUrl.startsWith("/@modules/")) return true;
2639
+ if (cleanUrl.startsWith("/@fs/")) return true;
2482
2640
  if (isAssetFile(cleanUrl)) {
2483
- const query = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
2641
+ const qIdx = url.indexOf("?");
2642
+ const hIdx = url.indexOf("#");
2643
+ const queryEnd = hIdx === -1 ? url.length : hIdx;
2644
+ const query = qIdx === -1 || qIdx > queryEnd ? "" : url.slice(qIdx + 1, queryEnd);
2484
2645
  const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query);
2485
2646
  return isExplicitAssetModule || destination === "script";
2486
2647
  }
2487
- if (!path5.extname(cleanUrl)) return true;
2648
+ if (!path6.extname(cleanUrl)) return true;
2488
2649
  return false;
2489
2650
  }
2490
2651
  function getHmrClientCode() {
@@ -2723,7 +2884,8 @@ var init_middleware = __esm({
2723
2884
  init_env();
2724
2885
  init_url();
2725
2886
  init_assets();
2726
- __dirname_esm = path5.dirname(fileURLToPath(import.meta.url));
2887
+ init_fs_allow();
2888
+ __dirname_esm = path6.dirname(fileURLToPath(import.meta.url));
2727
2889
  __require2 = createRequire(import.meta.url);
2728
2890
  __refreshRuntimeCache = null;
2729
2891
  REACT_REFRESH_BOUNDARY_HELPERS = `
@@ -2804,8 +2966,8 @@ window.__vite_plugin_react_preamble_installed__ = true;
2804
2966
  });
2805
2967
 
2806
2968
  // src/server/hmr.ts
2807
- import path6 from "path";
2808
- import fs6 from "fs";
2969
+ import path7 from "path";
2970
+ import fs7 from "fs";
2809
2971
  import pc4 from "picocolors";
2810
2972
  async function handleFileChange(file, server, environmentName = "client", timestamp = Date.now()) {
2811
2973
  const { config } = server;
@@ -2815,9 +2977,26 @@ async function handleFileChange(file, server, environmentName = "client", timest
2815
2977
  }
2816
2978
  const moduleGraph = environment.moduleGraph;
2817
2979
  const logger = config.logger;
2818
- const relativePath = "/" + path6.relative(config.root, file);
2819
- const shortFile = path6.relative(config.root, file);
2820
- const mods = moduleGraph.getModulesByFile(file);
2980
+ const relativePath = "/" + path7.relative(config.root, file);
2981
+ const shortFile = path7.relative(config.root, file);
2982
+ let mods = moduleGraph.getModulesByFile(file);
2983
+ if (!mods || mods.size === 0) {
2984
+ try {
2985
+ const real = fs7.realpathSync(file);
2986
+ if (real !== file) mods = moduleGraph.getModulesByFile(real);
2987
+ if (mods && mods.size > 0) file = real;
2988
+ } catch {
2989
+ }
2990
+ }
2991
+ if (!mods || mods.size === 0) {
2992
+ const packageRoot = findNearestPackageRoot(file);
2993
+ if (packageRoot && getLinkedPackageRoots(config.root).some(
2994
+ (r) => packageRoot === r || packageRoot.startsWith(r + path7.sep)
2995
+ )) {
2996
+ const under = moduleGraph.getModulesWithFileUnder(packageRoot);
2997
+ if (under.size > 0) mods = under;
2998
+ }
2999
+ }
2821
3000
  if (!mods || mods.size === 0) {
2822
3001
  return null;
2823
3002
  }
@@ -2832,7 +3011,7 @@ async function handleFileChange(file, server, environmentName = "client", timest
2832
3011
  file,
2833
3012
  timestamp,
2834
3013
  modules: [mod],
2835
- read: () => fs6.readFileSync(file, "utf-8"),
3014
+ read: () => fs7.readFileSync(file, "utf-8"),
2836
3015
  server,
2837
3016
  environment
2838
3017
  };
@@ -2896,16 +3075,17 @@ async function handleFileChange(file, server, environmentName = "client", timest
2896
3075
  var init_hmr = __esm({
2897
3076
  "src/server/hmr.ts"() {
2898
3077
  "use strict";
3078
+ init_fs_allow();
2899
3079
  }
2900
3080
  });
2901
3081
 
2902
3082
  // src/plugins/resolve.ts
2903
- import path7 from "path";
2904
- import fs7 from "fs";
3083
+ import path8 from "path";
3084
+ import fs8 from "fs";
2905
3085
  import { createRequire as createRequire2 } from "module";
2906
3086
  function resolvePlugin(config) {
2907
3087
  const { alias, extensions } = config.resolve;
2908
- const require2 = createRequire2(path7.resolve(config.root, "package.json"));
3088
+ const require2 = createRequire2(path8.resolve(config.root, "package.json"));
2909
3089
  const aliasEntries = Object.entries(alias).sort(
2910
3090
  ([a], [b]) => b.length - a.length
2911
3091
  );
@@ -2913,10 +3093,10 @@ function resolvePlugin(config) {
2913
3093
  if (config.framework === "vue") {
2914
3094
  try {
2915
3095
  const vuePkgJson = require2.resolve("vue/package.json", { paths: [config.root] });
2916
- const vueDir = path7.dirname(vuePkgJson);
2917
- const mod = JSON.parse(fs7.readFileSync(vuePkgJson, "utf-8")).module;
2918
- const entry = path7.join(vueDir, mod ?? "dist/vue.runtime.esm-bundler.js");
2919
- if (fs7.existsSync(entry)) vueRuntimeEntry = entry;
3096
+ const vueDir = path8.dirname(vuePkgJson);
3097
+ const mod = JSON.parse(fs8.readFileSync(vuePkgJson, "utf-8")).module;
3098
+ const entry = path8.join(vueDir, mod ?? "dist/vue.runtime.esm-bundler.js");
3099
+ if (fs8.existsSync(entry)) vueRuntimeEntry = entry;
2920
3100
  } catch {
2921
3101
  }
2922
3102
  }
@@ -2928,24 +3108,24 @@ function resolvePlugin(config) {
2928
3108
  if (source === key || source.startsWith(key + "/")) {
2929
3109
  const aliasBase = resolveAliasTarget2(value, config.root);
2930
3110
  const sub = source.slice(key.length).replace(/^\//, "");
2931
- const target = sub ? path7.join(aliasBase, sub) : aliasBase;
3111
+ const target = sub ? path8.join(aliasBase, sub) : aliasBase;
2932
3112
  const resolved = tryResolveFile(target, extensions);
2933
3113
  if (resolved) return resolved;
2934
3114
  break;
2935
3115
  }
2936
3116
  }
2937
3117
  if (source.startsWith("/") && !source.startsWith("//")) {
2938
- const rootRelative = path7.join(config.root, source.slice(1));
3118
+ const rootRelative = path8.join(config.root, source.slice(1));
2939
3119
  const resolved = tryResolveFile(rootRelative, extensions);
2940
3120
  if (resolved) return resolved;
2941
3121
  }
2942
- if (path7.isAbsolute(source) && fs7.existsSync(source)) {
3122
+ if (path8.isAbsolute(source) && fs8.existsSync(source)) {
2943
3123
  const resolved = tryResolveFile(source, extensions);
2944
3124
  if (resolved) return resolved;
2945
3125
  }
2946
3126
  if (source.startsWith(".")) {
2947
- const dir = importer ? path7.dirname(importer) : config.root;
2948
- const absolute = path7.resolve(dir, source);
3127
+ const dir = importer ? path8.dirname(importer) : config.root;
3128
+ const absolute = path8.resolve(dir, source);
2949
3129
  const resolved = tryResolveFile(absolute, extensions);
2950
3130
  if (resolved) return resolved;
2951
3131
  }
@@ -2954,7 +3134,7 @@ function resolvePlugin(config) {
2954
3134
  if (config.command === "build") return null;
2955
3135
  try {
2956
3136
  const resolved = require2.resolve(source, {
2957
- paths: [importer ? path7.dirname(importer) : config.root]
3137
+ paths: [importer ? path8.dirname(importer) : config.root]
2958
3138
  });
2959
3139
  return resolved;
2960
3140
  } catch {
@@ -2965,9 +3145,9 @@ function resolvePlugin(config) {
2965
3145
  },
2966
3146
  load(id) {
2967
3147
  if (id.startsWith("\0")) return null;
2968
- if (!fs7.existsSync(id)) return null;
3148
+ if (!fs8.existsSync(id)) return null;
2969
3149
  if (id.endsWith(".json")) {
2970
- const content = fs7.readFileSync(id, "utf-8");
3150
+ const content = fs8.readFileSync(id, "utf-8");
2971
3151
  return `export default ${content}`;
2972
3152
  }
2973
3153
  return null;
@@ -2975,24 +3155,24 @@ function resolvePlugin(config) {
2975
3155
  };
2976
3156
  }
2977
3157
  function resolveAliasTarget2(value, root) {
2978
- if (path7.isAbsolute(value) && fs7.existsSync(value)) return value;
2979
- if (value.startsWith("/")) return path7.join(root, value.slice(1));
2980
- return path7.resolve(root, value);
3158
+ if (path8.isAbsolute(value) && fs8.existsSync(value)) return value;
3159
+ if (value.startsWith("/")) return path8.join(root, value.slice(1));
3160
+ return path8.resolve(root, value);
2981
3161
  }
2982
3162
  function tryResolveFile(file, extensions) {
2983
- if (fs7.existsSync(file) && fs7.statSync(file).isFile()) {
3163
+ if (fs8.existsSync(file) && fs8.statSync(file).isFile()) {
2984
3164
  return file;
2985
3165
  }
2986
3166
  for (const ext of extensions) {
2987
3167
  const withExt = file + ext;
2988
- if (fs7.existsSync(withExt) && fs7.statSync(withExt).isFile()) {
3168
+ if (fs8.existsSync(withExt) && fs8.statSync(withExt).isFile()) {
2989
3169
  return withExt;
2990
3170
  }
2991
3171
  }
2992
- if (fs7.existsSync(file) && fs7.statSync(file).isDirectory()) {
3172
+ if (fs8.existsSync(file) && fs8.statSync(file).isDirectory()) {
2993
3173
  for (const ext of extensions) {
2994
- const indexFile = path7.join(file, "index" + ext);
2995
- if (fs7.existsSync(indexFile)) {
3174
+ const indexFile = path8.join(file, "index" + ext);
3175
+ if (fs8.existsSync(indexFile)) {
2996
3176
  return indexFile;
2997
3177
  }
2998
3178
  }
@@ -3040,27 +3220,27 @@ var require_process = __commonJS({
3040
3220
  var require_filesystem = __commonJS({
3041
3221
  "node_modules/detect-libc/lib/filesystem.js"(exports, module) {
3042
3222
  "use strict";
3043
- var fs13 = __require("fs");
3223
+ var fs14 = __require("fs");
3044
3224
  var LDD_PATH = "/usr/bin/ldd";
3045
3225
  var SELF_PATH = "/proc/self/exe";
3046
3226
  var MAX_LENGTH = 2048;
3047
- var readFileSync = (path18) => {
3048
- const fd = fs13.openSync(path18, "r");
3227
+ var readFileSync = (path19) => {
3228
+ const fd = fs14.openSync(path19, "r");
3049
3229
  const buffer = Buffer.alloc(MAX_LENGTH);
3050
- const bytesRead = fs13.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3051
- fs13.close(fd, () => {
3230
+ const bytesRead = fs14.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3231
+ fs14.close(fd, () => {
3052
3232
  });
3053
3233
  return buffer.subarray(0, bytesRead);
3054
3234
  };
3055
- var readFile = (path18) => new Promise((resolve, reject) => {
3056
- fs13.open(path18, "r", (err, fd) => {
3235
+ var readFile = (path19) => new Promise((resolve, reject) => {
3236
+ fs14.open(path19, "r", (err, fd) => {
3057
3237
  if (err) {
3058
3238
  reject(err);
3059
3239
  } else {
3060
3240
  const buffer = Buffer.alloc(MAX_LENGTH);
3061
- fs13.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3241
+ fs14.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3062
3242
  resolve(buffer.subarray(0, bytesRead));
3063
- fs13.close(fd, () => {
3243
+ fs14.close(fd, () => {
3064
3244
  });
3065
3245
  });
3066
3246
  }
@@ -3172,11 +3352,11 @@ var require_detect_libc = __commonJS({
3172
3352
  }
3173
3353
  return null;
3174
3354
  };
3175
- var familyFromInterpreterPath = (path18) => {
3176
- if (path18) {
3177
- if (path18.includes("/ld-musl-")) {
3355
+ var familyFromInterpreterPath = (path19) => {
3356
+ if (path19) {
3357
+ if (path19.includes("/ld-musl-")) {
3178
3358
  return MUSL;
3179
- } else if (path18.includes("/ld-linux-")) {
3359
+ } else if (path19.includes("/ld-linux-")) {
3180
3360
  return GLIBC;
3181
3361
  }
3182
3362
  }
@@ -3223,8 +3403,8 @@ var require_detect_libc = __commonJS({
3223
3403
  cachedFamilyInterpreter = null;
3224
3404
  try {
3225
3405
  const selfContent = await readFile(SELF_PATH);
3226
- const path18 = interpreterPath(selfContent);
3227
- cachedFamilyInterpreter = familyFromInterpreterPath(path18);
3406
+ const path19 = interpreterPath(selfContent);
3407
+ cachedFamilyInterpreter = familyFromInterpreterPath(path19);
3228
3408
  } catch (e) {
3229
3409
  }
3230
3410
  return cachedFamilyInterpreter;
@@ -3236,8 +3416,8 @@ var require_detect_libc = __commonJS({
3236
3416
  cachedFamilyInterpreter = null;
3237
3417
  try {
3238
3418
  const selfContent = readFileSync(SELF_PATH);
3239
- const path18 = interpreterPath(selfContent);
3240
- cachedFamilyInterpreter = familyFromInterpreterPath(path18);
3419
+ const path19 = interpreterPath(selfContent);
3420
+ cachedFamilyInterpreter = familyFromInterpreterPath(path19);
3241
3421
  } catch (e) {
3242
3422
  }
3243
3423
  return cachedFamilyInterpreter;
@@ -3956,7 +4136,7 @@ var init_css_engine = __esm({
3956
4136
  });
3957
4137
 
3958
4138
  // src/plugins/tailwind.ts
3959
- import path8 from "path";
4139
+ import path9 from "path";
3960
4140
  import { createRequire as createRequire3 } from "module";
3961
4141
  import { pathToFileURL as pathToFileURL3 } from "url";
3962
4142
  function hasTailwindDirectives(css) {
@@ -3966,7 +4146,7 @@ function hasTailwindDirectives(css) {
3966
4146
  }
3967
4147
  async function loadTailwind(projectRoot) {
3968
4148
  if (cached && cachedRoot === projectRoot) return cached;
3969
- const req = createRequire3(path8.join(projectRoot, "package.json"));
4149
+ const req = createRequire3(path9.join(projectRoot, "package.json"));
3970
4150
  let nodePath;
3971
4151
  let oxidePath;
3972
4152
  try {
@@ -3987,7 +4167,7 @@ async function compileTailwind(css, fromFile, projectRoot) {
3987
4167
  const { node, oxide } = await loadTailwind(projectRoot);
3988
4168
  const dependencies = [];
3989
4169
  const compiler2 = await node.compile(css, {
3990
- base: path8.dirname(fromFile),
4170
+ base: path9.dirname(fromFile),
3991
4171
  from: fromFile,
3992
4172
  onDependency: (p) => dependencies.push(p)
3993
4173
  });
@@ -4009,7 +4189,7 @@ var init_tailwind = __esm({
4009
4189
  });
4010
4190
 
4011
4191
  // src/plugins/css.ts
4012
- import path9 from "path";
4192
+ import path10 from "path";
4013
4193
  import { SourceMapGenerator } from "source-map-js";
4014
4194
  function cssPlugin(config, engine, consumer = "client") {
4015
4195
  return {
@@ -4133,8 +4313,8 @@ function rewriteCssUrls(css, from, root) {
4133
4313
  if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
4134
4314
  return match;
4135
4315
  }
4136
- const resolved = path9.resolve(path9.dirname(from), url);
4137
- const relative = "/" + path9.relative(root, resolved).replace(/\\/g, "/");
4316
+ const resolved = path10.resolve(path10.dirname(from), url);
4317
+ const relative = "/" + path10.relative(root, resolved).replace(/\\/g, "/");
4138
4318
  return `url(${relative})`;
4139
4319
  });
4140
4320
  }
@@ -4264,8 +4444,8 @@ function vuePlugin(config, environmentName = "client") {
4264
4444
  let cached2 = descriptorCache.get(filePath);
4265
4445
  if (!cached2) {
4266
4446
  try {
4267
- const fs13 = await import("fs");
4268
- const rawSource = fs13.readFileSync(filePath, "utf-8");
4447
+ const fs14 = await import("fs");
4448
+ const rawSource = fs14.readFileSync(filePath, "utf-8");
4269
4449
  const transformedSfc = await applySourceTransform(
4270
4450
  vueOptions.transformSfc,
4271
4451
  rawSource,
@@ -4693,8 +4873,8 @@ __export(runnable_environment_exports, {
4693
4873
  NastiModuleRunner: () => NastiModuleRunner,
4694
4874
  createModuleRunner: () => createModuleRunner
4695
4875
  });
4696
- import path10 from "path";
4697
- import fs8 from "fs";
4876
+ import path11 from "path";
4877
+ import fs9 from "fs";
4698
4878
  import { builtinModules, createRequire as createRequire4 } from "module";
4699
4879
  import { pathToFileURL as pathToFileURL4 } from "url";
4700
4880
  function createModuleRunner(environment) {
@@ -4728,7 +4908,7 @@ var init_runnable_environment = __esm({
4728
4908
  this.config.mode,
4729
4909
  ssrDefineOverrides(environment.consumer)
4730
4910
  );
4731
- this.require = createRequire4(path10.join(this.config.root, "package.json"));
4911
+ this.require = createRequire4(path11.join(this.config.root, "package.json"));
4732
4912
  const handlers = {
4733
4913
  fetchModule: async (id, importer) => this.fetchModule(id, importer),
4734
4914
  getBuiltins: () => [/^node:/, ...builtinModules]
@@ -4752,9 +4932,9 @@ var init_runnable_environment = __esm({
4752
4932
  this.cache.clear();
4753
4933
  }
4754
4934
  resolveToId(rawUrl) {
4755
- if (path10.isAbsolute(rawUrl) && fs8.existsSync(rawUrl.split("?")[0])) return rawUrl;
4935
+ if (path11.isAbsolute(rawUrl) && fs9.existsSync(rawUrl.split("?")[0])) return rawUrl;
4756
4936
  const clean = rawUrl.replace(/^\//, "");
4757
- return path10.resolve(this.config.root, clean);
4937
+ return path11.resolve(this.config.root, clean);
4758
4938
  }
4759
4939
  /**
4760
4940
  * fetchModule(invoke 契约方法):环境管线产出 runner 可执行代码。
@@ -4763,14 +4943,14 @@ var init_runnable_environment = __esm({
4763
4943
  */
4764
4944
  async fetchModule(id, importer) {
4765
4945
  if (NODE_BUILTINS.has(id)) return { externalize: id };
4766
- if (!id.startsWith(".") && !path10.isAbsolute(id) && !id.startsWith("\0")) {
4946
+ if (!id.startsWith(".") && !path11.isAbsolute(id) && !id.startsWith("\0")) {
4767
4947
  return { externalize: id };
4768
4948
  }
4769
4949
  const container = this.environment.pluginContainer;
4770
4950
  let resolvedId = id;
4771
4951
  if (id.startsWith(".") && importer) {
4772
4952
  const resolved = await container.resolveId(id, importer);
4773
- resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : path10.resolve(path10.dirname(importer.split("?")[0]), id);
4953
+ resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : path11.resolve(path11.dirname(importer.split("?")[0]), id);
4774
4954
  }
4775
4955
  resolvedId = this.completeExtension(resolvedId);
4776
4956
  const cleanId = resolvedId.split("?")[0];
@@ -4778,8 +4958,8 @@ var init_runnable_environment = __esm({
4778
4958
  const loaded = await container.load(resolvedId);
4779
4959
  if (loaded != null) {
4780
4960
  code = typeof loaded === "string" ? loaded : loaded.code;
4781
- } else if (fs8.existsSync(cleanId)) {
4782
- code = fs8.readFileSync(cleanId, "utf-8");
4961
+ } else if (fs9.existsSync(cleanId)) {
4962
+ code = fs9.readFileSync(cleanId, "utf-8");
4783
4963
  } else {
4784
4964
  throw new Error(`[nasti:ssr] cannot load module: ${resolvedId}`);
4785
4965
  }
@@ -4813,19 +4993,19 @@ var init_runnable_environment = __esm({
4813
4993
  completeExtension(id) {
4814
4994
  const clean = id.split("?")[0];
4815
4995
  const query = id.includes("?") ? id.slice(id.indexOf("?")) : "";
4816
- if (fs8.existsSync(clean) && fs8.statSync(clean).isFile()) return id;
4996
+ if (fs9.existsSync(clean) && fs9.statSync(clean).isFile()) return id;
4817
4997
  const jsMatch = clean.match(/^(.*)\.([mc]?)jsx?$/);
4818
4998
  if (jsMatch) {
4819
4999
  for (const tsExt of [`.${jsMatch[2]}ts`, `.${jsMatch[2]}tsx`]) {
4820
- if (fs8.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
5000
+ if (fs9.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
4821
5001
  }
4822
5002
  }
4823
5003
  for (const ext of this.config.resolve.extensions) {
4824
- if (fs8.existsSync(clean + ext)) return clean + ext + query;
5004
+ if (fs9.existsSync(clean + ext)) return clean + ext + query;
4825
5005
  }
4826
5006
  for (const ext of this.config.resolve.extensions) {
4827
- const indexPath = path10.join(clean, `index${ext}`);
4828
- if (fs8.existsSync(indexPath)) return indexPath;
5007
+ const indexPath = path11.join(clean, `index${ext}`);
5008
+ if (fs9.existsSync(indexPath)) return indexPath;
4829
5009
  }
4830
5010
  return id;
4831
5011
  }
@@ -4852,10 +5032,10 @@ var init_runnable_environment = __esm({
4852
5032
  return;
4853
5033
  }
4854
5034
  const ssrImport = async (dep) => {
4855
- if (NODE_BUILTINS.has(dep) || !dep.startsWith(".") && !path10.isAbsolute(dep) && !dep.startsWith("\0")) {
5035
+ if (NODE_BUILTINS.has(dep) || !dep.startsWith(".") && !path11.isAbsolute(dep) && !dep.startsWith("\0")) {
4856
5036
  return this.importExternal(dep);
4857
5037
  }
4858
- const depId = dep.startsWith(".") ? this.completeExtension(path10.resolve(path10.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
5038
+ const depId = dep.startsWith(".") ? this.completeExtension(path11.resolve(path11.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
4859
5039
  return this.instantiate(depId);
4860
5040
  };
4861
5041
  const ssrExportAll = (sourceModule) => {
@@ -4887,7 +5067,7 @@ var init_runnable_environment = __esm({
4887
5067
  }
4888
5068
  async importExternal(spec) {
4889
5069
  try {
4890
- return await (spec.startsWith("node:") || !path10.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import(pathToFileURL4(spec).href));
5070
+ return await (spec.startsWith("node:") || !path11.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import(pathToFileURL4(spec).href));
4891
5071
  } catch (err) {
4892
5072
  throw new Error(`[nasti:ssr] failed to import external "${spec}": ${err.message}`);
4893
5073
  }
@@ -4909,7 +5089,7 @@ var init_runnable_environment = __esm({
4909
5089
  });
4910
5090
 
4911
5091
  // src/build/reporter.ts
4912
- import path11 from "path";
5092
+ import path12 from "path";
4913
5093
  import { gzipSync } from "zlib";
4914
5094
  import pc5 from "picocolors";
4915
5095
  async function tryNativeReporterPlugin(config, logger) {
@@ -4950,7 +5130,7 @@ function reportBuildOutput(output, config, logger) {
4950
5130
  if (compressed && content != null) {
4951
5131
  gzip = gzipSync(typeof content === "string" ? Buffer.from(content) : content).byteLength;
4952
5132
  }
4953
- const ext = path11.extname(file.fileName);
5133
+ const ext = path12.extname(file.fileName);
4954
5134
  const group = file.type === "chunk" ? "js" : ext === ".css" ? "css" : "assets";
4955
5135
  entries.push({ name: file.fileName, size, gzip, group });
4956
5136
  }
@@ -4998,12 +5178,12 @@ var init_reporter = __esm({
4998
5178
  });
4999
5179
 
5000
5180
  // src/core/build-app-context.ts
5001
- import fs9 from "fs";
5002
- import path12 from "path";
5181
+ import fs10 from "fs";
5182
+ import path13 from "path";
5003
5183
  function createBuildAppContext(config, results) {
5004
5184
  const output = [];
5005
5185
  const emitted = /* @__PURE__ */ new Set();
5006
- const outDir = path12.resolve(config.root, config.build.outDir);
5186
+ const outDir = path13.resolve(config.root, config.build.outDir);
5007
5187
  let environmentArtifacts;
5008
5188
  return {
5009
5189
  config,
@@ -5059,14 +5239,14 @@ function createBuildAppContext(config, results) {
5059
5239
  if (environmentArtifacts.has(collisionKey)) {
5060
5240
  throw new Error(`[nasti] app artifact conflicts with environment output: ${fileName}`);
5061
5241
  }
5062
- const target = path12.resolve(outDir, ...fileName.split("/"));
5063
- const relative = path12.relative(outDir, target);
5064
- if (relative.startsWith("..") || path12.isAbsolute(relative)) {
5242
+ const target = path13.resolve(outDir, ...fileName.split("/"));
5243
+ const relative = path13.relative(outDir, target);
5244
+ if (relative.startsWith("..") || path13.isAbsolute(relative)) {
5065
5245
  throw new Error(`[nasti] app artifact must stay inside build.outDir: ${file.fileName}`);
5066
5246
  }
5067
5247
  assertNoSymlinkComponents(outDir, fileName);
5068
- fs9.mkdirSync(path12.dirname(target), { recursive: true });
5069
- fs9.writeFileSync(target, file.source);
5248
+ fs10.mkdirSync(path13.dirname(target), { recursive: true });
5249
+ fs10.writeFileSync(target, file.source);
5070
5250
  const artifact = {
5071
5251
  ...file,
5072
5252
  fileName,
@@ -5082,10 +5262,10 @@ function joinPublicPath(base, fileName) {
5082
5262
  return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
5083
5263
  }
5084
5264
  function normalizeEnvironmentFileName(fileName) {
5085
- return path12.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
5265
+ return path13.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
5086
5266
  }
5087
5267
  function isInvalidEnvironmentFileName(fileName) {
5088
- return !fileName || fileName === "." || fileName === ".." || fileName.startsWith("../") || path12.posix.isAbsolute(fileName) || /^[A-Za-z]:\//.test(fileName);
5268
+ return !fileName || fileName === "." || fileName === ".." || fileName.startsWith("../") || path13.posix.isAbsolute(fileName) || /^[A-Za-z]:\//.test(fileName);
5089
5269
  }
5090
5270
  function normalizeAppFileName(fileName) {
5091
5271
  const normalized = normalizeEnvironmentFileName(fileName);
@@ -5102,14 +5282,14 @@ function collectEnvironmentArtifacts(config, results, appOutDir) {
5102
5282
  for (const [environmentName, result] of Object.entries(results)) {
5103
5283
  const environment = config.environments[environmentName];
5104
5284
  if (!environment) continue;
5105
- const environmentOutDir = path12.resolve(config.root, environment.build.outDir);
5285
+ const environmentOutDir = path13.resolve(config.root, environment.build.outDir);
5106
5286
  for (const artifact of result.output) {
5107
- const artifactPath = path12.resolve(
5287
+ const artifactPath = path13.resolve(
5108
5288
  environmentOutDir,
5109
5289
  ...normalizeEnvironmentFileName(artifact.fileName).split("/")
5110
5290
  );
5111
- const relative = path12.relative(appOutDir, artifactPath);
5112
- if (!relative.startsWith("..") && !path12.isAbsolute(relative)) {
5291
+ const relative = path13.relative(appOutDir, artifactPath);
5292
+ if (!relative.startsWith("..") && !path13.isAbsolute(relative)) {
5113
5293
  occupied.add(artifactCollisionKey(relative));
5114
5294
  }
5115
5295
  }
@@ -5119,10 +5299,10 @@ function collectEnvironmentArtifacts(config, results, appOutDir) {
5119
5299
  function assertNoSymlinkComponents(outDir, fileName) {
5120
5300
  let current = outDir;
5121
5301
  for (const segment of fileName.split("/")) {
5122
- current = path12.join(current, segment);
5302
+ current = path13.join(current, segment);
5123
5303
  let stats;
5124
5304
  try {
5125
- stats = fs9.lstatSync(current);
5305
+ stats = fs10.lstatSync(current);
5126
5306
  } catch (error) {
5127
5307
  if (error.code === "ENOENT") continue;
5128
5308
  throw error;
@@ -5155,8 +5335,8 @@ __export(build_exports, {
5155
5335
  resolveClientEntries: () => resolveClientEntries,
5156
5336
  toRolldownPlugins: () => toRolldownPlugins
5157
5337
  });
5158
- import path13 from "path";
5159
- import fs10 from "fs";
5338
+ import path14 from "path";
5339
+ import fs11 from "fs";
5160
5340
  import { builtinModules as builtinModules2 } from "module";
5161
5341
  import { rolldown } from "rolldown";
5162
5342
  import pc6 from "picocolors";
@@ -5164,7 +5344,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
5164
5344
  const config = environment.config;
5165
5345
  const envOptions = environment.options;
5166
5346
  const isServer = environment.consumer === "server";
5167
- const outDir = path13.resolve(config.root, envOptions.build.outDir);
5347
+ const outDir = path14.resolve(config.root, envOptions.build.outDir);
5168
5348
  const assetsDir = envOptions.build.assetsDir;
5169
5349
  const {
5170
5350
  output: userOutput,
@@ -5204,7 +5384,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
5204
5384
  // 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
5205
5385
  external: restInputOptions.external ?? ((id) => {
5206
5386
  if (NODE_BUILTINS2.has(id)) return true;
5207
- return !id.startsWith(".") && !path13.isAbsolute(id) && !id.startsWith("\0");
5387
+ return !id.startsWith(".") && !path14.isAbsolute(id) && !id.startsWith("\0");
5208
5388
  })
5209
5389
  } : {}
5210
5390
  };
@@ -5361,11 +5541,11 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5361
5541
  const protectedPaths = /* @__PURE__ */ new Set();
5362
5542
  const clientIsBuilt = buildableNames.includes("client");
5363
5543
  if (!clientIsBuilt && config.build.emptyOutDir) {
5364
- directories.add(path13.resolve(config.root, config.build.outDir));
5544
+ directories.add(path14.resolve(config.root, config.build.outDir));
5365
5545
  }
5366
5546
  for (const name of buildableNames) {
5367
5547
  const environment = config.environments[name];
5368
- const outDir = path13.resolve(config.root, environment.build.outDir);
5548
+ const outDir = path14.resolve(config.root, environment.build.outDir);
5369
5549
  if (!environment.build.emptyOutDir) {
5370
5550
  protectedPaths.add(outDir);
5371
5551
  continue;
@@ -5373,8 +5553,8 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5373
5553
  if (!environment.driver) directories.add(outDir);
5374
5554
  }
5375
5555
  const containsPath = (parent, child) => {
5376
- const relative = path13.relative(parent, child);
5377
- return relative === "" || !relative.startsWith("..") && !path13.isAbsolute(relative);
5556
+ const relative = path14.relative(parent, child);
5557
+ return relative === "" || !relative.startsWith("..") && !path14.isAbsolute(relative);
5378
5558
  };
5379
5559
  const roots = [...directories].filter(
5380
5560
  (directory) => ![...protectedPaths].some((protectedPath) => containsPath(directory, protectedPath))
@@ -5382,7 +5562,7 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5382
5562
  (directory, index2, all) => !all.slice(0, index2).some((parent) => containsPath(parent, directory))
5383
5563
  );
5384
5564
  for (const directory of roots) {
5385
- if (fs10.existsSync(directory)) fs10.rmSync(directory, { recursive: true, force: true });
5565
+ if (fs11.existsSync(directory)) fs11.rmSync(directory, { recursive: true, force: true });
5386
5566
  }
5387
5567
  }
5388
5568
  function assertDriverBuildResult(environment, result) {
@@ -5401,7 +5581,7 @@ function resolveClientEntries(config, html) {
5401
5581
  if (configuredEntries.length > 0) return configuredEntries;
5402
5582
  const entryPoints = [];
5403
5583
  const htmlFile = config.environments.client?.html;
5404
- const htmlDir = htmlFile ? path13.dirname(htmlFile) : config.root;
5584
+ const htmlDir = htmlFile ? path14.dirname(htmlFile) : config.root;
5405
5585
  if (html) {
5406
5586
  const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
5407
5587
  for (const match of scriptMatches) {
@@ -5409,7 +5589,7 @@ function resolveClientEntries(config, html) {
5409
5589
  if (src && !src.startsWith("http")) {
5410
5590
  const cleanSrc = src.split(/[?#]/, 1)[0];
5411
5591
  entryPoints.push(
5412
- cleanSrc.startsWith("/") ? path13.resolve(config.root, cleanSrc.replace(/^\//, "")) : path13.resolve(htmlDir, cleanSrc)
5592
+ cleanSrc.startsWith("/") ? path14.resolve(config.root, cleanSrc.replace(/^\//, "")) : path14.resolve(htmlDir, cleanSrc)
5413
5593
  );
5414
5594
  }
5415
5595
  }
@@ -5417,8 +5597,8 @@ function resolveClientEntries(config, html) {
5417
5597
  if (entryPoints.length === 0) {
5418
5598
  const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
5419
5599
  for (const entry of fallbackEntries) {
5420
- const fullPath = path13.resolve(config.root, entry);
5421
- if (fs10.existsSync(fullPath)) {
5600
+ const fullPath = path14.resolve(config.root, entry);
5601
+ if (fs11.existsSync(fullPath)) {
5422
5602
  entryPoints.push(fullPath);
5423
5603
  break;
5424
5604
  }
@@ -5447,7 +5627,7 @@ async function build(inlineConfig = {}) {
5447
5627
  const startTime = performance.now();
5448
5628
  logger.info(
5449
5629
  pc6.cyan(`
5450
- nasti v${"2.4.3"} `) + pc6.green(`building for ${config.mode}...`)
5630
+ nasti v${"2.4.4"} `) + pc6.green(`building for ${config.mode}...`)
5451
5631
  );
5452
5632
  debug6?.(`root: ${config.root}`);
5453
5633
  const buildableNames = Object.keys(config.environments).filter((name) => {
@@ -5522,7 +5702,7 @@ nasti v${"2.4.3"} `) + pc6.green(`building for ${config.mode}...`)
5522
5702
  }
5523
5703
  async function buildClientEnvironment(config) {
5524
5704
  const logger = config.logger;
5525
- const outDir = path13.resolve(config.root, config.build.outDir);
5705
+ const outDir = path14.resolve(config.root, config.build.outDir);
5526
5706
  const cssEngine = createCssEngine();
5527
5707
  const pluginList = resolvePluginList(config, config.plugins, {
5528
5708
  cssEngine,
@@ -5545,8 +5725,8 @@ async function buildClientEnvironment(config) {
5545
5725
  assertDriverBuildResult(clientEnv, result);
5546
5726
  return { environment: clientEnv, result: finalizeEnvironmentResult(clientEnv, result) };
5547
5727
  }
5548
- fs10.mkdirSync(outDir, { recursive: true });
5549
- const htmlFile = config.environments.client.html ?? path13.resolve(config.root, "index.html");
5728
+ fs11.mkdirSync(outDir, { recursive: true });
5729
+ const htmlFile = config.environments.client.html ?? path14.resolve(config.root, "index.html");
5550
5730
  const html = await readHtmlFile(config.root, htmlFile);
5551
5731
  const entryPoints = resolveClientEntries(config, html);
5552
5732
  if (entryPoints.length === 0) {
@@ -5596,7 +5776,7 @@ async function buildClientEnvironment(config) {
5596
5776
  );
5597
5777
  }
5598
5778
  }
5599
- fs10.writeFileSync(path13.resolve(outDir, "index.html"), processedHtml);
5779
+ fs11.writeFileSync(path14.resolve(outDir, "index.html"), processedHtml);
5600
5780
  }
5601
5781
  if (!nativeReporter && config.logLevel !== "silent") {
5602
5782
  reportBuildOutput(output, config, logger);
@@ -5650,7 +5830,7 @@ async function buildServerEnvironment(config, name) {
5650
5830
  }
5651
5831
  }
5652
5832
  for (const entry of envOptions.entry) {
5653
- if (!fs10.existsSync(entry)) {
5833
+ if (!fs11.existsSync(entry)) {
5654
5834
  await environment.close();
5655
5835
  throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
5656
5836
  }
@@ -5664,13 +5844,13 @@ async function buildServerEnvironment(config, name) {
5664
5844
  envOptions.entry,
5665
5845
  rolldownPlugins
5666
5846
  );
5667
- fs10.mkdirSync(outDir, { recursive: true });
5847
+ fs11.mkdirSync(outDir, { recursive: true });
5668
5848
  const bundle2 = await rolldown(inputOptions);
5669
5849
  const { output } = await bundle2.write(outputOptions);
5670
5850
  await bundle2.close();
5671
5851
  if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
5672
5852
  logger.info(
5673
- pc6.dim(` [${name}] `) + output.map((o) => path13.join(envOptions.build.outDir, o.fileName)).join(pc6.dim(", "))
5853
+ pc6.dim(` [${name}] `) + output.map((o) => path14.join(envOptions.build.outDir, o.fileName)).join(pc6.dim(", "))
5674
5854
  );
5675
5855
  return {
5676
5856
  environment,
@@ -5702,9 +5882,9 @@ function escapeRegExp(string) {
5702
5882
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5703
5883
  }
5704
5884
  function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, urlPrefix) {
5705
- const rootRelative = path13.relative(config.root, facadeModuleId).split(path13.sep).join("/");
5706
- const resolvedHtmlFile = path13.resolve(config.root, htmlFile);
5707
- const htmlRelative = path13.relative(path13.dirname(resolvedHtmlFile), facadeModuleId).split(path13.sep).join("/");
5885
+ const rootRelative = path14.relative(config.root, facadeModuleId).split(path14.sep).join("/");
5886
+ const resolvedHtmlFile = path14.resolve(config.root, htmlFile);
5887
+ const htmlRelative = path14.relative(path14.dirname(resolvedHtmlFile), facadeModuleId).split(path14.sep).join("/");
5708
5888
  const candidates = /* @__PURE__ */ new Set([
5709
5889
  rootRelative,
5710
5890
  `/${rootRelative}`,
@@ -5745,7 +5925,7 @@ var dev_engine_exports = {};
5745
5925
  __export(dev_engine_exports, {
5746
5926
  createBundledDevServer: () => createBundledDevServer
5747
5927
  });
5748
- import path14 from "path";
5928
+ import path15 from "path";
5749
5929
  import crypto3 from "crypto";
5750
5930
  import { WebSocketServer as WsServer2 } from "ws";
5751
5931
  import pc7 from "picocolors";
@@ -5830,7 +6010,7 @@ async function createBundledDevServer(opts) {
5830
6010
  }
5831
6011
  const url = `/${patchPath}`;
5832
6012
  logger.info(
5833
- pc7.green("hmr update ") + pc7.dim(changedFiles.map((f) => path14.relative(config.root, f)).join(", ")),
6013
+ pc7.green("hmr update ") + pc7.dim(changedFiles.map((f) => path15.relative(config.root, f)).join(", ")),
5834
6014
  { timestamp: true }
5835
6015
  );
5836
6016
  sendTo(clientId, { type: "hmr:update", path: url, url });
@@ -5985,7 +6165,7 @@ async function createBundledDevServer(opts) {
5985
6165
  return;
5986
6166
  }
5987
6167
  res.setHeader("ETag", hit.etag);
5988
- res.setHeader("Content-Type", MIME_TYPES[path14.extname(fileName)] ?? "application/octet-stream");
6168
+ res.setHeader("Content-Type", MIME_TYPES[path15.extname(fileName)] ?? "application/octet-stream");
5989
6169
  res.setHeader("Cache-Control", "no-cache");
5990
6170
  res.once("finish", () => {
5991
6171
  void engine.notifyPayloadDelivered(fileName).catch(
@@ -6026,7 +6206,7 @@ function stripCatchAllLoad(plugins) {
6026
6206
  );
6027
6207
  }
6028
6208
  function createReactRefreshRuntimePlugin(entryPoints) {
6029
- const entryIds = new Set(entryPoints.map((p) => path14.resolve(p)));
6209
+ const entryIds = new Set(entryPoints.map((p) => path15.resolve(p)));
6030
6210
  return {
6031
6211
  name: "nasti:bundled-react-refresh",
6032
6212
  resolveId(source) {
@@ -6044,7 +6224,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
6044
6224
  return null;
6045
6225
  },
6046
6226
  transform(code, id) {
6047
- if (!entryIds.has(path14.resolve(id.split("?")[0]))) return null;
6227
+ if (!entryIds.has(path15.resolve(id.split("?")[0]))) return null;
6048
6228
  return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
6049
6229
  ${code}`, map: null };
6050
6230
  }
@@ -6215,7 +6395,7 @@ __export(server_exports, {
6215
6395
  createServer: () => createServer
6216
6396
  });
6217
6397
  import http from "http";
6218
- import path15 from "path";
6398
+ import path16 from "path";
6219
6399
  import os from "os";
6220
6400
  import connect from "connect";
6221
6401
  import sirv from "sirv";
@@ -6308,20 +6488,39 @@ async function createServer(inlineConfig = {}) {
6308
6488
  app.use(bundledServer.middleware);
6309
6489
  }
6310
6490
  const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
6311
- const outDirAbs = path15.resolve(config.root, config.build.outDir);
6312
- const watcher = watch(config.root, {
6491
+ const outDirAbs = path16.resolve(config.root, config.build.outDir);
6492
+ const linkedPackageRoots = getLinkedPackageRoots(config.root).filter(
6493
+ (r) => r !== config.root && !isUnderRoot(config.root, r)
6494
+ );
6495
+ const watchTargets = [config.root, ...linkedPackageRoots];
6496
+ const watcher = watch(watchTargets, {
6313
6497
  ignored: (filePath) => {
6314
- if (filePath === config.root) return false;
6315
- if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path15.sep)) return true;
6316
- const rel = path15.relative(config.root, filePath);
6317
- if (!rel || rel.startsWith("..") || path15.isAbsolute(rel)) return false;
6318
- for (const seg of rel.split(path15.sep)) {
6319
- if (ignoredSegments.has(seg)) return true;
6498
+ if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path16.sep)) return true;
6499
+ for (const watchRoot of watchTargets) {
6500
+ if (filePath === watchRoot) return false;
6501
+ const rel = path16.relative(watchRoot, filePath);
6502
+ if (!rel || rel.startsWith("..") || path16.isAbsolute(rel)) continue;
6503
+ for (const seg of rel.split(path16.sep)) {
6504
+ if (ignoredSegments.has(seg)) return true;
6505
+ }
6506
+ return false;
6320
6507
  }
6321
6508
  return false;
6322
6509
  },
6323
6510
  ignoreInitial: true
6324
6511
  });
6512
+ await new Promise((resolve, reject) => {
6513
+ const onReady = () => {
6514
+ watcher.off("error", onError);
6515
+ resolve();
6516
+ };
6517
+ const onError = (err) => {
6518
+ watcher.off("ready", onReady);
6519
+ reject(err);
6520
+ };
6521
+ watcher.once("ready", onReady);
6522
+ watcher.once("error", onError);
6523
+ });
6325
6524
  let server;
6326
6525
  const environmentServices = {};
6327
6526
  let environmentDriversStarted = false;
@@ -6433,16 +6632,25 @@ async function createServer(inlineConfig = {}) {
6433
6632
  });
6434
6633
  };
6435
6634
  watcher.on("change", (file) => {
6635
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6636
+ clearLinkedPackageRootsCache();
6637
+ }
6436
6638
  ssrRunner?.invalidateFile(file);
6437
6639
  queueClientEnvironmentUpdate(file);
6438
6640
  notifyEnvironmentDrivers(file, "change");
6439
6641
  });
6440
6642
  watcher.on("add", (file) => {
6643
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6644
+ clearLinkedPackageRootsCache();
6645
+ }
6441
6646
  ssrRunner?.invalidateFile(file);
6442
6647
  queueClientEnvironmentUpdate(file);
6443
6648
  notifyEnvironmentDrivers(file, "add");
6444
6649
  });
6445
6650
  watcher.on("unlink", (file) => {
6651
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6652
+ clearLinkedPackageRootsCache();
6653
+ }
6446
6654
  ssrRunner?.invalidateFile(file);
6447
6655
  notifyEnvironmentDrivers(file, "unlink");
6448
6656
  });
@@ -6472,7 +6680,7 @@ async function createServer(inlineConfig = {}) {
6472
6680
  const readyIn = Math.ceil(performance.now() - startTime);
6473
6681
  logger.info(
6474
6682
  `
6475
- ${pc8.cyan(pc8.bold("NASTI"))} ${pc8.cyan(`v${"2.4.3"}`)} ${pc8.dim("ready in")} ${pc8.bold(readyIn)} ${pc8.dim("ms")}
6683
+ ${pc8.cyan(pc8.bold("NASTI"))} ${pc8.cyan(`v${"2.4.4"}`)} ${pc8.dim("ready in")} ${pc8.bold(readyIn)} ${pc8.dim("ms")}
6476
6684
  `
6477
6685
  );
6478
6686
  printServerUrls(
@@ -6569,7 +6777,7 @@ async function createServer(inlineConfig = {}) {
6569
6777
  throw error;
6570
6778
  }
6571
6779
  app.use(transformMiddleware(transformContexts.get("client")));
6572
- const publicDir = path15.resolve(config.root, "public");
6780
+ const publicDir = path16.resolve(config.root, "public");
6573
6781
  app.use(sirv(publicDir, { dev: true, etag: true }));
6574
6782
  app.use(sirv(config.root, { dev: true, etag: true }));
6575
6783
  const postMiddlewares = [];
@@ -6608,6 +6816,7 @@ var init_server = __esm({
6608
6816
  init_builtins();
6609
6817
  init_plugin_api();
6610
6818
  init_env();
6819
+ init_fs_allow();
6611
6820
  }
6612
6821
  });
6613
6822
 
@@ -6658,24 +6867,25 @@ __export(electron_exports, {
6658
6867
  detectInstalledElectron: () => detectInstalledElectron,
6659
6868
  normalizePreload: () => normalizePreload
6660
6869
  });
6661
- import path16 from "path";
6662
- import fs11 from "fs";
6870
+ import path17 from "path";
6871
+ import fs12 from "fs";
6872
+ import { createRequire as createRequire5 } from "module";
6663
6873
  import { rolldown as rolldown2 } from "rolldown";
6664
6874
  import pc9 from "picocolors";
6665
6875
  async function buildElectron(inlineConfig = {}) {
6666
6876
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
6667
6877
  const startTime = performance.now();
6668
6878
  assertElectronVersion(config);
6669
- console.log(pc9.cyan("\n\u26A1 nasti build (electron)") + pc9.dim(` v${"2.4.3"}`));
6879
+ console.log(pc9.cyan("\n\u26A1 nasti build (electron)") + pc9.dim(` v${"2.4.4"}`));
6670
6880
  console.log(pc9.dim(` root: ${config.root}`));
6671
6881
  console.log(pc9.dim(` mode: ${config.mode}`));
6672
6882
  console.log(pc9.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
6673
- const outDir = path16.resolve(config.root, config.build.outDir);
6674
- if (config.build.emptyOutDir && fs11.existsSync(outDir)) {
6675
- fs11.rmSync(outDir, { recursive: true, force: true });
6883
+ const outDir = path17.resolve(config.root, config.build.outDir);
6884
+ if (config.build.emptyOutDir && fs12.existsSync(outDir)) {
6885
+ fs12.rmSync(outDir, { recursive: true, force: true });
6676
6886
  }
6677
- fs11.mkdirSync(outDir, { recursive: true });
6678
- const rendererOutDir = path16.join(outDir, "renderer");
6887
+ fs12.mkdirSync(outDir, { recursive: true });
6888
+ const rendererOutDir = path17.join(outDir, "renderer");
6679
6889
  const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
6680
6890
  await build2(createElectronRendererConfig(config, inlineConfig, {
6681
6891
  build: {
@@ -6684,8 +6894,8 @@ async function buildElectron(inlineConfig = {}) {
6684
6894
  emptyOutDir: false
6685
6895
  }
6686
6896
  }));
6687
- const mainEntry = path16.resolve(config.root, config.electron.main);
6688
- if (!fs11.existsSync(mainEntry)) {
6897
+ const mainEntry = path17.resolve(config.root, config.electron.main);
6898
+ if (!fs12.existsSync(mainEntry)) {
6689
6899
  throw new Error(
6690
6900
  `Electron main entry not found: ${config.electron.main}
6691
6901
  \u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
@@ -6699,11 +6909,11 @@ async function buildElectron(inlineConfig = {}) {
6699
6909
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
6700
6910
  const preloadFiles = [];
6701
6911
  for (const entry of preloadEntries) {
6702
- if (!fs11.existsSync(entry)) {
6912
+ if (!fs12.existsSync(entry)) {
6703
6913
  console.warn(pc9.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
6704
6914
  continue;
6705
6915
  }
6706
- const base = path16.basename(entry).replace(/\.[^.]+$/, "");
6916
+ const base = path17.basename(entry).replace(/\.[^.]+$/, "");
6707
6917
  const out = outFileName(outDir, base, config.electron.preloadFormat);
6708
6918
  await bundleNode(config, entry, {
6709
6919
  outFile: out,
@@ -6715,10 +6925,10 @@ async function buildElectron(inlineConfig = {}) {
6715
6925
  const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
6716
6926
  console.log(pc9.green(`
6717
6927
  \u2713 Electron build complete in ${elapsed}s`));
6718
- console.log(pc9.dim(` renderer: ${path16.relative(config.root, rendererOutDir)}/`));
6719
- console.log(pc9.dim(` main: ${path16.relative(config.root, mainFile)}`));
6928
+ console.log(pc9.dim(` renderer: ${path17.relative(config.root, rendererOutDir)}/`));
6929
+ console.log(pc9.dim(` main: ${path17.relative(config.root, mainFile)}`));
6720
6930
  for (const pf of preloadFiles) {
6721
- console.log(pc9.dim(` preload: ${path16.relative(config.root, pf)}`));
6931
+ console.log(pc9.dim(` preload: ${path17.relative(config.root, pf)}`));
6722
6932
  }
6723
6933
  console.log();
6724
6934
  return { rendererOutDir, mainFile, preloadFiles };
@@ -6756,7 +6966,7 @@ async function bundleNode(config, entry, opts) {
6756
6966
  },
6757
6967
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
6758
6968
  });
6759
- fs11.mkdirSync(path16.dirname(opts.outFile), { recursive: true });
6969
+ fs12.mkdirSync(path17.dirname(opts.outFile), { recursive: true });
6760
6970
  await bundle2.write({
6761
6971
  sourcemap: !!config.build.sourcemap,
6762
6972
  minify: !!config.build.minify,
@@ -6767,7 +6977,7 @@ async function bundleNode(config, entry, opts) {
6767
6977
  codeSplitting: false
6768
6978
  });
6769
6979
  await bundle2.close();
6770
- console.log(pc9.dim(` \u2713 ${opts.label} \u2192 ${path16.relative(config.root, opts.outFile)}`));
6980
+ console.log(pc9.dim(` \u2713 ${opts.label} \u2192 ${path17.relative(config.root, opts.outFile)}`));
6771
6981
  return opts.outFile;
6772
6982
  }
6773
6983
  function createElectronRendererConfig(config, inlineConfig = {}, overrides = {}) {
@@ -6791,11 +7001,11 @@ function createElectronRendererConfig(config, inlineConfig = {}, overrides = {})
6791
7001
  }
6792
7002
  function outFileName(outDir, base, format) {
6793
7003
  const ext = format === "cjs" ? ".cjs" : ".mjs";
6794
- return path16.join(outDir, base + ext);
7004
+ return path17.join(outDir, base + ext);
6795
7005
  }
6796
7006
  function normalizePreload(preload, root) {
6797
7007
  const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
6798
- return list.map((p) => path16.resolve(root, p));
7008
+ return list.map((p) => path17.resolve(root, p));
6799
7009
  }
6800
7010
  function assertElectronVersion(config) {
6801
7011
  const min = config.electron.minVersion;
@@ -6810,13 +7020,21 @@ function assertElectronVersion(config) {
6810
7020
  }
6811
7021
  function detectInstalledElectron(root) {
6812
7022
  try {
6813
- const pkgPath = path16.resolve(root, "node_modules/electron/package.json");
6814
- if (!fs11.existsSync(pkgPath)) return null;
6815
- const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf-8"));
7023
+ const require2 = createRequire5(path17.resolve(root, "package.json"));
7024
+ const pkgPath = require2.resolve("electron/package.json");
7025
+ const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
6816
7026
  const major = parseInt(String(pkg.version).split(".")[0], 10);
6817
7027
  return Number.isFinite(major) ? major : null;
6818
7028
  } catch {
6819
- return null;
7029
+ try {
7030
+ const pkgPath = path17.resolve(root, "node_modules/electron/package.json");
7031
+ if (!fs12.existsSync(pkgPath)) return null;
7032
+ const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
7033
+ const major = parseInt(String(pkg.version).split(".")[0], 10);
7034
+ return Number.isFinite(major) ? major : null;
7035
+ } catch {
7036
+ return null;
7037
+ }
6820
7038
  }
6821
7039
  }
6822
7040
  var init_electron2 = __esm({
@@ -6836,9 +7054,9 @@ __export(electron_dev_exports, {
6836
7054
  electronRendererDevPath: () => electronRendererDevPath,
6837
7055
  startElectronDev: () => startElectronDev
6838
7056
  });
6839
- import path17 from "path";
6840
- import fs12 from "fs";
6841
- import { createRequire as createRequire5 } from "module";
7057
+ import path18 from "path";
7058
+ import fs13 from "fs";
7059
+ import { createRequire as createRequire6 } from "module";
6842
7060
  import { spawn } from "child_process";
6843
7061
  import chokidar from "chokidar";
6844
7062
  import pc10 from "picocolors";
@@ -6847,7 +7065,7 @@ async function startElectronDev(inlineConfig = {}) {
6847
7065
  const { noSpawn, ...rest } = inlineConfig;
6848
7066
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
6849
7067
  warnElectronVersion(config);
6850
- console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.3"}`));
7068
+ console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.4"}`));
6851
7069
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
6852
7070
  const server = await createServer2({
6853
7071
  ...rest,
@@ -6857,11 +7075,11 @@ async function startElectronDev(inlineConfig = {}) {
6857
7075
  await server.listen();
6858
7076
  const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
6859
7077
  console.log(pc10.dim(` renderer: ${devUrl}`));
6860
- const stageDir = path17.resolve(config.root, ".nasti");
6861
- fs12.mkdirSync(stageDir, { recursive: true });
6862
- const mainEntry = path17.resolve(config.root, config.electron.main);
7078
+ const stageDir = path18.resolve(config.root, ".nasti");
7079
+ fs13.mkdirSync(stageDir, { recursive: true });
7080
+ const mainEntry = path18.resolve(config.root, config.electron.main);
6863
7081
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
6864
- const builtMainFile = path17.join(stageDir, "main" + extFor(config.electron.mainFormat));
7082
+ const builtMainFile = path18.join(stageDir, "main" + extFor(config.electron.mainFormat));
6865
7083
  const builtPreloadFiles = [];
6866
7084
  const compileAll = async () => {
6867
7085
  await compileNode(config, mainEntry, {
@@ -6871,9 +7089,9 @@ async function startElectronDev(inlineConfig = {}) {
6871
7089
  });
6872
7090
  builtPreloadFiles.length = 0;
6873
7091
  for (const entry of preloadEntries) {
6874
- if (!fs12.existsSync(entry)) continue;
6875
- const base = path17.basename(entry).replace(/\.[^.]+$/, "");
6876
- const out = path17.join(stageDir, base + extFor(config.electron.preloadFormat));
7092
+ if (!fs13.existsSync(entry)) continue;
7093
+ const base = path18.basename(entry).replace(/\.[^.]+$/, "");
7094
+ const out = path18.join(stageDir, base + extFor(config.electron.preloadFormat));
6877
7095
  await compileNode(config, entry, {
6878
7096
  outFile: out,
6879
7097
  format: config.electron.preloadFormat,
@@ -6912,7 +7130,7 @@ async function startElectronDev(inlineConfig = {}) {
6912
7130
  };
6913
7131
  spawnElectron();
6914
7132
  if (config.electron.autoRestart) {
6915
- const watchTargets = [mainEntry, ...preloadEntries].filter(fs12.existsSync);
7133
+ const watchTargets = [mainEntry, ...preloadEntries].filter(fs13.existsSync);
6916
7134
  const watcher = chokidar.watch(watchTargets, { ignoreInitial: true });
6917
7135
  let restarting = null;
6918
7136
  let pending = false;
@@ -6992,7 +7210,7 @@ async function compileNode(config, entry, opts) {
6992
7210
  platform: "node",
6993
7211
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
6994
7212
  });
6995
- fs12.mkdirSync(path17.dirname(opts.outFile), { recursive: true });
7213
+ fs13.mkdirSync(path18.dirname(opts.outFile), { recursive: true });
6996
7214
  await bundle2.write({
6997
7215
  file: opts.outFile,
6998
7216
  format: opts.format === "cjs" ? "cjs" : "esm",
@@ -7005,18 +7223,18 @@ async function compileNode(config, entry, opts) {
7005
7223
  await bundle2.close();
7006
7224
  }
7007
7225
  function electronRendererDevPath(renderer) {
7008
- const normalized = renderer.split(path17.sep).join("/").replace(/^\.?\//, "");
7226
+ const normalized = renderer.split(path18.sep).join("/").replace(/^\.?\//, "");
7009
7227
  return normalized === "index.html" ? "/" : `/${normalized}`;
7010
7228
  }
7011
7229
  function resolveElectronBinary(config) {
7012
- if (config.electron.electronPath && fs12.existsSync(config.electron.electronPath)) {
7230
+ if (config.electron.electronPath && fs13.existsSync(config.electron.electronPath)) {
7013
7231
  return config.electron.electronPath;
7014
7232
  }
7015
7233
  try {
7016
- const require2 = createRequire5(path17.resolve(config.root, "package.json"));
7234
+ const require2 = createRequire6(path18.resolve(config.root, "package.json"));
7017
7235
  const pathFile = require2.resolve("electron");
7018
7236
  const electronModule = require2(pathFile);
7019
- if (typeof electronModule === "string" && fs12.existsSync(electronModule)) {
7237
+ if (typeof electronModule === "string" && fs13.existsSync(electronModule)) {
7020
7238
  return electronModule;
7021
7239
  }
7022
7240
  } catch {
@@ -7191,20 +7409,20 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
7191
7409
  const logger = createCliLogger(options);
7192
7410
  try {
7193
7411
  const http2 = await import("http");
7194
- const path18 = await import("path");
7412
+ const path19 = await import("path");
7195
7413
  const os2 = await import("os");
7196
7414
  const sirv2 = (await import("sirv")).default;
7197
7415
  const connect2 = (await import("connect")).default;
7198
7416
  const { printServerUrls: printServerUrls2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
7199
- const resolvedRoot = path18.resolve(root ?? ".");
7200
- const outDir = path18.resolve(resolvedRoot, options.outDir);
7417
+ const resolvedRoot = path19.resolve(root ?? ".");
7418
+ const outDir = path19.resolve(resolvedRoot, options.outDir);
7201
7419
  const app = connect2();
7202
7420
  app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
7203
7421
  const port = options.port;
7204
7422
  const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
7205
7423
  http2.createServer(app).listen(port, host, () => {
7206
7424
  logger.info(`
7207
- ${pc11.cyan(pc11.bold("NASTI"))} ${pc11.cyan(`v${"2.4.3"}`)} ${pc11.dim("preview")}
7425
+ ${pc11.cyan(pc11.bold("NASTI"))} ${pc11.cyan(`v${"2.4.4"}`)} ${pc11.dim("preview")}
7208
7426
  `);
7209
7427
  printServerUrls2(
7210
7428
  {
@@ -7221,6 +7439,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
7221
7439
  }
7222
7440
  });
7223
7441
  cli.help();
7224
- cli.version("2.4.3");
7442
+ cli.version("2.4.4");
7225
7443
  cli.parse();
7226
7444
  //# sourceMappingURL=cli.js.map