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

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 +45 -0
  21. package/dist/decorators/method.decorator.js +193 -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 +126 -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, _l, _m;
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, _o, request_1, request_1_1, chunk, e_1_1, _p, parsedBody, rawHandlerName, handlerPropertype, handlerName, authAdapters, error_1, _i, authAdapters_1, AuthAdapterClass, adapter, authenticateResult, error_2, _q;
162
166
  var _this = this;
163
- return __generator(this, function (_m) {
164
- switch (_m.label) {
167
+ return __generator(this, function (_r) {
168
+ switch (_r.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
+ _r.label = 1;
185
+ case 1:
186
+ _r.trys.push([1, 14, , 15]);
187
+ _r.label = 2;
188
+ case 2:
189
+ _r.trys.push([2, 7, 8, 13]);
190
+ _o = true, request_1 = __asyncValues(request);
191
+ _r.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 = _r.sent(), _a = request_1_1.done, !_a)) return [3, 6];
195
195
  _c = request_1_1.value;
196
- _j = false;
196
+ _o = false;
197
197
  chunk = _c;
198
198
  chunks.push(chunk);
199
- _m.label = 7;
199
+ _r.label = 5;
200
+ case 5:
201
+ _o = 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 = _r.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
+ _r.trys.push([8, , 11, 12]);
210
+ if (!(!_o && !_a && (_b = request_1.return))) return [3, 10];
211
211
  return [4, _b.call(request_1)];
212
+ case 9:
213
+ _r.sent();
214
+ _r.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
+ _p = _r.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,89 @@ 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 = (_j = (_h = decorators_1.Method.getPool(handlerPropertype)) === null || _h === void 0 ? void 0 : _h.getAuthAdapters) === null || _j === void 0 ? void 0 : _j.call(_h, handlerName);
237
+ if (authAdapters === null)
238
+ authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters(handlerPropertype, handlerName);
239
+ if (!(!(sequelizeInstance instanceof Error) && !decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName))) return [3, 20];
240
+ _r.label = 16;
241
+ case 16:
242
+ _r.trys.push([16, 18, , 19]);
243
+ return [4, ((_l = (_k = sequelizeInstance === null || sequelizeInstance === void 0 ? void 0 : sequelizeInstance.transaction) === null || _k === void 0 ? void 0 : _k.call(sequelizeInstance)) === null || _l === void 0 ? void 0 : _l.catch(function () { return Promise.resolve(undefined); }))];
244
+ case 17:
245
+ transaction = _r.sent();
246
+ request.transaction = transaction;
247
+ this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Started transaction for route: ").concat(handlerName));
248
+ return [3, 19];
234
249
  case 18:
235
- _m.trys.push([18, 24, , 29]);
236
- if (!(Array.isArray(authAdapters) && authAdapters.length > 0)) return [3, 23];
250
+ error_1 = _r.sent();
251
+ if (error_1 instanceof Error) {
252
+ 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));
253
+ }
254
+ return [3, 19];
255
+ case 19: return [3, 21];
256
+ case 20:
257
+ if (decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName)) {
258
+ this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Transaction is disabled for this route: ").concat(handlerName));
259
+ }
260
+ _r.label = 21;
261
+ case 21:
262
+ _r.trys.push([21, 27, , 32]);
263
+ if (!(Array.isArray(authAdapters) && authAdapters.length > 0)) return [3, 26];
237
264
  _i = 0, authAdapters_1 = authAdapters;
238
- _m.label = 19;
239
- case 19:
240
- if (!(_i < authAdapters_1.length)) return [3, 22];
265
+ _r.label = 22;
266
+ case 22:
267
+ if (!(_i < authAdapters_1.length)) return [3, 25];
241
268
  AuthAdapterClass = authAdapters_1[_i];
242
269
  adapter = new AuthAdapterClass(request, this.ref);
243
270
  if (!adapter.match())
244
- return [3, 21];
271
+ return [3, 24];
245
272
  return [4, adapter.authenticate(transaction)];
246
- case 20:
247
- authenticateResult = _m.sent();
273
+ case 23:
274
+ authenticateResult = _r.sent();
248
275
  if (!authenticateResult)
249
- return [3, 22];
276
+ return [3, 25];
250
277
  request.authenticateResult = __assign({ AuthenticatorClass: AuthAdapterClass }, authenticateResult);
251
278
  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
279
  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];
280
+ _i++;
281
+ return [3, 22];
282
+ case 25: throw new common_2.UnauthorizedException();
283
+ case 26: return [3, 32];
266
284
  case 27:
267
- _l = _m.sent();
268
- return [3, 28];
269
- case 28: throw error_1;
270
- case 29: return [2, true];
285
+ error_2 = _r.sent();
286
+ _r.label = 28;
287
+ case 28:
288
+ _r.trys.push([28, 30, , 31]);
289
+ if (error_2 instanceof Error) {
290
+ 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));
291
+ }
292
+ return [4, ((_m = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _m === void 0 ? void 0 : _m.call(transaction))];
293
+ case 29:
294
+ _r.sent();
295
+ return [3, 31];
296
+ case 30:
297
+ _q = _r.sent();
298
+ return [3, 31];
299
+ case 31: throw error_2;
300
+ case 32: return [2, true];
271
301
  }
272
302
  });
273
303
  });
274
304
  };
305
+ HerbalGuardMixin.prototype.getLogger = function () {
306
+ var loggerService = this.ref.get(logger_service_1.LoggerService, { strict: false });
307
+ if (!(loggerService instanceof logger_service_1.LoggerService)) {
308
+ return {
309
+ log: function () { },
310
+ error: function () { },
311
+ };
312
+ }
313
+ return loggerService;
314
+ };
275
315
  HerbalGuardMixin = __decorate([
276
316
  (0, common_2.Injectable)(),
277
317
  __metadata("design:paramtypes", [core_1.ModuleRef])
@@ -286,21 +326,25 @@ var ControllerUtil = (function () {
286
326
  ControllerUtil.create = function (createOptions) {
287
327
  function Controller(options) {
288
328
  return function (target) {
329
+ var _a;
289
330
  var finalPrefix = string_util_class_1.StringUtil.isFalsyString(options === null || options === void 0 ? void 0 : options.prefix)
290
331
  ? string_util_class_1.StringUtil.isFalsyString(createOptions === null || createOptions === void 0 ? void 0 : createOptions.prefix)
291
332
  ? ''
292
333
  : createOptions.prefix
293
334
  : options.prefix;
294
- finalPrefix += "/".concat(_.camelCase(target.name.replace(/Controller$/g, '')));
335
+ var controllerName = _.camelCase(target.name.replace(/Controller$/g, ''));
336
+ finalPrefix += "".concat(((_a = finalPrefix === null || finalPrefix === void 0 ? void 0 : finalPrefix.endsWith) === null || _a === void 0 ? void 0 : _a.call(finalPrefix, '/')) ? '' : '/').concat(controllerName);
295
337
  if (!finalPrefix.startsWith('/'))
296
338
  finalPrefix = "/".concat(finalPrefix);
297
- Reflect.defineMetadata(IS_CONTROLLER, true, target.prototype);
339
+ Reflect.defineMetadata(IS_HERBAL_CONTROLLER, true, target.prototype);
340
+ Reflect.defineMetadata(CONTROLLER_NAME, controllerName, target.prototype);
298
341
  (0, common_1.Controller)(finalPrefix)(target);
299
342
  (0, common_1.UseInterceptors)(ControllerInterceptor)(target);
300
343
  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
344
  };
302
345
  }
303
346
  Controller.isHerbalController = isHerbalController;
347
+ Controller.getControllerName = getControllerName;
304
348
  return Controller;
305
349
  };
306
350
  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.21",
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;