@faapi/faapi 5.2.0 → 5.4.0

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/testing.js CHANGED
@@ -2770,6 +2770,7 @@ import fs7 from "fs";
2770
2770
  import fg2 from "fast-glob";
2771
2771
 
2772
2772
  // src/cli/aliasPlugin.ts
2773
+ import ts7 from "typescript";
2773
2774
  import path8 from "path";
2774
2775
  import fs6 from "fs";
2775
2776
 
@@ -2869,7 +2870,14 @@ function resolveRelativeSpecifier(importer, specifier) {
2869
2870
  const importerDir = path8.dirname(importer);
2870
2871
  const base = path8.resolve(importerDir, specifier);
2871
2872
  if (PROD_EXTS.some((ext) => specifier.endsWith(ext))) {
2872
- return fs6.existsSync(base) ? base : null;
2873
+ if (fs6.existsSync(base)) return base;
2874
+ if (base.endsWith(".js")) {
2875
+ for (const ext of [".ts", ".tsx", ".jsx"]) {
2876
+ const file = base.slice(0, -3) + ext;
2877
+ if (fs6.existsSync(file)) return file;
2878
+ }
2879
+ }
2880
+ return null;
2873
2881
  }
2874
2882
  if (/\.(ts|tsx|jsx)$/.test(specifier)) {
2875
2883
  return fs6.existsSync(base) ? base : null;
@@ -2885,8 +2893,18 @@ function resolveRelativeSpecifier(importer, specifier) {
2885
2893
  return null;
2886
2894
  }
2887
2895
  function createAliasPlugin(config, options) {
2888
- const SPEC_RE2 = /(\bfrom\s*|import\s*\(\s*)(['"])([^'"]+)\2/g;
2889
2896
  const appDirAbs = options?.rootDir ? toRealPath(path8.resolve(options.rootDir, APP_DIR)) : null;
2897
+ const probeCandidateFile = (candidate) => {
2898
+ for (const ext of SOURCE_EXTS) {
2899
+ const file = candidate + ext;
2900
+ if (fs6.existsSync(file)) return file;
2901
+ }
2902
+ for (const indexExt of INDEX_EXTS) {
2903
+ const file = candidate + indexExt;
2904
+ if (fs6.existsSync(file)) return file;
2905
+ }
2906
+ return null;
2907
+ };
2890
2908
  return {
2891
2909
  name: "faapi-alias",
2892
2910
  setup(build) {
@@ -2899,64 +2917,103 @@ function createAliasPlugin(config, options) {
2899
2917
  }
2900
2918
  const importer = args.path;
2901
2919
  const importerOutsideAppDir = appDirAbs ? !isInsideDir(importer, appDirAbs) : false;
2902
- let modified = false;
2903
- const newSource = source.replace(SPEC_RE2, (full, prefix, quote, specifier) => {
2920
+ const sourceFile = ts7.createSourceFile(importer, source, ts7.ScriptTarget.Latest, false);
2921
+ const literals = [];
2922
+ const visit = (node) => {
2923
+ if (ts7.isImportDeclaration(node)) {
2924
+ if (!node.importClause?.isTypeOnly && node.moduleSpecifier) {
2925
+ if (ts7.isStringLiteral(node.moduleSpecifier)) literals.push(node.moduleSpecifier);
2926
+ }
2927
+ } else if (ts7.isExportDeclaration(node)) {
2928
+ if (!node.isTypeOnly && node.moduleSpecifier) {
2929
+ if (ts7.isStringLiteral(node.moduleSpecifier)) literals.push(node.moduleSpecifier);
2930
+ }
2931
+ } else if (ts7.isCallExpression(node) && node.expression.kind === ts7.SyntaxKind.ImportKeyword && node.arguments[0] && ts7.isStringLiteral(node.arguments[0])) {
2932
+ literals.push(node.arguments[0]);
2933
+ }
2934
+ ts7.forEachChild(node, visit);
2935
+ };
2936
+ ts7.forEachChild(sourceFile, visit);
2937
+ const replacements = [];
2938
+ const unresolvable = [];
2939
+ for (const lit of literals) {
2940
+ const specifier = lit.text;
2904
2941
  if (specifier.startsWith("/") || specifier.startsWith("file:") || specifier.startsWith("node:")) {
2905
- return full;
2942
+ continue;
2906
2943
  }
2907
2944
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
2908
2945
  const resolved = resolveRelativeSpecifier(importer, specifier);
2909
- if (resolved) {
2910
- if (PROD_EXTS.some((ext) => specifier.endsWith(ext))) {
2911
- return full;
2912
- }
2913
- if (appDirAbs && importerOutsideAppDir && isInsideDir(resolved, appDirAbs)) {
2914
- modified = true;
2915
- return `${prefix}${quote}${toProdImportFromImporter(
2916
- importer,
2917
- options.rootDir,
2918
- toStrippedProdImportPath(resolved, options.rootDir)
2919
- )}${quote}`;
2920
- }
2921
- modified = true;
2922
- return `${prefix}${quote}${toProdImportPath(resolved, importer)}${quote}`;
2946
+ if (!resolved) {
2947
+ unresolvable.push(lit);
2948
+ continue;
2923
2949
  }
2924
- return full;
2925
- }
2926
- const candidates = resolveAlias(specifier, config);
2927
- for (const candidate of candidates) {
2928
- for (const ext of SOURCE_EXTS) {
2929
- const file = candidate + ext;
2930
- if (fs6.existsSync(file)) {
2931
- modified = true;
2932
- if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
2933
- return `${prefix}${quote}${toProdImportFromImporter(
2934
- importer,
2935
- options.rootDir,
2936
- toStrippedProdImportPath(file, options.rootDir)
2937
- )}${quote}`;
2938
- }
2939
- return `${prefix}${quote}${toProdImportPath(file, importer)}${quote}`;
2940
- }
2950
+ if (PROD_EXTS.some((ext) => specifier.endsWith(ext))) continue;
2951
+ let prodPath;
2952
+ if (appDirAbs && importerOutsideAppDir && isInsideDir(resolved, appDirAbs)) {
2953
+ prodPath = toProdImportFromImporter(
2954
+ importer,
2955
+ options.rootDir,
2956
+ toStrippedProdImportPath(resolved, options.rootDir)
2957
+ );
2958
+ } else {
2959
+ prodPath = toProdImportPath(resolved, importer);
2941
2960
  }
2942
- for (const indexExt of INDEX_EXTS) {
2943
- const file = candidate + indexExt;
2944
- if (fs6.existsSync(file)) {
2945
- modified = true;
2946
- if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
2947
- return `${prefix}${quote}${toProdImportFromImporter(
2948
- importer,
2949
- options.rootDir,
2950
- toStrippedProdImportPath(file, options.rootDir)
2951
- )}${quote}`;
2952
- }
2953
- return `${prefix}${quote}${toProdImportPath(file, importer)}${quote}`;
2954
- }
2961
+ const quote = source[lit.getStart(sourceFile)];
2962
+ replacements.push({
2963
+ start: lit.getStart(sourceFile),
2964
+ end: lit.getEnd(),
2965
+ text: quote + prodPath + quote
2966
+ });
2967
+ continue;
2968
+ }
2969
+ for (const candidate of resolveAlias(specifier, config)) {
2970
+ const file = probeCandidateFile(candidate);
2971
+ if (!file) continue;
2972
+ let prodPath;
2973
+ if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
2974
+ prodPath = toProdImportFromImporter(
2975
+ importer,
2976
+ options.rootDir,
2977
+ toStrippedProdImportPath(file, options.rootDir)
2978
+ );
2979
+ } else {
2980
+ prodPath = toProdImportPath(file, importer);
2955
2981
  }
2982
+ const quote = source[lit.getStart(sourceFile)];
2983
+ replacements.push({
2984
+ start: lit.getStart(sourceFile),
2985
+ end: lit.getEnd(),
2986
+ text: quote + prodPath + quote
2987
+ });
2988
+ break;
2956
2989
  }
2957
- return full;
2958
- });
2959
- if (!modified) return void 0;
2990
+ }
2991
+ if (unresolvable.length > 0) {
2992
+ const lineStarts = sourceFile.getLineStarts();
2993
+ return {
2994
+ errors: unresolvable.map((lit) => {
2995
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(
2996
+ lit.getStart(sourceFile)
2997
+ );
2998
+ const lineEnd = line + 1 < lineStarts.length ? lineStarts[line + 1] : sourceFile.getEnd();
2999
+ return {
3000
+ text: `\u65E0\u6CD5\u89E3\u6790\u7684\u76F8\u5BF9\u5BFC\u5165 "${lit.text}"\u2014\u2014\u9879\u76EE\u5185\u4E0D\u5B58\u5728\u5BF9\u5E94\u6E90\u6587\u4EF6\uFF08faapi \u9010\u6587\u4EF6\u7F16\u8BD1\uFF08bundle: false\uFF09\u4E0D\u89E3\u6790\u4F9D\u8D56\uFF0C\u8BE5\u5BFC\u5165\u4F1A\u539F\u6837\u8FDB\u5165\u4EA7\u7269\uFF0C\u751F\u4EA7 Node ESM \u8FD0\u884C\u65F6\u62A5 ERR_MODULE_NOT_FOUND\uFF09\u3002\u8BF7\u4FEE\u6B63\u8DEF\u5F84\u6216\u8865\u5168\u540E\u7F00`,
3001
+ location: {
3002
+ file: importer,
3003
+ line: line + 1,
3004
+ column: character,
3005
+ lineText: source.slice(lineStarts[line], lineEnd).replace(/\r?\n$/, "")
3006
+ }
3007
+ };
3008
+ })
3009
+ };
3010
+ }
3011
+ if (replacements.length === 0) return void 0;
3012
+ replacements.sort((a, b) => b.start - a.start);
3013
+ let newSource = source;
3014
+ for (const r of replacements) {
3015
+ newSource = newSource.slice(0, r.start) + r.text + newSource.slice(r.end);
3016
+ }
2960
3017
  return { contents: newSource, loader: "default" };
2961
3018
  });
2962
3019
  }