@faapi/faapi 3.0.0 → 3.1.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 +390 -254
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +265 -95
- package/dist/index.js +341 -223
- package/dist/index.js.map +1 -1
- package/dist/testing.js +342 -222
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1350,26 +1350,57 @@ function getTool(name) {
|
|
|
1350
1350
|
return registry.get(name);
|
|
1351
1351
|
}
|
|
1352
1352
|
|
|
1353
|
-
// src/injection/
|
|
1353
|
+
// src/injection/skillRegistry.ts
|
|
1354
1354
|
var registry2 = /* @__PURE__ */ new Map();
|
|
1355
|
+
function hydrateSkillRegistry(skills) {
|
|
1356
|
+
const next = /* @__PURE__ */ new Map();
|
|
1357
|
+
for (const skill of skills) {
|
|
1358
|
+
next.set(skill.name, skill);
|
|
1359
|
+
}
|
|
1360
|
+
registry2 = next;
|
|
1361
|
+
}
|
|
1362
|
+
function clearSkillRegistry() {
|
|
1363
|
+
registry2 = /* @__PURE__ */ new Map();
|
|
1364
|
+
}
|
|
1365
|
+
function upsertSkill(core) {
|
|
1366
|
+
registry2.set(core.name, core);
|
|
1367
|
+
}
|
|
1368
|
+
function removeSkill(name) {
|
|
1369
|
+
registry2.delete(name);
|
|
1370
|
+
}
|
|
1371
|
+
function getSkill(name) {
|
|
1372
|
+
return registry2.get(name);
|
|
1373
|
+
}
|
|
1374
|
+
function listSkills() {
|
|
1375
|
+
return Array.from(registry2.values());
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// src/injection/agentRegistry.ts
|
|
1379
|
+
var registry3 = /* @__PURE__ */ new Map();
|
|
1355
1380
|
function hydrateAgentRegistry(agents) {
|
|
1356
1381
|
const next = /* @__PURE__ */ new Map();
|
|
1357
1382
|
for (const agent of agents) {
|
|
1358
1383
|
next.set(agent.name, agent);
|
|
1359
1384
|
}
|
|
1360
|
-
|
|
1385
|
+
registry3 = next;
|
|
1361
1386
|
}
|
|
1362
1387
|
function clearAgentRegistry() {
|
|
1363
|
-
|
|
1388
|
+
registry3 = /* @__PURE__ */ new Map();
|
|
1364
1389
|
}
|
|
1365
1390
|
function getAgent(name) {
|
|
1366
|
-
return
|
|
1391
|
+
return getSkill(name) ?? registry3.get(name);
|
|
1392
|
+
}
|
|
1393
|
+
function getAgentEntry(name) {
|
|
1394
|
+
return registry3.get(name);
|
|
1367
1395
|
}
|
|
1368
1396
|
function listAgents() {
|
|
1369
|
-
|
|
1397
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1398
|
+
for (const agent of registry3.values()) merged.set(agent.name, agent);
|
|
1399
|
+
for (const skill of listSkills()) merged.set(skill.name, skill);
|
|
1400
|
+
return Array.from(merged.values());
|
|
1370
1401
|
}
|
|
1371
1402
|
function resolveAgentTools(name) {
|
|
1372
|
-
const agent =
|
|
1403
|
+
const agent = getAgent(name);
|
|
1373
1404
|
if (!agent) return [];
|
|
1374
1405
|
const result = /* @__PURE__ */ new Map();
|
|
1375
1406
|
if (agent.tools) {
|
|
@@ -1381,11 +1412,11 @@ function resolveAgentTools(name) {
|
|
|
1381
1412
|
return Array.from(result.values());
|
|
1382
1413
|
}
|
|
1383
1414
|
function resolveSubAgents(name) {
|
|
1384
|
-
const agent =
|
|
1415
|
+
const agent = getAgent(name);
|
|
1385
1416
|
if (!agent || !agent.agents) return [];
|
|
1386
1417
|
const result = [];
|
|
1387
1418
|
for (const agentName of agent.agents) {
|
|
1388
|
-
const subAgent =
|
|
1419
|
+
const subAgent = getAgent(agentName);
|
|
1389
1420
|
if (subAgent) result.push(subAgent);
|
|
1390
1421
|
}
|
|
1391
1422
|
return result;
|
|
@@ -1692,12 +1723,29 @@ function isProductFresh(sourceAbsPath, productAbsPath) {
|
|
|
1692
1723
|
return false;
|
|
1693
1724
|
}
|
|
1694
1725
|
}
|
|
1695
|
-
|
|
1726
|
+
function createDevOnDemandState() {
|
|
1727
|
+
return {
|
|
1728
|
+
enabled: false,
|
|
1729
|
+
distDir: void 0,
|
|
1730
|
+
compiledFiles: /* @__PURE__ */ new Set(),
|
|
1731
|
+
generatedSchemas: /* @__PURE__ */ new Set(),
|
|
1732
|
+
inFlightCompilations: /* @__PURE__ */ new Map(),
|
|
1733
|
+
inFlightSchemaGenerations: /* @__PURE__ */ new Map()
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
var state = createDevOnDemandState();
|
|
1696
1737
|
function clearCompiledFiles() {
|
|
1697
|
-
compiledFiles.clear();
|
|
1738
|
+
state.compiledFiles.clear();
|
|
1739
|
+
state.inFlightCompilations.clear();
|
|
1698
1740
|
}
|
|
1699
1741
|
async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
1700
|
-
|
|
1742
|
+
const inFlight = state.inFlightCompilations.get(sourceAbsPath);
|
|
1743
|
+
if (inFlight) {
|
|
1744
|
+
await inFlight.catch(() => {
|
|
1745
|
+
});
|
|
1746
|
+
return false;
|
|
1747
|
+
}
|
|
1748
|
+
if (state.compiledFiles.has(sourceAbsPath)) {
|
|
1701
1749
|
return false;
|
|
1702
1750
|
}
|
|
1703
1751
|
if (!fs5.existsSync(sourceAbsPath)) {
|
|
@@ -1705,17 +1753,25 @@ async function ensureCompiled(sourceAbsPath, rootDir, dist) {
|
|
|
1705
1753
|
}
|
|
1706
1754
|
const productPath = prodSourcePathToProductPath(sourceAbsPath, rootDir, dist);
|
|
1707
1755
|
if (productPath && isProductFresh(sourceAbsPath, productPath)) {
|
|
1708
|
-
compiledFiles.add(sourceAbsPath);
|
|
1756
|
+
state.compiledFiles.add(sourceAbsPath);
|
|
1709
1757
|
return false;
|
|
1710
1758
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1759
|
+
const compilePromise = (async () => {
|
|
1760
|
+
await compileDevRoutes({
|
|
1761
|
+
rootDir,
|
|
1762
|
+
dist,
|
|
1763
|
+
files: [sourceAbsPath],
|
|
1764
|
+
logLevel: "silent"
|
|
1765
|
+
});
|
|
1766
|
+
state.compiledFiles.add(sourceAbsPath);
|
|
1767
|
+
})();
|
|
1768
|
+
state.inFlightCompilations.set(sourceAbsPath, compilePromise);
|
|
1769
|
+
try {
|
|
1770
|
+
await compilePromise;
|
|
1771
|
+
return true;
|
|
1772
|
+
} finally {
|
|
1773
|
+
state.inFlightCompilations.delete(sourceAbsPath);
|
|
1774
|
+
}
|
|
1719
1775
|
}
|
|
1720
1776
|
function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
|
|
1721
1777
|
const rel = path6.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
@@ -1724,12 +1780,18 @@ function prodSourcePathToProductPath(sourceAbsPath, rootDir, dist) {
|
|
|
1724
1780
|
const jsRel = relWithoutSrc.replace(/\.ts$/, ".js");
|
|
1725
1781
|
return path6.resolve(rootDir, dist, jsRel);
|
|
1726
1782
|
}
|
|
1727
|
-
var generatedSchemas = /* @__PURE__ */ new Set();
|
|
1728
1783
|
function clearGeneratedSchemas() {
|
|
1729
|
-
generatedSchemas.clear();
|
|
1784
|
+
state.generatedSchemas.clear();
|
|
1785
|
+
state.inFlightSchemaGenerations.clear();
|
|
1730
1786
|
}
|
|
1731
1787
|
async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir, dist) {
|
|
1732
|
-
|
|
1788
|
+
const inFlight = state.inFlightSchemaGenerations.get(schemaPath);
|
|
1789
|
+
if (inFlight) {
|
|
1790
|
+
await inFlight.catch(() => {
|
|
1791
|
+
});
|
|
1792
|
+
return false;
|
|
1793
|
+
}
|
|
1794
|
+
if (state.generatedSchemas.has(schemaPath)) {
|
|
1733
1795
|
return false;
|
|
1734
1796
|
}
|
|
1735
1797
|
const prodAbsPath = path6.resolve(rootDir, routeFilePath);
|
|
@@ -1738,7 +1800,7 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
1738
1800
|
return false;
|
|
1739
1801
|
}
|
|
1740
1802
|
if (isProductFresh(sourceAbsPath, schemaPath)) {
|
|
1741
|
-
generatedSchemas.add(schemaPath);
|
|
1803
|
+
state.generatedSchemas.add(schemaPath);
|
|
1742
1804
|
return false;
|
|
1743
1805
|
}
|
|
1744
1806
|
const fileRoutes = routes.filter((r) => r.filePath === routeFilePath);
|
|
@@ -1747,9 +1809,17 @@ async function ensureSchemaGenerated(schemaPath, routeFilePath, routes, rootDir,
|
|
|
1747
1809
|
}
|
|
1748
1810
|
const sourceRelPath = path6.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
|
|
1749
1811
|
const sourceRoutes = fileRoutes.map((r) => ({ ...r, filePath: sourceRelPath }));
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1812
|
+
const generatePromise = (async () => {
|
|
1813
|
+
await generateSchemaFiles(sourceRoutes, rootDir, dist);
|
|
1814
|
+
state.generatedSchemas.add(schemaPath);
|
|
1815
|
+
})();
|
|
1816
|
+
state.inFlightSchemaGenerations.set(schemaPath, generatePromise);
|
|
1817
|
+
try {
|
|
1818
|
+
await generatePromise;
|
|
1819
|
+
return true;
|
|
1820
|
+
} finally {
|
|
1821
|
+
state.inFlightSchemaGenerations.delete(schemaPath);
|
|
1822
|
+
}
|
|
1753
1823
|
}
|
|
1754
1824
|
async function deleteSchemaFiles(routes, rootDir, dist) {
|
|
1755
1825
|
const deleted = /* @__PURE__ */ new Set();
|
|
@@ -1775,17 +1845,15 @@ function prodPathToSourcePath(prodAbsPath, rootDir, dist) {
|
|
|
1775
1845
|
if (fs5.existsSync(tsAbs)) return tsAbs;
|
|
1776
1846
|
return path6.resolve(rootDir, srcRel);
|
|
1777
1847
|
}
|
|
1778
|
-
var devOnDemandEnabled = false;
|
|
1779
1848
|
function isDevOnDemandEnabled() {
|
|
1780
|
-
return
|
|
1849
|
+
return state.enabled;
|
|
1781
1850
|
}
|
|
1782
|
-
var devDistDir;
|
|
1783
1851
|
function getDevDist() {
|
|
1784
|
-
return
|
|
1852
|
+
return state.distDir;
|
|
1785
1853
|
}
|
|
1786
1854
|
|
|
1787
1855
|
// src/loader/loadAgentModule.ts
|
|
1788
|
-
async function loadAgentModule(filePath,
|
|
1856
|
+
async function loadAgentModule(filePath, hasRun, rootDir) {
|
|
1789
1857
|
if (isDevOnDemandEnabled() && rootDir) {
|
|
1790
1858
|
const dist = getDevDist();
|
|
1791
1859
|
if (dist) {
|
|
@@ -1809,30 +1877,6 @@ async function loadAgentModule(filePath, hasConfig, hasRun, rootDir) {
|
|
|
1809
1877
|
const reason = err instanceof Error ? err.message : String(err);
|
|
1810
1878
|
throw new Error(`Failed to load agent module "${filePath}": ${reason}`, { cause: err });
|
|
1811
1879
|
}
|
|
1812
|
-
let config;
|
|
1813
|
-
if (hasConfig) {
|
|
1814
|
-
const configExport = resolveExport(module, "config");
|
|
1815
|
-
if (configExport === void 0) {
|
|
1816
|
-
throw new Error(
|
|
1817
|
-
`Agent module "${filePath}" does not export "config" (hasConfig=true but export missing).`
|
|
1818
|
-
);
|
|
1819
|
-
}
|
|
1820
|
-
if (typeof configExport === "function") {
|
|
1821
|
-
const returned = configExport();
|
|
1822
|
-
if (returned === null || typeof returned !== "object") {
|
|
1823
|
-
throw new Error(
|
|
1824
|
-
`Agent module "${filePath}" config() did not return an object (got ${returned === null ? "null" : typeof returned}).`
|
|
1825
|
-
);
|
|
1826
|
-
}
|
|
1827
|
-
config = returned;
|
|
1828
|
-
} else if (typeof configExport === "object" && configExport !== null) {
|
|
1829
|
-
config = configExport;
|
|
1830
|
-
} else {
|
|
1831
|
-
throw new Error(
|
|
1832
|
-
`Agent module "${filePath}" config export must be an object or function, got ${typeof configExport}.`
|
|
1833
|
-
);
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
1880
|
let run;
|
|
1837
1881
|
if (hasRun) {
|
|
1838
1882
|
const runExport = resolveExport(module, "run");
|
|
@@ -1843,7 +1887,7 @@ async function loadAgentModule(filePath, hasConfig, hasRun, rootDir) {
|
|
|
1843
1887
|
}
|
|
1844
1888
|
run = runExport;
|
|
1845
1889
|
}
|
|
1846
|
-
return {
|
|
1890
|
+
return { run };
|
|
1847
1891
|
}
|
|
1848
1892
|
|
|
1849
1893
|
// src/loader/loadToolModule.ts
|
|
@@ -2509,6 +2553,12 @@ var ModuleLoadError = class extends FaapiError {
|
|
|
2509
2553
|
this.name = "ModuleLoadError";
|
|
2510
2554
|
}
|
|
2511
2555
|
};
|
|
2556
|
+
var PayloadTooLargeError = class extends FaapiError {
|
|
2557
|
+
constructor(maxSize) {
|
|
2558
|
+
super("PAYLOAD_TOO_LARGE", `Request body exceeds size limit of ${maxSize} bytes`, 413);
|
|
2559
|
+
this.name = "PayloadTooLargeError";
|
|
2560
|
+
}
|
|
2561
|
+
};
|
|
2512
2562
|
|
|
2513
2563
|
// src/cli/createAppCore.ts
|
|
2514
2564
|
import fs15 from "fs";
|
|
@@ -2795,6 +2845,92 @@ function createSseWriter() {
|
|
|
2795
2845
|
return writer;
|
|
2796
2846
|
}
|
|
2797
2847
|
|
|
2848
|
+
// src/response/responseFormatter.ts
|
|
2849
|
+
function defaultOk(data) {
|
|
2850
|
+
return { data };
|
|
2851
|
+
}
|
|
2852
|
+
function defaultFail(e) {
|
|
2853
|
+
const error = { message: e.message };
|
|
2854
|
+
if (e.code !== void 0) error.code = e.code;
|
|
2855
|
+
return { error };
|
|
2856
|
+
}
|
|
2857
|
+
function getResponseConfig(config) {
|
|
2858
|
+
return config?.response;
|
|
2859
|
+
}
|
|
2860
|
+
function resolveOkFn(config) {
|
|
2861
|
+
return getResponseConfig(config)?.ok ?? defaultOk;
|
|
2862
|
+
}
|
|
2863
|
+
function resolveFailFn(config) {
|
|
2864
|
+
return getResponseConfig(config)?.fail ?? defaultFail;
|
|
2865
|
+
}
|
|
2866
|
+
function jsonOk(body, status = 200, extraHeaders) {
|
|
2867
|
+
return jsonRaw(body, status, extraHeaders);
|
|
2868
|
+
}
|
|
2869
|
+
function jsonRaw(body, status, extraHeaders) {
|
|
2870
|
+
const headers = new Headers({ "Content-Type": "application/json" });
|
|
2871
|
+
if (extraHeaders) {
|
|
2872
|
+
const extra = new Headers(extraHeaders);
|
|
2873
|
+
extra.forEach((value, key) => headers.set(key, value));
|
|
2874
|
+
}
|
|
2875
|
+
return new Response(JSON.stringify(body), { status, headers });
|
|
2876
|
+
}
|
|
2877
|
+
function wrapOkResult(result, config) {
|
|
2878
|
+
if (result instanceof Response) return result;
|
|
2879
|
+
return resolveOkFn(config)(result);
|
|
2880
|
+
}
|
|
2881
|
+
function formatFailResponse(options, config) {
|
|
2882
|
+
const failFn = resolveFailFn(config);
|
|
2883
|
+
const body = failFn({
|
|
2884
|
+
status: options.status,
|
|
2885
|
+
code: options.code,
|
|
2886
|
+
message: options.message
|
|
2887
|
+
});
|
|
2888
|
+
return jsonOk(body, options.status ?? 500);
|
|
2889
|
+
}
|
|
2890
|
+
function formatErrorResponse(error, config) {
|
|
2891
|
+
const failFn = resolveFailFn(config);
|
|
2892
|
+
if (error instanceof ValidationError) {
|
|
2893
|
+
const body2 = failFn({
|
|
2894
|
+
status: error.statusCode,
|
|
2895
|
+
code: error.code,
|
|
2896
|
+
message: error.message
|
|
2897
|
+
});
|
|
2898
|
+
const bodyObj = typeof body2 === "object" && body2 !== null ? body2 : { error: body2 };
|
|
2899
|
+
const errorObj = bodyObj.error ?? bodyObj;
|
|
2900
|
+
if (errorObj) {
|
|
2901
|
+
errorObj.issues = error.issues;
|
|
2902
|
+
}
|
|
2903
|
+
return jsonOk(bodyObj, error.statusCode);
|
|
2904
|
+
}
|
|
2905
|
+
if (error instanceof MethodNotAllowedError) {
|
|
2906
|
+
const body2 = failFn({
|
|
2907
|
+
status: error.statusCode,
|
|
2908
|
+
code: error.code,
|
|
2909
|
+
message: error.message
|
|
2910
|
+
});
|
|
2911
|
+
return jsonOk(body2, error.statusCode, { Allow: error.allowedMethods.join(", ") });
|
|
2912
|
+
}
|
|
2913
|
+
if (error instanceof PayloadTooLargeError) {
|
|
2914
|
+
const body2 = failFn({
|
|
2915
|
+
status: error.statusCode,
|
|
2916
|
+
code: error.code,
|
|
2917
|
+
message: error.message
|
|
2918
|
+
});
|
|
2919
|
+
return jsonOk(body2, error.statusCode);
|
|
2920
|
+
}
|
|
2921
|
+
if (error instanceof FaapiError) {
|
|
2922
|
+
const body2 = failFn({
|
|
2923
|
+
status: error.statusCode,
|
|
2924
|
+
code: error.code,
|
|
2925
|
+
message: error.message
|
|
2926
|
+
});
|
|
2927
|
+
return jsonOk(body2, error.statusCode);
|
|
2928
|
+
}
|
|
2929
|
+
const message = error instanceof Error ? error.message : "An unknown error occurred";
|
|
2930
|
+
const body = failFn({ status: 500, code: "INTERNAL_ERROR", message });
|
|
2931
|
+
return jsonOk(body, 500);
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2798
2934
|
// src/runtime/createContext.ts
|
|
2799
2935
|
function parseCookies(cookieHeader) {
|
|
2800
2936
|
const cookies = /* @__PURE__ */ new Map();
|
|
@@ -2855,11 +2991,7 @@ function createContext(request, params, config = {}, ip = "") {
|
|
|
2855
2991
|
});
|
|
2856
2992
|
},
|
|
2857
2993
|
json(data, status) {
|
|
2858
|
-
|
|
2859
|
-
return new Response(JSON.stringify(data), {
|
|
2860
|
-
status: status ?? 200,
|
|
2861
|
-
headers
|
|
2862
|
-
});
|
|
2994
|
+
return jsonOk(data, status ?? 200);
|
|
2863
2995
|
},
|
|
2864
2996
|
html(html, status) {
|
|
2865
2997
|
const headers = { "Content-Type": "text/html; charset=utf-8" };
|
|
@@ -2895,18 +3027,22 @@ function createContext(request, params, config = {}, ip = "") {
|
|
|
2895
3027
|
/**
|
|
2896
3028
|
* 显式包装成功响应(返回 Response,不会被自动包裹再次包装)
|
|
2897
3029
|
*
|
|
3030
|
+
* 实现委托给 [responseFormatter.wrapOkResult](../response/responseFormatter.ts),
|
|
3031
|
+
* 与 handler `return data` 走的自动包裹路径共享同一套 ok 函数。
|
|
3032
|
+
*
|
|
2898
3033
|
* 用 config.response.ok(或默认 (data) => ({ data })) 包裹 data 并返回 JSON Response。
|
|
2899
3034
|
* handler 也可直接 return data,框架会自动用 ok 包裹,两者等价。
|
|
2900
3035
|
*/
|
|
2901
3036
|
ok(data) {
|
|
2902
|
-
const
|
|
2903
|
-
|
|
2904
|
-
const body = okFn(data);
|
|
2905
|
-
return ctx.json(body);
|
|
3037
|
+
const body = wrapOkResult(data, config);
|
|
3038
|
+
return jsonOk(body, 200);
|
|
2906
3039
|
},
|
|
2907
3040
|
/**
|
|
2908
3041
|
* 返回错误响应(对象形式参数,status 和 code 均可省略)
|
|
2909
3042
|
*
|
|
3043
|
+
* 实现委托给 [responseFormatter.formatFailResponse](../response/responseFormatter.ts),
|
|
3044
|
+
* 与 formatErrorResponse(handler 抛错兜底)共享同一套 fail 函数,确保错误格式一致。
|
|
3045
|
+
*
|
|
2910
3046
|
* - status 省略时 HTTP 状态码默认 500
|
|
2911
3047
|
* - code 省略时响应 body 里不含 code 字段(默认 fail 函数只放非 undefined 的字段)
|
|
2912
3048
|
* - status 和 code 独立无关联
|
|
@@ -2914,18 +3050,7 @@ function createContext(request, params, config = {}, ip = "") {
|
|
|
2914
3050
|
* body 用 config.response.fail(或默认实现)包装。
|
|
2915
3051
|
*/
|
|
2916
3052
|
fail(options) {
|
|
2917
|
-
|
|
2918
|
-
const failFn = responseConfig?.fail ?? ((e) => {
|
|
2919
|
-
const error = { message: e.message };
|
|
2920
|
-
if (e.code !== void 0) error.code = e.code;
|
|
2921
|
-
return { error };
|
|
2922
|
-
});
|
|
2923
|
-
const body = failFn({
|
|
2924
|
-
status: options.status,
|
|
2925
|
-
code: options.code,
|
|
2926
|
-
message: options.message
|
|
2927
|
-
});
|
|
2928
|
-
return ctx.json(body, options.status ?? 500);
|
|
3053
|
+
return formatFailResponse(options, config);
|
|
2929
3054
|
}
|
|
2930
3055
|
};
|
|
2931
3056
|
const extend = config?.extendContext;
|
|
@@ -3191,10 +3316,7 @@ async function injectParamsAsync(handler, ctx, body, injectors) {
|
|
|
3191
3316
|
|
|
3192
3317
|
// src/runtime/invokeHandler.ts
|
|
3193
3318
|
function wrapResult(result, ctx) {
|
|
3194
|
-
|
|
3195
|
-
const responseConfig = ctx.config.response;
|
|
3196
|
-
const okFn = responseConfig?.ok ?? ((d) => ({ data: d }));
|
|
3197
|
-
return okFn(result);
|
|
3319
|
+
return wrapOkResult(result, ctx.config);
|
|
3198
3320
|
}
|
|
3199
3321
|
function mergeMeta(response, meta) {
|
|
3200
3322
|
const hasMeta = meta.status !== void 0 || Object.keys(meta.headers).length > 0 || meta.setCookies.length > 0;
|
|
@@ -3417,52 +3539,6 @@ import fs12 from "fs";
|
|
|
3417
3539
|
import { WebSocketServer, WebSocket } from "ws";
|
|
3418
3540
|
import path10 from "path";
|
|
3419
3541
|
|
|
3420
|
-
// src/errors/formatErrorResponse.ts
|
|
3421
|
-
function formatErrorResponse(error) {
|
|
3422
|
-
if (error instanceof ValidationError) {
|
|
3423
|
-
const body2 = {
|
|
3424
|
-
code: error.code,
|
|
3425
|
-
message: error.message,
|
|
3426
|
-
issues: error.issues
|
|
3427
|
-
};
|
|
3428
|
-
return new Response(JSON.stringify({ error: body2 }), {
|
|
3429
|
-
status: error.statusCode,
|
|
3430
|
-
headers: { "Content-Type": "application/json" }
|
|
3431
|
-
});
|
|
3432
|
-
}
|
|
3433
|
-
if (error instanceof MethodNotAllowedError) {
|
|
3434
|
-
const body2 = {
|
|
3435
|
-
code: error.code,
|
|
3436
|
-
message: error.message
|
|
3437
|
-
};
|
|
3438
|
-
return new Response(JSON.stringify({ error: body2 }), {
|
|
3439
|
-
status: error.statusCode,
|
|
3440
|
-
headers: {
|
|
3441
|
-
"Content-Type": "application/json",
|
|
3442
|
-
Allow: error.allowedMethods.join(", ")
|
|
3443
|
-
}
|
|
3444
|
-
});
|
|
3445
|
-
}
|
|
3446
|
-
if (error instanceof FaapiError) {
|
|
3447
|
-
const body2 = {
|
|
3448
|
-
code: error.code,
|
|
3449
|
-
message: error.message
|
|
3450
|
-
};
|
|
3451
|
-
return new Response(JSON.stringify({ error: body2 }), {
|
|
3452
|
-
status: error.statusCode,
|
|
3453
|
-
headers: { "Content-Type": "application/json" }
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
|
-
const body = {
|
|
3457
|
-
code: "INTERNAL_ERROR",
|
|
3458
|
-
message: error instanceof Error ? error.message : "An unknown error occurred"
|
|
3459
|
-
};
|
|
3460
|
-
return new Response(JSON.stringify({ error: body }), {
|
|
3461
|
-
status: 500,
|
|
3462
|
-
headers: { "Content-Type": "application/json" }
|
|
3463
|
-
});
|
|
3464
|
-
}
|
|
3465
|
-
|
|
3466
3542
|
// src/server/serverUtils.ts
|
|
3467
3543
|
function nodeHttpToWebHeaders(req) {
|
|
3468
3544
|
const headers = new Headers();
|
|
@@ -3476,9 +3552,9 @@ function nodeHttpToWebHeaders(req) {
|
|
|
3476
3552
|
}
|
|
3477
3553
|
return headers;
|
|
3478
3554
|
}
|
|
3479
|
-
function buildErrorResponse(err) {
|
|
3555
|
+
function buildErrorResponse(err, config) {
|
|
3480
3556
|
try {
|
|
3481
|
-
return formatErrorResponse(err);
|
|
3557
|
+
return formatErrorResponse(err, config);
|
|
3482
3558
|
} catch {
|
|
3483
3559
|
return new Response(
|
|
3484
3560
|
JSON.stringify({ error: { code: "INTERNAL_ERROR", message: "Internal Server Error" } }),
|
|
@@ -3502,37 +3578,42 @@ function setCachedMiddlewares(absPath, bundle) {
|
|
|
3502
3578
|
middlewareCache.set(absPath, bundle);
|
|
3503
3579
|
}
|
|
3504
3580
|
async function loadMiddlewaresFile(filePath) {
|
|
3581
|
+
let module;
|
|
3505
3582
|
try {
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
return true;
|
|
3518
|
-
});
|
|
3519
|
-
const injectors = module.injectors ?? {};
|
|
3520
|
-
if (typeof injectors !== "object" || injectors === null) {
|
|
3521
|
-
console.warn(`[faapi] injectors \u5E94\u5BFC\u51FA\u5BF9\u8C61\uFF0C\u5DF2\u5FFD\u7565: ${filePath}`);
|
|
3522
|
-
return { middlewares: validMiddlewares, injectors: {} };
|
|
3523
|
-
}
|
|
3524
|
-
const validInjectors = {};
|
|
3525
|
-
for (const [name, injector] of Object.entries(injectors)) {
|
|
3526
|
-
if (typeof injector !== "function") {
|
|
3527
|
-
console.warn(`[faapi] \u6CE8\u5165\u5668 ${name} \u5E94\u4E3A\u51FD\u6570\uFF0C\u5DF2\u5FFD\u7565`);
|
|
3528
|
-
continue;
|
|
3529
|
-
}
|
|
3530
|
-
validInjectors[name] = injector;
|
|
3531
|
-
}
|
|
3532
|
-
return { middlewares: validMiddlewares, injectors: validInjectors };
|
|
3533
|
-
} catch {
|
|
3583
|
+
module = await importWithCacheBust(filePath);
|
|
3584
|
+
} catch (err) {
|
|
3585
|
+
console.error(
|
|
3586
|
+
`[faapi] Failed to load middlewares from ${filePath}:`,
|
|
3587
|
+
err instanceof Error ? err.stack ?? err.message : err
|
|
3588
|
+
);
|
|
3589
|
+
return { middlewares: [], injectors: {} };
|
|
3590
|
+
}
|
|
3591
|
+
const middlewares = module.default ?? module.middlewares ?? [];
|
|
3592
|
+
if (!Array.isArray(middlewares)) {
|
|
3593
|
+
console.warn(`[faapi] middlewares.ts \u5E94\u5BFC\u51FA\u6570\u7EC4\uFF0C\u5DF2\u5FFD\u7565: ${filePath}`);
|
|
3534
3594
|
return { middlewares: [], injectors: {} };
|
|
3535
3595
|
}
|
|
3596
|
+
const validMiddlewares = middlewares.filter((m) => {
|
|
3597
|
+
if (typeof m !== "function") {
|
|
3598
|
+
console.warn(`[faapi] \u65E0\u6548\u7684\u4E2D\u95F4\u4EF6\u9879\uFF08\u5E94\u4E3A\u51FD\u6570\uFF09\uFF0C\u5DF2\u5FFD\u7565: ${typeof m}`);
|
|
3599
|
+
return false;
|
|
3600
|
+
}
|
|
3601
|
+
return true;
|
|
3602
|
+
});
|
|
3603
|
+
const injectors = module.injectors ?? {};
|
|
3604
|
+
if (typeof injectors !== "object" || injectors === null) {
|
|
3605
|
+
console.warn(`[faapi] injectors \u5E94\u5BFC\u51FA\u5BF9\u8C61\uFF0C\u5DF2\u5FFD\u7565: ${filePath}`);
|
|
3606
|
+
return { middlewares: validMiddlewares, injectors: {} };
|
|
3607
|
+
}
|
|
3608
|
+
const validInjectors = {};
|
|
3609
|
+
for (const [name, injector] of Object.entries(injectors)) {
|
|
3610
|
+
if (typeof injector !== "function") {
|
|
3611
|
+
console.warn(`[faapi] \u6CE8\u5165\u5668 ${name} \u5E94\u4E3A\u51FD\u6570\uFF0C\u5DF2\u5FFD\u7565`);
|
|
3612
|
+
continue;
|
|
3613
|
+
}
|
|
3614
|
+
validInjectors[name] = injector;
|
|
3615
|
+
}
|
|
3616
|
+
return { middlewares: validMiddlewares, injectors: validInjectors };
|
|
3536
3617
|
}
|
|
3537
3618
|
async function loadMergedMiddlewares(middlewarePaths) {
|
|
3538
3619
|
if (middlewarePaths.length === 0) return void 0;
|
|
@@ -3739,25 +3820,51 @@ function toWebRequest(req, bodyLimit = DEFAULT_BODY_LIMIT) {
|
|
|
3739
3820
|
}
|
|
3740
3821
|
function limitStreamSize(stream, maxSize) {
|
|
3741
3822
|
let totalSize = 0;
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
controller.close();
|
|
3823
|
+
let reader;
|
|
3824
|
+
let errored = false;
|
|
3825
|
+
const releaseReader = () => {
|
|
3826
|
+
if (reader) {
|
|
3827
|
+
try {
|
|
3748
3828
|
reader.releaseLock();
|
|
3749
|
-
|
|
3829
|
+
} catch {
|
|
3750
3830
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3831
|
+
reader = void 0;
|
|
3832
|
+
}
|
|
3833
|
+
};
|
|
3834
|
+
const failStream = (controller, err) => {
|
|
3835
|
+
if (errored) return;
|
|
3836
|
+
errored = true;
|
|
3837
|
+
controller.error(err instanceof Error ? err : new Error(String(err)));
|
|
3838
|
+
releaseReader();
|
|
3839
|
+
};
|
|
3840
|
+
return new ReadableStream({
|
|
3841
|
+
async pull(controller) {
|
|
3842
|
+
if (!reader) reader = stream.getReader();
|
|
3843
|
+
try {
|
|
3844
|
+
const { done, value } = await reader.read();
|
|
3845
|
+
if (done) {
|
|
3846
|
+
controller.close();
|
|
3847
|
+
releaseReader();
|
|
3848
|
+
return;
|
|
3849
|
+
}
|
|
3850
|
+
totalSize += value.byteLength;
|
|
3851
|
+
if (totalSize > maxSize) {
|
|
3852
|
+
failStream(controller, new PayloadTooLargeError(maxSize));
|
|
3853
|
+
return;
|
|
3854
|
+
}
|
|
3855
|
+
controller.enqueue(value);
|
|
3856
|
+
} catch (err) {
|
|
3857
|
+
failStream(controller, err);
|
|
3756
3858
|
}
|
|
3757
|
-
controller.enqueue(value);
|
|
3758
3859
|
},
|
|
3759
3860
|
cancel(reason) {
|
|
3760
|
-
reader
|
|
3861
|
+
if (reader) {
|
|
3862
|
+
try {
|
|
3863
|
+
reader.cancel(reason);
|
|
3864
|
+
} catch {
|
|
3865
|
+
}
|
|
3866
|
+
releaseReader();
|
|
3867
|
+
}
|
|
3761
3868
|
}
|
|
3762
3869
|
});
|
|
3763
3870
|
}
|
|
@@ -3838,21 +3945,27 @@ function createServer(options) {
|
|
|
3838
3945
|
}
|
|
3839
3946
|
return { server, routesRef };
|
|
3840
3947
|
}
|
|
3841
|
-
|
|
3948
|
+
function prepareRequest(req, config, bodyLimit) {
|
|
3842
3949
|
const request = toWebRequest(req, bodyLimit);
|
|
3843
3950
|
const method = request.method.toUpperCase();
|
|
3844
3951
|
const urlPath = new URL(request.url).pathname;
|
|
3845
3952
|
const ctx = createContext(request, {}, config, getClientIp(req));
|
|
3846
3953
|
const meta = ctx.meta;
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3954
|
+
return { request, ctx, meta, method, urlPath };
|
|
3955
|
+
}
|
|
3956
|
+
function resolveRouteOrThrow(routes, method, urlPath) {
|
|
3957
|
+
const match = matchRoute(routes, method, urlPath);
|
|
3958
|
+
if (match) return match;
|
|
3959
|
+
const allowedMethods = findAllowedMethods(routes, urlPath);
|
|
3960
|
+
if (allowedMethods.length > 0) {
|
|
3961
|
+
throw new MethodNotAllowedError(method, urlPath, allowedMethods);
|
|
3962
|
+
}
|
|
3963
|
+
throw new RouteNotFoundError(urlPath);
|
|
3964
|
+
}
|
|
3965
|
+
function createRoutePipeline(opts) {
|
|
3966
|
+
const { routes, method, urlPath, ctx, request, rootDir, dist, globalInjectors } = opts;
|
|
3967
|
+
return async () => {
|
|
3968
|
+
const match = resolveRouteOrThrow(routes, method, urlPath);
|
|
3856
3969
|
ctx.params = match.params;
|
|
3857
3970
|
const { route } = match;
|
|
3858
3971
|
const absoluteFilePath = path11.resolve(rootDir, route.filePath);
|
|
@@ -3882,37 +3995,44 @@ async function handleRequest(routes, rootDir, dist, req, res, configMiddlewares,
|
|
|
3882
3995
|
}
|
|
3883
3996
|
}
|
|
3884
3997
|
const mergedInjectors = globalInjectors ? { ...globalInjectors, ...route.injectors } : route.injectors;
|
|
3885
|
-
|
|
3886
|
-
routeModule.handler,
|
|
3887
|
-
ctx,
|
|
3888
|
-
body,
|
|
3889
|
-
route.middlewares,
|
|
3890
|
-
mergedInjectors
|
|
3891
|
-
);
|
|
3892
|
-
return response;
|
|
3998
|
+
return await invokeHandler(routeModule.handler, ctx, body, route.middlewares, mergedInjectors);
|
|
3893
3999
|
};
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
}
|
|
3904
|
-
response = await routePipeline();
|
|
4000
|
+
}
|
|
4001
|
+
async function sendSuccessResponse(response, res) {
|
|
4002
|
+
await sendNodeResponse(response, res);
|
|
4003
|
+
}
|
|
4004
|
+
async function sendErrorResponse(err, meta, res, onError, ctx) {
|
|
4005
|
+
await sendNodeResponse(mergeMeta(buildErrorResponse(err, ctx.config), meta), res);
|
|
4006
|
+
if (onError) {
|
|
4007
|
+
try {
|
|
4008
|
+
await onError(err, ctx);
|
|
4009
|
+
} catch {
|
|
3905
4010
|
}
|
|
3906
|
-
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
async function handleRequest(routes, rootDir, dist, req, res, configMiddlewares, onError, config, globalMiddlewares, globalInjectors, bodyLimit) {
|
|
4014
|
+
const { request, ctx, meta, method, urlPath } = prepareRequest(req, config, bodyLimit);
|
|
4015
|
+
const routePipeline = createRoutePipeline({
|
|
4016
|
+
routes,
|
|
4017
|
+
method,
|
|
4018
|
+
urlPath,
|
|
4019
|
+
ctx,
|
|
4020
|
+
request,
|
|
4021
|
+
rootDir,
|
|
4022
|
+
dist,
|
|
4023
|
+
globalMiddlewares,
|
|
4024
|
+
globalInjectors
|
|
4025
|
+
});
|
|
4026
|
+
const outerMiddlewares = [];
|
|
4027
|
+
if (configMiddlewares.length > 0) outerMiddlewares.push(...configMiddlewares);
|
|
4028
|
+
if (globalMiddlewares && globalMiddlewares.length > 0) {
|
|
4029
|
+
outerMiddlewares.push(...globalMiddlewares);
|
|
4030
|
+
}
|
|
4031
|
+
try {
|
|
4032
|
+
const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
|
|
4033
|
+
await sendSuccessResponse(response, res);
|
|
3907
4034
|
} catch (err) {
|
|
3908
|
-
|
|
3909
|
-
await sendNodeResponse(mergeMeta(errorResponse, meta), res);
|
|
3910
|
-
if (onError) {
|
|
3911
|
-
try {
|
|
3912
|
-
await onError(err, ctx);
|
|
3913
|
-
} catch {
|
|
3914
|
-
}
|
|
3915
|
-
}
|
|
4035
|
+
await sendErrorResponse(err, meta, res, onError, ctx);
|
|
3916
4036
|
}
|
|
3917
4037
|
}
|
|
3918
4038
|
|
|
@@ -4011,7 +4131,6 @@ function extractAgentMetadata(program, filePath, pathMeta) {
|
|
|
4011
4131
|
name: agentNameOverride ?? pathMeta.name,
|
|
4012
4132
|
description,
|
|
4013
4133
|
filePath: pathMeta.filePath,
|
|
4014
|
-
hasConfig: pathMeta.hasConfig,
|
|
4015
4134
|
hasRun: pathMeta.hasRun,
|
|
4016
4135
|
systemPrompt,
|
|
4017
4136
|
tools,
|
|
@@ -4177,7 +4296,6 @@ function serializeAgents(agents, dist = "dist") {
|
|
|
4177
4296
|
return agents.map((a) => ({
|
|
4178
4297
|
name: a.name,
|
|
4179
4298
|
description: a.description,
|
|
4180
|
-
hasConfig: a.hasConfig,
|
|
4181
4299
|
hasRun: a.hasRun,
|
|
4182
4300
|
systemPrompt: a.systemPrompt,
|
|
4183
4301
|
tools: a.tools,
|
|
@@ -4200,7 +4318,6 @@ function hydrateAgents(manifest) {
|
|
|
4200
4318
|
name: a.name,
|
|
4201
4319
|
description: a.description ?? void 0,
|
|
4202
4320
|
filePath: a.filePath,
|
|
4203
|
-
hasConfig: a.hasConfig,
|
|
4204
4321
|
hasRun: a.hasRun,
|
|
4205
4322
|
systemPrompt: a.systemPrompt ?? void 0,
|
|
4206
4323
|
tools: a.tools ?? void 0,
|
|
@@ -4217,7 +4334,6 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
4217
4334
|
const result = extractAgentMetadata(program, absPath, {
|
|
4218
4335
|
name: manifest.name,
|
|
4219
4336
|
filePath: manifest.filePath,
|
|
4220
|
-
hasConfig: manifest.hasConfig,
|
|
4221
4337
|
hasRun: manifest.hasRun
|
|
4222
4338
|
});
|
|
4223
4339
|
if (result) {
|
|
@@ -4435,10 +4551,8 @@ async function createAppBase(options) {
|
|
|
4435
4551
|
if (agents.length > 0) {
|
|
4436
4552
|
console.log(`- Loaded ${agents.length} agent(s):`);
|
|
4437
4553
|
for (const agent of agents) {
|
|
4438
|
-
const exports =
|
|
4439
|
-
|
|
4440
|
-
if (agent.hasRun) exports.push("run");
|
|
4441
|
-
console.log(` ${agent.name} [${exports.join("+")}] ${agent.filePath}`);
|
|
4554
|
+
const exports = agent.hasRun ? "run" : "-";
|
|
4555
|
+
console.log(` ${agent.name} [${exports}] ${agent.filePath}`);
|
|
4442
4556
|
}
|
|
4443
4557
|
}
|
|
4444
4558
|
if (config?.lifecycle?.onClose) {
|
|
@@ -4540,6 +4654,7 @@ async function createAppBase(options) {
|
|
|
4540
4654
|
}
|
|
4541
4655
|
clearToolRegistry();
|
|
4542
4656
|
clearAgentRegistry();
|
|
4657
|
+
clearSkillRegistry();
|
|
4543
4658
|
clearAgentHandleFactory();
|
|
4544
4659
|
if (!server.listening) {
|
|
4545
4660
|
app.server = null;
|
|
@@ -4831,7 +4946,6 @@ import fg4 from "fast-glob";
|
|
|
4831
4946
|
import path17 from "path";
|
|
4832
4947
|
import fs18 from "fs";
|
|
4833
4948
|
var DEFAULT_AGENT_PATTERNS = ["src/agents/*/handler.ts"];
|
|
4834
|
-
var CONFIG_EXPORT_RE = /export\s+(?:const|function)\s+config\b/;
|
|
4835
4949
|
var RUN_EXPORT_RE = /export\s+(?:async\s+)?(?:function\s+|const\s+)run\b/;
|
|
4836
4950
|
function extractAgentNameFromPath(filePath) {
|
|
4837
4951
|
const normalized = filePath.replace(/\\/g, "/");
|
|
@@ -4845,7 +4959,6 @@ function extractAgentNameFromPath(filePath) {
|
|
|
4845
4959
|
}
|
|
4846
4960
|
function detectAgentExports(source) {
|
|
4847
4961
|
return {
|
|
4848
|
-
hasConfig: CONFIG_EXPORT_RE.test(source),
|
|
4849
4962
|
hasRun: RUN_EXPORT_RE.test(source)
|
|
4850
4963
|
};
|
|
4851
4964
|
}
|
|
@@ -4865,7 +4978,7 @@ async function scanAgents(rootDir, patterns) {
|
|
|
4865
4978
|
}
|
|
4866
4979
|
const absPath = path17.resolve(rootDir, normalizedFile);
|
|
4867
4980
|
const source = await fs18.promises.readFile(absPath, "utf8").catch(() => "");
|
|
4868
|
-
const {
|
|
4981
|
+
const { hasRun } = detectAgentExports(source);
|
|
4869
4982
|
const name = extractAgentNameFromPath(normalizedFile);
|
|
4870
4983
|
const prevFile = seen.get(name);
|
|
4871
4984
|
if (prevFile) {
|
|
@@ -4877,7 +4990,6 @@ async function scanAgents(rootDir, patterns) {
|
|
|
4877
4990
|
agents.push({
|
|
4878
4991
|
name,
|
|
4879
4992
|
filePath: normalizedFile,
|
|
4880
|
-
hasConfig,
|
|
4881
4993
|
hasRun
|
|
4882
4994
|
});
|
|
4883
4995
|
}
|
|
@@ -4947,11 +5059,15 @@ export {
|
|
|
4947
5059
|
createProgram,
|
|
4948
5060
|
extractTypeInfo,
|
|
4949
5061
|
getAgent,
|
|
5062
|
+
getAgentEntry,
|
|
4950
5063
|
getApp,
|
|
4951
5064
|
getInputTypeForMethod,
|
|
5065
|
+
getSkill,
|
|
4952
5066
|
getTool,
|
|
4953
5067
|
helmet,
|
|
5068
|
+
hydrateSkillRegistry,
|
|
4954
5069
|
invalidateProgramCache,
|
|
5070
|
+
listSkills,
|
|
4955
5071
|
loadAgentModule,
|
|
4956
5072
|
loadConfig,
|
|
4957
5073
|
loadEnv,
|
|
@@ -4959,8 +5075,10 @@ export {
|
|
|
4959
5075
|
loadToolSchema,
|
|
4960
5076
|
logger,
|
|
4961
5077
|
registerAgentHandleFactory,
|
|
5078
|
+
removeSkill,
|
|
4962
5079
|
resolveAgentTools,
|
|
4963
5080
|
resolveSubAgents,
|
|
4964
|
-
resolveTypeNode
|
|
5081
|
+
resolveTypeNode,
|
|
5082
|
+
upsertSkill
|
|
4965
5083
|
};
|
|
4966
5084
|
//# sourceMappingURL=index.js.map
|