@faapi/faapi 6.10.0 → 6.11.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 CHANGED
@@ -6497,42 +6497,63 @@ function assertLogLevel(value, source) {
6497
6497
  );
6498
6498
  }
6499
6499
  }
6500
+ function createDefaultLoggingState() {
6501
+ return {
6502
+ level: null,
6503
+ consoleLevel: null,
6504
+ sink: null,
6505
+ fileSink: null,
6506
+ stdout: true,
6507
+ accessLog: true,
6508
+ disabled: false
6509
+ };
6510
+ }
6511
+ function getLoggingState() {
6512
+ const g = globalThis;
6513
+ let state2 = g[LOGGING_STATE_KEY];
6514
+ if (!state2) {
6515
+ state2 = createDefaultLoggingState();
6516
+ g[LOGGING_STATE_KEY] = state2;
6517
+ }
6518
+ return state2;
6519
+ }
6500
6520
  function configureLogging(config) {
6521
+ const state2 = getLoggingState();
6501
6522
  const objectConfig = typeof config === "object" ? config : {};
6502
6523
  if (objectConfig.sink && objectConfig.dir) {
6503
6524
  throw new Error(
6504
6525
  "[faapi] config.log.sink and config.log.dir are mutually exclusive: pick one output pipeline (custom sink OR built-in file logs)."
6505
6526
  );
6506
6527
  }
6507
- void globalState.fileSink?.close();
6508
- globalState.disabled = config === false;
6509
- globalState.sink = objectConfig.sink ?? null;
6510
- globalState.accessLog = objectConfig.accessLog ?? true;
6511
- globalState.stdout = objectConfig.stdout ?? true;
6512
- globalState.fileSink = objectConfig.dir ? createFileLogSink({ dir: objectConfig.dir, splitByLevel: objectConfig.splitByLevel }) : null;
6528
+ void state2.fileSink?.close();
6529
+ state2.disabled = config === false;
6530
+ state2.sink = objectConfig.sink ?? null;
6531
+ state2.accessLog = objectConfig.accessLog ?? true;
6532
+ state2.stdout = objectConfig.stdout ?? true;
6533
+ state2.fileSink = objectConfig.dir ? createFileLogSink({ dir: objectConfig.dir, splitByLevel: objectConfig.splitByLevel }) : null;
6513
6534
  if (objectConfig.consoleLevel !== void 0) {
6514
6535
  if (objectConfig.consoleLevel !== false) {
6515
6536
  assertLogLevel(objectConfig.consoleLevel, "config.log.consoleLevel");
6516
6537
  }
6517
- globalState.consoleLevel = objectConfig.consoleLevel;
6538
+ state2.consoleLevel = objectConfig.consoleLevel;
6518
6539
  } else {
6519
- globalState.consoleLevel = null;
6540
+ state2.consoleLevel = null;
6520
6541
  }
6521
6542
  if (objectConfig.level !== void 0) {
6522
6543
  assertLogLevel(objectConfig.level, "config.log.level");
6523
- globalState.level = objectConfig.level;
6544
+ state2.level = objectConfig.level;
6524
6545
  } else if (process.env.LOG_LEVEL !== void 0) {
6525
6546
  assertLogLevel(process.env.LOG_LEVEL, "LOG_LEVEL env");
6526
- globalState.level = process.env.LOG_LEVEL;
6547
+ state2.level = process.env.LOG_LEVEL;
6527
6548
  } else {
6528
- globalState.level = null;
6549
+ state2.level = null;
6529
6550
  }
6530
6551
  }
6531
6552
  function pipelineThreshold() {
6532
- return globalState.level ?? void 0;
6553
+ return getLoggingState().level ?? void 0;
6533
6554
  }
6534
6555
  function consoleThreshold() {
6535
- return globalState.consoleLevel ?? "info";
6556
+ return getLoggingState().consoleLevel ?? "info";
6536
6557
  }
6537
6558
  function belowThreshold(level, threshold) {
6538
6559
  return threshold !== void 0 && LEVEL_RANK[level] < LEVEL_RANK[threshold];
@@ -6546,15 +6567,16 @@ function consoleDispatch(entry) {
6546
6567
  console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
6547
6568
  }
6548
6569
  function globalDispatch(entry) {
6549
- if (globalState.disabled) return;
6570
+ const state2 = getLoggingState();
6571
+ if (state2.disabled) return;
6550
6572
  const pipeThreshold = pipelineThreshold();
6551
- if (globalState.sink) {
6552
- if (!belowThreshold(entry.level, pipeThreshold)) globalState.sink(entry);
6573
+ if (state2.sink) {
6574
+ if (!belowThreshold(entry.level, pipeThreshold)) state2.sink(entry);
6553
6575
  return;
6554
6576
  }
6555
- if (globalState.fileSink) {
6556
- if (!belowThreshold(entry.level, pipeThreshold)) globalState.fileSink.write(entry);
6557
- if (globalState.stdout) consoleDispatch(entry);
6577
+ if (state2.fileSink) {
6578
+ if (!belowThreshold(entry.level, pipeThreshold)) state2.fileSink.write(entry);
6579
+ if (state2.stdout) consoleDispatch(entry);
6558
6580
  return;
6559
6581
  }
6560
6582
  consoleDispatch(entry);
@@ -6563,7 +6585,8 @@ function writeLogEntry(entry) {
6563
6585
  globalDispatch(entry);
6564
6586
  }
6565
6587
  function isAccessLogEnabled() {
6566
- return !globalState.disabled && globalState.accessLog;
6588
+ const state2 = getLoggingState();
6589
+ return !state2.disabled && state2.accessLog;
6567
6590
  }
6568
6591
  function createLogger(scope, options) {
6569
6592
  const baseScope = scope;
@@ -6595,7 +6618,7 @@ function createLogger(scope, options) {
6595
6618
  });
6596
6619
  return makeLogger(void 0);
6597
6620
  }
6598
- var LEVEL_RANK, VALID_LEVELS, globalState, CONSOLE_METHOD;
6621
+ var LEVEL_RANK, VALID_LEVELS, LOGGING_STATE_KEY, CONSOLE_METHOD;
6599
6622
  var init_logger = __esm({
6600
6623
  "src/logger/logger.ts"() {
6601
6624
  "use strict";
@@ -6603,15 +6626,7 @@ var init_logger = __esm({
6603
6626
  init_fileSink();
6604
6627
  LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
6605
6628
  VALID_LEVELS = ["debug", "info", "warn", "error"];
6606
- globalState = {
6607
- level: null,
6608
- consoleLevel: null,
6609
- sink: null,
6610
- fileSink: null,
6611
- stdout: true,
6612
- accessLog: true,
6613
- disabled: false
6614
- };
6629
+ LOGGING_STATE_KEY = /* @__PURE__ */ Symbol.for("faapi.logger.state");
6615
6630
  CONSOLE_METHOD = {
6616
6631
  debug: "debug",
6617
6632
  info: "info",
@@ -7379,6 +7394,9 @@ var init_injectParams = __esm({
7379
7394
  function wrapResult(result, ctx) {
7380
7395
  return wrapOkResult(result, ctx.config);
7381
7396
  }
7397
+ function stashHandlerResult(ctx, result) {
7398
+ ctx.__faapiHandlerResult = result;
7399
+ }
7382
7400
  function mergeMeta(response, meta) {
7383
7401
  const hasMeta = meta.status !== void 0 || Object.keys(meta.headers).length > 0 || meta.setCookies.length > 0;
7384
7402
  if (!hasMeta) return response;
@@ -7447,7 +7465,9 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
7447
7465
  const result = await injectParamsAsync(handler, ctx, body, injectors);
7448
7466
  const sseResponse = pickSseAndAutoClose();
7449
7467
  if (sseResponse) return sseResponse;
7450
- return toResponse(wrapResult(result, ctx), meta);
7468
+ const response = await toResponse(wrapResult(result, ctx), meta);
7469
+ if (!(result instanceof Response)) stashHandlerResult(ctx, result);
7470
+ return response;
7451
7471
  } catch (err) {
7452
7472
  autoCloseSseOnError();
7453
7473
  throw err;
@@ -7458,7 +7478,9 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
7458
7478
  const result = await injectParamsAsync(handler, ctx, body, injectors);
7459
7479
  const sseResponse = pickSseAndAutoClose();
7460
7480
  if (sseResponse) return sseResponse;
7461
- return toResponse(wrapResult(result, ctx), meta);
7481
+ const response = await toResponse(wrapResult(result, ctx), meta);
7482
+ if (!(result instanceof Response)) stashHandlerResult(ctx, result);
7483
+ return response;
7462
7484
  } catch (err) {
7463
7485
  autoCloseSseOnError();
7464
7486
  throw err;
@@ -8560,6 +8582,7 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
8560
8582
  globalInjectors
8561
8583
  });
8562
8584
  const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
8585
+ res.__faapiHandlerResult = ctx.__faapiHandlerResult;
8563
8586
  await sendSuccessResponse(response, res);
8564
8587
  } catch (err) {
8565
8588
  if (res.destroyed || res.writableEnded) return;
@@ -9776,7 +9799,10 @@ async function createAppBase(options) {
9776
9799
  resolve3({
9777
9800
  status: mockRes.statusCode,
9778
9801
  headers: new Headers(mockRes._headers),
9779
- body: parsed
9802
+ body: parsed,
9803
+ // inject raw 捕获桥(第三跳):handler 原始返回值(handleRequest 从 ctx
9804
+ // 桥接到 res;未捕获时 undefined——语义见 InjectResponse.raw 注释)
9805
+ raw: mockRes.__faapiHandlerResult
9780
9806
  });
9781
9807
  });
9782
9808
  const listeners = server.listeners("request");