@faapi/faapi 6.22.0 → 6.23.0

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
@@ -649,9 +649,9 @@ var init_constants = __esm({
649
649
  });
650
650
 
651
651
  // src/utils/normalizePath.ts
652
- function normalizePath(path34) {
653
- if (!path34) return "";
654
- let result = path34.replace(/\\/g, "/");
652
+ function normalizePath(path35) {
653
+ if (!path35) return "";
654
+ let result = path35.replace(/\\/g, "/");
655
655
  result = result.replace(/\/+/g, "/");
656
656
  result = result.replace(/\/+$/, "");
657
657
  if (result && !result.startsWith("/")) {
@@ -3681,7 +3681,7 @@ async function compileSourceFiles(options) {
3681
3681
  cwd: rootDir,
3682
3682
  onlyFiles: true,
3683
3683
  absolute: true,
3684
- ignore: ["**/*.test.ts", "**/*.e2e.test.ts", "**/*.d.ts"]
3684
+ ignore: SOURCE_IGNORE
3685
3685
  });
3686
3686
  if (entryPoints.length === 0) {
3687
3687
  return { compiledFiles: [] };
@@ -3719,11 +3719,13 @@ async function compileSourceFiles(options) {
3719
3719
  }
3720
3720
  return { compiledFiles: entryPoints };
3721
3721
  }
3722
+ var SOURCE_IGNORE;
3722
3723
  var init_compileSourceFiles = __esm({
3723
3724
  "src/cli/compileSourceFiles.ts"() {
3724
3725
  "use strict";
3725
3726
  init_aliasPlugin();
3726
3727
  init_prodPaths();
3728
+ SOURCE_IGNORE = ["**/*.test.ts", "**/*.e2e.test.ts", "**/*.d.ts", `${APP_DIR}/resources/**`];
3727
3729
  }
3728
3730
  });
3729
3731
 
@@ -4132,7 +4134,7 @@ var init_esm = __esm({
4132
4134
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
4133
4135
  const statMethod = opts.lstat ? lstat : stat;
4134
4136
  if (wantBigintFsStats) {
4135
- this._stat = (path34) => statMethod(path34, { bigint: true });
4137
+ this._stat = (path35) => statMethod(path35, { bigint: true });
4136
4138
  } else {
4137
4139
  this._stat = statMethod;
4138
4140
  }
@@ -4157,8 +4159,8 @@ var init_esm = __esm({
4157
4159
  const par = this.parent;
4158
4160
  const fil = par && par.files;
4159
4161
  if (fil && fil.length > 0) {
4160
- const { path: path34, depth } = par;
4161
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path34));
4162
+ const { path: path35, depth } = par;
4163
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path35));
4162
4164
  const awaited = await Promise.all(slice);
4163
4165
  for (const entry of awaited) {
4164
4166
  if (!entry)
@@ -4198,20 +4200,20 @@ var init_esm = __esm({
4198
4200
  this.reading = false;
4199
4201
  }
4200
4202
  }
4201
- async _exploreDir(path34, depth) {
4203
+ async _exploreDir(path35, depth) {
4202
4204
  let files;
4203
4205
  try {
4204
- files = await readdir(path34, this._rdOptions);
4206
+ files = await readdir(path35, this._rdOptions);
4205
4207
  } catch (error) {
4206
4208
  this._onError(error);
4207
4209
  }
4208
- return { files, depth, path: path34 };
4210
+ return { files, depth, path: path35 };
4209
4211
  }
4210
- async _formatEntry(dirent, path34) {
4212
+ async _formatEntry(dirent, path35) {
4211
4213
  let entry;
4212
4214
  const basename3 = this._isDirent ? dirent.name : dirent;
4213
4215
  try {
4214
- const fullPath = presolve(pjoin(path34, basename3));
4216
+ const fullPath = presolve(pjoin(path35, basename3));
4215
4217
  entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
4216
4218
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
4217
4219
  } catch (err) {
@@ -4272,16 +4274,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
4272
4274
  import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
4273
4275
  import * as sysPath from "path";
4274
4276
  import { type as osType } from "os";
4275
- function createFsWatchInstance(path34, options, listener, errHandler, emitRaw) {
4277
+ function createFsWatchInstance(path35, options, listener, errHandler, emitRaw) {
4276
4278
  const handleEvent = (rawEvent, evPath) => {
4277
- listener(path34);
4278
- emitRaw(rawEvent, evPath, { watchedPath: path34 });
4279
- if (evPath && path34 !== evPath) {
4280
- fsWatchBroadcast(sysPath.resolve(path34, evPath), KEY_LISTENERS, sysPath.join(path34, evPath));
4279
+ listener(path35);
4280
+ emitRaw(rawEvent, evPath, { watchedPath: path35 });
4281
+ if (evPath && path35 !== evPath) {
4282
+ fsWatchBroadcast(sysPath.resolve(path35, evPath), KEY_LISTENERS, sysPath.join(path35, evPath));
4281
4283
  }
4282
4284
  };
4283
4285
  try {
4284
- return fs_watch(path34, {
4286
+ return fs_watch(path35, {
4285
4287
  persistent: options.persistent
4286
4288
  }, handleEvent);
4287
4289
  } catch (error) {
@@ -4626,12 +4628,12 @@ var init_handler = __esm({
4626
4628
  listener(val1, val2, val3);
4627
4629
  });
4628
4630
  };
4629
- setFsWatchListener = (path34, fullPath, options, handlers) => {
4631
+ setFsWatchListener = (path35, fullPath, options, handlers) => {
4630
4632
  const { listener, errHandler, rawEmitter } = handlers;
4631
4633
  let cont = FsWatchInstances.get(fullPath);
4632
4634
  let watcher;
4633
4635
  if (!options.persistent) {
4634
- watcher = createFsWatchInstance(path34, options, listener, errHandler, rawEmitter);
4636
+ watcher = createFsWatchInstance(path35, options, listener, errHandler, rawEmitter);
4635
4637
  if (!watcher)
4636
4638
  return;
4637
4639
  return watcher.close.bind(watcher);
@@ -4642,7 +4644,7 @@ var init_handler = __esm({
4642
4644
  addAndConvert(cont, KEY_RAW, rawEmitter);
4643
4645
  } else {
4644
4646
  watcher = createFsWatchInstance(
4645
- path34,
4647
+ path35,
4646
4648
  options,
4647
4649
  fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
4648
4650
  errHandler,
@@ -4657,7 +4659,7 @@ var init_handler = __esm({
4657
4659
  cont.watcherUnusable = true;
4658
4660
  if (isWindows && error.code === "EPERM") {
4659
4661
  try {
4660
- const fd = await open(path34, "r");
4662
+ const fd = await open(path35, "r");
4661
4663
  await fd.close();
4662
4664
  broadcastErr(error);
4663
4665
  } catch (err) {
@@ -4688,7 +4690,7 @@ var init_handler = __esm({
4688
4690
  };
4689
4691
  };
4690
4692
  FsWatchFileInstances = /* @__PURE__ */ new Map();
4691
- setFsWatchFileListener = (path34, fullPath, options, handlers) => {
4693
+ setFsWatchFileListener = (path35, fullPath, options, handlers) => {
4692
4694
  const { listener, rawEmitter } = handlers;
4693
4695
  let cont = FsWatchFileInstances.get(fullPath);
4694
4696
  const copts = cont && cont.options;
@@ -4710,7 +4712,7 @@ var init_handler = __esm({
4710
4712
  });
4711
4713
  const currmtime = curr.mtimeMs;
4712
4714
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
4713
- foreach(cont.listeners, (listener2) => listener2(path34, curr));
4715
+ foreach(cont.listeners, (listener2) => listener2(path35, curr));
4714
4716
  }
4715
4717
  })
4716
4718
  };
@@ -4738,13 +4740,13 @@ var init_handler = __esm({
4738
4740
  * @param listener on fs change
4739
4741
  * @returns closer for the watcher instance
4740
4742
  */
4741
- _watchWithNodeFs(path34, listener) {
4743
+ _watchWithNodeFs(path35, listener) {
4742
4744
  const opts = this.fsw.options;
4743
- const directory = sysPath.dirname(path34);
4744
- const basename3 = sysPath.basename(path34);
4745
+ const directory = sysPath.dirname(path35);
4746
+ const basename3 = sysPath.basename(path35);
4745
4747
  const parent = this.fsw._getWatchedDir(directory);
4746
4748
  parent.add(basename3);
4747
- const absolutePath = sysPath.resolve(path34);
4749
+ const absolutePath = sysPath.resolve(path35);
4748
4750
  const options = {
4749
4751
  persistent: opts.persistent
4750
4752
  };
@@ -4754,12 +4756,12 @@ var init_handler = __esm({
4754
4756
  if (opts.usePolling) {
4755
4757
  const enableBin = opts.interval !== opts.binaryInterval;
4756
4758
  options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
4757
- closer = setFsWatchFileListener(path34, absolutePath, options, {
4759
+ closer = setFsWatchFileListener(path35, absolutePath, options, {
4758
4760
  listener,
4759
4761
  rawEmitter: this.fsw._emitRaw
4760
4762
  });
4761
4763
  } else {
4762
- closer = setFsWatchListener(path34, absolutePath, options, {
4764
+ closer = setFsWatchListener(path35, absolutePath, options, {
4763
4765
  listener,
4764
4766
  errHandler: this._boundHandleError,
4765
4767
  rawEmitter: this.fsw._emitRaw
@@ -4781,7 +4783,7 @@ var init_handler = __esm({
4781
4783
  let prevStats = stats;
4782
4784
  if (parent.has(basename3))
4783
4785
  return;
4784
- const listener = async (path34, newStats) => {
4786
+ const listener = async (path35, newStats) => {
4785
4787
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
4786
4788
  return;
4787
4789
  if (!newStats || newStats.mtimeMs === 0) {
@@ -4795,11 +4797,11 @@ var init_handler = __esm({
4795
4797
  this.fsw._emit(EV.CHANGE, file, newStats2);
4796
4798
  }
4797
4799
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
4798
- this.fsw._closeFile(path34);
4800
+ this.fsw._closeFile(path35);
4799
4801
  prevStats = newStats2;
4800
4802
  const closer2 = this._watchWithNodeFs(file, listener);
4801
4803
  if (closer2)
4802
- this.fsw._addPathCloser(path34, closer2);
4804
+ this.fsw._addPathCloser(path35, closer2);
4803
4805
  } else {
4804
4806
  prevStats = newStats2;
4805
4807
  }
@@ -4831,7 +4833,7 @@ var init_handler = __esm({
4831
4833
  * @param item basename of this item
4832
4834
  * @returns true if no more processing is needed for this entry.
4833
4835
  */
4834
- async _handleSymlink(entry, directory, path34, item) {
4836
+ async _handleSymlink(entry, directory, path35, item) {
4835
4837
  if (this.fsw.closed) {
4836
4838
  return;
4837
4839
  }
@@ -4841,7 +4843,7 @@ var init_handler = __esm({
4841
4843
  this.fsw._incrReadyCount();
4842
4844
  let linkPath;
4843
4845
  try {
4844
- linkPath = await fsrealpath(path34);
4846
+ linkPath = await fsrealpath(path35);
4845
4847
  } catch (e) {
4846
4848
  this.fsw._emitReady();
4847
4849
  return true;
@@ -4851,12 +4853,12 @@ var init_handler = __esm({
4851
4853
  if (dir.has(item)) {
4852
4854
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
4853
4855
  this.fsw._symlinkPaths.set(full, linkPath);
4854
- this.fsw._emit(EV.CHANGE, path34, entry.stats);
4856
+ this.fsw._emit(EV.CHANGE, path35, entry.stats);
4855
4857
  }
4856
4858
  } else {
4857
4859
  dir.add(item);
4858
4860
  this.fsw._symlinkPaths.set(full, linkPath);
4859
- this.fsw._emit(EV.ADD, path34, entry.stats);
4861
+ this.fsw._emit(EV.ADD, path35, entry.stats);
4860
4862
  }
4861
4863
  this.fsw._emitReady();
4862
4864
  return true;
@@ -4885,9 +4887,9 @@ var init_handler = __esm({
4885
4887
  return;
4886
4888
  }
4887
4889
  const item = entry.path;
4888
- let path34 = sysPath.join(directory, item);
4890
+ let path35 = sysPath.join(directory, item);
4889
4891
  current.add(item);
4890
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path34, item)) {
4892
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path35, item)) {
4891
4893
  return;
4892
4894
  }
4893
4895
  if (this.fsw.closed) {
@@ -4896,8 +4898,8 @@ var init_handler = __esm({
4896
4898
  }
4897
4899
  if (item === target || !target && !previous.has(item)) {
4898
4900
  this.fsw._incrReadyCount();
4899
- path34 = sysPath.join(dir, sysPath.relative(dir, path34));
4900
- this._addToNodeFs(path34, initialAdd, wh, depth + 1);
4901
+ path35 = sysPath.join(dir, sysPath.relative(dir, path35));
4902
+ this._addToNodeFs(path35, initialAdd, wh, depth + 1);
4901
4903
  }
4902
4904
  }).on(EV.ERROR, this._boundHandleError);
4903
4905
  return new Promise((resolve3, reject) => {
@@ -4966,13 +4968,13 @@ var init_handler = __esm({
4966
4968
  * @param depth Child path actually targeted for watch
4967
4969
  * @param target Child path actually targeted for watch
4968
4970
  */
4969
- async _addToNodeFs(path34, initialAdd, priorWh, depth, target) {
4971
+ async _addToNodeFs(path35, initialAdd, priorWh, depth, target) {
4970
4972
  const ready = this.fsw._emitReady;
4971
- if (this.fsw._isIgnored(path34) || this.fsw.closed) {
4973
+ if (this.fsw._isIgnored(path35) || this.fsw.closed) {
4972
4974
  ready();
4973
4975
  return false;
4974
4976
  }
4975
- const wh = this.fsw._getWatchHelpers(path34);
4977
+ const wh = this.fsw._getWatchHelpers(path35);
4976
4978
  if (priorWh) {
4977
4979
  wh.filterPath = (entry) => priorWh.filterPath(entry);
4978
4980
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -4988,8 +4990,8 @@ var init_handler = __esm({
4988
4990
  const follow = this.fsw.options.followSymlinks;
4989
4991
  let closer;
4990
4992
  if (stats.isDirectory()) {
4991
- const absPath = sysPath.resolve(path34);
4992
- const targetPath = follow ? await fsrealpath(path34) : path34;
4993
+ const absPath = sysPath.resolve(path35);
4994
+ const targetPath = follow ? await fsrealpath(path35) : path35;
4993
4995
  if (this.fsw.closed)
4994
4996
  return;
4995
4997
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -4999,29 +5001,29 @@ var init_handler = __esm({
4999
5001
  this.fsw._symlinkPaths.set(absPath, targetPath);
5000
5002
  }
5001
5003
  } else if (stats.isSymbolicLink()) {
5002
- const targetPath = follow ? await fsrealpath(path34) : path34;
5004
+ const targetPath = follow ? await fsrealpath(path35) : path35;
5003
5005
  if (this.fsw.closed)
5004
5006
  return;
5005
5007
  const parent = sysPath.dirname(wh.watchPath);
5006
5008
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
5007
5009
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
5008
- closer = await this._handleDir(parent, stats, initialAdd, depth, path34, wh, targetPath);
5010
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path35, wh, targetPath);
5009
5011
  if (this.fsw.closed)
5010
5012
  return;
5011
5013
  if (targetPath !== void 0) {
5012
- this.fsw._symlinkPaths.set(sysPath.resolve(path34), targetPath);
5014
+ this.fsw._symlinkPaths.set(sysPath.resolve(path35), targetPath);
5013
5015
  }
5014
5016
  } else {
5015
5017
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
5016
5018
  }
5017
5019
  ready();
5018
5020
  if (closer)
5019
- this.fsw._addPathCloser(path34, closer);
5021
+ this.fsw._addPathCloser(path35, closer);
5020
5022
  return false;
5021
5023
  } catch (error) {
5022
5024
  if (this.fsw._handleError(error)) {
5023
5025
  ready();
5024
- return path34;
5026
+ return path35;
5025
5027
  }
5026
5028
  }
5027
5029
  }
@@ -5060,26 +5062,26 @@ function createPattern(matcher) {
5060
5062
  }
5061
5063
  return () => false;
5062
5064
  }
5063
- function normalizePath2(path34) {
5064
- if (typeof path34 !== "string")
5065
+ function normalizePath2(path35) {
5066
+ if (typeof path35 !== "string")
5065
5067
  throw new Error("string expected");
5066
- path34 = sysPath2.normalize(path34);
5067
- path34 = path34.replace(/\\/g, "/");
5068
+ path35 = sysPath2.normalize(path35);
5069
+ path35 = path35.replace(/\\/g, "/");
5068
5070
  let prepend = false;
5069
- if (path34.startsWith("//"))
5071
+ if (path35.startsWith("//"))
5070
5072
  prepend = true;
5071
5073
  const DOUBLE_SLASH_RE2 = /\/\//;
5072
- while (path34.match(DOUBLE_SLASH_RE2))
5073
- path34 = path34.replace(DOUBLE_SLASH_RE2, "/");
5074
+ while (path35.match(DOUBLE_SLASH_RE2))
5075
+ path35 = path35.replace(DOUBLE_SLASH_RE2, "/");
5074
5076
  if (prepend)
5075
- path34 = "/" + path34;
5076
- return path34;
5077
+ path35 = "/" + path35;
5078
+ return path35;
5077
5079
  }
5078
5080
  function matchPatterns(patterns, testString, stats) {
5079
- const path34 = normalizePath2(testString);
5081
+ const path35 = normalizePath2(testString);
5080
5082
  for (let index = 0; index < patterns.length; index++) {
5081
5083
  const pattern = patterns[index];
5082
- if (pattern(path34, stats)) {
5084
+ if (pattern(path35, stats)) {
5083
5085
  return true;
5084
5086
  }
5085
5087
  }
@@ -5140,19 +5142,19 @@ var init_esm2 = __esm({
5140
5142
  }
5141
5143
  return str;
5142
5144
  };
5143
- normalizePathToUnix = (path34) => toUnix(sysPath2.normalize(toUnix(path34)));
5144
- normalizeIgnored = (cwd = "") => (path34) => {
5145
- if (typeof path34 === "string") {
5146
- return normalizePathToUnix(sysPath2.isAbsolute(path34) ? path34 : sysPath2.join(cwd, path34));
5145
+ normalizePathToUnix = (path35) => toUnix(sysPath2.normalize(toUnix(path35)));
5146
+ normalizeIgnored = (cwd = "") => (path35) => {
5147
+ if (typeof path35 === "string") {
5148
+ return normalizePathToUnix(sysPath2.isAbsolute(path35) ? path35 : sysPath2.join(cwd, path35));
5147
5149
  } else {
5148
- return path34;
5150
+ return path35;
5149
5151
  }
5150
5152
  };
5151
- getAbsolutePath = (path34, cwd) => {
5152
- if (sysPath2.isAbsolute(path34)) {
5153
- return path34;
5153
+ getAbsolutePath = (path35, cwd) => {
5154
+ if (sysPath2.isAbsolute(path35)) {
5155
+ return path35;
5154
5156
  }
5155
- return sysPath2.join(cwd, path34);
5157
+ return sysPath2.join(cwd, path35);
5156
5158
  };
5157
5159
  EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
5158
5160
  DirEntry = class {
@@ -5207,10 +5209,10 @@ var init_esm2 = __esm({
5207
5209
  STAT_METHOD_F = "stat";
5208
5210
  STAT_METHOD_L = "lstat";
5209
5211
  WatchHelper = class {
5210
- constructor(path34, follow, fsw) {
5212
+ constructor(path35, follow, fsw) {
5211
5213
  this.fsw = fsw;
5212
- const watchPath = path34;
5213
- this.path = path34 = path34.replace(REPLACER_RE, "");
5214
+ const watchPath = path35;
5215
+ this.path = path35 = path35.replace(REPLACER_RE, "");
5214
5216
  this.watchPath = watchPath;
5215
5217
  this.fullWatchPath = sysPath2.resolve(watchPath);
5216
5218
  this.dirParts = [];
@@ -5332,20 +5334,20 @@ var init_esm2 = __esm({
5332
5334
  this._closePromise = void 0;
5333
5335
  let paths = unifyPaths(paths_);
5334
5336
  if (cwd) {
5335
- paths = paths.map((path34) => {
5336
- const absPath = getAbsolutePath(path34, cwd);
5337
+ paths = paths.map((path35) => {
5338
+ const absPath = getAbsolutePath(path35, cwd);
5337
5339
  return absPath;
5338
5340
  });
5339
5341
  }
5340
- paths.forEach((path34) => {
5341
- this._removeIgnoredPath(path34);
5342
+ paths.forEach((path35) => {
5343
+ this._removeIgnoredPath(path35);
5342
5344
  });
5343
5345
  this._userIgnored = void 0;
5344
5346
  if (!this._readyCount)
5345
5347
  this._readyCount = 0;
5346
5348
  this._readyCount += paths.length;
5347
- Promise.all(paths.map(async (path34) => {
5348
- const res = await this._nodeFsHandler._addToNodeFs(path34, !_internal, void 0, 0, _origAdd);
5349
+ Promise.all(paths.map(async (path35) => {
5350
+ const res = await this._nodeFsHandler._addToNodeFs(path35, !_internal, void 0, 0, _origAdd);
5349
5351
  if (res)
5350
5352
  this._emitReady();
5351
5353
  return res;
@@ -5367,17 +5369,17 @@ var init_esm2 = __esm({
5367
5369
  return this;
5368
5370
  const paths = unifyPaths(paths_);
5369
5371
  const { cwd } = this.options;
5370
- paths.forEach((path34) => {
5371
- if (!sysPath2.isAbsolute(path34) && !this._closers.has(path34)) {
5372
+ paths.forEach((path35) => {
5373
+ if (!sysPath2.isAbsolute(path35) && !this._closers.has(path35)) {
5372
5374
  if (cwd)
5373
- path34 = sysPath2.join(cwd, path34);
5374
- path34 = sysPath2.resolve(path34);
5375
+ path35 = sysPath2.join(cwd, path35);
5376
+ path35 = sysPath2.resolve(path35);
5375
5377
  }
5376
- this._closePath(path34);
5377
- this._addIgnoredPath(path34);
5378
- if (this._watched.has(path34)) {
5378
+ this._closePath(path35);
5379
+ this._addIgnoredPath(path35);
5380
+ if (this._watched.has(path35)) {
5379
5381
  this._addIgnoredPath({
5380
- path: path34,
5382
+ path: path35,
5381
5383
  recursive: true
5382
5384
  });
5383
5385
  }
@@ -5441,38 +5443,38 @@ var init_esm2 = __esm({
5441
5443
  * @param stats arguments to be passed with event
5442
5444
  * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
5443
5445
  */
5444
- async _emit(event, path34, stats) {
5446
+ async _emit(event, path35, stats) {
5445
5447
  if (this.closed)
5446
5448
  return;
5447
5449
  const opts = this.options;
5448
5450
  if (isWindows)
5449
- path34 = sysPath2.normalize(path34);
5451
+ path35 = sysPath2.normalize(path35);
5450
5452
  if (opts.cwd)
5451
- path34 = sysPath2.relative(opts.cwd, path34);
5452
- const args = [path34];
5453
+ path35 = sysPath2.relative(opts.cwd, path35);
5454
+ const args = [path35];
5453
5455
  if (stats != null)
5454
5456
  args.push(stats);
5455
5457
  const awf = opts.awaitWriteFinish;
5456
5458
  let pw;
5457
- if (awf && (pw = this._pendingWrites.get(path34))) {
5459
+ if (awf && (pw = this._pendingWrites.get(path35))) {
5458
5460
  pw.lastChange = /* @__PURE__ */ new Date();
5459
5461
  return this;
5460
5462
  }
5461
5463
  if (opts.atomic) {
5462
5464
  if (event === EVENTS.UNLINK) {
5463
- this._pendingUnlinks.set(path34, [event, ...args]);
5465
+ this._pendingUnlinks.set(path35, [event, ...args]);
5464
5466
  setTimeout(() => {
5465
- this._pendingUnlinks.forEach((entry, path35) => {
5467
+ this._pendingUnlinks.forEach((entry, path36) => {
5466
5468
  this.emit(...entry);
5467
5469
  this.emit(EVENTS.ALL, ...entry);
5468
- this._pendingUnlinks.delete(path35);
5470
+ this._pendingUnlinks.delete(path36);
5469
5471
  });
5470
5472
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
5471
5473
  return this;
5472
5474
  }
5473
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path34)) {
5475
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path35)) {
5474
5476
  event = EVENTS.CHANGE;
5475
- this._pendingUnlinks.delete(path34);
5477
+ this._pendingUnlinks.delete(path35);
5476
5478
  }
5477
5479
  }
5478
5480
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -5490,16 +5492,16 @@ var init_esm2 = __esm({
5490
5492
  this.emitWithAll(event, args);
5491
5493
  }
5492
5494
  };
5493
- this._awaitWriteFinish(path34, awf.stabilityThreshold, event, awfEmit);
5495
+ this._awaitWriteFinish(path35, awf.stabilityThreshold, event, awfEmit);
5494
5496
  return this;
5495
5497
  }
5496
5498
  if (event === EVENTS.CHANGE) {
5497
- const isThrottled = !this._throttle(EVENTS.CHANGE, path34, 50);
5499
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path35, 50);
5498
5500
  if (isThrottled)
5499
5501
  return this;
5500
5502
  }
5501
5503
  if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
5502
- const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path34) : path34;
5504
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path35) : path35;
5503
5505
  let stats2;
5504
5506
  try {
5505
5507
  stats2 = await stat3(fullPath);
@@ -5530,23 +5532,23 @@ var init_esm2 = __esm({
5530
5532
  * @param timeout duration of time to suppress duplicate actions
5531
5533
  * @returns tracking object or false if action should be suppressed
5532
5534
  */
5533
- _throttle(actionType, path34, timeout) {
5535
+ _throttle(actionType, path35, timeout) {
5534
5536
  if (!this._throttled.has(actionType)) {
5535
5537
  this._throttled.set(actionType, /* @__PURE__ */ new Map());
5536
5538
  }
5537
5539
  const action = this._throttled.get(actionType);
5538
5540
  if (!action)
5539
5541
  throw new Error("invalid throttle");
5540
- const actionPath = action.get(path34);
5542
+ const actionPath = action.get(path35);
5541
5543
  if (actionPath) {
5542
5544
  actionPath.count++;
5543
5545
  return false;
5544
5546
  }
5545
5547
  let timeoutObject;
5546
5548
  const clear = () => {
5547
- const item = action.get(path34);
5549
+ const item = action.get(path35);
5548
5550
  const count = item ? item.count : 0;
5549
- action.delete(path34);
5551
+ action.delete(path35);
5550
5552
  clearTimeout(timeoutObject);
5551
5553
  if (item)
5552
5554
  clearTimeout(item.timeoutObject);
@@ -5554,7 +5556,7 @@ var init_esm2 = __esm({
5554
5556
  };
5555
5557
  timeoutObject = setTimeout(clear, timeout);
5556
5558
  const thr = { timeoutObject, clear, count: 0 };
5557
- action.set(path34, thr);
5559
+ action.set(path35, thr);
5558
5560
  return thr;
5559
5561
  }
5560
5562
  _incrReadyCount() {
@@ -5568,44 +5570,44 @@ var init_esm2 = __esm({
5568
5570
  * @param event
5569
5571
  * @param awfEmit Callback to be called when ready for event to be emitted.
5570
5572
  */
5571
- _awaitWriteFinish(path34, threshold, event, awfEmit) {
5573
+ _awaitWriteFinish(path35, threshold, event, awfEmit) {
5572
5574
  const awf = this.options.awaitWriteFinish;
5573
5575
  if (typeof awf !== "object")
5574
5576
  return;
5575
5577
  const pollInterval = awf.pollInterval;
5576
5578
  let timeoutHandler;
5577
- let fullPath = path34;
5578
- if (this.options.cwd && !sysPath2.isAbsolute(path34)) {
5579
- fullPath = sysPath2.join(this.options.cwd, path34);
5579
+ let fullPath = path35;
5580
+ if (this.options.cwd && !sysPath2.isAbsolute(path35)) {
5581
+ fullPath = sysPath2.join(this.options.cwd, path35);
5580
5582
  }
5581
5583
  const now = /* @__PURE__ */ new Date();
5582
5584
  const writes = this._pendingWrites;
5583
5585
  function awaitWriteFinishFn(prevStat) {
5584
5586
  statcb(fullPath, (err, curStat) => {
5585
- if (err || !writes.has(path34)) {
5587
+ if (err || !writes.has(path35)) {
5586
5588
  if (err && err.code !== "ENOENT")
5587
5589
  awfEmit(err);
5588
5590
  return;
5589
5591
  }
5590
5592
  const now2 = Number(/* @__PURE__ */ new Date());
5591
5593
  if (prevStat && curStat.size !== prevStat.size) {
5592
- writes.get(path34).lastChange = now2;
5594
+ writes.get(path35).lastChange = now2;
5593
5595
  }
5594
- const pw = writes.get(path34);
5596
+ const pw = writes.get(path35);
5595
5597
  const df = now2 - pw.lastChange;
5596
5598
  if (df >= threshold) {
5597
- writes.delete(path34);
5599
+ writes.delete(path35);
5598
5600
  awfEmit(void 0, curStat);
5599
5601
  } else {
5600
5602
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
5601
5603
  }
5602
5604
  });
5603
5605
  }
5604
- if (!writes.has(path34)) {
5605
- writes.set(path34, {
5606
+ if (!writes.has(path35)) {
5607
+ writes.set(path35, {
5606
5608
  lastChange: now,
5607
5609
  cancelWait: () => {
5608
- writes.delete(path34);
5610
+ writes.delete(path35);
5609
5611
  clearTimeout(timeoutHandler);
5610
5612
  return event;
5611
5613
  }
@@ -5616,8 +5618,8 @@ var init_esm2 = __esm({
5616
5618
  /**
5617
5619
  * Determines whether user has asked to ignore this path.
5618
5620
  */
5619
- _isIgnored(path34, stats) {
5620
- if (this.options.atomic && DOT_RE.test(path34))
5621
+ _isIgnored(path35, stats) {
5622
+ if (this.options.atomic && DOT_RE.test(path35))
5621
5623
  return true;
5622
5624
  if (!this._userIgnored) {
5623
5625
  const { cwd } = this.options;
@@ -5627,17 +5629,17 @@ var init_esm2 = __esm({
5627
5629
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
5628
5630
  this._userIgnored = anymatch(list, void 0);
5629
5631
  }
5630
- return this._userIgnored(path34, stats);
5632
+ return this._userIgnored(path35, stats);
5631
5633
  }
5632
- _isntIgnored(path34, stat4) {
5633
- return !this._isIgnored(path34, stat4);
5634
+ _isntIgnored(path35, stat4) {
5635
+ return !this._isIgnored(path35, stat4);
5634
5636
  }
5635
5637
  /**
5636
5638
  * Provides a set of common helpers and properties relating to symlink handling.
5637
5639
  * @param path file or directory pattern being watched
5638
5640
  */
5639
- _getWatchHelpers(path34) {
5640
- return new WatchHelper(path34, this.options.followSymlinks, this);
5641
+ _getWatchHelpers(path35) {
5642
+ return new WatchHelper(path35, this.options.followSymlinks, this);
5641
5643
  }
5642
5644
  // Directory helpers
5643
5645
  // -----------------
@@ -5669,63 +5671,63 @@ var init_esm2 = __esm({
5669
5671
  * @param item base path of item/directory
5670
5672
  */
5671
5673
  _remove(directory, item, isDirectory) {
5672
- const path34 = sysPath2.join(directory, item);
5673
- const fullPath = sysPath2.resolve(path34);
5674
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path34) || this._watched.has(fullPath);
5675
- if (!this._throttle("remove", path34, 100))
5674
+ const path35 = sysPath2.join(directory, item);
5675
+ const fullPath = sysPath2.resolve(path35);
5676
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path35) || this._watched.has(fullPath);
5677
+ if (!this._throttle("remove", path35, 100))
5676
5678
  return;
5677
5679
  if (!isDirectory && this._watched.size === 1) {
5678
5680
  this.add(directory, item, true);
5679
5681
  }
5680
- const wp = this._getWatchedDir(path34);
5682
+ const wp = this._getWatchedDir(path35);
5681
5683
  const nestedDirectoryChildren = wp.getChildren();
5682
- nestedDirectoryChildren.forEach((nested) => this._remove(path34, nested));
5684
+ nestedDirectoryChildren.forEach((nested) => this._remove(path35, nested));
5683
5685
  const parent = this._getWatchedDir(directory);
5684
5686
  const wasTracked = parent.has(item);
5685
5687
  parent.remove(item);
5686
5688
  if (this._symlinkPaths.has(fullPath)) {
5687
5689
  this._symlinkPaths.delete(fullPath);
5688
5690
  }
5689
- let relPath = path34;
5691
+ let relPath = path35;
5690
5692
  if (this.options.cwd)
5691
- relPath = sysPath2.relative(this.options.cwd, path34);
5693
+ relPath = sysPath2.relative(this.options.cwd, path35);
5692
5694
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
5693
5695
  const event = this._pendingWrites.get(relPath).cancelWait();
5694
5696
  if (event === EVENTS.ADD)
5695
5697
  return;
5696
5698
  }
5697
- this._watched.delete(path34);
5699
+ this._watched.delete(path35);
5698
5700
  this._watched.delete(fullPath);
5699
5701
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
5700
- if (wasTracked && !this._isIgnored(path34))
5701
- this._emit(eventName, path34);
5702
- this._closePath(path34);
5702
+ if (wasTracked && !this._isIgnored(path35))
5703
+ this._emit(eventName, path35);
5704
+ this._closePath(path35);
5703
5705
  }
5704
5706
  /**
5705
5707
  * Closes all watchers for a path
5706
5708
  */
5707
- _closePath(path34) {
5708
- this._closeFile(path34);
5709
- const dir = sysPath2.dirname(path34);
5710
- this._getWatchedDir(dir).remove(sysPath2.basename(path34));
5709
+ _closePath(path35) {
5710
+ this._closeFile(path35);
5711
+ const dir = sysPath2.dirname(path35);
5712
+ this._getWatchedDir(dir).remove(sysPath2.basename(path35));
5711
5713
  }
5712
5714
  /**
5713
5715
  * Closes only file-specific watchers
5714
5716
  */
5715
- _closeFile(path34) {
5716
- const closers = this._closers.get(path34);
5717
+ _closeFile(path35) {
5718
+ const closers = this._closers.get(path35);
5717
5719
  if (!closers)
5718
5720
  return;
5719
5721
  closers.forEach((closer) => closer());
5720
- this._closers.delete(path34);
5722
+ this._closers.delete(path35);
5721
5723
  }
5722
- _addPathCloser(path34, closer) {
5724
+ _addPathCloser(path35, closer) {
5723
5725
  if (!closer)
5724
5726
  return;
5725
- let list = this._closers.get(path34);
5727
+ let list = this._closers.get(path35);
5726
5728
  if (!list) {
5727
5729
  list = [];
5728
- this._closers.set(path34, list);
5730
+ this._closers.set(path35, list);
5729
5731
  }
5730
5732
  list.push(closer);
5731
5733
  }
@@ -5816,8 +5818,55 @@ var init_rebuildScheduler = __esm({
5816
5818
  }
5817
5819
  });
5818
5820
 
5819
- // src/cli/watcher.ts
5821
+ // src/cli/copyResources.ts
5820
5822
  import path23 from "path";
5823
+ import fs18 from "fs";
5824
+ function isResourceSourcePath(rootDir, absPath) {
5825
+ return isInsideDir(absPath, path23.resolve(rootDir, RESOURCES_DIR));
5826
+ }
5827
+ function resolveResourcesDir(rootDir, dist) {
5828
+ return path23.resolve(rootDir, dist, RESOURCES_OUTPUT_DIR);
5829
+ }
5830
+ async function copyResources(rootDir, dist) {
5831
+ const sourceDir = path23.resolve(rootDir, RESOURCES_DIR);
5832
+ if (!fs18.existsSync(sourceDir)) return false;
5833
+ const outDir = resolveResourcesDir(rootDir, dist);
5834
+ await fs18.promises.rm(outDir, { recursive: true, force: true });
5835
+ await fs18.promises.cp(sourceDir, outDir, { recursive: true });
5836
+ return true;
5837
+ }
5838
+ async function copyResourceFile(rootDir, dist, absSourceFile) {
5839
+ const sourceDir = path23.resolve(rootDir, RESOURCES_DIR);
5840
+ if (!isInsideDir(absSourceFile, sourceDir)) {
5841
+ throw new Error(`[faapi] copyResourceFile: ${absSourceFile} is not under ${RESOURCES_DIR}`);
5842
+ }
5843
+ if (!fs18.existsSync(absSourceFile)) return;
5844
+ const rel = path23.relative(sourceDir, absSourceFile);
5845
+ const dest = path23.join(resolveResourcesDir(rootDir, dist), rel);
5846
+ await fs18.promises.mkdir(path23.dirname(dest), { recursive: true });
5847
+ await fs18.promises.cp(absSourceFile, dest);
5848
+ }
5849
+ async function removeResourceFile(rootDir, dist, absSourceFile) {
5850
+ const sourceDir = path23.resolve(rootDir, RESOURCES_DIR);
5851
+ if (!isInsideDir(absSourceFile, sourceDir)) {
5852
+ throw new Error(`[faapi] removeResourceFile: ${absSourceFile} is not under ${RESOURCES_DIR}`);
5853
+ }
5854
+ const rel = path23.relative(sourceDir, absSourceFile);
5855
+ const dest = path23.join(resolveResourcesDir(rootDir, dist), rel);
5856
+ await fs18.promises.rm(dest, { force: true });
5857
+ }
5858
+ var RESOURCES_DIR, RESOURCES_OUTPUT_DIR;
5859
+ var init_copyResources = __esm({
5860
+ "src/cli/copyResources.ts"() {
5861
+ "use strict";
5862
+ init_prodPaths();
5863
+ RESOURCES_DIR = "src/resources";
5864
+ RESOURCES_OUTPUT_DIR = "resources";
5865
+ }
5866
+ });
5867
+
5868
+ // src/cli/watcher.ts
5869
+ import path24 from "path";
5821
5870
  import { existsSync as existsSync2 } from "fs";
5822
5871
  function startWatcher(options) {
5823
5872
  const { rootDir, app, devDist } = options;
@@ -5852,9 +5901,9 @@ function startWatcher(options) {
5852
5901
  }
5853
5902
  });
5854
5903
  const CONFIG_FILES = ["faapi.config.ts", "faapi.config.js"];
5855
- const configAbsPaths = new Set(CONFIG_FILES.map((f) => path23.resolve(rootDir, f)));
5904
+ const configAbsPaths = new Set(CONFIG_FILES.map((f) => path24.resolve(rootDir, f)));
5856
5905
  const watchPaths = ["src", "tsconfig.json", ...CONFIG_FILES];
5857
- const scheduleOnly = /* @__PURE__ */ new Set([...configAbsPaths, path23.resolve(rootDir, "tsconfig.json")]);
5906
+ const scheduleOnly = /* @__PURE__ */ new Set([...configAbsPaths, path24.resolve(rootDir, "tsconfig.json")]);
5858
5907
  const watcher = esm_default.watch(watchPaths, {
5859
5908
  cwd: rootDir,
5860
5909
  ignoreInitial: true,
@@ -5865,13 +5914,23 @@ function startWatcher(options) {
5865
5914
  }
5866
5915
  if (!stats) return false;
5867
5916
  if (stats.isDirectory()) return false;
5917
+ if (isResourceSourcePath(rootDir, path24.resolve(rootDir, filePath))) return false;
5868
5918
  return !filePath.endsWith(".ts") && !filePath.endsWith(".js");
5869
5919
  }
5870
5920
  });
5871
5921
  watcher.on("add", (file) => handleFileEvent(file));
5872
5922
  watcher.on("change", (file) => handleFileEvent(file));
5873
5923
  function handleFileEvent(file) {
5874
- const abs = path23.resolve(rootDir, file);
5924
+ const abs = path24.resolve(rootDir, file);
5925
+ if (isResourceSourcePath(rootDir, abs)) {
5926
+ void copyResourceFile(rootDir, devDist, abs).catch((err) => {
5927
+ console.error(
5928
+ "- Error copying resource:",
5929
+ err instanceof Error ? err.message : String(err)
5930
+ );
5931
+ });
5932
+ return;
5933
+ }
5875
5934
  if (scheduleOnly.has(abs)) {
5876
5935
  scheduler.schedule();
5877
5936
  return;
@@ -5882,7 +5941,17 @@ function startWatcher(options) {
5882
5941
  scheduler.addFiles([abs]);
5883
5942
  }
5884
5943
  watcher.on("unlink", (file) => {
5885
- scheduler.removeFiles([path23.resolve(rootDir, file)]);
5944
+ const abs = path24.resolve(rootDir, file);
5945
+ if (isResourceSourcePath(rootDir, abs)) {
5946
+ void removeResourceFile(rootDir, devDist, abs).catch((err) => {
5947
+ console.error(
5948
+ "- Error removing resource:",
5949
+ err instanceof Error ? err.message : String(err)
5950
+ );
5951
+ });
5952
+ return;
5953
+ }
5954
+ scheduler.removeFiles([abs]);
5886
5955
  scheduler.schedule();
5887
5956
  });
5888
5957
  watcher.on("error", (err) => {
@@ -5903,6 +5972,7 @@ var init_watcher = __esm({
5903
5972
  init_compileDevRoutes();
5904
5973
  init_compileConfig();
5905
5974
  init_rebuildScheduler();
5975
+ init_copyResources();
5906
5976
  }
5907
5977
  });
5908
5978
 
@@ -5986,25 +6056,25 @@ function getWsIndex(routes) {
5986
6056
  wsIndexCache.set(routes, index);
5987
6057
  return index;
5988
6058
  }
5989
- function matchRoute(routes, method, path34) {
6059
+ function matchRoute(routes, method, path35) {
5990
6060
  const index = getHttpIndex(routes);
5991
6061
  const upper = method.toUpperCase();
5992
- const hit = matchByMethod(index, upper, path34);
6062
+ const hit = matchByMethod(index, upper, path35);
5993
6063
  if (hit) return hit;
5994
6064
  if (upper === "HEAD") {
5995
- return matchByMethod(index, "GET", path34);
6065
+ return matchByMethod(index, "GET", path35);
5996
6066
  }
5997
6067
  return null;
5998
6068
  }
5999
- function matchByMethod(index, method, path34) {
6000
- const staticHit = index.static.get(`${method}|${path34}`);
6069
+ function matchByMethod(index, method, path35) {
6070
+ const staticHit = index.static.get(`${method}|${path35}`);
6001
6071
  if (staticHit) {
6002
6072
  return { route: staticHit, params: {} };
6003
6073
  }
6004
6074
  if (index.dynamics.length === 0) {
6005
6075
  return null;
6006
6076
  }
6007
- const pathSegments = path34.split("/").filter(Boolean);
6077
+ const pathSegments = path35.split("/").filter(Boolean);
6008
6078
  for (const entry of index.dynamics) {
6009
6079
  const route = entry.route;
6010
6080
  if (route.method !== method) {
@@ -6017,31 +6087,31 @@ function matchByMethod(index, method, path34) {
6017
6087
  }
6018
6088
  return null;
6019
6089
  }
6020
- function matchWsRoute(wsRoutes, path34) {
6090
+ function matchWsRoute(wsRoutes, path35) {
6021
6091
  const index = getWsIndex(wsRoutes);
6022
- const staticHit = index.static.get(path34);
6092
+ const staticHit = index.static.get(path35);
6023
6093
  if (staticHit) {
6024
6094
  return { route: staticHit, params: {} };
6025
6095
  }
6026
6096
  for (const route of index.dynamics) {
6027
- const params = matchDynamicPath(route.urlPath, path34, route.paramNames, route.isCatchAll);
6097
+ const params = matchDynamicPath(route.urlPath, path35, route.paramNames, route.isCatchAll);
6028
6098
  if (params !== null) {
6029
6099
  return { route, params };
6030
6100
  }
6031
6101
  }
6032
6102
  return null;
6033
6103
  }
6034
- function findAllowedMethods(routes, path34) {
6104
+ function findAllowedMethods(routes, path35) {
6035
6105
  const index = getHttpIndex(routes);
6036
6106
  const methods = /* @__PURE__ */ new Set();
6037
- const staticMethods = index.methodsByStaticPath.get(path34);
6107
+ const staticMethods = index.methodsByStaticPath.get(path35);
6038
6108
  if (staticMethods) {
6039
6109
  for (const method of staticMethods) {
6040
6110
  methods.add(method);
6041
6111
  }
6042
6112
  }
6043
6113
  if (index.dynamics.length > 0) {
6044
- const pathSegments = path34.split("/").filter(Boolean);
6114
+ const pathSegments = path35.split("/").filter(Boolean);
6045
6115
  for (const entry of index.dynamics) {
6046
6116
  const params = matchSegments(
6047
6117
  entry.segments,
@@ -6059,10 +6129,10 @@ function findAllowedMethods(routes, path34) {
6059
6129
  }
6060
6130
  return Array.from(methods);
6061
6131
  }
6062
- function matchDynamicPath(pattern, path34, paramNames, isCatchAll) {
6132
+ function matchDynamicPath(pattern, path35, paramNames, isCatchAll) {
6063
6133
  return matchSegments(
6064
6134
  pattern.split("/").filter(Boolean),
6065
- path34.split("/").filter(Boolean),
6135
+ path35.split("/").filter(Boolean),
6066
6136
  paramNames,
6067
6137
  isCatchAll
6068
6138
  );
@@ -6541,14 +6611,14 @@ var init_httpErrors = __esm({
6541
6611
  issues;
6542
6612
  };
6543
6613
  RouteNotFoundError = class extends FaapiError {
6544
- constructor(path34) {
6545
- super("ROUTE_NOT_FOUND", `Route not found: ${path34}`, 404);
6614
+ constructor(path35) {
6615
+ super("ROUTE_NOT_FOUND", `Route not found: ${path35}`, 404);
6546
6616
  this.name = "RouteNotFoundError";
6547
6617
  }
6548
6618
  };
6549
6619
  MethodNotAllowedError = class extends FaapiError {
6550
- constructor(method, path34, allowedMethods) {
6551
- super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path34}`, 405);
6620
+ constructor(method, path35, allowedMethods) {
6621
+ super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path35}`, 405);
6552
6622
  this.allowedMethods = allowedMethods;
6553
6623
  this.name = "MethodNotAllowedError";
6554
6624
  }
@@ -6684,17 +6754,17 @@ var init_formatEntry = __esm({
6684
6754
  });
6685
6755
 
6686
6756
  // src/logger/fileSink.ts
6687
- import fs18 from "fs";
6688
- import path24 from "path";
6757
+ import fs19 from "fs";
6758
+ import path25 from "path";
6689
6759
  function createFileLogSink(options) {
6690
- fs18.mkdirSync(options.dir, { recursive: true });
6760
+ fs19.mkdirSync(options.dir, { recursive: true });
6691
6761
  const streams = /* @__PURE__ */ new Map();
6692
6762
  const getStream = (name) => {
6693
6763
  if (streams.has(name)) return streams.get(name);
6694
6764
  return void 0;
6695
6765
  };
6696
6766
  const openStream = (name) => {
6697
- const stream = fs18.createWriteStream(path24.join(options.dir, `${name}.log`), { flags: "a" });
6767
+ const stream = fs19.createWriteStream(path25.join(options.dir, `${name}.log`), { flags: "a" });
6698
6768
  stream.on("error", () => {
6699
6769
  });
6700
6770
  streams.set(name, stream);
@@ -6962,10 +7032,18 @@ function formatSetCookie(name, value, options) {
6962
7032
  if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
6963
7033
  return cookie;
6964
7034
  }
6965
- function createContext(request, params, config = {}, ip = "", registries) {
6966
- return createContextFromUrl(request, new URL(request.url), params, config, ip, registries);
7035
+ function createContext(request, params, config = {}, ip = "", registries, resourcesDir) {
7036
+ return createContextFromUrl(
7037
+ request,
7038
+ new URL(request.url),
7039
+ params,
7040
+ config,
7041
+ ip,
7042
+ registries,
7043
+ resourcesDir
7044
+ );
6967
7045
  }
6968
- function createContextFromUrl(request, url, params, config = {}, ip = "", registries) {
7046
+ function createContextFromUrl(request, url, params, config = {}, ip = "", registries, resourcesDir) {
6969
7047
  const meta = { headers: {}, setCookies: [] };
6970
7048
  const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
6971
7049
  const cookiesObj = {};
@@ -6993,6 +7071,9 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
6993
7071
  ua: request.headers.get("user-agent") ?? "",
6994
7072
  cookies: cookiesObj,
6995
7073
  config,
7074
+ // 运行时资源根目录(HTTP/WS 链路由 createServer/handleWsUpgrade 传入;
7075
+ // testing 直调未传时为 undefined,见 contextTypes.resourcesDir 注释)
7076
+ resourcesDir,
6996
7077
  meta,
6997
7078
  setStatus(status) {
6998
7079
  meta.status = status;
@@ -7891,9 +7972,9 @@ async function validateInput(schemaPath, method, inputType, input) {
7891
7972
  function mapZodIssues(error) {
7892
7973
  return error.issues.map((issue) => {
7893
7974
  const code = mapZodCode(issue);
7894
- const path34 = issue.path.map(String).join(".") || "";
7975
+ const path35 = issue.path.map(String).join(".") || "";
7895
7976
  return {
7896
- path: path34,
7977
+ path: path35,
7897
7978
  code,
7898
7979
  expected: issue.expected ?? mapExpectedFromMessage(issue.message),
7899
7980
  received: issue.received ?? mapReceivedFromMessage(issue.message),
@@ -8417,9 +8498,9 @@ var init_wsHandler = __esm({
8417
8498
  });
8418
8499
 
8419
8500
  // src/server/handleWsUpgrade.ts
8420
- import fs19 from "fs";
8501
+ import fs20 from "fs";
8421
8502
  import { WebSocketServer, WebSocket } from "ws";
8422
- import path25 from "path";
8503
+ import path26 from "path";
8423
8504
  function getPathname(req) {
8424
8505
  const url = req.url ?? "/";
8425
8506
  const idx = url.indexOf("?");
@@ -8430,7 +8511,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
8430
8511
  const dist = getDevDist();
8431
8512
  if (dist) {
8432
8513
  const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
8433
- if (sourcePath && fs19.existsSync(sourcePath)) {
8514
+ if (sourcePath && fs20.existsSync(sourcePath)) {
8434
8515
  await ensureCompiled(sourcePath, rootDir, dist);
8435
8516
  }
8436
8517
  }
@@ -8528,6 +8609,7 @@ function attachWebSocket(options) {
8528
8609
  trustedProxy = false,
8529
8610
  registries
8530
8611
  } = options;
8612
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
8531
8613
  const wss = new WebSocketServer({ noServer: true });
8532
8614
  server.on("upgrade", async (req, socket, head) => {
8533
8615
  try {
@@ -8559,12 +8641,19 @@ function attachWebSocket(options) {
8559
8641
  const host = req.headers.host ?? "localhost";
8560
8642
  const fullUrl = new URL(`http://${host}${req.url ?? "/"}`);
8561
8643
  const request = new Request(fullUrl.toString(), { method: "GET", headers });
8562
- const ctx = createContext(request, params, config, getClientIp(req, trustedProxy), registries);
8644
+ const ctx = createContext(
8645
+ request,
8646
+ params,
8647
+ config,
8648
+ getClientIp(req, trustedProxy),
8649
+ registries,
8650
+ resourcesDir
8651
+ );
8563
8652
  const meta = ctx.meta;
8564
8653
  let upgraded = false;
8565
8654
  const finalHandler = async () => {
8566
8655
  const schemaPath = getRuntimeSchemaPath(route.filePath, dist, rootDir);
8567
- if (fs19.existsSync(schemaPath)) {
8656
+ if (fs20.existsSync(schemaPath)) {
8568
8657
  if (isDevOnDemandEnabled()) {
8569
8658
  const devDist = getDevDist();
8570
8659
  if (devDist) {
@@ -8603,7 +8692,7 @@ function attachWebSocket(options) {
8603
8692
  }
8604
8693
  let handlers;
8605
8694
  try {
8606
- const absoluteFilePath = path25.resolve(rootDir, route.filePath);
8695
+ const absoluteFilePath = path26.resolve(rootDir, route.filePath);
8607
8696
  handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
8608
8697
  } catch (err) {
8609
8698
  const reason = err instanceof Error ? err.message : String(err);
@@ -8661,6 +8750,7 @@ var init_handleWsUpgrade = __esm({
8661
8750
  "use strict";
8662
8751
  init_matchRoute();
8663
8752
  init_createContext();
8753
+ init_copyResources();
8664
8754
  init_invokeHandler();
8665
8755
  init_importWithCacheBust();
8666
8756
  init_getClientIp();
@@ -8683,7 +8773,7 @@ import {
8683
8773
  import { createSecureServer as createHttp2SecureServer } from "http2";
8684
8774
  import { readFileSync } from "fs";
8685
8775
  import { Readable as Readable3 } from "stream";
8686
- import path26 from "path";
8776
+ import path27 from "path";
8687
8777
  function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT, requestSignal) {
8688
8778
  const forwardedProto = req.headers["x-forwarded-proto"];
8689
8779
  const protocol = Array.isArray(forwardedProto) ? forwardedProto[0]?.split(",")[0]?.trim() ?? "http" : forwardedProto?.split(",")[0]?.trim() ?? "http";
@@ -8787,6 +8877,7 @@ function createServer(options) {
8787
8877
  trustedProxy = false
8788
8878
  } = options;
8789
8879
  const routesRef = { current: routes, wsCurrent: wsRoutes ?? [] };
8880
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
8790
8881
  const configMiddlewares = [];
8791
8882
  if (compressionOption) {
8792
8883
  const compOpts = typeof compressionOption === "object" ? compressionOption : {};
@@ -8833,7 +8924,8 @@ function createServer(options) {
8833
8924
  bodyLimit,
8834
8925
  trustedProxy,
8835
8926
  registries,
8836
- routesRef.wsCurrent
8927
+ routesRef.wsCurrent,
8928
+ resourcesDir
8837
8929
  ).catch((err) => {
8838
8930
  console.error("[faapi] Request pipeline failed after error response attempt:", err);
8839
8931
  try {
@@ -8859,7 +8951,7 @@ function createServer(options) {
8859
8951
  });
8860
8952
  return { server, routesRef };
8861
8953
  }
8862
- function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched) {
8954
+ function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched, resourcesDir) {
8863
8955
  const method = request.method.toUpperCase();
8864
8956
  const urlPath = url.pathname;
8865
8957
  const ctx = createContextFromUrl(
@@ -8868,7 +8960,8 @@ function prepareRequest(req, request, url, config, trustedProxy, registries, pre
8868
8960
  preMatched?.params ?? {},
8869
8961
  config,
8870
8962
  getClientIp(req, trustedProxy),
8871
- registries
8963
+ registries,
8964
+ resourcesDir
8872
8965
  );
8873
8966
  const meta = ctx.meta;
8874
8967
  return { request, url, ctx, meta, method, urlPath };
@@ -8886,7 +8979,7 @@ function getRoutePaths(route, rootDir, dist) {
8886
8979
  let cached = routePathCache.get(route);
8887
8980
  if (!cached) {
8888
8981
  cached = {
8889
- absFilePath: path26.resolve(rootDir, route.filePath),
8982
+ absFilePath: path27.resolve(rootDir, route.filePath),
8890
8983
  schemaPath: getRuntimeSchemaPath(route.filePath, dist, rootDir)
8891
8984
  };
8892
8985
  routePathCache.set(route, cached);
@@ -9008,7 +9101,7 @@ async function sendErrorResponse(err, meta, res, onError, ctx) {
9008
9101
  }
9009
9102
  }
9010
9103
  }
9011
- async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes) {
9104
+ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes, resourcesDir) {
9012
9105
  let meta = { headers: {}, setCookies: [] };
9013
9106
  let ctx;
9014
9107
  let sseEarlySent = false;
@@ -9028,7 +9121,8 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
9028
9121
  config,
9029
9122
  trustedProxy,
9030
9123
  registries,
9031
- preMatched
9124
+ preMatched,
9125
+ resourcesDir
9032
9126
  );
9033
9127
  ctx = prepared.ctx;
9034
9128
  meta = prepared.meta;
@@ -9097,6 +9191,7 @@ var init_createServer = __esm({
9097
9191
  init_handleWsUpgrade();
9098
9192
  init_serverUtils();
9099
9193
  init_generateSchemaFiles();
9194
+ init_copyResources();
9100
9195
  init_compileOnDemand();
9101
9196
  init_loadMiddlewares();
9102
9197
  DEFAULT_BODY_LIMIT = 10 * 1024 * 1024;
@@ -9443,7 +9538,7 @@ function createTaskLogger(level, scope, fields) {
9443
9538
  });
9444
9539
 
9445
9540
  // src/task/taskQueue.ts
9446
- import path27 from "path";
9541
+ import path28 from "path";
9447
9542
  function createTaskQueue(deps) {
9448
9543
  const { registry, rootDir, driver } = deps;
9449
9544
  const registriesView = deps.registries ?? createEmptyTaskRegistriesView();
@@ -9473,7 +9568,7 @@ function createTaskQueue(deps) {
9473
9568
  }
9474
9569
  const loadTaskModule = deps.loadTaskModule ?? (async (filePath) => await import(filePath));
9475
9570
  const loadPayloadSchema = deps.loadPayloadSchema ?? (async (filePath) => {
9476
- const zodPath = path27.join(path27.dirname(filePath), "zod.js");
9571
+ const zodPath = path28.join(path28.dirname(filePath), "zod.js");
9477
9572
  try {
9478
9573
  const mod = await import(zodPath);
9479
9574
  const schemaKey = Object.keys(mod).find((k) => k.endsWith("Schema"));
@@ -9501,7 +9596,7 @@ function createTaskQueue(deps) {
9501
9596
  const meta = registry.get(name);
9502
9597
  schemaCache.set(
9503
9598
  name,
9504
- await loadPayloadSchema(path27.resolve(rootDir, meta.filePath)).catch(() => void 0)
9599
+ await loadPayloadSchema(path28.resolve(rootDir, meta.filePath)).catch(() => void 0)
9505
9600
  );
9506
9601
  }
9507
9602
  const schema = schemaCache.get(name);
@@ -9537,7 +9632,7 @@ function createTaskQueue(deps) {
9537
9632
  let result;
9538
9633
  if (meta.timeoutMs !== void 0 && meta.timeoutMs > 0) {
9539
9634
  result = await (deps.runIsolated ?? runTaskInWorker)({
9540
- taskModulePath: path27.resolve(rootDir, meta.filePath),
9635
+ taskModulePath: path28.resolve(rootDir, meta.filePath),
9541
9636
  payload: job.payload,
9542
9637
  taskCtx: {
9543
9638
  config: deps.config,
@@ -9562,7 +9657,7 @@ function createTaskQueue(deps) {
9562
9657
  } else {
9563
9658
  let mod = moduleCache2.get(job.name);
9564
9659
  if (!mod) {
9565
- mod = await loadTaskModule(path27.resolve(rootDir, meta.filePath));
9660
+ mod = await loadTaskModule(path28.resolve(rootDir, meta.filePath));
9566
9661
  moduleCache2.set(job.name, mod);
9567
9662
  }
9568
9663
  if (typeof mod.run !== "function") {
@@ -9851,8 +9946,8 @@ var init_cronScheduler = __esm({
9851
9946
  });
9852
9947
 
9853
9948
  // src/cli/loadPlugins.ts
9854
- import path28 from "path";
9855
- import fs20 from "fs";
9949
+ import path29 from "path";
9950
+ import fs21 from "fs";
9856
9951
  import { pathToFileURL as pathToFileURL3 } from "url";
9857
9952
  async function loadPlugins(declarations, ctx, rootDir, dist) {
9858
9953
  const handlerWrappers = [];
@@ -9915,30 +10010,30 @@ async function loadPlugins(declarations, ctx, rootDir, dist) {
9915
10010
  return { handlerWrappers, upgradeWrappers, failures };
9916
10011
  }
9917
10012
  function resolveLocalPluginSource(specifier, baseDir) {
9918
- const base = path28.isAbsolute(specifier) ? specifier : path28.resolve(baseDir, specifier);
9919
- if ((TS_EXTS.test(base) || JS_EXTS.test(base)) && fs20.existsSync(base)) return base;
10013
+ const base = path29.isAbsolute(specifier) ? specifier : path29.resolve(baseDir, specifier);
10014
+ if ((TS_EXTS.test(base) || JS_EXTS.test(base)) && fs21.existsSync(base)) return base;
9920
10015
  for (const ext of [".ts", ".js"]) {
9921
- if (fs20.existsSync(base + ext)) return base + ext;
10016
+ if (fs21.existsSync(base + ext)) return base + ext;
9922
10017
  }
9923
10018
  for (const indexExt of ["/index.ts", "/index.js"]) {
9924
- if (fs20.existsSync(base + indexExt)) return base + indexExt;
10019
+ if (fs21.existsSync(base + indexExt)) return base + indexExt;
9925
10020
  }
9926
10021
  return null;
9927
10022
  }
9928
10023
  function mirrorProductPath(sourcePath, baseDir, distDir) {
9929
- let rel = path28.relative(baseDir, sourcePath).replace(/\\/g, "/");
10024
+ let rel = path29.relative(baseDir, sourcePath).replace(/\\/g, "/");
9930
10025
  if (rel.startsWith("src/")) rel = rel.slice(4);
9931
- return path28.resolve(distDir, rel.replace(TS_EXTS, ".js"));
10026
+ return path29.resolve(distDir, rel.replace(TS_EXTS, ".js"));
9932
10027
  }
9933
10028
  async function importPluginModule(specifier, baseDir, dist) {
9934
10029
  const isRelative = specifier.startsWith("./") || specifier.startsWith("../");
9935
- if (!isRelative && !path28.isAbsolute(specifier)) {
10030
+ if (!isRelative && !path29.isAbsolute(specifier)) {
9936
10031
  return import(specifier);
9937
10032
  }
9938
- const distDir = dist ? path28.resolve(baseDir, dist) : null;
10033
+ const distDir = dist ? path29.resolve(baseDir, dist) : null;
9939
10034
  const sourcePath = resolveLocalPluginSource(specifier, baseDir);
9940
10035
  const productPath = sourcePath && distDir ? mirrorProductPath(sourcePath, baseDir, distDir) : null;
9941
- if (productPath !== null && fs20.existsSync(productPath) && (sourcePath === null || isProductFresh(sourcePath, productPath))) {
10036
+ if (productPath !== null && fs21.existsSync(productPath) && (sourcePath === null || isProductFresh(sourcePath, productPath))) {
9942
10037
  return import(pathToFileURL3(productPath).href);
9943
10038
  }
9944
10039
  if (sourcePath && TS_EXTS.test(sourcePath)) {
@@ -9947,13 +10042,13 @@ async function importPluginModule(specifier, baseDir, dist) {
9947
10042
  `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.`
9948
10043
  );
9949
10044
  }
9950
- const relFromRoot = path28.relative(baseDir, sourcePath).replace(/\\/g, "/");
10045
+ const relFromRoot = path29.relative(baseDir, sourcePath).replace(/\\/g, "/");
9951
10046
  if (relFromRoot.startsWith("src/")) {
9952
10047
  await ensureCompiled(sourcePath, baseDir, dist);
9953
10048
  } else {
9954
10049
  await compileProjectModules([sourcePath], baseDir, dist);
9955
10050
  }
9956
- if (productPath && fs20.existsSync(productPath)) {
10051
+ if (productPath && fs21.existsSync(productPath)) {
9957
10052
  return import(pathToFileURL3(productPath).href);
9958
10053
  }
9959
10054
  }
@@ -9965,7 +10060,7 @@ async function importPluginModule(specifier, baseDir, dist) {
9965
10060
  `${specifier}/index.ts`,
9966
10061
  `${specifier}.js`,
9967
10062
  `${specifier}/index.js`
9968
- ].map((c) => path28.isAbsolute(c) ? c : path28.join(baseDir, c));
10063
+ ].map((c) => path29.isAbsolute(c) ? c : path29.join(baseDir, c));
9969
10064
  throw new Error(
9970
10065
  `Cannot find local plugin "${specifier}" (resolved from ${baseDir}). Expected one of:
9971
10066
  ${candidates.join("\n ")}
@@ -10000,11 +10095,11 @@ var init_loadPlugins = __esm({
10000
10095
  });
10001
10096
 
10002
10097
  // src/cli/manifestLoader.ts
10003
- import fs21 from "fs";
10004
- import path29 from "path";
10098
+ import fs22 from "fs";
10099
+ import path30 from "path";
10005
10100
  async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries) {
10006
- const toolsPath = path29.resolve(rootDir, dist, TOOLS_FILE2);
10007
- if (!fs21.existsSync(toolsPath)) {
10101
+ const toolsPath = path30.resolve(rootDir, dist, TOOLS_FILE2);
10102
+ if (!fs22.existsSync(toolsPath)) {
10008
10103
  return [];
10009
10104
  }
10010
10105
  const serialized = await importWithCacheBust(toolsPath);
@@ -10013,8 +10108,8 @@ async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries
10013
10108
  return hydrated;
10014
10109
  }
10015
10110
  async function loadAndHydrateAgents(rootDir, dist, registries = defaultRegistries) {
10016
- const agentsPath = path29.resolve(rootDir, dist, AGENTS_FILE2);
10017
- if (!fs21.existsSync(agentsPath)) {
10111
+ const agentsPath = path30.resolve(rootDir, dist, AGENTS_FILE2);
10112
+ if (!fs22.existsSync(agentsPath)) {
10018
10113
  return [];
10019
10114
  }
10020
10115
  const serialized = await importWithCacheBust(agentsPath);
@@ -10029,8 +10124,8 @@ function getTaskDriverOptions(config) {
10029
10124
  return void 0;
10030
10125
  }
10031
10126
  async function loadAndHydrateTasks(rootDir, dist, registries = defaultRegistries) {
10032
- const tasksPath = path29.resolve(rootDir, dist, TASKS_FILE);
10033
- if (!fs21.existsSync(tasksPath)) {
10127
+ const tasksPath = path30.resolve(rootDir, dist, TASKS_FILE);
10128
+ if (!fs22.existsSync(tasksPath)) {
10034
10129
  return [];
10035
10130
  }
10036
10131
  const serialized = await importWithCacheBust(tasksPath);
@@ -10177,8 +10272,8 @@ var init_injectMock = __esm({
10177
10272
  });
10178
10273
 
10179
10274
  // src/cli/createAppCore.ts
10180
- import fs22 from "fs";
10181
- import path30 from "path";
10275
+ import fs23 from "fs";
10276
+ import path31 from "path";
10182
10277
  function isFaapiConfigKey(key) {
10183
10278
  return FAAPI_CONFIG_KEYS.has(key);
10184
10279
  }
@@ -10219,8 +10314,9 @@ function logStartupSummary(routes, wsRoutes, tools, agents, taskMetas, p) {
10219
10314
  async function createAppBase(options) {
10220
10315
  const rootDir = options?.rootDir ?? process.cwd();
10221
10316
  const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
10222
- const routesPath = path30.resolve(rootDir, dist, ROUTES_FILE);
10223
- if (!fs22.existsSync(routesPath)) {
10317
+ const resourcesDir = resolveResourcesDir(rootDir, dist);
10318
+ const routesPath = path31.resolve(rootDir, dist, ROUTES_FILE);
10319
+ if (!fs23.existsSync(routesPath)) {
10224
10320
  throw new Error(
10225
10321
  `[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
10226
10322
  );
@@ -10299,6 +10395,8 @@ async function createAppBase(options) {
10299
10395
  routes: sorted,
10300
10396
  wsRoutes,
10301
10397
  rootDir,
10398
+ dist,
10399
+ resourcesDir,
10302
10400
  tasks: taskQueue,
10303
10401
  async listen(listenPort) {
10304
10402
  const envPort = process.env.PORT ? Number(process.env.PORT) : void 0;
@@ -10310,7 +10408,8 @@ async function createAppBase(options) {
10310
10408
  routes: sorted,
10311
10409
  server,
10312
10410
  registries,
10313
- tasks: taskQueue
10411
+ tasks: taskQueue,
10412
+ resourcesDir
10314
10413
  });
10315
10414
  console.log("- onBoot hook executed");
10316
10415
  } catch (err) {
@@ -10345,7 +10444,8 @@ async function createAppBase(options) {
10345
10444
  routes: sorted,
10346
10445
  server,
10347
10446
  registries,
10348
- tasks: taskQueue
10447
+ tasks: taskQueue,
10448
+ resourcesDir
10349
10449
  });
10350
10450
  console.log("- onReady hook executed");
10351
10451
  }
@@ -10369,7 +10469,8 @@ async function createAppBase(options) {
10369
10469
  routes: sorted,
10370
10470
  server,
10371
10471
  registries,
10372
- tasks: taskQueue
10472
+ tasks: taskQueue,
10473
+ resourcesDir
10373
10474
  });
10374
10475
  }
10375
10476
  registries.tool.clear();
@@ -10451,6 +10552,7 @@ var init_createAppCore = __esm({
10451
10552
  init_manifestLoader();
10452
10553
  init_appSingleton();
10453
10554
  init_injectMock();
10555
+ init_copyResources();
10454
10556
  init_manifestLoader();
10455
10557
  DEFAULT_DIST = "dist";
10456
10558
  DEFAULT_PORT = 3e3;
@@ -10476,7 +10578,7 @@ var init_createAppCore = __esm({
10476
10578
  });
10477
10579
 
10478
10580
  // src/cli/createDevApp.ts
10479
- import path31 from "path";
10581
+ import path32 from "path";
10480
10582
  async function createDevApp(options) {
10481
10583
  const { app, ctx } = await createAppBase(options);
10482
10584
  const devApp = app;
@@ -10526,7 +10628,7 @@ async function createDevApp(options) {
10526
10628
  if (!suppressProgramInvalidation) invalidateProgramCache();
10527
10629
  const tasks = await scanTasks(ctx.rootDir, TASK_PATTERNS);
10528
10630
  for (const task of tasks) {
10529
- await ensureCompiled(path31.resolve(ctx.rootDir, task.filePath), ctx.rootDir, ctx.dist);
10631
+ await ensureCompiled(path32.resolve(ctx.rootDir, task.filePath), ctx.rootDir, ctx.dist);
10530
10632
  }
10531
10633
  await generateTaskArtifacts(tasks, ctx.rootDir, ctx.dist);
10532
10634
  ctx.taskQueue.invalidateModules();
@@ -10583,7 +10685,7 @@ __export(devCommand_exports, {
10583
10685
  generateTaskArtifactsForDev: () => generateTaskArtifactsForDev,
10584
10686
  generateToolArtifactsForDev: () => generateToolArtifactsForDev
10585
10687
  });
10586
- import path32 from "path";
10688
+ import path33 from "path";
10587
10689
  async function devCommand(options) {
10588
10690
  const rootDir = process.cwd();
10589
10691
  if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
@@ -10604,6 +10706,10 @@ async function devCommand(options) {
10604
10706
  await generateAgentArtifactsForDev(rootDir, devDist);
10605
10707
  console.log("- Generating task artifacts...");
10606
10708
  await generateTaskArtifactsForDev(rootDir, devDist);
10709
+ console.log("- Copying resources...");
10710
+ const copied = await copyResources(rootDir, devDist);
10711
+ if (copied)
10712
+ console.log(` Copied src/resources \u2192 ${path33.resolve(rootDir, devDist, "resources")}`);
10607
10713
  console.log("- Starting dev app...");
10608
10714
  const app = await createDevApp({ rootDir, port: options?.port });
10609
10715
  await app.listen();
@@ -10612,7 +10718,7 @@ async function devCommand(options) {
10612
10718
  async function generateRouteArtifacts(rootDir, patterns, dist) {
10613
10719
  const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
10614
10720
  const sorted = sortRoutes(routes);
10615
- const routesPath = path32.resolve(rootDir, dist, ROUTES_FILE2);
10721
+ const routesPath = path33.resolve(rootDir, dist, ROUTES_FILE2);
10616
10722
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
10617
10723
  await writeRoutesModule(serialized, routesPath);
10618
10724
  }
@@ -10627,7 +10733,7 @@ async function generateAgentArtifactsForDev(rootDir, dist) {
10627
10733
  async function generateTaskArtifactsForDev(rootDir, dist) {
10628
10734
  const tasks = await scanTasks(rootDir, TASK_PATTERNS);
10629
10735
  for (const task of tasks) {
10630
- await ensureCompiled(path32.resolve(rootDir, task.filePath), rootDir, dist);
10736
+ await ensureCompiled(path33.resolve(rootDir, task.filePath), rootDir, dist);
10631
10737
  }
10632
10738
  await generateTaskArtifacts(tasks, rootDir, dist);
10633
10739
  }
@@ -10653,6 +10759,7 @@ var init_devCommand = __esm({
10653
10759
  init_watcher();
10654
10760
  init_createDevApp();
10655
10761
  init_compileOnDemand();
10762
+ init_copyResources();
10656
10763
  init_prodPaths();
10657
10764
  DEV_DIST = ".faapi";
10658
10765
  ROUTES_FILE2 = "faapi-routes.js";
@@ -10675,15 +10782,15 @@ var buildCommand_exports = {};
10675
10782
  __export(buildCommand_exports, {
10676
10783
  buildCommand: () => buildCommand
10677
10784
  });
10678
- import path33 from "path";
10679
- import fs23 from "fs";
10785
+ import path34 from "path";
10786
+ import fs24 from "fs";
10680
10787
  async function buildCommand(options) {
10681
10788
  const rootDir = options?.rootDir ?? process.cwd();
10682
10789
  const outdir = options?.dist ?? DEFAULT_DIST2;
10683
- const absOut = path33.resolve(rootDir, outdir);
10684
- const realRoot = toRealPath(path33.resolve(rootDir));
10790
+ const absOut = path34.resolve(rootDir, outdir);
10791
+ const realRoot = toRealPath(path34.resolve(rootDir));
10685
10792
  if (isInsideDir(toRealPath(absOut), realRoot)) {
10686
- fs23.rmSync(absOut, { recursive: true, force: true });
10793
+ fs24.rmSync(absOut, { recursive: true, force: true });
10687
10794
  } else {
10688
10795
  console.warn(
10689
10796
  `! Output directory "${outdir}" is outside the project root, skipping clean (stale artifacts may remain)`
@@ -10691,10 +10798,10 @@ async function buildCommand(options) {
10691
10798
  }
10692
10799
  await compileConfig({ rootDir, dist: outdir });
10693
10800
  const _config = await loadConfig(rootDir, outdir);
10694
- const pkgPath = path33.resolve(rootDir, "package.json");
10695
- if (fs23.existsSync(pkgPath)) {
10801
+ const pkgPath = path34.resolve(rootDir, "package.json");
10802
+ if (fs24.existsSync(pkgPath)) {
10696
10803
  try {
10697
- const pkg = JSON.parse(fs23.readFileSync(pkgPath, "utf-8"));
10804
+ const pkg = JSON.parse(fs24.readFileSync(pkgPath, "utf-8"));
10698
10805
  if (pkg.type !== "module") {
10699
10806
  console.warn(
10700
10807
  '! package.json is missing "type": "module" \u2014 build output is ESM and `node dist/main` will fail without it'
@@ -10707,7 +10814,7 @@ async function buildCommand(options) {
10707
10814
  console.log(`- Root: ${rootDir}`);
10708
10815
  console.log(`- Source: src/`);
10709
10816
  console.log(`- Output: ${outdir}`);
10710
- console.log("\n[1/8] Compiling TypeScript (bundle: false)...");
10817
+ console.log("\n[1/9] Compiling TypeScript (bundle: false)...");
10711
10818
  const result = await compileBuildRoutes({
10712
10819
  rootDir,
10713
10820
  dist: outdir,
@@ -10720,9 +10827,9 @@ async function buildCommand(options) {
10720
10827
  }
10721
10828
  const localPluginSources = extractLocalPluginSources(_config?.plugins, rootDir);
10722
10829
  if (localPluginSources.length > 0) {
10723
- console.log("\n[2.5/8] Compiling local plugins...");
10830
+ console.log("\n[2.5/9] Compiling local plugins...");
10724
10831
  const outside = localPluginSources.filter((p) => {
10725
- const rel = path33.relative(rootDir, p).replace(/\\/g, "/");
10832
+ const rel = path34.relative(rootDir, p).replace(/\\/g, "/");
10726
10833
  return !rel.startsWith("src/");
10727
10834
  });
10728
10835
  if (outside.length > 0) {
@@ -10730,36 +10837,41 @@ async function buildCommand(options) {
10730
10837
  }
10731
10838
  console.log(` Compiled ${localPluginSources.length} local plugin(s)`);
10732
10839
  }
10733
- console.log("\n[3/8] Scanning routes...");
10840
+ console.log("\n[3/9] Scanning routes...");
10734
10841
  const { routes, wsRoutes } = await scanRoutes(rootDir, ROUTE_PATTERNS, outdir);
10735
10842
  const sorted = sortRoutes(routes);
10736
10843
  console.log(` Found ${sorted.length} routes, ${wsRoutes.length} WS routes`);
10737
10844
  reportRouteConflicts(sorted);
10738
- console.log("\n[4/8] Generating schema...");
10845
+ console.log("\n[4/9] Generating schema...");
10739
10846
  await generateSchemaFiles(sorted, rootDir, outdir, wsRoutes);
10740
- console.log(` Schema: zod.js files under ${path33.resolve(rootDir, outdir)}`);
10741
- console.log("\n[5/8] Generating routes manifest...");
10742
- const routesPath = path33.resolve(rootDir, outdir, "faapi-routes.js");
10847
+ console.log(` Schema: zod.js files under ${path34.resolve(rootDir, outdir)}`);
10848
+ console.log("\n[5/9] Generating routes manifest...");
10849
+ const routesPath = path34.resolve(rootDir, outdir, "faapi-routes.js");
10743
10850
  const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
10744
10851
  await writeRoutesModule(serialized, routesPath);
10745
10852
  console.log(` Written to ${routesPath}`);
10746
- console.log("\n[6/8] Generating tool manifest and schema...");
10853
+ console.log("\n[6/9] Generating tool manifest and schema...");
10747
10854
  const tools = await scanTools(rootDir, TOOL_PATTERNS);
10748
10855
  const toolMeta = await generateToolArtifacts(tools, rootDir, outdir);
10749
10856
  console.log(` Found ${toolMeta.length} tool(s)`);
10750
- console.log(` Tool manifest: ${path33.resolve(rootDir, outdir, "faapi-tools.js")}`);
10751
- console.log("\n[7/8] Generating agent manifest...");
10857
+ console.log(` Tool manifest: ${path34.resolve(rootDir, outdir, "faapi-tools.js")}`);
10858
+ console.log("\n[7/9] Generating agent manifest...");
10752
10859
  const agents = await scanAgents(rootDir, DEFAULT_AGENT_PATTERNS);
10753
10860
  const agentMeta = await generateAgentArtifacts(agents, rootDir, outdir);
10754
10861
  console.log(` Found ${agentMeta.length} agent(s)`);
10755
- console.log(` Agent manifest: ${path33.resolve(rootDir, outdir, "faapi-agents.js")}`);
10756
- console.log("\n[7.5/8] Generating task manifest and schema...");
10862
+ console.log(` Agent manifest: ${path34.resolve(rootDir, outdir, "faapi-agents.js")}`);
10863
+ console.log("\n[7.5/9] Generating task manifest and schema...");
10757
10864
  const tasks = await scanTasks(rootDir, TASK_PATTERNS);
10758
10865
  const taskMeta = await generateTaskArtifacts(tasks, rootDir, outdir);
10759
10866
  console.log(` Found ${taskMeta.length} task(s)`);
10760
- console.log(` Task manifest: ${path33.resolve(rootDir, outdir, "faapi-tasks.js")}`);
10761
- console.log("\n[8/8] Generating entry file...");
10762
- const mainPath = path33.resolve(rootDir, outdir, "main.js");
10867
+ console.log(` Task manifest: ${path34.resolve(rootDir, outdir, "faapi-tasks.js")}`);
10868
+ console.log("\n[8/9] Copying resources...");
10869
+ const resourcesCopied = await copyResources(rootDir, outdir);
10870
+ if (resourcesCopied) {
10871
+ console.log(` Copied src/resources \u2192 ${path34.resolve(rootDir, outdir, "resources")}`);
10872
+ }
10873
+ console.log("\n[9/9] Generating entry file...");
10874
+ const mainPath = path34.resolve(rootDir, outdir, "main.js");
10763
10875
  const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: ${JSON.stringify(outdir)} }` : "";
10764
10876
  const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
10765
10877
  import { createProdApp, loadEnv } from '@faapi/faapi';
@@ -10771,7 +10883,7 @@ loadEnv(process.cwd());
10771
10883
  const app = await createProdApp(${createProdAppArgs});
10772
10884
  await app.listen();
10773
10885
  `;
10774
- await fs23.promises.writeFile(mainPath, mainContent, "utf-8");
10886
+ await fs24.promises.writeFile(mainPath, mainContent, "utf-8");
10775
10887
  console.log(` Written to ${mainPath}`);
10776
10888
  console.log("\nfaapi build completed");
10777
10889
  }
@@ -10785,7 +10897,7 @@ function extractLocalPluginSources(declarations, rootDir) {
10785
10897
  else if (Array.isArray(decl)) specifier = decl[0];
10786
10898
  else if ("path" in decl) specifier = decl.path;
10787
10899
  if (!specifier) continue;
10788
- if (!specifier.startsWith("./") && !specifier.startsWith("../") && !path33.isAbsolute(specifier)) {
10900
+ if (!specifier.startsWith("./") && !specifier.startsWith("../") && !path34.isAbsolute(specifier)) {
10789
10901
  continue;
10790
10902
  }
10791
10903
  const source = resolveLocalPluginSource(specifier, rootDir);
@@ -10814,6 +10926,7 @@ var init_buildCommand = __esm({
10814
10926
  init_generateSchemaFiles();
10815
10927
  init_generateRoutes();
10816
10928
  init_compileBuildRoutes();
10929
+ init_copyResources();
10817
10930
  init_prodPaths();
10818
10931
  init_compileConfig();
10819
10932
  init_loadConfig();