@faapi/faapi 6.22.0 → 6.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +369 -256
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +31 -2
- package/dist/index.js +149 -111
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-CXWkRx4W.d.ts → routeTypes-CJV5M90s.d.ts} +8 -0
- package/dist/testing.d.ts +3 -1
- package/dist/testing.js +80 -47
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
|
@@ -1025,6 +1025,14 @@ interface FaapiContext {
|
|
|
1025
1025
|
cookies: Record<string, string>;
|
|
1026
1026
|
/** 配置文件中的自定义业务配置(类型可通过 declare module '@faapi/faapi' 增强 FaapiContextConfig) */
|
|
1027
1027
|
config: FaapiContextConfig;
|
|
1028
|
+
/**
|
|
1029
|
+
* 运行时资源根目录绝对路径(<rootDir>/<dist>/resources)
|
|
1030
|
+
*
|
|
1031
|
+
* `src/resources/` 经 dev/build 复制进产物后的位置,handler 读静态文件用:
|
|
1032
|
+
* `await fs.readFile(path.join(ctx.resourcesDir, 'prompts/foo.md'))`。
|
|
1033
|
+
* HTTP/WS 请求链路恒有值;testing 直调(createTestContext)未传时为 undefined。
|
|
1034
|
+
*/
|
|
1035
|
+
resourcesDir?: string;
|
|
1028
1036
|
/**
|
|
1029
1037
|
* 设置响应状态码
|
|
1030
1038
|
*/
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as FaapiContext, F as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions } from './routeTypes-
|
|
1
|
+
import { a as FaapiContext, F as FaapiMiddleware, I as InjectorMap, R as RouteManifest, W as WsRouteManifest, C as CorsOptions, H as HelmetOptions } from './routeTypes-CJV5M90s.js';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
3
|
import { WebSocket } from 'ws';
|
|
4
4
|
|
|
@@ -25,6 +25,8 @@ declare function createTestContext(options: CreateTestContextOptions): FaapiCont
|
|
|
25
25
|
interface CreateTestContextOptions {
|
|
26
26
|
/** app 级注册表(测试 handler 声明 agent/agents 参数时注入用,可选) */
|
|
27
27
|
registries?: FaapiContext['registries'];
|
|
28
|
+
/** 运行时资源根目录(测试 handler 读 ctx.resourcesDir 时传入,可选) */
|
|
29
|
+
resourcesDir?: string;
|
|
28
30
|
/** 请求方法,默认 'GET' */
|
|
29
31
|
method?: string;
|
|
30
32
|
/** 请求路径,必填,如 '/api/user'(无需写 host) */
|
package/dist/testing.js
CHANGED
|
@@ -312,14 +312,14 @@ var ValidationError = class extends FaapiError {
|
|
|
312
312
|
issues;
|
|
313
313
|
};
|
|
314
314
|
var RouteNotFoundError = class extends FaapiError {
|
|
315
|
-
constructor(
|
|
316
|
-
super("ROUTE_NOT_FOUND", `Route not found: ${
|
|
315
|
+
constructor(path17) {
|
|
316
|
+
super("ROUTE_NOT_FOUND", `Route not found: ${path17}`, 404);
|
|
317
317
|
this.name = "RouteNotFoundError";
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
var MethodNotAllowedError = class extends FaapiError {
|
|
321
|
-
constructor(method,
|
|
322
|
-
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${
|
|
321
|
+
constructor(method, path17, allowedMethods) {
|
|
322
|
+
super("METHOD_NOT_ALLOWED", `Method ${method} not allowed for ${path17}`, 405);
|
|
323
323
|
this.allowedMethods = allowedMethods;
|
|
324
324
|
this.name = "MethodNotAllowedError";
|
|
325
325
|
}
|
|
@@ -584,10 +584,18 @@ function formatSetCookie(name, value, options) {
|
|
|
584
584
|
if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
|
|
585
585
|
return cookie;
|
|
586
586
|
}
|
|
587
|
-
function createContext(request, params, config = {}, ip = "", registries) {
|
|
588
|
-
return createContextFromUrl(
|
|
587
|
+
function createContext(request, params, config = {}, ip = "", registries, resourcesDir) {
|
|
588
|
+
return createContextFromUrl(
|
|
589
|
+
request,
|
|
590
|
+
new URL(request.url),
|
|
591
|
+
params,
|
|
592
|
+
config,
|
|
593
|
+
ip,
|
|
594
|
+
registries,
|
|
595
|
+
resourcesDir
|
|
596
|
+
);
|
|
589
597
|
}
|
|
590
|
-
function createContextFromUrl(request, url, params, config = {}, ip = "", registries) {
|
|
598
|
+
function createContextFromUrl(request, url, params, config = {}, ip = "", registries, resourcesDir) {
|
|
591
599
|
const meta = { headers: {}, setCookies: [] };
|
|
592
600
|
const parsedCookies = parseCookies(request.headers.get("cookie") ?? "");
|
|
593
601
|
const cookiesObj = {};
|
|
@@ -615,6 +623,9 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
|
|
|
615
623
|
ua: request.headers.get("user-agent") ?? "",
|
|
616
624
|
cookies: cookiesObj,
|
|
617
625
|
config,
|
|
626
|
+
// 运行时资源根目录(HTTP/WS 链路由 createServer/handleWsUpgrade 传入;
|
|
627
|
+
// testing 直调未传时为 undefined,见 contextTypes.resourcesDir 注释)
|
|
628
|
+
resourcesDir,
|
|
618
629
|
meta,
|
|
619
630
|
setStatus(status) {
|
|
620
631
|
meta.status = status;
|
|
@@ -720,15 +731,16 @@ function createContextFromUrl(request, url, params, config = {}, ip = "", regist
|
|
|
720
731
|
function createTestContext(options) {
|
|
721
732
|
const {
|
|
722
733
|
method = "GET",
|
|
723
|
-
path:
|
|
734
|
+
path: path17,
|
|
724
735
|
query,
|
|
725
736
|
headers,
|
|
726
737
|
params = {},
|
|
727
738
|
config = {},
|
|
728
739
|
ip = "",
|
|
729
|
-
registries
|
|
740
|
+
registries,
|
|
741
|
+
resourcesDir
|
|
730
742
|
} = options;
|
|
731
|
-
const url = new URL(`http://localhost${
|
|
743
|
+
const url = new URL(`http://localhost${path17}`);
|
|
732
744
|
if (query) {
|
|
733
745
|
for (const [key, value] of Object.entries(query)) {
|
|
734
746
|
if (Array.isArray(value)) {
|
|
@@ -744,7 +756,7 @@ function createTestContext(options) {
|
|
|
744
756
|
method,
|
|
745
757
|
headers
|
|
746
758
|
});
|
|
747
|
-
return createContext(request, params, config, ip, registries);
|
|
759
|
+
return createContext(request, params, config, ip, registries, resourcesDir);
|
|
748
760
|
}
|
|
749
761
|
|
|
750
762
|
// src/response/pendingMeta.ts
|
|
@@ -1327,9 +1339,9 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
1327
1339
|
}
|
|
1328
1340
|
|
|
1329
1341
|
// src/testServer.ts
|
|
1330
|
-
import
|
|
1342
|
+
import path16 from "path";
|
|
1331
1343
|
import os from "os";
|
|
1332
|
-
import
|
|
1344
|
+
import fs13 from "fs/promises";
|
|
1333
1345
|
|
|
1334
1346
|
// src/router/scanRoutes.ts
|
|
1335
1347
|
import fg from "fast-glob";
|
|
@@ -1341,9 +1353,9 @@ var HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
|
1341
1353
|
var HTTP_METHOD_SET = new Set(HTTP_METHODS);
|
|
1342
1354
|
|
|
1343
1355
|
// src/utils/normalizePath.ts
|
|
1344
|
-
function normalizePath(
|
|
1345
|
-
if (!
|
|
1346
|
-
let result =
|
|
1356
|
+
function normalizePath(path17) {
|
|
1357
|
+
if (!path17) return "";
|
|
1358
|
+
let result = path17.replace(/\\/g, "/");
|
|
1347
1359
|
result = result.replace(/\/+/g, "/");
|
|
1348
1360
|
result = result.replace(/\/+$/, "");
|
|
1349
1361
|
if (result && !result.startsWith("/")) {
|
|
@@ -3511,13 +3523,14 @@ function buildAliasPlugins(rootDir) {
|
|
|
3511
3523
|
}
|
|
3512
3524
|
|
|
3513
3525
|
// src/cli/compileSourceFiles.ts
|
|
3526
|
+
var SOURCE_IGNORE = ["**/*.test.ts", "**/*.e2e.test.ts", "**/*.d.ts", `${APP_DIR}/resources/**`];
|
|
3514
3527
|
async function compileSourceFiles(options) {
|
|
3515
3528
|
const { rootDir, dist, files, logLevel = "silent", production, atomicWrite } = options;
|
|
3516
3529
|
const entryPoints = files ?? await fg2([`${APP_DIR}/**/*.ts`], {
|
|
3517
3530
|
cwd: rootDir,
|
|
3518
3531
|
onlyFiles: true,
|
|
3519
3532
|
absolute: true,
|
|
3520
|
-
ignore:
|
|
3533
|
+
ignore: SOURCE_IGNORE
|
|
3521
3534
|
});
|
|
3522
3535
|
if (entryPoints.length === 0) {
|
|
3523
3536
|
return { compiledFiles: [] };
|
|
@@ -3821,9 +3834,9 @@ async function validateInput(schemaPath, method, inputType, input) {
|
|
|
3821
3834
|
function mapZodIssues(error) {
|
|
3822
3835
|
return error.issues.map((issue) => {
|
|
3823
3836
|
const code = mapZodCode(issue);
|
|
3824
|
-
const
|
|
3837
|
+
const path17 = issue.path.map(String).join(".") || "";
|
|
3825
3838
|
return {
|
|
3826
|
-
path:
|
|
3839
|
+
path: path17,
|
|
3827
3840
|
code,
|
|
3828
3841
|
expected: issue.expected ?? mapExpectedFromMessage(issue.message),
|
|
3829
3842
|
received: issue.received ?? mapReceivedFromMessage(issue.message),
|
|
@@ -3873,7 +3886,7 @@ import {
|
|
|
3873
3886
|
import { createSecureServer as createHttp2SecureServer } from "http2";
|
|
3874
3887
|
import { readFileSync } from "fs";
|
|
3875
3888
|
import { Readable as Readable2 } from "stream";
|
|
3876
|
-
import
|
|
3889
|
+
import path15 from "path";
|
|
3877
3890
|
|
|
3878
3891
|
// src/router/matchRoute.ts
|
|
3879
3892
|
var httpIndexCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -3915,25 +3928,25 @@ function getWsIndex(routes) {
|
|
|
3915
3928
|
wsIndexCache.set(routes, index);
|
|
3916
3929
|
return index;
|
|
3917
3930
|
}
|
|
3918
|
-
function matchRoute(routes, method,
|
|
3931
|
+
function matchRoute(routes, method, path17) {
|
|
3919
3932
|
const index = getHttpIndex(routes);
|
|
3920
3933
|
const upper = method.toUpperCase();
|
|
3921
|
-
const hit = matchByMethod(index, upper,
|
|
3934
|
+
const hit = matchByMethod(index, upper, path17);
|
|
3922
3935
|
if (hit) return hit;
|
|
3923
3936
|
if (upper === "HEAD") {
|
|
3924
|
-
return matchByMethod(index, "GET",
|
|
3937
|
+
return matchByMethod(index, "GET", path17);
|
|
3925
3938
|
}
|
|
3926
3939
|
return null;
|
|
3927
3940
|
}
|
|
3928
|
-
function matchByMethod(index, method,
|
|
3929
|
-
const staticHit = index.static.get(`${method}|${
|
|
3941
|
+
function matchByMethod(index, method, path17) {
|
|
3942
|
+
const staticHit = index.static.get(`${method}|${path17}`);
|
|
3930
3943
|
if (staticHit) {
|
|
3931
3944
|
return { route: staticHit, params: {} };
|
|
3932
3945
|
}
|
|
3933
3946
|
if (index.dynamics.length === 0) {
|
|
3934
3947
|
return null;
|
|
3935
3948
|
}
|
|
3936
|
-
const pathSegments =
|
|
3949
|
+
const pathSegments = path17.split("/").filter(Boolean);
|
|
3937
3950
|
for (const entry of index.dynamics) {
|
|
3938
3951
|
const route = entry.route;
|
|
3939
3952
|
if (route.method !== method) {
|
|
@@ -3946,31 +3959,31 @@ function matchByMethod(index, method, path16) {
|
|
|
3946
3959
|
}
|
|
3947
3960
|
return null;
|
|
3948
3961
|
}
|
|
3949
|
-
function matchWsRoute(wsRoutes,
|
|
3962
|
+
function matchWsRoute(wsRoutes, path17) {
|
|
3950
3963
|
const index = getWsIndex(wsRoutes);
|
|
3951
|
-
const staticHit = index.static.get(
|
|
3964
|
+
const staticHit = index.static.get(path17);
|
|
3952
3965
|
if (staticHit) {
|
|
3953
3966
|
return { route: staticHit, params: {} };
|
|
3954
3967
|
}
|
|
3955
3968
|
for (const route of index.dynamics) {
|
|
3956
|
-
const params = matchDynamicPath(route.urlPath,
|
|
3969
|
+
const params = matchDynamicPath(route.urlPath, path17, route.paramNames, route.isCatchAll);
|
|
3957
3970
|
if (params !== null) {
|
|
3958
3971
|
return { route, params };
|
|
3959
3972
|
}
|
|
3960
3973
|
}
|
|
3961
3974
|
return null;
|
|
3962
3975
|
}
|
|
3963
|
-
function findAllowedMethods(routes,
|
|
3976
|
+
function findAllowedMethods(routes, path17) {
|
|
3964
3977
|
const index = getHttpIndex(routes);
|
|
3965
3978
|
const methods = /* @__PURE__ */ new Set();
|
|
3966
|
-
const staticMethods = index.methodsByStaticPath.get(
|
|
3979
|
+
const staticMethods = index.methodsByStaticPath.get(path17);
|
|
3967
3980
|
if (staticMethods) {
|
|
3968
3981
|
for (const method of staticMethods) {
|
|
3969
3982
|
methods.add(method);
|
|
3970
3983
|
}
|
|
3971
3984
|
}
|
|
3972
3985
|
if (index.dynamics.length > 0) {
|
|
3973
|
-
const pathSegments =
|
|
3986
|
+
const pathSegments = path17.split("/").filter(Boolean);
|
|
3974
3987
|
for (const entry of index.dynamics) {
|
|
3975
3988
|
const params = matchSegments(
|
|
3976
3989
|
entry.segments,
|
|
@@ -3988,10 +4001,10 @@ function findAllowedMethods(routes, path16) {
|
|
|
3988
4001
|
}
|
|
3989
4002
|
return Array.from(methods);
|
|
3990
4003
|
}
|
|
3991
|
-
function matchDynamicPath(pattern,
|
|
4004
|
+
function matchDynamicPath(pattern, path17, paramNames, isCatchAll) {
|
|
3992
4005
|
return matchSegments(
|
|
3993
4006
|
pattern.split("/").filter(Boolean),
|
|
3994
|
-
|
|
4007
|
+
path17.split("/").filter(Boolean),
|
|
3995
4008
|
paramNames,
|
|
3996
4009
|
isCatchAll
|
|
3997
4010
|
);
|
|
@@ -4613,9 +4626,17 @@ function logger(options = {}) {
|
|
|
4613
4626
|
}
|
|
4614
4627
|
|
|
4615
4628
|
// src/server/handleWsUpgrade.ts
|
|
4616
|
-
import
|
|
4629
|
+
import fs12 from "fs";
|
|
4617
4630
|
import { WebSocketServer, WebSocket } from "ws";
|
|
4631
|
+
import path14 from "path";
|
|
4632
|
+
|
|
4633
|
+
// src/cli/copyResources.ts
|
|
4618
4634
|
import path13 from "path";
|
|
4635
|
+
import fs11 from "fs";
|
|
4636
|
+
var RESOURCES_OUTPUT_DIR = "resources";
|
|
4637
|
+
function resolveResourcesDir(rootDir, dist) {
|
|
4638
|
+
return path13.resolve(rootDir, dist, RESOURCES_OUTPUT_DIR);
|
|
4639
|
+
}
|
|
4619
4640
|
|
|
4620
4641
|
// src/server/serverUtils.ts
|
|
4621
4642
|
function nodeHttpToWebHeaders(req) {
|
|
@@ -4673,7 +4694,7 @@ async function loadWsHandler(filePath, ctx, rootDir) {
|
|
|
4673
4694
|
const dist = getDevDist();
|
|
4674
4695
|
if (dist) {
|
|
4675
4696
|
const sourcePath = prodPathToSourcePath(filePath, rootDir, dist);
|
|
4676
|
-
if (sourcePath &&
|
|
4697
|
+
if (sourcePath && fs12.existsSync(sourcePath)) {
|
|
4677
4698
|
await ensureCompiled(sourcePath, rootDir, dist);
|
|
4678
4699
|
}
|
|
4679
4700
|
}
|
|
@@ -4771,6 +4792,7 @@ function attachWebSocket(options) {
|
|
|
4771
4792
|
trustedProxy = false,
|
|
4772
4793
|
registries
|
|
4773
4794
|
} = options;
|
|
4795
|
+
const resourcesDir = resolveResourcesDir(rootDir, dist);
|
|
4774
4796
|
const wss = new WebSocketServer({ noServer: true });
|
|
4775
4797
|
server.on("upgrade", async (req, socket, head) => {
|
|
4776
4798
|
try {
|
|
@@ -4802,12 +4824,19 @@ function attachWebSocket(options) {
|
|
|
4802
4824
|
const host = req.headers.host ?? "localhost";
|
|
4803
4825
|
const fullUrl = new URL(`http://${host}${req.url ?? "/"}`);
|
|
4804
4826
|
const request = new Request(fullUrl.toString(), { method: "GET", headers });
|
|
4805
|
-
const ctx = createContext(
|
|
4827
|
+
const ctx = createContext(
|
|
4828
|
+
request,
|
|
4829
|
+
params,
|
|
4830
|
+
config,
|
|
4831
|
+
getClientIp(req, trustedProxy),
|
|
4832
|
+
registries,
|
|
4833
|
+
resourcesDir
|
|
4834
|
+
);
|
|
4806
4835
|
const meta = ctx.meta;
|
|
4807
4836
|
let upgraded = false;
|
|
4808
4837
|
const finalHandler = async () => {
|
|
4809
4838
|
const schemaPath = getRuntimeSchemaPath(route.filePath, dist, rootDir);
|
|
4810
|
-
if (
|
|
4839
|
+
if (fs12.existsSync(schemaPath)) {
|
|
4811
4840
|
if (isDevOnDemandEnabled()) {
|
|
4812
4841
|
const devDist = getDevDist();
|
|
4813
4842
|
if (devDist) {
|
|
@@ -4846,7 +4875,7 @@ function attachWebSocket(options) {
|
|
|
4846
4875
|
}
|
|
4847
4876
|
let handlers;
|
|
4848
4877
|
try {
|
|
4849
|
-
const absoluteFilePath =
|
|
4878
|
+
const absoluteFilePath = path14.resolve(rootDir, route.filePath);
|
|
4850
4879
|
handlers = await loadWsHandler(absoluteFilePath, ctx, rootDir);
|
|
4851
4880
|
} catch (err) {
|
|
4852
4881
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -5005,6 +5034,7 @@ function createServer(options) {
|
|
|
5005
5034
|
trustedProxy = false
|
|
5006
5035
|
} = options;
|
|
5007
5036
|
const routesRef = { current: routes, wsCurrent: wsRoutes ?? [] };
|
|
5037
|
+
const resourcesDir = resolveResourcesDir(rootDir, dist);
|
|
5008
5038
|
const configMiddlewares = [];
|
|
5009
5039
|
if (compressionOption) {
|
|
5010
5040
|
const compOpts = typeof compressionOption === "object" ? compressionOption : {};
|
|
@@ -5051,7 +5081,8 @@ function createServer(options) {
|
|
|
5051
5081
|
bodyLimit,
|
|
5052
5082
|
trustedProxy,
|
|
5053
5083
|
registries,
|
|
5054
|
-
routesRef.wsCurrent
|
|
5084
|
+
routesRef.wsCurrent,
|
|
5085
|
+
resourcesDir
|
|
5055
5086
|
).catch((err) => {
|
|
5056
5087
|
console.error("[faapi] Request pipeline failed after error response attempt:", err);
|
|
5057
5088
|
try {
|
|
@@ -5077,7 +5108,7 @@ function createServer(options) {
|
|
|
5077
5108
|
});
|
|
5078
5109
|
return { server, routesRef };
|
|
5079
5110
|
}
|
|
5080
|
-
function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched) {
|
|
5111
|
+
function prepareRequest(req, request, url, config, trustedProxy, registries, preMatched, resourcesDir) {
|
|
5081
5112
|
const method = request.method.toUpperCase();
|
|
5082
5113
|
const urlPath = url.pathname;
|
|
5083
5114
|
const ctx = createContextFromUrl(
|
|
@@ -5086,7 +5117,8 @@ function prepareRequest(req, request, url, config, trustedProxy, registries, pre
|
|
|
5086
5117
|
preMatched?.params ?? {},
|
|
5087
5118
|
config,
|
|
5088
5119
|
getClientIp(req, trustedProxy),
|
|
5089
|
-
registries
|
|
5120
|
+
registries,
|
|
5121
|
+
resourcesDir
|
|
5090
5122
|
);
|
|
5091
5123
|
const meta = ctx.meta;
|
|
5092
5124
|
return { request, url, ctx, meta, method, urlPath };
|
|
@@ -5105,7 +5137,7 @@ function getRoutePaths(route, rootDir, dist) {
|
|
|
5105
5137
|
let cached = routePathCache.get(route);
|
|
5106
5138
|
if (!cached) {
|
|
5107
5139
|
cached = {
|
|
5108
|
-
absFilePath:
|
|
5140
|
+
absFilePath: path15.resolve(rootDir, route.filePath),
|
|
5109
5141
|
schemaPath: getRuntimeSchemaPath(route.filePath, dist, rootDir)
|
|
5110
5142
|
};
|
|
5111
5143
|
routePathCache.set(route, cached);
|
|
@@ -5228,7 +5260,7 @@ async function sendErrorResponse(err, meta, res, onError, ctx) {
|
|
|
5228
5260
|
}
|
|
5229
5261
|
}
|
|
5230
5262
|
}
|
|
5231
|
-
async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes) {
|
|
5263
|
+
async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares, onError, config, globalInjectors, bodyLimit, trustedProxy, registries, wsRoutes, resourcesDir) {
|
|
5232
5264
|
let meta = { headers: {}, setCookies: [] };
|
|
5233
5265
|
let ctx;
|
|
5234
5266
|
let sseEarlySent = false;
|
|
@@ -5248,7 +5280,8 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
|
|
|
5248
5280
|
config,
|
|
5249
5281
|
trustedProxy,
|
|
5250
5282
|
registries,
|
|
5251
|
-
preMatched
|
|
5283
|
+
preMatched,
|
|
5284
|
+
resourcesDir
|
|
5252
5285
|
);
|
|
5253
5286
|
ctx = prepared.ctx;
|
|
5254
5287
|
meta = prepared.meta;
|
|
@@ -5313,7 +5346,7 @@ async function createTestServer(options) {
|
|
|
5313
5346
|
} = options;
|
|
5314
5347
|
const { routes, wsRoutes } = await scanRoutes(rootDir, patterns);
|
|
5315
5348
|
const sorted = sortRoutes(routes);
|
|
5316
|
-
const schemaDist = dist ?
|
|
5349
|
+
const schemaDist = dist ? path16.isAbsolute(dist) ? dist : path16.resolve(rootDir, dist) : await fs13.mkdtemp(path16.join(os.tmpdir(), "faapi-test-schema-"));
|
|
5317
5350
|
await generateSchemaFiles(sorted, rootDir, schemaDist);
|
|
5318
5351
|
const { server } = createServer({
|
|
5319
5352
|
routes: sorted,
|
|
@@ -5345,7 +5378,7 @@ async function createTestServer(options) {
|
|
|
5345
5378
|
await new Promise((resolve) => {
|
|
5346
5379
|
server.close(() => resolve());
|
|
5347
5380
|
});
|
|
5348
|
-
await
|
|
5381
|
+
await fs13.rm(schemaDist, { recursive: true, force: true }).catch(() => {
|
|
5349
5382
|
});
|
|
5350
5383
|
invalidateSchemaCache();
|
|
5351
5384
|
}
|