@faapi/faapi 6.8.0 → 6.9.1
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 +384 -267
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +26 -12
- package/dist/index.js +353 -247
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-J5pPbjwR.d.ts → routeTypes-CuGMDCGB.d.ts} +20 -4
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +54 -16
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
|
@@ -306,11 +306,25 @@ interface CreateLoggerOptions {
|
|
|
306
306
|
/**
|
|
307
307
|
* `config.log` 的对象形状(config 侧另接受 boolean:false 全静默、true 默认)
|
|
308
308
|
*
|
|
309
|
-
* level 解析顺序:显式值 > `LOG_LEVEL` 环境变量 > `
|
|
309
|
+
* level 解析顺序:显式值 > `LOG_LEVEL` 环境变量 > 模式默认(`dir` 文件模式不过滤,
|
|
310
|
+
* 其余模式 `'info'`;非法值启动报错)。`sink` 与 `dir` 互斥,同时配置启动报错。
|
|
310
311
|
*/
|
|
311
312
|
interface LogConfig {
|
|
313
|
+
/** 实例级级别(覆盖全局 level) */
|
|
312
314
|
level?: LogLevel;
|
|
315
|
+
/** 自定义输出管道(整体接管,与 `dir` 互斥) */
|
|
313
316
|
sink?: LogSink;
|
|
317
|
+
/**
|
|
318
|
+
* 文件日志目录(egg 风格):配置即启用内置文件管道——默认 `app.log` 全量 +
|
|
319
|
+
* `error.log` 仅 error(dup 语义);请求日志自动并入(`accessLog` 缺省 true)
|
|
320
|
+
*/
|
|
321
|
+
dir?: string;
|
|
322
|
+
/** true 时按级别四文件 `debug.log`/`info.log`/`warn.log`/`error.log`(各只含对应级别) */
|
|
323
|
+
splitByLevel?: boolean;
|
|
324
|
+
/** 文件模式下是否保留 console 双写(默认 true;false 纯文件) */
|
|
325
|
+
stdout?: boolean;
|
|
326
|
+
/** 请求日志是否并入统一管道;缺省 = `dir` 配置时 true(见 middleware/logger.md) */
|
|
327
|
+
accessLog?: boolean;
|
|
314
328
|
}
|
|
315
329
|
|
|
316
330
|
/**
|
|
@@ -347,10 +361,11 @@ interface TaskWorkerOptions {
|
|
|
347
361
|
* 任务日志配置(纯数据,postMessage 传入,worker 内联重建日志器注入 taskCtx.log;
|
|
348
362
|
* 缺省时 taskCtx.log 为 undefined):scope/fields 与进程内路径一致(`task:<name>`
|
|
349
363
|
* + jobId/task/attempt),level 为宿主侧生效的全局级别(worker 侧预过滤,
|
|
350
|
-
* 宿主 writeLogEntry
|
|
364
|
+
* 宿主 writeLogEntry 再次过滤;undefined = 宿主未配置阈值——文件管道默认全量,
|
|
365
|
+
* worker 侧同样不过滤)
|
|
351
366
|
*/
|
|
352
367
|
log?: {
|
|
353
|
-
level
|
|
368
|
+
level?: LogLevel;
|
|
354
369
|
scope?: string;
|
|
355
370
|
fields?: Record<string, unknown>;
|
|
356
371
|
};
|
|
@@ -1133,7 +1148,8 @@ interface LoggerOptions {
|
|
|
1133
1148
|
* 错误用 try/catch 捕获,记录后重新抛出(让上层处理)。
|
|
1134
1149
|
* 成功时从 next() 返回的 Response 读取状态码。
|
|
1135
1150
|
*
|
|
1136
|
-
* log 函数每次请求时读取(options.log ??
|
|
1151
|
+
* log 函数每次请求时读取(options.log ?? defaultLog),运行时替换 console.log 或
|
|
1152
|
+
* 切换全局日志配置均会生效。
|
|
1137
1153
|
*/
|
|
1138
1154
|
declare function logger(options?: LoggerOptions): FaapiMiddleware;
|
|
1139
1155
|
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FaapiContext, b as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions, L as LoggerOptions } from './routeTypes-
|
|
1
|
+
import { F as FaapiContext, b as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions, L as LoggerOptions } from './routeTypes-CuGMDCGB.js';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
3
|
import { WebSocket } from 'ws';
|
|
4
4
|
|
package/dist/testing.js
CHANGED
|
@@ -245,16 +245,7 @@ function formatErrorResponse(error, config) {
|
|
|
245
245
|
return jsonOk(body, 500);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
// src/logger/
|
|
249
|
-
var LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
250
|
-
var globalState = {
|
|
251
|
-
level: null,
|
|
252
|
-
sink: null,
|
|
253
|
-
disabled: false
|
|
254
|
-
};
|
|
255
|
-
function globalThreshold() {
|
|
256
|
-
return globalState.level ?? "info";
|
|
257
|
-
}
|
|
248
|
+
// src/logger/formatEntry.ts
|
|
258
249
|
function serializeFieldValue(value) {
|
|
259
250
|
if (value instanceof Error) {
|
|
260
251
|
return { name: value.name, message: value.message, stack: value.stack };
|
|
@@ -277,25 +268,53 @@ function formatEntry(entry) {
|
|
|
277
268
|
}
|
|
278
269
|
return line;
|
|
279
270
|
}
|
|
271
|
+
|
|
272
|
+
// src/logger/logger.ts
|
|
273
|
+
var LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
274
|
+
var globalState = { level: null, sink: null, fileSink: null, stdout: true, accessLog: false, disabled: false };
|
|
275
|
+
function globalThreshold() {
|
|
276
|
+
if (globalState.level) return globalState.level;
|
|
277
|
+
if (globalState.fileSink) return void 0;
|
|
278
|
+
return "info";
|
|
279
|
+
}
|
|
280
|
+
function belowThreshold(level, threshold) {
|
|
281
|
+
return threshold !== void 0 && LEVEL_RANK[level] < LEVEL_RANK[threshold];
|
|
282
|
+
}
|
|
283
|
+
var consoleSink = (entry) => {
|
|
284
|
+
console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
|
|
285
|
+
};
|
|
280
286
|
var CONSOLE_METHOD = {
|
|
281
287
|
debug: "debug",
|
|
282
288
|
info: "info",
|
|
283
289
|
warn: "warn",
|
|
284
290
|
error: "error"
|
|
285
291
|
};
|
|
286
|
-
var consoleSink = (entry) => {
|
|
287
|
-
console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
|
|
288
|
-
};
|
|
289
292
|
function globalDispatch(entry) {
|
|
290
293
|
if (globalState.disabled) return;
|
|
291
|
-
(globalState.sink
|
|
294
|
+
if (globalState.sink) {
|
|
295
|
+
globalState.sink(entry);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (globalState.fileSink) {
|
|
299
|
+
globalState.fileSink.write(entry);
|
|
300
|
+
if (globalState.stdout) consoleSink(entry);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
consoleSink(entry);
|
|
304
|
+
}
|
|
305
|
+
function writeLogEntry(entry) {
|
|
306
|
+
if (belowThreshold(entry.level, globalThreshold())) return;
|
|
307
|
+
globalDispatch(entry);
|
|
308
|
+
}
|
|
309
|
+
function isAccessLogPiped() {
|
|
310
|
+
return !globalState.disabled && globalState.accessLog;
|
|
292
311
|
}
|
|
293
312
|
function createLogger(scope, options) {
|
|
294
313
|
const baseScope = scope;
|
|
295
314
|
const baseFields = options?.fields;
|
|
296
315
|
const write = (level, message, callFields, scopeSuffix) => {
|
|
297
316
|
const threshold = options?.level ?? globalThreshold();
|
|
298
|
-
if (
|
|
317
|
+
if (belowThreshold(level, threshold)) return;
|
|
299
318
|
const entry = {
|
|
300
319
|
level,
|
|
301
320
|
message,
|
|
@@ -4187,9 +4206,28 @@ function etag(options = {}) {
|
|
|
4187
4206
|
}
|
|
4188
4207
|
|
|
4189
4208
|
// src/middleware/logger.ts
|
|
4209
|
+
function levelForStatus(status) {
|
|
4210
|
+
if (status >= 500) return "error";
|
|
4211
|
+
if (status >= 400) return "warn";
|
|
4212
|
+
return "info";
|
|
4213
|
+
}
|
|
4214
|
+
function defaultLog(entry, text) {
|
|
4215
|
+
if (isAccessLogPiped()) {
|
|
4216
|
+
const logEntry = {
|
|
4217
|
+
level: levelForStatus(entry.status),
|
|
4218
|
+
message: text,
|
|
4219
|
+
time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4220
|
+
scope: "access",
|
|
4221
|
+
fields: entry
|
|
4222
|
+
};
|
|
4223
|
+
writeLogEntry(logEntry);
|
|
4224
|
+
return;
|
|
4225
|
+
}
|
|
4226
|
+
console.log(entry);
|
|
4227
|
+
}
|
|
4190
4228
|
function logger(options = {}) {
|
|
4191
4229
|
return async (ctx, next) => {
|
|
4192
|
-
const log = options.log ??
|
|
4230
|
+
const log = options.log ?? defaultLog;
|
|
4193
4231
|
const start = Date.now();
|
|
4194
4232
|
try {
|
|
4195
4233
|
const response = await next();
|