@faapi/faapi 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +480 -339
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +375 -234
- package/dist/index.js.map +1 -1
- package/dist/testing.js +303 -163
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,35 +10,107 @@ var __export = (target, all) => {
|
|
|
10
10
|
|
|
11
11
|
// src/ast/createProgram.ts
|
|
12
12
|
import ts from "typescript";
|
|
13
|
+
import fs from "fs";
|
|
14
|
+
import path from "path";
|
|
13
15
|
function invalidateProgramCache() {
|
|
14
16
|
programCache.clear();
|
|
17
|
+
tsConfigCache.clear();
|
|
18
|
+
}
|
|
19
|
+
function findTsConfig(filePath) {
|
|
20
|
+
let dir = path.dirname(filePath);
|
|
21
|
+
const root = path.parse(dir).root;
|
|
22
|
+
while (true) {
|
|
23
|
+
const candidate = path.join(dir, "tsconfig.json");
|
|
24
|
+
if (fs.existsSync(candidate)) {
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
if (dir === root) return null;
|
|
28
|
+
const parent = path.dirname(dir);
|
|
29
|
+
if (parent === dir) return null;
|
|
30
|
+
dir = parent;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function parseTsConfig(tsconfigPath) {
|
|
34
|
+
const cached = tsConfigCache.get(tsconfigPath);
|
|
35
|
+
if (cached) return cached;
|
|
36
|
+
const result = { fileNames: [] };
|
|
37
|
+
try {
|
|
38
|
+
const configFile = ts.readConfigFile(tsconfigPath, (p) => fs.readFileSync(p, "utf-8"));
|
|
39
|
+
if (configFile.error) {
|
|
40
|
+
tsConfigCache.set(tsconfigPath, result);
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
const config = configFile.config ?? {};
|
|
44
|
+
const basePath = path.dirname(tsconfigPath);
|
|
45
|
+
const parsed = ts.parseJsonConfigFileContent(
|
|
46
|
+
config,
|
|
47
|
+
ts.sys,
|
|
48
|
+
basePath,
|
|
49
|
+
/* existingOptions */
|
|
50
|
+
void 0,
|
|
51
|
+
tsconfigPath
|
|
52
|
+
);
|
|
53
|
+
result.fileNames = parsed.fileNames;
|
|
54
|
+
if (parsed.options.module !== void 0) {
|
|
55
|
+
result.module = parsed.options.module;
|
|
56
|
+
}
|
|
57
|
+
if (parsed.options.moduleResolution !== void 0) {
|
|
58
|
+
result.moduleResolution = parsed.options.moduleResolution;
|
|
59
|
+
}
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
tsConfigCache.set(tsconfigPath, result);
|
|
63
|
+
return result;
|
|
15
64
|
}
|
|
16
65
|
function createProgram(filePath) {
|
|
17
66
|
const cached = programCache.get(filePath);
|
|
18
67
|
if (cached) {
|
|
19
68
|
return cached;
|
|
20
69
|
}
|
|
21
|
-
const
|
|
70
|
+
const options = {
|
|
22
71
|
strict: true,
|
|
23
72
|
target: ts.ScriptTarget.ES2022,
|
|
24
73
|
module: ts.ModuleKind.NodeNext,
|
|
25
74
|
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
26
75
|
skipLibCheck: true,
|
|
27
76
|
noEmit: true
|
|
28
|
-
}
|
|
77
|
+
};
|
|
78
|
+
let rootNames = [filePath];
|
|
79
|
+
const tsconfigPath = findTsConfig(filePath);
|
|
80
|
+
if (tsconfigPath) {
|
|
81
|
+
const tsOptions = parseTsConfig(tsconfigPath);
|
|
82
|
+
if (tsOptions.module !== void 0) {
|
|
83
|
+
options.module = tsOptions.module;
|
|
84
|
+
}
|
|
85
|
+
if (tsOptions.moduleResolution !== void 0) {
|
|
86
|
+
options.moduleResolution = tsOptions.moduleResolution;
|
|
87
|
+
}
|
|
88
|
+
if (tsOptions.fileNames.length > 0) {
|
|
89
|
+
if (!tsOptions.fileNames.includes(filePath)) {
|
|
90
|
+
rootNames = [filePath, ...tsOptions.fileNames];
|
|
91
|
+
} else {
|
|
92
|
+
rootNames = tsOptions.fileNames;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const program = ts.createProgram(rootNames, options);
|
|
29
97
|
programCache.set(filePath, program);
|
|
30
98
|
return program;
|
|
31
99
|
}
|
|
32
|
-
var programCache;
|
|
100
|
+
var programCache, tsConfigCache;
|
|
33
101
|
var init_createProgram = __esm({
|
|
34
102
|
"src/ast/createProgram.ts"() {
|
|
35
103
|
"use strict";
|
|
36
104
|
programCache = /* @__PURE__ */ new Map();
|
|
105
|
+
tsConfigCache = /* @__PURE__ */ new Map();
|
|
37
106
|
}
|
|
38
107
|
});
|
|
39
108
|
|
|
40
109
|
// src/ast/resolveTypeNode.ts
|
|
41
110
|
import ts2 from "typescript";
|
|
111
|
+
function setProgramContext(program) {
|
|
112
|
+
currentProgram = program;
|
|
113
|
+
}
|
|
42
114
|
function resolveTypeNode(typeNode, checker, visited = /* @__PURE__ */ new Set()) {
|
|
43
115
|
const kind = typeNode.kind;
|
|
44
116
|
switch (kind) {
|
|
@@ -351,11 +423,69 @@ function resolveTypeReference(typeNode, checker, visited = /* @__PURE__ */ new S
|
|
|
351
423
|
if (ts2.isEnumDeclaration(declaration)) {
|
|
352
424
|
return resolveEnumDeclaration(declaration);
|
|
353
425
|
}
|
|
426
|
+
if (ts2.isImportSpecifier(declaration) || ts2.isImportClause(declaration)) {
|
|
427
|
+
const resolved = resolveImportAlias(typeNode, symbol, checker, visited);
|
|
428
|
+
if (resolved) return resolved;
|
|
429
|
+
}
|
|
354
430
|
}
|
|
355
431
|
}
|
|
356
432
|
}
|
|
357
433
|
throw new SchemaExtractionError(typeNode.getText(), `\u65E0\u6CD5\u89E3\u6790\u7684\u5F15\u7528\u7C7B\u578B "${typeName}"`);
|
|
358
434
|
}
|
|
435
|
+
function resolveImportAlias(typeNode, symbol, checker, visited) {
|
|
436
|
+
const typeName = typeNode.typeName.getText();
|
|
437
|
+
try {
|
|
438
|
+
const aliased = checker.getAliasedSymbol(symbol);
|
|
439
|
+
if (aliased && aliased.declarations && aliased.declarations.length > 0) {
|
|
440
|
+
const decl = aliased.declarations[0];
|
|
441
|
+
if (ts2.isInterfaceDeclaration(decl)) {
|
|
442
|
+
return resolveInterfaceDeclaration(decl, checker, visited);
|
|
443
|
+
}
|
|
444
|
+
if (ts2.isTypeAliasDeclaration(decl)) {
|
|
445
|
+
return resolveTypeNode(decl.type, checker, visited);
|
|
446
|
+
}
|
|
447
|
+
if (ts2.isEnumDeclaration(decl)) {
|
|
448
|
+
return resolveEnumDeclaration(decl);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
} catch {
|
|
452
|
+
}
|
|
453
|
+
const program = currentProgram;
|
|
454
|
+
if (!program) return null;
|
|
455
|
+
const allSFs = program.getSourceFiles();
|
|
456
|
+
for (const sourceFile of allSFs) {
|
|
457
|
+
if (sourceFile.fileName.includes("/node_modules/") || sourceFile.fileName.includes("typescript/lib/")) {
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
const found = findTopLevelDecl(sourceFile, typeName);
|
|
461
|
+
if (found) {
|
|
462
|
+
if (found.kind === "interface") {
|
|
463
|
+
return resolveInterfaceDeclaration(found.node, checker, visited);
|
|
464
|
+
}
|
|
465
|
+
if (found.kind === "typeAlias") {
|
|
466
|
+
return resolveTypeNode(found.node.type, checker, visited);
|
|
467
|
+
}
|
|
468
|
+
if (found.kind === "enum") {
|
|
469
|
+
return resolveEnumDeclaration(found.node);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
function findTopLevelDecl(sourceFile, typeName) {
|
|
476
|
+
let found = null;
|
|
477
|
+
ts2.forEachChild(sourceFile, (node) => {
|
|
478
|
+
if (found) return;
|
|
479
|
+
if (ts2.isInterfaceDeclaration(node) && node.name.text === typeName) {
|
|
480
|
+
found = { kind: "interface", node };
|
|
481
|
+
} else if (ts2.isTypeAliasDeclaration(node) && node.name.text === typeName) {
|
|
482
|
+
found = { kind: "typeAlias", node };
|
|
483
|
+
} else if (ts2.isEnumDeclaration(node) && node.name.text === typeName) {
|
|
484
|
+
found = { kind: "enum", node };
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
return found;
|
|
488
|
+
}
|
|
359
489
|
function resolveEnumDeclaration(node) {
|
|
360
490
|
const members = [];
|
|
361
491
|
let nextNumericValue = 0;
|
|
@@ -534,10 +664,11 @@ function validateConstraints(constraints, type, fieldName) {
|
|
|
534
664
|
}
|
|
535
665
|
}
|
|
536
666
|
}
|
|
537
|
-
var SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
|
|
667
|
+
var currentProgram, SchemaExtractionError, NUMBER_CONSTRAINT_KINDS, LENGTH_CONSTRAINT_KINDS, STRING_FORMAT_CONSTRAINT_KINDS;
|
|
538
668
|
var init_resolveTypeNode = __esm({
|
|
539
669
|
"src/ast/resolveTypeNode.ts"() {
|
|
540
670
|
"use strict";
|
|
671
|
+
currentProgram = null;
|
|
541
672
|
SchemaExtractionError = class extends Error {
|
|
542
673
|
constructor(typeText, reason, options) {
|
|
543
674
|
super(`\u65E0\u6CD5\u89E3\u6790\u7C7B\u578B "${typeText}": ${reason}`, options);
|
|
@@ -577,80 +708,90 @@ function extractTypeInfo(program, filePath, typeName) {
|
|
|
577
708
|
const sourceFile = program.getSourceFile(filePath);
|
|
578
709
|
if (!sourceFile) return null;
|
|
579
710
|
const checker = program.getTypeChecker();
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
711
|
+
setProgramContext(program);
|
|
712
|
+
try {
|
|
713
|
+
let result = null;
|
|
714
|
+
ts3.forEachChild(sourceFile, (node) => {
|
|
715
|
+
if (result) return;
|
|
716
|
+
if (ts3.isInterfaceDeclaration(node) && node.name.text === typeName) {
|
|
717
|
+
const visited = /* @__PURE__ */ new Set();
|
|
718
|
+
visited.add(typeName);
|
|
719
|
+
const runtimeType = withFileContext(
|
|
720
|
+
filePath,
|
|
721
|
+
typeName,
|
|
722
|
+
() => resolveInterfaceDeclaration(node, checker, visited)
|
|
723
|
+
);
|
|
724
|
+
result = {
|
|
725
|
+
name: typeName,
|
|
726
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
727
|
+
runtimeType
|
|
728
|
+
};
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
if (ts3.isTypeAliasDeclaration(node) && node.name.text === typeName) {
|
|
732
|
+
const visited = /* @__PURE__ */ new Set();
|
|
733
|
+
visited.add(typeName);
|
|
734
|
+
const runtimeType = withFileContext(
|
|
735
|
+
filePath,
|
|
736
|
+
typeName,
|
|
737
|
+
() => resolveTypeNode(node.type, checker, visited)
|
|
738
|
+
);
|
|
739
|
+
result = {
|
|
740
|
+
name: typeName,
|
|
741
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
742
|
+
runtimeType
|
|
743
|
+
};
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
return result;
|
|
748
|
+
} finally {
|
|
749
|
+
setProgramContext(null);
|
|
750
|
+
}
|
|
615
751
|
}
|
|
616
752
|
function extractAllTypes(program, filePath) {
|
|
617
753
|
const sourceFile = program.getSourceFile(filePath);
|
|
618
754
|
if (!sourceFile) return /* @__PURE__ */ new Map();
|
|
619
755
|
const checker = program.getTypeChecker();
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
756
|
+
setProgramContext(program);
|
|
757
|
+
try {
|
|
758
|
+
const result = /* @__PURE__ */ new Map();
|
|
759
|
+
ts3.forEachChild(sourceFile, (node) => {
|
|
760
|
+
if (ts3.isInterfaceDeclaration(node)) {
|
|
761
|
+
const visited = /* @__PURE__ */ new Set();
|
|
762
|
+
visited.add(node.name.text);
|
|
763
|
+
const runtimeType = withFileContext(
|
|
764
|
+
filePath,
|
|
765
|
+
node.name.text,
|
|
766
|
+
() => resolveInterfaceDeclaration(node, checker, visited)
|
|
767
|
+
);
|
|
768
|
+
result.set(node.name.text, {
|
|
769
|
+
name: node.name.text,
|
|
770
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
771
|
+
runtimeType
|
|
772
|
+
});
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
if (ts3.isTypeAliasDeclaration(node)) {
|
|
776
|
+
const visited = /* @__PURE__ */ new Set();
|
|
777
|
+
visited.add(node.name.text);
|
|
778
|
+
const runtimeType = withFileContext(
|
|
779
|
+
filePath,
|
|
780
|
+
node.name.text,
|
|
781
|
+
() => resolveTypeNode(node.type, checker, visited)
|
|
782
|
+
);
|
|
783
|
+
result.set(node.name.text, {
|
|
784
|
+
name: node.name.text,
|
|
785
|
+
properties: runtimeType.kind === "object" ? runtimeType.properties : [],
|
|
786
|
+
runtimeType
|
|
787
|
+
});
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
return result;
|
|
792
|
+
} finally {
|
|
793
|
+
setProgramContext(null);
|
|
794
|
+
}
|
|
654
795
|
}
|
|
655
796
|
function withFileContext(filePath, typeName, fn) {
|
|
656
797
|
try {
|
|
@@ -851,11 +992,11 @@ var init_analyzeInjection = __esm({
|
|
|
851
992
|
});
|
|
852
993
|
|
|
853
994
|
// src/cli/collectRouteSchemaSources.ts
|
|
854
|
-
import
|
|
995
|
+
import path2 from "path";
|
|
855
996
|
function collectRouteSchemaSources(routes, rootDir) {
|
|
856
997
|
const methodsByFile = /* @__PURE__ */ new Map();
|
|
857
998
|
for (const route of routes) {
|
|
858
|
-
const filePath = rootDir ?
|
|
999
|
+
const filePath = rootDir ? path2.resolve(rootDir, route.filePath) : route.filePath;
|
|
859
1000
|
let entry = methodsByFile.get(filePath);
|
|
860
1001
|
if (!entry) {
|
|
861
1002
|
entry = { urlPath: route.urlPath, methods: /* @__PURE__ */ new Set() };
|
|
@@ -1223,8 +1364,8 @@ __export(generateSchemaFiles_exports, {
|
|
|
1223
1364
|
getRuntimeSchemaPath: () => getRuntimeSchemaPath,
|
|
1224
1365
|
getSchemaOutputPath: () => getSchemaOutputPath
|
|
1225
1366
|
});
|
|
1226
|
-
import
|
|
1227
|
-
import
|
|
1367
|
+
import path6 from "path";
|
|
1368
|
+
import fs5 from "fs/promises";
|
|
1228
1369
|
function getSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
1229
1370
|
let rel = sourceFile.replace(/\\/g, "/");
|
|
1230
1371
|
if (rel.startsWith("src/")) {
|
|
@@ -1232,7 +1373,7 @@ function getSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
|
1232
1373
|
}
|
|
1233
1374
|
const idx = rel.lastIndexOf("/");
|
|
1234
1375
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
1235
|
-
return
|
|
1376
|
+
return path6.resolve(rootDir, dist, relDir, "zod.js");
|
|
1236
1377
|
}
|
|
1237
1378
|
function getRuntimeSchemaPath(filePath, dist, rootDir) {
|
|
1238
1379
|
let rel = filePath.replace(/\\/g, "/");
|
|
@@ -1243,7 +1384,7 @@ function getRuntimeSchemaPath(filePath, dist, rootDir) {
|
|
|
1243
1384
|
}
|
|
1244
1385
|
const idx = rel.lastIndexOf("/");
|
|
1245
1386
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
1246
|
-
return
|
|
1387
|
+
return path6.resolve(rootDir, dist, relDir, "zod.js");
|
|
1247
1388
|
}
|
|
1248
1389
|
function getHelpersImportPath(relDir) {
|
|
1249
1390
|
if (!relDir) return `./${HELPERS_FILENAME}`;
|
|
@@ -1293,7 +1434,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
1293
1434
|
}
|
|
1294
1435
|
const fileEntries = [];
|
|
1295
1436
|
for (const [filePath, fileSources] of sourcesByFile) {
|
|
1296
|
-
const relFile =
|
|
1437
|
+
const relFile = path6.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
1297
1438
|
const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
|
|
1298
1439
|
const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
|
|
1299
1440
|
let relForDir = relFile;
|
|
@@ -1308,7 +1449,7 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
1308
1449
|
}
|
|
1309
1450
|
const allSourceCode = fileEntries.map((e) => e.source).join("\n");
|
|
1310
1451
|
if (usesCoerceHelpers(allSourceCode)) {
|
|
1311
|
-
const helpersPath =
|
|
1452
|
+
const helpersPath = path6.resolve(rootDir, dist, HELPERS_FILENAME);
|
|
1312
1453
|
await writeSchemaFile(helpersPath, generateHelpersFileSource());
|
|
1313
1454
|
}
|
|
1314
1455
|
await Promise.all(
|
|
@@ -1316,8 +1457,8 @@ async function generateSchemaFiles(routes, rootDir, dist) {
|
|
|
1316
1457
|
);
|
|
1317
1458
|
}
|
|
1318
1459
|
async function writeSchemaFile(outputPath, source) {
|
|
1319
|
-
await
|
|
1320
|
-
await
|
|
1460
|
+
await fs5.mkdir(path6.dirname(outputPath), { recursive: true });
|
|
1461
|
+
await fs5.writeFile(outputPath, source, "utf-8");
|
|
1321
1462
|
}
|
|
1322
1463
|
var init_generateSchemaFiles = __esm({
|
|
1323
1464
|
"src/cli/generateSchemaFiles.ts"() {
|
|
@@ -1422,7 +1563,7 @@ function listSkills() {
|
|
|
1422
1563
|
}
|
|
1423
1564
|
|
|
1424
1565
|
// src/loader/loadAgentModule.ts
|
|
1425
|
-
import
|
|
1566
|
+
import fs7 from "fs";
|
|
1426
1567
|
|
|
1427
1568
|
// src/loader/resolveExports.ts
|
|
1428
1569
|
function resolveExport(module, exportName) {
|
|
@@ -1468,17 +1609,17 @@ async function importWithCacheBust(filePath, bustViteCache = false) {
|
|
|
1468
1609
|
}
|
|
1469
1610
|
|
|
1470
1611
|
// src/cli/compileOnDemand.ts
|
|
1471
|
-
import
|
|
1472
|
-
import
|
|
1612
|
+
import path7 from "path";
|
|
1613
|
+
import fs6 from "fs";
|
|
1473
1614
|
|
|
1474
1615
|
// src/cli/compileDevRoutes.ts
|
|
1475
|
-
import
|
|
1476
|
-
import
|
|
1616
|
+
import path5 from "path";
|
|
1617
|
+
import fs4 from "fs";
|
|
1477
1618
|
import fg from "fast-glob";
|
|
1478
1619
|
|
|
1479
1620
|
// src/cli/aliasPlugin.ts
|
|
1480
|
-
import
|
|
1481
|
-
import
|
|
1621
|
+
import path4 from "path";
|
|
1622
|
+
import fs3 from "fs";
|
|
1482
1623
|
|
|
1483
1624
|
// src/utils/resolveAlias.ts
|
|
1484
1625
|
function resolveAlias(specifier, config) {
|
|
@@ -1505,11 +1646,11 @@ function resolveAlias(specifier, config) {
|
|
|
1505
1646
|
|
|
1506
1647
|
// src/utils/readTsconfig.ts
|
|
1507
1648
|
import ts6 from "typescript";
|
|
1508
|
-
import
|
|
1509
|
-
import
|
|
1649
|
+
import path3 from "path";
|
|
1650
|
+
import fs2 from "fs";
|
|
1510
1651
|
function readTsconfig(rootDir) {
|
|
1511
|
-
const tsconfigPath =
|
|
1512
|
-
if (!
|
|
1652
|
+
const tsconfigPath = path3.resolve(rootDir, "tsconfig.json");
|
|
1653
|
+
if (!fs2.existsSync(tsconfigPath)) return null;
|
|
1513
1654
|
const configFile = ts6.readConfigFile(tsconfigPath, ts6.sys.readFile);
|
|
1514
1655
|
if (configFile.error || !configFile.config) return null;
|
|
1515
1656
|
const parsed = ts6.parseJsonConfigFileContent(configFile.config, ts6.sys, rootDir);
|
|
@@ -1518,7 +1659,7 @@ function readTsconfig(rootDir) {
|
|
|
1518
1659
|
if (!rawPaths) return null;
|
|
1519
1660
|
const paths = {};
|
|
1520
1661
|
for (const [pattern, targets] of Object.entries(rawPaths)) {
|
|
1521
|
-
paths[pattern] = targets.map((t) =>
|
|
1662
|
+
paths[pattern] = targets.map((t) => path3.resolve(baseUrl, t));
|
|
1522
1663
|
}
|
|
1523
1664
|
return { baseUrl, paths };
|
|
1524
1665
|
}
|
|
@@ -1531,29 +1672,29 @@ function toProdExtension(filePath) {
|
|
|
1531
1672
|
return filePath;
|
|
1532
1673
|
}
|
|
1533
1674
|
function toProdImportPath(sourceFile, importer) {
|
|
1534
|
-
const importerDir =
|
|
1535
|
-
let rel =
|
|
1536
|
-
rel = rel.split(
|
|
1675
|
+
const importerDir = path4.dirname(importer);
|
|
1676
|
+
let rel = path4.relative(importerDir, sourceFile);
|
|
1677
|
+
rel = rel.split(path4.sep).join("/");
|
|
1537
1678
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
1538
1679
|
return toProdExtension(rel);
|
|
1539
1680
|
}
|
|
1540
1681
|
function toRealPath(p) {
|
|
1541
1682
|
try {
|
|
1542
|
-
return
|
|
1683
|
+
return fs3.realpathSync(p);
|
|
1543
1684
|
} catch {
|
|
1544
1685
|
return p;
|
|
1545
1686
|
}
|
|
1546
1687
|
}
|
|
1547
1688
|
function isInsideDir(filePath, dir) {
|
|
1548
|
-
const rel =
|
|
1549
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
1689
|
+
const rel = path4.relative(dir, filePath);
|
|
1690
|
+
return rel !== "" && !rel.startsWith("..") && !path4.isAbsolute(rel);
|
|
1550
1691
|
}
|
|
1551
1692
|
var APP_DIR = "src";
|
|
1552
1693
|
function toStrippedProdImportPath(sourceFile, rootDir) {
|
|
1553
|
-
const appDirAbs = toRealPath(
|
|
1694
|
+
const appDirAbs = toRealPath(path4.resolve(rootDir, APP_DIR));
|
|
1554
1695
|
const sourceReal = toRealPath(sourceFile);
|
|
1555
|
-
let rel =
|
|
1556
|
-
rel = rel.split(
|
|
1696
|
+
let rel = path4.relative(appDirAbs, sourceReal);
|
|
1697
|
+
rel = rel.split(path4.sep).join("/");
|
|
1557
1698
|
if (!rel.startsWith(".")) rel = "./" + rel;
|
|
1558
1699
|
return toProdExtension(rel);
|
|
1559
1700
|
}
|
|
@@ -1568,34 +1709,34 @@ var INDEX_EXTS = [
|
|
|
1568
1709
|
"/index.cjs"
|
|
1569
1710
|
];
|
|
1570
1711
|
function resolveRelativeSpecifier(importer, specifier) {
|
|
1571
|
-
const importerDir =
|
|
1572
|
-
const base =
|
|
1712
|
+
const importerDir = path4.dirname(importer);
|
|
1713
|
+
const base = path4.resolve(importerDir, specifier);
|
|
1573
1714
|
if (PROD_EXTS.some((ext) => specifier.endsWith(ext))) {
|
|
1574
|
-
return
|
|
1715
|
+
return fs3.existsSync(base) ? base : null;
|
|
1575
1716
|
}
|
|
1576
1717
|
if (/\.(ts|tsx|jsx)$/.test(specifier)) {
|
|
1577
|
-
return
|
|
1718
|
+
return fs3.existsSync(base) ? base : null;
|
|
1578
1719
|
}
|
|
1579
1720
|
for (const ext of SOURCE_EXTS) {
|
|
1580
1721
|
const file = base + ext;
|
|
1581
|
-
if (
|
|
1722
|
+
if (fs3.existsSync(file)) return file;
|
|
1582
1723
|
}
|
|
1583
1724
|
for (const indexExt of INDEX_EXTS) {
|
|
1584
1725
|
const file = base + indexExt;
|
|
1585
|
-
if (
|
|
1726
|
+
if (fs3.existsSync(file)) return file;
|
|
1586
1727
|
}
|
|
1587
1728
|
return null;
|
|
1588
1729
|
}
|
|
1589
1730
|
function createAliasPlugin(config, options) {
|
|
1590
1731
|
const SPEC_RE = /(\bfrom\s*|import\s*\(\s*)(['"])([^'"]+)\2/g;
|
|
1591
|
-
const appDirAbs = options?.rootDir ? toRealPath(
|
|
1732
|
+
const appDirAbs = options?.rootDir ? toRealPath(path4.resolve(options.rootDir, APP_DIR)) : null;
|
|
1592
1733
|
return {
|
|
1593
1734
|
name: "faapi-alias",
|
|
1594
1735
|
setup(build) {
|
|
1595
1736
|
build.onLoad({ filter: /\.(ts|tsx|js|jsx|mjs|cjs)$/ }, (args) => {
|
|
1596
1737
|
let source;
|
|
1597
1738
|
try {
|
|
1598
|
-
source =
|
|
1739
|
+
source = fs3.readFileSync(args.path, "utf8");
|
|
1599
1740
|
} catch {
|
|
1600
1741
|
return void 0;
|
|
1601
1742
|
}
|
|
@@ -1628,7 +1769,7 @@ function createAliasPlugin(config, options) {
|
|
|
1628
1769
|
for (const candidate of candidates) {
|
|
1629
1770
|
for (const ext of SOURCE_EXTS) {
|
|
1630
1771
|
const file = candidate + ext;
|
|
1631
|
-
if (
|
|
1772
|
+
if (fs3.existsSync(file)) {
|
|
1632
1773
|
modified = true;
|
|
1633
1774
|
if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
|
|
1634
1775
|
return `${prefix}${quote}${toStrippedProdImportPath(
|
|
@@ -1641,7 +1782,7 @@ function createAliasPlugin(config, options) {
|
|
|
1641
1782
|
}
|
|
1642
1783
|
for (const indexExt of INDEX_EXTS) {
|
|
1643
1784
|
const file = candidate + indexExt;
|
|
1644
|
-
if (
|
|
1785
|
+
if (fs3.existsSync(file)) {
|
|
1645
1786
|
modified = true;
|
|
1646
1787
|
if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
|
|
1647
1788
|
return `${prefix}${quote}${toStrippedProdImportPath(
|
|
@@ -1679,11 +1820,11 @@ async function compileDevRoutes(options) {
|
|
|
1679
1820
|
if (entryPoints.length === 0) {
|
|
1680
1821
|
return { compiledFiles: [] };
|
|
1681
1822
|
}
|
|
1682
|
-
const absDist =
|
|
1683
|
-
await
|
|
1823
|
+
const absDist = path5.resolve(rootDir, dist);
|
|
1824
|
+
await fs4.promises.mkdir(absDist, { recursive: true });
|
|
1684
1825
|
const plugins = buildAliasPlugins(rootDir);
|
|
1685
1826
|
const esbuild = await import("esbuild");
|
|
1686
|
-
const outbase =
|
|
1827
|
+
const outbase = path5.resolve(rootDir, APP_DIR2);
|
|
1687
1828
|
const result = await esbuild.build({
|
|
1688
1829
|
entryPoints,
|
|
1689
1830
|
outdir: absDist,
|
|
@@ -1700,10 +1841,10 @@ async function compileDevRoutes(options) {
|
|
|
1700
1841
|
if (result.outputFiles) {
|
|
1701
1842
|
await Promise.all(
|
|
1702
1843
|
result.outputFiles.map(async (file) => {
|
|
1703
|
-
await
|
|
1844
|
+
await fs4.promises.mkdir(path5.dirname(file.path), { recursive: true });
|
|
1704
1845
|
const tmp = `${file.path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
1705
|
-
await
|
|
1706
|
-
await
|
|
1846
|
+
await fs4.promises.writeFile(tmp, file.contents);
|
|
1847
|
+
await fs4.promises.rename(tmp, file.path);
|
|
1707
1848
|
})
|
|
1708
1849
|
);
|
|
1709
1850
|
}
|
|
@@ -1715,8 +1856,8 @@ init_generateSchemaFiles();
|
|
|
1715
1856
|
init_generateSchemaFiles();
|
|
1716
1857
|
function isProductFresh(sourceAbsPath, productAbsPath) {
|
|
1717
1858
|
try {
|
|
1718
|
-
const srcStat =
|
|
1719
|
-
const prodStat =
|
|
1859
|
+
const srcStat = fs6.statSync(sourceAbsPath);
|
|
1860
|
+
const prodStat = fs6.statSync(productAbsPath);
|
|
1720
1861
|
return prodStat.mtimeMs >= srcStat.mtimeMs;
|
|
1721
1862
|
} catch {
|
|
1722
1863
|
return false;
|
|
@@ -1747,7 +1888,7 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
|
1747
1888
|
if (state.compiledFiles.has(sourceAbsPath)) {
|
|
1748
1889
|
return false;
|
|
1749
1890
|
}
|
|
1750
|
-
if (!
|
|
1891
|
+
if (!fs6.existsSync(sourceAbsPath)) {
|
|
1751
1892
|
return false;
|
|
1752
1893
|
}
|
|
1753
1894
|
const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
|
|
@@ -1773,11 +1914,11 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
|
1773
1914
|
}
|
|
1774
1915
|
}
|
|
1775
1916
|
function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
|
|
1776
|
-
const rel =
|
|
1917
|
+
const rel = path7.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
1777
1918
|
if (!rel.startsWith("src/")) return null;
|
|
1778
1919
|
const relWithoutSrc = rel.slice(4);
|
|
1779
1920
|
const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
|
|
1780
|
-
return
|
|
1921
|
+
return path7.resolve(rootDir, dist, jsRel);
|
|
1781
1922
|
}
|
|
1782
1923
|
function clearGeneratedSchemas() {
|
|
1783
1924
|
state.generatedSchemas.clear();
|
|
@@ -1793,9 +1934,9 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
1793
1934
|
if (state.generatedSchemas.has(schemaPath)) {
|
|
1794
1935
|
return false;
|
|
1795
1936
|
}
|
|
1796
|
-
const prodAbsPath =
|
|
1937
|
+
const prodAbsPath = path7.resolve(rootDir, routeFilePath);
|
|
1797
1938
|
const sourceAbsPath = prodPathToSourcePath(prodAbsPath, rootDir, dist);
|
|
1798
|
-
if (!
|
|
1939
|
+
if (!fs6.existsSync(sourceAbsPath)) {
|
|
1799
1940
|
return false;
|
|
1800
1941
|
}
|
|
1801
1942
|
if (isProductFresh(sourceAbsPath, schemaPath)) {
|
|
@@ -1806,7 +1947,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
1806
1947
|
if (fileRoutes.length === 0) {
|
|
1807
1948
|
return false;
|
|
1808
1949
|
}
|
|
1809
|
-
const sourceRelPath =
|
|
1950
|
+
const sourceRelPath = path7.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
1810
1951
|
const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
|
|
1811
1952
|
const generatePromise = (async () => {
|
|
1812
1953
|
await generateSchemaFiles(sourceRoutes, rootDir, dist);
|
|
@@ -1827,22 +1968,22 @@ async function deleteSchemaFiles(routes, rootDir, dist) {
|
|
|
1827
1968
|
if (deleted.has(schemaPath)) continue;
|
|
1828
1969
|
deleted.add(schemaPath);
|
|
1829
1970
|
try {
|
|
1830
|
-
await
|
|
1971
|
+
await fs6.promises.unlink(schemaPath);
|
|
1831
1972
|
} catch {
|
|
1832
1973
|
}
|
|
1833
1974
|
}
|
|
1834
1975
|
}
|
|
1835
1976
|
function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
|
|
1836
|
-
const rel =
|
|
1977
|
+
const rel = path7.relative(rootDir, prodAbsPath).replace(/\\/g, "/");
|
|
1837
1978
|
let relWithoutDist = rel;
|
|
1838
1979
|
if (relWithoutDist.startsWith(`${dist}/`)) {
|
|
1839
1980
|
relWithoutDist = relWithoutDist.slice(dist.length + 1);
|
|
1840
1981
|
}
|
|
1841
1982
|
const srcRel = `src/${relWithoutDist}`;
|
|
1842
1983
|
const tsRel = srcRel.replace(/\.js$/, ".ts");
|
|
1843
|
-
const tsAbs =
|
|
1844
|
-
if (
|
|
1845
|
-
return
|
|
1984
|
+
const tsAbs = path7.resolve(rootDir, tsRel);
|
|
1985
|
+
if (fs6.existsSync(tsAbs)) return tsAbs;
|
|
1986
|
+
return path7.resolve(rootDir, srcRel);
|
|
1846
1987
|
}
|
|
1847
1988
|
function isDevOnDemandEnabled() {
|
|
1848
1989
|
return state.enabled;
|
|
@@ -1857,7 +1998,7 @@ async function loadAgentModule(filePath, hasRun, rootDir) {
|
|
|
1857
1998
|
const dist = getDevDist();
|
|
1858
1999
|
if (dist) {
|
|
1859
2000
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
1860
|
-
if (sourcePath &&
|
|
2001
|
+
if (sourcePath && fs7.existsSync(sourcePath)) {
|
|
1861
2002
|
try {
|
|
1862
2003
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
1863
2004
|
} catch (compileErr) {
|
|
@@ -1890,13 +2031,13 @@ async function loadAgentModule(filePath, hasRun, rootDir) {
|
|
|
1890
2031
|
}
|
|
1891
2032
|
|
|
1892
2033
|
// src/loader/loadToolModule.ts
|
|
1893
|
-
import
|
|
2034
|
+
import fs8 from "fs";
|
|
1894
2035
|
async function loadToolModule(filePath, functionName, rootDir) {
|
|
1895
2036
|
if (isDevOnDemandEnabled() && rootDir) {
|
|
1896
2037
|
const dist = getDevDist();
|
|
1897
2038
|
if (dist) {
|
|
1898
2039
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
1899
|
-
if (sourcePath &&
|
|
2040
|
+
if (sourcePath && fs8.existsSync(sourcePath)) {
|
|
1900
2041
|
try {
|
|
1901
2042
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
1902
2043
|
} catch (compileErr) {
|
|
@@ -1928,8 +2069,8 @@ async function loadToolModule(filePath, functionName, rootDir) {
|
|
|
1928
2069
|
import { existsSync as existsSync2 } from "fs";
|
|
1929
2070
|
|
|
1930
2071
|
// src/cli/generateToolArtifacts.ts
|
|
1931
|
-
import
|
|
1932
|
-
import
|
|
2072
|
+
import path8 from "path";
|
|
2073
|
+
import fs9 from "fs/promises";
|
|
1933
2074
|
import { existsSync } from "fs";
|
|
1934
2075
|
|
|
1935
2076
|
// src/ast/extractToolMetadata.ts
|
|
@@ -2024,7 +2165,7 @@ function getToolSchemaOutputPath(sourceFile, dist, rootDir) {
|
|
|
2024
2165
|
}
|
|
2025
2166
|
const idx = rel.lastIndexOf("/");
|
|
2026
2167
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
2027
|
-
return
|
|
2168
|
+
return path8.resolve(rootDir, dist, relDir, "zod.js");
|
|
2028
2169
|
}
|
|
2029
2170
|
function getRuntimeToolSchemaPath(filePath, dist, rootDir) {
|
|
2030
2171
|
let rel = filePath.replace(/\\/g, "/");
|
|
@@ -2035,7 +2176,7 @@ function getRuntimeToolSchemaPath(filePath, dist, rootDir) {
|
|
|
2035
2176
|
}
|
|
2036
2177
|
const idx = rel.lastIndexOf("/");
|
|
2037
2178
|
const relDir = idx >= 0 ? rel.slice(0, idx) : "";
|
|
2038
|
-
return
|
|
2179
|
+
return path8.resolve(rootDir, dist, relDir, "zod.js");
|
|
2039
2180
|
}
|
|
2040
2181
|
function toProdFilePath(filePath, dist) {
|
|
2041
2182
|
let rel = filePath.replace(/\\/g, "/");
|
|
@@ -2055,12 +2196,12 @@ function serializeTools(tools, dist = "dist") {
|
|
|
2055
2196
|
}));
|
|
2056
2197
|
}
|
|
2057
2198
|
async function writeToolsModule(manifest, outputPath) {
|
|
2058
|
-
const dir =
|
|
2059
|
-
await
|
|
2199
|
+
const dir = path8.dirname(outputPath);
|
|
2200
|
+
await fs9.mkdir(dir, { recursive: true });
|
|
2060
2201
|
const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
|
|
2061
2202
|
export const tools = ${JSON.stringify(manifest, null, 2)};
|
|
2062
2203
|
`;
|
|
2063
|
-
await
|
|
2204
|
+
await fs9.writeFile(outputPath, content, "utf-8");
|
|
2064
2205
|
}
|
|
2065
2206
|
function hydrateTools(manifest) {
|
|
2066
2207
|
return manifest.map((t) => ({
|
|
@@ -2075,7 +2216,7 @@ function collectToolSchemaSources(tools, rootDir) {
|
|
|
2075
2216
|
const toolsByFile = /* @__PURE__ */ new Map();
|
|
2076
2217
|
for (const tool of tools) {
|
|
2077
2218
|
if (!tool.inputTypeName) continue;
|
|
2078
|
-
const absPath =
|
|
2219
|
+
const absPath = path8.resolve(rootDir, tool.filePath);
|
|
2079
2220
|
let list = toolsByFile.get(absPath);
|
|
2080
2221
|
if (!list) {
|
|
2081
2222
|
list = [];
|
|
@@ -2137,15 +2278,15 @@ function generateToolSchemaFileSource(sources, allTypes, helpersImportPath) {
|
|
|
2137
2278
|
}
|
|
2138
2279
|
async function maybeGenerateHelpers(allSourceCode, distDir) {
|
|
2139
2280
|
if (!usesCoerceHelpers(allSourceCode)) return;
|
|
2140
|
-
const helpersPath =
|
|
2281
|
+
const helpersPath = path8.resolve(distDir, HELPERS_FILENAME);
|
|
2141
2282
|
if (existsSync(helpersPath)) return;
|
|
2142
|
-
await
|
|
2143
|
-
await
|
|
2283
|
+
await fs9.mkdir(path8.dirname(helpersPath), { recursive: true });
|
|
2284
|
+
await fs9.writeFile(helpersPath, generateHelpersFileSource(), "utf-8");
|
|
2144
2285
|
}
|
|
2145
2286
|
async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
2146
2287
|
const metadata = [];
|
|
2147
2288
|
for (const manifest of tools) {
|
|
2148
|
-
const absPath =
|
|
2289
|
+
const absPath = path8.resolve(rootDir, manifest.filePath);
|
|
2149
2290
|
const program = createProgram(absPath);
|
|
2150
2291
|
const result = extractToolMetadata(program, absPath, manifest.functionName, {
|
|
2151
2292
|
name: manifest.name,
|
|
@@ -2156,7 +2297,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2156
2297
|
}
|
|
2157
2298
|
}
|
|
2158
2299
|
const serialized = serializeTools(metadata, dist);
|
|
2159
|
-
const toolsPath =
|
|
2300
|
+
const toolsPath = path8.resolve(rootDir, dist, TOOLS_FILE);
|
|
2160
2301
|
await writeToolsModule(serialized, toolsPath);
|
|
2161
2302
|
if (options?.skipSchema) {
|
|
2162
2303
|
return metadata;
|
|
@@ -2179,7 +2320,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2179
2320
|
}
|
|
2180
2321
|
const fileEntries = [];
|
|
2181
2322
|
for (const [filePath, fileSources] of sourcesByFile) {
|
|
2182
|
-
const relFile =
|
|
2323
|
+
const relFile = path8.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
2183
2324
|
const outputPath = getToolSchemaOutputPath(relFile, dist, rootDir);
|
|
2184
2325
|
const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
|
|
2185
2326
|
let relForDir = relFile;
|
|
@@ -2193,7 +2334,7 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2193
2334
|
fileEntries.push({ outputPath, source });
|
|
2194
2335
|
}
|
|
2195
2336
|
const allSourceCode = fileEntries.map((e) => e.source).join("\n");
|
|
2196
|
-
const distDir =
|
|
2337
|
+
const distDir = path8.resolve(rootDir, dist);
|
|
2197
2338
|
await maybeGenerateHelpers(allSourceCode, distDir);
|
|
2198
2339
|
await Promise.all(
|
|
2199
2340
|
fileEntries.map(({ outputPath, source }) => writeToolSchemaFile(outputPath, source))
|
|
@@ -2201,8 +2342,8 @@ async function generateToolArtifacts(tools, rootDir, dist, options) {
|
|
|
2201
2342
|
return metadata;
|
|
2202
2343
|
}
|
|
2203
2344
|
async function writeToolSchemaFile(outputPath, source) {
|
|
2204
|
-
await
|
|
2205
|
-
await
|
|
2345
|
+
await fs9.mkdir(path8.dirname(outputPath), { recursive: true });
|
|
2346
|
+
await fs9.writeFile(outputPath, source, "utf-8");
|
|
2206
2347
|
}
|
|
2207
2348
|
|
|
2208
2349
|
// src/loader/loadToolSchema.ts
|
|
@@ -2402,16 +2543,16 @@ function helmet(options = {}) {
|
|
|
2402
2543
|
}
|
|
2403
2544
|
|
|
2404
2545
|
// src/config/loadConfig.ts
|
|
2405
|
-
import
|
|
2406
|
-
import
|
|
2546
|
+
import path9 from "path";
|
|
2547
|
+
import fs10 from "fs";
|
|
2407
2548
|
var CONFIG_PRODUCT_FILE = "faapi-config.js";
|
|
2408
2549
|
async function loadConfig(rootDir, dist) {
|
|
2409
|
-
const configProductPath =
|
|
2410
|
-
if (
|
|
2550
|
+
const configProductPath = path9.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
|
|
2551
|
+
if (fs10.existsSync(configProductPath)) {
|
|
2411
2552
|
const module = await importWithCacheBust(configProductPath);
|
|
2412
2553
|
return module.default ?? {};
|
|
2413
2554
|
}
|
|
2414
|
-
const hasSourceConfig =
|
|
2555
|
+
const hasSourceConfig = fs10.existsSync(path9.join(rootDir, "faapi.config.ts")) || fs10.existsSync(path9.join(rootDir, "faapi.config.js"));
|
|
2415
2556
|
if (hasSourceConfig) {
|
|
2416
2557
|
throw new Error(
|
|
2417
2558
|
`[faapi] ${dist}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
|
|
@@ -2421,8 +2562,8 @@ async function loadConfig(rootDir, dist) {
|
|
|
2421
2562
|
}
|
|
2422
2563
|
|
|
2423
2564
|
// src/cli/loadEnv.ts
|
|
2424
|
-
import
|
|
2425
|
-
import
|
|
2565
|
+
import fs11 from "fs";
|
|
2566
|
+
import path10 from "path";
|
|
2426
2567
|
function resolveEnv() {
|
|
2427
2568
|
return process.env.NODE_ENV || "development";
|
|
2428
2569
|
}
|
|
@@ -2488,9 +2629,9 @@ function loadEnv(rootDir) {
|
|
|
2488
2629
|
const files = getEnvFiles(env);
|
|
2489
2630
|
const merged = {};
|
|
2490
2631
|
for (const file of files) {
|
|
2491
|
-
const filePath =
|
|
2492
|
-
if (!
|
|
2493
|
-
const content =
|
|
2632
|
+
const filePath = path10.join(rootDir, file);
|
|
2633
|
+
if (!fs11.existsSync(filePath)) continue;
|
|
2634
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
2494
2635
|
const parsed = parseEnvFile(content, merged);
|
|
2495
2636
|
Object.assign(merged, parsed);
|
|
2496
2637
|
}
|
|
@@ -2527,14 +2668,14 @@ var ValidationError = class extends FaapiError {
|
|
|
2527
2668
|
issues;
|
|
2528
2669
|
};
|
|
2529
2670
|
var RouteNotFoundError = class extends FaapiError {
|
|
2530
|
-
constructor(
|
|
2531
|
-
super("ROUTE_NOT_FOUND", `Route not found: ${
|
|
2671
|
+
constructor(path19) {
|
|
2672
|
+
super("ROUTE_NOT_FOUND", `Route not found: ${path19}`, 404);
|
|
2532
2673
|
this.name = "RouteNotFoundError";
|
|
2533
2674
|
}
|
|
2534
2675
|
};
|
|
2535
2676
|
var MethodNotAllowedError = class extends FaapiError {
|
|
2536
|
-
constructor(method,
|
|
2537
|
-
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${
|
|
2677
|
+
constructor(method, path19, allowedMethods) {
|
|
2678
|
+
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path19}`, 405);
|
|
2538
2679
|
this.allowedMethods = allowedMethods;
|
|
2539
2680
|
this.name = "MethodNotAllowedError";
|
|
2540
2681
|
}
|
|
@@ -2560,8 +2701,8 @@ var PayloadTooLargeError = class extends FaapiError {
|
|
|
2560
2701
|
};
|
|
2561
2702
|
|
|
2562
2703
|
// src/cli/createAppCore.ts
|
|
2563
|
-
import
|
|
2564
|
-
import
|
|
2704
|
+
import fs16 from "fs";
|
|
2705
|
+
import path15 from "path";
|
|
2565
2706
|
import { PassThrough, Readable as Readable3 } from "stream";
|
|
2566
2707
|
|
|
2567
2708
|
// src/router/sortRoutes.ts
|
|
@@ -2614,45 +2755,45 @@ import {
|
|
|
2614
2755
|
import { createSecureServer as createHttp2SecureServer } from "http2";
|
|
2615
2756
|
import { readFileSync } from "fs";
|
|
2616
2757
|
import { Readable as Readable2 } from "stream";
|
|
2617
|
-
import
|
|
2758
|
+
import path12 from "path";
|
|
2618
2759
|
|
|
2619
2760
|
// src/router/matchRoute.ts
|
|
2620
|
-
function matchRoute(routes, method,
|
|
2761
|
+
function matchRoute(routes, method, path19) {
|
|
2621
2762
|
for (const route of routes) {
|
|
2622
2763
|
if (route.method !== method) {
|
|
2623
2764
|
continue;
|
|
2624
2765
|
}
|
|
2625
2766
|
if (!route.isDynamic) {
|
|
2626
|
-
if (route.urlPath ===
|
|
2767
|
+
if (route.urlPath === path19) {
|
|
2627
2768
|
return { route, params: {} };
|
|
2628
2769
|
}
|
|
2629
2770
|
continue;
|
|
2630
2771
|
}
|
|
2631
|
-
const params = matchDynamicPath(route.urlPath,
|
|
2772
|
+
const params = matchDynamicPath(route.urlPath, path19, route.paramNames, route.isCatchAll);
|
|
2632
2773
|
if (params !== null) {
|
|
2633
2774
|
return { route, params };
|
|
2634
2775
|
}
|
|
2635
2776
|
}
|
|
2636
2777
|
return null;
|
|
2637
2778
|
}
|
|
2638
|
-
function matchWsRoute(wsRoutes,
|
|
2779
|
+
function matchWsRoute(wsRoutes, path19) {
|
|
2639
2780
|
for (const route of wsRoutes) {
|
|
2640
2781
|
if (!route.isDynamic) {
|
|
2641
|
-
if (route.urlPath ===
|
|
2782
|
+
if (route.urlPath === path19) {
|
|
2642
2783
|
return { route, params: {} };
|
|
2643
2784
|
}
|
|
2644
2785
|
continue;
|
|
2645
2786
|
}
|
|
2646
|
-
const params = matchDynamicPath(route.urlPath,
|
|
2787
|
+
const params = matchDynamicPath(route.urlPath, path19, route.paramNames, route.isCatchAll);
|
|
2647
2788
|
if (params !== null) {
|
|
2648
2789
|
return { route, params };
|
|
2649
2790
|
}
|
|
2650
2791
|
}
|
|
2651
2792
|
return null;
|
|
2652
2793
|
}
|
|
2653
|
-
function matchDynamicPath(pattern,
|
|
2794
|
+
function matchDynamicPath(pattern, path19, paramNames, isCatchAll) {
|
|
2654
2795
|
const patternSegments = pattern.split("/").filter(Boolean);
|
|
2655
|
-
const pathSegments =
|
|
2796
|
+
const pathSegments = path19.split("/").filter(Boolean);
|
|
2656
2797
|
if (isCatchAll) {
|
|
2657
2798
|
const nonCatchAllCount = patternSegments.length - 1;
|
|
2658
2799
|
if (pathSegments.length <= nonCatchAllCount) {
|
|
@@ -2698,7 +2839,7 @@ function matchDynamicPath(pattern, path18, paramNames, isCatchAll) {
|
|
|
2698
2839
|
}
|
|
2699
2840
|
|
|
2700
2841
|
// src/loader/loadRouteModule.ts
|
|
2701
|
-
import
|
|
2842
|
+
import fs12 from "fs";
|
|
2702
2843
|
|
|
2703
2844
|
// src/loader/validateRouteModule.ts
|
|
2704
2845
|
function validateRouteModule(value, method, filePath) {
|
|
@@ -2715,7 +2856,7 @@ async function loadRouteModule(filePath, method, rootDir) {
|
|
|
2715
2856
|
const dist = getDevDist();
|
|
2716
2857
|
if (dist) {
|
|
2717
2858
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
2718
|
-
if (sourcePath &&
|
|
2859
|
+
if (sourcePath && fs12.existsSync(sourcePath)) {
|
|
2719
2860
|
try {
|
|
2720
2861
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
2721
2862
|
} catch (compileErr) {
|
|
@@ -3470,9 +3611,9 @@ async function validateInput(schemaPath, method, inputType, input) {
|
|
|
3470
3611
|
function mapZodIssues(error) {
|
|
3471
3612
|
return error.issues.map((issue) => {
|
|
3472
3613
|
const code = mapZodCode(issue.code, issue.message);
|
|
3473
|
-
const
|
|
3614
|
+
const path19 = issue.path.map(String).join(".") || "";
|
|
3474
3615
|
return {
|
|
3475
|
-
path:
|
|
3616
|
+
path: path19,
|
|
3476
3617
|
code,
|
|
3477
3618
|
expected: issue.expected ?? mapExpectedFromMessage(issue.message),
|
|
3478
3619
|
received: issue.received ?? mapReceivedFromMessage(issue.message),
|
|
@@ -3534,9 +3675,9 @@ function getClientIp(req) {
|
|
|
3534
3675
|
}
|
|
3535
3676
|
|
|
3536
3677
|
// src/server/handleWsUpgrade.ts
|
|
3537
|
-
import
|
|
3678
|
+
import fs13 from "fs";
|
|
3538
3679
|
import { WebSocketServer, WebSocket } from "ws";
|
|
3539
|
-
import
|
|
3680
|
+
import path11 from "path";
|
|
3540
3681
|
|
|
3541
3682
|
// src/server/serverUtils.ts
|
|
3542
3683
|
function nodeHttpToWebHeaders(req) {
|
|
@@ -3662,7 +3803,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
|
|
|
3662
3803
|
const dist = getDevDist();
|
|
3663
3804
|
if (dist) {
|
|
3664
3805
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
3665
|
-
if (sourcePath &&
|
|
3806
|
+
if (sourcePath && fs13.existsSync(sourcePath)) {
|
|
3666
3807
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
3667
3808
|
}
|
|
3668
3809
|
}
|
|
@@ -3742,7 +3883,7 @@ function attachWebSocket(options) {
|
|
|
3742
3883
|
const finalHandler = async () => {
|
|
3743
3884
|
let handlers;
|
|
3744
3885
|
try {
|
|
3745
|
-
const absoluteFilePath =
|
|
3886
|
+
const absoluteFilePath = path11.resolve(rootDir, route.filePath);
|
|
3746
3887
|
handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
|
|
3747
3888
|
} catch (err) {
|
|
3748
3889
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -3867,15 +4008,15 @@ function limitStreamSize(stream, maxSize) {
|
|
|
3867
4008
|
}
|
|
3868
4009
|
});
|
|
3869
4010
|
}
|
|
3870
|
-
function findAllowedMethods(routes,
|
|
4011
|
+
function findAllowedMethods(routes, path19) {
|
|
3871
4012
|
const methods = /* @__PURE__ */ new Set();
|
|
3872
4013
|
for (const route of routes) {
|
|
3873
|
-
if (route.urlPath ===
|
|
4014
|
+
if (route.urlPath === path19) {
|
|
3874
4015
|
methods.add(route.method);
|
|
3875
4016
|
continue;
|
|
3876
4017
|
}
|
|
3877
4018
|
if (route.isDynamic) {
|
|
3878
|
-
const params = matchDynamicPath(route.urlPath,
|
|
4019
|
+
const params = matchDynamicPath(route.urlPath, path19, route.paramNames, route.isCatchAll);
|
|
3879
4020
|
if (params !== null) {
|
|
3880
4021
|
methods.add(route.method);
|
|
3881
4022
|
}
|
|
@@ -3967,7 +4108,7 @@ function createRoutePipeline(opts) {
|
|
|
3967
4108
|
const match = resolveRouteOrThrow(routes, method, urlPath);
|
|
3968
4109
|
ctx.params = match.params;
|
|
3969
4110
|
const { route } = match;
|
|
3970
|
-
const absoluteFilePath =
|
|
4111
|
+
const absoluteFilePath = path12.resolve(rootDir, route.filePath);
|
|
3971
4112
|
const routeModule = await loadRouteModule(absoluteFilePath, route.method, rootDir);
|
|
3972
4113
|
const input = await resolveInput(route.method, request);
|
|
3973
4114
|
const inputType = getInputTypeForMethod(route.method);
|
|
@@ -4064,8 +4205,8 @@ function applyPluginWrappers(server, handlerWrappers, upgradeWrappers) {
|
|
|
4064
4205
|
}
|
|
4065
4206
|
|
|
4066
4207
|
// src/cli/generateRoutes.ts
|
|
4067
|
-
import
|
|
4068
|
-
import
|
|
4208
|
+
import fs14 from "fs";
|
|
4209
|
+
import path13 from "path";
|
|
4069
4210
|
async function hydrateRoutes(manifest) {
|
|
4070
4211
|
const hydrateRoute = (serialized) => ({
|
|
4071
4212
|
method: serialized.method,
|
|
@@ -4090,8 +4231,8 @@ async function hydrateRoutes(manifest) {
|
|
|
4090
4231
|
}
|
|
4091
4232
|
|
|
4092
4233
|
// src/cli/generateAgentArtifacts.ts
|
|
4093
|
-
import
|
|
4094
|
-
import
|
|
4234
|
+
import path14 from "path";
|
|
4235
|
+
import fs15 from "fs/promises";
|
|
4095
4236
|
|
|
4096
4237
|
// src/ast/extractAgentMetadata.ts
|
|
4097
4238
|
import ts8 from "typescript";
|
|
@@ -4305,12 +4446,12 @@ function serializeAgents(agents, dist = "dist") {
|
|
|
4305
4446
|
}));
|
|
4306
4447
|
}
|
|
4307
4448
|
async function writeAgentsModule(manifest, outputPath) {
|
|
4308
|
-
const dir =
|
|
4309
|
-
await
|
|
4449
|
+
const dir = path14.dirname(outputPath);
|
|
4450
|
+
await fs15.mkdir(dir, { recursive: true });
|
|
4310
4451
|
const content = `// \u81EA\u52A8\u751F\u6210,\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91(faapi build/dev \u4EA7\u7269)
|
|
4311
4452
|
export const agents = ${JSON.stringify(manifest, null, 2)};
|
|
4312
4453
|
`;
|
|
4313
|
-
await
|
|
4454
|
+
await fs15.writeFile(outputPath, content, "utf-8");
|
|
4314
4455
|
}
|
|
4315
4456
|
function hydrateAgents(manifest) {
|
|
4316
4457
|
return manifest.map((a) => ({
|
|
@@ -4328,7 +4469,7 @@ function hydrateAgents(manifest) {
|
|
|
4328
4469
|
async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
4329
4470
|
const metadata = [];
|
|
4330
4471
|
for (const manifest of agents) {
|
|
4331
|
-
const absPath =
|
|
4472
|
+
const absPath = path14.resolve(rootDir, manifest.filePath);
|
|
4332
4473
|
const program = createProgram(absPath);
|
|
4333
4474
|
const result = extractAgentMetadata(program, absPath, {
|
|
4334
4475
|
name: manifest.name,
|
|
@@ -4340,7 +4481,7 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
4340
4481
|
}
|
|
4341
4482
|
}
|
|
4342
4483
|
const serialized = serializeAgents(metadata, dist);
|
|
4343
|
-
const agentsPath =
|
|
4484
|
+
const agentsPath = path14.resolve(rootDir, dist, AGENTS_FILE);
|
|
4344
4485
|
await writeAgentsModule(serialized, agentsPath);
|
|
4345
4486
|
return metadata;
|
|
4346
4487
|
}
|
|
@@ -4412,8 +4553,8 @@ var TOOLS_FILE2 = "faapi-tools.js";
|
|
|
4412
4553
|
var AGENTS_FILE2 = "faapi-agents.js";
|
|
4413
4554
|
var PATTERNS = ["src/api/**/*.ts"];
|
|
4414
4555
|
async function loadAndHydrateTools(rootDir, dist) {
|
|
4415
|
-
const toolsPath =
|
|
4416
|
-
if (!
|
|
4556
|
+
const toolsPath = path15.resolve(rootDir, dist, TOOLS_FILE2);
|
|
4557
|
+
if (!fs16.existsSync(toolsPath)) {
|
|
4417
4558
|
return [];
|
|
4418
4559
|
}
|
|
4419
4560
|
const serialized = await importWithCacheBust(toolsPath);
|
|
@@ -4422,8 +4563,8 @@ async function loadAndHydrateTools(rootDir, dist) {
|
|
|
4422
4563
|
return hydrated;
|
|
4423
4564
|
}
|
|
4424
4565
|
async function loadAndHydrateAgents(rootDir, dist) {
|
|
4425
|
-
const agentsPath =
|
|
4426
|
-
if (!
|
|
4566
|
+
const agentsPath = path15.resolve(rootDir, dist, AGENTS_FILE2);
|
|
4567
|
+
if (!fs16.existsSync(agentsPath)) {
|
|
4427
4568
|
return [];
|
|
4428
4569
|
}
|
|
4429
4570
|
const serialized = await importWithCacheBust(agentsPath);
|
|
@@ -4470,8 +4611,8 @@ function isFaapiConfigKey(key) {
|
|
|
4470
4611
|
async function createAppBase(options) {
|
|
4471
4612
|
const rootDir = options?.rootDir ?? process.cwd();
|
|
4472
4613
|
const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
|
|
4473
|
-
const routesPath =
|
|
4474
|
-
if (!
|
|
4614
|
+
const routesPath = path15.resolve(rootDir, dist, ROUTES_FILE);
|
|
4615
|
+
if (!fs16.existsSync(routesPath)) {
|
|
4475
4616
|
throw new Error(
|
|
4476
4617
|
`[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
|
|
4477
4618
|
);
|
|
@@ -4692,17 +4833,17 @@ async function createAppBase(options) {
|
|
|
4692
4833
|
|
|
4693
4834
|
// src/router/scanRoutes.ts
|
|
4694
4835
|
import fg2 from "fast-glob";
|
|
4695
|
-
import
|
|
4696
|
-
import
|
|
4836
|
+
import path16 from "path";
|
|
4837
|
+
import fs17 from "fs";
|
|
4697
4838
|
|
|
4698
4839
|
// src/router/constants.ts
|
|
4699
4840
|
var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
4700
4841
|
var HTTP_METHOD_SET = new Set(HTTP_METHODS);
|
|
4701
4842
|
|
|
4702
4843
|
// src/utils/normalizePath.ts
|
|
4703
|
-
function normalizePath(
|
|
4704
|
-
if (!
|
|
4705
|
-
let result =
|
|
4844
|
+
function normalizePath(path19) {
|
|
4845
|
+
if (!path19) return "";
|
|
4846
|
+
let result = path19.replace(/\\/g, "/");
|
|
4706
4847
|
result = result.replace(/\/+/g, "/");
|
|
4707
4848
|
result = result.replace(/\/+$/, "");
|
|
4708
4849
|
if (result && !result.startsWith("/")) {
|
|
@@ -4763,34 +4904,34 @@ function extractExportsFromSource(source) {
|
|
|
4763
4904
|
return names;
|
|
4764
4905
|
}
|
|
4765
4906
|
function collectMiddlewarePaths(routeFilePath, rootDir, dist) {
|
|
4766
|
-
const routeDir =
|
|
4767
|
-
const resolvedRoot =
|
|
4907
|
+
const routeDir = path16.dirname(routeFilePath);
|
|
4908
|
+
const resolvedRoot = path16.resolve(rootDir);
|
|
4768
4909
|
const paths = [];
|
|
4769
|
-
let currentDir =
|
|
4910
|
+
let currentDir = path16.resolve(rootDir, routeDir);
|
|
4770
4911
|
while (true) {
|
|
4771
4912
|
if (dist) {
|
|
4772
|
-
const mwTsPath =
|
|
4773
|
-
const mwJsPath =
|
|
4774
|
-
const absTsPath =
|
|
4775
|
-
const absJsPath =
|
|
4776
|
-
const absMwPath =
|
|
4913
|
+
const mwTsPath = path16.join(currentDir, "middlewares.ts");
|
|
4914
|
+
const mwJsPath = path16.join(currentDir, "middlewares.js");
|
|
4915
|
+
const absTsPath = path16.resolve(rootDir, mwTsPath);
|
|
4916
|
+
const absJsPath = path16.resolve(rootDir, mwJsPath);
|
|
4917
|
+
const absMwPath = fs17.existsSync(absTsPath) ? absTsPath : fs17.existsSync(absJsPath) ? absJsPath : null;
|
|
4777
4918
|
if (absMwPath) {
|
|
4778
|
-
const relMwPath =
|
|
4779
|
-
const prodAbsPath =
|
|
4919
|
+
const relMwPath = path16.relative(rootDir, absMwPath);
|
|
4920
|
+
const prodAbsPath = path16.resolve(rootDir, toProdFilePath3(relMwPath, dist));
|
|
4780
4921
|
paths.push(prodAbsPath);
|
|
4781
4922
|
}
|
|
4782
4923
|
} else {
|
|
4783
4924
|
for (const ext of [".ts", ".js"]) {
|
|
4784
|
-
const mwPath =
|
|
4785
|
-
const absMwPath =
|
|
4786
|
-
if (
|
|
4925
|
+
const mwPath = path16.join(currentDir, `middlewares${ext}`);
|
|
4926
|
+
const absMwPath = path16.resolve(rootDir, mwPath);
|
|
4927
|
+
if (fs17.existsSync(absMwPath)) {
|
|
4787
4928
|
paths.push(absMwPath);
|
|
4788
4929
|
break;
|
|
4789
4930
|
}
|
|
4790
4931
|
}
|
|
4791
4932
|
}
|
|
4792
4933
|
if (currentDir === resolvedRoot) break;
|
|
4793
|
-
const parentDir =
|
|
4934
|
+
const parentDir = path16.dirname(currentDir);
|
|
4794
4935
|
if (parentDir === currentDir) break;
|
|
4795
4936
|
currentDir = parentDir;
|
|
4796
4937
|
}
|
|
@@ -4817,7 +4958,7 @@ async function scanRoutes(rootDir, patterns, dist) {
|
|
|
4817
4958
|
const normalizedFile = file.replace(/\\/g, "/");
|
|
4818
4959
|
const fileName = normalizedFile.split("/").pop();
|
|
4819
4960
|
if (fileName === "handler.ts" || fileName === "handler.js") {
|
|
4820
|
-
const absPath =
|
|
4961
|
+
const absPath = path16.resolve(rootDir, normalizedFile);
|
|
4821
4962
|
const urlPath = filePathToUrlPath(normalizedFile);
|
|
4822
4963
|
const paramNames = extractParamNames(urlPath);
|
|
4823
4964
|
const isDynamic = paramNames.length > 0;
|
|
@@ -4830,7 +4971,7 @@ async function scanRoutes(rootDir, patterns, dist) {
|
|
|
4830
4971
|
const mwPaths = collectMiddlewarePaths(normalizedFile, rootDir);
|
|
4831
4972
|
middlewareBundle = await loadMergedMiddlewares(mwPaths);
|
|
4832
4973
|
}
|
|
4833
|
-
const source = await
|
|
4974
|
+
const source = await fs17.promises.readFile(absPath, "utf8").catch(() => "");
|
|
4834
4975
|
const exportNames = extractExportsFromSource(source);
|
|
4835
4976
|
const methods = HTTP_METHODS.filter((m) => exportNames.has(m));
|
|
4836
4977
|
for (const method of methods) {
|
|
@@ -4866,8 +5007,8 @@ async function scanRoutes(rootDir, patterns, dist) {
|
|
|
4866
5007
|
|
|
4867
5008
|
// src/tools/scanTools.ts
|
|
4868
5009
|
import fg3 from "fast-glob";
|
|
4869
|
-
import
|
|
4870
|
-
import
|
|
5010
|
+
import path17 from "path";
|
|
5011
|
+
import fs18 from "fs";
|
|
4871
5012
|
var TOOL_PATTERNS = ["src/tools/**/*.ts"];
|
|
4872
5013
|
var TOOL_EXPORT_RE = new RegExp(
|
|
4873
5014
|
String.raw`export\s+(?:async\s+)?(?:function\s+|const\s+)([A-Za-z_$][\w$]*)\s*(?:\(|=)`,
|
|
@@ -4917,8 +5058,8 @@ async function scanTools(rootDir, patterns) {
|
|
|
4917
5058
|
if (fileName !== "handler.ts" && fileName !== "handler.js") {
|
|
4918
5059
|
continue;
|
|
4919
5060
|
}
|
|
4920
|
-
const absPath =
|
|
4921
|
-
const source = await
|
|
5061
|
+
const absPath = path17.resolve(rootDir, normalizedFile);
|
|
5062
|
+
const source = await fs18.promises.readFile(absPath, "utf8").catch(() => "");
|
|
4922
5063
|
const exportNames = extractToolExportsFromSource(source);
|
|
4923
5064
|
const namespace = filePathToToolNamespace(normalizedFile);
|
|
4924
5065
|
for (const fnName of exportNames) {
|
|
@@ -4942,8 +5083,8 @@ async function scanTools(rootDir, patterns) {
|
|
|
4942
5083
|
|
|
4943
5084
|
// src/agents/scanAgents.ts
|
|
4944
5085
|
import fg4 from "fast-glob";
|
|
4945
|
-
import
|
|
4946
|
-
import
|
|
5086
|
+
import path18 from "path";
|
|
5087
|
+
import fs19 from "fs";
|
|
4947
5088
|
var DEFAULT_AGENT_PATTERNS = ["src/agents/*/handler.ts"];
|
|
4948
5089
|
var RUN_EXPORT_RE = /export\s+(?:async\s+)?(?:function\s+|const\s+)run\b/;
|
|
4949
5090
|
function extractAgentNameFromPath(filePath) {
|
|
@@ -4975,8 +5116,8 @@ async function scanAgents(rootDir, patterns) {
|
|
|
4975
5116
|
if (fileName !== "handler.ts" && fileName !== "handler.js") {
|
|
4976
5117
|
continue;
|
|
4977
5118
|
}
|
|
4978
|
-
const absPath =
|
|
4979
|
-
const source = await
|
|
5119
|
+
const absPath = path18.resolve(rootDir, normalizedFile);
|
|
5120
|
+
const source = await fs19.promises.readFile(absPath, "utf8").catch(() => "");
|
|
4980
5121
|
const { hasRun } = detectAgentExports(source);
|
|
4981
5122
|
const name = extractAgentNameFromPath(normalizedFile);
|
|
4982
5123
|
const prevFile = seen.get(name);
|