@faapi/faapi 6.11.0 → 6.13.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 +95 -38
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +8 -15
- package/dist/index.js +80 -33
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-m9wZHWyo.d.ts → routeTypes-CVPV8Yd3.d.ts} +3 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +79 -29
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2511,7 +2511,7 @@ function baseExpression(type, ctx) {
|
|
|
2511
2511
|
case "union":
|
|
2512
2512
|
return generateUnionExpression(type.members, ctx);
|
|
2513
2513
|
case "date":
|
|
2514
|
-
return 'z.preprocess((v) => (typeof v === "string" ? new Date(v) : v), z.date())';
|
|
2514
|
+
return 'z.preprocess((v) => (typeof v === "string" || typeof v === "number" ? new Date(v) : v), z.date())';
|
|
2515
2515
|
case "record":
|
|
2516
2516
|
return `z.record(${runtimeTypeToZodExpression(type.key, ctx)}, ${runtimeTypeToZodExpression(type.value, ctx)})`;
|
|
2517
2517
|
case "map":
|
|
@@ -6116,6 +6116,85 @@ var init_loadRouteModule = __esm({
|
|
|
6116
6116
|
}
|
|
6117
6117
|
});
|
|
6118
6118
|
|
|
6119
|
+
// src/utils/isPlainObject.ts
|
|
6120
|
+
function isPlainObject(value) {
|
|
6121
|
+
if (value === null || typeof value !== "object") {
|
|
6122
|
+
return false;
|
|
6123
|
+
}
|
|
6124
|
+
if (Array.isArray(value)) {
|
|
6125
|
+
return false;
|
|
6126
|
+
}
|
|
6127
|
+
const proto = Object.getPrototypeOf(value);
|
|
6128
|
+
return proto === null || proto === Object.prototype;
|
|
6129
|
+
}
|
|
6130
|
+
var init_isPlainObject = __esm({
|
|
6131
|
+
"src/utils/isPlainObject.ts"() {
|
|
6132
|
+
"use strict";
|
|
6133
|
+
}
|
|
6134
|
+
});
|
|
6135
|
+
|
|
6136
|
+
// src/utils/stringifyJson.ts
|
|
6137
|
+
function stringifyJson(value) {
|
|
6138
|
+
return JSON.stringify(convertValue(value, /* @__PURE__ */ new Set()));
|
|
6139
|
+
}
|
|
6140
|
+
function convertValue(value, ancestors) {
|
|
6141
|
+
if (value === null) return value;
|
|
6142
|
+
const type = typeof value;
|
|
6143
|
+
if (type === "bigint") return value.toString();
|
|
6144
|
+
if (type === "number") return Number.isFinite(value) ? value : String(value);
|
|
6145
|
+
if (type !== "object") return value;
|
|
6146
|
+
const obj = value;
|
|
6147
|
+
if (ancestors.has(obj)) {
|
|
6148
|
+
throw new TypeError("[faapi] Converting circular structure to JSON");
|
|
6149
|
+
}
|
|
6150
|
+
if (obj instanceof Date) return obj.getTime();
|
|
6151
|
+
if (obj instanceof Map) {
|
|
6152
|
+
ancestors.add(obj);
|
|
6153
|
+
const entries = Array.from(obj, ([k, v]) => [
|
|
6154
|
+
convertValue(k, ancestors),
|
|
6155
|
+
convertValue(v, ancestors)
|
|
6156
|
+
]);
|
|
6157
|
+
ancestors.delete(obj);
|
|
6158
|
+
return entries;
|
|
6159
|
+
}
|
|
6160
|
+
if (obj instanceof Set) {
|
|
6161
|
+
ancestors.add(obj);
|
|
6162
|
+
const values = Array.from(obj, (v) => convertValue(v, ancestors));
|
|
6163
|
+
ancestors.delete(obj);
|
|
6164
|
+
return values;
|
|
6165
|
+
}
|
|
6166
|
+
if (obj instanceof RegExp) return obj.toString();
|
|
6167
|
+
const toJSON = obj.toJSON;
|
|
6168
|
+
if (typeof toJSON === "function") {
|
|
6169
|
+
ancestors.add(obj);
|
|
6170
|
+
const result = convertValue(toJSON.call(obj), ancestors);
|
|
6171
|
+
ancestors.delete(obj);
|
|
6172
|
+
return result;
|
|
6173
|
+
}
|
|
6174
|
+
if (Array.isArray(obj)) {
|
|
6175
|
+
ancestors.add(obj);
|
|
6176
|
+
const arr = obj.map((item) => convertValue(item, ancestors));
|
|
6177
|
+
ancestors.delete(obj);
|
|
6178
|
+
return arr;
|
|
6179
|
+
}
|
|
6180
|
+
if (isPlainObject(obj)) {
|
|
6181
|
+
ancestors.add(obj);
|
|
6182
|
+
const out = {};
|
|
6183
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
6184
|
+
out[key] = convertValue(val, ancestors);
|
|
6185
|
+
}
|
|
6186
|
+
ancestors.delete(obj);
|
|
6187
|
+
return out;
|
|
6188
|
+
}
|
|
6189
|
+
return obj;
|
|
6190
|
+
}
|
|
6191
|
+
var init_stringifyJson = __esm({
|
|
6192
|
+
"src/utils/stringifyJson.ts"() {
|
|
6193
|
+
"use strict";
|
|
6194
|
+
init_isPlainObject();
|
|
6195
|
+
}
|
|
6196
|
+
});
|
|
6197
|
+
|
|
6119
6198
|
// src/runtime/sse.ts
|
|
6120
6199
|
function encodeSseEvent(event) {
|
|
6121
6200
|
let out = "";
|
|
@@ -6142,7 +6221,7 @@ function encodeSseEvent(event) {
|
|
|
6142
6221
|
} else if (event.data === null) {
|
|
6143
6222
|
dataStr = "null";
|
|
6144
6223
|
} else {
|
|
6145
|
-
dataStr =
|
|
6224
|
+
dataStr = stringifyJson(event.data);
|
|
6146
6225
|
}
|
|
6147
6226
|
const lines = dataStr.split("\n");
|
|
6148
6227
|
for (const line of lines) {
|
|
@@ -6173,7 +6252,9 @@ function createSseWriter() {
|
|
|
6173
6252
|
headers: {
|
|
6174
6253
|
"Content-Type": "text/event-stream",
|
|
6175
6254
|
"Cache-Control": "no-cache",
|
|
6176
|
-
Connection: "keep-alive"
|
|
6255
|
+
Connection: "keep-alive",
|
|
6256
|
+
// nginx 认到该头后按响应跳过 proxy_buffering;其他反代/客户端忽略,无副作用
|
|
6257
|
+
"X-Accel-Buffering": "no"
|
|
6177
6258
|
}
|
|
6178
6259
|
});
|
|
6179
6260
|
const writer = {
|
|
@@ -6223,6 +6304,7 @@ function createSseWriter() {
|
|
|
6223
6304
|
var init_sse = __esm({
|
|
6224
6305
|
"src/runtime/sse.ts"() {
|
|
6225
6306
|
"use strict";
|
|
6307
|
+
init_stringifyJson();
|
|
6226
6308
|
}
|
|
6227
6309
|
});
|
|
6228
6310
|
|
|
@@ -6318,7 +6400,7 @@ function jsonRaw(body, status, extraHeaders) {
|
|
|
6318
6400
|
const extra = new Headers(extraHeaders);
|
|
6319
6401
|
extra.forEach((value, key) => headers.set(key, value));
|
|
6320
6402
|
}
|
|
6321
|
-
return new Response(
|
|
6403
|
+
return new Response(stringifyJson(body), { status, headers });
|
|
6322
6404
|
}
|
|
6323
6405
|
function wrapOkResult(result, config) {
|
|
6324
6406
|
if (result instanceof Response) return result;
|
|
@@ -6385,6 +6467,7 @@ var init_responseFormatter = __esm({
|
|
|
6385
6467
|
"use strict";
|
|
6386
6468
|
init_FaapiError();
|
|
6387
6469
|
init_httpErrors();
|
|
6470
|
+
init_stringifyJson();
|
|
6388
6471
|
}
|
|
6389
6472
|
});
|
|
6390
6473
|
|
|
@@ -6931,23 +7014,6 @@ var init_resolveInput = __esm({
|
|
|
6931
7014
|
}
|
|
6932
7015
|
});
|
|
6933
7016
|
|
|
6934
|
-
// src/utils/isPlainObject.ts
|
|
6935
|
-
function isPlainObject(value) {
|
|
6936
|
-
if (value === null || typeof value !== "object") {
|
|
6937
|
-
return false;
|
|
6938
|
-
}
|
|
6939
|
-
if (Array.isArray(value)) {
|
|
6940
|
-
return false;
|
|
6941
|
-
}
|
|
6942
|
-
const proto = Object.getPrototypeOf(value);
|
|
6943
|
-
return proto === null || proto === Object.prototype;
|
|
6944
|
-
}
|
|
6945
|
-
var init_isPlainObject = __esm({
|
|
6946
|
-
"src/utils/isPlainObject.ts"() {
|
|
6947
|
-
"use strict";
|
|
6948
|
-
}
|
|
6949
|
-
});
|
|
6950
|
-
|
|
6951
7017
|
// src/response/pendingMeta.ts
|
|
6952
7018
|
function deferMetaHeaders(response, headers) {
|
|
6953
7019
|
const existing = pending.get(response);
|
|
@@ -7033,7 +7099,7 @@ async function toResponse(value, meta) {
|
|
|
7033
7099
|
});
|
|
7034
7100
|
}
|
|
7035
7101
|
if (isPlainObject(value) || Array.isArray(value)) {
|
|
7036
|
-
const body2 =
|
|
7102
|
+
const body2 = stringifyJson(value);
|
|
7037
7103
|
const headers2 = new Headers({ "Content-Type": "application/json" });
|
|
7038
7104
|
applyMeta(headers2);
|
|
7039
7105
|
return new Response(body2, {
|
|
@@ -7057,7 +7123,7 @@ async function toResponse(value, meta) {
|
|
|
7057
7123
|
headers: headers2
|
|
7058
7124
|
});
|
|
7059
7125
|
}
|
|
7060
|
-
const body =
|
|
7126
|
+
const body = stringifyJson(value);
|
|
7061
7127
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
7062
7128
|
applyMeta(headers);
|
|
7063
7129
|
return new Response(body, {
|
|
@@ -7069,6 +7135,7 @@ var init_toResponse = __esm({
|
|
|
7069
7135
|
"src/response/toResponse.ts"() {
|
|
7070
7136
|
"use strict";
|
|
7071
7137
|
init_isPlainObject();
|
|
7138
|
+
init_stringifyJson();
|
|
7072
7139
|
init_pendingMeta();
|
|
7073
7140
|
}
|
|
7074
7141
|
});
|
|
@@ -7394,9 +7461,6 @@ var init_injectParams = __esm({
|
|
|
7394
7461
|
function wrapResult(result, ctx) {
|
|
7395
7462
|
return wrapOkResult(result, ctx.config);
|
|
7396
7463
|
}
|
|
7397
|
-
function stashHandlerResult(ctx, result) {
|
|
7398
|
-
ctx.__faapiHandlerResult = result;
|
|
7399
|
-
}
|
|
7400
7464
|
function mergeMeta(response, meta) {
|
|
7401
7465
|
const hasMeta = meta.status !== void 0 || Object.keys(meta.headers).length > 0 || meta.setCookies.length > 0;
|
|
7402
7466
|
if (!hasMeta) return response;
|
|
@@ -7465,9 +7529,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
7465
7529
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
7466
7530
|
const sseResponse = pickSseAndAutoClose();
|
|
7467
7531
|
if (sseResponse) return sseResponse;
|
|
7468
|
-
|
|
7469
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
7470
|
-
return response;
|
|
7532
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
7471
7533
|
} catch (err) {
|
|
7472
7534
|
autoCloseSseOnError();
|
|
7473
7535
|
throw err;
|
|
@@ -7478,9 +7540,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
7478
7540
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
7479
7541
|
const sseResponse = pickSseAndAutoClose();
|
|
7480
7542
|
if (sseResponse) return sseResponse;
|
|
7481
|
-
|
|
7482
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
7483
|
-
return response;
|
|
7543
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
7484
7544
|
} catch (err) {
|
|
7485
7545
|
autoCloseSseOnError();
|
|
7486
7546
|
throw err;
|
|
@@ -8081,7 +8141,7 @@ var init_serverUtils = __esm({
|
|
|
8081
8141
|
function wrapWsSocket(rawSocket) {
|
|
8082
8142
|
return {
|
|
8083
8143
|
send(data) {
|
|
8084
|
-
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data :
|
|
8144
|
+
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data : stringifyJson(data);
|
|
8085
8145
|
rawSocket.send(payload);
|
|
8086
8146
|
},
|
|
8087
8147
|
close(code, reason) {
|
|
@@ -8095,6 +8155,7 @@ function wrapWsSocket(rawSocket) {
|
|
|
8095
8155
|
var init_wsHandler = __esm({
|
|
8096
8156
|
"src/runtime/wsHandler.ts"() {
|
|
8097
8157
|
"use strict";
|
|
8158
|
+
init_stringifyJson();
|
|
8098
8159
|
}
|
|
8099
8160
|
});
|
|
8100
8161
|
|
|
@@ -8582,7 +8643,6 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
|
|
|
8582
8643
|
globalInjectors
|
|
8583
8644
|
});
|
|
8584
8645
|
const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
|
|
8585
|
-
res.__faapiHandlerResult = ctx.__faapiHandlerResult;
|
|
8586
8646
|
await sendSuccessResponse(response, res);
|
|
8587
8647
|
} catch (err) {
|
|
8588
8648
|
if (res.destroyed || res.writableEnded) return;
|
|
@@ -9799,10 +9859,7 @@ async function createAppBase(options) {
|
|
|
9799
9859
|
resolve3({
|
|
9800
9860
|
status: mockRes.statusCode,
|
|
9801
9861
|
headers: new Headers(mockRes._headers),
|
|
9802
|
-
body: parsed
|
|
9803
|
-
// inject raw 捕获桥(第三跳):handler 原始返回值(handleRequest 从 ctx
|
|
9804
|
-
// 桥接到 res;未捕获时 undefined——语义见 InjectResponse.raw 注释)
|
|
9805
|
-
raw: mockRes.__faapiHandlerResult
|
|
9862
|
+
body: parsed
|
|
9806
9863
|
});
|
|
9807
9864
|
});
|
|
9808
9865
|
const listeners = server.listeners("request");
|