@nasti-toolchain/nasti 1.6.1 → 1.6.3

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.cjs CHANGED
@@ -464,6 +464,19 @@ var init_module_graph = __esm({
464
464
  }
465
465
  mods.add(mod);
466
466
  }
467
+ /**
468
+ * Reindex a module under a plugin-provided canonical id (e.g. a `\0virtual:foo`
469
+ * id returned from `resolveId`). Plugins look up their own virtual modules via
470
+ * `getModuleById(RESOLVED_ID)` to invalidate them on watcher events; without
471
+ * this remap they'd never find the node because `ensureEntryFromUrl` keys by
472
+ * the public URL only.
473
+ */
474
+ setModuleId(mod, id) {
475
+ if (mod.id === id) return;
476
+ this.idToModuleMap.delete(mod.id);
477
+ mod.id = id;
478
+ this.idToModuleMap.set(id, mod);
479
+ }
467
480
  /** 更新模块依赖关系 */
468
481
  updateModuleImports(mod, importedIds) {
469
482
  for (const imported of mod.importedModules) {
@@ -913,6 +926,16 @@ async function transformRequest(url, ctx) {
913
926
  if (cleanReqUrl === "/@react-refresh") {
914
927
  return { code: getReactRefreshRuntimeEsm() };
915
928
  }
929
+ if (cleanReqUrl.startsWith("/@modules/")) {
930
+ const spec = cleanReqUrl.slice("/@modules/".length);
931
+ const virtual = await loadVirtualModule(spec, ctx);
932
+ if (virtual) {
933
+ const mod2 = await moduleGraph.ensureEntryFromUrl(url);
934
+ moduleGraph.setModuleId(mod2, virtual.id);
935
+ mod2.transformResult = virtual.result;
936
+ return virtual.result;
937
+ }
938
+ }
916
939
  const filePath = resolveUrlToFile(url, config.root);
917
940
  if (!filePath || !import_node_fs4.default.existsSync(filePath)) return null;
918
941
  const mod = await moduleGraph.ensureEntryFromUrl(url);
@@ -959,6 +982,28 @@ async function transformRequest(url, ctx) {
959
982
  mod.transformResult = transformResult;
960
983
  return transformResult;
961
984
  }
985
+ async function loadVirtualModule(spec, ctx) {
986
+ const { config, pluginContainer } = ctx;
987
+ const resolved = await pluginContainer.resolveId(spec);
988
+ if (resolved == null) return null;
989
+ const resolvedId = typeof resolved === "string" ? resolved : resolved.id;
990
+ const looksVirtual = resolvedId.startsWith("\0") || !import_node_fs4.default.existsSync(resolvedId);
991
+ if (!looksVirtual) return null;
992
+ const loadResult = await pluginContainer.load(resolvedId);
993
+ if (loadResult == null) return null;
994
+ let code = typeof loadResult === "string" ? loadResult : loadResult.code;
995
+ const transformed = await pluginContainer.transform(code, resolvedId);
996
+ if (transformed != null) {
997
+ code = typeof transformed === "string" ? transformed : transformed.code;
998
+ }
999
+ code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(
1000
+ loadEnv(config.mode, config.root, config.envPrefix),
1001
+ config.mode
1002
+ ));
1003
+ const anchor = import_node_path4.default.join(config.root, "__nasti_virtual__.ts");
1004
+ code = rewriteImports(code, config, anchor);
1005
+ return { id: resolvedId, result: { code } };
1006
+ }
962
1007
  async function bundlePackageAsEsm(entryFile) {
963
1008
  if (!esmBundleCache.has(entryFile)) {
964
1009
  esmBundleCache.set(entryFile, doBundlePackage(entryFile));
@@ -966,6 +1011,8 @@ async function bundlePackageAsEsm(entryFile) {
966
1011
  return esmBundleCache.get(entryFile);
967
1012
  }
968
1013
  async function doBundlePackage(entryFile) {
1014
+ const shim = await tryGenerateSubpathShim(entryFile);
1015
+ if (shim != null) return shim;
969
1016
  const { rolldown: rolldown4 } = await import("rolldown");
970
1017
  const bundle = await rolldown4({
971
1018
  input: entryFile,
@@ -995,6 +1042,103 @@ async function doBundlePackage(entryFile) {
995
1042
  }
996
1043
  return code;
997
1044
  }
1045
+ async function tryGenerateSubpathShim(entryFile) {
1046
+ const NM = `${import_node_path4.default.sep}node_modules${import_node_path4.default.sep}`;
1047
+ if (!entryFile.includes(NM)) return null;
1048
+ let pkgDir = null;
1049
+ let pkgName = null;
1050
+ let dir = import_node_path4.default.dirname(entryFile);
1051
+ while (true) {
1052
+ const pkgJsonPath = import_node_path4.default.join(dir, "package.json");
1053
+ if (import_node_fs4.default.existsSync(pkgJsonPath)) {
1054
+ try {
1055
+ const pkg = JSON.parse(import_node_fs4.default.readFileSync(pkgJsonPath, "utf-8"));
1056
+ if (typeof pkg?.name === "string" && pkg.name) {
1057
+ pkgDir = dir;
1058
+ pkgName = pkg.name;
1059
+ break;
1060
+ }
1061
+ } catch {
1062
+ }
1063
+ }
1064
+ const parent = import_node_path4.default.dirname(dir);
1065
+ if (parent === dir) return null;
1066
+ dir = parent;
1067
+ if (!dir.includes(NM)) return null;
1068
+ }
1069
+ if (!pkgDir || !pkgName) return null;
1070
+ const entryExt = import_node_path4.default.extname(entryFile);
1071
+ const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
1072
+ if (!mainEntry) return null;
1073
+ if (import_node_path4.default.resolve(mainEntry) === import_node_path4.default.resolve(entryFile)) return null;
1074
+ let mainNs;
1075
+ let subNs;
1076
+ try {
1077
+ mainNs = await import((0, import_node_url2.pathToFileURL)(mainEntry).href);
1078
+ subNs = await import((0, import_node_url2.pathToFileURL)(entryFile).href);
1079
+ } catch {
1080
+ return null;
1081
+ }
1082
+ if (!mainNs || typeof mainNs !== "object") return null;
1083
+ if (!subNs || typeof subNs !== "object") return null;
1084
+ const subKeys = Object.keys(subNs).filter(
1085
+ (k) => k !== "__esModule" && k !== "default" && VALID_IDENT.test(k)
1086
+ );
1087
+ if (subKeys.length === 0) return null;
1088
+ for (const k of subKeys) {
1089
+ if (!(k in mainNs)) return null;
1090
+ if (mainNs[k] !== subNs[k]) return null;
1091
+ }
1092
+ if ("default" in subNs) {
1093
+ if (!("default" in mainNs)) return null;
1094
+ if (mainNs["default"] !== subNs["default"]) return null;
1095
+ }
1096
+ const lines = [
1097
+ `// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
1098
+ `import * as __pkg from "/@modules/${pkgName}";`
1099
+ ];
1100
+ for (const k of subKeys) {
1101
+ lines.push(`export const ${k} = __pkg[${JSON.stringify(k)}];`);
1102
+ }
1103
+ if ("default" in subNs) {
1104
+ lines.push(`export default ("default" in __pkg ? __pkg["default"] : __pkg);`);
1105
+ }
1106
+ return lines.join("\n") + "\n";
1107
+ }
1108
+ function pickMainEntryByExtension(pkgDir, preferredExt) {
1109
+ const pkgJsonPath = import_node_path4.default.join(pkgDir, "package.json");
1110
+ let pkg;
1111
+ try {
1112
+ pkg = JSON.parse(import_node_fs4.default.readFileSync(pkgJsonPath, "utf-8"));
1113
+ } catch {
1114
+ return null;
1115
+ }
1116
+ const candidates = [];
1117
+ const collectFromExportObject = (obj) => {
1118
+ if (!obj || typeof obj !== "object") return;
1119
+ for (const cond of ["import", "module", "default", "require", "node"]) {
1120
+ const v = obj[cond];
1121
+ if (typeof v === "string") candidates.push(v);
1122
+ else if (v && typeof v === "object") collectFromExportObject(v);
1123
+ }
1124
+ };
1125
+ const dot = pkg?.exports?.["."];
1126
+ if (typeof dot === "string") candidates.push(dot);
1127
+ else if (dot && typeof dot === "object") collectFromExportObject(dot);
1128
+ if (typeof pkg.module === "string") candidates.push(pkg.module);
1129
+ if (typeof pkg.main === "string") candidates.push(pkg.main);
1130
+ for (const cand of candidates) {
1131
+ if (import_node_path4.default.extname(cand) === preferredExt) {
1132
+ const full = import_node_path4.default.resolve(pkgDir, cand);
1133
+ if (import_node_fs4.default.existsSync(full)) return full;
1134
+ }
1135
+ }
1136
+ for (const cand of candidates) {
1137
+ const full = import_node_path4.default.resolve(pkgDir, cand);
1138
+ if (import_node_fs4.default.existsSync(full)) return full;
1139
+ }
1140
+ return null;
1141
+ }
998
1142
  function rewriteExternalRequires(code) {
999
1143
  const pkgs = /* @__PURE__ */ new Set();
1000
1144
  const re = /__require\(["']([^"']+)["']\)/g;
@@ -1711,7 +1855,7 @@ async function createServer(inlineConfig = {}) {
1711
1855
  const localUrl = `http://localhost:${actualPort}`;
1712
1856
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1713
1857
  console.log();
1714
- console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.6.1"}`));
1858
+ console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.6.3"}`));
1715
1859
  console.log();
1716
1860
  console.log(` ${import_picocolors.default.green(">")} Local: ${import_picocolors.default.cyan(localUrl)}`);
1717
1861
  if (networkUrl) {
@@ -1838,7 +1982,7 @@ __export(build_exports, {
1838
1982
  async function build(inlineConfig = {}) {
1839
1983
  const config = await resolveConfig(inlineConfig, "build");
1840
1984
  const startTime = performance.now();
1841
- console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.6.1"}`));
1985
+ console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.6.3"}`));
1842
1986
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1843
1987
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1844
1988
  const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
@@ -1904,7 +2048,11 @@ async function build(inlineConfig = {}) {
1904
2048
  load: p.load,
1905
2049
  transform: p.transform,
1906
2050
  buildStart: p.buildStart,
1907
- buildEnd: p.buildEnd
2051
+ buildEnd: p.buildEnd,
2052
+ // Forward `closeBundle` to Rolldown — it invokes the hook during
2053
+ // `bundle.close()` below. This is the hook Vite plugins (e.g. PWA
2054
+ // manifest/SW writers) rely on for final-stage artifact emission.
2055
+ closeBundle: p.closeBundle
1908
2056
  }))
1909
2057
  ],
1910
2058
  ...config.build.rolldownOptions
@@ -1999,7 +2147,7 @@ async function buildElectron(inlineConfig = {}) {
1999
2147
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
2000
2148
  const startTime = performance.now();
2001
2149
  assertElectronVersion(config);
2002
- console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.6.1"}`));
2150
+ console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.6.3"}`));
2003
2151
  console.log(import_picocolors3.default.dim(` root: ${config.root}`));
2004
2152
  console.log(import_picocolors3.default.dim(` mode: ${config.mode}`));
2005
2153
  console.log(import_picocolors3.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -2151,7 +2299,7 @@ async function startElectronDev(inlineConfig = {}) {
2151
2299
  const { noSpawn, ...rest } = inlineConfig;
2152
2300
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
2153
2301
  warnElectronVersion(config);
2154
- console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.6.1"}`));
2302
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.6.3"}`));
2155
2303
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2156
2304
  const server = await createServer2({ ...rest, target: "electron" });
2157
2305
  await server.listen();
@@ -2486,6 +2634,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
2486
2634
  }
2487
2635
  });
2488
2636
  cli.help();
2489
- cli.version("1.6.1");
2637
+ cli.version("1.6.3");
2490
2638
  cli.parse();
2491
2639
  //# sourceMappingURL=cli.cjs.map