@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/index.js CHANGED
@@ -1235,13 +1235,13 @@ var init_collectRouteSchemaSources = __esm({
1235
1235
  });
1236
1236
 
1237
1237
  // src/utils/atomicWrite.ts
1238
- import path9 from "path";
1239
- import fs7 from "fs";
1238
+ import path10 from "path";
1239
+ import fs8 from "fs";
1240
1240
  async function atomicWriteFile(outputPath, content) {
1241
- await fs7.promises.mkdir(path9.dirname(outputPath), { recursive: true });
1241
+ await fs8.promises.mkdir(path10.dirname(outputPath), { recursive: true });
1242
1242
  const tmp = `${outputPath}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
1243
- await fs7.promises.writeFile(tmp, content, "utf-8");
1244
- await fs7.promises.rename(tmp, outputPath);
1243
+ await fs8.promises.writeFile(tmp, content, "utf-8");
1244
+ await fs8.promises.rename(tmp, outputPath);
1245
1245
  }
1246
1246
  var init_atomicWrite = __esm({
1247
1247
  "src/utils/atomicWrite.ts"() {
@@ -1588,7 +1588,7 @@ __export(generateSchemaFiles_exports, {
1588
1588
  getRuntimeSchemaPath: () => getRuntimeSchemaPath,
1589
1589
  getSchemaOutputPath: () => getSchemaOutputPath
1590
1590
  });
1591
- import path10 from "path";
1591
+ import path11 from "path";
1592
1592
  function getSchemaOutputPath(sourceFile, dist, rootDir) {
1593
1593
  let rel = sourceFile.replace(/\\/g, "/");
1594
1594
  if (rel.startsWith("src/")) {
@@ -1596,7 +1596,7 @@ function getSchemaOutputPath(sourceFile, dist, rootDir) {
1596
1596
  }
1597
1597
  const idx = rel.lastIndexOf("/");
1598
1598
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
1599
- return path10.resolve(rootDir, dist, relDir, "zod.js");
1599
+ return path11.resolve(rootDir, dist, relDir, "zod.js");
1600
1600
  }
1601
1601
  function getRuntimeSchemaPath(filePath, dist, rootDir) {
1602
1602
  let rel = filePath.replace(/\\/g, "/");
@@ -1607,7 +1607,7 @@ function getRuntimeSchemaPath(filePath, dist, rootDir) {
1607
1607
  }
1608
1608
  const idx = rel.lastIndexOf("/");
1609
1609
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
1610
- return path10.resolve(rootDir, dist, relDir, "zod.js");
1610
+ return path11.resolve(rootDir, dist, relDir, "zod.js");
1611
1611
  }
1612
1612
  function getHelpersImportPath(relDir) {
1613
1613
  if (!relDir) return `./${HELPERS_FILENAME}`;
@@ -1666,7 +1666,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
1666
1666
  }
1667
1667
  const fileEntries = [];
1668
1668
  for (const [filePath, fileSources] of sourcesByFile) {
1669
- const relFile = path10.relative(rootDir, filePath).replace(/\\/g, "/");
1669
+ const relFile = path11.relative(rootDir, filePath).replace(/\\/g, "/");
1670
1670
  const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
1671
1671
  let relForDir = relFile;
1672
1672
  if (relForDir.startsWith("src/")) {
@@ -1685,7 +1685,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
1685
1685
  }
1686
1686
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
1687
1687
  if (usesCoerceHelpers(allSourceCode)) {
1688
- const helpersPath = path10.resolve(rootDir, dist, HELPERS_FILENAME);
1688
+ const helpersPath = path11.resolve(rootDir, dist, HELPERS_FILENAME);
1689
1689
  await writeSchemaFile(helpersPath, generateHelpersFileSource());
1690
1690
  }
1691
1691
  await Promise.all(
@@ -1917,7 +1917,7 @@ function createAppRegistries() {
1917
1917
  var defaultRegistries = createAppRegistries();
1918
1918
 
1919
1919
  // src/task/taskQueue.ts
1920
- import path3 from "path";
1920
+ import path4 from "path";
1921
1921
 
1922
1922
  // src/errors/FaapiError.ts
1923
1923
  var FaapiError = class extends Error {
@@ -1945,14 +1945,14 @@ var ValidationError = class extends FaapiError {
1945
1945
  issues;
1946
1946
  };
1947
1947
  var RouteNotFoundError = class extends FaapiError {
1948
- constructor(path28) {
1949
- super("ROUTE_NOT_FOUND", `Route not found: ${path28}`, 404);
1948
+ constructor(path29) {
1949
+ super("ROUTE_NOT_FOUND", `Route not found: ${path29}`, 404);
1950
1950
  this.name = "RouteNotFoundError";
1951
1951
  }
1952
1952
  };
1953
1953
  var MethodNotAllowedError = class extends FaapiError {
1954
- constructor(method, path28, allowedMethods) {
1955
- super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path28}`, 405);
1954
+ constructor(method, path29, allowedMethods) {
1955
+ super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path29}`, 405);
1956
1956
  this.allowedMethods = allowedMethods;
1957
1957
  this.name = "MethodNotAllowedError";
1958
1958
  }
@@ -2073,7 +2073,7 @@ var LOG_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
2073
2073
  function createTaskLogger(level, scope, fields) {
2074
2074
  function make(suffix) {
2075
2075
  function write(lvl, message, callFields) {
2076
- if (LOG_RANK[lvl] < LOG_RANK[level]) return;
2076
+ if (level !== undefined && LOG_RANK[lvl] < LOG_RANK[level]) return;
2077
2077
  var entry = { level: lvl, message: message, time: new Date().toISOString() };
2078
2078
  var fullScope = suffix === undefined ? scope : scope === undefined ? suffix : scope + ':' + suffix;
2079
2079
  if (fullScope !== undefined) entry.scope = fullScope;
@@ -2275,6 +2275,95 @@ async function runTaskInWorker(options) {
2275
2275
  });
2276
2276
  }
2277
2277
 
2278
+ // src/logger/formatEntry.ts
2279
+ function serializeFieldValue(value) {
2280
+ if (value instanceof Error) {
2281
+ return { name: value.name, message: value.message, stack: value.stack };
2282
+ }
2283
+ return value;
2284
+ }
2285
+ function formatEntry(entry) {
2286
+ let line = `[${entry.time}] ${entry.level.toUpperCase()} `;
2287
+ if (entry.scope) line += `[${entry.scope}] `;
2288
+ line += entry.message;
2289
+ if (entry.fields !== void 0) {
2290
+ const plain = Object.fromEntries(
2291
+ Object.entries(entry.fields).map(([k, v]) => [k, serializeFieldValue(v)])
2292
+ );
2293
+ try {
2294
+ line += ` ${JSON.stringify(plain)}`;
2295
+ } catch (err) {
2296
+ line += ` [unserializable fields: ${err instanceof Error ? err.message : String(err)}]`;
2297
+ }
2298
+ }
2299
+ return line;
2300
+ }
2301
+
2302
+ // src/logger/fileSink.ts
2303
+ import fs2 from "fs";
2304
+ import path3 from "path";
2305
+ var LEVEL_FILES = ["debug", "info", "warn", "error"];
2306
+ function createFileLogSink(options) {
2307
+ fs2.mkdirSync(options.dir, { recursive: true });
2308
+ const streams = /* @__PURE__ */ new Map();
2309
+ const getStream = (name) => {
2310
+ if (streams.has(name)) return streams.get(name);
2311
+ return void 0;
2312
+ };
2313
+ const openStream = (name) => {
2314
+ const stream = fs2.createWriteStream(path3.join(options.dir, `${name}.log`), { flags: "a" });
2315
+ stream.on("error", () => {
2316
+ });
2317
+ streams.set(name, stream);
2318
+ };
2319
+ const fileNames = options.splitByLevel ? [...LEVEL_FILES] : ["app", "error"];
2320
+ for (const name of fileNames) openStream(name);
2321
+ let pendingCount = 0;
2322
+ let drainWaiters = [];
2323
+ const onWriteDone = () => {
2324
+ pendingCount--;
2325
+ if (pendingCount === 0 && drainWaiters.length > 0) {
2326
+ const waiters = drainWaiters;
2327
+ drainWaiters = [];
2328
+ for (const waiter of waiters) waiter();
2329
+ }
2330
+ };
2331
+ const write = (entry) => {
2332
+ const line = `${formatEntry(entry)}
2333
+ `;
2334
+ const target = options.splitByLevel ? entry.level : "app";
2335
+ const main = getStream(target);
2336
+ if (main) {
2337
+ pendingCount++;
2338
+ main.write(line, onWriteDone);
2339
+ }
2340
+ if (!options.splitByLevel && entry.level === "error") {
2341
+ const dup = getStream("error");
2342
+ if (dup) {
2343
+ pendingCount++;
2344
+ dup.write(line, onWriteDone);
2345
+ }
2346
+ }
2347
+ };
2348
+ const flush = () => new Promise((resolve) => {
2349
+ if (pendingCount === 0) {
2350
+ resolve();
2351
+ return;
2352
+ }
2353
+ drainWaiters.push(resolve);
2354
+ });
2355
+ const close = () => Promise.all(
2356
+ [...streams.values()].map(
2357
+ (stream) => new Promise((resolve) => {
2358
+ stream.end(() => resolve());
2359
+ })
2360
+ )
2361
+ ).then(() => {
2362
+ streams.clear();
2363
+ });
2364
+ return { write, flush, close };
2365
+ }
2366
+
2278
2367
  // src/logger/logger.ts
2279
2368
  var LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
2280
2369
  var VALID_LEVELS = ["debug", "info", "warn", "error"];
@@ -2285,21 +2374,20 @@ function assertLogLevel(value, source) {
2285
2374
  );
2286
2375
  }
2287
2376
  }
2288
- var globalState = {
2289
- level: null,
2290
- sink: null,
2291
- disabled: false
2292
- };
2377
+ var globalState = { level: null, sink: null, fileSink: null, stdout: true, accessLog: false, disabled: false };
2293
2378
  function configureLogging(config) {
2294
- if (config === void 0) {
2295
- globalState.level = null;
2296
- globalState.sink = null;
2297
- globalState.disabled = false;
2298
- return;
2299
- }
2300
2379
  const objectConfig = typeof config === "object" ? config : {};
2380
+ if (objectConfig.sink && objectConfig.dir) {
2381
+ throw new Error(
2382
+ "[faapi] config.log.sink and config.log.dir are mutually exclusive: pick one output pipeline (custom sink OR built-in file logs)."
2383
+ );
2384
+ }
2385
+ void globalState.fileSink?.close();
2301
2386
  globalState.disabled = config === false;
2302
2387
  globalState.sink = objectConfig.sink ?? null;
2388
+ globalState.accessLog = objectConfig.accessLog ?? objectConfig.dir !== void 0;
2389
+ globalState.stdout = objectConfig.stdout ?? true;
2390
+ globalState.fileSink = objectConfig.dir ? createFileLogSink({ dir: objectConfig.dir, splitByLevel: objectConfig.splitByLevel }) : null;
2303
2391
  if (objectConfig.level !== void 0) {
2304
2392
  assertLogLevel(objectConfig.level, "config.log.level");
2305
2393
  globalState.level = objectConfig.level;
@@ -2311,56 +2399,54 @@ function configureLogging(config) {
2311
2399
  }
2312
2400
  }
2313
2401
  function globalThreshold() {
2314
- return globalState.level ?? "info";
2402
+ if (globalState.level) return globalState.level;
2403
+ if (globalState.fileSink) return void 0;
2404
+ return "info";
2405
+ }
2406
+ function belowThreshold(level, threshold) {
2407
+ return threshold !== void 0 && LEVEL_RANK[level] < LEVEL_RANK[threshold];
2315
2408
  }
2316
2409
  function getEffectiveLogLevel() {
2317
2410
  return globalThreshold();
2318
2411
  }
2319
- function serializeFieldValue(value) {
2320
- if (value instanceof Error) {
2321
- return { name: value.name, message: value.message, stack: value.stack };
2322
- }
2323
- return value;
2324
- }
2325
- function formatEntry(entry) {
2326
- let line = `[${entry.time}] ${entry.level.toUpperCase()} `;
2327
- if (entry.scope) line += `[${entry.scope}] `;
2328
- line += entry.message;
2329
- if (entry.fields !== void 0) {
2330
- const plain = Object.fromEntries(
2331
- Object.entries(entry.fields).map(([k, v]) => [k, serializeFieldValue(v)])
2332
- );
2333
- try {
2334
- line += ` ${JSON.stringify(plain)}`;
2335
- } catch (err) {
2336
- line += ` [unserializable fields: ${err instanceof Error ? err.message : String(err)}]`;
2337
- }
2338
- }
2339
- return line;
2340
- }
2412
+ var consoleSink = (entry) => {
2413
+ console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
2414
+ };
2341
2415
  var CONSOLE_METHOD = {
2342
2416
  debug: "debug",
2343
2417
  info: "info",
2344
2418
  warn: "warn",
2345
2419
  error: "error"
2346
2420
  };
2347
- var consoleSink = (entry) => {
2348
- console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
2349
- };
2350
2421
  function globalDispatch(entry) {
2351
2422
  if (globalState.disabled) return;
2352
- (globalState.sink ?? consoleSink)(entry);
2423
+ if (globalState.sink) {
2424
+ globalState.sink(entry);
2425
+ return;
2426
+ }
2427
+ if (globalState.fileSink) {
2428
+ globalState.fileSink.write(entry);
2429
+ if (globalState.stdout) consoleSink(entry);
2430
+ return;
2431
+ }
2432
+ consoleSink(entry);
2353
2433
  }
2354
2434
  function writeLogEntry(entry) {
2355
- if (LEVEL_RANK[entry.level] < LEVEL_RANK[globalThreshold()]) return;
2435
+ if (belowThreshold(entry.level, globalThreshold())) return;
2356
2436
  globalDispatch(entry);
2357
2437
  }
2438
+ function flushLogging() {
2439
+ return globalState.fileSink ? globalState.fileSink.flush() : Promise.resolve();
2440
+ }
2441
+ function isAccessLogPiped() {
2442
+ return !globalState.disabled && globalState.accessLog;
2443
+ }
2358
2444
  function createLogger(scope, options) {
2359
2445
  const baseScope = scope;
2360
2446
  const baseFields = options?.fields;
2361
2447
  const write = (level, message, callFields, scopeSuffix) => {
2362
2448
  const threshold = options?.level ?? globalThreshold();
2363
- if (LEVEL_RANK[level] < LEVEL_RANK[threshold]) return;
2449
+ if (belowThreshold(level, threshold)) return;
2364
2450
  const entry = {
2365
2451
  level,
2366
2452
  message,
@@ -2419,7 +2505,7 @@ function createTaskQueue(deps) {
2419
2505
  }
2420
2506
  const loadTaskModule = deps.loadTaskModule ?? (async (filePath) => await import(filePath));
2421
2507
  const loadPayloadSchema = deps.loadPayloadSchema ?? (async (filePath) => {
2422
- const zodPath = path3.join(path3.dirname(filePath), "zod.js");
2508
+ const zodPath = path4.join(path4.dirname(filePath), "zod.js");
2423
2509
  try {
2424
2510
  const mod = await import(zodPath);
2425
2511
  const schemaKey = Object.keys(mod).find((k) => k.endsWith("Schema"));
@@ -2447,7 +2533,7 @@ function createTaskQueue(deps) {
2447
2533
  const meta = registry.get(name);
2448
2534
  schemaCache.set(
2449
2535
  name,
2450
- await loadPayloadSchema(path3.resolve(rootDir, meta.filePath)).catch(() => void 0)
2536
+ await loadPayloadSchema(path4.resolve(rootDir, meta.filePath)).catch(() => void 0)
2451
2537
  );
2452
2538
  }
2453
2539
  const schema = schemaCache.get(name);
@@ -2483,7 +2569,7 @@ function createTaskQueue(deps) {
2483
2569
  let result;
2484
2570
  if (meta.timeoutMs !== void 0 && meta.timeoutMs > 0) {
2485
2571
  result = await (deps.runIsolated ?? runTaskInWorker)({
2486
- taskModulePath: path3.resolve(rootDir, meta.filePath),
2572
+ taskModulePath: path4.resolve(rootDir, meta.filePath),
2487
2573
  payload: job.payload,
2488
2574
  taskCtx: {
2489
2575
  config: deps.config,
@@ -2508,7 +2594,7 @@ function createTaskQueue(deps) {
2508
2594
  } else {
2509
2595
  let mod = moduleCache2.get(job.name);
2510
2596
  if (!mod) {
2511
- mod = await loadTaskModule(path3.resolve(rootDir, meta.filePath));
2597
+ mod = await loadTaskModule(path4.resolve(rootDir, meta.filePath));
2512
2598
  moduleCache2.set(job.name, mod);
2513
2599
  }
2514
2600
  if (typeof mod.run !== "function") {
@@ -2745,8 +2831,8 @@ function createCronScheduler(registry, enqueue) {
2745
2831
 
2746
2832
  // src/task/scanTasks.ts
2747
2833
  import fg from "fast-glob";
2748
- import path4 from "path";
2749
- import fs2 from "fs";
2834
+ import path5 from "path";
2835
+ import fs3 from "fs";
2750
2836
  var TASK_PATTERNS = ["src/tasks/**/task.ts"];
2751
2837
  var TASK_FILENAME = "task.ts";
2752
2838
  var CRON_RE = /(?:^|\n)\s*cron:\s*['"`]([^'"`\n]+)['"`]/;
@@ -2777,12 +2863,12 @@ async function scanTasks(rootDir, patterns) {
2777
2863
  const seen = /* @__PURE__ */ new Map();
2778
2864
  for (const file of files) {
2779
2865
  const normalizedFile = file.replace(/\\/g, "/");
2780
- const fileName = path4.posix.basename(normalizedFile);
2866
+ const fileName = path5.posix.basename(normalizedFile);
2781
2867
  if (fileName !== TASK_FILENAME) {
2782
2868
  continue;
2783
2869
  }
2784
- const absPath = path4.resolve(rootDir, normalizedFile);
2785
- const source = await fs2.promises.readFile(absPath, "utf8").catch(() => "");
2870
+ const absPath = path5.resolve(rootDir, normalizedFile);
2871
+ const source = await fs3.promises.readFile(absPath, "utf8").catch(() => "");
2786
2872
  const name = filePathToTaskName(normalizedFile);
2787
2873
  const prevFile = seen.get(name);
2788
2874
  if (prevFile) {
@@ -2855,7 +2941,7 @@ function listSkills() {
2855
2941
  }
2856
2942
 
2857
2943
  // src/loader/loadAgentModule.ts
2858
- import fs10 from "fs";
2944
+ import fs11 from "fs";
2859
2945
 
2860
2946
  // src/loader/resolveExports.ts
2861
2947
  function resolveExport(module, exportName) {
@@ -2901,18 +2987,18 @@ async function importWithCacheBust(filePath, bustViteCache = false) {
2901
2987
  }
2902
2988
 
2903
2989
  // src/cli/compileOnDemand.ts
2904
- import path12 from "path";
2905
- import fs9 from "fs";
2990
+ import path13 from "path";
2991
+ import fs10 from "fs";
2906
2992
 
2907
2993
  // src/cli/compileSourceFiles.ts
2908
- import path8 from "path";
2909
- import fs6 from "fs";
2994
+ import path9 from "path";
2995
+ import fs7 from "fs";
2910
2996
  import fg2 from "fast-glob";
2911
2997
 
2912
2998
  // src/cli/aliasPlugin.ts
2913
2999
  import ts7 from "typescript";
2914
- import path7 from "path";
2915
- import fs5 from "fs";
3000
+ import path8 from "path";
3001
+ import fs6 from "fs";
2916
3002
 
2917
3003
  // src/utils/resolveAlias.ts
2918
3004
  function resolveAlias(specifier, config) {
@@ -2938,8 +3024,8 @@ function resolveAlias(specifier, config) {
2938
3024
  }
2939
3025
 
2940
3026
  // src/utils/prodPaths.ts
2941
- import path5 from "path";
2942
- import fs3 from "fs";
3027
+ import path6 from "path";
3028
+ import fs4 from "fs";
2943
3029
  var APP_DIR = "src";
2944
3030
  var ROUTE_PATTERNS = ["src/api/**/*.ts"];
2945
3031
  function toProdFilePath(filePath, dist) {
@@ -2958,27 +3044,27 @@ function toProdExtension(filePath) {
2958
3044
  }
2959
3045
  function toRealPath(p) {
2960
3046
  try {
2961
- return fs3.realpathSync(p);
3047
+ return fs4.realpathSync(p);
2962
3048
  } catch {
2963
3049
  return p;
2964
3050
  }
2965
3051
  }
2966
3052
  function isInsideDir(filePath, dir) {
2967
- const rel = path5.relative(dir, filePath);
2968
- return rel !== "" && !rel.startsWith("..") && !path5.isAbsolute(rel);
3053
+ const rel = path6.relative(dir, filePath);
3054
+ return rel !== "" && !rel.startsWith("..") && !path6.isAbsolute(rel);
2969
3055
  }
2970
3056
 
2971
3057
  // src/utils/readTsconfig.ts
2972
3058
  import ts6 from "typescript";
2973
- import path6 from "path";
2974
- import fs4 from "fs";
3059
+ import path7 from "path";
3060
+ import fs5 from "fs";
2975
3061
  var tsconfigCache = /* @__PURE__ */ new Map();
2976
3062
  function readTsconfig(rootDir) {
2977
- const tsconfigPath = path6.resolve(rootDir, "tsconfig.json");
2978
- if (!fs4.existsSync(tsconfigPath)) return null;
3063
+ const tsconfigPath = path7.resolve(rootDir, "tsconfig.json");
3064
+ if (!fs5.existsSync(tsconfigPath)) return null;
2979
3065
  let mtimeMs;
2980
3066
  try {
2981
- mtimeMs = fs4.statSync(tsconfigPath).mtimeMs;
3067
+ mtimeMs = fs5.statSync(tsconfigPath).mtimeMs;
2982
3068
  } catch {
2983
3069
  return null;
2984
3070
  }
@@ -2994,7 +3080,7 @@ function readTsconfig(rootDir) {
2994
3080
  const config = rawPaths ? (() => {
2995
3081
  const paths = {};
2996
3082
  for (const [pattern, targets] of Object.entries(rawPaths)) {
2997
- paths[pattern] = targets.map((t) => path6.resolve(baseUrl, t));
3083
+ paths[pattern] = targets.map((t) => path7.resolve(baseUrl, t));
2998
3084
  }
2999
3085
  return { baseUrl, paths };
3000
3086
  })() : null;
@@ -3004,26 +3090,26 @@ function readTsconfig(rootDir) {
3004
3090
 
3005
3091
  // src/cli/aliasPlugin.ts
3006
3092
  function toProdImportPath(sourceFile, importer) {
3007
- const importerDir = path7.dirname(importer);
3008
- let rel = path7.relative(importerDir, sourceFile);
3009
- rel = rel.split(path7.sep).join("/");
3093
+ const importerDir = path8.dirname(importer);
3094
+ let rel = path8.relative(importerDir, sourceFile);
3095
+ rel = rel.split(path8.sep).join("/");
3010
3096
  if (!rel.startsWith(".")) rel = "./" + rel;
3011
3097
  return toProdExtension(rel);
3012
3098
  }
3013
3099
  function toStrippedProdImportPath(sourceFile, rootDir) {
3014
- const appDirAbs = toRealPath(path7.resolve(rootDir, APP_DIR));
3100
+ const appDirAbs = toRealPath(path8.resolve(rootDir, APP_DIR));
3015
3101
  const sourceReal = toRealPath(sourceFile);
3016
- let rel = path7.relative(appDirAbs, sourceReal);
3017
- rel = rel.split(path7.sep).join("/");
3102
+ let rel = path8.relative(appDirAbs, sourceReal);
3103
+ rel = rel.split(path8.sep).join("/");
3018
3104
  if (!rel.startsWith(".")) rel = "./" + rel;
3019
3105
  return toProdExtension(rel);
3020
3106
  }
3021
3107
  function toProdImportFromImporter(importer, rootDir, relFromDist) {
3022
- const importerRel = path7.relative(toRealPath(path7.resolve(rootDir)), toRealPath(importer)).split(path7.sep).join("/");
3023
- const importerProdDir = path7.posix.dirname(toProdExtension(importerRel));
3108
+ const importerRel = path8.relative(toRealPath(path8.resolve(rootDir)), toRealPath(importer)).split(path8.sep).join("/");
3109
+ const importerProdDir = path8.posix.dirname(toProdExtension(importerRel));
3024
3110
  if (importerProdDir === ".") return relFromDist;
3025
3111
  const target = relFromDist.replace(/^\.\//, "");
3026
- let rel = path7.posix.relative(importerProdDir, target);
3112
+ let rel = path8.posix.relative(importerProdDir, target);
3027
3113
  if (!rel.startsWith(".")) rel = "./" + rel;
3028
3114
  return rel;
3029
3115
  }
@@ -3038,41 +3124,41 @@ var INDEX_EXTS = [
3038
3124
  "/index.cjs"
3039
3125
  ];
3040
3126
  function resolveRelativeSpecifier(importer, specifier) {
3041
- const importerDir = path7.dirname(importer);
3042
- const base = path7.resolve(importerDir, specifier);
3127
+ const importerDir = path8.dirname(importer);
3128
+ const base = path8.resolve(importerDir, specifier);
3043
3129
  if (PROD_EXTS.some((ext) => specifier.endsWith(ext))) {
3044
- if (fs5.existsSync(base)) return base;
3130
+ if (fs6.existsSync(base)) return base;
3045
3131
  if (base.endsWith(".js")) {
3046
3132
  for (const ext of [".ts", ".tsx", ".jsx"]) {
3047
3133
  const file = base.slice(0, -3) + ext;
3048
- if (fs5.existsSync(file)) return file;
3134
+ if (fs6.existsSync(file)) return file;
3049
3135
  }
3050
3136
  }
3051
3137
  return null;
3052
3138
  }
3053
3139
  if (/\.(ts|tsx|jsx)$/.test(specifier)) {
3054
- return fs5.existsSync(base) ? base : null;
3140
+ return fs6.existsSync(base) ? base : null;
3055
3141
  }
3056
3142
  for (const ext of SOURCE_EXTS) {
3057
3143
  const file = base + ext;
3058
- if (fs5.existsSync(file)) return file;
3144
+ if (fs6.existsSync(file)) return file;
3059
3145
  }
3060
3146
  for (const indexExt of INDEX_EXTS) {
3061
3147
  const file = base + indexExt;
3062
- if (fs5.existsSync(file)) return file;
3148
+ if (fs6.existsSync(file)) return file;
3063
3149
  }
3064
3150
  return null;
3065
3151
  }
3066
3152
  function createAliasPlugin(config, options) {
3067
- const appDirAbs = options?.rootDir ? toRealPath(path7.resolve(options.rootDir, APP_DIR)) : null;
3153
+ const appDirAbs = options?.rootDir ? toRealPath(path8.resolve(options.rootDir, APP_DIR)) : null;
3068
3154
  const probeCandidateFile = (candidate) => {
3069
3155
  for (const ext of SOURCE_EXTS) {
3070
3156
  const file = candidate + ext;
3071
- if (fs5.existsSync(file)) return file;
3157
+ if (fs6.existsSync(file)) return file;
3072
3158
  }
3073
3159
  for (const indexExt of INDEX_EXTS) {
3074
3160
  const file = candidate + indexExt;
3075
- if (fs5.existsSync(file)) return file;
3161
+ if (fs6.existsSync(file)) return file;
3076
3162
  }
3077
3163
  return null;
3078
3164
  };
@@ -3082,7 +3168,7 @@ function createAliasPlugin(config, options) {
3082
3168
  build.onLoad({ filter: /\.(ts|tsx|js|jsx|mjs|cjs)$/ }, (args) => {
3083
3169
  let source;
3084
3170
  try {
3085
- source = fs5.readFileSync(args.path, "utf8");
3171
+ source = fs6.readFileSync(args.path, "utf8");
3086
3172
  } catch {
3087
3173
  return void 0;
3088
3174
  }
@@ -3207,11 +3293,11 @@ async function compileSourceFiles(options) {
3207
3293
  if (entryPoints.length === 0) {
3208
3294
  return { compiledFiles: [] };
3209
3295
  }
3210
- const absDist = path8.resolve(rootDir, dist);
3211
- await fs6.promises.mkdir(absDist, { recursive: true });
3296
+ const absDist = path9.resolve(rootDir, dist);
3297
+ await fs7.promises.mkdir(absDist, { recursive: true });
3212
3298
  const plugins = buildAliasPlugins(rootDir);
3213
3299
  const esbuild = await import("esbuild");
3214
- const outbase = path8.resolve(rootDir, APP_DIR);
3300
+ const outbase = path9.resolve(rootDir, APP_DIR);
3215
3301
  const result = await esbuild.build({
3216
3302
  entryPoints,
3217
3303
  outdir: absDist,
@@ -3231,10 +3317,10 @@ async function compileSourceFiles(options) {
3231
3317
  if (atomicWrite && result.outputFiles) {
3232
3318
  await Promise.all(
3233
3319
  result.outputFiles.map(async (file) => {
3234
- await fs6.promises.mkdir(path8.dirname(file.path), { recursive: true });
3320
+ await fs7.promises.mkdir(path9.dirname(file.path), { recursive: true });
3235
3321
  const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
3236
- await fs6.promises.writeFile(tmp, file.contents);
3237
- await fs6.promises.rename(tmp, file.path);
3322
+ await fs7.promises.writeFile(tmp, file.contents);
3323
+ await fs7.promises.rename(tmp, file.path);
3238
3324
  })
3239
3325
  );
3240
3326
  }
@@ -3251,8 +3337,8 @@ init_generateSchemaFiles();
3251
3337
  init_generateSchemaFiles();
3252
3338
 
3253
3339
  // src/cli/collectImports.ts
3254
- import path11 from "path";
3255
- import fs8 from "fs";
3340
+ import path12 from "path";
3341
+ import fs9 from "fs";
3256
3342
  var SPEC_RE = /(\bfrom\s*|import\s*\(\s*)(['"])([^'"]+)\2/g;
3257
3343
  function extractImportSpecifiers(source) {
3258
3344
  const specifiers = [];
@@ -3264,10 +3350,10 @@ function extractImportSpecifiers(source) {
3264
3350
  return specifiers;
3265
3351
  }
3266
3352
  function resolveSpecifierFromDir(dir, specifier) {
3267
- return resolveRelativeSpecifier(path11.join(dir, "__faapi_probe__.ts"), specifier);
3353
+ return resolveRelativeSpecifier(path12.join(dir, "__faapi_probe__.ts"), specifier);
3268
3354
  }
3269
3355
  async function collectRelativeImports(entryFiles, rootDir) {
3270
- const appDirAbs = toRealPath(path11.resolve(rootDir, "src"));
3356
+ const appDirAbs = toRealPath(path12.resolve(rootDir, "src"));
3271
3357
  const tsconfig = readTsconfig(rootDir);
3272
3358
  const visited = /* @__PURE__ */ new Set();
3273
3359
  const insideFiles = /* @__PURE__ */ new Set();
@@ -3277,7 +3363,7 @@ async function collectRelativeImports(entryFiles, rootDir) {
3277
3363
  visited.add(filePath);
3278
3364
  let source;
3279
3365
  try {
3280
- source = await fs8.promises.readFile(filePath, "utf8");
3366
+ source = await fs9.promises.readFile(filePath, "utf8");
3281
3367
  } catch {
3282
3368
  return;
3283
3369
  }
@@ -3299,7 +3385,7 @@ async function collectRelativeImports(entryFiles, rootDir) {
3299
3385
  resolved = null;
3300
3386
  }
3301
3387
  if (!resolved) continue;
3302
- if (!isInsideDir(toRealPath(resolved), toRealPath(path11.resolve(rootDir)))) continue;
3388
+ if (!isInsideDir(toRealPath(resolved), toRealPath(path12.resolve(rootDir)))) continue;
3303
3389
  if (isInsideDir(toRealPath(resolved), appDirAbs)) {
3304
3390
  insideFiles.add(resolved);
3305
3391
  } else {
@@ -3320,8 +3406,8 @@ async function collectRelativeImports(entryFiles, rootDir) {
3320
3406
  // src/cli/compileOnDemand.ts
3321
3407
  function isProductFresh(sourceAbsPath, productAbsPath) {
3322
3408
  try {
3323
- const srcStat = fs9.statSync(sourceAbsPath);
3324
- const prodStat = fs9.statSync(productAbsPath);
3409
+ const srcStat = fs10.statSync(sourceAbsPath);
3410
+ const prodStat = fs10.statSync(productAbsPath);
3325
3411
  return prodStat.mtimeMs >= srcStat.mtimeMs;
3326
3412
  } catch {
3327
3413
  return false;
@@ -3353,7 +3439,7 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
3353
3439
  if (state.compiledFiles.has(sourceAbsPath)) {
3354
3440
  return false;
3355
3441
  }
3356
- if (!fs9.existsSync(sourceAbsPath)) {
3442
+ if (!fs10.existsSync(sourceAbsPath)) {
3357
3443
  return false;
3358
3444
  }
3359
3445
  const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
@@ -3403,11 +3489,11 @@ async function ensureMiddlewaresCompiled(middlewarePaths, rootDir) {
3403
3489
  }
3404
3490
  }
3405
3491
  function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
3406
- const rel = path12.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3492
+ const rel = path13.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3407
3493
  if (!rel.startsWith("src/")) return null;
3408
3494
  const relWithoutSrc = rel.slice(4);
3409
3495
  const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
3410
- return path12.resolve(rootDir, dist, jsRel);
3496
+ return path13.resolve(rootDir, dist, jsRel);
3411
3497
  }
3412
3498
  function clearGeneratedSchemas() {
3413
3499
  state.generatedSchemas.clear();
@@ -3423,9 +3509,9 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
3423
3509
  if (state.generatedSchemas.has(schemaPath)) {
3424
3510
  return false;
3425
3511
  }
3426
- const prodAbsPath = path12.resolve(rootDir, routeFilePath);
3512
+ const prodAbsPath = path13.resolve(rootDir, routeFilePath);
3427
3513
  const sourceAbsPath = prodPathToSourcePath(prodAbsPath, rootDir, dist);
3428
- if (!fs9.existsSync(sourceAbsPath)) {
3514
+ if (!fs10.existsSync(sourceAbsPath)) {
3429
3515
  return false;
3430
3516
  }
3431
3517
  if (isProductFresh(sourceAbsPath, schemaPath)) {
@@ -3436,7 +3522,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
3436
3522
  if (fileRoutes.length === 0) {
3437
3523
  return false;
3438
3524
  }
3439
- const sourceRelPath = path12.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3525
+ const sourceRelPath = path13.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
3440
3526
  const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
3441
3527
  const generatePromise = (async () => {
3442
3528
  await generateSchemaFiles(sourceRoutes, rootDir, dist);
@@ -3457,7 +3543,7 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
3457
3543
  if (deleted.has(schemaPath)) continue;
3458
3544
  deleted.add(schemaPath);
3459
3545
  try {
3460
- await fs9.promises.unlink(schemaPath);
3546
+ await fs10.promises.unlink(schemaPath);
3461
3547
  } catch {
3462
3548
  }
3463
3549
  }
@@ -3466,19 +3552,19 @@ var sourcePathCache = /* @__PURE__ */ new Map();
3466
3552
  function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
3467
3553
  const cached = sourcePathCache.get(prodAbsPath);
3468
3554
  if (cached) return cached;
3469
- const rel = path12.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
3555
+ const rel = path13.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
3470
3556
  let relWithoutDist = rel;
3471
3557
  if (relWithoutDist.startsWith(`${dist}/`)) {
3472
3558
  relWithoutDist = relWithoutDist.slice(dist.length + 1);
3473
3559
  }
3474
3560
  const srcRel = `src/${relWithoutDist}`;
3475
3561
  const tsRel = srcRel.replace(/\.js$/, ".ts");
3476
- const tsAbs = path12.resolve(rootDir, tsRel);
3562
+ const tsAbs = path13.resolve(rootDir, tsRel);
3477
3563
  let result;
3478
- if (fs9.existsSync(tsAbs)) {
3564
+ if (fs10.existsSync(tsAbs)) {
3479
3565
  result = tsAbs;
3480
3566
  } else {
3481
- result = path12.resolve(rootDir, srcRel);
3567
+ result = path13.resolve(rootDir, srcRel);
3482
3568
  }
3483
3569
  sourcePathCache.set(prodAbsPath, result);
3484
3570
  return result;
@@ -3496,7 +3582,7 @@ async function loadAgentModule(filePath, hasRun, rootDir) {
3496
3582
  const dist = getDevDist();
3497
3583
  if (dist) {
3498
3584
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
3499
- if (sourcePath && fs10.existsSync(sourcePath)) {
3585
+ if (sourcePath && fs11.existsSync(sourcePath)) {
3500
3586
  try {
3501
3587
  await ensureCompiled(sourcePath, rootDir, dist);
3502
3588
  } catch (compileErr) {
@@ -3529,13 +3615,13 @@ async function loadAgentModule(filePath, hasRun, rootDir) {
3529
3615
  }
3530
3616
 
3531
3617
  // src/loader/loadToolModule.ts
3532
- import fs11 from "fs";
3618
+ import fs12 from "fs";
3533
3619
  async function loadToolModule(filePath, functionName, rootDir) {
3534
3620
  if (isDevOnDemandEnabled() && rootDir) {
3535
3621
  const dist = getDevDist();
3536
3622
  if (dist) {
3537
3623
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
3538
- if (sourcePath && fs11.existsSync(sourcePath)) {
3624
+ if (sourcePath && fs12.existsSync(sourcePath)) {
3539
3625
  try {
3540
3626
  await ensureCompiled(sourcePath, rootDir, dist);
3541
3627
  } catch (compileErr) {
@@ -3567,7 +3653,7 @@ async function loadToolModule(filePath, functionName, rootDir) {
3567
3653
  import { existsSync as existsSync2 } from "fs";
3568
3654
 
3569
3655
  // src/cli/generateToolArtifacts.ts
3570
- import path13 from "path";
3656
+ import path14 from "path";
3571
3657
  import { existsSync } from "fs";
3572
3658
 
3573
3659
  // src/ast/extractToolMetadata.ts
@@ -3691,7 +3777,7 @@ function collectToolSchemaSources(tools, rootDir) {
3691
3777
  const toolsByFile = /* @__PURE__ */ new Map();
3692
3778
  for (const tool of tools) {
3693
3779
  if (!tool.inputTypeName) continue;
3694
- const absPath = path13.resolve(rootDir, tool.filePath);
3780
+ const absPath = path14.resolve(rootDir, tool.filePath);
3695
3781
  let list = toolsByFile.get(absPath);
3696
3782
  if (!list) {
3697
3783
  list = [];
@@ -3751,15 +3837,15 @@ function generateToolSchemaFileSource(sources, resolveType, helpersImportPath) {
3751
3837
  }
3752
3838
  async function maybeGenerateHelpers(allSourceCode, distDir) {
3753
3839
  if (!usesCoerceHelpers(allSourceCode)) return;
3754
- const helpersPath = path13.resolve(distDir, HELPERS_FILENAME);
3840
+ const helpersPath = path14.resolve(distDir, HELPERS_FILENAME);
3755
3841
  if (existsSync(helpersPath)) return;
3756
3842
  await atomicWriteFile(helpersPath, generateHelpersFileSource());
3757
3843
  }
3758
3844
  async function generateToolArtifacts(tools, rootDir, dist, options) {
3759
3845
  const metadata = [];
3760
- const programByFile = createPrograms(tools.map((m) => path13.resolve(rootDir, m.filePath)));
3846
+ const programByFile = createPrograms(tools.map((m) => path14.resolve(rootDir, m.filePath)));
3761
3847
  for (const manifest of tools) {
3762
- const absPath = path13.resolve(rootDir, manifest.filePath);
3848
+ const absPath = path14.resolve(rootDir, manifest.filePath);
3763
3849
  const program = programByFile.get(absPath);
3764
3850
  const result = extractToolMetadata(program, absPath, manifest.functionName, {
3765
3851
  name: manifest.name,
@@ -3770,7 +3856,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
3770
3856
  }
3771
3857
  }
3772
3858
  const serialized = serializeTools(metadata, dist);
3773
- const toolsPath = path13.resolve(rootDir, dist, TOOLS_FILE);
3859
+ const toolsPath = path14.resolve(rootDir, dist, TOOLS_FILE);
3774
3860
  await writeToolsModule(serialized, toolsPath);
3775
3861
  if (options?.skipSchema) {
3776
3862
  return metadata;
@@ -3793,7 +3879,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
3793
3879
  }
3794
3880
  const fileEntries = [];
3795
3881
  for (const [filePath, fileSources] of sourcesByFile) {
3796
- const relFile = path13.relative(rootDir, filePath).replace(/\\/g, "/");
3882
+ const relFile = path14.relative(rootDir, filePath).replace(/\\/g, "/");
3797
3883
  const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
3798
3884
  const resolver = resolversByFile.get(filePath);
3799
3885
  let relForDir = relFile;
@@ -3811,7 +3897,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
3811
3897
  fileEntries.push({ outputPath, source });
3812
3898
  }
3813
3899
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
3814
- const distDir = path13.resolve(rootDir, dist);
3900
+ const distDir = path14.resolve(rootDir, dist);
3815
3901
  await maybeGenerateHelpers(allSourceCode, distDir);
3816
3902
  await Promise.all(
3817
3903
  fileEntries.map(({ outputPath, source }) => writeToolSchemaFile(outputPath, source))
@@ -3925,9 +4011,28 @@ function cors(options = {}) {
3925
4011
  }
3926
4012
 
3927
4013
  // src/middleware/logger.ts
4014
+ function levelForStatus(status) {
4015
+ if (status >= 500) return "error";
4016
+ if (status >= 400) return "warn";
4017
+ return "info";
4018
+ }
4019
+ function defaultLog(entry, text) {
4020
+ if (isAccessLogPiped()) {
4021
+ const logEntry = {
4022
+ level: levelForStatus(entry.status),
4023
+ message: text,
4024
+ time: (/* @__PURE__ */ new Date()).toISOString(),
4025
+ scope: "access",
4026
+ fields: entry
4027
+ };
4028
+ writeLogEntry(logEntry);
4029
+ return;
4030
+ }
4031
+ console.log(entry);
4032
+ }
3928
4033
  function logger(options = {}) {
3929
4034
  return async (ctx, next) => {
3930
- const log = options.log ?? console.log;
4035
+ const log = options.log ?? defaultLog;
3931
4036
  const start = Date.now();
3932
4037
  try {
3933
4038
  const response = await next();
@@ -4022,16 +4127,16 @@ function helmet(options = {}) {
4022
4127
  }
4023
4128
 
4024
4129
  // src/config/loadConfig.ts
4025
- import path14 from "path";
4026
- import fs12 from "fs";
4130
+ import path15 from "path";
4131
+ import fs13 from "fs";
4027
4132
  var CONFIG_PRODUCT_FILE = "faapi-config.js";
4028
4133
  async function loadConfig(rootDir, dist) {
4029
- const configProductPath = path14.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
4030
- if (fs12.existsSync(configProductPath)) {
4134
+ const configProductPath = path15.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
4135
+ if (fs13.existsSync(configProductPath)) {
4031
4136
  const module = await importWithCacheBust(configProductPath);
4032
4137
  return module.default ?? {};
4033
4138
  }
4034
- const hasSourceConfig = fs12.existsSync(path14.join(rootDir, "faapi.config.ts")) || fs12.existsSync(path14.join(rootDir, "faapi.config.js"));
4139
+ const hasSourceConfig = fs13.existsSync(path15.join(rootDir, "faapi.config.ts")) || fs13.existsSync(path15.join(rootDir, "faapi.config.js"));
4035
4140
  if (hasSourceConfig) {
4036
4141
  throw new Error(
4037
4142
  `[faapi] ${dist}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
@@ -4041,8 +4146,8 @@ async function loadConfig(rootDir, dist) {
4041
4146
  }
4042
4147
 
4043
4148
  // src/cli/loadEnv.ts
4044
- import fs13 from "fs";
4045
- import path15 from "path";
4149
+ import fs14 from "fs";
4150
+ import path16 from "path";
4046
4151
  function resolveEnv() {
4047
4152
  return process.env.NODE_ENV || "development";
4048
4153
  }
@@ -4109,9 +4214,9 @@ function loadEnv(rootDir) {
4109
4214
  const files = getEnvFiles(env);
4110
4215
  const merged = {};
4111
4216
  for (const file of files) {
4112
- const filePath = path15.join(rootDir, file);
4113
- if (!fs13.existsSync(filePath)) continue;
4114
- const content = fs13.readFileSync(filePath, "utf-8");
4217
+ const filePath = path16.join(rootDir, file);
4218
+ if (!fs14.existsSync(filePath)) continue;
4219
+ const content = fs14.readFileSync(filePath, "utf-8");
4115
4220
  const parsed = parseEnvFile(content, merged);
4116
4221
  Object.assign(merged, parsed);
4117
4222
  }
@@ -4123,8 +4228,8 @@ function loadEnv(rootDir) {
4123
4228
  }
4124
4229
 
4125
4230
  // src/cli/createAppCore.ts
4126
- import fs18 from "fs";
4127
- import path23 from "path";
4231
+ import fs19 from "fs";
4232
+ import path24 from "path";
4128
4233
  import { PassThrough, Readable as Readable3 } from "stream";
4129
4234
 
4130
4235
  // src/router/sortRoutes.ts
@@ -4177,7 +4282,7 @@ import {
4177
4282
  import { createSecureServer as createHttp2SecureServer } from "http2";
4178
4283
  import { readFileSync } from "fs";
4179
4284
  import { Readable as Readable2 } from "stream";
4180
- import path17 from "path";
4285
+ import path18 from "path";
4181
4286
 
4182
4287
  // src/router/matchRoute.ts
4183
4288
  var httpIndexCache = /* @__PURE__ */ new WeakMap();
@@ -4219,18 +4324,18 @@ function getWsIndex(routes) {
4219
4324
  wsIndexCache.set(routes, index);
4220
4325
  return index;
4221
4326
  }
4222
- function matchRoute(routes, method, path28) {
4327
+ function matchRoute(routes, method, path29) {
4223
4328
  const index = getHttpIndex(routes);
4224
4329
  const upper = method.toUpperCase();
4225
- const hit = matchByMethod(index, upper, path28);
4330
+ const hit = matchByMethod(index, upper, path29);
4226
4331
  if (hit) return hit;
4227
4332
  if (upper === "HEAD") {
4228
- return matchByMethod(index, "GET", path28);
4333
+ return matchByMethod(index, "GET", path29);
4229
4334
  }
4230
4335
  return null;
4231
4336
  }
4232
- function matchByMethod(index, method, path28) {
4233
- const staticHit = index.static.get(`${method}|${path28}`);
4337
+ function matchByMethod(index, method, path29) {
4338
+ const staticHit = index.static.get(`${method}|${path29}`);
4234
4339
  if (staticHit) {
4235
4340
  return { route: staticHit, params: {} };
4236
4341
  }
@@ -4239,31 +4344,31 @@ function matchByMethod(index, method, path28) {
4239
4344
  if (route.method !== method) {
4240
4345
  continue;
4241
4346
  }
4242
- const params = matchSegments(entry.segments, path28, route.paramNames, route.isCatchAll);
4347
+ const params = matchSegments(entry.segments, path29, route.paramNames, route.isCatchAll);
4243
4348
  if (params !== null) {
4244
4349
  return { route, params };
4245
4350
  }
4246
4351
  }
4247
4352
  return null;
4248
4353
  }
4249
- function matchWsRoute(wsRoutes, path28) {
4354
+ function matchWsRoute(wsRoutes, path29) {
4250
4355
  const index = getWsIndex(wsRoutes);
4251
- const staticHit = index.static.get(path28);
4356
+ const staticHit = index.static.get(path29);
4252
4357
  if (staticHit) {
4253
4358
  return { route: staticHit, params: {} };
4254
4359
  }
4255
4360
  for (const route of index.dynamics) {
4256
- const params = matchDynamicPath(route.urlPath, path28, route.paramNames, route.isCatchAll);
4361
+ const params = matchDynamicPath(route.urlPath, path29, route.paramNames, route.isCatchAll);
4257
4362
  if (params !== null) {
4258
4363
  return { route, params };
4259
4364
  }
4260
4365
  }
4261
4366
  return null;
4262
4367
  }
4263
- function findAllowedMethods(routes, path28) {
4368
+ function findAllowedMethods(routes, path29) {
4264
4369
  const index = getHttpIndex(routes);
4265
4370
  const methods = /* @__PURE__ */ new Set();
4266
- const staticMethods = index.methodsByStaticPath.get(path28);
4371
+ const staticMethods = index.methodsByStaticPath.get(path29);
4267
4372
  if (staticMethods) {
4268
4373
  for (const method of staticMethods) {
4269
4374
  methods.add(method);
@@ -4272,7 +4377,7 @@ function findAllowedMethods(routes, path28) {
4272
4377
  for (const entry of index.dynamics) {
4273
4378
  const params = matchSegments(
4274
4379
  entry.segments,
4275
- path28,
4380
+ path29,
4276
4381
  entry.route.paramNames,
4277
4382
  entry.route.isCatchAll
4278
4383
  );
@@ -4285,11 +4390,11 @@ function findAllowedMethods(routes, path28) {
4285
4390
  }
4286
4391
  return Array.from(methods);
4287
4392
  }
4288
- function matchDynamicPath(pattern, path28, paramNames, isCatchAll) {
4289
- return matchSegments(pattern.split("/").filter(Boolean), path28, paramNames, isCatchAll);
4393
+ function matchDynamicPath(pattern, path29, paramNames, isCatchAll) {
4394
+ return matchSegments(pattern.split("/").filter(Boolean), path29, paramNames, isCatchAll);
4290
4395
  }
4291
- function matchSegments(patternSegments, path28, paramNames, isCatchAll) {
4292
- const pathSegments = path28.split("/").filter(Boolean);
4396
+ function matchSegments(patternSegments, path29, paramNames, isCatchAll) {
4397
+ const pathSegments = path29.split("/").filter(Boolean);
4293
4398
  if (isCatchAll) {
4294
4399
  const nonCatchAllCount = patternSegments.length - 1;
4295
4400
  if (pathSegments.length <= nonCatchAllCount) {
@@ -5196,9 +5301,9 @@ async function validateInput(schemaPath, method, inputType, input) {
5196
5301
  function mapZodIssues(error) {
5197
5302
  return error.issues.map((issue) => {
5198
5303
  const code = mapZodCode(issue);
5199
- const path28 = issue.path.map(String).join(".") || "";
5304
+ const path29 = issue.path.map(String).join(".") || "";
5200
5305
  return {
5201
- path: path28,
5306
+ path: path29,
5202
5307
  code,
5203
5308
  expected: issue.expected ?? mapExpectedFromMessage(issue.message),
5204
5309
  received: issue.received ?? mapReceivedFromMessage(issue.message),
@@ -5430,9 +5535,9 @@ function etag(options = {}) {
5430
5535
  }
5431
5536
 
5432
5537
  // src/server/handleWsUpgrade.ts
5433
- import fs14 from "fs";
5538
+ import fs15 from "fs";
5434
5539
  import { WebSocketServer, WebSocket } from "ws";
5435
- import path16 from "path";
5540
+ import path17 from "path";
5436
5541
 
5437
5542
  // src/server/serverUtils.ts
5438
5543
  function nodeHttpToWebHeaders(req) {
@@ -5567,7 +5672,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
5567
5672
  const dist = getDevDist();
5568
5673
  if (dist) {
5569
5674
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
5570
- if (sourcePath && fs14.existsSync(sourcePath)) {
5675
+ if (sourcePath && fs15.existsSync(sourcePath)) {
5571
5676
  await ensureCompiled(sourcePath, rootDir, dist);
5572
5677
  }
5573
5678
  }
@@ -5681,7 +5786,7 @@ function attachWebSocket(options) {
5681
5786
  const finalHandler = async () => {
5682
5787
  let handlers;
5683
5788
  try {
5684
- const absoluteFilePath = path16.resolve(rootDir, route.filePath);
5789
+ const absoluteFilePath = path17.resolve(rootDir, route.filePath);
5685
5790
  handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
5686
5791
  } catch (err) {
5687
5792
  const reason = err instanceof Error ? err.message : String(err);
@@ -5934,7 +6039,7 @@ function getRoutePaths(route, rootDir, dist) {
5934
6039
  let cached = routePathCache.get(route);
5935
6040
  if (!cached) {
5936
6041
  cached = {
5937
- absFilePath: path17.resolve(rootDir, route.filePath),
6042
+ absFilePath: path18.resolve(rootDir, route.filePath),
5938
6043
  schemaPath: getRuntimeSchemaPath(route.filePath, dist, rootDir)
5939
6044
  };
5940
6045
  routePathCache.set(route, cached);
@@ -6056,8 +6161,8 @@ function applyPluginWrappers(server, handlerWrappers, upgradeWrappers) {
6056
6161
  }
6057
6162
 
6058
6163
  // src/cli/generateRoutes.ts
6059
- import fs15 from "fs";
6060
- import path18 from "path";
6164
+ import fs16 from "fs";
6165
+ import path19 from "path";
6061
6166
  async function hydrateRoutes(manifest) {
6062
6167
  const hydrateRoute = (serialized) => ({
6063
6168
  method: serialized.method,
@@ -6082,7 +6187,7 @@ async function hydrateRoutes(manifest) {
6082
6187
  }
6083
6188
 
6084
6189
  // src/cli/generateAgentArtifacts.ts
6085
- import path19 from "path";
6190
+ import path20 from "path";
6086
6191
 
6087
6192
  // src/ast/extractAgentMetadata.ts
6088
6193
  import ts10 from "typescript";
@@ -6355,9 +6460,9 @@ function validateAgentList(metadata) {
6355
6460
  }
6356
6461
  async function generateAgentArtifacts(agents, rootDir, dist) {
6357
6462
  const metadata = [];
6358
- const programByFile = createPrograms(agents.map((m) => path19.resolve(rootDir, m.filePath)));
6463
+ const programByFile = createPrograms(agents.map((m) => path20.resolve(rootDir, m.filePath)));
6359
6464
  for (const manifest of agents) {
6360
- const absPath = path19.resolve(rootDir, manifest.filePath);
6465
+ const absPath = path20.resolve(rootDir, manifest.filePath);
6361
6466
  const program = programByFile.get(absPath);
6362
6467
  const result = extractAgentMetadata(program, absPath, {
6363
6468
  name: manifest.name,
@@ -6373,13 +6478,13 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
6373
6478
  }
6374
6479
  validateAgentList(metadata);
6375
6480
  const serialized = serializeAgents(metadata, dist);
6376
- const agentsPath = path19.resolve(rootDir, dist, AGENTS_FILE);
6481
+ const agentsPath = path20.resolve(rootDir, dist, AGENTS_FILE);
6377
6482
  await writeAgentsModule(serialized, agentsPath);
6378
6483
  return metadata;
6379
6484
  }
6380
6485
 
6381
6486
  // src/cli/generateTaskArtifacts.ts
6382
- import path20 from "path";
6487
+ import path21 from "path";
6383
6488
  init_createProgram();
6384
6489
  init_atomicWrite();
6385
6490
  init_generateSchemaFiles();
@@ -6418,7 +6523,7 @@ function collectTaskSchemaSources(tasks, rootDir) {
6418
6523
  const tasksByFile = /* @__PURE__ */ new Map();
6419
6524
  for (const task of tasks) {
6420
6525
  if (!task.inputTypeName) continue;
6421
- const absPath = path20.resolve(rootDir, task.filePath);
6526
+ const absPath = path21.resolve(rootDir, task.filePath);
6422
6527
  let list = tasksByFile.get(absPath);
6423
6528
  if (!list) {
6424
6529
  list = [];
@@ -6475,9 +6580,9 @@ function generateTaskSchemaFileSource(sources, resolveType, helpersImportPath) {
6475
6580
  async function generateTaskArtifacts(manifests, rootDir, dist) {
6476
6581
  const metadata = [];
6477
6582
  if (manifests.length > 0) {
6478
- const programByFile = createPrograms(manifests.map((m) => path20.resolve(rootDir, m.filePath)));
6583
+ const programByFile = createPrograms(manifests.map((m) => path21.resolve(rootDir, m.filePath)));
6479
6584
  for (const manifest of manifests) {
6480
- const absPath = path20.resolve(rootDir, manifest.filePath);
6585
+ const absPath = path21.resolve(rootDir, manifest.filePath);
6481
6586
  const result = extractToolMetadata(programByFile.get(absPath), absPath, "run", {
6482
6587
  name: manifest.name,
6483
6588
  filePath: manifest.filePath
@@ -6488,7 +6593,7 @@ async function generateTaskArtifacts(manifests, rootDir, dist) {
6488
6593
  }
6489
6594
  }
6490
6595
  const serialized = serializeTasks(manifests, dist);
6491
- const tasksPath = path20.resolve(rootDir, dist, TASKS_FILE);
6596
+ const tasksPath = path21.resolve(rootDir, dist, TASKS_FILE);
6492
6597
  await writeTasksModule(serialized, tasksPath);
6493
6598
  if (metadata.length === 0) {
6494
6599
  return hydrateTasks(serialized);
@@ -6508,7 +6613,7 @@ async function generateTaskArtifacts(manifests, rootDir, dist) {
6508
6613
  }
6509
6614
  const fileEntries = [];
6510
6615
  for (const [filePath, fileSources] of sourcesByFile) {
6511
- const relFile = path20.relative(rootDir, filePath).replace(/\\/g, "/");
6616
+ const relFile = path21.relative(rootDir, filePath).replace(/\\/g, "/");
6512
6617
  const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
6513
6618
  const resolver = resolversByFile.get(filePath);
6514
6619
  let relForDir = relFile;
@@ -6527,7 +6632,7 @@ async function generateTaskArtifacts(manifests, rootDir, dist) {
6527
6632
  }
6528
6633
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
6529
6634
  if (usesCoerceHelpers(allSourceCode)) {
6530
- const helpersPath = path20.resolve(rootDir, dist, HELPERS_FILENAME);
6635
+ const helpersPath = path21.resolve(rootDir, dist, HELPERS_FILENAME);
6531
6636
  const { existsSync: existsSync3 } = await import("fs");
6532
6637
  if (!existsSync3(helpersPath)) {
6533
6638
  await atomicWriteFile(helpersPath, generateHelpersFileSource());
@@ -6559,18 +6664,18 @@ function createIdleTaskDriver() {
6559
6664
  }
6560
6665
 
6561
6666
  // src/cli/loadPlugins.ts
6562
- import path22 from "path";
6563
- import fs17 from "fs";
6667
+ import path23 from "path";
6668
+ import fs18 from "fs";
6564
6669
  import { pathToFileURL as pathToFileURL3 } from "url";
6565
6670
 
6566
6671
  // src/cli/compileConfig.ts
6567
- import path21 from "path";
6568
- import fs16 from "fs";
6672
+ import path22 from "path";
6673
+ import fs17 from "fs";
6569
6674
  async function compileProjectModules(entryPoints, rootDir, dist) {
6570
6675
  const { insideFiles, outsideFiles } = await collectRelativeImports(entryPoints, rootDir);
6571
6676
  const esbuild = await import("esbuild");
6572
6677
  const aliasPlugins = buildAliasPlugins(rootDir);
6573
- const absDist = path21.resolve(rootDir, dist);
6678
+ const absDist = path22.resolve(rootDir, dist);
6574
6679
  await esbuild.build({
6575
6680
  entryPoints: [...entryPoints, ...outsideFiles],
6576
6681
  outdir: absDist,
@@ -6584,7 +6689,7 @@ async function compileProjectModules(entryPoints, rootDir, dist) {
6584
6689
  logLevel: "silent"
6585
6690
  });
6586
6691
  if (insideFiles.length > 0) {
6587
- const appOutbase = path21.resolve(rootDir, "src");
6692
+ const appOutbase = path22.resolve(rootDir, "src");
6588
6693
  await esbuild.build({
6589
6694
  entryPoints: insideFiles,
6590
6695
  outdir: absDist,
@@ -6665,37 +6770,37 @@ async function loadPlugins(declarations, ctx, rootDir, dist) {
6665
6770
  var TS_EXTS = /\.(ts|tsx|mts|cts)$/;
6666
6771
  var JS_EXTS = /\.(js|mjs|cjs|jsx)$/;
6667
6772
  function resolveLocalPluginSource(specifier, baseDir) {
6668
- const base = path22.isAbsolute(specifier) ? specifier : path22.resolve(baseDir, specifier);
6669
- if ((TS_EXTS.test(base) || JS_EXTS.test(base)) && fs17.existsSync(base)) return base;
6773
+ const base = path23.isAbsolute(specifier) ? specifier : path23.resolve(baseDir, specifier);
6774
+ if ((TS_EXTS.test(base) || JS_EXTS.test(base)) && fs18.existsSync(base)) return base;
6670
6775
  for (const ext of [".ts", ".js"]) {
6671
- if (fs17.existsSync(base + ext)) return base + ext;
6776
+ if (fs18.existsSync(base + ext)) return base + ext;
6672
6777
  }
6673
6778
  for (const indexExt of ["/index.ts", "/index.js"]) {
6674
- if (fs17.existsSync(base + indexExt)) return base + indexExt;
6779
+ if (fs18.existsSync(base + indexExt)) return base + indexExt;
6675
6780
  }
6676
6781
  return null;
6677
6782
  }
6678
6783
  function mirrorProductPath(sourcePath, baseDir, distDir) {
6679
- let rel = path22.relative(baseDir, sourcePath).replace(/\\/g, "/");
6784
+ let rel = path23.relative(baseDir, sourcePath).replace(/\\/g, "/");
6680
6785
  if (rel.startsWith("src/")) rel = rel.slice(4);
6681
- return path22.resolve(distDir, rel.replace(TS_EXTS, ".js"));
6786
+ return path23.resolve(distDir, rel.replace(TS_EXTS, ".js"));
6682
6787
  }
6683
6788
  function isSourceNewer(sourcePath, productPath) {
6684
6789
  try {
6685
- return fs17.statSync(sourcePath).mtimeMs > fs17.statSync(productPath).mtimeMs;
6790
+ return fs18.statSync(sourcePath).mtimeMs > fs18.statSync(productPath).mtimeMs;
6686
6791
  } catch {
6687
6792
  return true;
6688
6793
  }
6689
6794
  }
6690
6795
  async function importPluginModule(specifier, baseDir, dist) {
6691
6796
  const isRelative = specifier.startsWith("./") || specifier.startsWith("../");
6692
- if (!isRelative && !path22.isAbsolute(specifier)) {
6797
+ if (!isRelative && !path23.isAbsolute(specifier)) {
6693
6798
  return import(specifier);
6694
6799
  }
6695
- const distDir = dist ? path22.resolve(baseDir, dist) : null;
6800
+ const distDir = dist ? path23.resolve(baseDir, dist) : null;
6696
6801
  const sourcePath = resolveLocalPluginSource(specifier, baseDir);
6697
6802
  const productPath = sourcePath && distDir ? mirrorProductPath(sourcePath, baseDir, distDir) : null;
6698
- if (productPath !== null && fs17.existsSync(productPath) && (sourcePath === null || !isSourceNewer(sourcePath, productPath))) {
6803
+ if (productPath !== null && fs18.existsSync(productPath) && (sourcePath === null || !isSourceNewer(sourcePath, productPath))) {
6699
6804
  return import(pathToFileURL3(productPath).href);
6700
6805
  }
6701
6806
  if (sourcePath && TS_EXTS.test(sourcePath)) {
@@ -6704,13 +6809,13 @@ async function importPluginModule(specifier, baseDir, dist) {
6704
6809
  `Local plugin "${specifier}" has no up-to-date build artifact (dist is stale or missing). Run "faapi build" first, or use "faapi dev" for on-demand compilation.`
6705
6810
  );
6706
6811
  }
6707
- const relFromRoot = path22.relative(baseDir, sourcePath).replace(/\\/g, "/");
6812
+ const relFromRoot = path23.relative(baseDir, sourcePath).replace(/\\/g, "/");
6708
6813
  if (relFromRoot.startsWith("src/")) {
6709
6814
  await ensureCompiled(sourcePath, baseDir, dist);
6710
6815
  } else {
6711
6816
  await compileProjectModules([sourcePath], baseDir, dist);
6712
6817
  }
6713
- if (productPath && fs17.existsSync(productPath)) {
6818
+ if (productPath && fs18.existsSync(productPath)) {
6714
6819
  return import(pathToFileURL3(productPath).href);
6715
6820
  }
6716
6821
  }
@@ -6722,7 +6827,7 @@ async function importPluginModule(specifier, baseDir, dist) {
6722
6827
  `${specifier}/index.ts`,
6723
6828
  `${specifier}.js`,
6724
6829
  `${specifier}/index.js`
6725
- ].map((c) => path22.isAbsolute(c) ? c : path22.join(baseDir, c));
6830
+ ].map((c) => path23.isAbsolute(c) ? c : path23.join(baseDir, c));
6726
6831
  throw new Error(
6727
6832
  `Cannot find local plugin "${specifier}" (resolved from ${baseDir}). Expected one of:
6728
6833
  ${candidates.join("\n ")}
@@ -6753,8 +6858,8 @@ var ROUTES_FILE = "faapi-routes.js";
6753
6858
  var TOOLS_FILE2 = "faapi-tools.js";
6754
6859
  var AGENTS_FILE2 = "faapi-agents.js";
6755
6860
  async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries) {
6756
- const toolsPath = path23.resolve(rootDir, dist, TOOLS_FILE2);
6757
- if (!fs18.existsSync(toolsPath)) {
6861
+ const toolsPath = path24.resolve(rootDir, dist, TOOLS_FILE2);
6862
+ if (!fs19.existsSync(toolsPath)) {
6758
6863
  return [];
6759
6864
  }
6760
6865
  const serialized = await importWithCacheBust(toolsPath);
@@ -6763,8 +6868,8 @@ async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries
6763
6868
  return hydrated;
6764
6869
  }
6765
6870
  async function loadAndHydrateAgents(rootDir, dist, registries = defaultRegistries) {
6766
- const agentsPath = path23.resolve(rootDir, dist, AGENTS_FILE2);
6767
- if (!fs18.existsSync(agentsPath)) {
6871
+ const agentsPath = path24.resolve(rootDir, dist, AGENTS_FILE2);
6872
+ if (!fs19.existsSync(agentsPath)) {
6768
6873
  return [];
6769
6874
  }
6770
6875
  const serialized = await importWithCacheBust(agentsPath);
@@ -6779,8 +6884,8 @@ function getTaskDriverOptions(config) {
6779
6884
  return void 0;
6780
6885
  }
6781
6886
  async function loadAndHydrateTasks(rootDir, dist, registries = defaultRegistries) {
6782
- const tasksPath = path23.resolve(rootDir, dist, TASKS_FILE);
6783
- if (!fs18.existsSync(tasksPath)) {
6887
+ const tasksPath = path24.resolve(rootDir, dist, TASKS_FILE);
6888
+ if (!fs19.existsSync(tasksPath)) {
6784
6889
  return [];
6785
6890
  }
6786
6891
  const serialized = await importWithCacheBust(tasksPath);
@@ -6849,8 +6954,8 @@ function isFaapiConfigKey(key) {
6849
6954
  async function createAppBase(options) {
6850
6955
  const rootDir = options?.rootDir ?? process.cwd();
6851
6956
  const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
6852
- const routesPath = path23.resolve(rootDir, dist, ROUTES_FILE);
6853
- if (!fs18.existsSync(routesPath)) {
6957
+ const routesPath = path24.resolve(rootDir, dist, ROUTES_FILE);
6958
+ if (!fs19.existsSync(routesPath)) {
6854
6959
  throw new Error(
6855
6960
  `[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
6856
6961
  );
@@ -7178,21 +7283,21 @@ async function createAppBase(options) {
7178
7283
  }
7179
7284
 
7180
7285
  // src/cli/createDevApp.ts
7181
- import path27 from "path";
7286
+ import path28 from "path";
7182
7287
 
7183
7288
  // src/router/scanRoutes.ts
7184
7289
  import fg3 from "fast-glob";
7185
- import path24 from "path";
7186
- import fs19 from "fs";
7290
+ import path25 from "path";
7291
+ import fs20 from "fs";
7187
7292
 
7188
7293
  // src/router/constants.ts
7189
7294
  var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
7190
7295
  var HTTP_METHOD_SET = new Set(HTTP_METHODS);
7191
7296
 
7192
7297
  // src/utils/normalizePath.ts
7193
- function normalizePath(path28) {
7194
- if (!path28) return "";
7195
- let result = path28.replace(/\\/g, "/");
7298
+ function normalizePath(path29) {
7299
+ if (!path29) return "";
7300
+ let result = path29.replace(/\\/g, "/");
7196
7301
  result = result.replace(/\/+/g, "/");
7197
7302
  result = result.replace(/\/+$/, "");
7198
7303
  if (result && !result.startsWith("/")) {
@@ -7253,34 +7358,34 @@ function extractExportsFromSource(source) {
7253
7358
  return names;
7254
7359
  }
7255
7360
  function collectMiddlewarePaths(routeFilePath, rootDir, dist) {
7256
- const routeDir = path24.dirname(routeFilePath);
7257
- const resolvedRoot = path24.resolve(rootDir);
7361
+ const routeDir = path25.dirname(routeFilePath);
7362
+ const resolvedRoot = path25.resolve(rootDir);
7258
7363
  const paths = [];
7259
- let currentDir = path24.resolve(rootDir, routeDir);
7364
+ let currentDir = path25.resolve(rootDir, routeDir);
7260
7365
  while (true) {
7261
7366
  if (dist) {
7262
- const mwTsPath = path24.join(currentDir, "middlewares.ts");
7263
- const mwJsPath = path24.join(currentDir, "middlewares.js");
7264
- const absTsPath = path24.resolve(rootDir, mwTsPath);
7265
- const absJsPath = path24.resolve(rootDir, mwJsPath);
7266
- const absMwPath = fs19.existsSync(absTsPath) ? absTsPath : fs19.existsSync(absJsPath) ? absJsPath : null;
7367
+ const mwTsPath = path25.join(currentDir, "middlewares.ts");
7368
+ const mwJsPath = path25.join(currentDir, "middlewares.js");
7369
+ const absTsPath = path25.resolve(rootDir, mwTsPath);
7370
+ const absJsPath = path25.resolve(rootDir, mwJsPath);
7371
+ const absMwPath = fs20.existsSync(absTsPath) ? absTsPath : fs20.existsSync(absJsPath) ? absJsPath : null;
7267
7372
  if (absMwPath) {
7268
- const relMwPath = path24.relative(rootDir, absMwPath);
7269
- const prodAbsPath = path24.resolve(rootDir, toProdFilePath(relMwPath, dist));
7373
+ const relMwPath = path25.relative(rootDir, absMwPath);
7374
+ const prodAbsPath = path25.resolve(rootDir, toProdFilePath(relMwPath, dist));
7270
7375
  paths.push(prodAbsPath);
7271
7376
  }
7272
7377
  } else {
7273
7378
  for (const ext of [".ts", ".js"]) {
7274
- const mwPath = path24.join(currentDir, `middlewares${ext}`);
7275
- const absMwPath = path24.resolve(rootDir, mwPath);
7276
- if (fs19.existsSync(absMwPath)) {
7379
+ const mwPath = path25.join(currentDir, `middlewares${ext}`);
7380
+ const absMwPath = path25.resolve(rootDir, mwPath);
7381
+ if (fs20.existsSync(absMwPath)) {
7277
7382
  paths.push(absMwPath);
7278
7383
  break;
7279
7384
  }
7280
7385
  }
7281
7386
  }
7282
7387
  if (currentDir === resolvedRoot) break;
7283
- const parentDir = path24.dirname(currentDir);
7388
+ const parentDir = path25.dirname(currentDir);
7284
7389
  if (parentDir === currentDir) break;
7285
7390
  currentDir = parentDir;
7286
7391
  }
@@ -7299,7 +7404,7 @@ async function scanRoutes(rootDir, patterns, dist) {
7299
7404
  const normalizedFile = file.replace(/\\/g, "/");
7300
7405
  const fileName = normalizedFile.split("/").pop();
7301
7406
  if (fileName === "handler.ts" || fileName === "handler.js") {
7302
- const absPath = path24.resolve(rootDir, normalizedFile);
7407
+ const absPath = path25.resolve(rootDir, normalizedFile);
7303
7408
  const urlPath = filePathToUrlPath(normalizedFile);
7304
7409
  const paramNames = extractParamNames(urlPath);
7305
7410
  const isDynamic = paramNames.length > 0;
@@ -7312,7 +7417,7 @@ async function scanRoutes(rootDir, patterns, dist) {
7312
7417
  const mwPaths = collectMiddlewarePaths(normalizedFile, rootDir);
7313
7418
  middlewareBundle = await loadMergedMiddlewares(mwPaths);
7314
7419
  }
7315
- const source = await fs19.promises.readFile(absPath, "utf8").catch(() => "");
7420
+ const source = await fs20.promises.readFile(absPath, "utf8").catch(() => "");
7316
7421
  const exportNames = extractExportsFromSource(source);
7317
7422
  const methods = HTTP_METHODS.filter((m) => exportNames.has(m));
7318
7423
  for (const method of methods) {
@@ -7348,8 +7453,8 @@ async function scanRoutes(rootDir, patterns, dist) {
7348
7453
 
7349
7454
  // src/tools/scanTools.ts
7350
7455
  import fg4 from "fast-glob";
7351
- import path25 from "path";
7352
- import fs20 from "fs";
7456
+ import path26 from "path";
7457
+ import fs21 from "fs";
7353
7458
  var TOOL_PATTERNS = ["src/tools/**/*.ts"];
7354
7459
  var TOOL_EXPORT_RE = new RegExp(
7355
7460
  String.raw`export\s+(?:async\s+)?(?:function\s+|const\s+)([A-Za-z_$][\w$]*)\s*(?:\(|=)`,
@@ -7399,8 +7504,8 @@ async function scanTools(rootDir, patterns) {
7399
7504
  if (fileName !== "handler.ts" && fileName !== "handler.js") {
7400
7505
  continue;
7401
7506
  }
7402
- const absPath = path25.resolve(rootDir, normalizedFile);
7403
- const source = await fs20.promises.readFile(absPath, "utf8").catch(() => "");
7507
+ const absPath = path26.resolve(rootDir, normalizedFile);
7508
+ const source = await fs21.promises.readFile(absPath, "utf8").catch(() => "");
7404
7509
  const exportNames = extractToolExportsFromSource(source);
7405
7510
  const namespace = filePathToToolNamespace(normalizedFile);
7406
7511
  for (const fnName of exportNames) {
@@ -7424,8 +7529,8 @@ async function scanTools(rootDir, patterns) {
7424
7529
 
7425
7530
  // src/agents/scanAgents.ts
7426
7531
  import fg5 from "fast-glob";
7427
- import path26 from "path";
7428
- import fs21 from "fs";
7532
+ import path27 from "path";
7533
+ import fs22 from "fs";
7429
7534
  var DEFAULT_AGENT_PATTERNS = ["src/agents/**/handler.ts"];
7430
7535
  var RUN_EXPORT_RE = /export\s+(?:async\s+)?(?:function\s+|const\s+)run\b/;
7431
7536
  function extractAgentNameFromPath(filePath) {
@@ -7457,8 +7562,8 @@ async function scanAgents(rootDir, patterns) {
7457
7562
  if (fileName !== "handler.ts" && fileName !== "handler.js") {
7458
7563
  continue;
7459
7564
  }
7460
- const absPath = path26.resolve(rootDir, normalizedFile);
7461
- const source = await fs21.promises.readFile(absPath, "utf8").catch(() => "");
7565
+ const absPath = path27.resolve(rootDir, normalizedFile);
7566
+ const source = await fs22.promises.readFile(absPath, "utf8").catch(() => "");
7462
7567
  const { hasRun } = detectAgentExports(source);
7463
7568
  const name = extractAgentNameFromPath(normalizedFile);
7464
7569
  const prevFile = seen.get(name);
@@ -7528,7 +7633,7 @@ async function createDevApp(options) {
7528
7633
  invalidateProgramCache();
7529
7634
  const tasks = await scanTasks(ctx.rootDir, TASK_PATTERNS);
7530
7635
  for (const task of tasks) {
7531
- await ensureCompiled(path27.resolve(ctx.rootDir, task.filePath), ctx.rootDir, ctx.dist);
7636
+ await ensureCompiled(path28.resolve(ctx.rootDir, task.filePath), ctx.rootDir, ctx.dist);
7532
7637
  }
7533
7638
  await generateTaskArtifacts(tasks, ctx.rootDir, ctx.dist);
7534
7639
  ctx.taskQueue.invalidateModules();
@@ -7569,6 +7674,7 @@ export {
7569
7674
  createTaskRegistriesView,
7570
7675
  createTaskRegistry,
7571
7676
  extractTypeInfo,
7677
+ flushLogging,
7572
7678
  getAgent,
7573
7679
  getAgentEntry,
7574
7680
  getApp,