@open-norantec/herbal 1.0.2-alpha.2 → 1.0.2-alpha.20

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.
Files changed (34) hide show
  1. package/dist/abstracts/client.abstract.class.d.ts +13 -0
  2. package/dist/abstracts/client.abstract.class.js +40 -0
  3. package/dist/abstracts/index.d.ts +1 -0
  4. package/dist/abstracts/index.js +1 -0
  5. package/dist/cli/herbal.js +129 -71
  6. package/dist/clients/index.d.ts +1 -0
  7. package/dist/clients/index.js +17 -0
  8. package/dist/clients/typescript-client.class.d.ts +22 -0
  9. package/dist/clients/typescript-client.class.js +374 -0
  10. package/dist/core.d.ts +4 -3
  11. package/dist/core.js +59 -41
  12. package/dist/{create.d.ts → create/create-application.d.ts} +8 -8
  13. package/dist/create/create-application.js +18 -0
  14. package/dist/create/create-client.d.ts +9 -0
  15. package/dist/create/create-client.js +17 -0
  16. package/dist/create/index.d.ts +2 -0
  17. package/dist/create/index.js +18 -0
  18. package/dist/decorators/index.d.ts +2 -0
  19. package/dist/decorators/index.js +2 -0
  20. package/dist/decorators/method.decorator.d.ts +44 -0
  21. package/dist/decorators/method.decorator.js +185 -0
  22. package/dist/decorators/no-transaction.decorator.d.ts +5 -0
  23. package/dist/decorators/no-transaction.decorator.js +16 -0
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1 -0
  26. package/dist/sequelize-di.d.ts +4 -8
  27. package/dist/sequelize-di.js +12 -31
  28. package/dist/transformers/reflect-declaration.d.ts +1 -1
  29. package/dist/transformers/reflect-declaration.js +2 -2
  30. package/dist/types/request.type.d.ts +5 -2
  31. package/dist/utilities/controller-util.class.d.ts +2 -0
  32. package/dist/utilities/controller-util.class.js +124 -82
  33. package/package.json +8 -12
  34. package/dist/create.js +0 -154
@@ -72,13 +72,13 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
72
72
  return to.concat(ar || Array.prototype.slice.call(from));
73
73
  };
74
74
  Object.defineProperty(exports, "__esModule", { value: true });
75
- exports.ControllerUtil = exports.isHerbalController = void 0;
75
+ exports.ControllerUtil = exports.getControllerName = exports.isHerbalController = void 0;
76
76
  require("reflect-metadata");
77
77
  var common_1 = require("@nestjs/common");
78
78
  var _ = require("lodash");
79
79
  var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
80
+ var uuid_util_class_1 = require("@open-norantec/utilities/dist/uuid-util.class");
80
81
  var common_2 = require("@nestjs/common");
81
- var uuid_1 = require("uuid");
82
82
  var headers_constant_1 = require("../constants/headers.constant");
83
83
  var core_1 = require("@nestjs/core");
84
84
  var auth_adapter_decorator_1 = require("../decorators/auth-adapter.decorator");
@@ -86,11 +86,17 @@ var rxjs_1 = require("rxjs");
86
86
  var operators_1 = require("rxjs/operators");
87
87
  var logger_service_1 = require("../modules/logger/logger.service");
88
88
  var sequelize_typescript_1 = require("sequelize-typescript");
89
- var IS_CONTROLLER = Symbol();
89
+ var decorators_1 = require("../decorators");
90
+ var IS_HERBAL_CONTROLLER = Symbol();
91
+ var CONTROLLER_NAME = Symbol();
90
92
  function isHerbalController(target) {
91
- return _.attempt(function () { return Reflect.getMetadata(IS_CONTROLLER, target.prototype); }) === true;
93
+ return _.attempt(function () { return Reflect.getMetadata(IS_HERBAL_CONTROLLER, target.prototype); }) === true;
92
94
  }
93
95
  exports.isHerbalController = isHerbalController;
96
+ function getControllerName(target) {
97
+ return Reflect.getMetadata(CONTROLLER_NAME, target.prototype);
98
+ }
99
+ exports.getControllerName = getControllerName;
94
100
  var ControllerInterceptor = (function () {
95
101
  function ControllerInterceptor(ref) {
96
102
  this.ref = ref;
@@ -102,9 +108,6 @@ var ControllerInterceptor = (function () {
102
108
  _.attempt(function () {
103
109
  _this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":response:url] ").concat(request === null || request === void 0 ? void 0 : request.originalUrl));
104
110
  });
105
- _.attempt(function () {
106
- return _this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":request:body] ").concat(JSON.stringify(request === null || request === void 0 ? void 0 : request.body)));
107
- });
108
111
  _.attempt(function () {
109
112
  return _this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":request:headers] ").concat(JSON.stringify(request === null || request === void 0 ? void 0 : request.headers)));
110
113
  });
@@ -139,6 +142,7 @@ var ControllerInterceptor = (function () {
139
142
  _.attempt(function () {
140
143
  _this.getLogger().error("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":response:error:stack] ").concat(error === null || error === void 0 ? void 0 : error.stack));
141
144
  });
145
+ _this.getLogger().error("Got error when handling route in interceptor: ".concat(error === null || error === void 0 ? void 0 : error.message, " ").concat(error === null || error === void 0 ? void 0 : error.stack));
142
146
  _.attempt(function () { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = request === null || request === void 0 ? void 0 : request.transaction) === null || _a === void 0 ? void 0 : _a.rollback) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.catch) === null || _d === void 0 ? void 0 : _d.call(_c, function () { }); });
143
147
  return (0, rxjs_1.throwError)(function () { return error; });
144
148
  }));
@@ -156,72 +160,68 @@ function HerbalGuard(options) {
156
160
  }
157
161
  HerbalGuardMixin.prototype.canActivate = function (context) {
158
162
  var _a, e_1, _b, _c;
159
- var _d, _e, _f, _g, _h;
163
+ var _d, _e, _f, _g, _h, _j, _k;
160
164
  return __awaiter(this, void 0, void 0, function () {
161
- var sequelizeInstance, transaction, request, response, traceId, chunks, _j, request_1, request_1_1, chunk, e_1_1, _k, parsedBody, authAdapters, _i, authAdapters_1, AuthAdapterClass, adapter, authenticateResult, error_1, _l;
165
+ var sequelizeInstance, transaction, request, response, traceId, chunks, _l, request_1, request_1_1, chunk, e_1_1, _m, parsedBody, rawHandlerName, handlerPropertype, handlerName, authAdapters, error_1, _i, authAdapters_1, AuthAdapterClass, adapter, authenticateResult, error_2, _o;
162
166
  var _this = this;
163
- return __generator(this, function (_m) {
164
- switch (_m.label) {
167
+ return __generator(this, function (_p) {
168
+ switch (_p.label) {
165
169
  case 0:
166
170
  sequelizeInstance = _.attempt(function () { return _this.ref.get(sequelize_typescript_1.Sequelize, { strict: false }); });
167
171
  transaction = undefined;
168
- if (!!(sequelizeInstance instanceof Error)) return [3, 2];
169
- return [4, ((_e = (_d = sequelizeInstance === null || sequelizeInstance === void 0 ? void 0 : sequelizeInstance.transaction) === null || _d === void 0 ? void 0 : _d.call(sequelizeInstance)) === null || _e === void 0 ? void 0 : _e.catch(function () { return Promise.resolve(undefined); }))];
170
- case 1:
171
- transaction = _m.sent();
172
- _m.label = 2;
173
- case 2:
174
172
  request = context.switchToHttp().getRequest();
175
173
  response = context.switchToHttp().getResponse();
176
- traceId = typeof (options === null || options === void 0 ? void 0 : options.getTraceId) === 'function' ? _.attempt(function () { return options.getTraceId(request); }) : (0, uuid_1.v4)();
177
- if (traceId instanceof Error)
178
- traceId = (0, uuid_1.v4)();
174
+ traceId = typeof (options === null || options === void 0 ? void 0 : options.getTraceId) === 'function'
175
+ ? _.attempt(function () { return options.getTraceId(request); })
176
+ : uuid_util_class_1.UUIDUtil.generateV4();
177
+ if (traceId instanceof Error || string_util_class_1.StringUtil.isFalsyString(traceId))
178
+ traceId = uuid_util_class_1.UUIDUtil.generateV4();
179
179
  request.traceId = traceId;
180
180
  request.methodName = request.url.split('/').pop();
181
- request.transaction = transaction;
181
+ request.moduleRef = this.ref;
182
182
  response.setHeader(headers_constant_1.HEADERS.TRACE_ID, traceId);
183
183
  chunks = [];
184
- _m.label = 3;
185
- case 3:
186
- _m.trys.push([3, 16, , 17]);
187
- _m.label = 4;
184
+ _p.label = 1;
185
+ case 1:
186
+ _p.trys.push([1, 14, , 15]);
187
+ _p.label = 2;
188
+ case 2:
189
+ _p.trys.push([2, 7, 8, 13]);
190
+ _l = true, request_1 = __asyncValues(request);
191
+ _p.label = 3;
192
+ case 3: return [4, request_1.next()];
188
193
  case 4:
189
- _m.trys.push([4, 9, 10, 15]);
190
- _j = true, request_1 = __asyncValues(request);
191
- _m.label = 5;
192
- case 5: return [4, request_1.next()];
193
- case 6:
194
- if (!(request_1_1 = _m.sent(), _a = request_1_1.done, !_a)) return [3, 8];
194
+ if (!(request_1_1 = _p.sent(), _a = request_1_1.done, !_a)) return [3, 6];
195
195
  _c = request_1_1.value;
196
- _j = false;
196
+ _l = false;
197
197
  chunk = _c;
198
198
  chunks.push(chunk);
199
- _m.label = 7;
199
+ _p.label = 5;
200
+ case 5:
201
+ _l = true;
202
+ return [3, 3];
203
+ case 6: return [3, 13];
200
204
  case 7:
201
- _j = true;
202
- return [3, 5];
203
- case 8: return [3, 15];
204
- case 9:
205
- e_1_1 = _m.sent();
205
+ e_1_1 = _p.sent();
206
206
  e_1 = { error: e_1_1 };
207
- return [3, 15];
208
- case 10:
209
- _m.trys.push([10, , 13, 14]);
210
- if (!(!_j && !_a && (_b = request_1.return))) return [3, 12];
207
+ return [3, 13];
208
+ case 8:
209
+ _p.trys.push([8, , 11, 12]);
210
+ if (!(!_l && !_a && (_b = request_1.return))) return [3, 10];
211
211
  return [4, _b.call(request_1)];
212
+ case 9:
213
+ _p.sent();
214
+ _p.label = 10;
215
+ case 10: return [3, 12];
212
216
  case 11:
213
- _m.sent();
214
- _m.label = 12;
215
- case 12: return [3, 14];
216
- case 13:
217
217
  if (e_1) throw e_1.error;
218
218
  return [7];
219
- case 14: return [7];
220
- case 15: return [3, 17];
221
- case 16:
222
- _k = _m.sent();
223
- return [3, 17];
224
- case 17:
219
+ case 12: return [7];
220
+ case 13: return [3, 15];
221
+ case 14:
222
+ _m = _p.sent();
223
+ return [3, 15];
224
+ case 15:
225
225
  parsedBody = _.attempt(function () { return Buffer.concat(chunks).toString('utf8'); });
226
226
  if (!(parsedBody instanceof Error)) {
227
227
  request.rawBody = parsedBody;
@@ -229,49 +229,87 @@ function HerbalGuard(options) {
229
229
  else {
230
230
  request.rawBody = null;
231
231
  }
232
- authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters((_g = (_f = context === null || context === void 0 ? void 0 : context.getClass) === null || _f === void 0 ? void 0 : _f.call(context)) === null || _g === void 0 ? void 0 : _g.prototype, request.methodName);
233
- _m.label = 18;
232
+ _.attempt(function () { return _this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":request:body] ").concat(request.rawBody)); });
233
+ rawHandlerName = (_e = (_d = context === null || context === void 0 ? void 0 : context.getHandler) === null || _d === void 0 ? void 0 : _d.call(context)) === null || _e === void 0 ? void 0 : _e.name;
234
+ handlerPropertype = (_g = (_f = context === null || context === void 0 ? void 0 : context.getClass) === null || _f === void 0 ? void 0 : _f.call(context)) === null || _g === void 0 ? void 0 : _g.prototype;
235
+ handlerName = string_util_class_1.StringUtil.isFalsyString(rawHandlerName) ? request.methodName : rawHandlerName;
236
+ authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters(handlerPropertype, handlerName);
237
+ if (!(!(sequelizeInstance instanceof Error) && !decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName))) return [3, 20];
238
+ _p.label = 16;
239
+ case 16:
240
+ _p.trys.push([16, 18, , 19]);
241
+ return [4, ((_j = (_h = sequelizeInstance === null || sequelizeInstance === void 0 ? void 0 : sequelizeInstance.transaction) === null || _h === void 0 ? void 0 : _h.call(sequelizeInstance)) === null || _j === void 0 ? void 0 : _j.catch(function () { return Promise.resolve(undefined); }))];
242
+ case 17:
243
+ transaction = _p.sent();
244
+ request.transaction = transaction;
245
+ this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Started transaction for route: ").concat(handlerName));
246
+ return [3, 19];
234
247
  case 18:
235
- _m.trys.push([18, 24, , 29]);
236
- if (!(Array.isArray(authAdapters) && authAdapters.length > 0)) return [3, 23];
248
+ error_1 = _p.sent();
249
+ if (error_1 instanceof Error) {
250
+ this.getLogger().error("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Failed to start transaction: ").concat(error_1 === null || error_1 === void 0 ? void 0 : error_1.message, "\n").concat(error_1 === null || error_1 === void 0 ? void 0 : error_1.stack));
251
+ }
252
+ return [3, 19];
253
+ case 19: return [3, 21];
254
+ case 20:
255
+ if (decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName)) {
256
+ this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Transaction is disabled for this route: ").concat(handlerName));
257
+ }
258
+ _p.label = 21;
259
+ case 21:
260
+ _p.trys.push([21, 27, , 32]);
261
+ if (!(Array.isArray(authAdapters) && authAdapters.length > 0)) return [3, 26];
237
262
  _i = 0, authAdapters_1 = authAdapters;
238
- _m.label = 19;
239
- case 19:
240
- if (!(_i < authAdapters_1.length)) return [3, 22];
263
+ _p.label = 22;
264
+ case 22:
265
+ if (!(_i < authAdapters_1.length)) return [3, 25];
241
266
  AuthAdapterClass = authAdapters_1[_i];
242
267
  adapter = new AuthAdapterClass(request, this.ref);
243
268
  if (!adapter.match())
244
- return [3, 21];
269
+ return [3, 24];
245
270
  return [4, adapter.authenticate(transaction)];
246
- case 20:
247
- authenticateResult = _m.sent();
271
+ case 23:
272
+ authenticateResult = _p.sent();
248
273
  if (!authenticateResult)
249
- return [3, 22];
274
+ return [3, 25];
250
275
  request.authenticateResult = __assign({ AuthenticatorClass: AuthAdapterClass }, authenticateResult);
251
276
  return [2, true];
252
- case 21:
253
- _i++;
254
- return [3, 19];
255
- case 22: throw new common_2.UnauthorizedException();
256
- case 23: return [3, 29];
257
277
  case 24:
258
- error_1 = _m.sent();
259
- _m.label = 25;
260
- case 25:
261
- _m.trys.push([25, 27, , 28]);
262
- return [4, ((_h = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _h === void 0 ? void 0 : _h.call(transaction))];
263
- case 26:
264
- _m.sent();
265
- return [3, 28];
278
+ _i++;
279
+ return [3, 22];
280
+ case 25: throw new common_2.UnauthorizedException();
281
+ case 26: return [3, 32];
266
282
  case 27:
267
- _l = _m.sent();
268
- return [3, 28];
269
- case 28: throw error_1;
270
- case 29: return [2, true];
283
+ error_2 = _p.sent();
284
+ _p.label = 28;
285
+ case 28:
286
+ _p.trys.push([28, 30, , 31]);
287
+ if (error_2 instanceof Error) {
288
+ this.getLogger().error("Got error when handling route: ".concat(error_2 === null || error_2 === void 0 ? void 0 : error_2.message, " ").concat(error_2 === null || error_2 === void 0 ? void 0 : error_2.stack));
289
+ }
290
+ return [4, ((_k = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _k === void 0 ? void 0 : _k.call(transaction))];
291
+ case 29:
292
+ _p.sent();
293
+ return [3, 31];
294
+ case 30:
295
+ _o = _p.sent();
296
+ return [3, 31];
297
+ case 31: throw error_2;
298
+ case 32: return [2, true];
271
299
  }
272
300
  });
273
301
  });
274
302
  };
303
+ HerbalGuardMixin.prototype.getLogger = function () {
304
+ var loggerService = this.ref.get(logger_service_1.LoggerService, { strict: false });
305
+ if (!(loggerService instanceof logger_service_1.LoggerService)) {
306
+ return {
307
+ log: function () { },
308
+ error: function () { },
309
+ };
310
+ }
311
+ return loggerService;
312
+ };
275
313
  HerbalGuardMixin = __decorate([
276
314
  (0, common_2.Injectable)(),
277
315
  __metadata("design:paramtypes", [core_1.ModuleRef])
@@ -286,21 +324,25 @@ var ControllerUtil = (function () {
286
324
  ControllerUtil.create = function (createOptions) {
287
325
  function Controller(options) {
288
326
  return function (target) {
327
+ var _a;
289
328
  var finalPrefix = string_util_class_1.StringUtil.isFalsyString(options === null || options === void 0 ? void 0 : options.prefix)
290
329
  ? string_util_class_1.StringUtil.isFalsyString(createOptions === null || createOptions === void 0 ? void 0 : createOptions.prefix)
291
330
  ? ''
292
331
  : createOptions.prefix
293
332
  : options.prefix;
294
- finalPrefix += "/".concat(_.camelCase(target.name.replace(/Controller$/g, '')));
333
+ var controllerName = _.camelCase(target.name.replace(/Controller$/g, ''));
334
+ finalPrefix += "".concat(((_a = finalPrefix === null || finalPrefix === void 0 ? void 0 : finalPrefix.endsWith) === null || _a === void 0 ? void 0 : _a.call(finalPrefix, '/')) ? '' : '/').concat(controllerName);
295
335
  if (!finalPrefix.startsWith('/'))
296
336
  finalPrefix = "/".concat(finalPrefix);
297
- Reflect.defineMetadata(IS_CONTROLLER, true, target.prototype);
337
+ Reflect.defineMetadata(IS_HERBAL_CONTROLLER, true, target.prototype);
338
+ Reflect.defineMetadata(CONTROLLER_NAME, controllerName, target.prototype);
298
339
  (0, common_1.Controller)(finalPrefix)(target);
299
340
  (0, common_1.UseInterceptors)(ControllerInterceptor)(target);
300
341
  common_1.UseGuards.apply(void 0, __spreadArray(__spreadArray(__spreadArray([HerbalGuard(_.pick(createOptions, ['getTraceId']))], (Array.isArray(options === null || options === void 0 ? void 0 : options.useHeadGuards) ? options.useHeadGuards : []), false), (Array.isArray(createOptions === null || createOptions === void 0 ? void 0 : createOptions.useGuards) ? createOptions.useGuards : []), false), (Array.isArray(options === null || options === void 0 ? void 0 : options.useTailGuards) ? options.useTailGuards : []), false))(target);
301
342
  };
302
343
  }
303
344
  Controller.isHerbalController = isHerbalController;
345
+ Controller.getControllerName = getControllerName;
304
346
  return Controller;
305
347
  };
306
348
  return ControllerUtil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-norantec/herbal",
3
- "version": "1.0.2-alpha.2",
3
+ "version": "1.0.2-alpha.20",
4
4
  "description": "Herbal is a builder and toolchain for Nest.js applications",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -38,9 +38,10 @@
38
38
  "@nestjs/common": "^10.0.0",
39
39
  "@nestjs/core": "^10.4.19",
40
40
  "@nestjs/sequelize": "^10.0.1",
41
- "@open-norantec/forge": "latest",
41
+ "@open-norantec/forge": "^2.0.0-alpha.9",
42
42
  "@open-norantec/utilities": "latest",
43
43
  "commander": "^12.1.0",
44
+ "fs-extra": "^11.3.4",
44
45
  "lodash": "^4.17.21",
45
46
  "nest-winston": "^1.10.2",
46
47
  "nj-request-scope": "^1.0.10",
@@ -49,26 +50,21 @@
49
50
  "rxjs": "^7.8.2",
50
51
  "sequelize": "6.37.7",
51
52
  "sequelize-typescript": "^2.1.5",
52
- "ts-patch": "^3.3.0",
53
53
  "type-fest": "^4.41.0",
54
+ "typescript": ">=5.1.0 <5.2.0",
54
55
  "uuid": "^11.1.0",
55
- "zod": "^3.25.67"
56
+ "zod": "^3.25.67",
57
+ "zod-openapi": "4.2.4"
56
58
  },
57
59
  "devDependencies": {
58
- "@stylistic/eslint-plugin": "^2.12.1",
59
60
  "@types/express": "^5.0.3",
61
+ "@types/fs-extra": "^11.0.4",
60
62
  "@types/lodash": "^4.17.16",
61
63
  "@types/node": "18.11.18",
62
- "@typescript-eslint/eslint-plugin": "^8.0.0",
63
- "@typescript-eslint/parser": "^8.0.0",
64
64
  "cross-env": "^7.0.3",
65
65
  "eslint": "^8.0.0",
66
- "eslint-config-prettier": "^9.0.0",
67
- "eslint-plugin-prettier": "^5.0.0",
68
66
  "express": "^4.21.2",
69
- "prettier": "^3.0.0",
70
67
  "rimraf": "^6.0.1",
71
- "ts-node": "^10.0.0",
72
- "typescript": "~5.1.3"
68
+ "ts-node": "^10.0.0"
73
69
  }
74
70
  }
package/dist/create.js DELETED
@@ -1,154 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.create = void 0;
4
- require("reflect-metadata");
5
- var _ = require("lodash");
6
- var nest_util_class_1 = require("./utilities/nest-util.class");
7
- var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
8
- var reflect_declaration_1 = require("./transformers/reflect-declaration");
9
- var client_groups_decorator_1 = require("./decorators/client-groups.decorator");
10
- var controller_util_class_1 = require("./utilities/controller-util.class");
11
- function create(options) {
12
- return {
13
- options: options,
14
- generateClientSourceFile: function () {
15
- if (!(options === null || options === void 0 ? void 0 : options.Module))
16
- throw new Error("Parameter 'Module' must be specified");
17
- var METHOD_TYPE_MAP_NAME = 'MethodTypeMap';
18
- var METHOD_TYPE_MAP_KEYS_NAME = 'MethodTypeMapKeys';
19
- var RESPONSE_CALLBACK_DATA_NAME = 'ResponseCallbackData';
20
- var REQUEST_OPTIONS_NAME = 'RequestOptions';
21
- var RESULT_TYPE_NAME = 'Result';
22
- var HTTP_RESPONSE_BODY_TYPE_NAME = 'HttpResponseBody';
23
- var REQUEST_METHOD_MAP_NAME = 'REQUEST_METHOD_MAP';
24
- var RESPONSE_CACHE_MAP_NAME = 'RESPONSE_CACHE_MAP';
25
- var REQUEST_BODY_TYPE_ANNOTATION = "".concat(METHOD_TYPE_MAP_NAME, "[T]['request']");
26
- var RESULT_TYPE_ANNOTATION = "".concat(RESULT_TYPE_NAME, "<").concat(HTTP_RESPONSE_BODY_TYPE_NAME, "<").concat(METHOD_TYPE_MAP_NAME, "[T]['response']>>");
27
- var methodTypeMapCodeLines = nest_util_class_1.NestUtil.getControllerClasses(options.Module)
28
- .reduce(function (result, Class) {
29
- if (string_util_class_1.StringUtil.isFalsyString(Class === null || Class === void 0 ? void 0 : Class.name))
30
- return result;
31
- var controllerName = _.camelCase(Class.name.replace(/Controller$/g, ''));
32
- if (string_util_class_1.StringUtil.isFalsyString(controllerName) || !(0, controller_util_class_1.isHerbalController)(Class)) {
33
- return result;
34
- }
35
- var metadataNames = Reflect.getMetadataKeys(Class.prototype).filter(function (metadataName) { return !string_util_class_1.StringUtil.isFalsyString(metadataName); });
36
- return result.concat(metadataNames.reduce(function (result, metadataName) {
37
- var methodName = metadataName.slice(reflect_declaration_1.DECORATOR_NAME_PREFIX.length);
38
- if (string_util_class_1.StringUtil.isFalsyString(metadataName) ||
39
- !metadataName.startsWith(reflect_declaration_1.DECORATOR_NAME_PREFIX) ||
40
- !client_groups_decorator_1.ClientGroups.shouldShowInClient(Class, methodName, options === null || options === void 0 ? void 0 : options.allowedClientGroupsFactory)) {
41
- return result;
42
- }
43
- var scopeIdentifier = "/".concat(controllerName, "/").concat(methodName);
44
- return result.concat(["'".concat(scopeIdentifier, "'"), "".concat(Reflect.getMetadata(metadataName, Class.prototype), ";")].join(': '));
45
- }, []));
46
- }, [])
47
- .map(function (line) { return " ".concat(line); });
48
- methodTypeMapCodeLines.unshift("export interface ".concat(METHOD_TYPE_MAP_NAME, " {"));
49
- methodTypeMapCodeLines.push('}');
50
- return [
51
- "import * as hash from 'object-hash';",
52
- "import * as _ from 'lodash';",
53
- "\n".concat(methodTypeMapCodeLines.join('\n')),
54
- "\ntype ".concat(METHOD_TYPE_MAP_KEYS_NAME, " = keyof ").concat(METHOD_TYPE_MAP_NAME, ";"),
55
- "\ntype ".concat(RESPONSE_CALLBACK_DATA_NAME, "<K extends ").concat(METHOD_TYPE_MAP_KEYS_NAME, "> = {"),
56
- ' url: K;',
57
- " result: ".concat(RESULT_TYPE_NAME, "<").concat(HTTP_RESPONSE_BODY_TYPE_NAME, "<").concat(METHOD_TYPE_MAP_NAME, "[K]['response']>>;"),
58
- '};',
59
- "\nexport type ".concat(HTTP_RESPONSE_BODY_TYPE_NAME, "<T> = {"),
60
- ' data: T;',
61
- ' token: string | null;',
62
- '};',
63
- "\nexport interface ".concat(REQUEST_OPTIONS_NAME, " extends RequestInit {"),
64
- ' headers?: Record<string, any>;',
65
- ' ignoreCache?: boolean;',
66
- ' prefix?: string;',
67
- ' timeout?: number;',
68
- ' getAuthorizationCredential?: () => string;',
69
- " onRequest?: (context: { cached: boolean; id: string; options: Omit<".concat(REQUEST_OPTIONS_NAME, ", 'getAuthorizationCredential' | 'onRequest' | 'onResponse'>; prefix: string | undefined; requestBody: string; url: string; }) => void | Promise<void>;"),
70
- " onResponse?: <K extends ".concat(METHOD_TYPE_MAP_KEYS_NAME, ">(response: ").concat(RESPONSE_CALLBACK_DATA_NAME, "<K>, id: string) => void | Promise<void>;"),
71
- '}',
72
- "\nexport interface ".concat(RESULT_TYPE_NAME, "<T> {"),
73
- ' error: Error | null;',
74
- " response: T | null;",
75
- ' status: number;',
76
- ' statusText: string;',
77
- ' headers?: Record<string, any>;',
78
- '}',
79
- '\nexport class Client {',
80
- " public constructor(private readonly options: ".concat(REQUEST_OPTIONS_NAME, " = {}) {}"),
81
- "\n protected readonly ".concat(REQUEST_METHOD_MAP_NAME, " = new Map<keyof ").concat(METHOD_TYPE_MAP_NAME, ", (...params: any[]) => Promise<unknown>>();"),
82
- "\n protected readonly ".concat(RESPONSE_CACHE_MAP_NAME, " = new Map<string, ").concat(RESULT_TYPE_NAME, "<unknown>>();"),
83
- "\n public createRequest<T extends keyof ".concat(METHOD_TYPE_MAP_NAME, ">(url: T): (requestBody?: ").concat(REQUEST_BODY_TYPE_ANNOTATION, ", options?: ").concat(REQUEST_OPTIONS_NAME, ") => Promise<").concat(RESULT_TYPE_ANNOTATION, "> {"),
84
- " if (typeof this.".concat(REQUEST_METHOD_MAP_NAME, ".get(url) !== 'function') {"),
85
- " this.".concat(REQUEST_METHOD_MAP_NAME, ".set(url, (requestBody?: ").concat(REQUEST_BODY_TYPE_ANNOTATION, ", options?: ").concat(REQUEST_OPTIONS_NAME, ") => this.request.call(this, url, requestBody, options));"),
86
- ' }',
87
- " return this.".concat(REQUEST_METHOD_MAP_NAME, ".get(url) as (requestBody?: ").concat(REQUEST_BODY_TYPE_ANNOTATION, ", options?: ").concat(REQUEST_OPTIONS_NAME, ") => Promise<").concat(RESULT_TYPE_ANNOTATION, ">;"),
88
- ' }',
89
- "\n public async request<T extends keyof ".concat(METHOD_TYPE_MAP_NAME, ">(url: T, requestBody?: ").concat(REQUEST_BODY_TYPE_ANNOTATION, ", options?: Omit<").concat(REQUEST_OPTIONS_NAME, ", 'getAuthorizationCredential' | 'onRequest' | 'onResponse'>): Promise<").concat(RESULT_TYPE_ANNOTATION, "> {"),
90
- ' const id = `${Math.random().toString(32).slice(2)}${Date.now().toString(16)}`;',
91
- ' const requestHash = hash(requestBody ?? null);',
92
- ' const requestBodyString = JSON.stringify(requestBody);',
93
- " const finalOptions = _.merge({}, this?.options, _.omit(options, ['getAuthorizationCredential', 'onRequest', 'onResponse']));",
94
- " const onRequestOptions = _.omit(finalOptions, ['getAuthorizationCredential', 'onRequest', 'onResponse']);",
95
- ' const { getAuthorizationCredential, onResponse, onRequest, ignoreCache, timeout, prefix, ...requestOptions } = finalOptions;',
96
- " if (this.".concat(RESPONSE_CACHE_MAP_NAME, ".has(requestHash) && !ignoreCache) {"),
97
- ' onRequest?.({',
98
- ' prefix,',
99
- ' url,',
100
- ' requestBody: requestBodyString,',
101
- ' cached: true,',
102
- ' options: onRequestOptions,',
103
- ' id,',
104
- ' });',
105
- " return this.".concat(RESPONSE_CACHE_MAP_NAME, ".get(requestHash) as ").concat(RESULT_TYPE_ANNOTATION, ";"),
106
- ' }',
107
- ' onRequest?.({',
108
- ' prefix,',
109
- ' url,',
110
- ' id,',
111
- ' requestBody: requestBodyString,',
112
- ' cached: false,',
113
- ' options: onRequestOptions,',
114
- ' });',
115
- ' const credential = getAuthorizationCredential?.();',
116
- ' const abortController = new AbortController();',
117
- ' if (timeout! > 0) {',
118
- ' setTimeout(() => {',
119
- ' abortController.abort();',
120
- ' }, timeout);',
121
- ' }',
122
- " const result: ".concat(RESULT_TYPE_ANNOTATION, " = await fetch((prefix ?? '') + url, {"),
123
- ' ...requestOptions,',
124
- ' body: JSON.stringify(requestBody),',
125
- " method: 'POST',",
126
- ' signal: abortController.signal,',
127
- ' headers: {',
128
- ' ...requestOptions?.headers,',
129
- " 'Content-Type': 'application/json',",
130
- " Authorization: (typeof credential === 'string' && credential.length > 0) ? credential : finalOptions?.headers?.Authorization,",
131
- ' },',
132
- ' }).then((response) => {',
133
- ' const status = response?.status;',
134
- ' const statusText = response?.statusText;',
135
- ' const headers = Array.from(response?.headers?.entries?.() ?? []).reduce((result, [key, value]) => {',
136
- " if (typeof key !== 'string' || key.length === 0) return result;",
137
- ' result[key] = value;',
138
- ' return result;',
139
- ' }, {});',
140
- ' if (!response?.ok) {',
141
- ' return response.text().then((errorText) => ({ error: new Error(errorText), response: null, headers, status, statusText }));',
142
- ' }',
143
- " return response.json().then((response) => ({ error: null, response, headers, status, statusText } as ".concat(RESULT_TYPE_ANNOTATION, "));"),
144
- " }).catch((error) => Promise.resolve({ error, response: null, headers: {}, status: 0, statusText: '' }));",
145
- " onResponse?.({ url, result }, id);",
146
- " this.".concat(RESPONSE_CACHE_MAP_NAME, ".set(requestHash, result);"),
147
- ' return result;',
148
- ' }',
149
- '}\n',
150
- ].join('\n');
151
- },
152
- };
153
- }
154
- exports.create = create;