@nasti-toolchain/nasti 2.4.2 → 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,
@@ -4354,8 +4534,10 @@ function vuePlugin(config, environmentName = "client") {
4354
4534
  });
4355
4535
  const scopeId = hashId(id);
4356
4536
  const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
4537
+ const vapor = resolveVaporMode(descriptor, vueOptions, sfc, config);
4357
4538
  let scriptCode = "";
4358
4539
  let scriptMap;
4540
+ let scriptBindings;
4359
4541
  if (descriptor.script || descriptor.scriptSetup) {
4360
4542
  const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
4361
4543
  const compiled = sfc.compileScript(descriptor, {
@@ -4367,9 +4549,11 @@ function vuePlugin(config, environmentName = "client") {
4367
4549
  // 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
4368
4550
  // 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
4369
4551
  // 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
4370
- genDefaultAs: "__sfc__"
4552
+ genDefaultAs: "__sfc__",
4553
+ vapor
4371
4554
  });
4372
4555
  scriptCode = compiled.content;
4556
+ scriptBindings = compiled.bindings;
4373
4557
  scriptMap = composeSourceMapChain(
4374
4558
  [compiled.map, transformedSfc.map],
4375
4559
  { filename: id, environmentName, type: "sfc" }
@@ -4383,7 +4567,9 @@ function vuePlugin(config, environmentName = "client") {
4383
4567
  }
4384
4568
  let templateCode = "";
4385
4569
  let templateMap;
4570
+ let templateMultiRoot;
4386
4571
  const scriptSetupIsInline = !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false;
4572
+ const isTemplateOnlyVapor = vapor && !descriptor.script && !descriptor.scriptSetup;
4387
4573
  if (descriptor.template && !scriptSetupIsInline) {
4388
4574
  const transformedTemplate = await applySourceTransform(
4389
4575
  vueOptions.transformTemplate,
@@ -4405,12 +4591,16 @@ function vuePlugin(config, environmentName = "client") {
4405
4591
  filename: id,
4406
4592
  id: scopeId,
4407
4593
  inMap: templateInputMap,
4594
+ vapor,
4408
4595
  compilerOptions: {
4409
4596
  ...customCompilerOptions,
4597
+ // Vapor 在 bindingMetadata 缺失时需要空对象(与 Vite / compiler-sfc 一致)
4598
+ bindingMetadata: customCompilerOptions.bindingMetadata ?? scriptBindings ?? (vapor ? {} : void 0),
4410
4599
  scopeId: `data-v-${scopeId}`
4411
4600
  }
4412
4601
  });
4413
4602
  templateCode = compiled.code;
4603
+ templateMultiRoot = compiled.multiRoot;
4414
4604
  if (wantsSourceMap || transformedTemplate.map != null) {
4415
4605
  templateMap = compiled.map;
4416
4606
  }
@@ -4448,12 +4638,20 @@ function vuePlugin(config, environmentName = "client") {
4448
4638
  outputNode.add(fragment);
4449
4639
  }
4450
4640
  };
4451
- append(scriptCode || "const __sfc__ = {}", scriptMap);
4641
+ append(
4642
+ scriptCode || (vapor ? "const __sfc__ = { __vapor: true }" : "const __sfc__ = {}"),
4643
+ scriptMap
4644
+ );
4452
4645
  if (templateCode) {
4453
4646
  append("\n");
4454
4647
  append(templateCode, templateMap);
4455
4648
  append("\n");
4456
4649
  append("\n__sfc__.render = render\n");
4650
+ if (isTemplateOnlyVapor && templateMultiRoot !== void 0) {
4651
+ append(`
4652
+ __sfc__.__multiRoot = ${JSON.stringify(templateMultiRoot)}
4653
+ `);
4654
+ }
4457
4655
  }
4458
4656
  if (descriptor.styles.length > 0) {
4459
4657
  for (let i = 0; i < descriptor.styles.length; i++) {
@@ -4462,6 +4660,16 @@ import "${id}?vue&type=style&index=${i}&lang.css"
4462
4660
  `);
4463
4661
  }
4464
4662
  }
4663
+ if (vapor) {
4664
+ append(
4665
+ `
4666
+ if (!globalThis.__NASTI_VAPOR_BETA_WARNED__) {
4667
+ globalThis.__NASTI_VAPOR_BETA_WARNED__ = true
4668
+ console.warn(${JSON.stringify(VAPOR_BETA_WARNING)})
4669
+ }
4670
+ `
4671
+ );
4672
+ }
4465
4673
  append(`
4466
4674
  __sfc__.__scopeId = "data-v-${scopeId}"
4467
4675
  `);
@@ -4521,6 +4729,32 @@ if (import.meta.hot) {
4521
4729
  }
4522
4730
  };
4523
4731
  }
4732
+ function resolveVaporMode(descriptor, vueOptions, sfc, config) {
4733
+ const requested = !!descriptor.vapor || !!vueOptions.features?.vapor && canForceVaporMode(descriptor);
4734
+ if (!requested) return false;
4735
+ if (!supportsVaporCompiler(sfc)) {
4736
+ config.logger.warnOnce(
4737
+ "[nasti:vue] Vapor Mode requires @vue/compiler-sfc >= 3.6. Install it: npm install @vue/compiler-sfc@^3.6.0-0"
4738
+ );
4739
+ return false;
4740
+ }
4741
+ config.logger.warnOnce(VAPOR_BETA_WARNING);
4742
+ return true;
4743
+ }
4744
+ function canForceVaporMode(descriptor) {
4745
+ if (typeof descriptor.filename === "string" && descriptor.filename.endsWith(".vue")) {
4746
+ if (descriptor.script && !descriptor.scriptSetup) return false;
4747
+ return !!(descriptor.scriptSetup || descriptor.template);
4748
+ }
4749
+ return true;
4750
+ }
4751
+ function supportsVaporCompiler(sfc) {
4752
+ const version = sfc.version;
4753
+ if (!version) return false;
4754
+ const [major, minor] = version.split(".").map((part) => Number.parseInt(part, 10));
4755
+ if (!Number.isFinite(major) || !Number.isFinite(minor)) return false;
4756
+ return major > 3 || major === 3 && minor >= 6;
4757
+ }
4524
4758
  async function applySourceTransform(transform2, source, context) {
4525
4759
  if (!transform2) return { code: source };
4526
4760
  const result = await transform2(source, context);
@@ -4581,7 +4815,7 @@ function warnUnchainableMap(context, reason) {
4581
4815
  function hashId(filename) {
4582
4816
  return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
4583
4817
  }
4584
- var VUE_FILE_RE, VUE_QUERY_RE, debug3, compiler;
4818
+ var VUE_FILE_RE, VUE_QUERY_RE, debug3, VAPOR_BETA_WARNING, compiler;
4585
4819
  var init_vue = __esm({
4586
4820
  "src/plugins/vue.ts"() {
4587
4821
  "use strict";
@@ -4590,6 +4824,7 @@ var init_vue = __esm({
4590
4824
  VUE_FILE_RE = /\.vue$/;
4591
4825
  VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
4592
4826
  debug3 = createDebugger("nasti:vue");
4827
+ VAPOR_BETA_WARNING = "Vapor Mode is a beta feature; Zixiao Labs and the Vue team do not provide guarantees against crashes in production environments, and it is not suitable for server-side rendering environments.";
4593
4828
  compiler = null;
4594
4829
  }
4595
4830
  });
@@ -4638,8 +4873,8 @@ __export(runnable_environment_exports, {
4638
4873
  NastiModuleRunner: () => NastiModuleRunner,
4639
4874
  createModuleRunner: () => createModuleRunner
4640
4875
  });
4641
- import path10 from "path";
4642
- import fs8 from "fs";
4876
+ import path11 from "path";
4877
+ import fs9 from "fs";
4643
4878
  import { builtinModules, createRequire as createRequire4 } from "module";
4644
4879
  import { pathToFileURL as pathToFileURL4 } from "url";
4645
4880
  function createModuleRunner(environment) {
@@ -4673,7 +4908,7 @@ var init_runnable_environment = __esm({
4673
4908
  this.config.mode,
4674
4909
  ssrDefineOverrides(environment.consumer)
4675
4910
  );
4676
- this.require = createRequire4(path10.join(this.config.root, "package.json"));
4911
+ this.require = createRequire4(path11.join(this.config.root, "package.json"));
4677
4912
  const handlers = {
4678
4913
  fetchModule: async (id, importer) => this.fetchModule(id, importer),
4679
4914
  getBuiltins: () => [/^node:/, ...builtinModules]
@@ -4697,9 +4932,9 @@ var init_runnable_environment = __esm({
4697
4932
  this.cache.clear();
4698
4933
  }
4699
4934
  resolveToId(rawUrl) {
4700
- if (path10.isAbsolute(rawUrl) && fs8.existsSync(rawUrl.split("?")[0])) return rawUrl;
4935
+ if (path11.isAbsolute(rawUrl) && fs9.existsSync(rawUrl.split("?")[0])) return rawUrl;
4701
4936
  const clean = rawUrl.replace(/^\//, "");
4702
- return path10.resolve(this.config.root, clean);
4937
+ return path11.resolve(this.config.root, clean);
4703
4938
  }
4704
4939
  /**
4705
4940
  * fetchModule(invoke 契约方法):环境管线产出 runner 可执行代码。
@@ -4708,14 +4943,14 @@ var init_runnable_environment = __esm({
4708
4943
  */
4709
4944
  async fetchModule(id, importer) {
4710
4945
  if (NODE_BUILTINS.has(id)) return { externalize: id };
4711
- if (!id.startsWith(".") && !path10.isAbsolute(id) && !id.startsWith("\0")) {
4946
+ if (!id.startsWith(".") && !path11.isAbsolute(id) && !id.startsWith("\0")) {
4712
4947
  return { externalize: id };
4713
4948
  }
4714
4949
  const container = this.environment.pluginContainer;
4715
4950
  let resolvedId = id;
4716
4951
  if (id.startsWith(".") && importer) {
4717
4952
  const resolved = await container.resolveId(id, importer);
4718
- 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);
4719
4954
  }
4720
4955
  resolvedId = this.completeExtension(resolvedId);
4721
4956
  const cleanId = resolvedId.split("?")[0];
@@ -4723,8 +4958,8 @@ var init_runnable_environment = __esm({
4723
4958
  const loaded = await container.load(resolvedId);
4724
4959
  if (loaded != null) {
4725
4960
  code = typeof loaded === "string" ? loaded : loaded.code;
4726
- } else if (fs8.existsSync(cleanId)) {
4727
- code = fs8.readFileSync(cleanId, "utf-8");
4961
+ } else if (fs9.existsSync(cleanId)) {
4962
+ code = fs9.readFileSync(cleanId, "utf-8");
4728
4963
  } else {
4729
4964
  throw new Error(`[nasti:ssr] cannot load module: ${resolvedId}`);
4730
4965
  }
@@ -4758,19 +4993,19 @@ var init_runnable_environment = __esm({
4758
4993
  completeExtension(id) {
4759
4994
  const clean = id.split("?")[0];
4760
4995
  const query = id.includes("?") ? id.slice(id.indexOf("?")) : "";
4761
- if (fs8.existsSync(clean) && fs8.statSync(clean).isFile()) return id;
4996
+ if (fs9.existsSync(clean) && fs9.statSync(clean).isFile()) return id;
4762
4997
  const jsMatch = clean.match(/^(.*)\.([mc]?)jsx?$/);
4763
4998
  if (jsMatch) {
4764
4999
  for (const tsExt of [`.${jsMatch[2]}ts`, `.${jsMatch[2]}tsx`]) {
4765
- if (fs8.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
5000
+ if (fs9.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
4766
5001
  }
4767
5002
  }
4768
5003
  for (const ext of this.config.resolve.extensions) {
4769
- if (fs8.existsSync(clean + ext)) return clean + ext + query;
5004
+ if (fs9.existsSync(clean + ext)) return clean + ext + query;
4770
5005
  }
4771
5006
  for (const ext of this.config.resolve.extensions) {
4772
- const indexPath = path10.join(clean, `index${ext}`);
4773
- if (fs8.existsSync(indexPath)) return indexPath;
5007
+ const indexPath = path11.join(clean, `index${ext}`);
5008
+ if (fs9.existsSync(indexPath)) return indexPath;
4774
5009
  }
4775
5010
  return id;
4776
5011
  }
@@ -4797,10 +5032,10 @@ var init_runnable_environment = __esm({
4797
5032
  return;
4798
5033
  }
4799
5034
  const ssrImport = async (dep) => {
4800
- 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")) {
4801
5036
  return this.importExternal(dep);
4802
5037
  }
4803
- 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);
4804
5039
  return this.instantiate(depId);
4805
5040
  };
4806
5041
  const ssrExportAll = (sourceModule) => {
@@ -4832,7 +5067,7 @@ var init_runnable_environment = __esm({
4832
5067
  }
4833
5068
  async importExternal(spec) {
4834
5069
  try {
4835
- 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));
4836
5071
  } catch (err) {
4837
5072
  throw new Error(`[nasti:ssr] failed to import external "${spec}": ${err.message}`);
4838
5073
  }
@@ -4854,7 +5089,7 @@ var init_runnable_environment = __esm({
4854
5089
  });
4855
5090
 
4856
5091
  // src/build/reporter.ts
4857
- import path11 from "path";
5092
+ import path12 from "path";
4858
5093
  import { gzipSync } from "zlib";
4859
5094
  import pc5 from "picocolors";
4860
5095
  async function tryNativeReporterPlugin(config, logger) {
@@ -4895,7 +5130,7 @@ function reportBuildOutput(output, config, logger) {
4895
5130
  if (compressed && content != null) {
4896
5131
  gzip = gzipSync(typeof content === "string" ? Buffer.from(content) : content).byteLength;
4897
5132
  }
4898
- const ext = path11.extname(file.fileName);
5133
+ const ext = path12.extname(file.fileName);
4899
5134
  const group = file.type === "chunk" ? "js" : ext === ".css" ? "css" : "assets";
4900
5135
  entries.push({ name: file.fileName, size, gzip, group });
4901
5136
  }
@@ -4943,12 +5178,12 @@ var init_reporter = __esm({
4943
5178
  });
4944
5179
 
4945
5180
  // src/core/build-app-context.ts
4946
- import fs9 from "fs";
4947
- import path12 from "path";
5181
+ import fs10 from "fs";
5182
+ import path13 from "path";
4948
5183
  function createBuildAppContext(config, results) {
4949
5184
  const output = [];
4950
5185
  const emitted = /* @__PURE__ */ new Set();
4951
- const outDir = path12.resolve(config.root, config.build.outDir);
5186
+ const outDir = path13.resolve(config.root, config.build.outDir);
4952
5187
  let environmentArtifacts;
4953
5188
  return {
4954
5189
  config,
@@ -5004,14 +5239,14 @@ function createBuildAppContext(config, results) {
5004
5239
  if (environmentArtifacts.has(collisionKey)) {
5005
5240
  throw new Error(`[nasti] app artifact conflicts with environment output: ${fileName}`);
5006
5241
  }
5007
- const target = path12.resolve(outDir, ...fileName.split("/"));
5008
- const relative = path12.relative(outDir, target);
5009
- 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)) {
5010
5245
  throw new Error(`[nasti] app artifact must stay inside build.outDir: ${file.fileName}`);
5011
5246
  }
5012
5247
  assertNoSymlinkComponents(outDir, fileName);
5013
- fs9.mkdirSync(path12.dirname(target), { recursive: true });
5014
- fs9.writeFileSync(target, file.source);
5248
+ fs10.mkdirSync(path13.dirname(target), { recursive: true });
5249
+ fs10.writeFileSync(target, file.source);
5015
5250
  const artifact = {
5016
5251
  ...file,
5017
5252
  fileName,
@@ -5027,10 +5262,10 @@ function joinPublicPath(base, fileName) {
5027
5262
  return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
5028
5263
  }
5029
5264
  function normalizeEnvironmentFileName(fileName) {
5030
- return path12.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
5265
+ return path13.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
5031
5266
  }
5032
5267
  function isInvalidEnvironmentFileName(fileName) {
5033
- 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);
5034
5269
  }
5035
5270
  function normalizeAppFileName(fileName) {
5036
5271
  const normalized = normalizeEnvironmentFileName(fileName);
@@ -5047,14 +5282,14 @@ function collectEnvironmentArtifacts(config, results, appOutDir) {
5047
5282
  for (const [environmentName, result] of Object.entries(results)) {
5048
5283
  const environment = config.environments[environmentName];
5049
5284
  if (!environment) continue;
5050
- const environmentOutDir = path12.resolve(config.root, environment.build.outDir);
5285
+ const environmentOutDir = path13.resolve(config.root, environment.build.outDir);
5051
5286
  for (const artifact of result.output) {
5052
- const artifactPath = path12.resolve(
5287
+ const artifactPath = path13.resolve(
5053
5288
  environmentOutDir,
5054
5289
  ...normalizeEnvironmentFileName(artifact.fileName).split("/")
5055
5290
  );
5056
- const relative = path12.relative(appOutDir, artifactPath);
5057
- if (!relative.startsWith("..") && !path12.isAbsolute(relative)) {
5291
+ const relative = path13.relative(appOutDir, artifactPath);
5292
+ if (!relative.startsWith("..") && !path13.isAbsolute(relative)) {
5058
5293
  occupied.add(artifactCollisionKey(relative));
5059
5294
  }
5060
5295
  }
@@ -5064,10 +5299,10 @@ function collectEnvironmentArtifacts(config, results, appOutDir) {
5064
5299
  function assertNoSymlinkComponents(outDir, fileName) {
5065
5300
  let current = outDir;
5066
5301
  for (const segment of fileName.split("/")) {
5067
- current = path12.join(current, segment);
5302
+ current = path13.join(current, segment);
5068
5303
  let stats;
5069
5304
  try {
5070
- stats = fs9.lstatSync(current);
5305
+ stats = fs10.lstatSync(current);
5071
5306
  } catch (error) {
5072
5307
  if (error.code === "ENOENT") continue;
5073
5308
  throw error;
@@ -5100,8 +5335,8 @@ __export(build_exports, {
5100
5335
  resolveClientEntries: () => resolveClientEntries,
5101
5336
  toRolldownPlugins: () => toRolldownPlugins
5102
5337
  });
5103
- import path13 from "path";
5104
- import fs10 from "fs";
5338
+ import path14 from "path";
5339
+ import fs11 from "fs";
5105
5340
  import { builtinModules as builtinModules2 } from "module";
5106
5341
  import { rolldown } from "rolldown";
5107
5342
  import pc6 from "picocolors";
@@ -5109,7 +5344,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
5109
5344
  const config = environment.config;
5110
5345
  const envOptions = environment.options;
5111
5346
  const isServer = environment.consumer === "server";
5112
- const outDir = path13.resolve(config.root, envOptions.build.outDir);
5347
+ const outDir = path14.resolve(config.root, envOptions.build.outDir);
5113
5348
  const assetsDir = envOptions.build.assetsDir;
5114
5349
  const {
5115
5350
  output: userOutput,
@@ -5149,7 +5384,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
5149
5384
  // 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
5150
5385
  external: restInputOptions.external ?? ((id) => {
5151
5386
  if (NODE_BUILTINS2.has(id)) return true;
5152
- return !id.startsWith(".") && !path13.isAbsolute(id) && !id.startsWith("\0");
5387
+ return !id.startsWith(".") && !path14.isAbsolute(id) && !id.startsWith("\0");
5153
5388
  })
5154
5389
  } : {}
5155
5390
  };
@@ -5306,11 +5541,11 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5306
5541
  const protectedPaths = /* @__PURE__ */ new Set();
5307
5542
  const clientIsBuilt = buildableNames.includes("client");
5308
5543
  if (!clientIsBuilt && config.build.emptyOutDir) {
5309
- directories.add(path13.resolve(config.root, config.build.outDir));
5544
+ directories.add(path14.resolve(config.root, config.build.outDir));
5310
5545
  }
5311
5546
  for (const name of buildableNames) {
5312
5547
  const environment = config.environments[name];
5313
- const outDir = path13.resolve(config.root, environment.build.outDir);
5548
+ const outDir = path14.resolve(config.root, environment.build.outDir);
5314
5549
  if (!environment.build.emptyOutDir) {
5315
5550
  protectedPaths.add(outDir);
5316
5551
  continue;
@@ -5318,8 +5553,8 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5318
5553
  if (!environment.driver) directories.add(outDir);
5319
5554
  }
5320
5555
  const containsPath = (parent, child) => {
5321
- const relative = path13.relative(parent, child);
5322
- return relative === "" || !relative.startsWith("..") && !path13.isAbsolute(relative);
5556
+ const relative = path14.relative(parent, child);
5557
+ return relative === "" || !relative.startsWith("..") && !path14.isAbsolute(relative);
5323
5558
  };
5324
5559
  const roots = [...directories].filter(
5325
5560
  (directory) => ![...protectedPaths].some((protectedPath) => containsPath(directory, protectedPath))
@@ -5327,7 +5562,7 @@ function prepareBuildOutputDirectories(config, buildableNames) {
5327
5562
  (directory, index2, all) => !all.slice(0, index2).some((parent) => containsPath(parent, directory))
5328
5563
  );
5329
5564
  for (const directory of roots) {
5330
- if (fs10.existsSync(directory)) fs10.rmSync(directory, { recursive: true, force: true });
5565
+ if (fs11.existsSync(directory)) fs11.rmSync(directory, { recursive: true, force: true });
5331
5566
  }
5332
5567
  }
5333
5568
  function assertDriverBuildResult(environment, result) {
@@ -5346,7 +5581,7 @@ function resolveClientEntries(config, html) {
5346
5581
  if (configuredEntries.length > 0) return configuredEntries;
5347
5582
  const entryPoints = [];
5348
5583
  const htmlFile = config.environments.client?.html;
5349
- const htmlDir = htmlFile ? path13.dirname(htmlFile) : config.root;
5584
+ const htmlDir = htmlFile ? path14.dirname(htmlFile) : config.root;
5350
5585
  if (html) {
5351
5586
  const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
5352
5587
  for (const match of scriptMatches) {
@@ -5354,7 +5589,7 @@ function resolveClientEntries(config, html) {
5354
5589
  if (src && !src.startsWith("http")) {
5355
5590
  const cleanSrc = src.split(/[?#]/, 1)[0];
5356
5591
  entryPoints.push(
5357
- 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)
5358
5593
  );
5359
5594
  }
5360
5595
  }
@@ -5362,8 +5597,8 @@ function resolveClientEntries(config, html) {
5362
5597
  if (entryPoints.length === 0) {
5363
5598
  const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
5364
5599
  for (const entry of fallbackEntries) {
5365
- const fullPath = path13.resolve(config.root, entry);
5366
- if (fs10.existsSync(fullPath)) {
5600
+ const fullPath = path14.resolve(config.root, entry);
5601
+ if (fs11.existsSync(fullPath)) {
5367
5602
  entryPoints.push(fullPath);
5368
5603
  break;
5369
5604
  }
@@ -5392,7 +5627,7 @@ async function build(inlineConfig = {}) {
5392
5627
  const startTime = performance.now();
5393
5628
  logger.info(
5394
5629
  pc6.cyan(`
5395
- nasti v${"2.4.2"} `) + pc6.green(`building for ${config.mode}...`)
5630
+ nasti v${"2.4.4"} `) + pc6.green(`building for ${config.mode}...`)
5396
5631
  );
5397
5632
  debug6?.(`root: ${config.root}`);
5398
5633
  const buildableNames = Object.keys(config.environments).filter((name) => {
@@ -5467,7 +5702,7 @@ nasti v${"2.4.2"} `) + pc6.green(`building for ${config.mode}...`)
5467
5702
  }
5468
5703
  async function buildClientEnvironment(config) {
5469
5704
  const logger = config.logger;
5470
- const outDir = path13.resolve(config.root, config.build.outDir);
5705
+ const outDir = path14.resolve(config.root, config.build.outDir);
5471
5706
  const cssEngine = createCssEngine();
5472
5707
  const pluginList = resolvePluginList(config, config.plugins, {
5473
5708
  cssEngine,
@@ -5490,8 +5725,8 @@ async function buildClientEnvironment(config) {
5490
5725
  assertDriverBuildResult(clientEnv, result);
5491
5726
  return { environment: clientEnv, result: finalizeEnvironmentResult(clientEnv, result) };
5492
5727
  }
5493
- fs10.mkdirSync(outDir, { recursive: true });
5494
- 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");
5495
5730
  const html = await readHtmlFile(config.root, htmlFile);
5496
5731
  const entryPoints = resolveClientEntries(config, html);
5497
5732
  if (entryPoints.length === 0) {
@@ -5541,7 +5776,7 @@ async function buildClientEnvironment(config) {
5541
5776
  );
5542
5777
  }
5543
5778
  }
5544
- fs10.writeFileSync(path13.resolve(outDir, "index.html"), processedHtml);
5779
+ fs11.writeFileSync(path14.resolve(outDir, "index.html"), processedHtml);
5545
5780
  }
5546
5781
  if (!nativeReporter && config.logLevel !== "silent") {
5547
5782
  reportBuildOutput(output, config, logger);
@@ -5595,7 +5830,7 @@ async function buildServerEnvironment(config, name) {
5595
5830
  }
5596
5831
  }
5597
5832
  for (const entry of envOptions.entry) {
5598
- if (!fs10.existsSync(entry)) {
5833
+ if (!fs11.existsSync(entry)) {
5599
5834
  await environment.close();
5600
5835
  throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
5601
5836
  }
@@ -5609,13 +5844,13 @@ async function buildServerEnvironment(config, name) {
5609
5844
  envOptions.entry,
5610
5845
  rolldownPlugins
5611
5846
  );
5612
- fs10.mkdirSync(outDir, { recursive: true });
5847
+ fs11.mkdirSync(outDir, { recursive: true });
5613
5848
  const bundle2 = await rolldown(inputOptions);
5614
5849
  const { output } = await bundle2.write(outputOptions);
5615
5850
  await bundle2.close();
5616
5851
  if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
5617
5852
  logger.info(
5618
- 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(", "))
5619
5854
  );
5620
5855
  return {
5621
5856
  environment,
@@ -5647,9 +5882,9 @@ function escapeRegExp(string) {
5647
5882
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5648
5883
  }
5649
5884
  function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, urlPrefix) {
5650
- const rootRelative = path13.relative(config.root, facadeModuleId).split(path13.sep).join("/");
5651
- const resolvedHtmlFile = path13.resolve(config.root, htmlFile);
5652
- 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("/");
5653
5888
  const candidates = /* @__PURE__ */ new Set([
5654
5889
  rootRelative,
5655
5890
  `/${rootRelative}`,
@@ -5690,7 +5925,7 @@ var dev_engine_exports = {};
5690
5925
  __export(dev_engine_exports, {
5691
5926
  createBundledDevServer: () => createBundledDevServer
5692
5927
  });
5693
- import path14 from "path";
5928
+ import path15 from "path";
5694
5929
  import crypto3 from "crypto";
5695
5930
  import { WebSocketServer as WsServer2 } from "ws";
5696
5931
  import pc7 from "picocolors";
@@ -5775,7 +6010,7 @@ async function createBundledDevServer(opts) {
5775
6010
  }
5776
6011
  const url = `/${patchPath}`;
5777
6012
  logger.info(
5778
- 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(", ")),
5779
6014
  { timestamp: true }
5780
6015
  );
5781
6016
  sendTo(clientId, { type: "hmr:update", path: url, url });
@@ -5930,7 +6165,7 @@ async function createBundledDevServer(opts) {
5930
6165
  return;
5931
6166
  }
5932
6167
  res.setHeader("ETag", hit.etag);
5933
- 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");
5934
6169
  res.setHeader("Cache-Control", "no-cache");
5935
6170
  res.once("finish", () => {
5936
6171
  void engine.notifyPayloadDelivered(fileName).catch(
@@ -5971,7 +6206,7 @@ function stripCatchAllLoad(plugins) {
5971
6206
  );
5972
6207
  }
5973
6208
  function createReactRefreshRuntimePlugin(entryPoints) {
5974
- const entryIds = new Set(entryPoints.map((p) => path14.resolve(p)));
6209
+ const entryIds = new Set(entryPoints.map((p) => path15.resolve(p)));
5975
6210
  return {
5976
6211
  name: "nasti:bundled-react-refresh",
5977
6212
  resolveId(source) {
@@ -5989,7 +6224,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
5989
6224
  return null;
5990
6225
  },
5991
6226
  transform(code, id) {
5992
- if (!entryIds.has(path14.resolve(id.split("?")[0]))) return null;
6227
+ if (!entryIds.has(path15.resolve(id.split("?")[0]))) return null;
5993
6228
  return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
5994
6229
  ${code}`, map: null };
5995
6230
  }
@@ -6160,7 +6395,7 @@ __export(server_exports, {
6160
6395
  createServer: () => createServer
6161
6396
  });
6162
6397
  import http from "http";
6163
- import path15 from "path";
6398
+ import path16 from "path";
6164
6399
  import os from "os";
6165
6400
  import connect from "connect";
6166
6401
  import sirv from "sirv";
@@ -6253,20 +6488,39 @@ async function createServer(inlineConfig = {}) {
6253
6488
  app.use(bundledServer.middleware);
6254
6489
  }
6255
6490
  const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
6256
- const outDirAbs = path15.resolve(config.root, config.build.outDir);
6257
- 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, {
6258
6497
  ignored: (filePath) => {
6259
- if (filePath === config.root) return false;
6260
- if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path15.sep)) return true;
6261
- const rel = path15.relative(config.root, filePath);
6262
- if (!rel || rel.startsWith("..") || path15.isAbsolute(rel)) return false;
6263
- for (const seg of rel.split(path15.sep)) {
6264
- 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;
6265
6507
  }
6266
6508
  return false;
6267
6509
  },
6268
6510
  ignoreInitial: true
6269
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
+ });
6270
6524
  let server;
6271
6525
  const environmentServices = {};
6272
6526
  let environmentDriversStarted = false;
@@ -6378,16 +6632,25 @@ async function createServer(inlineConfig = {}) {
6378
6632
  });
6379
6633
  };
6380
6634
  watcher.on("change", (file) => {
6635
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6636
+ clearLinkedPackageRootsCache();
6637
+ }
6381
6638
  ssrRunner?.invalidateFile(file);
6382
6639
  queueClientEnvironmentUpdate(file);
6383
6640
  notifyEnvironmentDrivers(file, "change");
6384
6641
  });
6385
6642
  watcher.on("add", (file) => {
6643
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6644
+ clearLinkedPackageRootsCache();
6645
+ }
6386
6646
  ssrRunner?.invalidateFile(file);
6387
6647
  queueClientEnvironmentUpdate(file);
6388
6648
  notifyEnvironmentDrivers(file, "add");
6389
6649
  });
6390
6650
  watcher.on("unlink", (file) => {
6651
+ if (file.includes(`${path16.sep}node_modules${path16.sep}`) || file.endsWith(`${path16.sep}node_modules`)) {
6652
+ clearLinkedPackageRootsCache();
6653
+ }
6391
6654
  ssrRunner?.invalidateFile(file);
6392
6655
  notifyEnvironmentDrivers(file, "unlink");
6393
6656
  });
@@ -6417,7 +6680,7 @@ async function createServer(inlineConfig = {}) {
6417
6680
  const readyIn = Math.ceil(performance.now() - startTime);
6418
6681
  logger.info(
6419
6682
  `
6420
- ${pc8.cyan(pc8.bold("NASTI"))} ${pc8.cyan(`v${"2.4.2"}`)} ${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")}
6421
6684
  `
6422
6685
  );
6423
6686
  printServerUrls(
@@ -6514,7 +6777,7 @@ async function createServer(inlineConfig = {}) {
6514
6777
  throw error;
6515
6778
  }
6516
6779
  app.use(transformMiddleware(transformContexts.get("client")));
6517
- const publicDir = path15.resolve(config.root, "public");
6780
+ const publicDir = path16.resolve(config.root, "public");
6518
6781
  app.use(sirv(publicDir, { dev: true, etag: true }));
6519
6782
  app.use(sirv(config.root, { dev: true, etag: true }));
6520
6783
  const postMiddlewares = [];
@@ -6553,6 +6816,7 @@ var init_server = __esm({
6553
6816
  init_builtins();
6554
6817
  init_plugin_api();
6555
6818
  init_env();
6819
+ init_fs_allow();
6556
6820
  }
6557
6821
  });
6558
6822
 
@@ -6603,24 +6867,25 @@ __export(electron_exports, {
6603
6867
  detectInstalledElectron: () => detectInstalledElectron,
6604
6868
  normalizePreload: () => normalizePreload
6605
6869
  });
6606
- import path16 from "path";
6607
- import fs11 from "fs";
6870
+ import path17 from "path";
6871
+ import fs12 from "fs";
6872
+ import { createRequire as createRequire5 } from "module";
6608
6873
  import { rolldown as rolldown2 } from "rolldown";
6609
6874
  import pc9 from "picocolors";
6610
6875
  async function buildElectron(inlineConfig = {}) {
6611
6876
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
6612
6877
  const startTime = performance.now();
6613
6878
  assertElectronVersion(config);
6614
- console.log(pc9.cyan("\n\u26A1 nasti build (electron)") + pc9.dim(` v${"2.4.2"}`));
6879
+ console.log(pc9.cyan("\n\u26A1 nasti build (electron)") + pc9.dim(` v${"2.4.4"}`));
6615
6880
  console.log(pc9.dim(` root: ${config.root}`));
6616
6881
  console.log(pc9.dim(` mode: ${config.mode}`));
6617
6882
  console.log(pc9.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
6618
- const outDir = path16.resolve(config.root, config.build.outDir);
6619
- if (config.build.emptyOutDir && fs11.existsSync(outDir)) {
6620
- 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 });
6621
6886
  }
6622
- fs11.mkdirSync(outDir, { recursive: true });
6623
- const rendererOutDir = path16.join(outDir, "renderer");
6887
+ fs12.mkdirSync(outDir, { recursive: true });
6888
+ const rendererOutDir = path17.join(outDir, "renderer");
6624
6889
  const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
6625
6890
  await build2(createElectronRendererConfig(config, inlineConfig, {
6626
6891
  build: {
@@ -6629,8 +6894,8 @@ async function buildElectron(inlineConfig = {}) {
6629
6894
  emptyOutDir: false
6630
6895
  }
6631
6896
  }));
6632
- const mainEntry = path16.resolve(config.root, config.electron.main);
6633
- if (!fs11.existsSync(mainEntry)) {
6897
+ const mainEntry = path17.resolve(config.root, config.electron.main);
6898
+ if (!fs12.existsSync(mainEntry)) {
6634
6899
  throw new Error(
6635
6900
  `Electron main entry not found: ${config.electron.main}
6636
6901
  \u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
@@ -6644,11 +6909,11 @@ async function buildElectron(inlineConfig = {}) {
6644
6909
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
6645
6910
  const preloadFiles = [];
6646
6911
  for (const entry of preloadEntries) {
6647
- if (!fs11.existsSync(entry)) {
6912
+ if (!fs12.existsSync(entry)) {
6648
6913
  console.warn(pc9.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
6649
6914
  continue;
6650
6915
  }
6651
- const base = path16.basename(entry).replace(/\.[^.]+$/, "");
6916
+ const base = path17.basename(entry).replace(/\.[^.]+$/, "");
6652
6917
  const out = outFileName(outDir, base, config.electron.preloadFormat);
6653
6918
  await bundleNode(config, entry, {
6654
6919
  outFile: out,
@@ -6660,10 +6925,10 @@ async function buildElectron(inlineConfig = {}) {
6660
6925
  const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
6661
6926
  console.log(pc9.green(`
6662
6927
  \u2713 Electron build complete in ${elapsed}s`));
6663
- console.log(pc9.dim(` renderer: ${path16.relative(config.root, rendererOutDir)}/`));
6664
- 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)}`));
6665
6930
  for (const pf of preloadFiles) {
6666
- console.log(pc9.dim(` preload: ${path16.relative(config.root, pf)}`));
6931
+ console.log(pc9.dim(` preload: ${path17.relative(config.root, pf)}`));
6667
6932
  }
6668
6933
  console.log();
6669
6934
  return { rendererOutDir, mainFile, preloadFiles };
@@ -6701,7 +6966,7 @@ async function bundleNode(config, entry, opts) {
6701
6966
  },
6702
6967
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
6703
6968
  });
6704
- fs11.mkdirSync(path16.dirname(opts.outFile), { recursive: true });
6969
+ fs12.mkdirSync(path17.dirname(opts.outFile), { recursive: true });
6705
6970
  await bundle2.write({
6706
6971
  sourcemap: !!config.build.sourcemap,
6707
6972
  minify: !!config.build.minify,
@@ -6712,7 +6977,7 @@ async function bundleNode(config, entry, opts) {
6712
6977
  codeSplitting: false
6713
6978
  });
6714
6979
  await bundle2.close();
6715
- 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)}`));
6716
6981
  return opts.outFile;
6717
6982
  }
6718
6983
  function createElectronRendererConfig(config, inlineConfig = {}, overrides = {}) {
@@ -6736,11 +7001,11 @@ function createElectronRendererConfig(config, inlineConfig = {}, overrides = {})
6736
7001
  }
6737
7002
  function outFileName(outDir, base, format) {
6738
7003
  const ext = format === "cjs" ? ".cjs" : ".mjs";
6739
- return path16.join(outDir, base + ext);
7004
+ return path17.join(outDir, base + ext);
6740
7005
  }
6741
7006
  function normalizePreload(preload, root) {
6742
7007
  const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
6743
- return list.map((p) => path16.resolve(root, p));
7008
+ return list.map((p) => path17.resolve(root, p));
6744
7009
  }
6745
7010
  function assertElectronVersion(config) {
6746
7011
  const min = config.electron.minVersion;
@@ -6755,13 +7020,21 @@ function assertElectronVersion(config) {
6755
7020
  }
6756
7021
  function detectInstalledElectron(root) {
6757
7022
  try {
6758
- const pkgPath = path16.resolve(root, "node_modules/electron/package.json");
6759
- if (!fs11.existsSync(pkgPath)) return null;
6760
- 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"));
6761
7026
  const major = parseInt(String(pkg.version).split(".")[0], 10);
6762
7027
  return Number.isFinite(major) ? major : null;
6763
7028
  } catch {
6764
- 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
+ }
6765
7038
  }
6766
7039
  }
6767
7040
  var init_electron2 = __esm({
@@ -6781,9 +7054,9 @@ __export(electron_dev_exports, {
6781
7054
  electronRendererDevPath: () => electronRendererDevPath,
6782
7055
  startElectronDev: () => startElectronDev
6783
7056
  });
6784
- import path17 from "path";
6785
- import fs12 from "fs";
6786
- import { createRequire as createRequire5 } from "module";
7057
+ import path18 from "path";
7058
+ import fs13 from "fs";
7059
+ import { createRequire as createRequire6 } from "module";
6787
7060
  import { spawn } from "child_process";
6788
7061
  import chokidar from "chokidar";
6789
7062
  import pc10 from "picocolors";
@@ -6792,7 +7065,7 @@ async function startElectronDev(inlineConfig = {}) {
6792
7065
  const { noSpawn, ...rest } = inlineConfig;
6793
7066
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
6794
7067
  warnElectronVersion(config);
6795
- console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.2"}`));
7068
+ console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.4"}`));
6796
7069
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
6797
7070
  const server = await createServer2({
6798
7071
  ...rest,
@@ -6802,11 +7075,11 @@ async function startElectronDev(inlineConfig = {}) {
6802
7075
  await server.listen();
6803
7076
  const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
6804
7077
  console.log(pc10.dim(` renderer: ${devUrl}`));
6805
- const stageDir = path17.resolve(config.root, ".nasti");
6806
- fs12.mkdirSync(stageDir, { recursive: true });
6807
- 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);
6808
7081
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
6809
- const builtMainFile = path17.join(stageDir, "main" + extFor(config.electron.mainFormat));
7082
+ const builtMainFile = path18.join(stageDir, "main" + extFor(config.electron.mainFormat));
6810
7083
  const builtPreloadFiles = [];
6811
7084
  const compileAll = async () => {
6812
7085
  await compileNode(config, mainEntry, {
@@ -6816,9 +7089,9 @@ async function startElectronDev(inlineConfig = {}) {
6816
7089
  });
6817
7090
  builtPreloadFiles.length = 0;
6818
7091
  for (const entry of preloadEntries) {
6819
- if (!fs12.existsSync(entry)) continue;
6820
- const base = path17.basename(entry).replace(/\.[^.]+$/, "");
6821
- 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));
6822
7095
  await compileNode(config, entry, {
6823
7096
  outFile: out,
6824
7097
  format: config.electron.preloadFormat,
@@ -6857,7 +7130,7 @@ async function startElectronDev(inlineConfig = {}) {
6857
7130
  };
6858
7131
  spawnElectron();
6859
7132
  if (config.electron.autoRestart) {
6860
- const watchTargets = [mainEntry, ...preloadEntries].filter(fs12.existsSync);
7133
+ const watchTargets = [mainEntry, ...preloadEntries].filter(fs13.existsSync);
6861
7134
  const watcher = chokidar.watch(watchTargets, { ignoreInitial: true });
6862
7135
  let restarting = null;
6863
7136
  let pending = false;
@@ -6937,7 +7210,7 @@ async function compileNode(config, entry, opts) {
6937
7210
  platform: "node",
6938
7211
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
6939
7212
  });
6940
- fs12.mkdirSync(path17.dirname(opts.outFile), { recursive: true });
7213
+ fs13.mkdirSync(path18.dirname(opts.outFile), { recursive: true });
6941
7214
  await bundle2.write({
6942
7215
  file: opts.outFile,
6943
7216
  format: opts.format === "cjs" ? "cjs" : "esm",
@@ -6950,18 +7223,18 @@ async function compileNode(config, entry, opts) {
6950
7223
  await bundle2.close();
6951
7224
  }
6952
7225
  function electronRendererDevPath(renderer) {
6953
- const normalized = renderer.split(path17.sep).join("/").replace(/^\.?\//, "");
7226
+ const normalized = renderer.split(path18.sep).join("/").replace(/^\.?\//, "");
6954
7227
  return normalized === "index.html" ? "/" : `/${normalized}`;
6955
7228
  }
6956
7229
  function resolveElectronBinary(config) {
6957
- if (config.electron.electronPath && fs12.existsSync(config.electron.electronPath)) {
7230
+ if (config.electron.electronPath && fs13.existsSync(config.electron.electronPath)) {
6958
7231
  return config.electron.electronPath;
6959
7232
  }
6960
7233
  try {
6961
- const require2 = createRequire5(path17.resolve(config.root, "package.json"));
7234
+ const require2 = createRequire6(path18.resolve(config.root, "package.json"));
6962
7235
  const pathFile = require2.resolve("electron");
6963
7236
  const electronModule = require2(pathFile);
6964
- if (typeof electronModule === "string" && fs12.existsSync(electronModule)) {
7237
+ if (typeof electronModule === "string" && fs13.existsSync(electronModule)) {
6965
7238
  return electronModule;
6966
7239
  }
6967
7240
  } catch {
@@ -7136,20 +7409,20 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
7136
7409
  const logger = createCliLogger(options);
7137
7410
  try {
7138
7411
  const http2 = await import("http");
7139
- const path18 = await import("path");
7412
+ const path19 = await import("path");
7140
7413
  const os2 = await import("os");
7141
7414
  const sirv2 = (await import("sirv")).default;
7142
7415
  const connect2 = (await import("connect")).default;
7143
7416
  const { printServerUrls: printServerUrls2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
7144
- const resolvedRoot = path18.resolve(root ?? ".");
7145
- const outDir = path18.resolve(resolvedRoot, options.outDir);
7417
+ const resolvedRoot = path19.resolve(root ?? ".");
7418
+ const outDir = path19.resolve(resolvedRoot, options.outDir);
7146
7419
  const app = connect2();
7147
7420
  app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
7148
7421
  const port = options.port;
7149
7422
  const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
7150
7423
  http2.createServer(app).listen(port, host, () => {
7151
7424
  logger.info(`
7152
- ${pc11.cyan(pc11.bold("NASTI"))} ${pc11.cyan(`v${"2.4.2"}`)} ${pc11.dim("preview")}
7425
+ ${pc11.cyan(pc11.bold("NASTI"))} ${pc11.cyan(`v${"2.4.4"}`)} ${pc11.dim("preview")}
7153
7426
  `);
7154
7427
  printServerUrls2(
7155
7428
  {
@@ -7166,6 +7439,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
7166
7439
  }
7167
7440
  });
7168
7441
  cli.help();
7169
- cli.version("2.4.2");
7442
+ cli.version("2.4.4");
7170
7443
  cli.parse();
7171
7444
  //# sourceMappingURL=cli.js.map