/* Auto-generated CJS entry by build-cjs.mjs — DO NOT EDIT */
const __vext_esm_url = require("node:url").pathToFileURL(__filename).href;
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// dist/adapters/express/index.js
var index_exports = {};
__export(index_exports, {
  createExpressAdapter: () => createExpressAdapter,
  expressAdapter: () => expressAdapter
});
module.exports = __toCommonJS(index_exports);

// dist/adapters/express/adapter.js
var import_express = __toESM(require("express"), 1);
var import_node_crypto = __toESM(require("node:crypto"), 1);
var import_node_http = require("node:http");

// dist/lib/middlewares/body-parser.js
function parseBytes(value) {
  if (typeof value === "number") {
    return value;
  }
  const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)$/i);
  if (!match) {
    throw new Error(`[vextjs] Invalid body size format: "${value}". Expected format: '1mb', '512kb', '1gb', or a number (bytes).`);
  }
  const num = parseFloat(match[1]);
  const unit = match[2].toLowerCase();
  const multipliers = {
    b: 1,
    kb: 1024,
    mb: 1024 * 1024,
    gb: 1024 * 1024 * 1024
  };
  return Math.floor(num * multipliers[unit]);
}
__name(parseBytes, "parseBytes");
var PayloadTooLargeError = class extends Error {
  static {
    __name(this, "PayloadTooLargeError");
  }
  maxBytes;
  status = 413;
  constructor(maxBytes) {
    super("Payload Too Large");
    this.maxBytes = maxBytes;
    this.name = "PayloadTooLargeError";
  }
};
function createPayloadTooLargeError(maxBytes) {
  return new PayloadTooLargeError(maxBytes);
}
__name(createPayloadTooLargeError, "createPayloadTooLargeError");
function isPayloadTooLargeError(err) {
  return err instanceof PayloadTooLargeError || typeof err === "object" && err !== null && err.status === 413 && err.message === "Payload Too Large";
}
__name(isPayloadTooLargeError, "isPayloadTooLargeError");
function assertBodySize(size, maxBytes) {
  if (maxBytes !== void 0 && size > maxBytes) {
    throw createPayloadTooLargeError(maxBytes);
  }
}
__name(assertBodySize, "assertBodySize");
function resolveRouteBodyParserConfig(routeOptions) {
  if (routeOptions?.bodyParser)
    return routeOptions.bodyParser;
  if (routeOptions?.override?.maxBodySize !== void 0) {
    return { maxBodySize: routeOptions.override.maxBodySize };
  }
  return void 0;
}
__name(resolveRouteBodyParserConfig, "resolveRouteBodyParserConfig");
function resolveAdapterBodyLimitBytes(args) {
  const bodyParserLimit = parseBytes(args.routeBodyParser?.maxBodySize ?? args.globalBodyParser?.maxBodySize ?? "1mb");
  const adapterLimit = args.adapterBodyLimit !== void 0 ? parseBytes(args.adapterBodyLimit) : void 0;
  return adapterLimit === void 0 ? bodyParserLimit : Math.min(bodyParserLimit, adapterLimit);
}
__name(resolveAdapterBodyLimitBytes, "resolveAdapterBodyLimitBytes");

// dist/adapters/express/request.js
function createVextRequest(expressReq, app, rawBody) {
  const trustProxy = app.config.trustProxy ?? false;
  const closeHandlers = [];
  const queryRecord = {};
  if (expressReq.query && typeof expressReq.query === "object") {
    for (const [key, value] of Object.entries(expressReq.query)) {
      if (typeof value === "string") {
        queryRecord[key] = value;
      } else if (Array.isArray(value) && typeof value[0] === "string") {
        queryRecord[key] = value[0];
      }
    }
  }
  const urlPath = expressReq.url.split("?")[0] ?? "/";
  let _rawBodyCache;
  function getRawBody(maxBytes) {
    if (_rawBodyCache !== void 0) {
      assertBodySize(Buffer.byteLength(_rawBodyCache, "utf-8"), maxBytes);
      return Promise.resolve(_rawBodyCache);
    }
    if (rawBody === void 0 || rawBody === null) {
      _rawBodyCache = "";
      return Promise.resolve(_rawBodyCache);
    }
    if (Buffer.isBuffer(rawBody)) {
      assertBodySize(rawBody.byteLength, maxBytes);
      _rawBodyCache = rawBody.toString("utf-8");
      return Promise.resolve(_rawBodyCache);
    }
    if (typeof rawBody === "string") {
      assertBodySize(Buffer.byteLength(rawBody, "utf-8"), maxBytes);
      _rawBodyCache = rawBody;
      return Promise.resolve(_rawBodyCache);
    }
    _rawBodyCache = "";
    return Promise.resolve(_rawBodyCache);
  }
  __name(getRawBody, "getRawBody");
  function getRawBodyBuffer(maxBytes) {
    if (rawBody === void 0 || rawBody === null)
      return Promise.resolve(Buffer.alloc(0));
    if (Buffer.isBuffer(rawBody)) {
      assertBodySize(rawBody.byteLength, maxBytes);
      return Promise.resolve(rawBody);
    }
    return Promise.resolve(Buffer.alloc(0));
  }
  __name(getRawBodyBuffer, "getRawBodyBuffer");
  let ip;
  if (trustProxy) {
    const xff = expressReq.headers["x-forwarded-for"];
    if (typeof xff === "string") {
      const firstIp = xff.split(",")[0];
      ip = firstIp ? firstIp.trim() : expressReq.socket.remoteAddress ?? "127.0.0.1";
    } else if (Array.isArray(xff) && xff.length > 0) {
      const firstEntry = xff[0];
      const firstIp = firstEntry ? firstEntry.split(",")[0] : void 0;
      ip = firstIp ? firstIp.trim() : expressReq.socket.remoteAddress ?? "127.0.0.1";
    } else {
      ip = expressReq.socket.remoteAddress ?? "127.0.0.1";
    }
  } else {
    ip = expressReq.socket.remoteAddress ?? "127.0.0.1";
  }
  let protocol;
  if (trustProxy) {
    const proto = expressReq.headers["x-forwarded-proto"];
    protocol = proto === "https" ? "https" : "http";
  } else {
    const encrypted = expressReq.socket?.encrypted;
    protocol = encrypted ? "https" : "http";
  }
  const req = {
    // ── 原始数据 ────────────────────────────────────────
    query: queryRecord,
    body: void 0,
    // body-parser 中间件负责填充
    params: expressReq.params ?? {},
    headers: expressReq.headers,
    method: expressReq.method.toUpperCase(),
    url: expressReq.originalUrl ?? expressReq.url,
    path: urlPath,
    route: "",
    // F-01: 由 registerRoute handler 在路由匹配后覆写为真实路由模板
    // ── 元信息 ──────────────────────────────────────────
    app,
    requestId: "",
    // requestId 中间件负责填充
    ip,
    protocol,
    // ── 生命周期 ────────────────────────────────────────
    onClose(handler) {
      closeHandlers.push(handler);
    },
    // ── 校验数据 ────────────────────────────────────────
    valid(location) {
      return req[`_validated_${location}`];
    },
    // ── 内部方法（body-parser 中间件使用）───────────────────
    _getRawBody: getRawBody,
    _getRawBodyBuffer: getRawBodyBuffer
  };
  expressReq.on("close", () => {
    for (const h of closeHandlers) {
      try {
        h();
      } catch {
      }
    }
    closeHandlers.length = 0;
  });
  return req;
}
__name(createVextRequest, "createVextRequest");

// dist/adapters/express/response.js
function createVextResponse(expressRes, getRequestId) {
  let _status = 200;
  const _headers = {};
  let _wrapEnabled = false;
  let _sent = false;
  function applyHeaders() {
    for (const [k, v] of Object.entries(_headers)) {
      expressRes.setHeader(k, v);
    }
  }
  __name(applyHeaders, "applyHeaders");
  function checkSent(methodName) {
    if (_sent) {
      if (process.env.NODE_ENV !== "production") {
        console.warn(`[vextjs] ⚠️ res.${methodName}() called after response already sent. This is a no-op. Check your handler for duplicate sends.`);
      }
      return true;
    }
    _sent = true;
    return false;
  }
  __name(checkSent, "checkSent");
  const res = {
    /**
     * 返回 JSON 响应
     *
     * 当出口包装开启时（response-wrapper 中间件已执行 _enableWrap()），
     * 自动包装为：{ code: 0, data, requestId }
     * 当包装未开启时，直接发送原始 data。
     *
     * 204 特殊处理：无论包装是否开启，204 均不发送消息体（RFC 9110 §15.3.5）。
     *
     * Express 特殊处理：
     *   使用 expressRes.end(JSON.stringify(...)) 手动序列化，
     *   而非 expressRes.json(object)（会触发 Express 内置 JSON 处理），
     *   确保与 Hono / Fastify Adapter 行为一致。
     */
    json(data, status) {
      if (checkSent("json"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      if (res._onSend) {
        res._onSend(data, finalStatus, { ..._headers });
      }
      expressRes.statusCode = finalStatus;
      applyHeaders();
      if (_wrapEnabled) {
        if (finalStatus === 204) {
          expressRes.removeHeader("Content-Type");
          expressRes.end();
          return;
        }
        expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
        expressRes.end(JSON.stringify({
          code: 0,
          data,
          requestId: getRequestId()
        }));
        return;
      }
      if (finalStatus === 204) {
        expressRes.removeHeader("Content-Type");
        expressRes.end();
        return;
      }
      expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
      expressRes.end(JSON.stringify(data));
    },
    /**
     * 返回原始 JSON（不经过出口包装）
     *
     * 仅框架内部错误处理使用，用户代码不应直接调用。
     * 通过 VextPublicResponse 类型从用户可见接口中排除。
     *
     * @internal
     */
    rawJson(data, status) {
      if (checkSent("rawJson"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      expressRes.statusCode = finalStatus;
      applyHeaders();
      expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
      expressRes.end(JSON.stringify(data));
    },
    /**
     * 返回纯文本响应（不经过出口包装）
     */
    text(content, status) {
      if (checkSent("text"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      expressRes.statusCode = finalStatus;
      expressRes.setHeader("Content-Type", "text/plain; charset=utf-8");
      applyHeaders();
      expressRes.end(content);
    },
    /**
     * 流式响应（大文件传输、实时数据流）
     *
     * Express 基于 Node.js 原生 HTTP，直接将 ReadableStream pipe 到 response。
     */
    stream(readable, contentType = "application/octet-stream") {
      if (checkSent("stream"))
        return;
      expressRes.statusCode = _status;
      expressRes.setHeader("Content-Type", contentType);
      applyHeaders();
      readable.pipe(expressRes);
    },
    /**
     * 文件下载（触发浏览器下载行为）
     *
     * 自动设置 Content-Disposition: attachment 头，
     * 触发浏览器的文件下载对话框。
     */
    download(readable, filename, contentType) {
      if (checkSent("download"))
        return;
      const ct = contentType ?? "application/octet-stream";
      expressRes.statusCode = _status;
      expressRes.setHeader("Content-Type", ct);
      expressRes.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
      applyHeaders();
      readable.pipe(expressRes);
    },
    /**
     * 重定向
     *
     * Express 原生支持 res.redirect()，但这里使用手动设置 Location 头 + end()
     * 的方式，与 Hono / Fastify Adapter 行为保持一致。
     */
    redirect(url, status = 302) {
      if (checkSent("redirect"))
        return;
      applyHeaders();
      expressRes.statusCode = status;
      expressRes.setHeader("Location", url);
      expressRes.end();
    },
    /**
     * 设置 HTTP 状态码（链式调用）
     */
    status(code) {
      _status = code;
      return res;
    },
    /**
     * 设置响应头（链式调用）
     */
    setHeader(name, value) {
      _headers[name] = value;
      return res;
    },
    /**
     * 当前 HTTP 状态码（只读）
     *
     * 返回通过 .status() 设置的值，或 json/rawJson/text 等方法
     * 传入的 status 参数所确定的最终状态码。默认 200。
     *
     * 主要用途：洋葱模型 after-middleware 在 `await next()` 后
     * 读取响应状态码（如 access-log 中间件记录请求耗时与状态码）。
     */
    get statusCode() {
      return _status;
    },
    /**
     * 开启出口包装标志（内部方法）
     *
     * 仅由 response-wrapper 中间件调用，用户代码不应直接调用。
     * 调用后 json() 将自动包装响应为 { code: 0, data, requestId }。
     *
     * @internal
     */
    _enableWrap() {
      _wrapEnabled = true;
    }
  };
  return res;
}
__name(createVextResponse, "createVextResponse");

// dist/lib/request-context.js
var import_node_async_hooks = require("node:async_hooks");
var GLOBAL_KEY = /* @__PURE__ */ Symbol.for("vextjs.requestContext");
function getOrCreateRequestContext() {
  const existing = globalThis[GLOBAL_KEY];
  if (existing instanceof import_node_async_hooks.AsyncLocalStorage) {
    return existing;
  }
  const instance = new import_node_async_hooks.AsyncLocalStorage();
  globalThis[GLOBAL_KEY] = instance;
  return instance;
}
__name(getOrCreateRequestContext, "getOrCreateRequestContext");
var requestContext = getOrCreateRequestContext();

// dist/lib/server-config.js
function createNodeServerOptions(config) {
  const options = {};
  if (config?.requestTimeout !== void 0) {
    options.requestTimeout = config.requestTimeout;
  }
  if (config?.headersTimeout !== void 0) {
    options.headersTimeout = config.headersTimeout;
  }
  if (config?.keepAliveTimeout !== void 0) {
    options.keepAliveTimeout = config.keepAliveTimeout;
  }
  if (config?.maxHeaderSize !== void 0) {
    options.maxHeaderSize = config.maxHeaderSize;
  }
  if (config?.connectionsCheckingInterval !== void 0) {
    options.connectionsCheckingInterval = config.connectionsCheckingInterval;
  }
  return options;
}
__name(createNodeServerOptions, "createNodeServerOptions");
function applyServerConfig(server, config) {
  if (!config) {
    return;
  }
  if (config.requestTimeout !== void 0) {
    server.requestTimeout = config.requestTimeout;
  }
  if (config.headersTimeout !== void 0) {
    server.headersTimeout = config.headersTimeout;
  }
  if (config.keepAliveTimeout !== void 0) {
    server.keepAliveTimeout = config.keepAliveTimeout;
  }
  if (config.socketTimeout !== void 0) {
    server.timeout = config.socketTimeout;
  }
  if (config.maxRequestsPerSocket !== void 0) {
    server.maxRequestsPerSocket = config.maxRequestsPerSocket;
  }
}
__name(applyServerConfig, "applyServerConfig");

// dist/adapters/express/adapter.js
async function executeChain(chain, req, res) {
  const len = chain.length;
  if (len === 1) {
    await chain[0](req, res, _noop);
    return;
  }
  if (len === 2) {
    await chain[0](req, res, async () => {
      await chain[1](req, res, _noop);
    });
    return;
  }
  if (len === 3) {
    await chain[0](req, res, async () => {
      await chain[1](req, res, async () => {
        await chain[2](req, res, _noop);
      });
    });
    return;
  }
  if (len === 4) {
    await chain[0](req, res, async () => {
      await chain[1](req, res, async () => {
        await chain[2](req, res, async () => {
          await chain[3](req, res, _noop);
        });
      });
    });
    return;
  }
  async function dispatch(i) {
    if (i >= len)
      return;
    const middleware = chain[i];
    await middleware(req, res, () => dispatch(i + 1));
  }
  __name(dispatch, "dispatch");
  await dispatch(0);
}
__name(executeChain, "executeChain");
var _noop = /* @__PURE__ */ __name(async () => {
}, "_noop");
function collectRawBody(req, maxBytes) {
  return new Promise((resolve, reject) => {
    const method = (req.method ?? "GET").toUpperCase();
    if (method === "GET" || method === "HEAD") {
      resolve(Buffer.alloc(0));
      return;
    }
    const chunks = [];
    let total = 0;
    let settled = false;
    req.on("data", (chunk) => {
      if (settled)
        return;
      const bufferChunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
      total += bufferChunk.byteLength;
      if (maxBytes !== void 0 && total > maxBytes) {
        settled = true;
        reject(createPayloadTooLargeError(maxBytes));
        return;
      }
      chunks.push(bufferChunk);
    });
    req.on("end", () => {
      if (settled)
        return;
      settled = true;
      resolve(Buffer.concat(chunks));
    });
    req.on("error", (err) => {
      if (settled)
        return;
      settled = true;
      reject(err);
    });
  });
}
__name(collectRawBody, "collectRawBody");
function createExpressAdapter(options, app) {
  const expressApp = (0, import_express.default)();
  expressApp.disable("x-powered-by");
  expressApp.disable("etag");
  const alsEnabled = app.config.requestContext?.enabled !== false;
  const globalMiddlewares = [];
  let errorHandler = null;
  let notFoundHandler = null;
  let _fallbacksRegistered = false;
  function registerFallbacks() {
    if (_fallbacksRegistered)
      return;
    _fallbacksRegistered = true;
    expressApp.use(async (expressReq, expressRes, _next) => {
      if (!notFoundHandler) {
        expressRes.statusCode = 404;
        expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
        expressRes.end(JSON.stringify({ code: 404, message: "Not Found" }));
        return;
      }
      const routeBodyParser = void 0;
      const maxBodyBytes = resolveAdapterBodyLimitBytes({
        globalBodyParser: app.config.bodyParser,
        routeBodyParser,
        multipart: app.config.multipart,
        adapterBodyLimit: options.bodyLimit
      });
      let rawBody;
      try {
        rawBody = await collectRawBody(expressReq, maxBodyBytes);
      } catch (error) {
        if (isPayloadTooLargeError(error)) {
          expressRes.status(413).json({
            error: "Payload Too Large",
            message: `Request body exceeds maximum size of ${maxBodyBytes} bytes`
          });
          return;
        }
        throw error;
      }
      const req = createVextRequest(expressReq, app, rawBody);
      if (routeBodyParser) {
        req._routeBodyParser = routeBodyParser;
      }
      if (!req.requestId) {
        const headerName = app.config.requestId?.header ?? "x-request-id";
        req.requestId = req.headers[headerName] || import_node_crypto.default.randomUUID();
      }
      const res = createVextResponse(expressRes, () => req.requestId);
      const runNotFound = /* @__PURE__ */ __name(async () => {
        const noop = /* @__PURE__ */ __name(async () => {
        }, "noop");
        await notFoundHandler(req, res, noop);
      }, "runNotFound");
      if (alsEnabled) {
        await requestContext.run({ requestId: req.requestId, locale: void 0 }, runNotFound);
      } else {
        await runNotFound();
      }
    });
    expressApp.use((err, expressReq, expressRes, _next) => {
      if (errorHandler) {
        try {
          const req = createVextRequest(expressReq, app);
          if (!req.requestId) {
            const headerName = app.config.requestId?.header ?? "x-request-id";
            req.requestId = req.headers[headerName] || import_node_crypto.default.randomUUID();
          }
          const res = createVextResponse(expressRes, () => req.requestId);
          errorHandler(err, req, res);
        } catch {
          if (!expressRes.headersSent) {
            expressRes.statusCode = 500;
            expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
            expressRes.end(JSON.stringify({ code: 500, message: "Internal Server Error" }));
          }
        }
      } else {
        if (!expressRes.headersSent) {
          expressRes.statusCode = 500;
          expressRes.setHeader("Content-Type", "application/json; charset=utf-8");
          expressRes.end(JSON.stringify({ code: 500, message: "Internal Server Error" }));
        }
      }
    });
  }
  __name(registerFallbacks, "registerFallbacks");
  return {
    name: "express",
    // ── registerMiddleware ───────────────────────────────────
    //
    // 收集全局中间件。bootstrap 步骤⑥中注册的内置中间件
    // （requestId / cors / body-parser / rate-limit / response-wrapper / access-log）
    // 和插件通过 app.use() 注册的中间件都通过此方法收集。
    //
    // 执行时机：在每个路由的 handler 中，全局中间件拼接在路由级中间件之前执行。
    //
    registerMiddleware(middleware) {
      globalMiddlewares.push(middleware);
    },
    // ── registerRoute ───────────────────────────────────────
    //
    // 为每条路由注册 Express handler。
    //
    // 流程：
    //   1. 将 HTTP 方法转为小写（Express API 使用小写方法名）
    //   2. 路由路径参数格式：vext 使用 :param，Express 也使用 :param，无需转换
    //   3. 在 handler 中收集 rawBody、创建 VextRequest / VextResponse
    //   4. 在 AsyncLocalStorage 请求上下文中执行 executeChain
    //   5. 全局中间件 + 路由级中间件 + validate + handler 组成完整链
    //
    // 错误处理：
    //   - executeChain 抛出异常时，由 errorHandler 处理
    //   - errorHandler 自身也可能抛出异常（如 logger 写入失败），
    //     此时发送最低限度的 500 JSON 响应
    //
    registerRoute(method, path, chain, routeOptions = {}) {
      let prebuiltChain = null;
      const expressMethod = method.toLowerCase();
      const expressPath = path;
      expressApp[expressMethod](expressPath, async (expressReq, expressRes, next) => {
        try {
          const routeBodyParser = resolveRouteBodyParserConfig(routeOptions);
          const maxBodyBytes = resolveAdapterBodyLimitBytes({
            globalBodyParser: app.config.bodyParser,
            routeBodyParser,
            multipart: app.config.multipart,
            adapterBodyLimit: options.bodyLimit
          });
          let rawBody;
          try {
            rawBody = await collectRawBody(expressReq, maxBodyBytes);
          } catch (error) {
            if (isPayloadTooLargeError(error)) {
              expressRes.status(413).json({
                error: "Payload Too Large",
                message: `Request body exceeds maximum size of ${maxBodyBytes} bytes`
              });
              return;
            }
            throw error;
          }
          const req = createVextRequest(expressReq, app, rawBody);
          req._routeOptions = routeOptions;
          if (routeBodyParser) {
            req._routeBodyParser = routeBodyParser;
          }
          req.route = expressPath;
          const res = createVextResponse(expressRes, () => req.requestId);
          const runChain = /* @__PURE__ */ __name(async () => {
            try {
              if (prebuiltChain === null) {
                prebuiltChain = globalMiddlewares.concat(chain);
              }
              await executeChain(prebuiltChain, req, res);
            } catch (err) {
              if (errorHandler) {
                try {
                  errorHandler(err, req, res);
                } catch (handlerError) {
                  try {
                    res.rawJson({ code: 500, message: "Internal Server Error" }, 500);
                  } catch {
                    next(handlerError);
                  }
                }
              } else {
                next(err);
              }
            }
          }, "runChain");
          if (alsEnabled) {
            await requestContext.run({ requestId: "", locale: void 0 }, runChain);
          } else {
            await runChain();
          }
        } catch (err) {
          next(err);
        }
      });
    },
    // ── registerErrorHandler ────────────────────────────────
    //
    // 注册全局错误处理函数。
    //
    // 与 Hono / Fastify 不同，Express 的错误处理中间件是通过
    // app.use((err, req, res, next) => ...) 注册的 4 参数中间件。
    //
    // 这里仅保存 handler 引用，实际的 Express 错误中间件
    // 在 registerFallbacks() 中注册（确保在所有路由之后）。
    //
    registerErrorHandler(handler) {
      errorHandler = handler;
    },
    // ── registerNotFound ────────────────────────────────────
    //
    // 注册 404 兜底处理函数。
    //
    // 当没有任何路由匹配时，Express 会将请求传递到后续的 use() 中间件。
    // 实际的 Express 404 中间件在 registerFallbacks() 中注册。
    //
    registerNotFound(handler) {
      notFoundHandler = handler;
    },
    // ── listen ──────────────────────────────────────────────
    //
    // 启动 HTTP 服务器。
    //
    // 流程：
    //   1. 注册兜底中间件（404 + 错误处理）
    //   2. 创建 Node.js HTTP server（Express 不内置 server 创建）
    //   3. 调用 server.listen() 开始监听端口
    //   4. 返回 VextServerHandle（含 close / port / host）
    //
    async listen(port, host = "0.0.0.0", options2) {
      registerFallbacks();
      const server = (0, import_node_http.createServer)(createNodeServerOptions(options2?.server), expressApp);
      applyServerConfig(server, options2?.server);
      return new Promise((resolve, reject) => {
        server.on("error", (err) => {
          reject(err);
        });
        server.listen(port, host, () => {
          const addr = server.address();
          const actualPort = typeof addr === "object" && addr !== null ? addr.port : port;
          const actualHost = typeof addr === "object" && addr !== null ? addr.address ?? host : host;
          resolve({
            port: actualPort,
            host: actualHost,
            close() {
              return new Promise((resolveClose, rejectClose) => {
                server.close((err) => {
                  if (err) {
                    rejectClose(err);
                  } else {
                    resolveClose();
                  }
                });
              });
            }
          });
        });
      });
    },
    // ── buildHandler ────────────────────────────────────────
    //
    // 构建完整的请求处理函数（不启动 server）。
    //
    // Express app 本身就是一个 (req, res) => void 函数，
    // 可以直接作为 Node.js http.createServer 的 requestListener。
    //
    // 用途：dev 模式下 Hot Reload 每次创建 fresh adapter 后调用
    // buildHandler() 获取新 handler，由 HotSwappableHandler 原子替换。
    //
    // 约定：调用 buildHandler() 前必须确保：
    //   1. 所有 registerRoute / registerMiddleware / registerErrorHandler / registerNotFound 已完成
    //   2. 兜底中间件已注册
    //
    buildHandler() {
      registerFallbacks();
      return (nodeReq, nodeRes) => {
        expressApp(nodeReq, nodeRes);
      };
    }
  };
}
__name(createExpressAdapter, "createExpressAdapter");

// dist/adapters/express/index.js
function expressAdapter(options) {
  const opts = options ?? {};
  return (app) => {
    return createExpressAdapter(opts, app);
  };
}
__name(expressAdapter, "expressAdapter");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  createExpressAdapter,
  expressAdapter
});
