/* 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/fastify/index.js
var index_exports = {};
__export(index_exports, {
  createFastifyAdapter: () => createFastifyAdapter,
  fastifyAdapter: () => fastifyAdapter
});
module.exports = __toCommonJS(index_exports);

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

// 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 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/fastify/request.js
function createVextRequest(request, app) {
  const trustProxy = app.config.trustProxy ?? false;
  const closeHandlers = [];
  const urlPath = request.url.split("?")[0] ?? "/";
  let _rawBodyCache;
  function getRawBody(maxBytes) {
    if (_rawBodyCache !== void 0) {
      assertBodySize(Buffer.byteLength(_rawBodyCache, "utf-8"), maxBytes);
      return Promise.resolve(_rawBodyCache);
    }
    const body = request.body;
    if (body === void 0 || body === null) {
      _rawBodyCache = "";
      return Promise.resolve(_rawBodyCache);
    }
    if (Buffer.isBuffer(body)) {
      assertBodySize(body.byteLength, maxBytes);
      _rawBodyCache = body.toString("utf-8");
      return Promise.resolve(_rawBodyCache);
    }
    if (typeof body === "string") {
      assertBodySize(Buffer.byteLength(body, "utf-8"), maxBytes);
      _rawBodyCache = body;
      return Promise.resolve(_rawBodyCache);
    }
    _rawBodyCache = "";
    return Promise.resolve(_rawBodyCache);
  }
  __name(getRawBody, "getRawBody");
  function getRawBodyBuffer(maxBytes) {
    const body = request.body;
    if (body === void 0 || body === null)
      return Promise.resolve(Buffer.alloc(0));
    if (Buffer.isBuffer(body)) {
      assertBodySize(body.byteLength, maxBytes);
      return Promise.resolve(body);
    }
    return Promise.resolve(Buffer.alloc(0));
  }
  __name(getRawBodyBuffer, "getRawBodyBuffer");
  let ip;
  if (trustProxy) {
    const xff = request.headers["x-forwarded-for"];
    if (typeof xff === "string") {
      const firstIp = xff.split(",")[0];
      ip = firstIp ? firstIp.trim() : request.raw.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() : request.raw.socket.remoteAddress ?? "127.0.0.1";
    } else {
      ip = request.raw.socket.remoteAddress ?? "127.0.0.1";
    }
  } else {
    ip = request.raw.socket.remoteAddress ?? "127.0.0.1";
  }
  let protocol;
  if (trustProxy) {
    const proto = request.headers["x-forwarded-proto"];
    protocol = proto === "https" ? "https" : "http";
  } else {
    const encrypted = request.raw.socket?.encrypted;
    protocol = encrypted ? "https" : "http";
  }
  const req = {
    // ── 原始数据 ────────────────────────────────────────
    query: request.query ?? {},
    body: void 0,
    // body-parser 中间件负责填充
    params: request.params ?? {},
    headers: request.headers,
    method: request.method.toUpperCase(),
    url: request.url,
    path: urlPath,
    route: "",
    // F-01: 由 registerRoute handler 在路由匹配后覆写为真实路由模板
    // ── 元信息 ──────────────────────────────────────────
    app,
    requestId: "",
    // requestId 中间件负责填充
    ip,
    protocol,
    // ── 生命周期 ────────────────────────────────────────
    onClose(handler) {
      closeHandlers.push(handler);
    },
    // ── 校验数据 ────────────────────────────────────────
    //
    // validate 中间件将校验后的数据存储在 req._validated_<location> 上。
    // valid() 方法从对应的 key 中读取数据返回。
    //
    valid(location) {
      return req[`_validated_${location}`];
    },
    // ── 内部方法（body-parser 中间件使用）───────────────────
    //
    // 通过 (req as any)._getRawBody() 访问，不暴露在 VextRequest 公共类型中。
    // 从 Fastify request.body（Buffer，由通用 content-type parser 提供）
    // 转为 string，供 body-parser 中间件解析。
    //
    _getRawBody: getRawBody,
    _getRawBodyBuffer: getRawBodyBuffer
  };
  request.raw.on("close", () => {
    for (const h of closeHandlers) {
      try {
        h();
      } catch {
      }
    }
    closeHandlers.length = 0;
  });
  return req;
}
__name(createVextRequest, "createVextRequest");

// dist/adapters/fastify/response.js
function createVextResponse(reply, getRequestId) {
  let _status = 200;
  const _headers = {};
  let _wrapEnabled = false;
  let _sent = false;
  function applyHeaders() {
    for (const [k, v] of Object.entries(_headers)) {
      reply.header(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）。
     *
     * Fastify 特殊处理：
     *   使用 reply.send(JSON.stringify(...)) 手动序列化，
     *   而非 reply.send(object)（会触发 Fastify 自动序列化），
     *   确保与 Hono Adapter 行为一致。
     */
    json(data, status) {
      if (checkSent("json"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      if (res._onSend) {
        res._onSend(data, finalStatus, { ..._headers });
      }
      reply.status(finalStatus);
      applyHeaders();
      if (_wrapEnabled) {
        if (finalStatus === 204) {
          reply.removeHeader("Content-Type");
          reply.send(void 0);
          return;
        }
        reply.header("Content-Type", "application/json; charset=utf-8");
        reply.send(JSON.stringify({
          code: 0,
          data,
          requestId: getRequestId()
        }));
        return;
      }
      if (finalStatus === 204) {
        reply.removeHeader("Content-Type");
        reply.send(void 0);
        return;
      }
      reply.header("Content-Type", "application/json; charset=utf-8");
      reply.send(JSON.stringify(data));
    },
    /**
     * 返回原始 JSON（不经过出口包装）
     *
     * 仅框架内部错误处理使用，用户代码不应直接调用。
     * 通过 VextPublicResponse 类型从用户可见接口中排除。
     *
     * @internal
     */
    rawJson(data, status) {
      if (checkSent("rawJson"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      reply.status(finalStatus);
      applyHeaders();
      reply.header("Content-Type", "application/json; charset=utf-8");
      reply.send(JSON.stringify(data));
    },
    /**
     * 返回纯文本响应（不经过出口包装）
     */
    text(content, status) {
      if (checkSent("text"))
        return;
      const finalStatus = status ?? _status;
      _status = finalStatus;
      reply.status(finalStatus);
      reply.header("Content-Type", "text/plain; charset=utf-8");
      applyHeaders();
      reply.send(content);
    },
    /**
     * 流式响应（大文件传输、实时数据流）
     *
     * Fastify 支持直接将 ReadableStream 传给 reply.send()，
     * 内部使用 pump 管道传输数据。
     */
    stream(readable, contentType = "application/octet-stream") {
      if (checkSent("stream"))
        return;
      reply.status(_status);
      reply.header("Content-Type", contentType);
      applyHeaders();
      reply.send(readable);
    },
    /**
     * 文件下载（触发浏览器下载行为）
     *
     * 自动设置 Content-Disposition: attachment 头，
     * 触发浏览器的文件下载对话框。
     */
    download(readable, filename, contentType) {
      if (checkSent("download"))
        return;
      const ct = contentType ?? "application/octet-stream";
      reply.status(_status);
      reply.header("Content-Type", ct);
      reply.header("Content-Disposition", `attachment; filename="${filename}"`);
      applyHeaders();
      reply.send(readable);
    },
    /**
     * 重定向
     *
     * Fastify v5 的 reply.redirect() 参数顺序与标准不同：
     *   - Fastify v4: reply.redirect(url, statusCode?)
     *   - Fastify v5: reply.redirect(url, statusCode?) — 同 v4
     *
     * 注意：Fastify 的 redirect 内部会自动发送响应，
     * 不需要额外调用 reply.send()。
     */
    redirect(url, status = 302) {
      if (checkSent("redirect"))
        return;
      applyHeaders();
      reply.redirect(url, status);
    },
    /**
     * 设置 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
var SERVER_CONFIG_KEYS = [
  "requestTimeout",
  "headersTimeout",
  "keepAliveTimeout",
  "socketTimeout",
  "maxHeaderSize",
  "maxRequestsPerSocket",
  "connectionsCheckingInterval"
];
function hasServerConfig(config) {
  return Boolean(config && SERVER_CONFIG_KEYS.some((key) => config[key] !== void 0));
}
__name(hasServerConfig, "hasServerConfig");
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/fastify/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 createFastifyAdapter(options, app) {
  const defaultBodyLimit = resolveAdapterBodyLimitBytes({
    globalBodyParser: app.config.bodyParser,
    multipart: app.config.multipart,
    adapterBodyLimit: options.bodyLimit
  });
  const serverConfig = app.config.server;
  const serverFactory = hasServerConfig(serverConfig) ? (handler) => {
    const server = (0, import_node_http.createServer)(createNodeServerOptions(serverConfig), handler);
    applyServerConfig(server, serverConfig);
    return server;
  } : void 0;
  const fastify = (0, import_fastify.default)({
    logger: options.logger ?? false,
    pluginTimeout: options.pluginTimeout ?? 1e4,
    bodyLimit: defaultBodyLimit,
    ...serverFactory ? { serverFactory } : {},
    // Fastify v5 要求路由器选项通过 routerOptions 传递（FSTDEP022）
    // 直接传 ignoreTrailingSlash / caseSensitive 在 v5 仍可用但会触发 deprecation warning，
    // v6 将彻底移除顶层支持。
    routerOptions: {
      ignoreTrailingSlash: options.ignoreTrailingSlash ?? true,
      caseSensitive: options.caseSensitive ?? false
    }
  });
  const alsEnabled = app.config.requestContext?.enabled !== false;
  const globalMiddlewares = [];
  let errorHandler = null;
  let _ready = false;
  fastify.removeAllContentTypeParsers();
  fastify.addContentTypeParser("*", { parseAs: "buffer" }, (_req, body, done) => {
    done(null, body);
  });
  return {
    name: "fastify",
    // ── registerMiddleware ───────────────────────────────────
    //
    // 收集全局中间件。bootstrap 步骤⑥中注册的内置中间件
    // （requestId / cors / body-parser / rate-limit / response-wrapper / access-log）
    // 和插件通过 app.use() 注册的中间件都通过此方法收集。
    //
    // 执行时机：在每个路由的 handler 中，全局中间件拼接在路由级中间件之前执行。
    //
    registerMiddleware(middleware) {
      globalMiddlewares.push(middleware);
    },
    // ── registerRoute ───────────────────────────────────────
    //
    // 为每条路由注册 Fastify handler。
    //
    // 流程：
    //   1. 将 HTTP 方法转为小写（Fastify API 使用小写方法名）
    //   2. 将路由路径参数格式转换（vext 和 Fastify v5 都使用 :param 格式，无需转换）
    //   3. 在 handler 中创建 VextRequest / VextResponse
    //   4. 在 AsyncLocalStorage 请求上下文中执行 executeChain
    //   5. 全局中间件 + 路由级中间件 + validate + handler 组成完整链
    //
    // 错误处理：
    //   - executeChain 抛出异常时，由 errorHandler 处理
    //   - errorHandler 自身也可能抛出异常（如 logger 写入失败），
    //     此时发送最低限度的 500 JSON 响应
    //
    registerRoute(method, path, chain, routeOptions = {}) {
      let prebuiltChain = null;
      const fastifyMethod = method.toLowerCase();
      const fastifyPath = path;
      const routeBodyParser = resolveRouteBodyParserConfig(routeOptions);
      const routeBodyLimit = resolveAdapterBodyLimitBytes({
        globalBodyParser: app.config.bodyParser,
        routeBodyParser,
        multipart: app.config.multipart,
        adapterBodyLimit: options.bodyLimit
      });
      fastify[fastifyMethod](fastifyPath, { bodyLimit: routeBodyLimit }, async (request, reply) => {
        const req = createVextRequest(request, app);
        req._routeOptions = routeOptions;
        if (routeBodyParser) {
          req._routeBodyParser = routeBodyParser;
        }
        req.route = fastifyPath;
        const res = createVextResponse(reply, () => 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 {
                  throw handlerError;
                }
              }
            } else {
              throw err;
            }
          }
        }, "runChain");
        if (alsEnabled) {
          await requestContext.run({ requestId: "", locale: void 0 }, runChain);
        } else {
          await runChain();
        }
      });
    },
    // ── registerErrorHandler ────────────────────────────────
    //
    // 注册全局错误处理函数。
    //
    // 同时注册到 Fastify 的 setErrorHandler，
    // 捕获 Fastify 内部抛出的错误（如路由匹配中间的异常等）。
    // 这确保了即使在 Fastify 内部流程中发生错误，也能返回统一的 JSON 格式。
    //
    registerErrorHandler(handler) {
      errorHandler = handler;
      fastify.setErrorHandler(async (error, request, reply) => {
        const req = createVextRequest(request, 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(reply, () => req.requestId);
        const statusCode = error.statusCode;
        if (statusCode === 413) {
          res.rawJson({
            code: 413,
            message: "Payload Too Large",
            requestId: req.requestId
          }, 413);
          return;
        }
        try {
          handler(error, req, res);
        } catch (_handlerError) {
          try {
            res.rawJson({ code: 500, message: "Internal Server Error" }, 500);
          } catch {
            reply.status(500).send("Internal Server Error");
          }
        }
      });
    },
    // ── registerNotFound ────────────────────────────────────
    //
    // 注册 404 兜底处理函数。
    //
    // 当没有任何路由匹配时执行此处理函数。
    // 使用 Fastify 的 setNotFoundHandler，在 Fastify 路由匹配失败时触发。
    //
    // 注意：notFound 不经过中间件链，requestId 中间件不会执行。
    // 需要内联生成 requestId，确保 404 响应也有有效的 requestId。
    //
    registerNotFound(handler) {
      fastify.setNotFoundHandler(async (request, reply) => {
        const req = createVextRequest(request, 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(reply, () => req.requestId);
        const runNotFound = /* @__PURE__ */ __name(async () => {
          const noop = /* @__PURE__ */ __name(async () => {
          }, "noop");
          await handler(req, res, noop);
        }, "runNotFound");
        if (alsEnabled) {
          await requestContext.run({ requestId: req.requestId, locale: void 0 }, runNotFound);
        } else {
          await runNotFound();
        }
      });
    },
    // ── listen ──────────────────────────────────────────────
    //
    // 启动 HTTP 服务器。
    //
    // 流程：
    //   1. 调用 fastify.ready() 确保所有路由和插件注册完成
    //   2. 调用 fastify.listen() 开始监听端口
    //   3. 返回 VextServerHandle（含 close / port / host）
    //
    // Fastify 内置了 Node.js http.createServer，无需手动创建。
    //
    async listen(port, host = "0.0.0.0", options2) {
      await fastify.ready();
      _ready = true;
      applyServerConfig(fastify.server, options2?.server);
      await fastify.listen({ port, host });
      const addr = fastify.server.address();
      const actualPort = typeof addr === "object" && addr !== null ? addr.port : port;
      const actualHost = typeof addr === "object" && addr !== null ? addr.address ?? host : host;
      return {
        port: actualPort,
        host: actualHost,
        async close() {
          await fastify.close();
        }
      };
    },
    // ── buildHandler ────────────────────────────────────────
    //
    // 构建完整的请求处理函数（不启动 server）。
    //
    // 在所有路由 / 中间件注册完成后调用。
    // 返回的 handler 接受原始 Node.js req/res。
    //
    // 用途：dev 模式下 Hot Reload 每次创建 fresh adapter 后调用
    // buildHandler() 获取新 handler，由 HotSwappableHandler 原子替换。
    //
    // Fastify 提供 fastify.routing(req, res) 方法，
    // 它是 Fastify 内部的标准 Node.js 请求处理函数，
    // 执行路由匹配 + handler 调用 + 错误处理 + 404 兜底。
    //
    // 约定：调用 buildHandler() 前必须确保：
    //   1. 所有 registerRoute / registerMiddleware / registerErrorHandler / registerNotFound 已完成
    //   2. fastify.ready() 已调用（通过 listen() 或手动调用）
    //
    // 对于 dev 模式热重载场景，框架应在调用 buildHandler() 前确保 ready() 已完成。
    // 如果 ready() 尚未调用，这里会同步返回 routing 函数，
    // 但实际请求处理可能会失败。为安全起见，如果 _ready 为 false，
    // 返回一个包装函数，在首次请求时异步调用 ready()。
    //
    buildHandler() {
      if (_ready) {
        return (nodeReq, nodeRes) => {
          fastify.routing(nodeReq, nodeRes);
        };
      }
      let readyPromise = null;
      return (nodeReq, nodeRes) => {
        if (!readyPromise) {
          readyPromise = Promise.resolve(fastify.ready()).then(() => {
            _ready = true;
          });
        }
        if (_ready) {
          fastify.routing(nodeReq, nodeRes);
        } else {
          readyPromise.then(() => {
            fastify.routing(nodeReq, nodeRes);
          }).catch(() => {
            if (!nodeRes.headersSent) {
              nodeRes.statusCode = 500;
              nodeRes.setHeader("Content-Type", "application/json");
              nodeRes.end(JSON.stringify({
                code: 500,
                message: "Internal Server Error: adapter not ready"
              }));
            }
          });
        }
      };
    }
  };
}
__name(createFastifyAdapter, "createFastifyAdapter");

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