@faapi/faapi 0.0.0-canary.2a7b6a3 → 0.0.0-canary.4e89b9b

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/index.d.ts CHANGED
@@ -307,6 +307,8 @@ interface LoggerOptions {
307
307
  * before/after 一体,闭包变量共享开始时间,无需污染 ctx。
308
308
  * 错误用 try/catch 捕获,记录后重新抛出(让上层处理)。
309
309
  * 成功时从 next() 返回的 Response 读取状态码。
310
+ *
311
+ * log 函数每次请求时读取(options.log ?? console.log),运行时替换 console.log 会生效。
310
312
  */
311
313
  declare function logger(options?: LoggerOptions): FaapiMiddleware;
312
314
 
@@ -561,9 +563,8 @@ interface LifecycleContext {
561
563
  * 环境覆盖通过 faapi.config.{NODE_ENV}.ts 实现(如 faapi.config.production.ts)
562
564
  *
563
565
  * 框架元信息通过环境变量配置(不放在 config 内):
564
- * - `FAAPI_APP_DIR`:源码目录前缀,默认 'src',设为 '.' 表示源码在项目根目录
565
566
  * - `PORT`:服务端口,默认 3000
566
- * - `FAAPI_OUT_DIR`:产物输出目录,dev 固定为 '.faapi/dev',prod 默认 'dist'
567
+ * - `FAAPI_DIST`:产物输出目录,dev 固定为 `.faapi`(不可修改),prod 默认为 `dist`(可通过 `--dist` 修改)
567
568
  */
568
569
  interface FaapiConfig {
569
570
  /** CORS 配置,false 禁用 */
@@ -810,6 +811,13 @@ type RuntimeType = {
810
811
  kind: 'record';
811
812
  key: RuntimeType;
812
813
  value: RuntimeType;
814
+ } | {
815
+ kind: 'map';
816
+ key: RuntimeType;
817
+ value: RuntimeType;
818
+ } | {
819
+ kind: 'set';
820
+ element: RuntimeType;
813
821
  } | {
814
822
  kind: 'ref';
815
823
  name: string;
@@ -949,6 +957,18 @@ interface RouteSchemaSource {
949
957
  filePath: string;
950
958
  schemaName: string;
951
959
  typeInfo: HandlerTypeInfo | null;
960
+ /**
961
+ * 是否对 number/boolean 字段生成 z.preprocess 字符串转换(coerce)。
962
+ *
963
+ * - query/params:始终 coerce=true(URL 来源均为 string)
964
+ * - body:始终 coerce=false(JSON 解析已是天然 JS 类型)
965
+ * - form:coerce=true(form-urlencoded 来源均为 string),由本函数在提取时
966
+ * 检测到 handler 声明 `form` 参数时显式设置。schema 名仍为 `POSTBody`
967
+ * (与 body 共享运行时 schema key),运行时 validateInput 无需感知 form/body 差异。
968
+ *
969
+ * 未设置时由 generateSchemaFileSource 回退到 schemaName 后缀正则推断(Query/Params → true)。
970
+ */
971
+ coerce?: boolean;
952
972
  }
953
973
  /**
954
974
  * 从路由清单收集 schema 提取所需的原始数据
@@ -974,8 +994,8 @@ declare function collectRouteSchemaSources(routes: RouteManifest, rootDir?: stri
974
994
  /**
975
995
  * 加载 faapi 配置文件
976
996
  *
977
- * 统一读取 `<outDir>/faapi-config.js` 产物:
978
- * - dev 模式:`faapi dev` 启动时由 `compileConfig` 生成 `.faapi/dev/faapi-config.js`
997
+ * 统一读取 `<dist>/faapi-config.js` 产物:
998
+ * - dev 模式:`faapi dev` 启动时由 `compileConfig` 生成 `.faapi/faapi-config.js`
979
999
  * - prod 模式:`faapi build` 时由 `compileConfig` 生成 `dist/faapi-config.js`
980
1000
  *
981
1001
  * 产物由 `compileConfig` 在构建阶段合并 env 后固化,运行时不读源码、不现场编译、不按 env 合并。
@@ -985,10 +1005,10 @@ declare function collectRouteSchemaSources(routes: RouteManifest, rootDir?: stri
985
1005
  * - 源码也无配置文件 → 返回 `null`(配置可选)
986
1006
  *
987
1007
  * @param rootDir 项目根目录
988
- * @param outDir 产物目录(如 'dist' 或 '.faapi/dev')
1008
+ * @param dist 产物目录(如 'dist' 或 '.faapi')
989
1009
  * @returns 配置对象,无配置文件时返回 null
990
1010
  */
991
- declare function loadConfig(rootDir: string, outDir: string): Promise<Partial<FaapiConfig> | null>;
1011
+ declare function loadConfig(rootDir: string, dist: string): Promise<Partial<FaapiConfig> | null>;
992
1012
 
993
1013
  declare const VALIDATION_ERROR = "VALIDATION_ERROR";
994
1014
  declare const ROUTE_NOT_FOUND = "ROUTE_NOT_FOUND";
@@ -1044,6 +1064,30 @@ interface ValidationIssue {
1044
1064
  }
1045
1065
  type ValidationErrorCode = 'TYPE_MISMATCH' | 'MISSING_FIELD' | 'INVALID_FORMAT' | 'INVALID_VALUE' | 'COERCE_FAILED';
1046
1066
 
1067
+ /**
1068
+ * 从 Request 对象创建 FaapiContext
1069
+ * @param request Web Request 对象
1070
+ * @param params 动态路由参数
1071
+ * @param config 自定义业务配置(来自 faapi.config.ts)
1072
+ * @param ip 客户端 IP(由调用方从 IncomingMessage 提取,HTTP/WS 握手均通过 utils/getClientIp)
1073
+ */
1074
+ declare function createContext(request: Request, params: Record<string, string>, config?: Record<string, unknown>, ip?: string): FaapiContext;
1075
+
1076
+ /**
1077
+ * 调用路由 handler 并将返回值转为 Response
1078
+ *
1079
+ * 流程(洋葱模型):
1080
+ * 1. 中间件按洋葱模型执行:mw1.before → mw2.before → ... → handler → ... → mw2.after → mw1.after
1081
+ * 2. 中间件不调用 next() 即拦截请求(必须返回 Response)
1082
+ * 3. 中间件可用 try/catch 捕获内层错误
1083
+ * 4. 最内层执行注入器(按需)→ handler
1084
+ *
1085
+ * 注入器与中间件解耦:
1086
+ * - 注入器按 handler 参数名匹配,只执行需要的
1087
+ * - 注入器可读取中间件塞进 ctx 的值
1088
+ */
1089
+ declare function invokeHandler(handler: (...args: unknown[]) => unknown, ctx: FaapiContext, body?: unknown, middlewares?: FaapiMiddleware[], injectors?: InjectorMap): Promise<Response>;
1090
+
1047
1091
  interface InjectOptions {
1048
1092
  method?: string;
1049
1093
  path?: string;
@@ -1059,8 +1103,8 @@ interface InjectResponse {
1059
1103
  interface CreateAppOptions {
1060
1104
  /** 项目根目录,默认 process.cwd() */
1061
1105
  rootDir?: string;
1062
- /** 源码目录前缀,覆盖环境变量 FAAPI_APP_DIR,默认 'src' */
1063
- appDir?: string;
1106
+ /** 产物输出目录(如 dist 或 .faapi),覆盖环境变量 FAAPI_DIST,默认 'dist' */
1107
+ dist?: string;
1064
1108
  /** 端口号,也可在 listen() 时传入;默认环境变量 PORT 或 3000 */
1065
1109
  port?: number;
1066
1110
  }
@@ -1108,7 +1152,7 @@ interface DevApp extends AppBase {
1108
1152
  * // devCommand 内部
1109
1153
  * const app = await createDevApp();
1110
1154
  * await app.listen();
1111
- * startWatcher({ rootDir, appDir, app });
1155
+ * startWatcher({ rootDir, app, devDist });
1112
1156
  * ```
1113
1157
  */
1114
1158
  declare function createDevApp(options?: CreateAppOptions): Promise<DevApp>;
@@ -1137,4 +1181,4 @@ type ProdApp = AppBase;
1137
1181
  */
1138
1182
  declare function createProdApp(options?: CreateAppOptions): Promise<ProdApp>;
1139
1183
 
1140
- export { type ProdApp as App, type CorsOptions, type CreateAppOptions, type DevApp, type FaapiConfig, type FaapiContext, type FaapiContextConfig, FaapiError, type FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, type HelmetOptions, type InjectOptions, type InjectResponse, type Injector, type InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, type LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type RouteInfo, type RouteInputSchema, type RouteManifest, RouteNotFoundError, type RouteOutputSchema, type RouteParamSchema, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, type SseEvent, type SseWriter, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, collectRouteSchemaSources, cors, createProdApp as createApp, createDevApp, createProdApp, createProgram, extractTypeInfo, getInputTypeForMethod, helmet, invalidateProgramCache, loadConfig, logger, resolveTypeNode };
1184
+ export { type ProdApp as App, type CorsOptions, type CreateAppOptions, type DevApp, type FaapiConfig, type FaapiContext, type FaapiContextConfig, FaapiError, type FaapiMiddleware, type FaapiPlugin, type HandlerTypeInfo, type HelmetOptions, type InjectOptions, type InjectResponse, type Injector, type InjectorMap, InternalError, type LifecycleContext, type LifecycleHooks, type LoggerOptions, MethodNotAllowedError, ModuleLoadError, type PluginContext, type PluginDeclaration, type ProdApp, type PropertyType, type RequestHandler, type RouteInfo, type RouteInputSchema, type RouteManifest, RouteNotFoundError, type RouteOutputSchema, type RouteParamSchema, type RouteSchemaSource, type RuntimeType, SchemaExtractionError, type SseEvent, type SseWriter, type TypeConstraint, type UpgradeHandler, ValidationError, type ValidationErrorCode, type ValidationIssue, type WsContext, type WsEventHandlers, type WsHandler, type WsSocket, collectRouteSchemaSources, cors, createProdApp as createApp, createContext, createDevApp, createProdApp, createProgram, extractTypeInfo, getInputTypeForMethod, helmet, invalidateProgramCache, invokeHandler, loadConfig, logger, resolveTypeNode };