@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 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 = JSON.stringify(event.data);
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(JSON.stringify(body), { status, headers });
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 = JSON.stringify(value);
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 = JSON.stringify(value);
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
- const response = await toResponse(wrapResult(result, ctx), meta);
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
- const response = await toResponse(wrapResult(result, ctx), meta);
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 : JSON.stringify(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");