@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/testing.js
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
// src/utils/isPlainObject.ts
|
|
2
|
+
function isPlainObject(value) {
|
|
3
|
+
if (value === null || typeof value !== "object") {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
if (Array.isArray(value)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const proto = Object.getPrototypeOf(value);
|
|
10
|
+
return proto === null || proto === Object.prototype;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/utils/stringifyJson.ts
|
|
14
|
+
function stringifyJson(value) {
|
|
15
|
+
return JSON.stringify(convertValue(value, /* @__PURE__ */ new Set()));
|
|
16
|
+
}
|
|
17
|
+
function convertValue(value, ancestors) {
|
|
18
|
+
if (value === null) return value;
|
|
19
|
+
const type = typeof value;
|
|
20
|
+
if (type === "bigint") return value.toString();
|
|
21
|
+
if (type === "number") return Number.isFinite(value) ? value : String(value);
|
|
22
|
+
if (type !== "object") return value;
|
|
23
|
+
const obj = value;
|
|
24
|
+
if (ancestors.has(obj)) {
|
|
25
|
+
throw new TypeError("[faapi] Converting circular structure to JSON");
|
|
26
|
+
}
|
|
27
|
+
if (obj instanceof Date) return obj.getTime();
|
|
28
|
+
if (obj instanceof Map) {
|
|
29
|
+
ancestors.add(obj);
|
|
30
|
+
const entries = Array.from(obj, ([k, v]) => [
|
|
31
|
+
convertValue(k, ancestors),
|
|
32
|
+
convertValue(v, ancestors)
|
|
33
|
+
]);
|
|
34
|
+
ancestors.delete(obj);
|
|
35
|
+
return entries;
|
|
36
|
+
}
|
|
37
|
+
if (obj instanceof Set) {
|
|
38
|
+
ancestors.add(obj);
|
|
39
|
+
const values = Array.from(obj, (v) => convertValue(v, ancestors));
|
|
40
|
+
ancestors.delete(obj);
|
|
41
|
+
return values;
|
|
42
|
+
}
|
|
43
|
+
if (obj instanceof RegExp) return obj.toString();
|
|
44
|
+
const toJSON = obj.toJSON;
|
|
45
|
+
if (typeof toJSON === "function") {
|
|
46
|
+
ancestors.add(obj);
|
|
47
|
+
const result = convertValue(toJSON.call(obj), ancestors);
|
|
48
|
+
ancestors.delete(obj);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(obj)) {
|
|
52
|
+
ancestors.add(obj);
|
|
53
|
+
const arr = obj.map((item) => convertValue(item, ancestors));
|
|
54
|
+
ancestors.delete(obj);
|
|
55
|
+
return arr;
|
|
56
|
+
}
|
|
57
|
+
if (isPlainObject(obj)) {
|
|
58
|
+
ancestors.add(obj);
|
|
59
|
+
const out = {};
|
|
60
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
61
|
+
out[key] = convertValue(val, ancestors);
|
|
62
|
+
}
|
|
63
|
+
ancestors.delete(obj);
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
return obj;
|
|
67
|
+
}
|
|
68
|
+
|
|
1
69
|
// src/runtime/sse.ts
|
|
2
70
|
function encodeSseEvent(event) {
|
|
3
71
|
let out = "";
|
|
@@ -24,7 +92,7 @@ function encodeSseEvent(event) {
|
|
|
24
92
|
} else if (event.data === null) {
|
|
25
93
|
dataStr = "null";
|
|
26
94
|
} else {
|
|
27
|
-
dataStr =
|
|
95
|
+
dataStr = stringifyJson(event.data);
|
|
28
96
|
}
|
|
29
97
|
const lines = dataStr.split("\n");
|
|
30
98
|
for (const line of lines) {
|
|
@@ -182,7 +250,7 @@ function jsonRaw(body, status, extraHeaders) {
|
|
|
182
250
|
const extra = new Headers(extraHeaders);
|
|
183
251
|
extra.forEach((value, key) => headers.set(key, value));
|
|
184
252
|
}
|
|
185
|
-
return new Response(
|
|
253
|
+
return new Response(stringifyJson(body), { status, headers });
|
|
186
254
|
}
|
|
187
255
|
function wrapOkResult(result, config) {
|
|
188
256
|
if (result instanceof Response) return result;
|
|
@@ -541,18 +609,6 @@ function createTestContext(options) {
|
|
|
541
609
|
return createContext(request, params, config, ip, registries);
|
|
542
610
|
}
|
|
543
611
|
|
|
544
|
-
// src/utils/isPlainObject.ts
|
|
545
|
-
function isPlainObject(value) {
|
|
546
|
-
if (value === null || typeof value !== "object") {
|
|
547
|
-
return false;
|
|
548
|
-
}
|
|
549
|
-
if (Array.isArray(value)) {
|
|
550
|
-
return false;
|
|
551
|
-
}
|
|
552
|
-
const proto = Object.getPrototypeOf(value);
|
|
553
|
-
return proto === null || proto === Object.prototype;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
612
|
// src/response/pendingMeta.ts
|
|
557
613
|
var pending = /* @__PURE__ */ new WeakMap();
|
|
558
614
|
function deferMetaHeaders(response, headers) {
|
|
@@ -632,7 +688,7 @@ async function toResponse(value, meta) {
|
|
|
632
688
|
});
|
|
633
689
|
}
|
|
634
690
|
if (isPlainObject(value) || Array.isArray(value)) {
|
|
635
|
-
const body2 =
|
|
691
|
+
const body2 = stringifyJson(value);
|
|
636
692
|
const headers2 = new Headers({ "Content-Type": "application/json" });
|
|
637
693
|
applyMeta(headers2);
|
|
638
694
|
return new Response(body2, {
|
|
@@ -656,7 +712,7 @@ async function toResponse(value, meta) {
|
|
|
656
712
|
headers: headers2
|
|
657
713
|
});
|
|
658
714
|
}
|
|
659
|
-
const body =
|
|
715
|
+
const body = stringifyJson(value);
|
|
660
716
|
const headers = new Headers({ "Content-Type": "application/json" });
|
|
661
717
|
applyMeta(headers);
|
|
662
718
|
return new Response(body, {
|
|
@@ -1036,9 +1092,6 @@ async function injectParamsAsync(handler, ctx, body, injectors) {
|
|
|
1036
1092
|
function wrapResult(result, ctx) {
|
|
1037
1093
|
return wrapOkResult(result, ctx.config);
|
|
1038
1094
|
}
|
|
1039
|
-
function stashHandlerResult(ctx, result) {
|
|
1040
|
-
ctx.__faapiHandlerResult = result;
|
|
1041
|
-
}
|
|
1042
1095
|
function mergeMeta(response, meta) {
|
|
1043
1096
|
const hasMeta = meta.status !== void 0 || Object.keys(meta.headers).length > 0 || meta.setCookies.length > 0;
|
|
1044
1097
|
if (!hasMeta) return response;
|
|
@@ -1107,9 +1160,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
1107
1160
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
1108
1161
|
const sseResponse = pickSseAndAutoClose();
|
|
1109
1162
|
if (sseResponse) return sseResponse;
|
|
1110
|
-
|
|
1111
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
1112
|
-
return response;
|
|
1163
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
1113
1164
|
} catch (err) {
|
|
1114
1165
|
autoCloseSseOnError();
|
|
1115
1166
|
throw err;
|
|
@@ -1120,9 +1171,7 @@ async function invokeHandler(handler, ctx, body, middlewares, injectors) {
|
|
|
1120
1171
|
const result = await injectParamsAsync(handler, ctx, body, injectors);
|
|
1121
1172
|
const sseResponse = pickSseAndAutoClose();
|
|
1122
1173
|
if (sseResponse) return sseResponse;
|
|
1123
|
-
|
|
1124
|
-
if (!(result instanceof Response)) stashHandlerResult(ctx, result);
|
|
1125
|
-
return response;
|
|
1174
|
+
return toResponse(wrapResult(result, ctx), meta);
|
|
1126
1175
|
} catch (err) {
|
|
1127
1176
|
autoCloseSseOnError();
|
|
1128
1177
|
throw err;
|
|
@@ -2695,7 +2744,7 @@ function baseExpression(type, ctx) {
|
|
|
2695
2744
|
case "union":
|
|
2696
2745
|
return generateUnionExpression(type.members, ctx);
|
|
2697
2746
|
case "date":
|
|
2698
|
-
return 'z.preprocess((v) => (typeof v === "string" ? new Date(v) : v), z.date())';
|
|
2747
|
+
return 'z.preprocess((v) => (typeof v === "string" || typeof v === "number" ? new Date(v) : v), z.date())';
|
|
2699
2748
|
case "record":
|
|
2700
2749
|
return `z.record(${runtimeTypeToZodExpression(type.key, ctx)}, ${runtimeTypeToZodExpression(type.value, ctx)})`;
|
|
2701
2750
|
case "map":
|
|
@@ -4322,7 +4371,7 @@ function buildErrorResponse(err, config) {
|
|
|
4322
4371
|
function wrapWsSocket(rawSocket) {
|
|
4323
4372
|
return {
|
|
4324
4373
|
send(data) {
|
|
4325
|
-
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data :
|
|
4374
|
+
const payload = typeof data === "string" || Buffer.isBuffer(data) ? data : stringifyJson(data);
|
|
4326
4375
|
rawSocket.send(payload);
|
|
4327
4376
|
},
|
|
4328
4377
|
close(code, reason) {
|
|
@@ -4795,7 +4844,6 @@ async function handleRequest(routes, rootDir, dist, req, res, outerMiddlewares,
|
|
|
4795
4844
|
globalInjectors
|
|
4796
4845
|
});
|
|
4797
4846
|
const response = outerMiddlewares.length > 0 ? await compose(outerMiddlewares, ctx, routePipeline) : await routePipeline();
|
|
4798
|
-
res.__faapiHandlerResult = ctx.__faapiHandlerResult;
|
|
4799
4847
|
await sendSuccessResponse(response, res);
|
|
4800
4848
|
} catch (err) {
|
|
4801
4849
|
if (res.destroyed || res.writableEnded) return;
|