@faapi/faapi 6.7.0 → 6.9.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 +539 -233
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +50 -3
- package/dist/index.js +494 -210
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-CsL7xtqu.d.ts → routeTypes-CuGMDCGB.d.ts} +121 -2
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +136 -2
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
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(
|
|
653
|
-
if (!
|
|
654
|
-
let result =
|
|
652
|
+
function normalizePath(path32) {
|
|
653
|
+
if (!path32) return "";
|
|
654
|
+
let result = path32.replace(/\\/g, "/");
|
|
655
655
|
result = result.replace(/\/+/g, "/");
|
|
656
656
|
result = result.replace(/\/+$/, "");
|
|
657
657
|
if (result && !result.startsWith("/")) {
|
|
@@ -2260,8 +2260,10 @@ var init_resolveInjection = __esm({
|
|
|
2260
2260
|
// Phase 2.3
|
|
2261
2261
|
agents: "agents",
|
|
2262
2262
|
// Phase 2.3
|
|
2263
|
-
tasks: "tasks"
|
|
2263
|
+
tasks: "tasks",
|
|
2264
2264
|
// 任务子系统:TaskClient(入队/查询)
|
|
2265
|
+
log: "log"
|
|
2266
|
+
// 请求级日志器(ctx.log 同一实例:scope http,自动带 requestId 等字段)
|
|
2265
2267
|
};
|
|
2266
2268
|
injectionCache = /* @__PURE__ */ new WeakMap();
|
|
2267
2269
|
}
|
|
@@ -4080,7 +4082,7 @@ var init_esm = __esm({
|
|
|
4080
4082
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
4081
4083
|
const statMethod = opts.lstat ? lstat : stat;
|
|
4082
4084
|
if (wantBigintFsStats) {
|
|
4083
|
-
this._stat = (
|
|
4085
|
+
this._stat = (path32) => statMethod(path32, { bigint: true });
|
|
4084
4086
|
} else {
|
|
4085
4087
|
this._stat = statMethod;
|
|
4086
4088
|
}
|
|
@@ -4105,8 +4107,8 @@ var init_esm = __esm({
|
|
|
4105
4107
|
const par = this.parent;
|
|
4106
4108
|
const fil = par && par.files;
|
|
4107
4109
|
if (fil && fil.length > 0) {
|
|
4108
|
-
const { path:
|
|
4109
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
4110
|
+
const { path: path32, depth } = par;
|
|
4111
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path32));
|
|
4110
4112
|
const awaited = await Promise.all(slice);
|
|
4111
4113
|
for (const entry of awaited) {
|
|
4112
4114
|
if (!entry)
|
|
@@ -4146,20 +4148,20 @@ var init_esm = __esm({
|
|
|
4146
4148
|
this.reading = false;
|
|
4147
4149
|
}
|
|
4148
4150
|
}
|
|
4149
|
-
async _exploreDir(
|
|
4151
|
+
async _exploreDir(path32, depth) {
|
|
4150
4152
|
let files;
|
|
4151
4153
|
try {
|
|
4152
|
-
files = await readdir(
|
|
4154
|
+
files = await readdir(path32, this._rdOptions);
|
|
4153
4155
|
} catch (error) {
|
|
4154
4156
|
this._onError(error);
|
|
4155
4157
|
}
|
|
4156
|
-
return { files, depth, path:
|
|
4158
|
+
return { files, depth, path: path32 };
|
|
4157
4159
|
}
|
|
4158
|
-
async _formatEntry(dirent,
|
|
4160
|
+
async _formatEntry(dirent, path32) {
|
|
4159
4161
|
let entry;
|
|
4160
4162
|
const basename3 = this._isDirent ? dirent.name : dirent;
|
|
4161
4163
|
try {
|
|
4162
|
-
const fullPath = presolve(pjoin(
|
|
4164
|
+
const fullPath = presolve(pjoin(path32, basename3));
|
|
4163
4165
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename3 };
|
|
4164
4166
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
4165
4167
|
} catch (err) {
|
|
@@ -4220,16 +4222,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
|
|
|
4220
4222
|
import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
|
|
4221
4223
|
import * as sysPath from "path";
|
|
4222
4224
|
import { type as osType } from "os";
|
|
4223
|
-
function createFsWatchInstance(
|
|
4225
|
+
function createFsWatchInstance(path32, options, listener, errHandler, emitRaw) {
|
|
4224
4226
|
const handleEvent = (rawEvent, evPath) => {
|
|
4225
|
-
listener(
|
|
4226
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
4227
|
-
if (evPath &&
|
|
4228
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
4227
|
+
listener(path32);
|
|
4228
|
+
emitRaw(rawEvent, evPath, { watchedPath: path32 });
|
|
4229
|
+
if (evPath && path32 !== evPath) {
|
|
4230
|
+
fsWatchBroadcast(sysPath.resolve(path32, evPath), KEY_LISTENERS, sysPath.join(path32, evPath));
|
|
4229
4231
|
}
|
|
4230
4232
|
};
|
|
4231
4233
|
try {
|
|
4232
|
-
return fs_watch(
|
|
4234
|
+
return fs_watch(path32, {
|
|
4233
4235
|
persistent: options.persistent
|
|
4234
4236
|
}, handleEvent);
|
|
4235
4237
|
} catch (error) {
|
|
@@ -4574,12 +4576,12 @@ var init_handler = __esm({
|
|
|
4574
4576
|
listener(val1, val2, val3);
|
|
4575
4577
|
});
|
|
4576
4578
|
};
|
|
4577
|
-
setFsWatchListener = (
|
|
4579
|
+
setFsWatchListener = (path32, fullPath, options, handlers) => {
|
|
4578
4580
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
4579
4581
|
let cont = FsWatchInstances.get(fullPath);
|
|
4580
4582
|
let watcher;
|
|
4581
4583
|
if (!options.persistent) {
|
|
4582
|
-
watcher = createFsWatchInstance(
|
|
4584
|
+
watcher = createFsWatchInstance(path32, options, listener, errHandler, rawEmitter);
|
|
4583
4585
|
if (!watcher)
|
|
4584
4586
|
return;
|
|
4585
4587
|
return watcher.close.bind(watcher);
|
|
@@ -4590,7 +4592,7 @@ var init_handler = __esm({
|
|
|
4590
4592
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
4591
4593
|
} else {
|
|
4592
4594
|
watcher = createFsWatchInstance(
|
|
4593
|
-
|
|
4595
|
+
path32,
|
|
4594
4596
|
options,
|
|
4595
4597
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
4596
4598
|
errHandler,
|
|
@@ -4605,7 +4607,7 @@ var init_handler = __esm({
|
|
|
4605
4607
|
cont.watcherUnusable = true;
|
|
4606
4608
|
if (isWindows && error.code === "EPERM") {
|
|
4607
4609
|
try {
|
|
4608
|
-
const fd = await open(
|
|
4610
|
+
const fd = await open(path32, "r");
|
|
4609
4611
|
await fd.close();
|
|
4610
4612
|
broadcastErr(error);
|
|
4611
4613
|
} catch (err) {
|
|
@@ -4636,7 +4638,7 @@ var init_handler = __esm({
|
|
|
4636
4638
|
};
|
|
4637
4639
|
};
|
|
4638
4640
|
FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
4639
|
-
setFsWatchFileListener = (
|
|
4641
|
+
setFsWatchFileListener = (path32, fullPath, options, handlers) => {
|
|
4640
4642
|
const { listener, rawEmitter } = handlers;
|
|
4641
4643
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
4642
4644
|
const copts = cont && cont.options;
|
|
@@ -4658,7 +4660,7 @@ var init_handler = __esm({
|
|
|
4658
4660
|
});
|
|
4659
4661
|
const currmtime = curr.mtimeMs;
|
|
4660
4662
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
4661
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
4663
|
+
foreach(cont.listeners, (listener2) => listener2(path32, curr));
|
|
4662
4664
|
}
|
|
4663
4665
|
})
|
|
4664
4666
|
};
|
|
@@ -4686,13 +4688,13 @@ var init_handler = __esm({
|
|
|
4686
4688
|
* @param listener on fs change
|
|
4687
4689
|
* @returns closer for the watcher instance
|
|
4688
4690
|
*/
|
|
4689
|
-
_watchWithNodeFs(
|
|
4691
|
+
_watchWithNodeFs(path32, listener) {
|
|
4690
4692
|
const opts = this.fsw.options;
|
|
4691
|
-
const directory = sysPath.dirname(
|
|
4692
|
-
const basename3 = sysPath.basename(
|
|
4693
|
+
const directory = sysPath.dirname(path32);
|
|
4694
|
+
const basename3 = sysPath.basename(path32);
|
|
4693
4695
|
const parent = this.fsw._getWatchedDir(directory);
|
|
4694
4696
|
parent.add(basename3);
|
|
4695
|
-
const absolutePath = sysPath.resolve(
|
|
4697
|
+
const absolutePath = sysPath.resolve(path32);
|
|
4696
4698
|
const options = {
|
|
4697
4699
|
persistent: opts.persistent
|
|
4698
4700
|
};
|
|
@@ -4702,12 +4704,12 @@ var init_handler = __esm({
|
|
|
4702
4704
|
if (opts.usePolling) {
|
|
4703
4705
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
4704
4706
|
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
4705
|
-
closer = setFsWatchFileListener(
|
|
4707
|
+
closer = setFsWatchFileListener(path32, absolutePath, options, {
|
|
4706
4708
|
listener,
|
|
4707
4709
|
rawEmitter: this.fsw._emitRaw
|
|
4708
4710
|
});
|
|
4709
4711
|
} else {
|
|
4710
|
-
closer = setFsWatchListener(
|
|
4712
|
+
closer = setFsWatchListener(path32, absolutePath, options, {
|
|
4711
4713
|
listener,
|
|
4712
4714
|
errHandler: this._boundHandleError,
|
|
4713
4715
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -4729,7 +4731,7 @@ var init_handler = __esm({
|
|
|
4729
4731
|
let prevStats = stats;
|
|
4730
4732
|
if (parent.has(basename3))
|
|
4731
4733
|
return;
|
|
4732
|
-
const listener = async (
|
|
4734
|
+
const listener = async (path32, newStats) => {
|
|
4733
4735
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
4734
4736
|
return;
|
|
4735
4737
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -4743,11 +4745,11 @@ var init_handler = __esm({
|
|
|
4743
4745
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
4744
4746
|
}
|
|
4745
4747
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
4746
|
-
this.fsw._closeFile(
|
|
4748
|
+
this.fsw._closeFile(path32);
|
|
4747
4749
|
prevStats = newStats2;
|
|
4748
4750
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
4749
4751
|
if (closer2)
|
|
4750
|
-
this.fsw._addPathCloser(
|
|
4752
|
+
this.fsw._addPathCloser(path32, closer2);
|
|
4751
4753
|
} else {
|
|
4752
4754
|
prevStats = newStats2;
|
|
4753
4755
|
}
|
|
@@ -4779,7 +4781,7 @@ var init_handler = __esm({
|
|
|
4779
4781
|
* @param item basename of this item
|
|
4780
4782
|
* @returns true if no more processing is needed for this entry.
|
|
4781
4783
|
*/
|
|
4782
|
-
async _handleSymlink(entry, directory,
|
|
4784
|
+
async _handleSymlink(entry, directory, path32, item) {
|
|
4783
4785
|
if (this.fsw.closed) {
|
|
4784
4786
|
return;
|
|
4785
4787
|
}
|
|
@@ -4789,7 +4791,7 @@ var init_handler = __esm({
|
|
|
4789
4791
|
this.fsw._incrReadyCount();
|
|
4790
4792
|
let linkPath;
|
|
4791
4793
|
try {
|
|
4792
|
-
linkPath = await fsrealpath(
|
|
4794
|
+
linkPath = await fsrealpath(path32);
|
|
4793
4795
|
} catch (e) {
|
|
4794
4796
|
this.fsw._emitReady();
|
|
4795
4797
|
return true;
|
|
@@ -4799,12 +4801,12 @@ var init_handler = __esm({
|
|
|
4799
4801
|
if (dir.has(item)) {
|
|
4800
4802
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
4801
4803
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4802
|
-
this.fsw._emit(EV.CHANGE,
|
|
4804
|
+
this.fsw._emit(EV.CHANGE, path32, entry.stats);
|
|
4803
4805
|
}
|
|
4804
4806
|
} else {
|
|
4805
4807
|
dir.add(item);
|
|
4806
4808
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
4807
|
-
this.fsw._emit(EV.ADD,
|
|
4809
|
+
this.fsw._emit(EV.ADD, path32, entry.stats);
|
|
4808
4810
|
}
|
|
4809
4811
|
this.fsw._emitReady();
|
|
4810
4812
|
return true;
|
|
@@ -4833,9 +4835,9 @@ var init_handler = __esm({
|
|
|
4833
4835
|
return;
|
|
4834
4836
|
}
|
|
4835
4837
|
const item = entry.path;
|
|
4836
|
-
let
|
|
4838
|
+
let path32 = sysPath.join(directory, item);
|
|
4837
4839
|
current.add(item);
|
|
4838
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
4840
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path32, item)) {
|
|
4839
4841
|
return;
|
|
4840
4842
|
}
|
|
4841
4843
|
if (this.fsw.closed) {
|
|
@@ -4844,8 +4846,8 @@ var init_handler = __esm({
|
|
|
4844
4846
|
}
|
|
4845
4847
|
if (item === target || !target && !previous.has(item)) {
|
|
4846
4848
|
this.fsw._incrReadyCount();
|
|
4847
|
-
|
|
4848
|
-
this._addToNodeFs(
|
|
4849
|
+
path32 = sysPath.join(dir, sysPath.relative(dir, path32));
|
|
4850
|
+
this._addToNodeFs(path32, initialAdd, wh, depth + 1);
|
|
4849
4851
|
}
|
|
4850
4852
|
}).on(EV.ERROR, this._boundHandleError);
|
|
4851
4853
|
return new Promise((resolve3, reject) => {
|
|
@@ -4914,13 +4916,13 @@ var init_handler = __esm({
|
|
|
4914
4916
|
* @param depth Child path actually targeted for watch
|
|
4915
4917
|
* @param target Child path actually targeted for watch
|
|
4916
4918
|
*/
|
|
4917
|
-
async _addToNodeFs(
|
|
4919
|
+
async _addToNodeFs(path32, initialAdd, priorWh, depth, target) {
|
|
4918
4920
|
const ready = this.fsw._emitReady;
|
|
4919
|
-
if (this.fsw._isIgnored(
|
|
4921
|
+
if (this.fsw._isIgnored(path32) || this.fsw.closed) {
|
|
4920
4922
|
ready();
|
|
4921
4923
|
return false;
|
|
4922
4924
|
}
|
|
4923
|
-
const wh = this.fsw._getWatchHelpers(
|
|
4925
|
+
const wh = this.fsw._getWatchHelpers(path32);
|
|
4924
4926
|
if (priorWh) {
|
|
4925
4927
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
4926
4928
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -4936,8 +4938,8 @@ var init_handler = __esm({
|
|
|
4936
4938
|
const follow = this.fsw.options.followSymlinks;
|
|
4937
4939
|
let closer;
|
|
4938
4940
|
if (stats.isDirectory()) {
|
|
4939
|
-
const absPath = sysPath.resolve(
|
|
4940
|
-
const targetPath = follow ? await fsrealpath(
|
|
4941
|
+
const absPath = sysPath.resolve(path32);
|
|
4942
|
+
const targetPath = follow ? await fsrealpath(path32) : path32;
|
|
4941
4943
|
if (this.fsw.closed)
|
|
4942
4944
|
return;
|
|
4943
4945
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -4947,29 +4949,29 @@ var init_handler = __esm({
|
|
|
4947
4949
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
4948
4950
|
}
|
|
4949
4951
|
} else if (stats.isSymbolicLink()) {
|
|
4950
|
-
const targetPath = follow ? await fsrealpath(
|
|
4952
|
+
const targetPath = follow ? await fsrealpath(path32) : path32;
|
|
4951
4953
|
if (this.fsw.closed)
|
|
4952
4954
|
return;
|
|
4953
4955
|
const parent = sysPath.dirname(wh.watchPath);
|
|
4954
4956
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
4955
4957
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
4956
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
4958
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path32, wh, targetPath);
|
|
4957
4959
|
if (this.fsw.closed)
|
|
4958
4960
|
return;
|
|
4959
4961
|
if (targetPath !== void 0) {
|
|
4960
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
4962
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path32), targetPath);
|
|
4961
4963
|
}
|
|
4962
4964
|
} else {
|
|
4963
4965
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
4964
4966
|
}
|
|
4965
4967
|
ready();
|
|
4966
4968
|
if (closer)
|
|
4967
|
-
this.fsw._addPathCloser(
|
|
4969
|
+
this.fsw._addPathCloser(path32, closer);
|
|
4968
4970
|
return false;
|
|
4969
4971
|
} catch (error) {
|
|
4970
4972
|
if (this.fsw._handleError(error)) {
|
|
4971
4973
|
ready();
|
|
4972
|
-
return
|
|
4974
|
+
return path32;
|
|
4973
4975
|
}
|
|
4974
4976
|
}
|
|
4975
4977
|
}
|
|
@@ -5008,26 +5010,26 @@ function createPattern(matcher) {
|
|
|
5008
5010
|
}
|
|
5009
5011
|
return () => false;
|
|
5010
5012
|
}
|
|
5011
|
-
function normalizePath2(
|
|
5012
|
-
if (typeof
|
|
5013
|
+
function normalizePath2(path32) {
|
|
5014
|
+
if (typeof path32 !== "string")
|
|
5013
5015
|
throw new Error("string expected");
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
+
path32 = sysPath2.normalize(path32);
|
|
5017
|
+
path32 = path32.replace(/\\/g, "/");
|
|
5016
5018
|
let prepend = false;
|
|
5017
|
-
if (
|
|
5019
|
+
if (path32.startsWith("//"))
|
|
5018
5020
|
prepend = true;
|
|
5019
5021
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
5020
|
-
while (
|
|
5021
|
-
|
|
5022
|
+
while (path32.match(DOUBLE_SLASH_RE2))
|
|
5023
|
+
path32 = path32.replace(DOUBLE_SLASH_RE2, "/");
|
|
5022
5024
|
if (prepend)
|
|
5023
|
-
|
|
5024
|
-
return
|
|
5025
|
+
path32 = "/" + path32;
|
|
5026
|
+
return path32;
|
|
5025
5027
|
}
|
|
5026
5028
|
function matchPatterns(patterns, testString, stats) {
|
|
5027
|
-
const
|
|
5029
|
+
const path32 = normalizePath2(testString);
|
|
5028
5030
|
for (let index = 0; index < patterns.length; index++) {
|
|
5029
5031
|
const pattern = patterns[index];
|
|
5030
|
-
if (pattern(
|
|
5032
|
+
if (pattern(path32, stats)) {
|
|
5031
5033
|
return true;
|
|
5032
5034
|
}
|
|
5033
5035
|
}
|
|
@@ -5088,19 +5090,19 @@ var init_esm2 = __esm({
|
|
|
5088
5090
|
}
|
|
5089
5091
|
return str;
|
|
5090
5092
|
};
|
|
5091
|
-
normalizePathToUnix = (
|
|
5092
|
-
normalizeIgnored = (cwd = "") => (
|
|
5093
|
-
if (typeof
|
|
5094
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
5093
|
+
normalizePathToUnix = (path32) => toUnix(sysPath2.normalize(toUnix(path32)));
|
|
5094
|
+
normalizeIgnored = (cwd = "") => (path32) => {
|
|
5095
|
+
if (typeof path32 === "string") {
|
|
5096
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path32) ? path32 : sysPath2.join(cwd, path32));
|
|
5095
5097
|
} else {
|
|
5096
|
-
return
|
|
5098
|
+
return path32;
|
|
5097
5099
|
}
|
|
5098
5100
|
};
|
|
5099
|
-
getAbsolutePath = (
|
|
5100
|
-
if (sysPath2.isAbsolute(
|
|
5101
|
-
return
|
|
5101
|
+
getAbsolutePath = (path32, cwd) => {
|
|
5102
|
+
if (sysPath2.isAbsolute(path32)) {
|
|
5103
|
+
return path32;
|
|
5102
5104
|
}
|
|
5103
|
-
return sysPath2.join(cwd,
|
|
5105
|
+
return sysPath2.join(cwd, path32);
|
|
5104
5106
|
};
|
|
5105
5107
|
EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
5106
5108
|
DirEntry = class {
|
|
@@ -5155,10 +5157,10 @@ var init_esm2 = __esm({
|
|
|
5155
5157
|
STAT_METHOD_F = "stat";
|
|
5156
5158
|
STAT_METHOD_L = "lstat";
|
|
5157
5159
|
WatchHelper = class {
|
|
5158
|
-
constructor(
|
|
5160
|
+
constructor(path32, follow, fsw) {
|
|
5159
5161
|
this.fsw = fsw;
|
|
5160
|
-
const watchPath =
|
|
5161
|
-
this.path =
|
|
5162
|
+
const watchPath = path32;
|
|
5163
|
+
this.path = path32 = path32.replace(REPLACER_RE, "");
|
|
5162
5164
|
this.watchPath = watchPath;
|
|
5163
5165
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
5164
5166
|
this.dirParts = [];
|
|
@@ -5280,20 +5282,20 @@ var init_esm2 = __esm({
|
|
|
5280
5282
|
this._closePromise = void 0;
|
|
5281
5283
|
let paths = unifyPaths(paths_);
|
|
5282
5284
|
if (cwd) {
|
|
5283
|
-
paths = paths.map((
|
|
5284
|
-
const absPath = getAbsolutePath(
|
|
5285
|
+
paths = paths.map((path32) => {
|
|
5286
|
+
const absPath = getAbsolutePath(path32, cwd);
|
|
5285
5287
|
return absPath;
|
|
5286
5288
|
});
|
|
5287
5289
|
}
|
|
5288
|
-
paths.forEach((
|
|
5289
|
-
this._removeIgnoredPath(
|
|
5290
|
+
paths.forEach((path32) => {
|
|
5291
|
+
this._removeIgnoredPath(path32);
|
|
5290
5292
|
});
|
|
5291
5293
|
this._userIgnored = void 0;
|
|
5292
5294
|
if (!this._readyCount)
|
|
5293
5295
|
this._readyCount = 0;
|
|
5294
5296
|
this._readyCount += paths.length;
|
|
5295
|
-
Promise.all(paths.map(async (
|
|
5296
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
5297
|
+
Promise.all(paths.map(async (path32) => {
|
|
5298
|
+
const res = await this._nodeFsHandler._addToNodeFs(path32, !_internal, void 0, 0, _origAdd);
|
|
5297
5299
|
if (res)
|
|
5298
5300
|
this._emitReady();
|
|
5299
5301
|
return res;
|
|
@@ -5315,17 +5317,17 @@ var init_esm2 = __esm({
|
|
|
5315
5317
|
return this;
|
|
5316
5318
|
const paths = unifyPaths(paths_);
|
|
5317
5319
|
const { cwd } = this.options;
|
|
5318
|
-
paths.forEach((
|
|
5319
|
-
if (!sysPath2.isAbsolute(
|
|
5320
|
+
paths.forEach((path32) => {
|
|
5321
|
+
if (!sysPath2.isAbsolute(path32) && !this._closers.has(path32)) {
|
|
5320
5322
|
if (cwd)
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
+
path32 = sysPath2.join(cwd, path32);
|
|
5324
|
+
path32 = sysPath2.resolve(path32);
|
|
5323
5325
|
}
|
|
5324
|
-
this._closePath(
|
|
5325
|
-
this._addIgnoredPath(
|
|
5326
|
-
if (this._watched.has(
|
|
5326
|
+
this._closePath(path32);
|
|
5327
|
+
this._addIgnoredPath(path32);
|
|
5328
|
+
if (this._watched.has(path32)) {
|
|
5327
5329
|
this._addIgnoredPath({
|
|
5328
|
-
path:
|
|
5330
|
+
path: path32,
|
|
5329
5331
|
recursive: true
|
|
5330
5332
|
});
|
|
5331
5333
|
}
|
|
@@ -5389,38 +5391,38 @@ var init_esm2 = __esm({
|
|
|
5389
5391
|
* @param stats arguments to be passed with event
|
|
5390
5392
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
5391
5393
|
*/
|
|
5392
|
-
async _emit(event,
|
|
5394
|
+
async _emit(event, path32, stats) {
|
|
5393
5395
|
if (this.closed)
|
|
5394
5396
|
return;
|
|
5395
5397
|
const opts = this.options;
|
|
5396
5398
|
if (isWindows)
|
|
5397
|
-
|
|
5399
|
+
path32 = sysPath2.normalize(path32);
|
|
5398
5400
|
if (opts.cwd)
|
|
5399
|
-
|
|
5400
|
-
const args = [
|
|
5401
|
+
path32 = sysPath2.relative(opts.cwd, path32);
|
|
5402
|
+
const args = [path32];
|
|
5401
5403
|
if (stats != null)
|
|
5402
5404
|
args.push(stats);
|
|
5403
5405
|
const awf = opts.awaitWriteFinish;
|
|
5404
5406
|
let pw;
|
|
5405
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
5407
|
+
if (awf && (pw = this._pendingWrites.get(path32))) {
|
|
5406
5408
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
5407
5409
|
return this;
|
|
5408
5410
|
}
|
|
5409
5411
|
if (opts.atomic) {
|
|
5410
5412
|
if (event === EVENTS.UNLINK) {
|
|
5411
|
-
this._pendingUnlinks.set(
|
|
5413
|
+
this._pendingUnlinks.set(path32, [event, ...args]);
|
|
5412
5414
|
setTimeout(() => {
|
|
5413
|
-
this._pendingUnlinks.forEach((entry,
|
|
5415
|
+
this._pendingUnlinks.forEach((entry, path33) => {
|
|
5414
5416
|
this.emit(...entry);
|
|
5415
5417
|
this.emit(EVENTS.ALL, ...entry);
|
|
5416
|
-
this._pendingUnlinks.delete(
|
|
5418
|
+
this._pendingUnlinks.delete(path33);
|
|
5417
5419
|
});
|
|
5418
5420
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
5419
5421
|
return this;
|
|
5420
5422
|
}
|
|
5421
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
5423
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path32)) {
|
|
5422
5424
|
event = EVENTS.CHANGE;
|
|
5423
|
-
this._pendingUnlinks.delete(
|
|
5425
|
+
this._pendingUnlinks.delete(path32);
|
|
5424
5426
|
}
|
|
5425
5427
|
}
|
|
5426
5428
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -5438,16 +5440,16 @@ var init_esm2 = __esm({
|
|
|
5438
5440
|
this.emitWithAll(event, args);
|
|
5439
5441
|
}
|
|
5440
5442
|
};
|
|
5441
|
-
this._awaitWriteFinish(
|
|
5443
|
+
this._awaitWriteFinish(path32, awf.stabilityThreshold, event, awfEmit);
|
|
5442
5444
|
return this;
|
|
5443
5445
|
}
|
|
5444
5446
|
if (event === EVENTS.CHANGE) {
|
|
5445
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
5447
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path32, 50);
|
|
5446
5448
|
if (isThrottled)
|
|
5447
5449
|
return this;
|
|
5448
5450
|
}
|
|
5449
5451
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
5450
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
5452
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path32) : path32;
|
|
5451
5453
|
let stats2;
|
|
5452
5454
|
try {
|
|
5453
5455
|
stats2 = await stat3(fullPath);
|
|
@@ -5478,23 +5480,23 @@ var init_esm2 = __esm({
|
|
|
5478
5480
|
* @param timeout duration of time to suppress duplicate actions
|
|
5479
5481
|
* @returns tracking object or false if action should be suppressed
|
|
5480
5482
|
*/
|
|
5481
|
-
_throttle(actionType,
|
|
5483
|
+
_throttle(actionType, path32, timeout) {
|
|
5482
5484
|
if (!this._throttled.has(actionType)) {
|
|
5483
5485
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
5484
5486
|
}
|
|
5485
5487
|
const action = this._throttled.get(actionType);
|
|
5486
5488
|
if (!action)
|
|
5487
5489
|
throw new Error("invalid throttle");
|
|
5488
|
-
const actionPath = action.get(
|
|
5490
|
+
const actionPath = action.get(path32);
|
|
5489
5491
|
if (actionPath) {
|
|
5490
5492
|
actionPath.count++;
|
|
5491
5493
|
return false;
|
|
5492
5494
|
}
|
|
5493
5495
|
let timeoutObject;
|
|
5494
5496
|
const clear = () => {
|
|
5495
|
-
const item = action.get(
|
|
5497
|
+
const item = action.get(path32);
|
|
5496
5498
|
const count = item ? item.count : 0;
|
|
5497
|
-
action.delete(
|
|
5499
|
+
action.delete(path32);
|
|
5498
5500
|
clearTimeout(timeoutObject);
|
|
5499
5501
|
if (item)
|
|
5500
5502
|
clearTimeout(item.timeoutObject);
|
|
@@ -5502,7 +5504,7 @@ var init_esm2 = __esm({
|
|
|
5502
5504
|
};
|
|
5503
5505
|
timeoutObject = setTimeout(clear, timeout);
|
|
5504
5506
|
const thr = { timeoutObject, clear, count: 0 };
|
|
5505
|
-
action.set(
|
|
5507
|
+
action.set(path32, thr);
|
|
5506
5508
|
return thr;
|
|
5507
5509
|
}
|
|
5508
5510
|
_incrReadyCount() {
|
|
@@ -5516,44 +5518,44 @@ var init_esm2 = __esm({
|
|
|
5516
5518
|
* @param event
|
|
5517
5519
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
5518
5520
|
*/
|
|
5519
|
-
_awaitWriteFinish(
|
|
5521
|
+
_awaitWriteFinish(path32, threshold, event, awfEmit) {
|
|
5520
5522
|
const awf = this.options.awaitWriteFinish;
|
|
5521
5523
|
if (typeof awf !== "object")
|
|
5522
5524
|
return;
|
|
5523
5525
|
const pollInterval = awf.pollInterval;
|
|
5524
5526
|
let timeoutHandler;
|
|
5525
|
-
let fullPath =
|
|
5526
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
5527
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
5527
|
+
let fullPath = path32;
|
|
5528
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path32)) {
|
|
5529
|
+
fullPath = sysPath2.join(this.options.cwd, path32);
|
|
5528
5530
|
}
|
|
5529
5531
|
const now = /* @__PURE__ */ new Date();
|
|
5530
5532
|
const writes = this._pendingWrites;
|
|
5531
5533
|
function awaitWriteFinishFn(prevStat) {
|
|
5532
5534
|
statcb(fullPath, (err, curStat) => {
|
|
5533
|
-
if (err || !writes.has(
|
|
5535
|
+
if (err || !writes.has(path32)) {
|
|
5534
5536
|
if (err && err.code !== "ENOENT")
|
|
5535
5537
|
awfEmit(err);
|
|
5536
5538
|
return;
|
|
5537
5539
|
}
|
|
5538
5540
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
5539
5541
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
5540
|
-
writes.get(
|
|
5542
|
+
writes.get(path32).lastChange = now2;
|
|
5541
5543
|
}
|
|
5542
|
-
const pw = writes.get(
|
|
5544
|
+
const pw = writes.get(path32);
|
|
5543
5545
|
const df = now2 - pw.lastChange;
|
|
5544
5546
|
if (df >= threshold) {
|
|
5545
|
-
writes.delete(
|
|
5547
|
+
writes.delete(path32);
|
|
5546
5548
|
awfEmit(void 0, curStat);
|
|
5547
5549
|
} else {
|
|
5548
5550
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
5549
5551
|
}
|
|
5550
5552
|
});
|
|
5551
5553
|
}
|
|
5552
|
-
if (!writes.has(
|
|
5553
|
-
writes.set(
|
|
5554
|
+
if (!writes.has(path32)) {
|
|
5555
|
+
writes.set(path32, {
|
|
5554
5556
|
lastChange: now,
|
|
5555
5557
|
cancelWait: () => {
|
|
5556
|
-
writes.delete(
|
|
5558
|
+
writes.delete(path32);
|
|
5557
5559
|
clearTimeout(timeoutHandler);
|
|
5558
5560
|
return event;
|
|
5559
5561
|
}
|
|
@@ -5564,8 +5566,8 @@ var init_esm2 = __esm({
|
|
|
5564
5566
|
/**
|
|
5565
5567
|
* Determines whether user has asked to ignore this path.
|
|
5566
5568
|
*/
|
|
5567
|
-
_isIgnored(
|
|
5568
|
-
if (this.options.atomic && DOT_RE.test(
|
|
5569
|
+
_isIgnored(path32, stats) {
|
|
5570
|
+
if (this.options.atomic && DOT_RE.test(path32))
|
|
5569
5571
|
return true;
|
|
5570
5572
|
if (!this._userIgnored) {
|
|
5571
5573
|
const { cwd } = this.options;
|
|
@@ -5575,17 +5577,17 @@ var init_esm2 = __esm({
|
|
|
5575
5577
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
5576
5578
|
this._userIgnored = anymatch(list, void 0);
|
|
5577
5579
|
}
|
|
5578
|
-
return this._userIgnored(
|
|
5580
|
+
return this._userIgnored(path32, stats);
|
|
5579
5581
|
}
|
|
5580
|
-
_isntIgnored(
|
|
5581
|
-
return !this._isIgnored(
|
|
5582
|
+
_isntIgnored(path32, stat4) {
|
|
5583
|
+
return !this._isIgnored(path32, stat4);
|
|
5582
5584
|
}
|
|
5583
5585
|
/**
|
|
5584
5586
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
5585
5587
|
* @param path file or directory pattern being watched
|
|
5586
5588
|
*/
|
|
5587
|
-
_getWatchHelpers(
|
|
5588
|
-
return new WatchHelper(
|
|
5589
|
+
_getWatchHelpers(path32) {
|
|
5590
|
+
return new WatchHelper(path32, this.options.followSymlinks, this);
|
|
5589
5591
|
}
|
|
5590
5592
|
// Directory helpers
|
|
5591
5593
|
// -----------------
|
|
@@ -5617,63 +5619,63 @@ var init_esm2 = __esm({
|
|
|
5617
5619
|
* @param item base path of item/directory
|
|
5618
5620
|
*/
|
|
5619
5621
|
_remove(directory, item, isDirectory) {
|
|
5620
|
-
const
|
|
5621
|
-
const fullPath = sysPath2.resolve(
|
|
5622
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
5623
|
-
if (!this._throttle("remove",
|
|
5622
|
+
const path32 = sysPath2.join(directory, item);
|
|
5623
|
+
const fullPath = sysPath2.resolve(path32);
|
|
5624
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path32) || this._watched.has(fullPath);
|
|
5625
|
+
if (!this._throttle("remove", path32, 100))
|
|
5624
5626
|
return;
|
|
5625
5627
|
if (!isDirectory && this._watched.size === 1) {
|
|
5626
5628
|
this.add(directory, item, true);
|
|
5627
5629
|
}
|
|
5628
|
-
const wp = this._getWatchedDir(
|
|
5630
|
+
const wp = this._getWatchedDir(path32);
|
|
5629
5631
|
const nestedDirectoryChildren = wp.getChildren();
|
|
5630
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
5632
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path32, nested));
|
|
5631
5633
|
const parent = this._getWatchedDir(directory);
|
|
5632
5634
|
const wasTracked = parent.has(item);
|
|
5633
5635
|
parent.remove(item);
|
|
5634
5636
|
if (this._symlinkPaths.has(fullPath)) {
|
|
5635
5637
|
this._symlinkPaths.delete(fullPath);
|
|
5636
5638
|
}
|
|
5637
|
-
let relPath =
|
|
5639
|
+
let relPath = path32;
|
|
5638
5640
|
if (this.options.cwd)
|
|
5639
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
5641
|
+
relPath = sysPath2.relative(this.options.cwd, path32);
|
|
5640
5642
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
5641
5643
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
5642
5644
|
if (event === EVENTS.ADD)
|
|
5643
5645
|
return;
|
|
5644
5646
|
}
|
|
5645
|
-
this._watched.delete(
|
|
5647
|
+
this._watched.delete(path32);
|
|
5646
5648
|
this._watched.delete(fullPath);
|
|
5647
5649
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
5648
|
-
if (wasTracked && !this._isIgnored(
|
|
5649
|
-
this._emit(eventName,
|
|
5650
|
-
this._closePath(
|
|
5650
|
+
if (wasTracked && !this._isIgnored(path32))
|
|
5651
|
+
this._emit(eventName, path32);
|
|
5652
|
+
this._closePath(path32);
|
|
5651
5653
|
}
|
|
5652
5654
|
/**
|
|
5653
5655
|
* Closes all watchers for a path
|
|
5654
5656
|
*/
|
|
5655
|
-
_closePath(
|
|
5656
|
-
this._closeFile(
|
|
5657
|
-
const dir = sysPath2.dirname(
|
|
5658
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
5657
|
+
_closePath(path32) {
|
|
5658
|
+
this._closeFile(path32);
|
|
5659
|
+
const dir = sysPath2.dirname(path32);
|
|
5660
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path32));
|
|
5659
5661
|
}
|
|
5660
5662
|
/**
|
|
5661
5663
|
* Closes only file-specific watchers
|
|
5662
5664
|
*/
|
|
5663
|
-
_closeFile(
|
|
5664
|
-
const closers = this._closers.get(
|
|
5665
|
+
_closeFile(path32) {
|
|
5666
|
+
const closers = this._closers.get(path32);
|
|
5665
5667
|
if (!closers)
|
|
5666
5668
|
return;
|
|
5667
5669
|
closers.forEach((closer) => closer());
|
|
5668
|
-
this._closers.delete(
|
|
5670
|
+
this._closers.delete(path32);
|
|
5669
5671
|
}
|
|
5670
|
-
_addPathCloser(
|
|
5672
|
+
_addPathCloser(path32, closer) {
|
|
5671
5673
|
if (!closer)
|
|
5672
5674
|
return;
|
|
5673
|
-
let list = this._closers.get(
|
|
5675
|
+
let list = this._closers.get(path32);
|
|
5674
5676
|
if (!list) {
|
|
5675
5677
|
list = [];
|
|
5676
|
-
this._closers.set(
|
|
5678
|
+
this._closers.set(path32, list);
|
|
5677
5679
|
}
|
|
5678
5680
|
list.push(closer);
|
|
5679
5681
|
}
|
|
@@ -5918,18 +5920,18 @@ function getWsIndex(routes) {
|
|
|
5918
5920
|
wsIndexCache.set(routes, index);
|
|
5919
5921
|
return index;
|
|
5920
5922
|
}
|
|
5921
|
-
function matchRoute(routes, method,
|
|
5923
|
+
function matchRoute(routes, method, path32) {
|
|
5922
5924
|
const index = getHttpIndex(routes);
|
|
5923
5925
|
const upper = method.toUpperCase();
|
|
5924
|
-
const hit = matchByMethod(index, upper,
|
|
5926
|
+
const hit = matchByMethod(index, upper, path32);
|
|
5925
5927
|
if (hit) return hit;
|
|
5926
5928
|
if (upper === "HEAD") {
|
|
5927
|
-
return matchByMethod(index, "GET",
|
|
5929
|
+
return matchByMethod(index, "GET", path32);
|
|
5928
5930
|
}
|
|
5929
5931
|
return null;
|
|
5930
5932
|
}
|
|
5931
|
-
function matchByMethod(index, method,
|
|
5932
|
-
const staticHit = index.static.get(`${method}|${
|
|
5933
|
+
function matchByMethod(index, method, path32) {
|
|
5934
|
+
const staticHit = index.static.get(`${method}|${path32}`);
|
|
5933
5935
|
if (staticHit) {
|
|
5934
5936
|
return { route: staticHit, params: {} };
|
|
5935
5937
|
}
|
|
@@ -5938,31 +5940,31 @@ function matchByMethod(index, method, path31) {
|
|
|
5938
5940
|
if (route.method !== method) {
|
|
5939
5941
|
continue;
|
|
5940
5942
|
}
|
|
5941
|
-
const params = matchSegments(entry.segments,
|
|
5943
|
+
const params = matchSegments(entry.segments, path32, route.paramNames, route.isCatchAll);
|
|
5942
5944
|
if (params !== null) {
|
|
5943
5945
|
return { route, params };
|
|
5944
5946
|
}
|
|
5945
5947
|
}
|
|
5946
5948
|
return null;
|
|
5947
5949
|
}
|
|
5948
|
-
function matchWsRoute(wsRoutes,
|
|
5950
|
+
function matchWsRoute(wsRoutes, path32) {
|
|
5949
5951
|
const index = getWsIndex(wsRoutes);
|
|
5950
|
-
const staticHit = index.static.get(
|
|
5952
|
+
const staticHit = index.static.get(path32);
|
|
5951
5953
|
if (staticHit) {
|
|
5952
5954
|
return { route: staticHit, params: {} };
|
|
5953
5955
|
}
|
|
5954
5956
|
for (const route of index.dynamics) {
|
|
5955
|
-
const params = matchDynamicPath(route.urlPath,
|
|
5957
|
+
const params = matchDynamicPath(route.urlPath, path32, route.paramNames, route.isCatchAll);
|
|
5956
5958
|
if (params !== null) {
|
|
5957
5959
|
return { route, params };
|
|
5958
5960
|
}
|
|
5959
5961
|
}
|
|
5960
5962
|
return null;
|
|
5961
5963
|
}
|
|
5962
|
-
function findAllowedMethods(routes,
|
|
5964
|
+
function findAllowedMethods(routes, path32) {
|
|
5963
5965
|
const index = getHttpIndex(routes);
|
|
5964
5966
|
const methods = /* @__PURE__ */ new Set();
|
|
5965
|
-
const staticMethods = index.methodsByStaticPath.get(
|
|
5967
|
+
const staticMethods = index.methodsByStaticPath.get(path32);
|
|
5966
5968
|
if (staticMethods) {
|
|
5967
5969
|
for (const method of staticMethods) {
|
|
5968
5970
|
methods.add(method);
|
|
@@ -5971,7 +5973,7 @@ function findAllowedMethods(routes, path31) {
|
|
|
5971
5973
|
for (const entry of index.dynamics) {
|
|
5972
5974
|
const params = matchSegments(
|
|
5973
5975
|
entry.segments,
|
|
5974
|
-
|
|
5976
|
+
path32,
|
|
5975
5977
|
entry.route.paramNames,
|
|
5976
5978
|
entry.route.isCatchAll
|
|
5977
5979
|
);
|
|
@@ -5984,11 +5986,11 @@ function findAllowedMethods(routes, path31) {
|
|
|
5984
5986
|
}
|
|
5985
5987
|
return Array.from(methods);
|
|
5986
5988
|
}
|
|
5987
|
-
function matchDynamicPath(pattern,
|
|
5988
|
-
return matchSegments(pattern.split("/").filter(Boolean),
|
|
5989
|
+
function matchDynamicPath(pattern, path32, paramNames, isCatchAll) {
|
|
5990
|
+
return matchSegments(pattern.split("/").filter(Boolean), path32, paramNames, isCatchAll);
|
|
5989
5991
|
}
|
|
5990
|
-
function matchSegments(patternSegments,
|
|
5991
|
-
const pathSegments =
|
|
5992
|
+
function matchSegments(patternSegments, path32, paramNames, isCatchAll) {
|
|
5993
|
+
const pathSegments = path32.split("/").filter(Boolean);
|
|
5992
5994
|
if (isCatchAll) {
|
|
5993
5995
|
const nonCatchAllCount = patternSegments.length - 1;
|
|
5994
5996
|
if (pathSegments.length <= nonCatchAllCount) {
|
|
@@ -6261,14 +6263,14 @@ var init_httpErrors = __esm({
|
|
|
6261
6263
|
issues;
|
|
6262
6264
|
};
|
|
6263
6265
|
RouteNotFoundError = class extends FaapiError {
|
|
6264
|
-
constructor(
|
|
6265
|
-
super("ROUTE_NOT_FOUND", `Route not found: ${
|
|
6266
|
+
constructor(path32) {
|
|
6267
|
+
super("ROUTE_NOT_FOUND", `Route not found: ${path32}`, 404);
|
|
6266
6268
|
this.name = "RouteNotFoundError";
|
|
6267
6269
|
}
|
|
6268
6270
|
};
|
|
6269
6271
|
MethodNotAllowedError = class extends FaapiError {
|
|
6270
|
-
constructor(method,
|
|
6271
|
-
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${
|
|
6272
|
+
constructor(method, path32, allowedMethods) {
|
|
6273
|
+
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path32}`, 405);
|
|
6272
6274
|
this.allowedMethods = allowedMethods;
|
|
6273
6275
|
this.name = "MethodNotAllowedError";
|
|
6274
6276
|
}
|
|
@@ -6386,7 +6388,228 @@ var init_responseFormatter = __esm({
|
|
|
6386
6388
|
}
|
|
6387
6389
|
});
|
|
6388
6390
|
|
|
6391
|
+
// src/logger/formatEntry.ts
|
|
6392
|
+
function serializeFieldValue(value) {
|
|
6393
|
+
if (value instanceof Error) {
|
|
6394
|
+
return { name: value.name, message: value.message, stack: value.stack };
|
|
6395
|
+
}
|
|
6396
|
+
return value;
|
|
6397
|
+
}
|
|
6398
|
+
function formatEntry(entry) {
|
|
6399
|
+
let line = `[${entry.time}] ${entry.level.toUpperCase()} `;
|
|
6400
|
+
if (entry.scope) line += `[${entry.scope}] `;
|
|
6401
|
+
line += entry.message;
|
|
6402
|
+
if (entry.fields !== void 0) {
|
|
6403
|
+
const plain = Object.fromEntries(
|
|
6404
|
+
Object.entries(entry.fields).map(([k, v]) => [k, serializeFieldValue(v)])
|
|
6405
|
+
);
|
|
6406
|
+
try {
|
|
6407
|
+
line += ` ${JSON.stringify(plain)}`;
|
|
6408
|
+
} catch (err) {
|
|
6409
|
+
line += ` [unserializable fields: ${err instanceof Error ? err.message : String(err)}]`;
|
|
6410
|
+
}
|
|
6411
|
+
}
|
|
6412
|
+
return line;
|
|
6413
|
+
}
|
|
6414
|
+
var init_formatEntry = __esm({
|
|
6415
|
+
"src/logger/formatEntry.ts"() {
|
|
6416
|
+
"use strict";
|
|
6417
|
+
}
|
|
6418
|
+
});
|
|
6419
|
+
|
|
6420
|
+
// src/logger/fileSink.ts
|
|
6421
|
+
import fs17 from "fs";
|
|
6422
|
+
import path23 from "path";
|
|
6423
|
+
function createFileLogSink(options) {
|
|
6424
|
+
fs17.mkdirSync(options.dir, { recursive: true });
|
|
6425
|
+
const streams = /* @__PURE__ */ new Map();
|
|
6426
|
+
const getStream = (name) => {
|
|
6427
|
+
if (streams.has(name)) return streams.get(name);
|
|
6428
|
+
return void 0;
|
|
6429
|
+
};
|
|
6430
|
+
const openStream = (name) => {
|
|
6431
|
+
const stream = fs17.createWriteStream(path23.join(options.dir, `${name}.log`), { flags: "a" });
|
|
6432
|
+
stream.on("error", () => {
|
|
6433
|
+
});
|
|
6434
|
+
streams.set(name, stream);
|
|
6435
|
+
};
|
|
6436
|
+
const fileNames = options.splitByLevel ? [...LEVEL_FILES] : ["app", "error"];
|
|
6437
|
+
for (const name of fileNames) openStream(name);
|
|
6438
|
+
let pendingCount = 0;
|
|
6439
|
+
let drainWaiters = [];
|
|
6440
|
+
const onWriteDone = () => {
|
|
6441
|
+
pendingCount--;
|
|
6442
|
+
if (pendingCount === 0 && drainWaiters.length > 0) {
|
|
6443
|
+
const waiters = drainWaiters;
|
|
6444
|
+
drainWaiters = [];
|
|
6445
|
+
for (const waiter of waiters) waiter();
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6448
|
+
const write = (entry) => {
|
|
6449
|
+
const line = `${formatEntry(entry)}
|
|
6450
|
+
`;
|
|
6451
|
+
const target = options.splitByLevel ? entry.level : "app";
|
|
6452
|
+
const main = getStream(target);
|
|
6453
|
+
if (main) {
|
|
6454
|
+
pendingCount++;
|
|
6455
|
+
main.write(line, onWriteDone);
|
|
6456
|
+
}
|
|
6457
|
+
if (!options.splitByLevel && entry.level === "error") {
|
|
6458
|
+
const dup = getStream("error");
|
|
6459
|
+
if (dup) {
|
|
6460
|
+
pendingCount++;
|
|
6461
|
+
dup.write(line, onWriteDone);
|
|
6462
|
+
}
|
|
6463
|
+
}
|
|
6464
|
+
};
|
|
6465
|
+
const flush = () => new Promise((resolve3) => {
|
|
6466
|
+
if (pendingCount === 0) {
|
|
6467
|
+
resolve3();
|
|
6468
|
+
return;
|
|
6469
|
+
}
|
|
6470
|
+
drainWaiters.push(resolve3);
|
|
6471
|
+
});
|
|
6472
|
+
const close = () => Promise.all(
|
|
6473
|
+
[...streams.values()].map(
|
|
6474
|
+
(stream) => new Promise((resolve3) => {
|
|
6475
|
+
stream.end(() => resolve3());
|
|
6476
|
+
})
|
|
6477
|
+
)
|
|
6478
|
+
).then(() => {
|
|
6479
|
+
streams.clear();
|
|
6480
|
+
});
|
|
6481
|
+
return { write, flush, close };
|
|
6482
|
+
}
|
|
6483
|
+
var LEVEL_FILES;
|
|
6484
|
+
var init_fileSink = __esm({
|
|
6485
|
+
"src/logger/fileSink.ts"() {
|
|
6486
|
+
"use strict";
|
|
6487
|
+
init_formatEntry();
|
|
6488
|
+
LEVEL_FILES = ["debug", "info", "warn", "error"];
|
|
6489
|
+
}
|
|
6490
|
+
});
|
|
6491
|
+
|
|
6492
|
+
// src/logger/logger.ts
|
|
6493
|
+
function assertLogLevel(value, source) {
|
|
6494
|
+
if (typeof value !== "string" || !VALID_LEVELS.includes(value)) {
|
|
6495
|
+
throw new Error(
|
|
6496
|
+
`[faapi] Invalid log level from ${source}: ${String(value)}. Expected one of: ${VALID_LEVELS.join(", ")}.`
|
|
6497
|
+
);
|
|
6498
|
+
}
|
|
6499
|
+
}
|
|
6500
|
+
function configureLogging(config) {
|
|
6501
|
+
const objectConfig = typeof config === "object" ? config : {};
|
|
6502
|
+
if (objectConfig.sink && objectConfig.dir) {
|
|
6503
|
+
throw new Error(
|
|
6504
|
+
"[faapi] config.log.sink and config.log.dir are mutually exclusive: pick one output pipeline (custom sink OR built-in file logs)."
|
|
6505
|
+
);
|
|
6506
|
+
}
|
|
6507
|
+
void globalState.fileSink?.close();
|
|
6508
|
+
globalState.disabled = config === false;
|
|
6509
|
+
globalState.sink = objectConfig.sink ?? null;
|
|
6510
|
+
globalState.accessLog = objectConfig.accessLog ?? objectConfig.dir !== void 0;
|
|
6511
|
+
globalState.stdout = objectConfig.stdout ?? true;
|
|
6512
|
+
globalState.fileSink = objectConfig.dir ? createFileLogSink({ dir: objectConfig.dir, splitByLevel: objectConfig.splitByLevel }) : null;
|
|
6513
|
+
if (objectConfig.level !== void 0) {
|
|
6514
|
+
assertLogLevel(objectConfig.level, "config.log.level");
|
|
6515
|
+
globalState.level = objectConfig.level;
|
|
6516
|
+
} else if (process.env.LOG_LEVEL !== void 0) {
|
|
6517
|
+
assertLogLevel(process.env.LOG_LEVEL, "LOG_LEVEL env");
|
|
6518
|
+
globalState.level = process.env.LOG_LEVEL;
|
|
6519
|
+
} else {
|
|
6520
|
+
globalState.level = null;
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6523
|
+
function globalThreshold() {
|
|
6524
|
+
if (globalState.level) return globalState.level;
|
|
6525
|
+
if (globalState.fileSink) return void 0;
|
|
6526
|
+
return "info";
|
|
6527
|
+
}
|
|
6528
|
+
function belowThreshold(level, threshold) {
|
|
6529
|
+
return threshold !== void 0 && LEVEL_RANK[level] < LEVEL_RANK[threshold];
|
|
6530
|
+
}
|
|
6531
|
+
function getEffectiveLogLevel() {
|
|
6532
|
+
return globalThreshold();
|
|
6533
|
+
}
|
|
6534
|
+
function globalDispatch(entry) {
|
|
6535
|
+
if (globalState.disabled) return;
|
|
6536
|
+
if (globalState.sink) {
|
|
6537
|
+
globalState.sink(entry);
|
|
6538
|
+
return;
|
|
6539
|
+
}
|
|
6540
|
+
if (globalState.fileSink) {
|
|
6541
|
+
globalState.fileSink.write(entry);
|
|
6542
|
+
if (globalState.stdout) consoleSink(entry);
|
|
6543
|
+
return;
|
|
6544
|
+
}
|
|
6545
|
+
consoleSink(entry);
|
|
6546
|
+
}
|
|
6547
|
+
function writeLogEntry(entry) {
|
|
6548
|
+
if (belowThreshold(entry.level, globalThreshold())) return;
|
|
6549
|
+
globalDispatch(entry);
|
|
6550
|
+
}
|
|
6551
|
+
function isAccessLogPiped() {
|
|
6552
|
+
return !globalState.disabled && globalState.accessLog;
|
|
6553
|
+
}
|
|
6554
|
+
function createLogger(scope, options) {
|
|
6555
|
+
const baseScope = scope;
|
|
6556
|
+
const baseFields = options?.fields;
|
|
6557
|
+
const write = (level, message, callFields, scopeSuffix) => {
|
|
6558
|
+
const threshold = options?.level ?? globalThreshold();
|
|
6559
|
+
if (belowThreshold(level, threshold)) return;
|
|
6560
|
+
const entry = {
|
|
6561
|
+
level,
|
|
6562
|
+
message,
|
|
6563
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
6564
|
+
};
|
|
6565
|
+
const fullScope = scopeSuffix === void 0 ? baseScope : baseScope === void 0 ? scopeSuffix : `${baseScope}:${scopeSuffix}`;
|
|
6566
|
+
if (fullScope !== void 0) entry.scope = fullScope;
|
|
6567
|
+
if (baseFields !== void 0 || callFields !== void 0) {
|
|
6568
|
+
entry.fields = { ...baseFields, ...callFields };
|
|
6569
|
+
}
|
|
6570
|
+
if (options?.sink) {
|
|
6571
|
+
options.sink(entry);
|
|
6572
|
+
} else {
|
|
6573
|
+
globalDispatch(entry);
|
|
6574
|
+
}
|
|
6575
|
+
};
|
|
6576
|
+
const makeLogger = (scopeSuffix) => ({
|
|
6577
|
+
debug: (message, fields) => write("debug", message, fields, scopeSuffix),
|
|
6578
|
+
info: (message, fields) => write("info", message, fields, scopeSuffix),
|
|
6579
|
+
warn: (message, fields) => write("warn", message, fields, scopeSuffix),
|
|
6580
|
+
error: (message, fields) => write("error", message, fields, scopeSuffix),
|
|
6581
|
+
child: (childScope) => makeLogger(scopeSuffix === void 0 ? childScope : `${scopeSuffix}:${childScope}`)
|
|
6582
|
+
});
|
|
6583
|
+
return makeLogger(void 0);
|
|
6584
|
+
}
|
|
6585
|
+
var LEVEL_RANK, VALID_LEVELS, globalState, consoleSink, CONSOLE_METHOD;
|
|
6586
|
+
var init_logger = __esm({
|
|
6587
|
+
"src/logger/logger.ts"() {
|
|
6588
|
+
"use strict";
|
|
6589
|
+
init_formatEntry();
|
|
6590
|
+
init_fileSink();
|
|
6591
|
+
LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
6592
|
+
VALID_LEVELS = ["debug", "info", "warn", "error"];
|
|
6593
|
+
globalState = { level: null, sink: null, fileSink: null, stdout: true, accessLog: false, disabled: false };
|
|
6594
|
+
consoleSink = (entry) => {
|
|
6595
|
+
console[CONSOLE_METHOD[entry.level]](formatEntry(entry));
|
|
6596
|
+
};
|
|
6597
|
+
CONSOLE_METHOD = {
|
|
6598
|
+
debug: "debug",
|
|
6599
|
+
info: "info",
|
|
6600
|
+
warn: "warn",
|
|
6601
|
+
error: "error"
|
|
6602
|
+
};
|
|
6603
|
+
}
|
|
6604
|
+
});
|
|
6605
|
+
|
|
6389
6606
|
// src/runtime/createContext.ts
|
|
6607
|
+
function resolveRequestId(request) {
|
|
6608
|
+
const header = request.headers.get("x-request-id");
|
|
6609
|
+
const first = header?.split(",")[0]?.trim();
|
|
6610
|
+
if (first) return first;
|
|
6611
|
+
return crypto.randomUUID();
|
|
6612
|
+
}
|
|
6390
6613
|
function parseCookies(cookieHeader) {
|
|
6391
6614
|
const cookies = /* @__PURE__ */ new Map();
|
|
6392
6615
|
if (!cookieHeader) return cookies;
|
|
@@ -6420,7 +6643,13 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
|
|
|
6420
6643
|
for (const [key, val] of parsedCookies) {
|
|
6421
6644
|
cookiesObj[key] = val;
|
|
6422
6645
|
}
|
|
6646
|
+
const requestId = resolveRequestId(request);
|
|
6647
|
+
const log = createLogger("http", {
|
|
6648
|
+
fields: { requestId, method: request.method, path: url.pathname }
|
|
6649
|
+
});
|
|
6423
6650
|
const ctx = {
|
|
6651
|
+
requestId,
|
|
6652
|
+
log,
|
|
6424
6653
|
request,
|
|
6425
6654
|
params,
|
|
6426
6655
|
query: url.searchParams,
|
|
@@ -6525,6 +6754,7 @@ var init_createContext = __esm({
|
|
|
6525
6754
|
"use strict";
|
|
6526
6755
|
init_sse();
|
|
6527
6756
|
init_responseFormatter();
|
|
6757
|
+
init_logger();
|
|
6528
6758
|
}
|
|
6529
6759
|
});
|
|
6530
6760
|
|
|
@@ -7092,6 +7322,9 @@ function getBuiltinInjectionValue(type, ctx, body) {
|
|
|
7092
7322
|
// 任务子系统:注入 TaskClient(入队/查询);未注册工厂(无 app 编排)时 undefined
|
|
7093
7323
|
case "tasks":
|
|
7094
7324
|
return ctx.registries ? ctx.registries.taskHandle.get(ctx) : void 0;
|
|
7325
|
+
// 请求级日志器:与 ctx.log 同一实例(scope http,自动带 requestId/method/path 字段)
|
|
7326
|
+
case "log":
|
|
7327
|
+
return ctx.log;
|
|
7095
7328
|
default:
|
|
7096
7329
|
return void 0;
|
|
7097
7330
|
}
|
|
@@ -7308,9 +7541,9 @@ async function validateInput(schemaPath, method, inputType, input) {
|
|
|
7308
7541
|
function mapZodIssues(error) {
|
|
7309
7542
|
return error.issues.map((issue) => {
|
|
7310
7543
|
const code = mapZodCode(issue);
|
|
7311
|
-
const
|
|
7544
|
+
const path32 = issue.path.map(String).join(".") || "";
|
|
7312
7545
|
return {
|
|
7313
|
-
path:
|
|
7546
|
+
path: path32,
|
|
7314
7547
|
code,
|
|
7315
7548
|
expected: issue.expected ?? mapExpectedFromMessage(issue.message),
|
|
7316
7549
|
received: issue.received ?? mapReceivedFromMessage(issue.message),
|
|
@@ -7708,14 +7941,34 @@ var init_etag = __esm({
|
|
|
7708
7941
|
});
|
|
7709
7942
|
|
|
7710
7943
|
// src/middleware/logger.ts
|
|
7944
|
+
function levelForStatus(status) {
|
|
7945
|
+
if (status >= 500) return "error";
|
|
7946
|
+
if (status >= 400) return "warn";
|
|
7947
|
+
return "info";
|
|
7948
|
+
}
|
|
7949
|
+
function defaultLog(entry, text) {
|
|
7950
|
+
if (isAccessLogPiped()) {
|
|
7951
|
+
const logEntry = {
|
|
7952
|
+
level: levelForStatus(entry.status),
|
|
7953
|
+
message: text,
|
|
7954
|
+
time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7955
|
+
scope: "access",
|
|
7956
|
+
fields: entry
|
|
7957
|
+
};
|
|
7958
|
+
writeLogEntry(logEntry);
|
|
7959
|
+
return;
|
|
7960
|
+
}
|
|
7961
|
+
console.log(entry);
|
|
7962
|
+
}
|
|
7711
7963
|
function logger(options = {}) {
|
|
7712
7964
|
return async (ctx, next) => {
|
|
7713
|
-
const log = options.log ??
|
|
7965
|
+
const log = options.log ?? defaultLog;
|
|
7714
7966
|
const start = Date.now();
|
|
7715
7967
|
try {
|
|
7716
7968
|
const response = await next();
|
|
7717
7969
|
const duration = Date.now() - start;
|
|
7718
7970
|
const entry = {
|
|
7971
|
+
requestId: ctx.requestId,
|
|
7719
7972
|
method: ctx.method,
|
|
7720
7973
|
path: ctx.path,
|
|
7721
7974
|
status: response.status,
|
|
@@ -7728,6 +7981,7 @@ function logger(options = {}) {
|
|
|
7728
7981
|
const message = err instanceof Error ? err.message : String(err);
|
|
7729
7982
|
const status = err?.statusCode ?? 500;
|
|
7730
7983
|
const entry = {
|
|
7984
|
+
requestId: ctx.requestId,
|
|
7731
7985
|
method: ctx.method,
|
|
7732
7986
|
path: ctx.path,
|
|
7733
7987
|
status,
|
|
@@ -7739,9 +7993,10 @@ function logger(options = {}) {
|
|
|
7739
7993
|
}
|
|
7740
7994
|
};
|
|
7741
7995
|
}
|
|
7742
|
-
var
|
|
7996
|
+
var init_logger2 = __esm({
|
|
7743
7997
|
"src/middleware/logger.ts"() {
|
|
7744
7998
|
"use strict";
|
|
7999
|
+
init_logger();
|
|
7745
8000
|
}
|
|
7746
8001
|
});
|
|
7747
8002
|
|
|
@@ -7808,9 +8063,9 @@ var init_wsHandler = __esm({
|
|
|
7808
8063
|
});
|
|
7809
8064
|
|
|
7810
8065
|
// src/server/handleWsUpgrade.ts
|
|
7811
|
-
import
|
|
8066
|
+
import fs18 from "fs";
|
|
7812
8067
|
import { WebSocketServer, WebSocket } from "ws";
|
|
7813
|
-
import
|
|
8068
|
+
import path24 from "path";
|
|
7814
8069
|
function getPathname(req) {
|
|
7815
8070
|
const url = req.url ?? "/";
|
|
7816
8071
|
const idx = url.indexOf("?");
|
|
@@ -7821,7 +8076,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
|
|
|
7821
8076
|
const dist = getDevDist();
|
|
7822
8077
|
if (dist) {
|
|
7823
8078
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
7824
|
-
if (sourcePath &&
|
|
8079
|
+
if (sourcePath && fs18.existsSync(sourcePath)) {
|
|
7825
8080
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
7826
8081
|
}
|
|
7827
8082
|
}
|
|
@@ -7935,7 +8190,7 @@ function attachWebSocket(options) {
|
|
|
7935
8190
|
const finalHandler = async () => {
|
|
7936
8191
|
let handlers;
|
|
7937
8192
|
try {
|
|
7938
|
-
const absoluteFilePath =
|
|
8193
|
+
const absoluteFilePath = path24.resolve(rootDir, route.filePath);
|
|
7939
8194
|
handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
|
|
7940
8195
|
} catch (err) {
|
|
7941
8196
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -8011,7 +8266,7 @@ import {
|
|
|
8011
8266
|
import { createSecureServer as createHttp2SecureServer } from "http2";
|
|
8012
8267
|
import { readFileSync } from "fs";
|
|
8013
8268
|
import { Readable as Readable3 } from "stream";
|
|
8014
|
-
import
|
|
8269
|
+
import path25 from "path";
|
|
8015
8270
|
function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT, requestSignal) {
|
|
8016
8271
|
const forwardedProto = req.headers["x-forwarded-proto"];
|
|
8017
8272
|
const protocol = Array.isArray(forwardedProto) ? forwardedProto[0]?.split(",")[0]?.trim() ?? "http" : forwardedProto?.split(",")[0]?.trim() ?? "http";
|
|
@@ -8207,7 +8462,7 @@ function getRoutePaths(route, rootDir, dist) {
|
|
|
8207
8462
|
let cached = routePathCache.get(route);
|
|
8208
8463
|
if (!cached) {
|
|
8209
8464
|
cached = {
|
|
8210
|
-
absFilePath:
|
|
8465
|
+
absFilePath: path25.resolve(rootDir, route.filePath),
|
|
8211
8466
|
schemaPath: getRuntimeSchemaPath(route.filePath, dist, rootDir)
|
|
8212
8467
|
};
|
|
8213
8468
|
routePathCache.set(route, cached);
|
|
@@ -8317,7 +8572,7 @@ var init_createServer = __esm({
|
|
|
8317
8572
|
init_helmet();
|
|
8318
8573
|
init_compression();
|
|
8319
8574
|
init_etag();
|
|
8320
|
-
|
|
8575
|
+
init_logger2();
|
|
8321
8576
|
init_handleWsUpgrade();
|
|
8322
8577
|
init_serverUtils();
|
|
8323
8578
|
init_generateSchemaFiles();
|
|
@@ -8386,6 +8641,8 @@ ${BUILD_VIEW_SOURCE}
|
|
|
8386
8641
|
|
|
8387
8642
|
${SERIALIZE_ERROR_SOURCE}
|
|
8388
8643
|
|
|
8644
|
+
${BUILD_LOGGER_SOURCE}
|
|
8645
|
+
|
|
8389
8646
|
const run = mod.run;
|
|
8390
8647
|
if (typeof run !== 'function') {
|
|
8391
8648
|
parentPort.postMessage({
|
|
@@ -8405,7 +8662,8 @@ if (typeof run !== 'function') {
|
|
|
8405
8662
|
try {
|
|
8406
8663
|
const registries = buildRegistriesView(msg.registries);
|
|
8407
8664
|
const progress = (value) => parentPort.postMessage({ type: 'progress', value });
|
|
8408
|
-
const
|
|
8665
|
+
const taskLog = msg.log ? createTaskLogger(msg.log.level, msg.log.scope, msg.log.fields) : undefined;
|
|
8666
|
+
const result = await run(payload, { ...taskCtx, signal: controller.signal, registries, progress, log: taskLog });
|
|
8409
8667
|
parentPort.postMessage({ type: 'done', result });
|
|
8410
8668
|
} catch (err) {
|
|
8411
8669
|
const serialized = serializeError(err);
|
|
@@ -8513,6 +8771,8 @@ async function runTaskInWorker(options) {
|
|
|
8513
8771
|
finish(() => reject(reviveError(msg.error)));
|
|
8514
8772
|
} else if (msg?.type === "progress") {
|
|
8515
8773
|
options.onProgress?.(msg.value);
|
|
8774
|
+
} else if (msg?.type === "log") {
|
|
8775
|
+
options.onLog?.(msg.entry);
|
|
8516
8776
|
}
|
|
8517
8777
|
}
|
|
8518
8778
|
);
|
|
@@ -8536,7 +8796,8 @@ async function runTaskInWorker(options) {
|
|
|
8536
8796
|
type: "run",
|
|
8537
8797
|
payload,
|
|
8538
8798
|
taskCtx: { config: safeConfig(taskCtx.config), job: taskCtx.job },
|
|
8539
|
-
registries: options.registries
|
|
8799
|
+
registries: options.registries,
|
|
8800
|
+
log: options.log
|
|
8540
8801
|
});
|
|
8541
8802
|
} catch (err) {
|
|
8542
8803
|
finish(
|
|
@@ -8547,7 +8808,7 @@ async function runTaskInWorker(options) {
|
|
|
8547
8808
|
}
|
|
8548
8809
|
});
|
|
8549
8810
|
}
|
|
8550
|
-
var KILL_GRACE_MS, TaskCancelledError, BUILD_VIEW_SOURCE, SERIALIZE_ERROR_SOURCE;
|
|
8811
|
+
var KILL_GRACE_MS, TaskCancelledError, BUILD_VIEW_SOURCE, SERIALIZE_ERROR_SOURCE, BUILD_LOGGER_SOURCE;
|
|
8551
8812
|
var init_taskWorker = __esm({
|
|
8552
8813
|
"src/task/taskWorker.ts"() {
|
|
8553
8814
|
"use strict";
|
|
@@ -8625,12 +8886,42 @@ function serializeError(err) {
|
|
|
8625
8886
|
}
|
|
8626
8887
|
return { name: 'Error', message: String(err), stack: undefined, props: {} };
|
|
8627
8888
|
}
|
|
8889
|
+
`;
|
|
8890
|
+
BUILD_LOGGER_SOURCE = `
|
|
8891
|
+
var LOG_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
8892
|
+
function createTaskLogger(level, scope, fields) {
|
|
8893
|
+
function make(suffix) {
|
|
8894
|
+
function write(lvl, message, callFields) {
|
|
8895
|
+
if (level !== undefined && LOG_RANK[lvl] < LOG_RANK[level]) return;
|
|
8896
|
+
var entry = { level: lvl, message: message, time: new Date().toISOString() };
|
|
8897
|
+
var fullScope = suffix === undefined ? scope : scope === undefined ? suffix : scope + ':' + suffix;
|
|
8898
|
+
if (fullScope !== undefined) entry.scope = fullScope;
|
|
8899
|
+
if (fields !== undefined || callFields !== undefined) {
|
|
8900
|
+
entry.fields = Object.assign({}, fields, callFields);
|
|
8901
|
+
}
|
|
8902
|
+
try {
|
|
8903
|
+
parentPort.postMessage({ type: 'log', entry: entry });
|
|
8904
|
+
} catch (_) {
|
|
8905
|
+
entry.fields = { warning: 'log fields not cloneable across worker boundary, dropped' };
|
|
8906
|
+
parentPort.postMessage({ type: 'log', entry: entry });
|
|
8907
|
+
}
|
|
8908
|
+
}
|
|
8909
|
+
return {
|
|
8910
|
+
debug: function (m, f) { write('debug', m, f); },
|
|
8911
|
+
info: function (m, f) { write('info', m, f); },
|
|
8912
|
+
warn: function (m, f) { write('warn', m, f); },
|
|
8913
|
+
error: function (m, f) { write('error', m, f); },
|
|
8914
|
+
child: function (cs) { return make(suffix === undefined ? cs : suffix + ':' + cs); },
|
|
8915
|
+
};
|
|
8916
|
+
}
|
|
8917
|
+
return make(undefined);
|
|
8918
|
+
}
|
|
8628
8919
|
`;
|
|
8629
8920
|
}
|
|
8630
8921
|
});
|
|
8631
8922
|
|
|
8632
8923
|
// src/task/taskQueue.ts
|
|
8633
|
-
import
|
|
8924
|
+
import path26 from "path";
|
|
8634
8925
|
function createTaskQueue(deps) {
|
|
8635
8926
|
const { registry, rootDir, driver } = deps;
|
|
8636
8927
|
const registriesView = deps.registries ?? createEmptyTaskRegistriesView();
|
|
@@ -8660,7 +8951,7 @@ function createTaskQueue(deps) {
|
|
|
8660
8951
|
}
|
|
8661
8952
|
const loadTaskModule = deps.loadTaskModule ?? (async (filePath) => await import(filePath));
|
|
8662
8953
|
const loadPayloadSchema = deps.loadPayloadSchema ?? (async (filePath) => {
|
|
8663
|
-
const zodPath =
|
|
8954
|
+
const zodPath = path26.join(path26.dirname(filePath), "zod.js");
|
|
8664
8955
|
try {
|
|
8665
8956
|
const mod = await import(zodPath);
|
|
8666
8957
|
const schemaKey = Object.keys(mod).find((k) => k.endsWith("Schema"));
|
|
@@ -8688,7 +8979,7 @@ function createTaskQueue(deps) {
|
|
|
8688
8979
|
const meta = registry.get(name);
|
|
8689
8980
|
schemaCache.set(
|
|
8690
8981
|
name,
|
|
8691
|
-
await loadPayloadSchema(
|
|
8982
|
+
await loadPayloadSchema(path26.resolve(rootDir, meta.filePath)).catch(() => void 0)
|
|
8692
8983
|
);
|
|
8693
8984
|
}
|
|
8694
8985
|
const schema = schemaCache.get(name);
|
|
@@ -8724,24 +9015,32 @@ function createTaskQueue(deps) {
|
|
|
8724
9015
|
let result;
|
|
8725
9016
|
if (meta.timeoutMs !== void 0 && meta.timeoutMs > 0) {
|
|
8726
9017
|
result = await (deps.runIsolated ?? runTaskInWorker)({
|
|
8727
|
-
taskModulePath:
|
|
9018
|
+
taskModulePath: path26.resolve(rootDir, meta.filePath),
|
|
8728
9019
|
payload: job.payload,
|
|
8729
9020
|
taskCtx: {
|
|
8730
9021
|
config: deps.config,
|
|
8731
9022
|
job: { id: job.id, name: job.name, attempt: job.attempt }
|
|
8732
9023
|
},
|
|
8733
9024
|
registries: snapshotRegistries(),
|
|
9025
|
+
// 日志配置随 workerData 下发(纯数据),worker 内联重建 taskCtx.log,
|
|
9026
|
+
// 条目回传宿主走统一管道(scope/fields 与进程内路径一致)
|
|
9027
|
+
log: {
|
|
9028
|
+
level: getEffectiveLogLevel(),
|
|
9029
|
+
scope: `task:${job.name}`,
|
|
9030
|
+
fields: { jobId: job.id, task: job.name, attempt: job.attempt }
|
|
9031
|
+
},
|
|
8734
9032
|
timeoutMs: meta.timeoutMs,
|
|
8735
9033
|
graceMs: meta.graceMs,
|
|
8736
9034
|
externalSignal: job.signal,
|
|
8737
9035
|
onProgress: (value) => {
|
|
8738
9036
|
if (record.status === "running") record.progress = value;
|
|
8739
|
-
}
|
|
9037
|
+
},
|
|
9038
|
+
onLog: writeLogEntry
|
|
8740
9039
|
});
|
|
8741
9040
|
} else {
|
|
8742
9041
|
let mod = moduleCache2.get(job.name);
|
|
8743
9042
|
if (!mod) {
|
|
8744
|
-
mod = await loadTaskModule(
|
|
9043
|
+
mod = await loadTaskModule(path26.resolve(rootDir, meta.filePath));
|
|
8745
9044
|
moduleCache2.set(job.name, mod);
|
|
8746
9045
|
}
|
|
8747
9046
|
if (typeof mod.run !== "function") {
|
|
@@ -8752,6 +9051,9 @@ function createTaskQueue(deps) {
|
|
|
8752
9051
|
config: deps.config,
|
|
8753
9052
|
job: { id: job.id, name: job.name, attempt: job.attempt },
|
|
8754
9053
|
registries: registriesView,
|
|
9054
|
+
log: createLogger(`task:${job.name}`, {
|
|
9055
|
+
fields: { jobId: job.id, task: job.name, attempt: job.attempt }
|
|
9056
|
+
}),
|
|
8755
9057
|
progress: (value) => {
|
|
8756
9058
|
if (record.status === "running") record.progress = value;
|
|
8757
9059
|
}
|
|
@@ -8906,6 +9208,7 @@ var init_taskQueue = __esm({
|
|
|
8906
9208
|
init_httpErrors();
|
|
8907
9209
|
init_taskWorker();
|
|
8908
9210
|
init_registries();
|
|
9211
|
+
init_logger();
|
|
8909
9212
|
TERMINAL_STATUSES = /* @__PURE__ */ new Set(["done", "failed", "cancelled"]);
|
|
8910
9213
|
MAX_FINISHED_RECORDS = 1e3;
|
|
8911
9214
|
}
|
|
@@ -9019,8 +9322,8 @@ var init_cronScheduler = __esm({
|
|
|
9019
9322
|
});
|
|
9020
9323
|
|
|
9021
9324
|
// src/cli/loadPlugins.ts
|
|
9022
|
-
import
|
|
9023
|
-
import
|
|
9325
|
+
import path27 from "path";
|
|
9326
|
+
import fs19 from "fs";
|
|
9024
9327
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
9025
9328
|
async function loadPlugins(declarations, ctx, rootDir, dist) {
|
|
9026
9329
|
const handlerWrappers = [];
|
|
@@ -9083,37 +9386,37 @@ async function loadPlugins(declarations, ctx, rootDir, dist) {
|
|
|
9083
9386
|
return { handlerWrappers, upgradeWrappers, failures };
|
|
9084
9387
|
}
|
|
9085
9388
|
function resolveLocalPluginSource(specifier, baseDir) {
|
|
9086
|
-
const base =
|
|
9087
|
-
if ((TS_EXTS.test(base) || JS_EXTS.test(base)) &&
|
|
9389
|
+
const base = path27.isAbsolute(specifier) ? specifier : path27.resolve(baseDir, specifier);
|
|
9390
|
+
if ((TS_EXTS.test(base) || JS_EXTS.test(base)) && fs19.existsSync(base)) return base;
|
|
9088
9391
|
for (const ext of [".ts", ".js"]) {
|
|
9089
|
-
if (
|
|
9392
|
+
if (fs19.existsSync(base + ext)) return base + ext;
|
|
9090
9393
|
}
|
|
9091
9394
|
for (const indexExt of ["/index.ts", "/index.js"]) {
|
|
9092
|
-
if (
|
|
9395
|
+
if (fs19.existsSync(base + indexExt)) return base + indexExt;
|
|
9093
9396
|
}
|
|
9094
9397
|
return null;
|
|
9095
9398
|
}
|
|
9096
9399
|
function mirrorProductPath(sourcePath, baseDir, distDir) {
|
|
9097
|
-
let rel =
|
|
9400
|
+
let rel = path27.relative(baseDir, sourcePath).replace(/\\/g, "/");
|
|
9098
9401
|
if (rel.startsWith("src/")) rel = rel.slice(4);
|
|
9099
|
-
return
|
|
9402
|
+
return path27.resolve(distDir, rel.replace(TS_EXTS, ".js"));
|
|
9100
9403
|
}
|
|
9101
9404
|
function isSourceNewer(sourcePath, productPath) {
|
|
9102
9405
|
try {
|
|
9103
|
-
return
|
|
9406
|
+
return fs19.statSync(sourcePath).mtimeMs > fs19.statSync(productPath).mtimeMs;
|
|
9104
9407
|
} catch {
|
|
9105
9408
|
return true;
|
|
9106
9409
|
}
|
|
9107
9410
|
}
|
|
9108
9411
|
async function importPluginModule(specifier, baseDir, dist) {
|
|
9109
9412
|
const isRelative = specifier.startsWith("./") || specifier.startsWith("../");
|
|
9110
|
-
if (!isRelative && !
|
|
9413
|
+
if (!isRelative && !path27.isAbsolute(specifier)) {
|
|
9111
9414
|
return import(specifier);
|
|
9112
9415
|
}
|
|
9113
|
-
const distDir = dist ?
|
|
9416
|
+
const distDir = dist ? path27.resolve(baseDir, dist) : null;
|
|
9114
9417
|
const sourcePath = resolveLocalPluginSource(specifier, baseDir);
|
|
9115
9418
|
const productPath = sourcePath && distDir ? mirrorProductPath(sourcePath, baseDir, distDir) : null;
|
|
9116
|
-
if (productPath !== null &&
|
|
9419
|
+
if (productPath !== null && fs19.existsSync(productPath) && (sourcePath === null || !isSourceNewer(sourcePath, productPath))) {
|
|
9117
9420
|
return import(pathToFileURL3(productPath).href);
|
|
9118
9421
|
}
|
|
9119
9422
|
if (sourcePath && TS_EXTS.test(sourcePath)) {
|
|
@@ -9122,13 +9425,13 @@ async function importPluginModule(specifier, baseDir, dist) {
|
|
|
9122
9425
|
`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.`
|
|
9123
9426
|
);
|
|
9124
9427
|
}
|
|
9125
|
-
const relFromRoot =
|
|
9428
|
+
const relFromRoot = path27.relative(baseDir, sourcePath).replace(/\\/g, "/");
|
|
9126
9429
|
if (relFromRoot.startsWith("src/")) {
|
|
9127
9430
|
await ensureCompiled(sourcePath, baseDir, dist);
|
|
9128
9431
|
} else {
|
|
9129
9432
|
await compileProjectModules([sourcePath], baseDir, dist);
|
|
9130
9433
|
}
|
|
9131
|
-
if (productPath &&
|
|
9434
|
+
if (productPath && fs19.existsSync(productPath)) {
|
|
9132
9435
|
return import(pathToFileURL3(productPath).href);
|
|
9133
9436
|
}
|
|
9134
9437
|
}
|
|
@@ -9140,7 +9443,7 @@ async function importPluginModule(specifier, baseDir, dist) {
|
|
|
9140
9443
|
`${specifier}/index.ts`,
|
|
9141
9444
|
`${specifier}.js`,
|
|
9142
9445
|
`${specifier}/index.js`
|
|
9143
|
-
].map((c) =>
|
|
9446
|
+
].map((c) => path27.isAbsolute(c) ? c : path27.join(baseDir, c));
|
|
9144
9447
|
throw new Error(
|
|
9145
9448
|
`Cannot find local plugin "${specifier}" (resolved from ${baseDir}). Expected one of:
|
|
9146
9449
|
${candidates.join("\n ")}
|
|
@@ -9175,12 +9478,12 @@ var init_loadPlugins = __esm({
|
|
|
9175
9478
|
});
|
|
9176
9479
|
|
|
9177
9480
|
// src/cli/createAppCore.ts
|
|
9178
|
-
import
|
|
9179
|
-
import
|
|
9481
|
+
import fs20 from "fs";
|
|
9482
|
+
import path28 from "path";
|
|
9180
9483
|
import { PassThrough, Readable as Readable4 } from "stream";
|
|
9181
9484
|
async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries) {
|
|
9182
|
-
const toolsPath =
|
|
9183
|
-
if (!
|
|
9485
|
+
const toolsPath = path28.resolve(rootDir, dist, TOOLS_FILE2);
|
|
9486
|
+
if (!fs20.existsSync(toolsPath)) {
|
|
9184
9487
|
return [];
|
|
9185
9488
|
}
|
|
9186
9489
|
const serialized = await importWithCacheBust(toolsPath);
|
|
@@ -9189,8 +9492,8 @@ async function loadAndHydrateTools(rootDir, dist, registries = defaultRegistries
|
|
|
9189
9492
|
return hydrated;
|
|
9190
9493
|
}
|
|
9191
9494
|
async function loadAndHydrateAgents(rootDir, dist, registries = defaultRegistries) {
|
|
9192
|
-
const agentsPath =
|
|
9193
|
-
if (!
|
|
9495
|
+
const agentsPath = path28.resolve(rootDir, dist, AGENTS_FILE2);
|
|
9496
|
+
if (!fs20.existsSync(agentsPath)) {
|
|
9194
9497
|
return [];
|
|
9195
9498
|
}
|
|
9196
9499
|
const serialized = await importWithCacheBust(agentsPath);
|
|
@@ -9205,8 +9508,8 @@ function getTaskDriverOptions(config) {
|
|
|
9205
9508
|
return void 0;
|
|
9206
9509
|
}
|
|
9207
9510
|
async function loadAndHydrateTasks(rootDir, dist, registries = defaultRegistries) {
|
|
9208
|
-
const tasksPath =
|
|
9209
|
-
if (!
|
|
9511
|
+
const tasksPath = path28.resolve(rootDir, dist, TASKS_FILE);
|
|
9512
|
+
if (!fs20.existsSync(tasksPath)) {
|
|
9210
9513
|
return [];
|
|
9211
9514
|
}
|
|
9212
9515
|
const serialized = await importWithCacheBust(tasksPath);
|
|
@@ -9246,13 +9549,14 @@ function isFaapiConfigKey(key) {
|
|
|
9246
9549
|
async function createAppBase(options) {
|
|
9247
9550
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
9248
9551
|
const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
|
|
9249
|
-
const routesPath =
|
|
9250
|
-
if (!
|
|
9552
|
+
const routesPath = path28.resolve(rootDir, dist, ROUTES_FILE);
|
|
9553
|
+
if (!fs20.existsSync(routesPath)) {
|
|
9251
9554
|
throw new Error(
|
|
9252
9555
|
`[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
|
|
9253
9556
|
);
|
|
9254
9557
|
}
|
|
9255
9558
|
const config = await loadConfig(rootDir, dist);
|
|
9559
|
+
configureLogging(config?.log);
|
|
9256
9560
|
const serialized = await importWithCacheBust(routesPath);
|
|
9257
9561
|
const hydrated = await hydrateRoutes(serialized);
|
|
9258
9562
|
let sorted = sortRoutes(hydrated.routes);
|
|
@@ -9589,6 +9893,7 @@ var init_createAppCore = __esm({
|
|
|
9589
9893
|
init_loadTaskDriver();
|
|
9590
9894
|
init_idleTaskDriver();
|
|
9591
9895
|
init_cronScheduler();
|
|
9896
|
+
init_logger();
|
|
9592
9897
|
init_loadPlugins();
|
|
9593
9898
|
init_importWithCacheBust();
|
|
9594
9899
|
init_registries();
|
|
@@ -9612,6 +9917,7 @@ var init_createAppCore = __esm({
|
|
|
9612
9917
|
"etag",
|
|
9613
9918
|
"bodyLimit",
|
|
9614
9919
|
"logger",
|
|
9920
|
+
"log",
|
|
9615
9921
|
"http2",
|
|
9616
9922
|
"trustedProxy",
|
|
9617
9923
|
"response",
|
|
@@ -9621,7 +9927,7 @@ var init_createAppCore = __esm({
|
|
|
9621
9927
|
});
|
|
9622
9928
|
|
|
9623
9929
|
// src/cli/createDevApp.ts
|
|
9624
|
-
import
|
|
9930
|
+
import path29 from "path";
|
|
9625
9931
|
async function createDevApp(options) {
|
|
9626
9932
|
const { app, ctx } = await createAppBase(options);
|
|
9627
9933
|
const devApp = app;
|
|
@@ -9671,7 +9977,7 @@ async function createDevApp(options) {
|
|
|
9671
9977
|
invalidateProgramCache();
|
|
9672
9978
|
const tasks = await scanTasks(ctx.rootDir, TASK_PATTERNS);
|
|
9673
9979
|
for (const task of tasks) {
|
|
9674
|
-
await ensureCompiled(
|
|
9980
|
+
await ensureCompiled(path29.resolve(ctx.rootDir, task.filePath), ctx.rootDir, ctx.dist);
|
|
9675
9981
|
}
|
|
9676
9982
|
await generateTaskArtifacts(tasks, ctx.rootDir, ctx.dist);
|
|
9677
9983
|
ctx.taskQueue.invalidateModules();
|
|
@@ -9713,7 +10019,7 @@ __export(devCommand_exports, {
|
|
|
9713
10019
|
generateTaskArtifactsForDev: () => generateTaskArtifactsForDev,
|
|
9714
10020
|
generateToolArtifactsForDev: () => generateToolArtifactsForDev
|
|
9715
10021
|
});
|
|
9716
|
-
import
|
|
10022
|
+
import path30 from "path";
|
|
9717
10023
|
async function devCommand(options) {
|
|
9718
10024
|
const rootDir = process.cwd();
|
|
9719
10025
|
if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
|
|
@@ -9742,7 +10048,7 @@ async function devCommand(options) {
|
|
|
9742
10048
|
async function generateRouteArtifacts(rootDir, patterns, dist) {
|
|
9743
10049
|
const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
|
|
9744
10050
|
const sorted = sortRoutes(routes);
|
|
9745
|
-
const routesPath =
|
|
10051
|
+
const routesPath = path30.resolve(rootDir, dist, ROUTES_FILE2);
|
|
9746
10052
|
const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
|
|
9747
10053
|
await writeRoutesModule(serialized, routesPath);
|
|
9748
10054
|
}
|
|
@@ -9757,7 +10063,7 @@ async function generateAgentArtifactsForDev(rootDir, dist) {
|
|
|
9757
10063
|
async function generateTaskArtifactsForDev(rootDir, dist) {
|
|
9758
10064
|
const tasks = await scanTasks(rootDir, TASK_PATTERNS);
|
|
9759
10065
|
for (const task of tasks) {
|
|
9760
|
-
await ensureCompiled(
|
|
10066
|
+
await ensureCompiled(path30.resolve(rootDir, task.filePath), rootDir, dist);
|
|
9761
10067
|
}
|
|
9762
10068
|
await generateTaskArtifacts(tasks, rootDir, dist);
|
|
9763
10069
|
}
|
|
@@ -9805,15 +10111,15 @@ var buildCommand_exports = {};
|
|
|
9805
10111
|
__export(buildCommand_exports, {
|
|
9806
10112
|
buildCommand: () => buildCommand
|
|
9807
10113
|
});
|
|
9808
|
-
import
|
|
9809
|
-
import
|
|
10114
|
+
import path31 from "path";
|
|
10115
|
+
import fs21 from "fs";
|
|
9810
10116
|
async function buildCommand(options) {
|
|
9811
10117
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
9812
10118
|
const outdir = options?.dist ?? DEFAULT_DIST2;
|
|
9813
|
-
const absOut =
|
|
9814
|
-
const realRoot = toRealPath(
|
|
10119
|
+
const absOut = path31.resolve(rootDir, outdir);
|
|
10120
|
+
const realRoot = toRealPath(path31.resolve(rootDir));
|
|
9815
10121
|
if (isInsideDir(toRealPath(absOut), realRoot)) {
|
|
9816
|
-
|
|
10122
|
+
fs21.rmSync(absOut, { recursive: true, force: true });
|
|
9817
10123
|
} else {
|
|
9818
10124
|
console.warn(
|
|
9819
10125
|
`! Output directory "${outdir}" is outside the project root, skipping clean (stale artifacts may remain)`
|
|
@@ -9821,10 +10127,10 @@ async function buildCommand(options) {
|
|
|
9821
10127
|
}
|
|
9822
10128
|
await compileConfig({ rootDir, dist: outdir });
|
|
9823
10129
|
const _config = await loadConfig(rootDir, outdir);
|
|
9824
|
-
const pkgPath =
|
|
9825
|
-
if (
|
|
10130
|
+
const pkgPath = path31.resolve(rootDir, "package.json");
|
|
10131
|
+
if (fs21.existsSync(pkgPath)) {
|
|
9826
10132
|
try {
|
|
9827
|
-
const pkg = JSON.parse(
|
|
10133
|
+
const pkg = JSON.parse(fs21.readFileSync(pkgPath, "utf-8"));
|
|
9828
10134
|
if (pkg.type !== "module") {
|
|
9829
10135
|
console.warn(
|
|
9830
10136
|
'! package.json is missing "type": "module" \u2014 build output is ESM and `node dist/main` will fail without it'
|
|
@@ -9852,7 +10158,7 @@ async function buildCommand(options) {
|
|
|
9852
10158
|
if (localPluginSources.length > 0) {
|
|
9853
10159
|
console.log("\n[2.5/8] Compiling local plugins...");
|
|
9854
10160
|
const outside = localPluginSources.filter((p) => {
|
|
9855
|
-
const rel =
|
|
10161
|
+
const rel = path31.relative(rootDir, p).replace(/\\/g, "/");
|
|
9856
10162
|
return !rel.startsWith("src/");
|
|
9857
10163
|
});
|
|
9858
10164
|
if (outside.length > 0) {
|
|
@@ -9876,9 +10182,9 @@ async function buildCommand(options) {
|
|
|
9876
10182
|
}
|
|
9877
10183
|
console.log("\n[4/8] Generating schema...");
|
|
9878
10184
|
await generateSchemaFiles(sorted, rootDir, outdir);
|
|
9879
|
-
console.log(` Schema: zod.js files under ${
|
|
10185
|
+
console.log(` Schema: zod.js files under ${path31.resolve(rootDir, outdir)}`);
|
|
9880
10186
|
console.log("\n[5/8] Generating routes manifest...");
|
|
9881
|
-
const routesPath =
|
|
10187
|
+
const routesPath = path31.resolve(rootDir, outdir, "faapi-routes.js");
|
|
9882
10188
|
const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
|
|
9883
10189
|
await writeRoutesModule(serialized, routesPath);
|
|
9884
10190
|
console.log(` Written to ${routesPath}`);
|
|
@@ -9886,19 +10192,19 @@ async function buildCommand(options) {
|
|
|
9886
10192
|
const tools = await scanTools(rootDir, TOOL_PATTERNS);
|
|
9887
10193
|
const toolMeta = await generateToolArtifacts(tools, rootDir, outdir);
|
|
9888
10194
|
console.log(` Found ${toolMeta.length} tool(s)`);
|
|
9889
|
-
console.log(` Tool manifest: ${
|
|
10195
|
+
console.log(` Tool manifest: ${path31.resolve(rootDir, outdir, "faapi-tools.js")}`);
|
|
9890
10196
|
console.log("\n[7/8] Generating agent manifest...");
|
|
9891
10197
|
const agents = await scanAgents(rootDir, DEFAULT_AGENT_PATTERNS);
|
|
9892
10198
|
const agentMeta = await generateAgentArtifacts(agents, rootDir, outdir);
|
|
9893
10199
|
console.log(` Found ${agentMeta.length} agent(s)`);
|
|
9894
|
-
console.log(` Agent manifest: ${
|
|
10200
|
+
console.log(` Agent manifest: ${path31.resolve(rootDir, outdir, "faapi-agents.js")}`);
|
|
9895
10201
|
console.log("\n[7.5/8] Generating task manifest and schema...");
|
|
9896
10202
|
const tasks = await scanTasks(rootDir, TASK_PATTERNS);
|
|
9897
10203
|
const taskMeta = await generateTaskArtifacts(tasks, rootDir, outdir);
|
|
9898
10204
|
console.log(` Found ${taskMeta.length} task(s)`);
|
|
9899
|
-
console.log(` Task manifest: ${
|
|
10205
|
+
console.log(` Task manifest: ${path31.resolve(rootDir, outdir, "faapi-tasks.js")}`);
|
|
9900
10206
|
console.log("\n[8/8] Generating entry file...");
|
|
9901
|
-
const mainPath =
|
|
10207
|
+
const mainPath = path31.resolve(rootDir, outdir, "main.js");
|
|
9902
10208
|
const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: ${JSON.stringify(outdir)} }` : "";
|
|
9903
10209
|
const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
|
|
9904
10210
|
import { createProdApp, loadEnv } from '@faapi/faapi';
|
|
@@ -9910,7 +10216,7 @@ loadEnv(process.cwd());
|
|
|
9910
10216
|
const app = await createProdApp(${createProdAppArgs});
|
|
9911
10217
|
await app.listen();
|
|
9912
10218
|
`;
|
|
9913
|
-
await
|
|
10219
|
+
await fs21.promises.writeFile(mainPath, mainContent, "utf-8");
|
|
9914
10220
|
console.log(` Written to ${mainPath}`);
|
|
9915
10221
|
console.log("\nfaapi build completed");
|
|
9916
10222
|
}
|
|
@@ -9924,7 +10230,7 @@ function extractLocalPluginSources(declarations, rootDir) {
|
|
|
9924
10230
|
else if (Array.isArray(decl)) specifier = decl[0];
|
|
9925
10231
|
else if ("path" in decl) specifier = decl.path;
|
|
9926
10232
|
if (!specifier) continue;
|
|
9927
|
-
if (!specifier.startsWith("./") && !specifier.startsWith("../") && !
|
|
10233
|
+
if (!specifier.startsWith("./") && !specifier.startsWith("../") && !path31.isAbsolute(specifier)) {
|
|
9928
10234
|
continue;
|
|
9929
10235
|
}
|
|
9930
10236
|
const source = resolveLocalPluginSource(specifier, rootDir);
|