@nasti-toolchain/nasti 1.6.3 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -353,8 +353,61 @@ var init_resolve = __esm({
353
353
  }
354
354
  });
355
355
 
356
- // src/plugins/css.ts
356
+ // src/plugins/tailwind.ts
357
357
  import path3 from "path";
358
+ import { createRequire as createRequire2 } from "module";
359
+ import { pathToFileURL as pathToFileURL2 } from "url";
360
+ function hasTailwindDirectives(css) {
361
+ const withoutBlockComments = css.replace(/\/\*[\s\S]*?\*\//g, "");
362
+ const withoutLineComments = withoutBlockComments.replace(/\/\/.*$/gm, "");
363
+ return TAILWIND_DIRECTIVE_RE.test(withoutLineComments);
364
+ }
365
+ async function loadTailwind(projectRoot) {
366
+ if (cached && cachedRoot === projectRoot) return cached;
367
+ const req = createRequire2(path3.join(projectRoot, "package.json"));
368
+ let nodePath;
369
+ let oxidePath;
370
+ try {
371
+ nodePath = req.resolve("@tailwindcss/node");
372
+ oxidePath = req.resolve("@tailwindcss/oxide");
373
+ } catch {
374
+ throw new Error(
375
+ "[nasti] CSS contains Tailwind v4 directives but `@tailwindcss/node` and/or `@tailwindcss/oxide` are not installed in this project. Install them with: npm i -D tailwindcss @tailwindcss/node @tailwindcss/oxide"
376
+ );
377
+ }
378
+ const node = await import(pathToFileURL2(nodePath).href);
379
+ const oxide = await import(pathToFileURL2(oxidePath).href);
380
+ cached = { node, oxide };
381
+ cachedRoot = projectRoot;
382
+ return cached;
383
+ }
384
+ async function compileTailwind(css, fromFile, projectRoot) {
385
+ const { node, oxide } = await loadTailwind(projectRoot);
386
+ const dependencies = [];
387
+ const compiler = await node.compile(css, {
388
+ base: path3.dirname(fromFile),
389
+ from: fromFile,
390
+ onDependency: (p) => dependencies.push(p)
391
+ });
392
+ const scanner = new oxide.Scanner({ sources: compiler.sources });
393
+ const candidates = scanner.scan();
394
+ return {
395
+ css: compiler.build(candidates),
396
+ dependencies: [...dependencies, ...scanner.files]
397
+ };
398
+ }
399
+ var TAILWIND_DIRECTIVE_RE, cached, cachedRoot;
400
+ var init_tailwind = __esm({
401
+ "src/plugins/tailwind.ts"() {
402
+ "use strict";
403
+ TAILWIND_DIRECTIVE_RE = /@(?:import\s+["']tailwindcss(?:\b|\/)|tailwind\b|theme\b|apply\b|plugin\b|source\b|utility\b|variant\b|custom-variant\b|reference\b)/;
404
+ cached = null;
405
+ cachedRoot = null;
406
+ }
407
+ });
408
+
409
+ // src/plugins/css.ts
410
+ import path4 from "path";
358
411
  function cssPlugin(config) {
359
412
  return {
360
413
  name: "nasti:css",
@@ -362,9 +415,14 @@ function cssPlugin(config) {
362
415
  if (source.endsWith(".css")) return null;
363
416
  return null;
364
417
  },
365
- transform(code, id) {
418
+ async transform(code, id) {
366
419
  if (!id.endsWith(".css")) return null;
367
- const rewritten = rewriteCssUrls(code, id, config.root);
420
+ let cssSource = code;
421
+ if (hasTailwindDirectives(code)) {
422
+ const compiled = await compileTailwind(code, id, config.root);
423
+ cssSource = compiled.css;
424
+ }
425
+ const rewritten = rewriteCssUrls(cssSource, id, config.root);
368
426
  if (config.command === "serve") {
369
427
  const escaped = JSON.stringify(rewritten);
370
428
  return {
@@ -399,19 +457,20 @@ function rewriteCssUrls(css, from, root) {
399
457
  if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
400
458
  return match;
401
459
  }
402
- const resolved = path3.resolve(path3.dirname(from), url);
403
- const relative = "/" + path3.relative(root, resolved);
460
+ const resolved = path4.resolve(path4.dirname(from), url);
461
+ const relative = "/" + path4.relative(root, resolved);
404
462
  return `url(${relative})`;
405
463
  });
406
464
  }
407
465
  var init_css = __esm({
408
466
  "src/plugins/css.ts"() {
409
467
  "use strict";
468
+ init_tailwind();
410
469
  }
411
470
  });
412
471
 
413
472
  // src/plugins/assets.ts
414
- import path4 from "path";
473
+ import path5 from "path";
415
474
  import fs3 from "fs";
416
475
  import crypto from "crypto";
417
476
  function assetsPlugin(config) {
@@ -424,7 +483,7 @@ function assetsPlugin(config) {
424
483
  return null;
425
484
  },
426
485
  load(id) {
427
- const ext = path4.extname(id.replace(/\?.*$/, ""));
486
+ const ext = path5.extname(id.replace(/\?.*$/, ""));
428
487
  if (id.endsWith("?raw")) {
429
488
  const file = id.slice(0, -4);
430
489
  if (fs3.existsSync(file)) {
@@ -436,12 +495,12 @@ function assetsPlugin(config) {
436
495
  const file = id.replace(/\?.*$/, "");
437
496
  if (!fs3.existsSync(file)) return null;
438
497
  if (config.command === "serve") {
439
- const url = "/" + path4.relative(config.root, file);
498
+ const url = "/" + path5.relative(config.root, file);
440
499
  return `export default ${JSON.stringify(url)}`;
441
500
  }
442
501
  const content = fs3.readFileSync(file);
443
502
  const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
444
- const basename = path4.basename(file, ext);
503
+ const basename = path5.basename(file, ext);
445
504
  const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
446
505
  return `export default ${JSON.stringify(config.base + hashedName)}`;
447
506
  }
@@ -481,7 +540,7 @@ var init_assets = __esm({
481
540
  });
482
541
 
483
542
  // src/plugins/html.ts
484
- import path5 from "path";
543
+ import path6 from "path";
485
544
  import fs4 from "fs";
486
545
  function htmlPlugin(config) {
487
546
  return {
@@ -545,7 +604,7 @@ function serializeTag(tag) {
545
604
  return ` <${tag.tag}${attrs}>${children}</${tag.tag}>`;
546
605
  }
547
606
  async function readHtmlFile(root) {
548
- const htmlPath = path5.resolve(root, "index.html");
607
+ const htmlPath = path6.resolve(root, "index.html");
549
608
  if (!fs4.existsSync(htmlPath)) return null;
550
609
  return fs4.readFileSync(htmlPath, "utf-8");
551
610
  }
@@ -601,7 +660,7 @@ var init_transformer = __esm({
601
660
  });
602
661
 
603
662
  // src/core/env.ts
604
- import path6 from "path";
663
+ import path7 from "path";
605
664
  import fs5 from "fs";
606
665
  function loadEnv(mode, root, prefixes) {
607
666
  const envFiles = [
@@ -612,7 +671,7 @@ function loadEnv(mode, root, prefixes) {
612
671
  ];
613
672
  const raw = {};
614
673
  for (const file of envFiles) {
615
- const filePath = path6.resolve(root, file);
674
+ const filePath = path7.resolve(root, file);
616
675
  if (!fs5.existsSync(filePath)) continue;
617
676
  const content = fs5.readFileSync(filePath, "utf-8");
618
677
  for (const line of content.split("\n")) {
@@ -786,17 +845,17 @@ var build_exports = {};
786
845
  __export(build_exports, {
787
846
  build: () => build
788
847
  });
789
- import path7 from "path";
848
+ import path8 from "path";
790
849
  import fs6 from "fs";
791
850
  import { rolldown } from "rolldown";
792
851
  import pc from "picocolors";
793
852
  async function build(inlineConfig = {}) {
794
853
  const config = await resolveConfig(inlineConfig, "build");
795
854
  const startTime = performance.now();
796
- console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.6.3"}`));
855
+ console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.6.4"}`));
797
856
  console.log(pc.dim(` root: ${config.root}`));
798
857
  console.log(pc.dim(` mode: ${config.mode}`));
799
- const outDir = path7.resolve(config.root, config.build.outDir);
858
+ const outDir = path8.resolve(config.root, config.build.outDir);
800
859
  if (config.build.emptyOutDir && fs6.existsSync(outDir)) {
801
860
  fs6.rmSync(outDir, { recursive: true, force: true });
802
861
  }
@@ -808,14 +867,14 @@ async function build(inlineConfig = {}) {
808
867
  for (const match of scriptMatches) {
809
868
  const src = match[1];
810
869
  if (src && !src.startsWith("http")) {
811
- entryPoints.push(path7.resolve(config.root, src.replace(/^\//, "")));
870
+ entryPoints.push(path8.resolve(config.root, src.replace(/^\//, "")));
812
871
  }
813
872
  }
814
873
  }
815
874
  if (entryPoints.length === 0) {
816
875
  const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
817
876
  for (const entry of fallbackEntries) {
818
- const fullPath = path7.resolve(config.root, entry);
877
+ const fullPath = path8.resolve(config.root, entry);
819
878
  if (fs6.existsSync(fullPath)) {
820
879
  entryPoints.push(fullPath);
821
880
  break;
@@ -880,8 +939,8 @@ async function build(inlineConfig = {}) {
880
939
  await bundle.close();
881
940
  await pluginContainer.buildEnd();
882
941
  for (const ef of pluginContainer.getEmittedFiles()) {
883
- const dest = path7.resolve(outDir, ef.fileName);
884
- fs6.mkdirSync(path7.dirname(dest), { recursive: true });
942
+ const dest = path8.resolve(outDir, ef.fileName);
943
+ fs6.mkdirSync(path8.dirname(dest), { recursive: true });
885
944
  fs6.writeFileSync(dest, ef.source);
886
945
  }
887
946
  if (html) {
@@ -899,14 +958,14 @@ async function build(inlineConfig = {}) {
899
958
  }
900
959
  for (const chunk of output) {
901
960
  if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
902
- const originalEntry = path7.relative(config.root, chunk.facadeModuleId);
961
+ const originalEntry = path8.relative(config.root, chunk.facadeModuleId);
903
962
  processedHtml = processedHtml.replace(
904
963
  new RegExp(`(src=["'])/?(${escapeRegExp(originalEntry)})(["'])`, "g"),
905
964
  `$1${config.base}${chunk.fileName}$3`
906
965
  );
907
966
  }
908
967
  }
909
- fs6.writeFileSync(path7.resolve(outDir, "index.html"), processedHtml);
968
+ fs6.writeFileSync(path8.resolve(outDir, "index.html"), processedHtml);
910
969
  }
911
970
  const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
912
971
  const totalSize = output.reduce((sum, chunk) => {
@@ -1118,18 +1177,18 @@ __export(middleware_exports, {
1118
1177
  transformMiddleware: () => transformMiddleware,
1119
1178
  transformRequest: () => transformRequest
1120
1179
  });
1121
- import path9 from "path";
1180
+ import path10 from "path";
1122
1181
  import fs8 from "fs";
1123
- import { createRequire as createRequire2 } from "module";
1124
- import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
1182
+ import { createRequire as createRequire3 } from "module";
1183
+ import { fileURLToPath, pathToFileURL as pathToFileURL3 } from "url";
1125
1184
  function getReactRefreshRuntimeEsm() {
1126
1185
  if (__refreshRuntimeCache) return __refreshRuntimeCache;
1127
1186
  let cjsPath;
1128
1187
  try {
1129
1188
  const pkgPath = __require.resolve("react-refresh/package.json");
1130
- cjsPath = path9.join(path9.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1189
+ cjsPath = path10.join(path10.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1131
1190
  } catch (err) {
1132
- cjsPath = path9.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1191
+ cjsPath = path10.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1133
1192
  if (!fs8.existsSync(cjsPath)) {
1134
1193
  const origMsg = err instanceof Error ? err.message : String(err);
1135
1194
  throw new Error(
@@ -1269,9 +1328,9 @@ function transformMiddleware(ctx) {
1269
1328
  async function transformRequest(url, ctx) {
1270
1329
  const { config, pluginContainer, moduleGraph } = ctx;
1271
1330
  const cleanReqUrl = url.split("?")[0];
1272
- const cached = moduleGraph.getModuleByUrl(url);
1273
- if (cached?.transformResult) {
1274
- return cached.transformResult;
1331
+ const cached2 = moduleGraph.getModuleByUrl(url);
1332
+ if (cached2?.transformResult) {
1333
+ return cached2.transformResult;
1275
1334
  }
1276
1335
  if (cleanReqUrl === "/@react-refresh") {
1277
1336
  return { code: getReactRefreshRuntimeEsm() };
@@ -1350,7 +1409,7 @@ async function loadVirtualModule(spec, ctx) {
1350
1409
  loadEnv(config.mode, config.root, config.envPrefix),
1351
1410
  config.mode
1352
1411
  ));
1353
- const anchor = path9.join(config.root, "__nasti_virtual__.ts");
1412
+ const anchor = path10.join(config.root, "__nasti_virtual__.ts");
1354
1413
  code = rewriteImports(code, config, anchor);
1355
1414
  return { id: resolvedId, result: { code } };
1356
1415
  }
@@ -1393,13 +1452,13 @@ async function doBundlePackage(entryFile) {
1393
1452
  return code;
1394
1453
  }
1395
1454
  async function tryGenerateSubpathShim(entryFile) {
1396
- const NM = `${path9.sep}node_modules${path9.sep}`;
1455
+ const NM = `${path10.sep}node_modules${path10.sep}`;
1397
1456
  if (!entryFile.includes(NM)) return null;
1398
1457
  let pkgDir = null;
1399
1458
  let pkgName = null;
1400
- let dir = path9.dirname(entryFile);
1459
+ let dir = path10.dirname(entryFile);
1401
1460
  while (true) {
1402
- const pkgJsonPath = path9.join(dir, "package.json");
1461
+ const pkgJsonPath = path10.join(dir, "package.json");
1403
1462
  if (fs8.existsSync(pkgJsonPath)) {
1404
1463
  try {
1405
1464
  const pkg = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
@@ -1411,21 +1470,21 @@ async function tryGenerateSubpathShim(entryFile) {
1411
1470
  } catch {
1412
1471
  }
1413
1472
  }
1414
- const parent = path9.dirname(dir);
1473
+ const parent = path10.dirname(dir);
1415
1474
  if (parent === dir) return null;
1416
1475
  dir = parent;
1417
1476
  if (!dir.includes(NM)) return null;
1418
1477
  }
1419
1478
  if (!pkgDir || !pkgName) return null;
1420
- const entryExt = path9.extname(entryFile);
1479
+ const entryExt = path10.extname(entryFile);
1421
1480
  const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
1422
1481
  if (!mainEntry) return null;
1423
- if (path9.resolve(mainEntry) === path9.resolve(entryFile)) return null;
1482
+ if (path10.resolve(mainEntry) === path10.resolve(entryFile)) return null;
1424
1483
  let mainNs;
1425
1484
  let subNs;
1426
1485
  try {
1427
- mainNs = await import(pathToFileURL2(mainEntry).href);
1428
- subNs = await import(pathToFileURL2(entryFile).href);
1486
+ mainNs = await import(pathToFileURL3(mainEntry).href);
1487
+ subNs = await import(pathToFileURL3(entryFile).href);
1429
1488
  } catch {
1430
1489
  return null;
1431
1490
  }
@@ -1456,7 +1515,7 @@ async function tryGenerateSubpathShim(entryFile) {
1456
1515
  return lines.join("\n") + "\n";
1457
1516
  }
1458
1517
  function pickMainEntryByExtension(pkgDir, preferredExt) {
1459
- const pkgJsonPath = path9.join(pkgDir, "package.json");
1518
+ const pkgJsonPath = path10.join(pkgDir, "package.json");
1460
1519
  let pkg;
1461
1520
  try {
1462
1521
  pkg = JSON.parse(fs8.readFileSync(pkgJsonPath, "utf-8"));
@@ -1478,13 +1537,13 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
1478
1537
  if (typeof pkg.module === "string") candidates.push(pkg.module);
1479
1538
  if (typeof pkg.main === "string") candidates.push(pkg.main);
1480
1539
  for (const cand of candidates) {
1481
- if (path9.extname(cand) === preferredExt) {
1482
- const full = path9.resolve(pkgDir, cand);
1540
+ if (path10.extname(cand) === preferredExt) {
1541
+ const full = path10.resolve(pkgDir, cand);
1483
1542
  if (fs8.existsSync(full)) return full;
1484
1543
  }
1485
1544
  }
1486
1545
  for (const cand of candidates) {
1487
- const full = path9.resolve(pkgDir, cand);
1546
+ const full = path10.resolve(pkgDir, cand);
1488
1547
  if (fs8.existsSync(full)) return full;
1489
1548
  }
1490
1549
  return null;
@@ -1510,19 +1569,20 @@ function rewriteExternalRequires(code) {
1510
1569
  }
1511
1570
  async function injectCjsNamedExports(code, entryFile) {
1512
1571
  try {
1513
- const { createRequire: createRequire5 } = await import("module");
1514
- const req = createRequire5(entryFile);
1572
+ const { createRequire: createRequire6 } = await import("module");
1573
+ const req = createRequire6(entryFile);
1515
1574
  const cjsExports = req(entryFile);
1516
1575
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
1517
1576
  const namedKeys = Object.keys(cjsExports).filter(
1518
1577
  (k) => k !== "__esModule" && k !== "default" && VALID_IDENT.test(k)
1519
1578
  );
1520
- if (namedKeys.length === 0) return code;
1579
+ const hasEsmInterop = cjsExports.__esModule === true && "default" in cjsExports;
1580
+ if (!hasEsmInterop && namedKeys.length === 0) return code;
1521
1581
  return code.replace(
1522
1582
  /^export default (\w+\(\));?\s*$/m,
1523
1583
  (_, call) => [
1524
1584
  `const __cjsMod = ${call};`,
1525
- `export default __cjsMod;`,
1585
+ hasEsmInterop ? `export default __cjsMod.default;` : `export default __cjsMod;`,
1526
1586
  ...namedKeys.map((k) => `export const ${k} = __cjsMod[${JSON.stringify(k)}];`)
1527
1587
  ].join("\n")
1528
1588
  );
@@ -1532,11 +1592,11 @@ async function injectCjsNamedExports(code, entryFile) {
1532
1592
  }
1533
1593
  function rewriteImports(code, config, filePath) {
1534
1594
  const root = config.root;
1535
- const fileDir = path9.dirname(filePath);
1595
+ const fileDir = path10.dirname(filePath);
1536
1596
  const aliasEntries = Object.entries(config.resolve.alias).sort(
1537
1597
  ([a], [b]) => b.length - a.length
1538
1598
  );
1539
- const toRootUrl = (abs) => "/" + path9.relative(root, abs).replace(/\\/g, "/");
1599
+ const toRootUrl = (abs) => "/" + path10.relative(root, abs).replace(/\\/g, "/");
1540
1600
  const transformSpec = (spec) => {
1541
1601
  const suffixMatch = spec.match(/[?#].*$/);
1542
1602
  const suffix = suffixMatch ? suffixMatch[0] : "";
@@ -1545,18 +1605,18 @@ function rewriteImports(code, config, filePath) {
1545
1605
  if (baseSpec === key || baseSpec.startsWith(key + "/")) {
1546
1606
  const aliasBase = resolveAliasTarget(value, root);
1547
1607
  const sub = baseSpec.slice(key.length).replace(/^\//, "");
1548
- const target = sub ? path9.join(aliasBase, sub) : aliasBase;
1608
+ const target = sub ? path10.join(aliasBase, sub) : aliasBase;
1549
1609
  const resolved = tryResolveDiskPath(target);
1550
1610
  return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1551
1611
  }
1552
1612
  }
1553
1613
  if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
1554
- const target = path9.resolve(fileDir, baseSpec);
1614
+ const target = path10.resolve(fileDir, baseSpec);
1555
1615
  const resolved = tryResolveDiskPath(target);
1556
1616
  return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1557
1617
  }
1558
1618
  if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
1559
- const target = path9.join(root, baseSpec.replace(/^\//, ""));
1619
+ const target = path10.join(root, baseSpec.replace(/^\//, ""));
1560
1620
  const resolved = tryResolveDiskPath(target);
1561
1621
  return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1562
1622
  }
@@ -1575,9 +1635,9 @@ function rewriteImports(code, config, filePath) {
1575
1635
  );
1576
1636
  }
1577
1637
  function resolveAliasTarget(value, root) {
1578
- if (path9.isAbsolute(value) && fs8.existsSync(value)) return value;
1579
- if (value.startsWith("/")) return path9.join(root, value.slice(1));
1580
- return path9.resolve(root, value);
1638
+ if (path10.isAbsolute(value) && fs8.existsSync(value)) return value;
1639
+ if (value.startsWith("/")) return path10.join(root, value.slice(1));
1640
+ return path10.resolve(root, value);
1581
1641
  }
1582
1642
  function tryResolveDiskPath(target) {
1583
1643
  if (fs8.existsSync(target) && fs8.statSync(target).isFile()) return target;
@@ -1587,15 +1647,15 @@ function tryResolveDiskPath(target) {
1587
1647
  }
1588
1648
  if (fs8.existsSync(target) && fs8.statSync(target).isDirectory()) {
1589
1649
  for (const ext of RESOLVE_EXTENSIONS) {
1590
- const idx = path9.join(target, "index" + ext);
1650
+ const idx = path10.join(target, "index" + ext);
1591
1651
  if (fs8.existsSync(idx) && fs8.statSync(idx).isFile()) return idx;
1592
1652
  }
1593
1653
  }
1594
1654
  return null;
1595
1655
  }
1596
1656
  function isUnderRoot(abs, root) {
1597
- const rel = path9.relative(root, abs);
1598
- return !!rel && !rel.startsWith("..") && !path9.isAbsolute(rel);
1657
+ const rel = path10.relative(root, abs);
1658
+ return !!rel && !rel.startsWith("..") && !path10.isAbsolute(rel);
1599
1659
  }
1600
1660
  function resolveNodeModule(root, moduleName) {
1601
1661
  let pkgName;
@@ -1612,17 +1672,17 @@ function resolveNodeModule(root, moduleName) {
1612
1672
  let pkgDir = null;
1613
1673
  let dir = root;
1614
1674
  for (; ; ) {
1615
- const candidate = path9.join(dir, "node_modules", pkgName);
1675
+ const candidate = path10.join(dir, "node_modules", pkgName);
1616
1676
  if (fs8.existsSync(candidate)) {
1617
1677
  pkgDir = candidate;
1618
1678
  break;
1619
1679
  }
1620
- const parent = path9.dirname(dir);
1680
+ const parent = path10.dirname(dir);
1621
1681
  if (parent === dir) break;
1622
1682
  dir = parent;
1623
1683
  }
1624
1684
  if (!pkgDir) return null;
1625
- const pkgJsonPath = path9.join(pkgDir, "package.json");
1685
+ const pkgJsonPath = path10.join(pkgDir, "package.json");
1626
1686
  if (!fs8.existsSync(pkgJsonPath)) return null;
1627
1687
  let pkg;
1628
1688
  try {
@@ -1639,12 +1699,12 @@ function resolveNodeModule(root, moduleName) {
1639
1699
  const subDirs = [""];
1640
1700
  for (const field of ["module", "main"]) {
1641
1701
  if (typeof pkg[field] === "string") {
1642
- const dir2 = path9.dirname(pkg[field]);
1702
+ const dir2 = path10.dirname(pkg[field]);
1643
1703
  if (dir2 && dir2 !== "." && !subDirs.includes(dir2)) subDirs.push(dir2);
1644
1704
  }
1645
1705
  }
1646
1706
  for (const dir2 of subDirs) {
1647
- const direct = path9.join(pkgDir, dir2, subpath);
1707
+ const direct = path10.join(pkgDir, dir2, subpath);
1648
1708
  if (fs8.existsSync(direct) && fs8.statSync(direct).isFile()) return direct;
1649
1709
  for (const ext of RESOLVE_EXTENSIONS) {
1650
1710
  if (fs8.existsSync(direct + ext)) return direct + ext;
@@ -1654,24 +1714,24 @@ function resolveNodeModule(root, moduleName) {
1654
1714
  }
1655
1715
  for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
1656
1716
  if (typeof pkg[field] === "string") {
1657
- const entry = path9.join(pkgDir, pkg[field]);
1717
+ const entry = path10.join(pkgDir, pkg[field]);
1658
1718
  if (fs8.existsSync(entry)) return entry;
1659
1719
  }
1660
1720
  }
1661
- const indexFallback = path9.join(pkgDir, "index.js");
1721
+ const indexFallback = path10.join(pkgDir, "index.js");
1662
1722
  if (fs8.existsSync(indexFallback)) return indexFallback;
1663
1723
  return null;
1664
1724
  }
1665
1725
  function resolvePackageExports(exports, key, pkgDir) {
1666
1726
  if (typeof exports === "string") {
1667
- return key === "." ? path9.join(pkgDir, exports) : null;
1727
+ return key === "." ? path10.join(pkgDir, exports) : null;
1668
1728
  }
1669
1729
  const entry = exports[key];
1670
1730
  if (entry === void 0) return null;
1671
1731
  return resolveExportValue(entry, pkgDir);
1672
1732
  }
1673
1733
  function resolveExportValue(value, pkgDir) {
1674
- if (typeof value === "string") return path9.join(pkgDir, value);
1734
+ if (typeof value === "string") return path10.join(pkgDir, value);
1675
1735
  if (Array.isArray(value)) {
1676
1736
  for (const item of value) {
1677
1737
  const r = resolveExportValue(item, pkgDir);
@@ -1695,7 +1755,7 @@ function resolveUrlToFile(url, root) {
1695
1755
  const moduleName = cleanUrl.slice("/@modules/".length);
1696
1756
  return resolveNodeModule(root, moduleName);
1697
1757
  }
1698
- const filePath = path9.resolve(root, cleanUrl.replace(/^\//, ""));
1758
+ const filePath = path10.resolve(root, cleanUrl.replace(/^\//, ""));
1699
1759
  if (fs8.existsSync(filePath) && fs8.statSync(filePath).isFile()) {
1700
1760
  return filePath;
1701
1761
  }
@@ -1704,7 +1764,7 @@ function resolveUrlToFile(url, root) {
1704
1764
  if (fs8.existsSync(withExt)) return withExt;
1705
1765
  }
1706
1766
  for (const ext of RESOLVE_EXTENSIONS) {
1707
- const indexFile = path9.join(filePath, "index" + ext);
1767
+ const indexFile = path10.join(filePath, "index" + ext);
1708
1768
  if (fs8.existsSync(indexFile)) return indexFile;
1709
1769
  }
1710
1770
  return null;
@@ -1713,7 +1773,7 @@ function isModuleRequest(url) {
1713
1773
  const cleanUrl = url.split("?")[0];
1714
1774
  if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
1715
1775
  if (cleanUrl.startsWith("/@modules/")) return true;
1716
- if (!path9.extname(cleanUrl)) return true;
1776
+ if (!path10.extname(cleanUrl)) return true;
1717
1777
  return false;
1718
1778
  }
1719
1779
  function getHmrClientCode() {
@@ -1851,8 +1911,8 @@ var init_middleware = __esm({
1851
1911
  init_transformer();
1852
1912
  init_html();
1853
1913
  init_env();
1854
- __dirname_esm = path9.dirname(fileURLToPath(import.meta.url));
1855
- __require = createRequire2(import.meta.url);
1914
+ __dirname_esm = path10.dirname(fileURLToPath(import.meta.url));
1915
+ __require = createRequire3(import.meta.url);
1856
1916
  __refreshRuntimeCache = null;
1857
1917
  REACT_REFRESH_GLOBAL_PREAMBLE = `
1858
1918
  import RefreshRuntime from "/@react-refresh";
@@ -1869,11 +1929,11 @@ window.__vite_plugin_react_preamble_installed__ = true;
1869
1929
  });
1870
1930
 
1871
1931
  // src/server/hmr.ts
1872
- import path10 from "path";
1932
+ import path11 from "path";
1873
1933
  import fs9 from "fs";
1874
1934
  async function handleFileChange(file, server) {
1875
1935
  const { moduleGraph, ws, config } = server;
1876
- const relativePath = "/" + path10.relative(config.root, file);
1936
+ const relativePath = "/" + path11.relative(config.root, file);
1877
1937
  const mods = moduleGraph.getModulesByFile(file);
1878
1938
  if (!mods || mods.size === 0) {
1879
1939
  return;
@@ -1930,7 +1990,7 @@ __export(server_exports, {
1930
1990
  createServer: () => createServer
1931
1991
  });
1932
1992
  import http from "http";
1933
- import path11 from "path";
1993
+ import path12 from "path";
1934
1994
  import os from "os";
1935
1995
  import connect from "connect";
1936
1996
  import sirv from "sirv";
@@ -1954,20 +2014,20 @@ async function createServer(inlineConfig = {}) {
1954
2014
  pluginContainer,
1955
2015
  moduleGraph
1956
2016
  }));
1957
- const publicDir = path11.resolve(config.root, "public");
2017
+ const publicDir = path12.resolve(config.root, "public");
1958
2018
  app.use(sirv(publicDir, { dev: true, etag: true }));
1959
2019
  app.use(sirv(config.root, { dev: true, etag: true }));
1960
2020
  const httpServer = http.createServer(app);
1961
2021
  const ws = createWebSocketServer(httpServer);
1962
2022
  const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
1963
- const outDirAbs = path11.resolve(config.root, config.build.outDir);
2023
+ const outDirAbs = path12.resolve(config.root, config.build.outDir);
1964
2024
  const watcher = watch(config.root, {
1965
2025
  ignored: (filePath) => {
1966
2026
  if (filePath === config.root) return false;
1967
- if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path11.sep)) return true;
1968
- const rel = path11.relative(config.root, filePath);
1969
- if (!rel || rel.startsWith("..") || path11.isAbsolute(rel)) return false;
1970
- for (const seg of rel.split(path11.sep)) {
2027
+ if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path12.sep)) return true;
2028
+ const rel = path12.relative(config.root, filePath);
2029
+ if (!rel || rel.startsWith("..") || path12.isAbsolute(rel)) return false;
2030
+ for (const seg of rel.split(path12.sep)) {
1971
2031
  if (ignoredSegments.has(seg)) return true;
1972
2032
  }
1973
2033
  return false;
@@ -1999,7 +2059,7 @@ async function createServer(inlineConfig = {}) {
1999
2059
  const localUrl = `http://localhost:${actualPort}`;
2000
2060
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
2001
2061
  console.log();
2002
- console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.6.3"}`));
2062
+ console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.6.4"}`));
2003
2063
  console.log();
2004
2064
  console.log(` ${pc3.green(">")} Local: ${pc3.cyan(localUrl)}`);
2005
2065
  if (networkUrl) {
@@ -2078,7 +2138,7 @@ init_build();
2078
2138
  // src/build/electron.ts
2079
2139
  init_config();
2080
2140
  init_resolve();
2081
- import path8 from "path";
2141
+ import path9 from "path";
2082
2142
  import fs7 from "fs";
2083
2143
  import { rolldown as rolldown2 } from "rolldown";
2084
2144
  import pc2 from "picocolors";
@@ -2123,16 +2183,16 @@ async function buildElectron(inlineConfig = {}) {
2123
2183
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
2124
2184
  const startTime = performance.now();
2125
2185
  assertElectronVersion(config);
2126
- console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.6.3"}`));
2186
+ console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.6.4"}`));
2127
2187
  console.log(pc2.dim(` root: ${config.root}`));
2128
2188
  console.log(pc2.dim(` mode: ${config.mode}`));
2129
2189
  console.log(pc2.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
2130
- const outDir = path8.resolve(config.root, config.build.outDir);
2190
+ const outDir = path9.resolve(config.root, config.build.outDir);
2131
2191
  if (config.build.emptyOutDir && fs7.existsSync(outDir)) {
2132
2192
  fs7.rmSync(outDir, { recursive: true, force: true });
2133
2193
  }
2134
2194
  fs7.mkdirSync(outDir, { recursive: true });
2135
- const rendererOutDir = path8.join(outDir, "renderer");
2195
+ const rendererOutDir = path9.join(outDir, "renderer");
2136
2196
  const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
2137
2197
  await build2({
2138
2198
  ...inlineConfig,
@@ -2143,7 +2203,7 @@ async function buildElectron(inlineConfig = {}) {
2143
2203
  emptyOutDir: false
2144
2204
  }
2145
2205
  });
2146
- const mainEntry = path8.resolve(config.root, config.electron.main);
2206
+ const mainEntry = path9.resolve(config.root, config.electron.main);
2147
2207
  if (!fs7.existsSync(mainEntry)) {
2148
2208
  throw new Error(
2149
2209
  `Electron main entry not found: ${config.electron.main}
@@ -2162,7 +2222,7 @@ async function buildElectron(inlineConfig = {}) {
2162
2222
  console.warn(pc2.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
2163
2223
  continue;
2164
2224
  }
2165
- const base = path8.basename(entry).replace(/\.[^.]+$/, "");
2225
+ const base = path9.basename(entry).replace(/\.[^.]+$/, "");
2166
2226
  const out = outFileName(outDir, base, config.electron.preloadFormat);
2167
2227
  await bundleNode(config, entry, {
2168
2228
  outFile: out,
@@ -2174,10 +2234,10 @@ async function buildElectron(inlineConfig = {}) {
2174
2234
  const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
2175
2235
  console.log(pc2.green(`
2176
2236
  \u2713 Electron build complete in ${elapsed}s`));
2177
- console.log(pc2.dim(` renderer: ${path8.relative(config.root, rendererOutDir)}/`));
2178
- console.log(pc2.dim(` main: ${path8.relative(config.root, mainFile)}`));
2237
+ console.log(pc2.dim(` renderer: ${path9.relative(config.root, rendererOutDir)}/`));
2238
+ console.log(pc2.dim(` main: ${path9.relative(config.root, mainFile)}`));
2179
2239
  for (const pf of preloadFiles) {
2180
- console.log(pc2.dim(` preload: ${path8.relative(config.root, pf)}`));
2240
+ console.log(pc2.dim(` preload: ${path9.relative(config.root, pf)}`));
2181
2241
  }
2182
2242
  console.log();
2183
2243
  return { rendererOutDir, mainFile, preloadFiles };
@@ -2208,7 +2268,7 @@ async function bundleNode(config, entry, opts) {
2208
2268
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)],
2209
2269
  ...config.build.rolldownOptions
2210
2270
  });
2211
- fs7.mkdirSync(path8.dirname(opts.outFile), { recursive: true });
2271
+ fs7.mkdirSync(path9.dirname(opts.outFile), { recursive: true });
2212
2272
  await bundle.write({
2213
2273
  file: opts.outFile,
2214
2274
  format: opts.format === "cjs" ? "cjs" : "esm",
@@ -2217,16 +2277,16 @@ async function bundleNode(config, entry, opts) {
2217
2277
  codeSplitting: false
2218
2278
  });
2219
2279
  await bundle.close();
2220
- console.log(pc2.dim(` \u2713 ${opts.label} \u2192 ${path8.relative(config.root, opts.outFile)}`));
2280
+ console.log(pc2.dim(` \u2713 ${opts.label} \u2192 ${path9.relative(config.root, opts.outFile)}`));
2221
2281
  return opts.outFile;
2222
2282
  }
2223
2283
  function outFileName(outDir, base, format) {
2224
2284
  const ext = format === "cjs" ? ".cjs" : ".mjs";
2225
- return path8.join(outDir, base + ext);
2285
+ return path9.join(outDir, base + ext);
2226
2286
  }
2227
2287
  function normalizePreload(preload, root) {
2228
2288
  const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
2229
- return list.map((p) => path8.resolve(root, p));
2289
+ return list.map((p) => path9.resolve(root, p));
2230
2290
  }
2231
2291
  function assertElectronVersion(config) {
2232
2292
  const min = config.electron.minVersion;
@@ -2241,7 +2301,7 @@ function assertElectronVersion(config) {
2241
2301
  }
2242
2302
  function detectInstalledElectron(root) {
2243
2303
  try {
2244
- const pkgPath = path8.resolve(root, "node_modules/electron/package.json");
2304
+ const pkgPath = path9.resolve(root, "node_modules/electron/package.json");
2245
2305
  if (!fs7.existsSync(pkgPath)) return null;
2246
2306
  const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
2247
2307
  const major = parseInt(String(pkg.version).split(".")[0], 10);
@@ -2256,9 +2316,9 @@ init_server();
2256
2316
 
2257
2317
  // src/server/electron-dev.ts
2258
2318
  init_config();
2259
- import path12 from "path";
2319
+ import path13 from "path";
2260
2320
  import fs10 from "fs";
2261
- import { createRequire as createRequire3 } from "module";
2321
+ import { createRequire as createRequire4 } from "module";
2262
2322
  import { spawn } from "child_process";
2263
2323
  import chokidar from "chokidar";
2264
2324
  import pc4 from "picocolors";
@@ -2270,17 +2330,17 @@ async function startElectronDev(inlineConfig = {}) {
2270
2330
  const { noSpawn, ...rest } = inlineConfig;
2271
2331
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
2272
2332
  warnElectronVersion(config);
2273
- console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.6.3"}`));
2333
+ console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.6.4"}`));
2274
2334
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2275
2335
  const server = await createServer2({ ...rest, target: "electron" });
2276
2336
  await server.listen();
2277
2337
  const devUrl = `http://localhost:${server.config.server.port}/`;
2278
2338
  console.log(pc4.dim(` renderer: ${devUrl}`));
2279
- const stageDir = path12.resolve(config.root, ".nasti");
2339
+ const stageDir = path13.resolve(config.root, ".nasti");
2280
2340
  fs10.mkdirSync(stageDir, { recursive: true });
2281
- const mainEntry = path12.resolve(config.root, config.electron.main);
2341
+ const mainEntry = path13.resolve(config.root, config.electron.main);
2282
2342
  const preloadEntries = normalizePreload(config.electron.preload, config.root);
2283
- const builtMainFile = path12.join(stageDir, "main" + extFor(config.electron.mainFormat));
2343
+ const builtMainFile = path13.join(stageDir, "main" + extFor(config.electron.mainFormat));
2284
2344
  const builtPreloadFiles = [];
2285
2345
  const compileAll = async () => {
2286
2346
  await compileNode(config, mainEntry, {
@@ -2291,8 +2351,8 @@ async function startElectronDev(inlineConfig = {}) {
2291
2351
  builtPreloadFiles.length = 0;
2292
2352
  for (const entry of preloadEntries) {
2293
2353
  if (!fs10.existsSync(entry)) continue;
2294
- const base = path12.basename(entry).replace(/\.[^.]+$/, "");
2295
- const out = path12.join(stageDir, base + extFor(config.electron.preloadFormat));
2354
+ const base = path13.basename(entry).replace(/\.[^.]+$/, "");
2355
+ const out = path13.join(stageDir, base + extFor(config.electron.preloadFormat));
2296
2356
  await compileNode(config, entry, {
2297
2357
  outFile: out,
2298
2358
  format: config.electron.preloadFormat,
@@ -2407,7 +2467,7 @@ async function compileNode(config, entry, opts) {
2407
2467
  platform: "node",
2408
2468
  plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
2409
2469
  });
2410
- fs10.mkdirSync(path12.dirname(opts.outFile), { recursive: true });
2470
+ fs10.mkdirSync(path13.dirname(opts.outFile), { recursive: true });
2411
2471
  await bundle.write({
2412
2472
  file: opts.outFile,
2413
2473
  format: opts.format === "cjs" ? "cjs" : "esm",
@@ -2424,7 +2484,7 @@ function resolveElectronBinary(config) {
2424
2484
  return config.electron.electronPath;
2425
2485
  }
2426
2486
  try {
2427
- const require2 = createRequire3(path12.resolve(config.root, "package.json"));
2487
+ const require2 = createRequire4(path13.resolve(config.root, "package.json"));
2428
2488
  const pathFile = require2.resolve("electron");
2429
2489
  const electronModule = require2(pathFile);
2430
2490
  if (typeof electronModule === "string" && fs10.existsSync(electronModule)) {
@@ -2454,10 +2514,10 @@ function warnElectronVersion(config) {
2454
2514
  }
2455
2515
 
2456
2516
  // src/plugins/monaco-editor.ts
2457
- import path13 from "path";
2517
+ import path14 from "path";
2458
2518
  import fs11 from "fs";
2459
2519
  import crypto2 from "crypto";
2460
- import { createRequire as createRequire4 } from "module";
2520
+ import { createRequire as createRequire5 } from "module";
2461
2521
  var DEFAULT_WORKERS = {
2462
2522
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
2463
2523
  css: "monaco-editor/esm/vs/language/css/css.worker",
@@ -2476,7 +2536,7 @@ function normalizePublicPath(p) {
2476
2536
  }
2477
2537
  function readMonacoVersion(root) {
2478
2538
  try {
2479
- const require2 = createRequire4(path13.resolve(root, "package.json"));
2539
+ const require2 = createRequire5(path14.resolve(root, "package.json"));
2480
2540
  const pkgJsonPath = require2.resolve("monaco-editor/package.json", { paths: [root] });
2481
2541
  const pkg = JSON.parse(fs11.readFileSync(pkgJsonPath, "utf-8"));
2482
2542
  return typeof pkg.version === "string" ? pkg.version : "unknown";
@@ -2498,13 +2558,13 @@ function monacoEditorPlugin(options = {}) {
2498
2558
  let cacheDir = "";
2499
2559
  const building = /* @__PURE__ */ new Map();
2500
2560
  async function buildWorker(worker) {
2501
- const cacheFile = path13.join(cacheDir, `${worker.label}.worker.js`);
2561
+ const cacheFile = path14.join(cacheDir, `${worker.label}.worker.js`);
2502
2562
  if (fs11.existsSync(cacheFile)) return cacheFile;
2503
2563
  const existing = building.get(worker.label);
2504
2564
  if (existing) return existing;
2505
2565
  const task = (async () => {
2506
2566
  const { rolldown: rolldown4 } = await import("rolldown");
2507
- const require2 = createRequire4(path13.resolve(resolvedConfig.root, "package.json"));
2567
+ const require2 = createRequire5(path14.resolve(resolvedConfig.root, "package.json"));
2508
2568
  let entry;
2509
2569
  try {
2510
2570
  entry = require2.resolve(worker.entry, { paths: [resolvedConfig.root] });
@@ -2571,12 +2631,12 @@ function monacoEditorPlugin(options = {}) {
2571
2631
  resolvedConfig = config;
2572
2632
  const version = readMonacoVersion(config.root);
2573
2633
  const key = crypto2.createHash("sha1").update(version + "|" + publicPath).digest("hex").slice(0, 8);
2574
- cacheDir = path13.resolve(config.root, "node_modules/.nasti/monaco", key);
2634
+ cacheDir = path14.resolve(config.root, "node_modules/.nasti/monaco", key);
2575
2635
  },
2576
2636
  async configureServer(server) {
2577
2637
  const shouldBuild = !isCDN(publicPath) || forceBuildCDN;
2578
2638
  const watcher = server.watcher;
2579
- const monacoDir = path13.resolve(resolvedConfig.root, "node_modules/monaco-editor");
2639
+ const monacoDir = path14.resolve(resolvedConfig.root, "node_modules/monaco-editor");
2580
2640
  try {
2581
2641
  watcher?.unwatch?.(monacoDir);
2582
2642
  } catch {
@@ -2641,7 +2701,7 @@ self.monaco = monaco;`,
2641
2701
  resolvedConfig.root,
2642
2702
  resolvedConfig.build.outDir,
2643
2703
  resolvedConfig.base
2644
- ) : isCDN(publicPath) ? path13.resolve(resolvedConfig.root, resolvedConfig.build.outDir, "monaco") : path13.resolve(
2704
+ ) : isCDN(publicPath) ? path14.resolve(resolvedConfig.root, resolvedConfig.build.outDir, "monaco") : path14.resolve(
2645
2705
  resolvedConfig.root,
2646
2706
  resolvedConfig.build.outDir,
2647
2707
  publicPath.replace(/^\//, "")
@@ -2650,7 +2710,7 @@ self.monaco = monaco;`,
2650
2710
  for (const worker of workers) {
2651
2711
  try {
2652
2712
  const cacheFile = await buildWorker(worker);
2653
- fs11.copyFileSync(cacheFile, path13.join(outDir, `${worker.label}.worker.js`));
2713
+ fs11.copyFileSync(cacheFile, path14.join(outDir, `${worker.label}.worker.js`));
2654
2714
  } catch (e) {
2655
2715
  throw new Error(
2656
2716
  `[nasti:monaco-editor] worker build failed for "${worker.label}": ${e.message}