@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/cli/index.js +242 -170
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.js +158 -86
- package/dist/index.js.map +1 -1
- package/dist/testing.js +109 -52
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
2903
|
-
const
|
|
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
|
-
|
|
2942
|
+
continue;
|
|
2906
2943
|
}
|
|
2907
2944
|
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
2908
2945
|
const resolved = resolveRelativeSpecifier(importer, specifier);
|
|
2909
|
-
if (resolved) {
|
|
2910
|
-
|
|
2911
|
-
|
|
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
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
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
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
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
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
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
|
}
|