@faapi/faapi 0.0.0-canary.f08a14e → 1.0.0-canary.3a00f3e

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
@@ -235,7 +235,7 @@ async function compileDevRoutes(options) {
235
235
  const plugins = buildAliasPlugins(rootDir);
236
236
  const esbuild = await import("esbuild");
237
237
  const outbase = path3.resolve(rootDir, APP_DIR2);
238
- await esbuild.build({
238
+ const result = await esbuild.build({
239
239
  entryPoints,
240
240
  outdir: absDist,
241
241
  outbase,
@@ -245,8 +245,19 @@ async function compileDevRoutes(options) {
245
245
  sourcemap: true,
246
246
  packages: "external",
247
247
  plugins,
248
- logLevel
248
+ logLevel,
249
+ write: false
249
250
  });
251
+ if (result.outputFiles) {
252
+ await Promise.all(
253
+ result.outputFiles.map(async (file) => {
254
+ await fs3.promises.mkdir(path3.dirname(file.path), { recursive: true });
255
+ const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
256
+ await fs3.promises.writeFile(tmp, file.contents);
257
+ await fs3.promises.rename(tmp, file.path);
258
+ })
259
+ );
260
+ }
250
261
  return { compiledFiles: entryPoints };
251
262
  }
252
263
  var APP_DIR2;
@@ -258,35 +269,6 @@ var init_compileDevRoutes = __esm({
258
269
  }
259
270
  });
260
271
 
261
- // src/config/deepMerge.ts
262
- function deepMerge(base, override) {
263
- const result = { ...base };
264
- for (const key of Object.keys(override)) {
265
- const baseVal = base[key];
266
- const overVal = override[key];
267
- if (baseVal instanceof Date || overVal instanceof Date || baseVal instanceof RegExp || overVal instanceof RegExp || baseVal instanceof Map || overVal instanceof Map || baseVal instanceof Set || overVal instanceof Set) {
268
- result[key] = overVal;
269
- continue;
270
- }
271
- if (baseVal !== null && overVal !== null && typeof baseVal === "object" && typeof overVal === "object" && !Array.isArray(baseVal) && !Array.isArray(overVal) && !(baseVal instanceof Function) && !(overVal instanceof Function)) {
272
- result[key] = deepMerge(
273
- baseVal,
274
- overVal
275
- );
276
- } else {
277
- result[key] = overVal;
278
- }
279
- }
280
- return result;
281
- }
282
- var DEEP_MERGE_SOURCE;
283
- var init_deepMerge = __esm({
284
- "src/config/deepMerge.ts"() {
285
- "use strict";
286
- DEEP_MERGE_SOURCE = `const deepMerge = ${deepMerge.toString()};`;
287
- }
288
- });
289
-
290
272
  // src/cli/compileConfig.ts
291
273
  import path4 from "path";
292
274
  import fs4 from "fs";
@@ -301,9 +283,6 @@ function isInsideDir2(filePath, dir) {
301
283
  const rel = path4.relative(dir, filePath);
302
284
  return rel !== "" && !rel.startsWith("..") && !path4.isAbsolute(rel);
303
285
  }
304
- function getEnv() {
305
- return process.env.FAAPI_ENV || process.env.NODE_ENV || "development";
306
- }
307
286
  function findBaseConfig(rootDir) {
308
287
  for (const f of BASE_CONFIG_FILES) {
309
288
  if (fs4.existsSync(path4.join(rootDir, f))) {
@@ -312,15 +291,6 @@ function findBaseConfig(rootDir) {
312
291
  }
313
292
  return null;
314
293
  }
315
- function findEnvConfig(rootDir, env) {
316
- for (const ext of ENV_CONFIG_EXTS) {
317
- const f = `faapi.config.${env}${ext}`;
318
- if (fs4.existsSync(path4.join(rootDir, f))) {
319
- return f;
320
- }
321
- }
322
- return null;
323
- }
324
294
  function toProdExtension2(filePath) {
325
295
  if (filePath.endsWith(".ts")) return filePath.slice(0, -3) + ".js";
326
296
  if (filePath.endsWith(".tsx")) return filePath.slice(0, -4) + ".js";
@@ -394,14 +364,9 @@ async function compileConfig(options) {
394
364
  if (!baseConfigName) {
395
365
  return { generated: false, outputFile: "" };
396
366
  }
397
- const env = getEnv();
398
- const envConfigName = findEnvConfig(rootDir, env);
399
367
  const absDist = path4.resolve(rootDir, dist);
400
368
  await fs4.promises.mkdir(absDist, { recursive: true });
401
369
  const configEntryPoints = [path4.resolve(rootDir, baseConfigName)];
402
- if (envConfigName) {
403
- configEntryPoints.push(path4.resolve(rootDir, envConfigName));
404
- }
405
370
  const { appDirFiles, nonAppDirFiles } = await collectRelativeImports(configEntryPoints, rootDir);
406
371
  const esbuild = await import("esbuild");
407
372
  const aliasPlugins = buildAliasPlugins(rootDir);
@@ -434,16 +399,8 @@ async function compileConfig(options) {
434
399
  });
435
400
  }
436
401
  const baseImport = `import base from './${toProdImport(baseConfigName)}';`;
437
- const imports = [baseImport];
438
- let exportDefault;
439
- if (envConfigName) {
440
- const envImport = `import env from './${toProdImport(envConfigName)}';`;
441
- imports.push(envImport);
442
- exportDefault = "export default deepMerge(base, env);";
443
- } else {
444
- exportDefault = "export default base;";
445
- }
446
- const entryCode = [...imports, DEEP_MERGE_SOURCE, exportDefault].join("\n");
402
+ const exportDefault = "export default base;";
403
+ const entryCode = [baseImport, exportDefault].join("\n");
447
404
  const outputFile = path4.resolve(absDist, "faapi-config.js");
448
405
  await esbuild.build({
449
406
  stdin: { contents: entryCode, resolveDir: absDist, loader: "ts" },
@@ -459,14 +416,12 @@ async function compileConfig(options) {
459
416
  });
460
417
  return { generated: true, outputFile };
461
418
  }
462
- var BASE_CONFIG_FILES, ENV_CONFIG_EXTS, SPEC_RE;
419
+ var BASE_CONFIG_FILES, SPEC_RE;
463
420
  var init_compileConfig = __esm({
464
421
  "src/cli/compileConfig.ts"() {
465
422
  "use strict";
466
- init_deepMerge();
467
423
  init_aliasPlugin();
468
424
  BASE_CONFIG_FILES = ["faapi.config.ts", "faapi.config.js"];
469
- ENV_CONFIG_EXTS = [".ts", ".js"];
470
425
  SPEC_RE = /(\bfrom\s*|import\s*\(\s*)(['"])([^'"]+)\2/g;
471
426
  }
472
427
  });
@@ -1981,9 +1936,9 @@ var init_constants = __esm({
1981
1936
  });
1982
1937
 
1983
1938
  // src/utils/normalizePath.ts
1984
- function normalizePath(path17) {
1985
- if (!path17) return "";
1986
- let result = path17.replace(/\\/g, "/");
1939
+ function normalizePath(path18) {
1940
+ if (!path18) return "";
1941
+ let result = path18.replace(/\\/g, "/");
1987
1942
  result = result.replace(/\/+/g, "/");
1988
1943
  result = result.replace(/\/+$/, "");
1989
1944
  if (result && !result.startsWith("/")) {
@@ -2236,6 +2191,92 @@ var init_loadConfig = __esm({
2236
2191
  }
2237
2192
  });
2238
2193
 
2194
+ // src/cli/loadEnv.ts
2195
+ import fs9 from "fs";
2196
+ import path10 from "path";
2197
+ function resolveEnv() {
2198
+ return process.env.NODE_ENV || "development";
2199
+ }
2200
+ function getEnvFiles(env) {
2201
+ return [".env", ".env.local", `.env.${env}`, `.env.${env}.local`];
2202
+ }
2203
+ function parseEnvFile(content, fileVars) {
2204
+ const result = {};
2205
+ const lines = content.replace(/\r\n/g, "\n").split("\n");
2206
+ for (const line of lines) {
2207
+ const trimmed = line.trim();
2208
+ if (!trimmed || trimmed.startsWith("#")) continue;
2209
+ const match = /^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(trimmed);
2210
+ if (!match) continue;
2211
+ const [, key, rawValue] = match;
2212
+ const value = parseValue(rawValue, { ...fileVars, ...result });
2213
+ result[key] = value;
2214
+ }
2215
+ return result;
2216
+ }
2217
+ function parseValue(raw, env) {
2218
+ if (raw === "") return "";
2219
+ if (raw[0] === "'") {
2220
+ const end = raw.indexOf("'", 1);
2221
+ return end === -1 ? raw.slice(1) : raw.slice(1, end);
2222
+ }
2223
+ if (raw[0] === '"') {
2224
+ const match = /^"((?:\\.|[^"\\])*)"/.exec(raw);
2225
+ const inner = match ? match[1] : raw.slice(1);
2226
+ return expandEscapesAndVars(inner, env);
2227
+ }
2228
+ const commentMatch = /^(.*?)(\s+#.*)$/.exec(raw);
2229
+ const value = commentMatch ? commentMatch[1] : raw;
2230
+ return value.trim();
2231
+ }
2232
+ function expandEscapesAndVars(str, env) {
2233
+ const escaped = str.replace(/\\(.)/g, (_, ch) => {
2234
+ switch (ch) {
2235
+ case "n":
2236
+ return "\n";
2237
+ case "r":
2238
+ return "\r";
2239
+ case "t":
2240
+ return " ";
2241
+ case "\\":
2242
+ return "\\";
2243
+ case '"':
2244
+ return '"';
2245
+ default:
2246
+ return ch;
2247
+ }
2248
+ });
2249
+ return escaped.replace(
2250
+ /\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g,
2251
+ (_, braced, plain) => {
2252
+ const varName = braced || plain;
2253
+ return env[varName] ?? process.env[varName] ?? "";
2254
+ }
2255
+ );
2256
+ }
2257
+ function loadEnv(rootDir) {
2258
+ const env = resolveEnv();
2259
+ const files = getEnvFiles(env);
2260
+ const merged = {};
2261
+ for (const file of files) {
2262
+ const filePath = path10.join(rootDir, file);
2263
+ if (!fs9.existsSync(filePath)) continue;
2264
+ const content = fs9.readFileSync(filePath, "utf-8");
2265
+ const parsed = parseEnvFile(content, merged);
2266
+ Object.assign(merged, parsed);
2267
+ }
2268
+ for (const [key, value] of Object.entries(merged)) {
2269
+ if (process.env[key] === void 0) {
2270
+ process.env[key] = value;
2271
+ }
2272
+ }
2273
+ }
2274
+ var init_loadEnv = __esm({
2275
+ "src/cli/loadEnv.ts"() {
2276
+ "use strict";
2277
+ }
2278
+ });
2279
+
2239
2280
  // ../../node_modules/.pnpm/readdirp@4.1.2/node_modules/readdirp/esm/index.js
2240
2281
  import { stat, lstat, readdir, realpath } from "fs/promises";
2241
2282
  import { Readable } from "stream";
@@ -2326,7 +2367,7 @@ var init_esm = __esm({
2326
2367
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
2327
2368
  const statMethod = opts.lstat ? lstat : stat;
2328
2369
  if (wantBigintFsStats) {
2329
- this._stat = (path17) => statMethod(path17, { bigint: true });
2370
+ this._stat = (path18) => statMethod(path18, { bigint: true });
2330
2371
  } else {
2331
2372
  this._stat = statMethod;
2332
2373
  }
@@ -2351,8 +2392,8 @@ var init_esm = __esm({
2351
2392
  const par = this.parent;
2352
2393
  const fil = par && par.files;
2353
2394
  if (fil && fil.length > 0) {
2354
- const { path: path17, depth } = par;
2355
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path17));
2395
+ const { path: path18, depth } = par;
2396
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path18));
2356
2397
  const awaited = await Promise.all(slice);
2357
2398
  for (const entry of awaited) {
2358
2399
  if (!entry)
@@ -2392,20 +2433,20 @@ var init_esm = __esm({
2392
2433
  this.reading = false;
2393
2434
  }
2394
2435
  }
2395
- async _exploreDir(path17, depth) {
2436
+ async _exploreDir(path18, depth) {
2396
2437
  let files;
2397
2438
  try {
2398
- files = await readdir(path17, this._rdOptions);
2439
+ files = await readdir(path18, this._rdOptions);
2399
2440
  } catch (error) {
2400
2441
  this._onError(error);
2401
2442
  }
2402
- return { files, depth, path: path17 };
2443
+ return { files, depth, path: path18 };
2403
2444
  }
2404
- async _formatEntry(dirent, path17) {
2445
+ async _formatEntry(dirent, path18) {
2405
2446
  let entry;
2406
2447
  const basename3 = this._isDirent ? dirent.name : dirent;
2407
2448
  try {
2408
- const fullPath = presolve(pjoin(path17, basename3));
2449
+ const fullPath = presolve(pjoin(path18, basename3));
2409
2450
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
2410
2451
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
2411
2452
  } catch (err) {
@@ -2466,16 +2507,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
2466
2507
  import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
2467
2508
  import * as sysPath from "path";
2468
2509
  import { type as osType } from "os";
2469
- function createFsWatchInstance(path17, options, listener, errHandler, emitRaw) {
2510
+ function createFsWatchInstance(path18, options, listener, errHandler, emitRaw) {
2470
2511
  const handleEvent = (rawEvent, evPath) => {
2471
- listener(path17);
2472
- emitRaw(rawEvent, evPath, { watchedPath: path17 });
2473
- if (evPath && path17 !== evPath) {
2474
- fsWatchBroadcast(sysPath.resolve(path17, evPath), KEY_LISTENERS, sysPath.join(path17, evPath));
2512
+ listener(path18);
2513
+ emitRaw(rawEvent, evPath, { watchedPath: path18 });
2514
+ if (evPath && path18 !== evPath) {
2515
+ fsWatchBroadcast(sysPath.resolve(path18, evPath), KEY_LISTENERS, sysPath.join(path18, evPath));
2475
2516
  }
2476
2517
  };
2477
2518
  try {
2478
- return fs_watch(path17, {
2519
+ return fs_watch(path18, {
2479
2520
  persistent: options.persistent
2480
2521
  }, handleEvent);
2481
2522
  } catch (error) {
@@ -2820,12 +2861,12 @@ var init_handler = __esm({
2820
2861
  listener(val1, val2, val3);
2821
2862
  });
2822
2863
  };
2823
- setFsWatchListener = (path17, fullPath, options, handlers) => {
2864
+ setFsWatchListener = (path18, fullPath, options, handlers) => {
2824
2865
  const { listener, errHandler, rawEmitter } = handlers;
2825
2866
  let cont = FsWatchInstances.get(fullPath);
2826
2867
  let watcher;
2827
2868
  if (!options.persistent) {
2828
- watcher = createFsWatchInstance(path17, options, listener, errHandler, rawEmitter);
2869
+ watcher = createFsWatchInstance(path18, options, listener, errHandler, rawEmitter);
2829
2870
  if (!watcher)
2830
2871
  return;
2831
2872
  return watcher.close.bind(watcher);
@@ -2836,7 +2877,7 @@ var init_handler = __esm({
2836
2877
  addAndConvert(cont, KEY_RAW, rawEmitter);
2837
2878
  } else {
2838
2879
  watcher = createFsWatchInstance(
2839
- path17,
2880
+ path18,
2840
2881
  options,
2841
2882
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
2842
2883
  errHandler,
@@ -2851,7 +2892,7 @@ var init_handler = __esm({
2851
2892
  cont.watcherUnusable = true;
2852
2893
  if (isWindows && error.code === "EPERM") {
2853
2894
  try {
2854
- const fd = await open(path17, "r");
2895
+ const fd = await open(path18, "r");
2855
2896
  await fd.close();
2856
2897
  broadcastErr(error);
2857
2898
  } catch (err) {
@@ -2882,7 +2923,7 @@ var init_handler = __esm({
2882
2923
  };
2883
2924
  };
2884
2925
  FsWatchFileInstances = /* @__PURE__ */ new Map();
2885
- setFsWatchFileListener = (path17, fullPath, options, handlers) => {
2926
+ setFsWatchFileListener = (path18, fullPath, options, handlers) => {
2886
2927
  const { listener, rawEmitter } = handlers;
2887
2928
  let cont = FsWatchFileInstances.get(fullPath);
2888
2929
  const copts = cont && cont.options;
@@ -2904,7 +2945,7 @@ var init_handler = __esm({
2904
2945
  });
2905
2946
  const currmtime = curr.mtimeMs;
2906
2947
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
2907
- foreach(cont.listeners, (listener2) => listener2(path17, curr));
2948
+ foreach(cont.listeners, (listener2) => listener2(path18, curr));
2908
2949
  }
2909
2950
  })
2910
2951
  };
@@ -2932,13 +2973,13 @@ var init_handler = __esm({
2932
2973
  * @param listener on fs change
2933
2974
  * @returns closer for the watcher instance
2934
2975
  */
2935
- _watchWithNodeFs(path17, listener) {
2976
+ _watchWithNodeFs(path18, listener) {
2936
2977
  const opts = this.fsw.options;
2937
- const directory = sysPath.dirname(path17);
2938
- const basename3 = sysPath.basename(path17);
2978
+ const directory = sysPath.dirname(path18);
2979
+ const basename3 = sysPath.basename(path18);
2939
2980
  const parent = this.fsw._getWatchedDir(directory);
2940
2981
  parent.add(basename3);
2941
- const absolutePath = sysPath.resolve(path17);
2982
+ const absolutePath = sysPath.resolve(path18);
2942
2983
  const options = {
2943
2984
  persistent: opts.persistent
2944
2985
  };
@@ -2948,12 +2989,12 @@ var init_handler = __esm({
2948
2989
  if (opts.usePolling) {
2949
2990
  const enableBin = opts.interval !== opts.binaryInterval;
2950
2991
  options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
2951
- closer = setFsWatchFileListener(path17, absolutePath, options, {
2992
+ closer = setFsWatchFileListener(path18, absolutePath, options, {
2952
2993
  listener,
2953
2994
  rawEmitter: this.fsw._emitRaw
2954
2995
  });
2955
2996
  } else {
2956
- closer = setFsWatchListener(path17, absolutePath, options, {
2997
+ closer = setFsWatchListener(path18, absolutePath, options, {
2957
2998
  listener,
2958
2999
  errHandler: this._boundHandleError,
2959
3000
  rawEmitter: this.fsw._emitRaw
@@ -2975,7 +3016,7 @@ var init_handler = __esm({
2975
3016
  let prevStats = stats;
2976
3017
  if (parent.has(basename3))
2977
3018
  return;
2978
- const listener = async (path17, newStats) => {
3019
+ const listener = async (path18, newStats) => {
2979
3020
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
2980
3021
  return;
2981
3022
  if (!newStats || newStats.mtimeMs === 0) {
@@ -2989,11 +3030,11 @@ var init_handler = __esm({
2989
3030
  this.fsw._emit(EV.CHANGE, file, newStats2);
2990
3031
  }
2991
3032
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
2992
- this.fsw._closeFile(path17);
3033
+ this.fsw._closeFile(path18);
2993
3034
  prevStats = newStats2;
2994
3035
  const closer2 = this._watchWithNodeFs(file, listener);
2995
3036
  if (closer2)
2996
- this.fsw._addPathCloser(path17, closer2);
3037
+ this.fsw._addPathCloser(path18, closer2);
2997
3038
  } else {
2998
3039
  prevStats = newStats2;
2999
3040
  }
@@ -3025,7 +3066,7 @@ var init_handler = __esm({
3025
3066
  * @param item basename of this item
3026
3067
  * @returns true if no more processing is needed for this entry.
3027
3068
  */
3028
- async _handleSymlink(entry, directory, path17, item) {
3069
+ async _handleSymlink(entry, directory, path18, item) {
3029
3070
  if (this.fsw.closed) {
3030
3071
  return;
3031
3072
  }
@@ -3035,7 +3076,7 @@ var init_handler = __esm({
3035
3076
  this.fsw._incrReadyCount();
3036
3077
  let linkPath;
3037
3078
  try {
3038
- linkPath = await fsrealpath(path17);
3079
+ linkPath = await fsrealpath(path18);
3039
3080
  } catch (e) {
3040
3081
  this.fsw._emitReady();
3041
3082
  return true;
@@ -3045,12 +3086,12 @@ var init_handler = __esm({
3045
3086
  if (dir.has(item)) {
3046
3087
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
3047
3088
  this.fsw._symlinkPaths.set(full, linkPath);
3048
- this.fsw._emit(EV.CHANGE, path17, entry.stats);
3089
+ this.fsw._emit(EV.CHANGE, path18, entry.stats);
3049
3090
  }
3050
3091
  } else {
3051
3092
  dir.add(item);
3052
3093
  this.fsw._symlinkPaths.set(full, linkPath);
3053
- this.fsw._emit(EV.ADD, path17, entry.stats);
3094
+ this.fsw._emit(EV.ADD, path18, entry.stats);
3054
3095
  }
3055
3096
  this.fsw._emitReady();
3056
3097
  return true;
@@ -3079,9 +3120,9 @@ var init_handler = __esm({
3079
3120
  return;
3080
3121
  }
3081
3122
  const item = entry.path;
3082
- let path17 = sysPath.join(directory, item);
3123
+ let path18 = sysPath.join(directory, item);
3083
3124
  current.add(item);
3084
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path17, item)) {
3125
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path18, item)) {
3085
3126
  return;
3086
3127
  }
3087
3128
  if (this.fsw.closed) {
@@ -3090,8 +3131,8 @@ var init_handler = __esm({
3090
3131
  }
3091
3132
  if (item === target || !target && !previous.has(item)) {
3092
3133
  this.fsw._incrReadyCount();
3093
- path17 = sysPath.join(dir, sysPath.relative(dir, path17));
3094
- this._addToNodeFs(path17, initialAdd, wh, depth + 1);
3134
+ path18 = sysPath.join(dir, sysPath.relative(dir, path18));
3135
+ this._addToNodeFs(path18, initialAdd, wh, depth + 1);
3095
3136
  }
3096
3137
  }).on(EV.ERROR, this._boundHandleError);
3097
3138
  return new Promise((resolve3, reject) => {
@@ -3160,13 +3201,13 @@ var init_handler = __esm({
3160
3201
  * @param depth Child path actually targeted for watch
3161
3202
  * @param target Child path actually targeted for watch
3162
3203
  */
3163
- async _addToNodeFs(path17, initialAdd, priorWh, depth, target) {
3204
+ async _addToNodeFs(path18, initialAdd, priorWh, depth, target) {
3164
3205
  const ready = this.fsw._emitReady;
3165
- if (this.fsw._isIgnored(path17) || this.fsw.closed) {
3206
+ if (this.fsw._isIgnored(path18) || this.fsw.closed) {
3166
3207
  ready();
3167
3208
  return false;
3168
3209
  }
3169
- const wh = this.fsw._getWatchHelpers(path17);
3210
+ const wh = this.fsw._getWatchHelpers(path18);
3170
3211
  if (priorWh) {
3171
3212
  wh.filterPath = (entry) => priorWh.filterPath(entry);
3172
3213
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -3182,8 +3223,8 @@ var init_handler = __esm({
3182
3223
  const follow = this.fsw.options.followSymlinks;
3183
3224
  let closer;
3184
3225
  if (stats.isDirectory()) {
3185
- const absPath = sysPath.resolve(path17);
3186
- const targetPath = follow ? await fsrealpath(path17) : path17;
3226
+ const absPath = sysPath.resolve(path18);
3227
+ const targetPath = follow ? await fsrealpath(path18) : path18;
3187
3228
  if (this.fsw.closed)
3188
3229
  return;
3189
3230
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -3193,29 +3234,29 @@ var init_handler = __esm({
3193
3234
  this.fsw._symlinkPaths.set(absPath, targetPath);
3194
3235
  }
3195
3236
  } else if (stats.isSymbolicLink()) {
3196
- const targetPath = follow ? await fsrealpath(path17) : path17;
3237
+ const targetPath = follow ? await fsrealpath(path18) : path18;
3197
3238
  if (this.fsw.closed)
3198
3239
  return;
3199
3240
  const parent = sysPath.dirname(wh.watchPath);
3200
3241
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
3201
3242
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
3202
- closer = await this._handleDir(parent, stats, initialAdd, depth, path17, wh, targetPath);
3243
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path18, wh, targetPath);
3203
3244
  if (this.fsw.closed)
3204
3245
  return;
3205
3246
  if (targetPath !== void 0) {
3206
- this.fsw._symlinkPaths.set(sysPath.resolve(path17), targetPath);
3247
+ this.fsw._symlinkPaths.set(sysPath.resolve(path18), targetPath);
3207
3248
  }
3208
3249
  } else {
3209
3250
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
3210
3251
  }
3211
3252
  ready();
3212
3253
  if (closer)
3213
- this.fsw._addPathCloser(path17, closer);
3254
+ this.fsw._addPathCloser(path18, closer);
3214
3255
  return false;
3215
3256
  } catch (error) {
3216
3257
  if (this.fsw._handleError(error)) {
3217
3258
  ready();
3218
- return path17;
3259
+ return path18;
3219
3260
  }
3220
3261
  }
3221
3262
  }
@@ -3254,26 +3295,26 @@ function createPattern(matcher) {
3254
3295
  }
3255
3296
  return () => false;
3256
3297
  }
3257
- function normalizePath2(path17) {
3258
- if (typeof path17 !== "string")
3298
+ function normalizePath2(path18) {
3299
+ if (typeof path18 !== "string")
3259
3300
  throw new Error("string expected");
3260
- path17 = sysPath2.normalize(path17);
3261
- path17 = path17.replace(/\\/g, "/");
3301
+ path18 = sysPath2.normalize(path18);
3302
+ path18 = path18.replace(/\\/g, "/");
3262
3303
  let prepend = false;
3263
- if (path17.startsWith("//"))
3304
+ if (path18.startsWith("//"))
3264
3305
  prepend = true;
3265
3306
  const DOUBLE_SLASH_RE2 = /\/\//;
3266
- while (path17.match(DOUBLE_SLASH_RE2))
3267
- path17 = path17.replace(DOUBLE_SLASH_RE2, "/");
3307
+ while (path18.match(DOUBLE_SLASH_RE2))
3308
+ path18 = path18.replace(DOUBLE_SLASH_RE2, "/");
3268
3309
  if (prepend)
3269
- path17 = "/" + path17;
3270
- return path17;
3310
+ path18 = "/" + path18;
3311
+ return path18;
3271
3312
  }
3272
3313
  function matchPatterns(patterns, testString, stats) {
3273
- const path17 = normalizePath2(testString);
3314
+ const path18 = normalizePath2(testString);
3274
3315
  for (let index = 0; index < patterns.length; index++) {
3275
3316
  const pattern = patterns[index];
3276
- if (pattern(path17, stats)) {
3317
+ if (pattern(path18, stats)) {
3277
3318
  return true;
3278
3319
  }
3279
3320
  }
@@ -3334,19 +3375,19 @@ var init_esm2 = __esm({
3334
3375
  }
3335
3376
  return str;
3336
3377
  };
3337
- normalizePathToUnix = (path17) => toUnix(sysPath2.normalize(toUnix(path17)));
3338
- normalizeIgnored = (cwd = "") => (path17) => {
3339
- if (typeof path17 === "string") {
3340
- return normalizePathToUnix(sysPath2.isAbsolute(path17) ? path17 : sysPath2.join(cwd, path17));
3378
+ normalizePathToUnix = (path18) => toUnix(sysPath2.normalize(toUnix(path18)));
3379
+ normalizeIgnored = (cwd = "") => (path18) => {
3380
+ if (typeof path18 === "string") {
3381
+ return normalizePathToUnix(sysPath2.isAbsolute(path18) ? path18 : sysPath2.join(cwd, path18));
3341
3382
  } else {
3342
- return path17;
3383
+ return path18;
3343
3384
  }
3344
3385
  };
3345
- getAbsolutePath = (path17, cwd) => {
3346
- if (sysPath2.isAbsolute(path17)) {
3347
- return path17;
3386
+ getAbsolutePath = (path18, cwd) => {
3387
+ if (sysPath2.isAbsolute(path18)) {
3388
+ return path18;
3348
3389
  }
3349
- return sysPath2.join(cwd, path17);
3390
+ return sysPath2.join(cwd, path18);
3350
3391
  };
3351
3392
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
3352
3393
  DirEntry = class {
@@ -3401,10 +3442,10 @@ var init_esm2 = __esm({
3401
3442
  STAT_METHOD_F = "stat";
3402
3443
  STAT_METHOD_L = "lstat";
3403
3444
  WatchHelper = class {
3404
- constructor(path17, follow, fsw) {
3445
+ constructor(path18, follow, fsw) {
3405
3446
  this.fsw = fsw;
3406
- const watchPath = path17;
3407
- this.path = path17 = path17.replace(REPLACER_RE, "");
3447
+ const watchPath = path18;
3448
+ this.path = path18 = path18.replace(REPLACER_RE, "");
3408
3449
  this.watchPath = watchPath;
3409
3450
  this.fullWatchPath = sysPath2.resolve(watchPath);
3410
3451
  this.dirParts = [];
@@ -3526,20 +3567,20 @@ var init_esm2 = __esm({
3526
3567
  this._closePromise = void 0;
3527
3568
  let paths = unifyPaths(paths_);
3528
3569
  if (cwd) {
3529
- paths = paths.map((path17) => {
3530
- const absPath = getAbsolutePath(path17, cwd);
3570
+ paths = paths.map((path18) => {
3571
+ const absPath = getAbsolutePath(path18, cwd);
3531
3572
  return absPath;
3532
3573
  });
3533
3574
  }
3534
- paths.forEach((path17) => {
3535
- this._removeIgnoredPath(path17);
3575
+ paths.forEach((path18) => {
3576
+ this._removeIgnoredPath(path18);
3536
3577
  });
3537
3578
  this._userIgnored = void 0;
3538
3579
  if (!this._readyCount)
3539
3580
  this._readyCount = 0;
3540
3581
  this._readyCount += paths.length;
3541
- Promise.all(paths.map(async (path17) => {
3542
- const res = await this._nodeFsHandler._addToNodeFs(path17, !_internal, void 0, 0, _origAdd);
3582
+ Promise.all(paths.map(async (path18) => {
3583
+ const res = await this._nodeFsHandler._addToNodeFs(path18, !_internal, void 0, 0, _origAdd);
3543
3584
  if (res)
3544
3585
  this._emitReady();
3545
3586
  return res;
@@ -3561,17 +3602,17 @@ var init_esm2 = __esm({
3561
3602
  return this;
3562
3603
  const paths = unifyPaths(paths_);
3563
3604
  const { cwd } = this.options;
3564
- paths.forEach((path17) => {
3565
- if (!sysPath2.isAbsolute(path17) && !this._closers.has(path17)) {
3605
+ paths.forEach((path18) => {
3606
+ if (!sysPath2.isAbsolute(path18) && !this._closers.has(path18)) {
3566
3607
  if (cwd)
3567
- path17 = sysPath2.join(cwd, path17);
3568
- path17 = sysPath2.resolve(path17);
3608
+ path18 = sysPath2.join(cwd, path18);
3609
+ path18 = sysPath2.resolve(path18);
3569
3610
  }
3570
- this._closePath(path17);
3571
- this._addIgnoredPath(path17);
3572
- if (this._watched.has(path17)) {
3611
+ this._closePath(path18);
3612
+ this._addIgnoredPath(path18);
3613
+ if (this._watched.has(path18)) {
3573
3614
  this._addIgnoredPath({
3574
- path: path17,
3615
+ path: path18,
3575
3616
  recursive: true
3576
3617
  });
3577
3618
  }
@@ -3635,38 +3676,38 @@ var init_esm2 = __esm({
3635
3676
  * @param stats arguments to be passed with event
3636
3677
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
3637
3678
  */
3638
- async _emit(event, path17, stats) {
3679
+ async _emit(event, path18, stats) {
3639
3680
  if (this.closed)
3640
3681
  return;
3641
3682
  const opts = this.options;
3642
3683
  if (isWindows)
3643
- path17 = sysPath2.normalize(path17);
3684
+ path18 = sysPath2.normalize(path18);
3644
3685
  if (opts.cwd)
3645
- path17 = sysPath2.relative(opts.cwd, path17);
3646
- const args = [path17];
3686
+ path18 = sysPath2.relative(opts.cwd, path18);
3687
+ const args = [path18];
3647
3688
  if (stats != null)
3648
3689
  args.push(stats);
3649
3690
  const awf = opts.awaitWriteFinish;
3650
3691
  let pw;
3651
- if (awf && (pw = this._pendingWrites.get(path17))) {
3692
+ if (awf && (pw = this._pendingWrites.get(path18))) {
3652
3693
  pw.lastChange = /* @__PURE__ */ new Date();
3653
3694
  return this;
3654
3695
  }
3655
3696
  if (opts.atomic) {
3656
3697
  if (event === EVENTS.UNLINK) {
3657
- this._pendingUnlinks.set(path17, [event, ...args]);
3698
+ this._pendingUnlinks.set(path18, [event, ...args]);
3658
3699
  setTimeout(() => {
3659
- this._pendingUnlinks.forEach((entry, path18) => {
3700
+ this._pendingUnlinks.forEach((entry, path19) => {
3660
3701
  this.emit(...entry);
3661
3702
  this.emit(EVENTS.ALL, ...entry);
3662
- this._pendingUnlinks.delete(path18);
3703
+ this._pendingUnlinks.delete(path19);
3663
3704
  });
3664
3705
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
3665
3706
  return this;
3666
3707
  }
3667
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path17)) {
3708
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path18)) {
3668
3709
  event = EVENTS.CHANGE;
3669
- this._pendingUnlinks.delete(path17);
3710
+ this._pendingUnlinks.delete(path18);
3670
3711
  }
3671
3712
  }
3672
3713
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -3684,16 +3725,16 @@ var init_esm2 = __esm({
3684
3725
  this.emitWithAll(event, args);
3685
3726
  }
3686
3727
  };
3687
- this._awaitWriteFinish(path17, awf.stabilityThreshold, event, awfEmit);
3728
+ this._awaitWriteFinish(path18, awf.stabilityThreshold, event, awfEmit);
3688
3729
  return this;
3689
3730
  }
3690
3731
  if (event === EVENTS.CHANGE) {
3691
- const isThrottled = !this._throttle(EVENTS.CHANGE, path17, 50);
3732
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path18, 50);
3692
3733
  if (isThrottled)
3693
3734
  return this;
3694
3735
  }
3695
3736
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
3696
- const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path17) : path17;
3737
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path18) : path18;
3697
3738
  let stats2;
3698
3739
  try {
3699
3740
  stats2 = await stat3(fullPath);
@@ -3724,23 +3765,23 @@ var init_esm2 = __esm({
3724
3765
  * @param timeout duration of time to suppress duplicate actions
3725
3766
  * @returns tracking object or false if action should be suppressed
3726
3767
  */
3727
- _throttle(actionType, path17, timeout) {
3768
+ _throttle(actionType, path18, timeout) {
3728
3769
  if (!this._throttled.has(actionType)) {
3729
3770
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
3730
3771
  }
3731
3772
  const action = this._throttled.get(actionType);
3732
3773
  if (!action)
3733
3774
  throw new Error("invalid throttle");
3734
- const actionPath = action.get(path17);
3775
+ const actionPath = action.get(path18);
3735
3776
  if (actionPath) {
3736
3777
  actionPath.count++;
3737
3778
  return false;
3738
3779
  }
3739
3780
  let timeoutObject;
3740
3781
  const clear = () => {
3741
- const item = action.get(path17);
3782
+ const item = action.get(path18);
3742
3783
  const count = item ? item.count : 0;
3743
- action.delete(path17);
3784
+ action.delete(path18);
3744
3785
  clearTimeout(timeoutObject);
3745
3786
  if (item)
3746
3787
  clearTimeout(item.timeoutObject);
@@ -3748,7 +3789,7 @@ var init_esm2 = __esm({
3748
3789
  };
3749
3790
  timeoutObject = setTimeout(clear, timeout);
3750
3791
  const thr = { timeoutObject, clear, count: 0 };
3751
- action.set(path17, thr);
3792
+ action.set(path18, thr);
3752
3793
  return thr;
3753
3794
  }
3754
3795
  _incrReadyCount() {
@@ -3762,44 +3803,44 @@ var init_esm2 = __esm({
3762
3803
  * @param event
3763
3804
  * @param awfEmit Callback to be called when ready for event to be emitted.
3764
3805
  */
3765
- _awaitWriteFinish(path17, threshold, event, awfEmit) {
3806
+ _awaitWriteFinish(path18, threshold, event, awfEmit) {
3766
3807
  const awf = this.options.awaitWriteFinish;
3767
3808
  if (typeof awf !== "object")
3768
3809
  return;
3769
3810
  const pollInterval = awf.pollInterval;
3770
3811
  let timeoutHandler;
3771
- let fullPath = path17;
3772
- if (this.options.cwd && !sysPath2.isAbsolute(path17)) {
3773
- fullPath = sysPath2.join(this.options.cwd, path17);
3812
+ let fullPath = path18;
3813
+ if (this.options.cwd && !sysPath2.isAbsolute(path18)) {
3814
+ fullPath = sysPath2.join(this.options.cwd, path18);
3774
3815
  }
3775
3816
  const now = /* @__PURE__ */ new Date();
3776
3817
  const writes = this._pendingWrites;
3777
3818
  function awaitWriteFinishFn(prevStat) {
3778
3819
  statcb(fullPath, (err, curStat) => {
3779
- if (err || !writes.has(path17)) {
3820
+ if (err || !writes.has(path18)) {
3780
3821
  if (err && err.code !== "ENOENT")
3781
3822
  awfEmit(err);
3782
3823
  return;
3783
3824
  }
3784
3825
  const now2 = Number(/* @__PURE__ */ new Date());
3785
3826
  if (prevStat && curStat.size !== prevStat.size) {
3786
- writes.get(path17).lastChange = now2;
3827
+ writes.get(path18).lastChange = now2;
3787
3828
  }
3788
- const pw = writes.get(path17);
3829
+ const pw = writes.get(path18);
3789
3830
  const df = now2 - pw.lastChange;
3790
3831
  if (df >= threshold) {
3791
- writes.delete(path17);
3832
+ writes.delete(path18);
3792
3833
  awfEmit(void 0, curStat);
3793
3834
  } else {
3794
3835
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
3795
3836
  }
3796
3837
  });
3797
3838
  }
3798
- if (!writes.has(path17)) {
3799
- writes.set(path17, {
3839
+ if (!writes.has(path18)) {
3840
+ writes.set(path18, {
3800
3841
  lastChange: now,
3801
3842
  cancelWait: () => {
3802
- writes.delete(path17);
3843
+ writes.delete(path18);
3803
3844
  clearTimeout(timeoutHandler);
3804
3845
  return event;
3805
3846
  }
@@ -3810,8 +3851,8 @@ var init_esm2 = __esm({
3810
3851
  /**
3811
3852
  * Determines whether user has asked to ignore this path.
3812
3853
  */
3813
- _isIgnored(path17, stats) {
3814
- if (this.options.atomic && DOT_RE.test(path17))
3854
+ _isIgnored(path18, stats) {
3855
+ if (this.options.atomic && DOT_RE.test(path18))
3815
3856
  return true;
3816
3857
  if (!this._userIgnored) {
3817
3858
  const { cwd } = this.options;
@@ -3821,17 +3862,17 @@ var init_esm2 = __esm({
3821
3862
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
3822
3863
  this._userIgnored = anymatch(list, void 0);
3823
3864
  }
3824
- return this._userIgnored(path17, stats);
3865
+ return this._userIgnored(path18, stats);
3825
3866
  }
3826
- _isntIgnored(path17, stat4) {
3827
- return !this._isIgnored(path17, stat4);
3867
+ _isntIgnored(path18, stat4) {
3868
+ return !this._isIgnored(path18, stat4);
3828
3869
  }
3829
3870
  /**
3830
3871
  * Provides a set of common helpers and properties relating to symlink handling.
3831
3872
  * @param path file or directory pattern being watched
3832
3873
  */
3833
- _getWatchHelpers(path17) {
3834
- return new WatchHelper(path17, this.options.followSymlinks, this);
3874
+ _getWatchHelpers(path18) {
3875
+ return new WatchHelper(path18, this.options.followSymlinks, this);
3835
3876
  }
3836
3877
  // Directory helpers
3837
3878
  // -----------------
@@ -3863,63 +3904,63 @@ var init_esm2 = __esm({
3863
3904
  * @param item base path of item/directory
3864
3905
  */
3865
3906
  _remove(directory, item, isDirectory) {
3866
- const path17 = sysPath2.join(directory, item);
3867
- const fullPath = sysPath2.resolve(path17);
3868
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path17) || this._watched.has(fullPath);
3869
- if (!this._throttle("remove", path17, 100))
3907
+ const path18 = sysPath2.join(directory, item);
3908
+ const fullPath = sysPath2.resolve(path18);
3909
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path18) || this._watched.has(fullPath);
3910
+ if (!this._throttle("remove", path18, 100))
3870
3911
  return;
3871
3912
  if (!isDirectory && this._watched.size === 1) {
3872
3913
  this.add(directory, item, true);
3873
3914
  }
3874
- const wp = this._getWatchedDir(path17);
3915
+ const wp = this._getWatchedDir(path18);
3875
3916
  const nestedDirectoryChildren = wp.getChildren();
3876
- nestedDirectoryChildren.forEach((nested) => this._remove(path17, nested));
3917
+ nestedDirectoryChildren.forEach((nested) => this._remove(path18, nested));
3877
3918
  const parent = this._getWatchedDir(directory);
3878
3919
  const wasTracked = parent.has(item);
3879
3920
  parent.remove(item);
3880
3921
  if (this._symlinkPaths.has(fullPath)) {
3881
3922
  this._symlinkPaths.delete(fullPath);
3882
3923
  }
3883
- let relPath = path17;
3924
+ let relPath = path18;
3884
3925
  if (this.options.cwd)
3885
- relPath = sysPath2.relative(this.options.cwd, path17);
3926
+ relPath = sysPath2.relative(this.options.cwd, path18);
3886
3927
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
3887
3928
  const event = this._pendingWrites.get(relPath).cancelWait();
3888
3929
  if (event === EVENTS.ADD)
3889
3930
  return;
3890
3931
  }
3891
- this._watched.delete(path17);
3932
+ this._watched.delete(path18);
3892
3933
  this._watched.delete(fullPath);
3893
3934
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
3894
- if (wasTracked && !this._isIgnored(path17))
3895
- this._emit(eventName, path17);
3896
- this._closePath(path17);
3935
+ if (wasTracked && !this._isIgnored(path18))
3936
+ this._emit(eventName, path18);
3937
+ this._closePath(path18);
3897
3938
  }
3898
3939
  /**
3899
3940
  * Closes all watchers for a path
3900
3941
  */
3901
- _closePath(path17) {
3902
- this._closeFile(path17);
3903
- const dir = sysPath2.dirname(path17);
3904
- this._getWatchedDir(dir).remove(sysPath2.basename(path17));
3942
+ _closePath(path18) {
3943
+ this._closeFile(path18);
3944
+ const dir = sysPath2.dirname(path18);
3945
+ this._getWatchedDir(dir).remove(sysPath2.basename(path18));
3905
3946
  }
3906
3947
  /**
3907
3948
  * Closes only file-specific watchers
3908
3949
  */
3909
- _closeFile(path17) {
3910
- const closers = this._closers.get(path17);
3950
+ _closeFile(path18) {
3951
+ const closers = this._closers.get(path18);
3911
3952
  if (!closers)
3912
3953
  return;
3913
3954
  closers.forEach((closer) => closer());
3914
- this._closers.delete(path17);
3955
+ this._closers.delete(path18);
3915
3956
  }
3916
- _addPathCloser(path17, closer) {
3957
+ _addPathCloser(path18, closer) {
3917
3958
  if (!closer)
3918
3959
  return;
3919
- let list = this._closers.get(path17);
3960
+ let list = this._closers.get(path18);
3920
3961
  if (!list) {
3921
3962
  list = [];
3922
- this._closers.set(path17, list);
3963
+ this._closers.set(path18, list);
3923
3964
  }
3924
3965
  list.push(closer);
3925
3966
  }
@@ -3946,7 +3987,7 @@ var init_esm2 = __esm({
3946
3987
  });
3947
3988
 
3948
3989
  // src/cli/watcher.ts
3949
- import path10 from "path";
3990
+ import path11 from "path";
3950
3991
  function startWatcher(options) {
3951
3992
  const { rootDir, app, devDist } = options;
3952
3993
  let rebuildTimer = null;
@@ -3979,12 +4020,7 @@ function startWatcher(options) {
3979
4020
  void rebuildRoutes();
3980
4021
  }, 100);
3981
4022
  }
3982
- const CONFIG_FILES = [
3983
- "faapi.config.ts",
3984
- "faapi.config.js",
3985
- "faapi.config.production.ts",
3986
- "faapi.config.production.js"
3987
- ];
4023
+ const CONFIG_FILES = ["faapi.config.ts", "faapi.config.js"];
3988
4024
  const watchPaths = ["src", ...CONFIG_FILES];
3989
4025
  const watcher = esm_default.watch(watchPaths, {
3990
4026
  cwd: rootDir,
@@ -3999,11 +4035,11 @@ function startWatcher(options) {
3999
4035
  }
4000
4036
  });
4001
4037
  watcher.on("add", (file) => {
4002
- pendingFiles.add(path10.resolve(rootDir, file));
4038
+ pendingFiles.add(path11.resolve(rootDir, file));
4003
4039
  scheduleRebuild();
4004
4040
  });
4005
4041
  watcher.on("change", (file) => {
4006
- pendingFiles.add(path10.resolve(rootDir, file));
4042
+ pendingFiles.add(path11.resolve(rootDir, file));
4007
4043
  scheduleRebuild();
4008
4044
  });
4009
4045
  watcher.on("unlink", () => {
@@ -4060,42 +4096,42 @@ var init_detectRouteConflicts = __esm({
4060
4096
  });
4061
4097
 
4062
4098
  // src/router/matchRoute.ts
4063
- function matchRoute(routes, method, path17) {
4099
+ function matchRoute(routes, method, path18) {
4064
4100
  for (const route of routes) {
4065
4101
  if (route.method !== method) {
4066
4102
  continue;
4067
4103
  }
4068
4104
  if (!route.isDynamic) {
4069
- if (route.urlPath === path17) {
4105
+ if (route.urlPath === path18) {
4070
4106
  return { route, params: {} };
4071
4107
  }
4072
4108
  continue;
4073
4109
  }
4074
- const params = matchDynamicPath(route.urlPath, path17, route.paramNames, route.isCatchAll);
4110
+ const params = matchDynamicPath(route.urlPath, path18, route.paramNames, route.isCatchAll);
4075
4111
  if (params !== null) {
4076
4112
  return { route, params };
4077
4113
  }
4078
4114
  }
4079
4115
  return null;
4080
4116
  }
4081
- function matchWsRoute(wsRoutes, path17) {
4117
+ function matchWsRoute(wsRoutes, path18) {
4082
4118
  for (const route of wsRoutes) {
4083
4119
  if (!route.isDynamic) {
4084
- if (route.urlPath === path17) {
4120
+ if (route.urlPath === path18) {
4085
4121
  return { route, params: {} };
4086
4122
  }
4087
4123
  continue;
4088
4124
  }
4089
- const params = matchDynamicPath(route.urlPath, path17, route.paramNames, route.isCatchAll);
4125
+ const params = matchDynamicPath(route.urlPath, path18, route.paramNames, route.isCatchAll);
4090
4126
  if (params !== null) {
4091
4127
  return { route, params };
4092
4128
  }
4093
4129
  }
4094
4130
  return null;
4095
4131
  }
4096
- function matchDynamicPath(pattern, path17, paramNames, isCatchAll) {
4132
+ function matchDynamicPath(pattern, path18, paramNames, isCatchAll) {
4097
4133
  const patternSegments = pattern.split("/").filter(Boolean);
4098
- const pathSegments = path17.split("/").filter(Boolean);
4134
+ const pathSegments = path18.split("/").filter(Boolean);
4099
4135
  if (isCatchAll) {
4100
4136
  const nonCatchAllCount = patternSegments.length - 1;
4101
4137
  if (pathSegments.length <= nonCatchAllCount) {
@@ -4522,14 +4558,14 @@ var init_httpErrors = __esm({
4522
4558
  issues;
4523
4559
  };
4524
4560
  RouteNotFoundError = class extends FaapiError {
4525
- constructor(path17) {
4526
- super("ROUTE_NOT_FOUND", `Route not found: ${path17}`, 404);
4561
+ constructor(path18) {
4562
+ super("ROUTE_NOT_FOUND", `Route not found: ${path18}`, 404);
4527
4563
  this.name = "RouteNotFoundError";
4528
4564
  }
4529
4565
  };
4530
4566
  MethodNotAllowedError = class extends FaapiError {
4531
- constructor(method, path17, allowedMethods) {
4532
- super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path17}`, 405);
4567
+ constructor(method, path18, allowedMethods) {
4568
+ super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path18}`, 405);
4533
4569
  this.allowedMethods = allowedMethods;
4534
4570
  this.name = "MethodNotAllowedError";
4535
4571
  }
@@ -4931,9 +4967,9 @@ async function validateInput(schemaPath, method, inputType, input) {
4931
4967
  function mapZodIssues(error) {
4932
4968
  return error.issues.map((issue) => {
4933
4969
  const code = mapZodCode(issue.code, issue.message);
4934
- const path17 = issue.path.map(String).join(".") || "";
4970
+ const path18 = issue.path.map(String).join(".") || "";
4935
4971
  return {
4936
- path: path17,
4972
+ path: path18,
4937
4973
  code,
4938
4974
  expected: issue.expected ?? mapExpectedFromMessage(issue.message),
4939
4975
  received: issue.received ?? mapReceivedFromMessage(issue.message),
@@ -5292,7 +5328,7 @@ var init_wsHandler = __esm({
5292
5328
 
5293
5329
  // src/server/handleWsUpgrade.ts
5294
5330
  import { WebSocketServer, WebSocket } from "ws";
5295
- import path11 from "path";
5331
+ import path12 from "path";
5296
5332
  function getPathname(req) {
5297
5333
  const url = req.url ?? "/";
5298
5334
  const idx = url.indexOf("?");
@@ -5374,7 +5410,7 @@ function attachWebSocket(options) {
5374
5410
  const finalHandler = async () => {
5375
5411
  let handlers;
5376
5412
  try {
5377
- const absoluteFilePath = path11.resolve(rootDir, route.filePath);
5413
+ const absoluteFilePath = path12.resolve(rootDir, route.filePath);
5378
5414
  handlers = await loadWsHandler(absoluteFilePath, ctx);
5379
5415
  } catch (err) {
5380
5416
  const reason = err instanceof Error ? err.message : String(err);
@@ -5438,7 +5474,7 @@ import {
5438
5474
  import { createSecureServer as createHttp2SecureServer } from "http2";
5439
5475
  import { readFileSync } from "fs";
5440
5476
  import { Readable as Readable3 } from "stream";
5441
- import path12 from "path";
5477
+ import path13 from "path";
5442
5478
  function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT) {
5443
5479
  const forwardedProto = req.headers["x-forwarded-proto"];
5444
5480
  const protocol = Array.isArray(forwardedProto) ? forwardedProto[0]?.split(",")[0]?.trim() ?? "http" : forwardedProto?.split(",")[0]?.trim() ?? "http";
@@ -5482,15 +5518,15 @@ function limitStreamSize(stream, maxSize) {
5482
5518
  }
5483
5519
  });
5484
5520
  }
5485
- function findAllowedMethods(routes, path17) {
5521
+ function findAllowedMethods(routes, path18) {
5486
5522
  const methods = /* @__PURE__ */ new Set();
5487
5523
  for (const route of routes) {
5488
- if (route.urlPath === path17) {
5524
+ if (route.urlPath === path18) {
5489
5525
  methods.add(route.method);
5490
5526
  continue;
5491
5527
  }
5492
5528
  if (route.isDynamic) {
5493
- const params = matchDynamicPath(route.urlPath, path17, route.paramNames, route.isCatchAll);
5529
+ const params = matchDynamicPath(route.urlPath, path18, route.paramNames, route.isCatchAll);
5494
5530
  if (params !== null) {
5495
5531
  methods.add(route.method);
5496
5532
  }
@@ -5576,7 +5612,7 @@ async function handleRequest(routes, rootDir, dist, req, res, configMiddlewares,
5576
5612
  }
5577
5613
  ctx.params = match.params;
5578
5614
  const { route } = match;
5579
- const absoluteFilePath = path12.resolve(rootDir, route.filePath);
5615
+ const absoluteFilePath = path13.resolve(rootDir, route.filePath);
5580
5616
  const routeModule = await loadRouteModule(absoluteFilePath, route.method);
5581
5617
  const input = await resolveInput(route.method, request);
5582
5618
  const inputType = getInputTypeForMethod(route.method);
@@ -5742,8 +5778,8 @@ var init_loadPlugins = __esm({
5742
5778
  });
5743
5779
 
5744
5780
  // src/cli/createAppCore.ts
5745
- import fs9 from "fs";
5746
- import path13 from "path";
5781
+ import fs10 from "fs";
5782
+ import path14 from "path";
5747
5783
  import { PassThrough } from "stream";
5748
5784
  function isFaapiConfigKey(key) {
5749
5785
  return FAAPI_CONFIG_KEYS.has(key);
@@ -5751,8 +5787,8 @@ function isFaapiConfigKey(key) {
5751
5787
  async function createAppBase(options) {
5752
5788
  const rootDir = options?.rootDir ?? process.cwd();
5753
5789
  const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
5754
- const routesPath = path13.resolve(rootDir, dist, ROUTES_FILE);
5755
- if (!fs9.existsSync(routesPath)) {
5790
+ const routesPath = path14.resolve(rootDir, dist, ROUTES_FILE);
5791
+ if (!fs10.existsSync(routesPath)) {
5756
5792
  throw new Error(
5757
5793
  `[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
5758
5794
  );
@@ -6019,12 +6055,13 @@ __export(devCommand_exports, {
6019
6055
  devCommand: () => devCommand,
6020
6056
  generateRouteArtifacts: () => generateRouteArtifacts
6021
6057
  });
6022
- import path14 from "path";
6058
+ import path15 from "path";
6023
6059
  async function devCommand(options) {
6024
6060
  const rootDir = process.cwd();
6061
+ if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
6062
+ loadEnv(rootDir);
6025
6063
  const devDist = DEV_DIST;
6026
6064
  process.env.FAAPI_DIST = devDist;
6027
- if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
6028
6065
  console.log("- Development mode");
6029
6066
  console.log("- Compiling config...");
6030
6067
  await compileConfig({ rootDir, dist: devDist });
@@ -6041,7 +6078,7 @@ async function devCommand(options) {
6041
6078
  async function generateRouteArtifacts(rootDir, patterns, dist) {
6042
6079
  const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
6043
6080
  const sorted = sortRoutes(routes);
6044
- const routesPath = path14.resolve(rootDir, dist, ROUTES_FILE2);
6081
+ const routesPath = path15.resolve(rootDir, dist, ROUTES_FILE2);
6045
6082
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
6046
6083
  await writeRoutesModule(serialized, routesPath);
6047
6084
  await generateSchemaFiles(sorted, rootDir, dist);
@@ -6057,6 +6094,7 @@ var init_devCommand = __esm({
6057
6094
  init_scanRoutes();
6058
6095
  init_sortRoutes();
6059
6096
  init_loadConfig();
6097
+ init_loadEnv();
6060
6098
  init_watcher();
6061
6099
  init_createDevApp();
6062
6100
  DEV_DIST = ".faapi";
@@ -6066,8 +6104,8 @@ var init_devCommand = __esm({
6066
6104
  });
6067
6105
 
6068
6106
  // src/cli/compileBuildRoutes.ts
6069
- import path15 from "path";
6070
- import fs10 from "fs";
6107
+ import path16 from "path";
6108
+ import fs11 from "fs";
6071
6109
  import fg3 from "fast-glob";
6072
6110
  async function compileBuildRoutes(options) {
6073
6111
  const { rootDir, dist, files, logLevel = "silent" } = options;
@@ -6080,11 +6118,11 @@ async function compileBuildRoutes(options) {
6080
6118
  if (entryPoints.length === 0) {
6081
6119
  return { compiledFiles: [] };
6082
6120
  }
6083
- const absDist = path15.resolve(rootDir, dist);
6084
- await fs10.promises.mkdir(absDist, { recursive: true });
6121
+ const absDist = path16.resolve(rootDir, dist);
6122
+ await fs11.promises.mkdir(absDist, { recursive: true });
6085
6123
  const plugins = buildAliasPlugins(rootDir);
6086
6124
  const esbuild = await import("esbuild");
6087
- const outbase = path15.resolve(rootDir, APP_DIR4);
6125
+ const outbase = path16.resolve(rootDir, APP_DIR4);
6088
6126
  await esbuild.build({
6089
6127
  entryPoints,
6090
6128
  outdir: absDist,
@@ -6115,8 +6153,8 @@ var buildCommand_exports = {};
6115
6153
  __export(buildCommand_exports, {
6116
6154
  buildCommand: () => buildCommand
6117
6155
  });
6118
- import path16 from "path";
6119
- import fs11 from "fs";
6156
+ import path17 from "path";
6157
+ import fs12 from "fs";
6120
6158
  async function buildCommand(options) {
6121
6159
  const rootDir = options?.rootDir ?? process.cwd();
6122
6160
  const outdir = options?.dist ?? DEFAULT_DIST2;
@@ -6160,22 +6198,26 @@ async function buildCommand(options) {
6160
6198
  }
6161
6199
  console.log("\n[4/6] Generating schema...");
6162
6200
  await generateSchemaFiles(sorted, rootDir, outdir);
6163
- console.log(` Schema: zod.js files under ${path16.resolve(rootDir, outdir)}`);
6201
+ console.log(` Schema: zod.js files under ${path17.resolve(rootDir, outdir)}`);
6164
6202
  console.log("\n[5/6] Generating routes manifest...");
6165
- const routesPath = path16.resolve(rootDir, outdir, "faapi-routes.js");
6203
+ const routesPath = path17.resolve(rootDir, outdir, "faapi-routes.js");
6166
6204
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
6167
6205
  await writeRoutesModule(serialized, routesPath);
6168
6206
  console.log(` Written to ${routesPath}`);
6169
6207
  console.log("\n[6/6] Generating entry file...");
6170
- const mainPath = path16.resolve(rootDir, outdir, "main.js");
6208
+ const mainPath = path17.resolve(rootDir, outdir, "main.js");
6171
6209
  const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: '${outdir}' }` : "";
6172
6210
  const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
6173
- import { createProdApp } from '@faapi/faapi';
6211
+ import { createProdApp, loadEnv } from '@faapi/faapi';
6212
+
6213
+ // \u515C\u5E95 NODE_ENV\uFF08\u672A\u663E\u5F0F\u8BBE\u7F6E\u65F6\uFF09+ \u52A0\u8F7D .env \u7CFB\u5217\u6587\u4EF6\u5230 process.env
6214
+ if (!process.env.NODE_ENV) process.env.NODE_ENV = 'production';
6215
+ loadEnv(process.cwd());
6174
6216
 
6175
6217
  const app = await createProdApp(${createProdAppArgs});
6176
6218
  await app.listen();
6177
6219
  `;
6178
- await fs11.promises.writeFile(mainPath, mainContent, "utf-8");
6220
+ await fs12.promises.writeFile(mainPath, mainContent, "utf-8");
6179
6221
  console.log(` Written to ${mainPath}`);
6180
6222
  console.log("\nfaapi build completed");
6181
6223
  }