@faapi/faapi 6.11.0 → 6.12.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 +92 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +6 -13
- package/dist/index.js +77 -32
- package/dist/index.js.map +1 -1
- package/dist/testing.js +76 -28
- 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) {
|
|
@@ -6223,6 +6302,7 @@ function createSseWriter() {
|
|
|
6223
6302
|
var init_sse = __esm({
|
|
6224
6303
|
"src/runtime/sse.ts"() {
|
|
6225
6304
|
"use strict";
|
|
6305
|
+
init_stringifyJson();
|
|
6226
6306
|
}
|
|
6227
6307
|
});
|
|
6228
6308
|
|
|
@@ -6318,7 +6398,7 @@ function jsonRaw(body, status, extraHeaders) {
|
|
|
6318
6398
|
const extra = new Headers(extraHeaders);
|
|
6319
6399
|
extra.forEach((value, key) => headers.set(key, value));
|
|
6320
6400
|
}
|
|
6321
|
-
return new Response(
|
|
6401
|
+
return new Response(stringifyJson(body), { status, headers });
|
|
6322
6402
|
}
|
|
6323
6403
|
function wrapOkResult(result, config) {
|
|
6324
6404
|
if (result instanceof Response) return result;
|
|
@@ -6385,6 +6465,7 @@ var init_responseFormatter = __esm({
|
|
|
6385
6465
|
"use strict";
|
|
6386
6466
|
init_FaapiError();
|
|
6387
6467
|
init_httpErrors();
|
|
6468
|
+
init_stringifyJson();
|
|
6388
6469
|
}
|
|
6389
6470
|
});
|
|
6390
6471
|
|
|
@@ -6931,23 +7012,6 @@ var init_resolveInput = __esm({
|
|
|
6931
7012
|
}
|
|
6932
7013
|
});
|
|
6933
7014
|
|
|
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
7015
|
// src/response/pendingMeta.ts
|
|
6952
7016
|
function deferMetaHeaders(response, headers) {
|
|
6953
7017
|
const existing = pending.get(response);
|
|
@@ -7033,7 +7097,7 @@ async function toResponse(value, meta) {
|
|
|
7033
7097
|
});
|
|
7034
7098
|
}
|
|
7035
7099
|
if (isPlainObject(value) || Array.isArray(value)) {
|
|
7036
|
-
const body2 =
|
|
7100
|
+
const body2 = stringifyJson(value);
|
|
7037
7101
|
const headers2 = new Headers({ "Content-Type": "application/json" });
|
|
7038
7102
|
applyMeta(headers2);
|
|
7039
7103
|
return new Response(body2, {
|
|
@@ -7057,7 +7121,7 @@ async function toResponse(value, meta) {
|
|
|
7057
7121
|
headers: headers2
|
|
7058
7122
|
});
|
|
7059
7123
|
}
|
|
7060
|
-
const body =
|
|
7124
|
+
const body = stringifyJson(value);
|
|
7061
7125
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
7062
7126
|
applyMeta(headers);
|
|
7063
7127
|
return new Response(body, {
|
|
@@ -7069,6 +7133,7 @@ var init_toResponse = __esm({
|
|
|
7069
7133
|
"src/response/toResponse.ts"() {
|
|
7070
7134
|
"use strict";
|
|
7071
7135
|
init_isPlainObject();
|
|
7136
|
+
init_stringifyJson();
|
|
7072
7137
|
init_pendingMeta();
|
|
7073
7138
|
}
|
|
7074
7139
|
});
|
|
@@ -7394,9 +7459,6 @@ var init_injectParams = __esm({
|
|
|
7394
7459
|
function wrapResult(result, ctx) {
|
|
7395
7460
|
return wrapOkResult(result, ctx.config);
|
|
7396
7461
|
}
|
|
7397
|
-
function stashHandlerResult(ctx, result) {
|
|
7398
|
-
ctx.__faapiHandlerResult = result;
|
|
7399
|
-
}
|
|
7400
7462
|
function mergeMeta(response, meta) {
|
|
7401
7463
|
const hasMeta = meta.status !== void 0 || Object.keys(meta.headers).length > 0 || meta.setCookies.length > 0;
|
|
7402
7464
|
if (!hasMeta) return response;
|
|
@@ -7465,9 +7527,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
7465
7527
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
7466
7528
|
const sseResponse = pickSseAndAutoClose();
|
|
7467
7529
|
if (sseResponse) return sseResponse;
|
|
7468
|
-
|
|
7469
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
7470
|
-
return response;
|
|
7530
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
7471
7531
|
} catch (err) {
|
|
7472
7532
|
autoCloseSseOnError();
|
|
7473
7533
|
throw err;
|
|
@@ -7478,9 +7538,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
7478
7538
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
7479
7539
|
const sseResponse = pickSseAndAutoClose();
|
|
7480
7540
|
if (sseResponse) return sseResponse;
|
|
7481
|
-
|
|
7482
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
7483
|
-
return response;
|
|
7541
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
7484
7542
|
} catch (err) {
|
|
7485
7543
|
autoCloseSseOnError();
|
|
7486
7544
|
throw err;
|
|
@@ -8081,7 +8139,7 @@ var init_serverUtils = __esm({
|
|
|
8081
8139
|
function wrapWsSocket(rawSocket) {
|
|
8082
8140
|
return {
|
|
8083
8141
|
send(data) {
|
|
8084
|
-
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data :
|
|
8142
|
+
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data : stringifyJson(data);
|
|
8085
8143
|
rawSocket.send(payload);
|
|
8086
8144
|
},
|
|
8087
8145
|
close(code, reason) {
|
|
@@ -8095,6 +8153,7 @@ function wrapWsSocket(rawSocket) {
|
|
|
8095
8153
|
var init_wsHandler = __esm({
|
|
8096
8154
|
"src/runtime/wsHandler.ts"() {
|
|
8097
8155
|
"use strict";
|
|
8156
|
+
init_stringifyJson();
|
|
8098
8157
|
}
|
|
8099
8158
|
});
|
|
8100
8159
|
|
|
@@ -8582,7 +8641,6 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
|
|
|
8582
8641
|
globalInjectors
|
|
8583
8642
|
});
|
|
8584
8643
|
const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
|
|
8585
|
-
res.__faapiHandlerResult = ctx.__faapiHandlerResult;
|
|
8586
8644
|
await sendSuccessResponse(response, res);
|
|
8587
8645
|
} catch (err) {
|
|
8588
8646
|
if (res.destroyed || res.writableEnded) return;
|
|
@@ -9799,10 +9857,7 @@ async function createAppBase(options) {
|
|
|
9799
9857
|
resolve3({
|
|
9800
9858
|
status: mockRes.statusCode,
|
|
9801
9859
|
headers: new Headers(mockRes._headers),
|
|
9802
|
-
body: parsed
|
|
9803
|
-
// inject raw 捕获桥(第三跳):handler 原始返回值(handleRequest 从 ctx
|
|
9804
|
-
// 桥接到 res;未捕获时 undefined——语义见 InjectResponse.raw 注释)
|
|
9805
|
-
raw: mockRes.__faapiHandlerResult
|
|
9860
|
+
body: parsed
|
|
9806
9861
|
});
|
|
9807
9862
|
});
|
|
9808
9863
|
const listeners = server.listeners("request");
|