@nasti-toolchain/nasti 1.6.0 → 1.6.2

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
@@ -954,7 +954,7 @@ async function transformRequest(url, ctx) {
954
954
  config.mode
955
955
  );
956
956
  code = replaceEnvInCode(code, envDefine);
957
- code = rewriteImports(code, config);
957
+ code = rewriteImports(code, config, filePath);
958
958
  const transformResult = { code };
959
959
  mod.transformResult = transformResult;
960
960
  return transformResult;
@@ -966,6 +966,8 @@ async function bundlePackageAsEsm(entryFile) {
966
966
  return esmBundleCache.get(entryFile);
967
967
  }
968
968
  async function doBundlePackage(entryFile) {
969
+ const shim = await tryGenerateSubpathShim(entryFile);
970
+ if (shim != null) return shim;
969
971
  const { rolldown: rolldown4 } = await import("rolldown");
970
972
  const bundle = await rolldown4({
971
973
  input: entryFile,
@@ -995,6 +997,103 @@ async function doBundlePackage(entryFile) {
995
997
  }
996
998
  return code;
997
999
  }
1000
+ async function tryGenerateSubpathShim(entryFile) {
1001
+ const NM = `${import_node_path4.default.sep}node_modules${import_node_path4.default.sep}`;
1002
+ if (!entryFile.includes(NM)) return null;
1003
+ let pkgDir = null;
1004
+ let pkgName = null;
1005
+ let dir = import_node_path4.default.dirname(entryFile);
1006
+ while (true) {
1007
+ const pkgJsonPath = import_node_path4.default.join(dir, "package.json");
1008
+ if (import_node_fs4.default.existsSync(pkgJsonPath)) {
1009
+ try {
1010
+ const pkg = JSON.parse(import_node_fs4.default.readFileSync(pkgJsonPath, "utf-8"));
1011
+ if (typeof pkg?.name === "string" && pkg.name) {
1012
+ pkgDir = dir;
1013
+ pkgName = pkg.name;
1014
+ break;
1015
+ }
1016
+ } catch {
1017
+ }
1018
+ }
1019
+ const parent = import_node_path4.default.dirname(dir);
1020
+ if (parent === dir) return null;
1021
+ dir = parent;
1022
+ if (!dir.includes(NM)) return null;
1023
+ }
1024
+ if (!pkgDir || !pkgName) return null;
1025
+ const entryExt = import_node_path4.default.extname(entryFile);
1026
+ const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
1027
+ if (!mainEntry) return null;
1028
+ if (import_node_path4.default.resolve(mainEntry) === import_node_path4.default.resolve(entryFile)) return null;
1029
+ let mainNs;
1030
+ let subNs;
1031
+ try {
1032
+ mainNs = await import((0, import_node_url2.pathToFileURL)(mainEntry).href);
1033
+ subNs = await import((0, import_node_url2.pathToFileURL)(entryFile).href);
1034
+ } catch {
1035
+ return null;
1036
+ }
1037
+ if (!mainNs || typeof mainNs !== "object") return null;
1038
+ if (!subNs || typeof subNs !== "object") return null;
1039
+ const subKeys = Object.keys(subNs).filter(
1040
+ (k) => k !== "__esModule" && k !== "default" && VALID_IDENT.test(k)
1041
+ );
1042
+ if (subKeys.length === 0) return null;
1043
+ for (const k of subKeys) {
1044
+ if (!(k in mainNs)) return null;
1045
+ if (mainNs[k] !== subNs[k]) return null;
1046
+ }
1047
+ if ("default" in subNs) {
1048
+ if (!("default" in mainNs)) return null;
1049
+ if (mainNs["default"] !== subNs["default"]) return null;
1050
+ }
1051
+ const lines = [
1052
+ `// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
1053
+ `import * as __pkg from "/@modules/${pkgName}";`
1054
+ ];
1055
+ for (const k of subKeys) {
1056
+ lines.push(`export const ${k} = __pkg[${JSON.stringify(k)}];`);
1057
+ }
1058
+ if ("default" in subNs) {
1059
+ lines.push(`export default ("default" in __pkg ? __pkg["default"] : __pkg);`);
1060
+ }
1061
+ return lines.join("\n") + "\n";
1062
+ }
1063
+ function pickMainEntryByExtension(pkgDir, preferredExt) {
1064
+ const pkgJsonPath = import_node_path4.default.join(pkgDir, "package.json");
1065
+ let pkg;
1066
+ try {
1067
+ pkg = JSON.parse(import_node_fs4.default.readFileSync(pkgJsonPath, "utf-8"));
1068
+ } catch {
1069
+ return null;
1070
+ }
1071
+ const candidates = [];
1072
+ const collectFromExportObject = (obj) => {
1073
+ if (!obj || typeof obj !== "object") return;
1074
+ for (const cond of ["import", "module", "default", "require", "node"]) {
1075
+ const v = obj[cond];
1076
+ if (typeof v === "string") candidates.push(v);
1077
+ else if (v && typeof v === "object") collectFromExportObject(v);
1078
+ }
1079
+ };
1080
+ const dot = pkg?.exports?.["."];
1081
+ if (typeof dot === "string") candidates.push(dot);
1082
+ else if (dot && typeof dot === "object") collectFromExportObject(dot);
1083
+ if (typeof pkg.module === "string") candidates.push(pkg.module);
1084
+ if (typeof pkg.main === "string") candidates.push(pkg.main);
1085
+ for (const cand of candidates) {
1086
+ if (import_node_path4.default.extname(cand) === preferredExt) {
1087
+ const full = import_node_path4.default.resolve(pkgDir, cand);
1088
+ if (import_node_fs4.default.existsSync(full)) return full;
1089
+ }
1090
+ }
1091
+ for (const cand of candidates) {
1092
+ const full = import_node_path4.default.resolve(pkgDir, cand);
1093
+ if (import_node_fs4.default.existsSync(full)) return full;
1094
+ }
1095
+ return null;
1096
+ }
998
1097
  function rewriteExternalRequires(code) {
999
1098
  const pkgs = /* @__PURE__ */ new Set();
1000
1099
  const re = /__require\(["']([^"']+)["']\)/g;
@@ -1036,26 +1135,73 @@ async function injectCjsNamedExports(code, entryFile) {
1036
1135
  return code;
1037
1136
  }
1038
1137
  }
1039
- function rewriteImports(code, _config) {
1040
- return code.replace(
1041
- /\bfrom\s+(['"])([^'"./][^'"]*)\1/g,
1042
- (match, quote, specifier) => {
1043
- return `from ${quote}/@modules/${specifier}${quote}`;
1138
+ function rewriteImports(code, config, filePath) {
1139
+ const root = config.root;
1140
+ const fileDir = import_node_path4.default.dirname(filePath);
1141
+ const aliasEntries = Object.entries(config.resolve.alias).sort(
1142
+ ([a], [b]) => b.length - a.length
1143
+ );
1144
+ const toRootUrl = (abs) => "/" + import_node_path4.default.relative(root, abs).replace(/\\/g, "/");
1145
+ const transformSpec = (spec) => {
1146
+ const suffixMatch = spec.match(/[?#].*$/);
1147
+ const suffix = suffixMatch ? suffixMatch[0] : "";
1148
+ const baseSpec = suffix ? spec.slice(0, -suffix.length) : spec;
1149
+ for (const [key, value] of aliasEntries) {
1150
+ if (baseSpec === key || baseSpec.startsWith(key + "/")) {
1151
+ const aliasBase = resolveAliasTarget(value, root);
1152
+ const sub = baseSpec.slice(key.length).replace(/^\//, "");
1153
+ const target = sub ? import_node_path4.default.join(aliasBase, sub) : aliasBase;
1154
+ const resolved = tryResolveDiskPath(target);
1155
+ return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1156
+ }
1044
1157
  }
1045
- ).replace(
1046
- // 处理纯副作用导入: import 'bare-specifier'
1047
- /\bimport\s+(['"])([^'"./][^'"]*)\1/g,
1048
- (match, quote, specifier) => {
1049
- return `import ${quote}/@modules/${specifier}${quote}`;
1158
+ if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
1159
+ const target = import_node_path4.default.resolve(fileDir, baseSpec);
1160
+ const resolved = tryResolveDiskPath(target);
1161
+ return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1050
1162
  }
1051
- ).replace(
1052
- // 处理动态导入: import('bare-specifier')
1053
- /\bimport\s*\(\s*(['"])([^'"./][^'"]*)\1\s*\)/g,
1054
- (match, quote, specifier) => {
1055
- return `import(${quote}/@modules/${specifier}${quote})`;
1163
+ if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
1164
+ const target = import_node_path4.default.join(root, baseSpec.replace(/^\//, ""));
1165
+ const resolved = tryResolveDiskPath(target);
1166
+ return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
1056
1167
  }
1168
+ if (baseSpec.startsWith("/")) return spec;
1169
+ return `/@modules/${spec}`;
1170
+ };
1171
+ return code.replace(
1172
+ /\bfrom\s+(['"])([^'"]+)\1/g,
1173
+ (_m, q, s) => `from ${q}${transformSpec(s)}${q}`
1174
+ ).replace(
1175
+ /\bimport\s+(['"])([^'"]+)\1/g,
1176
+ (_m, q, s) => `import ${q}${transformSpec(s)}${q}`
1177
+ ).replace(
1178
+ /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g,
1179
+ (_m, q, s) => `import(${q}${transformSpec(s)}${q})`
1057
1180
  );
1058
1181
  }
1182
+ function resolveAliasTarget(value, root) {
1183
+ if (import_node_path4.default.isAbsolute(value) && import_node_fs4.default.existsSync(value)) return value;
1184
+ if (value.startsWith("/")) return import_node_path4.default.join(root, value.slice(1));
1185
+ return import_node_path4.default.resolve(root, value);
1186
+ }
1187
+ function tryResolveDiskPath(target) {
1188
+ if (import_node_fs4.default.existsSync(target) && import_node_fs4.default.statSync(target).isFile()) return target;
1189
+ for (const ext of RESOLVE_EXTENSIONS) {
1190
+ const withExt = target + ext;
1191
+ if (import_node_fs4.default.existsSync(withExt) && import_node_fs4.default.statSync(withExt).isFile()) return withExt;
1192
+ }
1193
+ if (import_node_fs4.default.existsSync(target) && import_node_fs4.default.statSync(target).isDirectory()) {
1194
+ for (const ext of RESOLVE_EXTENSIONS) {
1195
+ const idx = import_node_path4.default.join(target, "index" + ext);
1196
+ if (import_node_fs4.default.existsSync(idx) && import_node_fs4.default.statSync(idx).isFile()) return idx;
1197
+ }
1198
+ }
1199
+ return null;
1200
+ }
1201
+ function isUnderRoot(abs, root) {
1202
+ const rel = import_node_path4.default.relative(root, abs);
1203
+ return !!rel && !rel.startsWith("..") && !import_node_path4.default.isAbsolute(rel);
1204
+ }
1059
1205
  function resolveNodeModule(root, moduleName) {
1060
1206
  let pkgName;
1061
1207
  let subpath;
@@ -1664,7 +1810,7 @@ async function createServer(inlineConfig = {}) {
1664
1810
  const localUrl = `http://localhost:${actualPort}`;
1665
1811
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1666
1812
  console.log();
1667
- console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.6.0"}`));
1813
+ console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.6.2"}`));
1668
1814
  console.log();
1669
1815
  console.log(` ${import_picocolors.default.green(">")} Local: ${import_picocolors.default.cyan(localUrl)}`);
1670
1816
  if (networkUrl) {
@@ -1791,7 +1937,7 @@ __export(build_exports, {
1791
1937
  async function build(inlineConfig = {}) {
1792
1938
  const config = await resolveConfig(inlineConfig, "build");
1793
1939
  const startTime = performance.now();
1794
- console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.6.0"}`));
1940
+ console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.6.2"}`));
1795
1941
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1796
1942
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1797
1943
  const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
@@ -1952,7 +2098,7 @@ async function buildElectron(inlineConfig = {}) {
1952
2098
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1953
2099
  const startTime = performance.now();
1954
2100
  assertElectronVersion(config);
1955
- console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.6.0"}`));
2101
+ console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.6.2"}`));
1956
2102
  console.log(import_picocolors3.default.dim(` root: ${config.root}`));
1957
2103
  console.log(import_picocolors3.default.dim(` mode: ${config.mode}`));
1958
2104
  console.log(import_picocolors3.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -2104,7 +2250,7 @@ async function startElectronDev(inlineConfig = {}) {
2104
2250
  const { noSpawn, ...rest } = inlineConfig;
2105
2251
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
2106
2252
  warnElectronVersion(config);
2107
- console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.6.0"}`));
2253
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.6.2"}`));
2108
2254
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
2109
2255
  const server = await createServer2({ ...rest, target: "electron" });
2110
2256
  await server.listen();
@@ -2439,6 +2585,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
2439
2585
  }
2440
2586
  });
2441
2587
  cli.help();
2442
- cli.version("1.6.0");
2588
+ cli.version("1.6.2");
2443
2589
  cli.parse();
2444
2590
  //# sourceMappingURL=cli.cjs.map