@xfe-repo/bff-endpoint 1.6.0 → 1.6.4

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.
@@ -14,10 +14,18 @@ import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from "@nestjs/core";
14
14
  import { ValidationPipe } from "@xfe-repo/bff-validation";
15
15
 
16
16
  // src/apiResponse/ApiResponse.exception.filter.ts
17
- import { Catch } from "@nestjs/common";
17
+ import { Catch, Logger as Logger2 } from "@nestjs/common";
18
18
  import { HttpException, HttpStatus } from "@nestjs/common";
19
- import { CtxService } from "@xfe-repo/bff-core";
19
+ import { CtxService as CtxService2 } from "@xfe-repo/bff-core";
20
20
  import { ApiResponseException } from "@xfe-repo/bff-validation";
21
+
22
+ // src/apiResponse/ApiResponse.interceptor.ts
23
+ import { Injectable, Logger } from "@nestjs/common";
24
+ import { Reflector } from "@nestjs/core";
25
+ import { DECORATORS } from "@nestjs/swagger/dist/constants";
26
+ import { CtxService } from "@xfe-repo/bff-core";
27
+ import { createValidationPipe } from "@xfe-repo/bff-validation";
28
+ import { mergeMap } from "rxjs/operators";
21
29
  function _ts_decorate(decorators, target, key, desc) {
22
30
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23
31
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -29,9 +37,110 @@ function _ts_metadata(k, v) {
29
37
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
30
38
  }
31
39
  __name(_ts_metadata, "_ts_metadata");
40
+ var _ApiResponseInterceptor = class _ApiResponseInterceptor {
41
+ constructor(reflector, ctx) {
42
+ __publicField(this, "reflector");
43
+ __publicField(this, "ctx");
44
+ __publicField(this, "validationPipe");
45
+ __publicField(this, "logger", new Logger(_ApiResponseInterceptor.name));
46
+ /**
47
+ * 注册 tracks 日志记录器,在响应完成后消费 tracks 日志并输出
48
+ * 响应流会保证外层 TransformInterceptor 的 UnionQueryPlugin 等日志采集写入后,再由 ApiResponseInterceptor 一次性输出完整 tracks 列表
49
+ */
50
+ __publicField(this, "wrapApiResponseWithTracks", /* @__PURE__ */ __name((resJson) => {
51
+ Object.defineProperty(resJson, "toJSON", {
52
+ configurable: true,
53
+ value: /* @__PURE__ */ __name(() => {
54
+ const tracks = this.consumeTracks();
55
+ this.logger.log({
56
+ traceid: this.ctx.traceid,
57
+ tracks
58
+ });
59
+ return {
60
+ ...resJson,
61
+ tracks
62
+ };
63
+ }, "value")
64
+ });
65
+ }, "wrapApiResponseWithTracks"));
66
+ this.reflector = reflector;
67
+ this.ctx = ctx;
68
+ this.validationPipe = createValidationPipe({
69
+ // 配合配置 validationPipe.transform({ type: 'custom' }) 时使用
70
+ validateCustomDecorators: true
71
+ });
72
+ }
73
+ intercept(context, next) {
74
+ const contextClass = context.getClass();
75
+ const contextHandler = context.getHandler();
76
+ return next.handle().pipe(mergeMap((data) => this.handlerSuccess(data, contextClass, contextHandler)));
77
+ }
78
+ async handlerSuccess(data, contextClass, contextHandler) {
79
+ const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, contextHandler);
80
+ if (hasApiRawResponse) {
81
+ return data;
82
+ }
83
+ const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, contextClass);
84
+ const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, contextHandler);
85
+ const apiWrapResponse = hasApiSuccessResponse || hasApiSuccessMethodResponse;
86
+ const apiResponseDto = {
87
+ code: 200,
88
+ msg: "success",
89
+ traceid: this.ctx.traceid
90
+ };
91
+ const transformData = apiWrapResponse ? {
92
+ ...apiResponseDto,
93
+ data
94
+ } : data;
95
+ const apiResponse = this.reflector.get(DECORATORS.API_RESPONSE, contextHandler);
96
+ const metatype = (apiResponse?.["200"] || apiResponse?.["201"])?.type;
97
+ const res = await this.validationPipe.transform(transformData, {
98
+ metatype,
99
+ type: "custom"
100
+ });
101
+ const baseJson = apiWrapResponse ? res : {
102
+ ...apiResponseDto,
103
+ data: res
104
+ };
105
+ if (!needDevTracks()) return baseJson;
106
+ this.wrapApiResponseWithTracks(baseJson);
107
+ return baseJson;
108
+ }
109
+ consumeTracks() {
110
+ return this.ctx.consumeTracks().map(({ response, ...track }) => track);
111
+ }
112
+ };
113
+ __name(_ApiResponseInterceptor, "ApiResponseInterceptor");
114
+ var ApiResponseInterceptor = _ApiResponseInterceptor;
115
+ ApiResponseInterceptor = _ts_decorate([
116
+ Injectable(),
117
+ _ts_metadata("design:type", Function),
118
+ _ts_metadata("design:paramtypes", [
119
+ typeof Reflector === "undefined" ? Object : Reflector,
120
+ typeof CtxService === "undefined" ? Object : CtxService
121
+ ])
122
+ ], ApiResponseInterceptor);
123
+ function needDevTracks() {
124
+ return process.env.ENV !== "prod" || process.env.NODE_ENV === "development";
125
+ }
126
+ __name(needDevTracks, "needDevTracks");
127
+
128
+ // src/apiResponse/ApiResponse.exception.filter.ts
129
+ function _ts_decorate2(decorators, target, key, desc) {
130
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
131
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
132
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
133
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
134
+ }
135
+ __name(_ts_decorate2, "_ts_decorate");
136
+ function _ts_metadata2(k, v) {
137
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
138
+ }
139
+ __name(_ts_metadata2, "_ts_metadata");
32
140
  var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
33
141
  constructor(ctx) {
34
142
  __publicField(this, "ctx");
143
+ __publicField(this, "logger", new Logger2(_ApiResponseExceptionFilter.name));
35
144
  this.ctx = ctx;
36
145
  }
37
146
  catch(exception, host) {
@@ -44,46 +153,56 @@ var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
44
153
  data: {},
45
154
  msg: "\u5C0F\u6613\u7D2F\u4E86\uFF0C\u8BA9\u5C0F\u6613\u4F11\u606F\u4E00\u4E0B\u5427~"
46
155
  };
47
- response.status(HttpStatus.OK).json({
48
- code: apiResponse?.code || defaultError.code,
49
- msg: apiResponse?.msg || defaultError.msg,
50
- data: apiResponse?.data || defaultError.data,
51
- debug: {
52
- stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
53
- tracks: this.ctx.tracks
54
- }
55
- });
156
+ const code = apiResponse?.code || defaultError.code;
157
+ const data = apiResponse?.data || defaultError.data;
158
+ const msg = apiResponse?.msg || defaultError.msg;
159
+ const debug = {
160
+ stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
161
+ tracks: this.ctx.consumeTracks()
162
+ };
163
+ const baseJson = {
164
+ code,
165
+ data,
166
+ msg,
167
+ traceid: this.ctx.traceid
168
+ };
169
+ const loggerJson = {
170
+ ...baseJson,
171
+ debug
172
+ };
173
+ this.logger.error(loggerJson);
174
+ response.status(HttpStatus.OK).json(needDevTracks() ? loggerJson : baseJson);
56
175
  }
57
176
  handleException(exception, _host) {
58
177
  if (exception instanceof HttpException) {
59
178
  return {
60
179
  code: exception.getStatus(),
61
- msg: exception.message,
62
180
  data: exception.getResponse(),
181
+ msg: exception.message,
63
182
  stack: exception.stack
64
183
  };
65
184
  }
66
185
  if (exception instanceof ApiResponseException) {
67
186
  return {
68
187
  code: exception.code,
69
- msg: exception.msg,
70
188
  data: exception.data,
189
+ msg: exception.msg,
71
190
  stack: exception.stack
72
191
  };
73
192
  }
74
193
  if (exception instanceof Error) {
75
194
  return {
76
195
  code: HttpStatus.INTERNAL_SERVER_ERROR,
77
- msg: exception.message,
78
196
  data: exception,
197
+ msg: exception.message,
79
198
  stack: exception.stack
80
199
  };
81
200
  }
82
201
  if (typeof exception === "string") {
83
202
  return {
84
203
  code: HttpStatus.INTERNAL_SERVER_ERROR,
85
- msg: exception,
86
204
  data: {},
205
+ msg: exception,
87
206
  stack: new Error(exception).stack
88
207
  };
89
208
  }
@@ -92,91 +211,13 @@ var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
92
211
  };
93
212
  __name(_ApiResponseExceptionFilter, "ApiResponseExceptionFilter");
94
213
  var ApiResponseExceptionFilter = _ApiResponseExceptionFilter;
95
- ApiResponseExceptionFilter = _ts_decorate([
214
+ ApiResponseExceptionFilter = _ts_decorate2([
96
215
  Catch(),
97
- _ts_metadata("design:type", Function),
98
- _ts_metadata("design:paramtypes", [
99
- typeof CtxService === "undefined" ? Object : CtxService
100
- ])
101
- ], ApiResponseExceptionFilter);
102
-
103
- // src/apiResponse/ApiResponse.interceptor.ts
104
- import { Injectable } from "@nestjs/common";
105
- import { Reflector } from "@nestjs/core";
106
- import { DECORATORS } from "@nestjs/swagger/dist/constants";
107
- import { CtxService as CtxService2 } from "@xfe-repo/bff-core";
108
- import { createValidationPipe } from "@xfe-repo/bff-validation";
109
- import { mergeMap } from "rxjs/operators";
110
- function _ts_decorate2(decorators, target, key, desc) {
111
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
112
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
113
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
114
- return c > 3 && r && Object.defineProperty(target, key, r), r;
115
- }
116
- __name(_ts_decorate2, "_ts_decorate");
117
- function _ts_metadata2(k, v) {
118
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
119
- }
120
- __name(_ts_metadata2, "_ts_metadata");
121
- var _ApiResponseInterceptor = class _ApiResponseInterceptor {
122
- constructor(reflector, ctx) {
123
- __publicField(this, "reflector");
124
- __publicField(this, "ctx");
125
- __publicField(this, "validationPipe");
126
- __publicField(this, "contextClass");
127
- __publicField(this, "contextHandler");
128
- this.reflector = reflector;
129
- this.ctx = ctx;
130
- this.validationPipe = createValidationPipe({
131
- // 配合配置 validationPipe.transform({ type: 'custom' }) 时使用
132
- validateCustomDecorators: true
133
- });
134
- }
135
- intercept(context, next) {
136
- this.contextClass = context.getClass();
137
- this.contextHandler = context.getHandler();
138
- return next.handle().pipe(mergeMap((data) => this.handlerSuccess(data)));
139
- }
140
- async handlerSuccess(data) {
141
- const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, this.contextHandler);
142
- if (hasApiRawResponse) {
143
- return data;
144
- }
145
- const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, this.contextClass);
146
- const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, this.contextHandler);
147
- const apiWrapResponse = hasApiSuccessResponse || hasApiSuccessMethodResponse;
148
- const apiResponseDto = {
149
- code: 200,
150
- msg: "success",
151
- traceid: this.ctx.traceid
152
- };
153
- const transformData = apiWrapResponse ? {
154
- ...apiResponseDto,
155
- data
156
- } : data;
157
- const apiResponse = this.reflector.get(DECORATORS.API_RESPONSE, this.contextHandler);
158
- const metatype = (apiResponse?.["200"] || apiResponse?.["201"])?.type;
159
- const res = await this.validationPipe.transform(transformData, {
160
- metatype,
161
- // 自定义类型校验器
162
- type: "custom"
163
- });
164
- return apiWrapResponse ? res : {
165
- ...apiResponseDto,
166
- data: res
167
- };
168
- }
169
- };
170
- __name(_ApiResponseInterceptor, "ApiResponseInterceptor");
171
- var ApiResponseInterceptor = _ApiResponseInterceptor;
172
- ApiResponseInterceptor = _ts_decorate2([
173
- Injectable(),
174
216
  _ts_metadata2("design:type", Function),
175
217
  _ts_metadata2("design:paramtypes", [
176
- typeof Reflector === "undefined" ? Object : Reflector,
177
218
  typeof CtxService2 === "undefined" ? Object : CtxService2
178
219
  ])
179
- ], ApiResponseInterceptor);
220
+ ], ApiResponseExceptionFilter);
180
221
 
181
222
  // src/endpoint.module.ts
182
223
  function _ts_decorate3(decorators, target, key, desc) {
@@ -211,5 +252,6 @@ EndpointModule = _ts_decorate3([
211
252
 
212
253
  export {
213
254
  ApiResponseInterceptor,
255
+ needDevTracks,
214
256
  EndpointModule
215
257
  };
@@ -31,151 +31,89 @@ var import_core2 = require("@nestjs/core");
31
31
  var import_bff_validation3 = require("@xfe-repo/bff-validation");
32
32
 
33
33
  // src/apiResponse/ApiResponse.exception.filter.ts
34
- var import_common = require("@nestjs/common");
35
- var import_common2 = require("@nestjs/common");
36
- var import_bff_core = require("@xfe-repo/bff-core");
37
- var import_bff_validation = require("@xfe-repo/bff-validation");
38
- function _ts_decorate(decorators, target, key, desc) {
39
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
40
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
41
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
42
- return c > 3 && r && Object.defineProperty(target, key, r), r;
43
- }
44
- __name(_ts_decorate, "_ts_decorate");
45
- function _ts_metadata(k, v) {
46
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
47
- }
48
- __name(_ts_metadata, "_ts_metadata");
49
- var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
50
- constructor(ctx) {
51
- __publicField(this, "ctx");
52
- this.ctx = ctx;
53
- }
54
- catch(exception, host) {
55
- if (!exception) return;
56
- const apiResponse = this.handleException(exception, host);
57
- const context = host.switchToHttp();
58
- const response = context.getResponse();
59
- const defaultError = {
60
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
61
- data: {},
62
- msg: "\u5C0F\u6613\u7D2F\u4E86\uFF0C\u8BA9\u5C0F\u6613\u4F11\u606F\u4E00\u4E0B\u5427~"
63
- };
64
- response.status(import_common2.HttpStatus.OK).json({
65
- code: apiResponse?.code || defaultError.code,
66
- msg: apiResponse?.msg || defaultError.msg,
67
- data: apiResponse?.data || defaultError.data,
68
- debug: {
69
- stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
70
- tracks: this.ctx.tracks
71
- }
72
- });
73
- }
74
- handleException(exception, _host) {
75
- if (exception instanceof import_common2.HttpException) {
76
- return {
77
- code: exception.getStatus(),
78
- msg: exception.message,
79
- data: exception.getResponse(),
80
- stack: exception.stack
81
- };
82
- }
83
- if (exception instanceof import_bff_validation.ApiResponseException) {
84
- return {
85
- code: exception.code,
86
- msg: exception.msg,
87
- data: exception.data,
88
- stack: exception.stack
89
- };
90
- }
91
- if (exception instanceof Error) {
92
- return {
93
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
94
- msg: exception.message,
95
- data: exception,
96
- stack: exception.stack
97
- };
98
- }
99
- if (typeof exception === "string") {
100
- return {
101
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
102
- msg: exception,
103
- data: {},
104
- stack: new Error(exception).stack
105
- };
106
- }
107
- return exception;
108
- }
109
- };
110
- __name(_ApiResponseExceptionFilter, "ApiResponseExceptionFilter");
111
- var ApiResponseExceptionFilter = _ApiResponseExceptionFilter;
112
- ApiResponseExceptionFilter = _ts_decorate([
113
- (0, import_common.Catch)(),
114
- _ts_metadata("design:type", Function),
115
- _ts_metadata("design:paramtypes", [
116
- typeof import_bff_core.CtxService === "undefined" ? Object : import_bff_core.CtxService
117
- ])
118
- ], ApiResponseExceptionFilter);
34
+ var import_common4 = require("@nestjs/common");
35
+ var import_common5 = require("@nestjs/common");
36
+ var import_bff_core3 = require("@xfe-repo/bff-core");
37
+ var import_bff_validation2 = require("@xfe-repo/bff-validation");
119
38
 
120
39
  // src/apiResponse/ApiResponse.interceptor.ts
121
- var import_common5 = require("@nestjs/common");
40
+ var import_common3 = require("@nestjs/common");
122
41
  var import_core = require("@nestjs/core");
123
42
  var import_constants2 = require("@nestjs/swagger/dist/constants");
124
- var import_bff_core3 = require("@xfe-repo/bff-core");
125
- var import_bff_validation2 = require("@xfe-repo/bff-validation");
43
+ var import_bff_core2 = require("@xfe-repo/bff-core");
44
+ var import_bff_validation = require("@xfe-repo/bff-validation");
126
45
  var import_operators = require("rxjs/operators");
127
46
 
128
47
  // src/apiResponse/ApiRawResponse.decorator.ts
129
- var import_common3 = require("@nestjs/common");
48
+ var import_common = require("@nestjs/common");
130
49
  var API_RAW_RESPONSE = "API_RAW_RESPONSE";
131
50
 
132
51
  // src/apiResponse/ApiSuccessResponse.decorator.ts
133
- var import_common4 = require("@nestjs/common");
52
+ var import_common2 = require("@nestjs/common");
134
53
  var import_constants = require("@nestjs/swagger/dist/constants");
135
- var import_bff_core2 = require("@xfe-repo/bff-core");
54
+ var import_bff_core = require("@xfe-repo/bff-core");
136
55
  var import_class_transformer = require("class-transformer");
137
56
  var import_class_validator = require("class-validator");
138
57
  var API_SUCCESS_RESPONSE = "API_SUCCESS_RESPONSE";
139
58
  var API_SUCCESS_METHOD_RESPONSE = "API_SUCCESS_METHOD_RESPONSE";
140
59
 
141
60
  // src/apiResponse/ApiResponse.interceptor.ts
142
- function _ts_decorate2(decorators, target, key, desc) {
61
+ function _ts_decorate(decorators, target, key, desc) {
143
62
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
144
63
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
145
64
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
146
65
  return c > 3 && r && Object.defineProperty(target, key, r), r;
147
66
  }
148
- __name(_ts_decorate2, "_ts_decorate");
149
- function _ts_metadata2(k, v) {
67
+ __name(_ts_decorate, "_ts_decorate");
68
+ function _ts_metadata(k, v) {
150
69
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
151
70
  }
152
- __name(_ts_metadata2, "_ts_metadata");
71
+ __name(_ts_metadata, "_ts_metadata");
153
72
  var _ApiResponseInterceptor = class _ApiResponseInterceptor {
154
73
  constructor(reflector, ctx) {
155
74
  __publicField(this, "reflector");
156
75
  __publicField(this, "ctx");
157
76
  __publicField(this, "validationPipe");
158
- __publicField(this, "contextClass");
159
- __publicField(this, "contextHandler");
77
+ __publicField(this, "logger", new import_common3.Logger(_ApiResponseInterceptor.name));
78
+ /**
79
+ * 注册 tracks 日志记录器,在响应完成后消费 tracks 日志并输出
80
+ * 响应流会保证外层 TransformInterceptor 的 UnionQueryPlugin 等日志采集写入后,再由 ApiResponseInterceptor 一次性输出完整 tracks 列表
81
+ */
82
+ __publicField(this, "wrapApiResponseWithTracks", /* @__PURE__ */ __name((resJson) => {
83
+ Object.defineProperty(resJson, "toJSON", {
84
+ configurable: true,
85
+ value: /* @__PURE__ */ __name(() => {
86
+ const tracks = this.consumeTracks();
87
+ this.logger.log({
88
+ traceid: this.ctx.traceid,
89
+ tracks
90
+ });
91
+ return {
92
+ ...resJson,
93
+ tracks
94
+ };
95
+ }, "value")
96
+ });
97
+ }, "wrapApiResponseWithTracks"));
160
98
  this.reflector = reflector;
161
99
  this.ctx = ctx;
162
- this.validationPipe = (0, import_bff_validation2.createValidationPipe)({
100
+ this.validationPipe = (0, import_bff_validation.createValidationPipe)({
163
101
  // 配合配置 validationPipe.transform({ type: 'custom' }) 时使用
164
102
  validateCustomDecorators: true
165
103
  });
166
104
  }
167
105
  intercept(context, next) {
168
- this.contextClass = context.getClass();
169
- this.contextHandler = context.getHandler();
170
- return next.handle().pipe((0, import_operators.mergeMap)((data) => this.handlerSuccess(data)));
106
+ const contextClass = context.getClass();
107
+ const contextHandler = context.getHandler();
108
+ return next.handle().pipe((0, import_operators.mergeMap)((data) => this.handlerSuccess(data, contextClass, contextHandler)));
171
109
  }
172
- async handlerSuccess(data) {
173
- const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, this.contextHandler);
110
+ async handlerSuccess(data, contextClass, contextHandler) {
111
+ const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, contextHandler);
174
112
  if (hasApiRawResponse) {
175
113
  return data;
176
114
  }
177
- const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, this.contextClass);
178
- const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, this.contextHandler);
115
+ const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, contextClass);
116
+ const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, contextHandler);
179
117
  const apiWrapResponse = hasApiSuccessResponse || hasApiSuccessMethodResponse;
180
118
  const apiResponseDto = {
181
119
  code: 200,
@@ -186,29 +124,132 @@ var _ApiResponseInterceptor = class _ApiResponseInterceptor {
186
124
  ...apiResponseDto,
187
125
  data
188
126
  } : data;
189
- const apiResponse = this.reflector.get(import_constants2.DECORATORS.API_RESPONSE, this.contextHandler);
127
+ const apiResponse = this.reflector.get(import_constants2.DECORATORS.API_RESPONSE, contextHandler);
190
128
  const metatype = (apiResponse?.["200"] || apiResponse?.["201"])?.type;
191
129
  const res = await this.validationPipe.transform(transformData, {
192
130
  metatype,
193
- // 自定义类型校验器
194
131
  type: "custom"
195
132
  });
196
- return apiWrapResponse ? res : {
133
+ const baseJson = apiWrapResponse ? res : {
197
134
  ...apiResponseDto,
198
135
  data: res
199
136
  };
137
+ if (!needDevTracks()) return baseJson;
138
+ this.wrapApiResponseWithTracks(baseJson);
139
+ return baseJson;
140
+ }
141
+ consumeTracks() {
142
+ return this.ctx.consumeTracks().map(({ response, ...track }) => track);
200
143
  }
201
144
  };
202
145
  __name(_ApiResponseInterceptor, "ApiResponseInterceptor");
203
146
  var ApiResponseInterceptor = _ApiResponseInterceptor;
204
- ApiResponseInterceptor = _ts_decorate2([
205
- (0, import_common5.Injectable)(),
147
+ ApiResponseInterceptor = _ts_decorate([
148
+ (0, import_common3.Injectable)(),
149
+ _ts_metadata("design:type", Function),
150
+ _ts_metadata("design:paramtypes", [
151
+ typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
152
+ typeof import_bff_core2.CtxService === "undefined" ? Object : import_bff_core2.CtxService
153
+ ])
154
+ ], ApiResponseInterceptor);
155
+ function needDevTracks() {
156
+ return process.env.ENV !== "prod" || process.env.NODE_ENV === "development";
157
+ }
158
+ __name(needDevTracks, "needDevTracks");
159
+
160
+ // src/apiResponse/ApiResponse.exception.filter.ts
161
+ function _ts_decorate2(decorators, target, key, desc) {
162
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
163
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
164
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
165
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
166
+ }
167
+ __name(_ts_decorate2, "_ts_decorate");
168
+ function _ts_metadata2(k, v) {
169
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
170
+ }
171
+ __name(_ts_metadata2, "_ts_metadata");
172
+ var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
173
+ constructor(ctx) {
174
+ __publicField(this, "ctx");
175
+ __publicField(this, "logger", new import_common4.Logger(_ApiResponseExceptionFilter.name));
176
+ this.ctx = ctx;
177
+ }
178
+ catch(exception, host) {
179
+ if (!exception) return;
180
+ const apiResponse = this.handleException(exception, host);
181
+ const context = host.switchToHttp();
182
+ const response = context.getResponse();
183
+ const defaultError = {
184
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
185
+ data: {},
186
+ msg: "\u5C0F\u6613\u7D2F\u4E86\uFF0C\u8BA9\u5C0F\u6613\u4F11\u606F\u4E00\u4E0B\u5427~"
187
+ };
188
+ const code = apiResponse?.code || defaultError.code;
189
+ const data = apiResponse?.data || defaultError.data;
190
+ const msg = apiResponse?.msg || defaultError.msg;
191
+ const debug = {
192
+ stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
193
+ tracks: this.ctx.consumeTracks()
194
+ };
195
+ const baseJson = {
196
+ code,
197
+ data,
198
+ msg,
199
+ traceid: this.ctx.traceid
200
+ };
201
+ const loggerJson = {
202
+ ...baseJson,
203
+ debug
204
+ };
205
+ this.logger.error(loggerJson);
206
+ response.status(import_common5.HttpStatus.OK).json(needDevTracks() ? loggerJson : baseJson);
207
+ }
208
+ handleException(exception, _host) {
209
+ if (exception instanceof import_common5.HttpException) {
210
+ return {
211
+ code: exception.getStatus(),
212
+ data: exception.getResponse(),
213
+ msg: exception.message,
214
+ stack: exception.stack
215
+ };
216
+ }
217
+ if (exception instanceof import_bff_validation2.ApiResponseException) {
218
+ return {
219
+ code: exception.code,
220
+ data: exception.data,
221
+ msg: exception.msg,
222
+ stack: exception.stack
223
+ };
224
+ }
225
+ if (exception instanceof Error) {
226
+ return {
227
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
228
+ data: exception,
229
+ msg: exception.message,
230
+ stack: exception.stack
231
+ };
232
+ }
233
+ if (typeof exception === "string") {
234
+ return {
235
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
236
+ data: {},
237
+ msg: exception,
238
+ stack: new Error(exception).stack
239
+ };
240
+ }
241
+ return exception;
242
+ }
243
+ };
244
+ __name(_ApiResponseExceptionFilter, "ApiResponseExceptionFilter");
245
+ var ApiResponseExceptionFilter = _ApiResponseExceptionFilter;
246
+ ApiResponseExceptionFilter = _ts_decorate2([
247
+ (0, import_common4.Catch)(),
206
248
  _ts_metadata2("design:type", Function),
207
249
  _ts_metadata2("design:paramtypes", [
208
- typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
209
250
  typeof import_bff_core3.CtxService === "undefined" ? Object : import_bff_core3.CtxService
210
251
  ])
211
- ], ApiResponseInterceptor);
252
+ ], ApiResponseExceptionFilter);
212
253
 
213
254
  // src/endpoint.module.ts
214
255
  function _ts_decorate3(decorators, target, key, desc) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EndpointModule
3
- } from "./chunk-L6OSYIFY.mjs";
3
+ } from "./chunk-F42XQQAA.mjs";
4
4
  import "./chunk-MFNQSBS5.mjs";
5
5
  import "./chunk-Q7G5RLD4.mjs";
6
6
  export {
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { EndpointModule } from './endpoint.module.mjs';
2
2
  import * as _nestjs_common from '@nestjs/common';
3
- import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
3
+ import { NestInterceptor, ExecutionContext, CallHandler, Type } from '@nestjs/common';
4
4
  import { Reflector } from '@nestjs/core';
5
5
  import { CtxService } from '@xfe-repo/bff-core';
6
6
  import { Observable } from 'rxjs';
@@ -14,16 +14,18 @@ declare class ApiResponseInterceptor<T> implements NestInterceptor {
14
14
  private readonly reflector;
15
15
  private readonly ctx;
16
16
  private readonly validationPipe;
17
- private contextClass;
18
- private contextHandler;
17
+ private readonly logger;
19
18
  constructor(reflector: Reflector, ctx: CtxService);
20
19
  intercept(context: ExecutionContext, next: CallHandler): Observable<T>;
21
- handlerSuccess(data: T): Promise<any>;
20
+ handlerSuccess(data: T, contextClass: Type<T>, contextHandler: Function): Promise<any>;
21
+ private wrapApiResponseWithTracks;
22
+ private consumeTracks;
22
23
  }
24
+ declare function needDevTracks(): boolean;
23
25
 
24
26
  declare const API_SUCCESS_RESPONSE = "API_SUCCESS_RESPONSE";
25
27
  declare const API_SUCCESS_METHOD_RESPONSE = "API_SUCCESS_METHOD_RESPONSE";
26
28
  declare function ApiSuccessResponse(): ClassDecorator;
27
29
  declare function ApiSuccessMethodResponse(): MethodDecorator;
28
30
 
29
- export { API_RAW_RESPONSE, API_SUCCESS_METHOD_RESPONSE, API_SUCCESS_RESPONSE, ApiRawResponse, ApiResponseInterceptor, ApiSuccessMethodResponse, ApiSuccessResponse };
31
+ export { API_RAW_RESPONSE, API_SUCCESS_METHOD_RESPONSE, API_SUCCESS_RESPONSE, ApiRawResponse, ApiResponseInterceptor, ApiSuccessMethodResponse, ApiSuccessResponse, needDevTracks };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { EndpointModule } from './endpoint.module.js';
2
2
  import * as _nestjs_common from '@nestjs/common';
3
- import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
3
+ import { NestInterceptor, ExecutionContext, CallHandler, Type } from '@nestjs/common';
4
4
  import { Reflector } from '@nestjs/core';
5
5
  import { CtxService } from '@xfe-repo/bff-core';
6
6
  import { Observable } from 'rxjs';
@@ -14,16 +14,18 @@ declare class ApiResponseInterceptor<T> implements NestInterceptor {
14
14
  private readonly reflector;
15
15
  private readonly ctx;
16
16
  private readonly validationPipe;
17
- private contextClass;
18
- private contextHandler;
17
+ private readonly logger;
19
18
  constructor(reflector: Reflector, ctx: CtxService);
20
19
  intercept(context: ExecutionContext, next: CallHandler): Observable<T>;
21
- handlerSuccess(data: T): Promise<any>;
20
+ handlerSuccess(data: T, contextClass: Type<T>, contextHandler: Function): Promise<any>;
21
+ private wrapApiResponseWithTracks;
22
+ private consumeTracks;
22
23
  }
24
+ declare function needDevTracks(): boolean;
23
25
 
24
26
  declare const API_SUCCESS_RESPONSE = "API_SUCCESS_RESPONSE";
25
27
  declare const API_SUCCESS_METHOD_RESPONSE = "API_SUCCESS_METHOD_RESPONSE";
26
28
  declare function ApiSuccessResponse(): ClassDecorator;
27
29
  declare function ApiSuccessMethodResponse(): MethodDecorator;
28
30
 
29
- export { API_RAW_RESPONSE, API_SUCCESS_METHOD_RESPONSE, API_SUCCESS_RESPONSE, ApiRawResponse, ApiResponseInterceptor, ApiSuccessMethodResponse, ApiSuccessResponse };
31
+ export { API_RAW_RESPONSE, API_SUCCESS_METHOD_RESPONSE, API_SUCCESS_RESPONSE, ApiRawResponse, ApiResponseInterceptor, ApiSuccessMethodResponse, ApiSuccessResponse, needDevTracks };
package/dist/index.js CHANGED
@@ -32,7 +32,8 @@ __export(index_exports, {
32
32
  ApiSuccessResponse: () => ApiSuccessResponse,
33
33
  Endpoint: () => Endpoint,
34
34
  EndpointModule: () => EndpointModule,
35
- Endpoints: () => Endpoints
35
+ Endpoints: () => Endpoints,
36
+ needDevTracks: () => needDevTracks
36
37
  });
37
38
  module.exports = __toCommonJS(index_exports);
38
39
 
@@ -42,122 +43,41 @@ var import_core2 = require("@nestjs/core");
42
43
  var import_bff_validation3 = require("@xfe-repo/bff-validation");
43
44
 
44
45
  // src/apiResponse/ApiResponse.exception.filter.ts
45
- var import_common = require("@nestjs/common");
46
- var import_common2 = require("@nestjs/common");
47
- var import_bff_core = require("@xfe-repo/bff-core");
48
- var import_bff_validation = require("@xfe-repo/bff-validation");
49
- function _ts_decorate(decorators, target, key, desc) {
50
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
51
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
52
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
53
- return c > 3 && r && Object.defineProperty(target, key, r), r;
54
- }
55
- __name(_ts_decorate, "_ts_decorate");
56
- function _ts_metadata(k, v) {
57
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
58
- }
59
- __name(_ts_metadata, "_ts_metadata");
60
- var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
61
- constructor(ctx) {
62
- __publicField(this, "ctx");
63
- this.ctx = ctx;
64
- }
65
- catch(exception, host) {
66
- if (!exception) return;
67
- const apiResponse = this.handleException(exception, host);
68
- const context = host.switchToHttp();
69
- const response = context.getResponse();
70
- const defaultError = {
71
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
72
- data: {},
73
- msg: "\u5C0F\u6613\u7D2F\u4E86\uFF0C\u8BA9\u5C0F\u6613\u4F11\u606F\u4E00\u4E0B\u5427~"
74
- };
75
- response.status(import_common2.HttpStatus.OK).json({
76
- code: apiResponse?.code || defaultError.code,
77
- msg: apiResponse?.msg || defaultError.msg,
78
- data: apiResponse?.data || defaultError.data,
79
- debug: {
80
- stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
81
- tracks: this.ctx.tracks
82
- }
83
- });
84
- }
85
- handleException(exception, _host) {
86
- if (exception instanceof import_common2.HttpException) {
87
- return {
88
- code: exception.getStatus(),
89
- msg: exception.message,
90
- data: exception.getResponse(),
91
- stack: exception.stack
92
- };
93
- }
94
- if (exception instanceof import_bff_validation.ApiResponseException) {
95
- return {
96
- code: exception.code,
97
- msg: exception.msg,
98
- data: exception.data,
99
- stack: exception.stack
100
- };
101
- }
102
- if (exception instanceof Error) {
103
- return {
104
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
105
- msg: exception.message,
106
- data: exception,
107
- stack: exception.stack
108
- };
109
- }
110
- if (typeof exception === "string") {
111
- return {
112
- code: import_common2.HttpStatus.INTERNAL_SERVER_ERROR,
113
- msg: exception,
114
- data: {},
115
- stack: new Error(exception).stack
116
- };
117
- }
118
- return exception;
119
- }
120
- };
121
- __name(_ApiResponseExceptionFilter, "ApiResponseExceptionFilter");
122
- var ApiResponseExceptionFilter = _ApiResponseExceptionFilter;
123
- ApiResponseExceptionFilter = _ts_decorate([
124
- (0, import_common.Catch)(),
125
- _ts_metadata("design:type", Function),
126
- _ts_metadata("design:paramtypes", [
127
- typeof import_bff_core.CtxService === "undefined" ? Object : import_bff_core.CtxService
128
- ])
129
- ], ApiResponseExceptionFilter);
46
+ var import_common4 = require("@nestjs/common");
47
+ var import_common5 = require("@nestjs/common");
48
+ var import_bff_core3 = require("@xfe-repo/bff-core");
49
+ var import_bff_validation2 = require("@xfe-repo/bff-validation");
130
50
 
131
51
  // src/apiResponse/ApiResponse.interceptor.ts
132
- var import_common5 = require("@nestjs/common");
52
+ var import_common3 = require("@nestjs/common");
133
53
  var import_core = require("@nestjs/core");
134
54
  var import_constants2 = require("@nestjs/swagger/dist/constants");
135
- var import_bff_core3 = require("@xfe-repo/bff-core");
136
- var import_bff_validation2 = require("@xfe-repo/bff-validation");
55
+ var import_bff_core2 = require("@xfe-repo/bff-core");
56
+ var import_bff_validation = require("@xfe-repo/bff-validation");
137
57
  var import_operators = require("rxjs/operators");
138
58
 
139
59
  // src/apiResponse/ApiRawResponse.decorator.ts
140
- var import_common3 = require("@nestjs/common");
60
+ var import_common = require("@nestjs/common");
141
61
  var API_RAW_RESPONSE = "API_RAW_RESPONSE";
142
- var ApiRawResponse = /* @__PURE__ */ __name(() => (0, import_common3.SetMetadata)(API_RAW_RESPONSE, true), "ApiRawResponse");
62
+ var ApiRawResponse = /* @__PURE__ */ __name(() => (0, import_common.SetMetadata)(API_RAW_RESPONSE, true), "ApiRawResponse");
143
63
 
144
64
  // src/apiResponse/ApiSuccessResponse.decorator.ts
145
- var import_common4 = require("@nestjs/common");
65
+ var import_common2 = require("@nestjs/common");
146
66
  var import_constants = require("@nestjs/swagger/dist/constants");
147
- var import_bff_core2 = require("@xfe-repo/bff-core");
67
+ var import_bff_core = require("@xfe-repo/bff-core");
148
68
  var import_class_transformer = require("class-transformer");
149
69
  var import_class_validator = require("class-validator");
150
- function _ts_decorate2(decorators, target, key, desc) {
70
+ function _ts_decorate(decorators, target, key, desc) {
151
71
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
152
72
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
153
73
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
154
74
  return c > 3 && r && Object.defineProperty(target, key, r), r;
155
75
  }
156
- __name(_ts_decorate2, "_ts_decorate");
157
- function _ts_metadata2(k, v) {
76
+ __name(_ts_decorate, "_ts_decorate");
77
+ function _ts_metadata(k, v) {
158
78
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
159
79
  }
160
- __name(_ts_metadata2, "_ts_metadata");
80
+ __name(_ts_metadata, "_ts_metadata");
161
81
  var API_SUCCESS_RESPONSE = "API_SUCCESS_RESPONSE";
162
82
  var API_SUCCESS_METHOD_RESPONSE = "API_SUCCESS_METHOD_RESPONSE";
163
83
  function ApiSuccessResponse() {
@@ -228,39 +148,39 @@ function withApiSuccessResponse(Base, isArray) {
228
148
  var _a;
229
149
  let ApiResponse2 = (_a = class {
230
150
  constructor() {
231
- __publicField(this, "code", import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
151
+ __publicField(this, "code", import_common2.HttpStatus.INTERNAL_SERVER_ERROR);
232
152
  __publicField(this, "msg", "\u5C0F\u6613\u5F88\u5FD9\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5~");
233
153
  __publicField(this, "traceid");
234
154
  __publicField(this, "data");
235
155
  }
236
156
  }, __name(_a, "ApiResponse"), _a);
237
- _ts_decorate2([
238
- (0, import_bff_core2.ApiProperty)({
157
+ _ts_decorate([
158
+ (0, import_bff_core.ApiProperty)({
239
159
  example: 200,
240
160
  description: "\u54CD\u5E94\u72B6\u6001\u7801, \u6B64\u5904\u7EA6\u5B9A 0 - 100000 \u533A\u95F4\u5BA2\u6237\u7AEFToast\u5904\u7406, \u5927\u4E8E 100000 \u4E3A\u81EA\u5B9A\u4E49\u5904\u7406"
241
161
  }),
242
162
  (0, import_class_validator.IsInt)(),
243
163
  (0, import_class_validator.IsNotEmpty)(),
244
- _ts_metadata2("design:type", Number)
164
+ _ts_metadata("design:type", Number)
245
165
  ], ApiResponse2.prototype, "code", void 0);
246
- _ts_decorate2([
247
- (0, import_bff_core2.ApiProperty)({
166
+ _ts_decorate([
167
+ (0, import_bff_core.ApiProperty)({
248
168
  description: "\u9519\u8BEF\u4FE1\u606F"
249
169
  }),
250
170
  (0, import_class_validator.IsString)(),
251
171
  (0, import_class_validator.IsNotEmpty)(),
252
- _ts_metadata2("design:type", String)
172
+ _ts_metadata("design:type", String)
253
173
  ], ApiResponse2.prototype, "msg", void 0);
254
- _ts_decorate2([
255
- (0, import_bff_core2.ApiPropertyOptional)({
174
+ _ts_decorate([
175
+ (0, import_bff_core.ApiPropertyOptional)({
256
176
  description: "\u9519\u8BEF\u4FE1\u606F\u8FFD\u8E2Aid"
257
177
  }),
258
178
  (0, import_class_validator.IsString)(),
259
179
  (0, import_class_validator.IsOptional)(),
260
- _ts_metadata2("design:type", String)
180
+ _ts_metadata("design:type", String)
261
181
  ], ApiResponse2.prototype, "traceid", void 0);
262
- _ts_decorate2([
263
- (0, import_bff_core2.ApiProperty)({
182
+ _ts_decorate([
183
+ (0, import_bff_core.ApiProperty)({
264
184
  description: "\u54CD\u5E94\u6570\u636E",
265
185
  type: isArray ? [
266
186
  Base
@@ -272,50 +192,69 @@ function withApiSuccessResponse(Base, isArray) {
272
192
  }),
273
193
  (0, import_class_validator.IsNotEmpty)(),
274
194
  IsArrayOrObject(isArray),
275
- _ts_metadata2("design:type", Object)
195
+ _ts_metadata("design:type", Object)
276
196
  ], ApiResponse2.prototype, "data", void 0);
277
197
  return mixin(ApiResponse2, `${ApiResponse2.name}<${Base.name}>`);
278
198
  }
279
199
  __name(withApiSuccessResponse, "withApiSuccessResponse");
280
200
 
281
201
  // src/apiResponse/ApiResponse.interceptor.ts
282
- function _ts_decorate3(decorators, target, key, desc) {
202
+ function _ts_decorate2(decorators, target, key, desc) {
283
203
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
284
204
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
285
205
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
286
206
  return c > 3 && r && Object.defineProperty(target, key, r), r;
287
207
  }
288
- __name(_ts_decorate3, "_ts_decorate");
289
- function _ts_metadata3(k, v) {
208
+ __name(_ts_decorate2, "_ts_decorate");
209
+ function _ts_metadata2(k, v) {
290
210
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
291
211
  }
292
- __name(_ts_metadata3, "_ts_metadata");
212
+ __name(_ts_metadata2, "_ts_metadata");
293
213
  var _ApiResponseInterceptor = class _ApiResponseInterceptor {
294
214
  constructor(reflector, ctx) {
295
215
  __publicField(this, "reflector");
296
216
  __publicField(this, "ctx");
297
217
  __publicField(this, "validationPipe");
298
- __publicField(this, "contextClass");
299
- __publicField(this, "contextHandler");
218
+ __publicField(this, "logger", new import_common3.Logger(_ApiResponseInterceptor.name));
219
+ /**
220
+ * 注册 tracks 日志记录器,在响应完成后消费 tracks 日志并输出
221
+ * 响应流会保证外层 TransformInterceptor 的 UnionQueryPlugin 等日志采集写入后,再由 ApiResponseInterceptor 一次性输出完整 tracks 列表
222
+ */
223
+ __publicField(this, "wrapApiResponseWithTracks", /* @__PURE__ */ __name((resJson) => {
224
+ Object.defineProperty(resJson, "toJSON", {
225
+ configurable: true,
226
+ value: /* @__PURE__ */ __name(() => {
227
+ const tracks = this.consumeTracks();
228
+ this.logger.log({
229
+ traceid: this.ctx.traceid,
230
+ tracks
231
+ });
232
+ return {
233
+ ...resJson,
234
+ tracks
235
+ };
236
+ }, "value")
237
+ });
238
+ }, "wrapApiResponseWithTracks"));
300
239
  this.reflector = reflector;
301
240
  this.ctx = ctx;
302
- this.validationPipe = (0, import_bff_validation2.createValidationPipe)({
241
+ this.validationPipe = (0, import_bff_validation.createValidationPipe)({
303
242
  // 配合配置 validationPipe.transform({ type: 'custom' }) 时使用
304
243
  validateCustomDecorators: true
305
244
  });
306
245
  }
307
246
  intercept(context, next) {
308
- this.contextClass = context.getClass();
309
- this.contextHandler = context.getHandler();
310
- return next.handle().pipe((0, import_operators.mergeMap)((data) => this.handlerSuccess(data)));
247
+ const contextClass = context.getClass();
248
+ const contextHandler = context.getHandler();
249
+ return next.handle().pipe((0, import_operators.mergeMap)((data) => this.handlerSuccess(data, contextClass, contextHandler)));
311
250
  }
312
- async handlerSuccess(data) {
313
- const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, this.contextHandler);
251
+ async handlerSuccess(data, contextClass, contextHandler) {
252
+ const hasApiRawResponse = this.reflector.get(API_RAW_RESPONSE, contextHandler);
314
253
  if (hasApiRawResponse) {
315
254
  return data;
316
255
  }
317
- const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, this.contextClass);
318
- const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, this.contextHandler);
256
+ const hasApiSuccessResponse = this.reflector.get(API_SUCCESS_RESPONSE, contextClass);
257
+ const hasApiSuccessMethodResponse = this.reflector.get(API_SUCCESS_METHOD_RESPONSE, contextHandler);
319
258
  const apiWrapResponse = hasApiSuccessResponse || hasApiSuccessMethodResponse;
320
259
  const apiResponseDto = {
321
260
  code: 200,
@@ -326,29 +265,132 @@ var _ApiResponseInterceptor = class _ApiResponseInterceptor {
326
265
  ...apiResponseDto,
327
266
  data
328
267
  } : data;
329
- const apiResponse = this.reflector.get(import_constants2.DECORATORS.API_RESPONSE, this.contextHandler);
268
+ const apiResponse = this.reflector.get(import_constants2.DECORATORS.API_RESPONSE, contextHandler);
330
269
  const metatype = (apiResponse?.["200"] || apiResponse?.["201"])?.type;
331
270
  const res = await this.validationPipe.transform(transformData, {
332
271
  metatype,
333
- // 自定义类型校验器
334
272
  type: "custom"
335
273
  });
336
- return apiWrapResponse ? res : {
274
+ const baseJson = apiWrapResponse ? res : {
337
275
  ...apiResponseDto,
338
276
  data: res
339
277
  };
278
+ if (!needDevTracks()) return baseJson;
279
+ this.wrapApiResponseWithTracks(baseJson);
280
+ return baseJson;
281
+ }
282
+ consumeTracks() {
283
+ return this.ctx.consumeTracks().map(({ response, ...track }) => track);
340
284
  }
341
285
  };
342
286
  __name(_ApiResponseInterceptor, "ApiResponseInterceptor");
343
287
  var ApiResponseInterceptor = _ApiResponseInterceptor;
344
- ApiResponseInterceptor = _ts_decorate3([
345
- (0, import_common5.Injectable)(),
288
+ ApiResponseInterceptor = _ts_decorate2([
289
+ (0, import_common3.Injectable)(),
290
+ _ts_metadata2("design:type", Function),
291
+ _ts_metadata2("design:paramtypes", [
292
+ typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
293
+ typeof import_bff_core2.CtxService === "undefined" ? Object : import_bff_core2.CtxService
294
+ ])
295
+ ], ApiResponseInterceptor);
296
+ function needDevTracks() {
297
+ return process.env.ENV !== "prod" || process.env.NODE_ENV === "development";
298
+ }
299
+ __name(needDevTracks, "needDevTracks");
300
+
301
+ // src/apiResponse/ApiResponse.exception.filter.ts
302
+ function _ts_decorate3(decorators, target, key, desc) {
303
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
304
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
305
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
306
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
307
+ }
308
+ __name(_ts_decorate3, "_ts_decorate");
309
+ function _ts_metadata3(k, v) {
310
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
311
+ }
312
+ __name(_ts_metadata3, "_ts_metadata");
313
+ var _ApiResponseExceptionFilter = class _ApiResponseExceptionFilter {
314
+ constructor(ctx) {
315
+ __publicField(this, "ctx");
316
+ __publicField(this, "logger", new import_common4.Logger(_ApiResponseExceptionFilter.name));
317
+ this.ctx = ctx;
318
+ }
319
+ catch(exception, host) {
320
+ if (!exception) return;
321
+ const apiResponse = this.handleException(exception, host);
322
+ const context = host.switchToHttp();
323
+ const response = context.getResponse();
324
+ const defaultError = {
325
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
326
+ data: {},
327
+ msg: "\u5C0F\u6613\u7D2F\u4E86\uFF0C\u8BA9\u5C0F\u6613\u4F11\u606F\u4E00\u4E0B\u5427~"
328
+ };
329
+ const code = apiResponse?.code || defaultError.code;
330
+ const data = apiResponse?.data || defaultError.data;
331
+ const msg = apiResponse?.msg || defaultError.msg;
332
+ const debug = {
333
+ stack: apiResponse?.stack || "\u672A\u77E5\u7684stack\u9519\u8BEF",
334
+ tracks: this.ctx.consumeTracks()
335
+ };
336
+ const baseJson = {
337
+ code,
338
+ data,
339
+ msg,
340
+ traceid: this.ctx.traceid
341
+ };
342
+ const loggerJson = {
343
+ ...baseJson,
344
+ debug
345
+ };
346
+ this.logger.error(loggerJson);
347
+ response.status(import_common5.HttpStatus.OK).json(needDevTracks() ? loggerJson : baseJson);
348
+ }
349
+ handleException(exception, _host) {
350
+ if (exception instanceof import_common5.HttpException) {
351
+ return {
352
+ code: exception.getStatus(),
353
+ data: exception.getResponse(),
354
+ msg: exception.message,
355
+ stack: exception.stack
356
+ };
357
+ }
358
+ if (exception instanceof import_bff_validation2.ApiResponseException) {
359
+ return {
360
+ code: exception.code,
361
+ data: exception.data,
362
+ msg: exception.msg,
363
+ stack: exception.stack
364
+ };
365
+ }
366
+ if (exception instanceof Error) {
367
+ return {
368
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
369
+ data: exception,
370
+ msg: exception.message,
371
+ stack: exception.stack
372
+ };
373
+ }
374
+ if (typeof exception === "string") {
375
+ return {
376
+ code: import_common5.HttpStatus.INTERNAL_SERVER_ERROR,
377
+ data: {},
378
+ msg: exception,
379
+ stack: new Error(exception).stack
380
+ };
381
+ }
382
+ return exception;
383
+ }
384
+ };
385
+ __name(_ApiResponseExceptionFilter, "ApiResponseExceptionFilter");
386
+ var ApiResponseExceptionFilter = _ApiResponseExceptionFilter;
387
+ ApiResponseExceptionFilter = _ts_decorate3([
388
+ (0, import_common4.Catch)(),
346
389
  _ts_metadata3("design:type", Function),
347
390
  _ts_metadata3("design:paramtypes", [
348
- typeof import_core.Reflector === "undefined" ? Object : import_core.Reflector,
349
391
  typeof import_bff_core3.CtxService === "undefined" ? Object : import_bff_core3.CtxService
350
392
  ])
351
- ], ApiResponseInterceptor);
393
+ ], ApiResponseExceptionFilter);
352
394
 
353
395
  // src/endpoint.module.ts
354
396
  function _ts_decorate4(decorators, target, key, desc) {
@@ -493,5 +535,6 @@ __name(routeToTag, "routeToTag");
493
535
  ApiSuccessResponse,
494
536
  Endpoint,
495
537
  EndpointModule,
496
- Endpoints
538
+ Endpoints,
539
+ needDevTracks
497
540
  });
package/dist/index.mjs CHANGED
@@ -3,8 +3,9 @@ import {
3
3
  } from "./chunk-G3XZMNHG.mjs";
4
4
  import {
5
5
  ApiResponseInterceptor,
6
- EndpointModule
7
- } from "./chunk-L6OSYIFY.mjs";
6
+ EndpointModule,
7
+ needDevTracks
8
+ } from "./chunk-F42XQQAA.mjs";
8
9
  import {
9
10
  Endpoints
10
11
  } from "./chunk-5FTZ5OJ5.mjs";
@@ -27,5 +28,6 @@ export {
27
28
  ApiSuccessResponse,
28
29
  Endpoint,
29
30
  EndpointModule,
30
- Endpoints
31
+ Endpoints,
32
+ needDevTracks
31
33
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfe-repo/bff-endpoint",
3
- "version": "1.6.0",
3
+ "version": "1.6.4",
4
4
  "sideEffects": false,
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,8 +28,8 @@
28
28
  "eslint": "8.57.1",
29
29
  "reflect-metadata": "^0.2.2",
30
30
  "rxjs": "^7.8.2",
31
- "@xfe-repo/bff-core": "1.6.0",
32
- "@xfe-repo/bff-validation": "1.6.0"
31
+ "@xfe-repo/bff-core": "1.6.4",
32
+ "@xfe-repo/bff-validation": "1.6.4"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@nestjs/testing": "11.1.13",
@@ -37,8 +37,8 @@
37
37
  "@types/node": "^20.17.0",
38
38
  "jest": "^30.2.0",
39
39
  "@xfe-repo/eslint-config": "1.6.0",
40
- "@xfe-repo/jest-config": "1.6.0",
41
- "@xfe-repo/typescript-config": "1.6.0"
40
+ "@xfe-repo/typescript-config": "1.6.2",
41
+ "@xfe-repo/jest-config": "1.6.0"
42
42
  },
43
43
  "peerDependencies": {},
44
44
  "publishConfig": {