@faapi/faapi 0.0.0-canary.0e994fe → 0.0.0-canary.0f443f9

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
@@ -613,12 +613,12 @@ var init_normalizePatterns = __esm({
613
613
  // src/cli/parseArgs.ts
614
614
  function parseArgs(argv) {
615
615
  const cli = cac("faapi");
616
- cli.option("--port <port>", "Server port (env: PORT)").option("--app-dir <dir>", "App directory (root by default)", { default: "." }).option("--cors", "Enable CORS (default in dev mode)").option("--no-cors", "Disable CORS").option("--static <dir>", "Static files directory", { default: void 0 }).option("--no-static", "Disable static file serving").option("--types <path>", "Output path for generated types file").option("--config <path>", "Path to config file (faapi.config.ts)");
616
+ cli.option("--port <port>", "Server port (env: PORT)").option("--app-dir <dir>", "App directory (src by default)", { default: "src" }).option("--cors", "Enable CORS (default in dev mode)").option("--no-cors", "Disable CORS").option("--static <dir>", "Static files directory", { default: void 0 }).option("--no-static", "Disable static file serving").option("--types <path>", "Output path for generated types file").option("--config <path>", "Path to config file (faapi.config.ts)");
617
617
  const { args, options } = cli.parse(["", "", ...argv]);
618
618
  const rawPatterns = args.map(String).filter((a) => a !== "dev");
619
619
  const patterns = normalizePatterns(rawPatterns);
620
620
  const port = options.port ? Number(options.port) : Number(process.env.PORT) || 3e3;
621
- const appDir = String(options.appDir ?? ".");
621
+ const appDir = String(options.appDir ?? "src");
622
622
  const cors2 = options.cors !== false;
623
623
  const staticDir = options.static === false ? void 0 : options.static;
624
624
  const defaultPattern = appDir === "." ? "api/**/*.ts" : `${appDir}/api/**/*.ts`;
@@ -1233,7 +1233,7 @@ function formatSetCookie(name, value, options) {
1233
1233
  if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
1234
1234
  return cookie;
1235
1235
  }
1236
- function createContext(request, params, config = {}) {
1236
+ function createContext(request, params, config = {}, ip = "") {
1237
1237
  const url = new URL(request.url);
1238
1238
  const meta = { headers: {}, setCookies: [] };
1239
1239
  const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
@@ -1248,6 +1248,7 @@ function createContext(request, params, config = {}) {
1248
1248
  headers: request.headers,
1249
1249
  method: request.method,
1250
1250
  path: url.pathname,
1251
+ ip,
1251
1252
  cookies: cookiesObj,
1252
1253
  config,
1253
1254
  meta,
@@ -1705,6 +1706,7 @@ var init_resolveInjection = __esm({
1705
1706
  ctx: "context",
1706
1707
  // 别名
1707
1708
  cookies: "cookies",
1709
+ ip: "ip",
1708
1710
  files: "files",
1709
1711
  fields: "fields"
1710
1712
  };
@@ -1724,6 +1726,8 @@ function getBuiltinInjectionValue(type, ctx, body) {
1724
1726
  return ctx;
1725
1727
  case "cookies":
1726
1728
  return ctx.cookies;
1729
+ case "ip":
1730
+ return ctx.ip;
1727
1731
  case "body":
1728
1732
  return body;
1729
1733
  case "files":
@@ -2130,6 +2134,28 @@ var init_validateInput = __esm({
2130
2134
  }
2131
2135
  });
2132
2136
 
2137
+ // src/utils/getClientIp.ts
2138
+ function getClientIp(req) {
2139
+ const xff = req.headers["x-forwarded-for"];
2140
+ if (typeof xff === "string" && xff.length > 0) {
2141
+ const first = xff.split(",")[0]?.trim();
2142
+ if (first) return first;
2143
+ }
2144
+ const remote = req.socket.remoteAddress;
2145
+ if (remote) {
2146
+ if (remote.startsWith("::ffff:")) {
2147
+ return remote.slice(7);
2148
+ }
2149
+ return remote;
2150
+ }
2151
+ return "";
2152
+ }
2153
+ var init_getClientIp = __esm({
2154
+ "src/utils/getClientIp.ts"() {
2155
+ "use strict";
2156
+ }
2157
+ });
2158
+
2133
2159
  // src/middleware/cors.ts
2134
2160
  function cors(options = {}) {
2135
2161
  const {
@@ -3467,7 +3493,7 @@ function attachWebSocket(options) {
3467
3493
  const host = req.headers.host ?? "localhost";
3468
3494
  const url = `http://${host}${req.url ?? "/"}`;
3469
3495
  const request = new Request(url, { method: "GET", headers });
3470
- const ctx = createContext(request, params, config);
3496
+ const ctx = createContext(request, params, config, getClientIp(req));
3471
3497
  const meta = ctx.meta;
3472
3498
  let upgraded = false;
3473
3499
  const finalHandler = async () => {
@@ -3524,6 +3550,7 @@ var init_handleWsUpgrade = __esm({
3524
3550
  init_createContext();
3525
3551
  init_invokeHandler();
3526
3552
  init_importWithCacheBust();
3553
+ init_getClientIp();
3527
3554
  init_serverUtils();
3528
3555
  init_wsHandler();
3529
3556
  }
@@ -3647,7 +3674,7 @@ async function handleRequest(routes, rootDir, req, res, corsMiddleware, staticDi
3647
3674
  const request = toWebRequest(req);
3648
3675
  const method = request.method.toUpperCase();
3649
3676
  const urlPath = new URL(request.url).pathname;
3650
- const ctx = createContext(request, {}, config);
3677
+ const ctx = createContext(request, {}, config, getClientIp(req));
3651
3678
  const meta = ctx.meta;
3652
3679
  const routePipeline = async () => {
3653
3680
  const match = matchRoute(routes, method, urlPath);
@@ -3732,6 +3759,7 @@ var init_createServer = __esm({
3732
3759
  init_httpErrors();
3733
3760
  init_validateInput();
3734
3761
  init_inputType();
3762
+ init_getClientIp();
3735
3763
  init_cors();
3736
3764
  init_serveStatic();
3737
3765
  init_schemaRegistry();