@faapi/faapi 5.1.0 → 5.3.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.
@@ -152,9 +152,9 @@ interface AgentCore {
152
152
  description?: string;
153
153
  /** 系统提示词(config 块字面量提取);文件型 agent 必填(构建期校验),DB skill 由业务方自治 */
154
154
  systemPrompt?: string;
155
- /** agent 显式声明可用的 tool 引用列表(config 块字面量提取),未声明时为 `undefined`;声明了但含非字面量元素在构建期抛错 */
155
+ /** agent 显式声明可用的 tool 引用列表(config 块字面量提取),未声明时为 `undefined`;声明了但含无法静态求值的元素在构建期抛错 */
156
156
  tools?: string[];
157
- /** 可调用的其他 agent 名列表(config 块字面量提取),未声明时为 `undefined`;声明了但含非字面量元素在构建期抛错 */
157
+ /** 可调用的其他 agent 名列表(config 块字面量提取),未声明时为 `undefined`;声明了但含无法静态求值的元素在构建期抛错 */
158
158
  agents?: string[];
159
159
  /** LLM 模型名(config 块字面量提取),未声明时为 `undefined`;声明了但非字面量在构建期抛错 */
160
160
  model?: string;
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { F as FaapiContext, a as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions, L as LoggerOptions } from './routeTypes-DG0eL3l5.js';
1
+ import { F as FaapiContext, a as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions, L as LoggerOptions } from './routeTypes-Bm--uTbm.js';
2
2
  import { Server } from 'node:http';
3
3
  import { WebSocket } from 'ws';
4
4
 
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
  }