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

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.
@@ -5,7 +5,6 @@ require("reflect-metadata");
5
5
  var nest_util_class_1 = require("../utilities/nest-util.class");
6
6
  var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
7
7
  var controller_util_class_1 = require("../utilities/controller-util.class");
8
- var method_decorator_1 = require("../decorators/method.decorator");
9
8
  var Client = (function () {
10
9
  function Client(options) {
11
10
  this.options = options;
@@ -26,7 +25,7 @@ var Client = (function () {
26
25
  if (string_util_class_1.StringUtil.isFalsyString(Class === null || Class === void 0 ? void 0 : Class.name) || !(0, controller_util_class_1.isHerbalController)(Class))
27
26
  return;
28
27
  var controllerName = (0, controller_util_class_1.getControllerName)(Class);
29
- var pool = method_decorator_1.Method.getPool(Class.prototype);
28
+ var pool = controller_util_class_1.ControllerUtil.getPool(Class.prototype);
30
29
  if (string_util_class_1.StringUtil.isFalsyString(controllerName) || pool === null)
31
30
  return;
32
31
  Object.entries(pool.getOpenAPIPathsObject(group)).forEach(function (_a) {
@@ -38,10 +38,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.TypeScriptClient = exports.convertOpenApiToTypescript = void 0;
39
39
  require("reflect-metadata");
40
40
  var client_abstract_class_1 = require("../abstracts/client.abstract.class");
41
- var nest_util_class_1 = require("../utilities/nest-util.class");
42
- var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
43
- var controller_util_class_1 = require("../utilities/controller-util.class");
44
- var method_decorator_1 = require("../decorators/method.decorator");
45
41
  var OpenApiToTypescriptConverter = (function () {
46
42
  function OpenApiToTypescriptConverter(options) {
47
43
  if (options === void 0) { options = {}; }
@@ -230,7 +226,7 @@ var TypeScriptClient = (function (_super) {
230
226
  return _super.call(this, options) || this;
231
227
  }
232
228
  TypeScriptClient.prototype.generateClientSourceFile = function () {
233
- var _this = this;
229
+ var _a;
234
230
  var options = this.options;
235
231
  if (!(options === null || options === void 0 ? void 0 : options.Module))
236
232
  throw new Error("Parameter 'Module' must be specified");
@@ -243,32 +239,22 @@ var TypeScriptClient = (function (_super) {
243
239
  var RESPONSE_CACHE_MAP_NAME = 'RESPONSE_CACHE_MAP';
244
240
  var REQUEST_BODY_TYPE_ANNOTATION = "".concat(METHOD_TYPE_MAP_NAME, "[T]['request']");
245
241
  var RESULT_TYPE_ANNOTATION = "".concat(RESULT_TYPE_NAME, "<").concat(METHOD_TYPE_MAP_NAME, "[T]['response']>");
246
- var methodTypeMapCodeLines = nest_util_class_1.NestUtil.getControllerClasses(options.Module)
247
- .reduce(function (result, Class) {
248
- var _a;
249
- if (string_util_class_1.StringUtil.isFalsyString(Class === null || Class === void 0 ? void 0 : Class.name) || !(0, controller_util_class_1.isHerbalController)(Class))
250
- return result;
251
- var pool = method_decorator_1.Method.getPool(Class.prototype);
252
- if (pool === null)
253
- return result;
254
- return result.concat(Object.entries((_a = _this.document.paths) !== null && _a !== void 0 ? _a : {})
255
- .map(function (_a) {
256
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
257
- var pathname = _a[0], schema = _a[1];
258
- var requestSchema = (_e = (_d = (_c = (_b = schema === null || schema === void 0 ? void 0 : schema.post) === null || _b === void 0 ? void 0 : _b.requestBody) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d['application/json']) === null || _e === void 0 ? void 0 : _e.schema;
259
- var responseSchema = (_k = (_j = (_h = (_g = (_f = schema === null || schema === void 0 ? void 0 : schema.post) === null || _f === void 0 ? void 0 : _f.responses) === null || _g === void 0 ? void 0 : _g['200']) === null || _h === void 0 ? void 0 : _h.content) === null || _j === void 0 ? void 0 : _j['application/json']) === null || _k === void 0 ? void 0 : _k.schema;
260
- if (!requestSchema && !responseSchema)
261
- return null;
262
- return [
263
- "'".concat(pathname, "': {"),
264
- " request: ".concat(((_l = convertOpenApiToTypescript(requestSchema)) === null || _l === void 0 ? void 0 : _l.code) || 'any', ";"),
265
- " response: ".concat(((_m = convertOpenApiToTypescript(responseSchema)) === null || _m === void 0 ? void 0 : _m.code) || 'any', ";"),
266
- ' };',
267
- ].join('');
268
- })
269
- .filter(function (value) { return value !== null; }));
270
- }, [])
271
- .map(function (line) { return " ".concat(line); });
242
+ var methodTypeMapCodeLines = Object.entries((_a = this.document.paths) !== null && _a !== void 0 ? _a : {})
243
+ .map(function (_a) {
244
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
245
+ var pathname = _a[0], schema = _a[1];
246
+ var requestSchema = (_e = (_d = (_c = (_b = schema === null || schema === void 0 ? void 0 : schema.post) === null || _b === void 0 ? void 0 : _b.requestBody) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d['application/json']) === null || _e === void 0 ? void 0 : _e.schema;
247
+ var responseSchema = (_k = (_j = (_h = (_g = (_f = schema === null || schema === void 0 ? void 0 : schema.post) === null || _f === void 0 ? void 0 : _f.responses) === null || _g === void 0 ? void 0 : _g['200']) === null || _h === void 0 ? void 0 : _h.content) === null || _j === void 0 ? void 0 : _j['application/json']) === null || _k === void 0 ? void 0 : _k.schema;
248
+ if (!requestSchema && !responseSchema)
249
+ return null;
250
+ return [
251
+ "'".concat(pathname, "': {"),
252
+ " request: ".concat(((_l = convertOpenApiToTypescript(requestSchema)) === null || _l === void 0 ? void 0 : _l.code) || 'any', ";"),
253
+ " response: ".concat(((_m = convertOpenApiToTypescript(responseSchema)) === null || _m === void 0 ? void 0 : _m.code) || 'any', ";"),
254
+ ' };',
255
+ ].join('');
256
+ })
257
+ .filter(function (value) { return value !== null; }).map(function (line) { return " ".concat(line); });
272
258
  methodTypeMapCodeLines.unshift("export interface ".concat(METHOD_TYPE_MAP_NAME, " {"));
273
259
  methodTypeMapCodeLines.push('}');
274
260
  return [
package/dist/core.d.ts CHANGED
@@ -2,6 +2,7 @@ import 'reflect-metadata';
2
2
  import { HeaderUtil } from '@open-norantec/utilities/dist/header-util.class';
3
3
  import { z } from 'zod';
4
4
  import { Request } from './types/request.type';
5
+ import { ModuleRef } from '@nestjs/core';
5
6
  export * from '@nestjs/core';
6
7
  interface LegacyMethodContext<IS extends z.Schema<any>> {
7
8
  headers: ReturnType<typeof HeaderUtil.parse>;
@@ -14,6 +15,7 @@ export type MethodHandler<IS extends z.Schema<any>, OS extends z.Schema<any>> =
14
15
  }>;
15
16
  export declare class HerbalController {
16
17
  protected registerMethod: <IS extends z.ZodType<any, z.ZodTypeDef, any>, OS extends z.ZodType<any, z.ZodTypeDef, any>>(inputSchema: IS, outputSchema: OS, callback: (context: LegacyMethodContext<IS>) => Promise<z.TypeOf<OS>>) => MethodHandler<IS, OS>;
18
+ protected moduleRef: ModuleRef;
17
19
  private $handleRequest;
18
20
  private $call;
19
21
  }
package/dist/core.js CHANGED
@@ -69,8 +69,9 @@ var header_util_class_1 = require("@open-norantec/utilities/dist/header-util.cla
69
69
  var zod_1 = require("zod");
70
70
  var _ = require("lodash");
71
71
  var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
72
- var decorators_1 = require("./decorators");
73
72
  var utilities_1 = require("@open-norantec/utilities");
73
+ var core_1 = require("@nestjs/core");
74
+ var controller_util_class_1 = require("./utilities/controller-util.class");
74
75
  __exportStar(require("@nestjs/core"), exports);
75
76
  var HerbalController = exports.HerbalController = (function () {
76
77
  function HerbalController() {
@@ -122,7 +123,7 @@ var HerbalController = exports.HerbalController = (function () {
122
123
  traceId: request.traceId,
123
124
  transaction: request.transaction,
124
125
  url: request.originalUrl,
125
- getProvider: function (token) { return request.moduleRef.get(token, { strict: false }); },
126
+ controller: this,
126
127
  })];
127
128
  case 1:
128
129
  result = (_e.data = _f.sent(),
@@ -162,7 +163,7 @@ var HerbalController = exports.HerbalController = (function () {
162
163
  return __generator(this, function (_c) {
163
164
  switch (_c.label) {
164
165
  case 0:
165
- callFn = (_b = (_a = decorators_1.Method.getPool(this)) === null || _a === void 0 ? void 0 : _a.getCallFn) === null || _b === void 0 ? void 0 : _b.call(_a, name);
166
+ callFn = (_b = (_a = controller_util_class_1.ControllerUtil.getPool(this)) === null || _a === void 0 ? void 0 : _a.getCallFn) === null || _b === void 0 ? void 0 : _b.call(_a, name);
166
167
  if (typeof callFn !== 'function')
167
168
  throw new common_1.NotFoundException("Method ".concat(name, " not found"));
168
169
  return [4, callFn(context)];
@@ -171,6 +172,10 @@ var HerbalController = exports.HerbalController = (function () {
171
172
  });
172
173
  });
173
174
  };
175
+ __decorate([
176
+ (0, common_1.Inject)(core_1.ModuleRef),
177
+ __metadata("design:type", core_1.ModuleRef)
178
+ ], HerbalController.prototype, "moduleRef", void 0);
174
179
  __decorate([
175
180
  (0, common_1.Post)('*'),
176
181
  __param(0, (0, common_1.Req)()),
@@ -1,4 +1,3 @@
1
1
  export * from './auth-adapter.decorator';
2
2
  export * from './client-groups.decorator';
3
3
  export * from './no-transaction.decorator';
4
- export * from './method.decorator';
@@ -17,4 +17,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./auth-adapter.decorator"), exports);
18
18
  __exportStar(require("./client-groups.decorator"), exports);
19
19
  __exportStar(require("./no-transaction.decorator"), exports);
20
- __exportStar(require("./method.decorator"), exports);
@@ -1,10 +1,8 @@
1
1
  import { Request as ExpressRequest } from 'express';
2
2
  import { AuthenticateResult } from '../abstracts/auth-adapter.abstract.class';
3
3
  import { Transaction } from 'sequelize';
4
- import { ModuleRef } from '@nestjs/core';
5
4
  export interface RequestContext {
6
5
  methodName: string;
7
- moduleRef: ModuleRef;
8
6
  rawBody: string | null;
9
7
  traceId: string;
10
8
  authenticateResult?: AuthenticateResult;
@@ -1,12 +1,51 @@
1
1
  import 'reflect-metadata';
2
+ import { RequestContext } from '../types/request.type';
2
3
  import { Request as ExpressRequest } from 'express';
3
4
  import { Constructor } from 'type-fest';
5
+ import { z } from 'zod';
6
+ import { AuthAdapter } from '../abstracts/auth-adapter.abstract.class';
7
+ import { HeaderUtil } from '@open-norantec/utilities/dist/header-util.class';
8
+ import { PathsObject } from 'zod-openapi/dist/openapi3-ts/dist/model/openapi31';
9
+ type ClientGroups = Array<string> | null | undefined;
10
+ type ClienttGroupsFactory = (defaultGroupName: string) => ClientGroups;
11
+ export interface MethodRegisterOptions<IS extends z.Schema<any>, OS extends z.Schema<any>> {
12
+ inputSchema: IS;
13
+ outputSchema: OS;
14
+ authAdapters?: Constructor<AuthAdapter>[];
15
+ clientGroups?: ClientGroups | ClienttGroupsFactory;
16
+ disableTransaction?: boolean;
17
+ }
18
+ export type MethodRegisterFn<C> = <IS extends z.Schema<any>, OS extends z.Schema<any>>(name: string, options: MethodRegisterOptions<IS, OS>, callback: MethodCallback<IS, OS, C>) => void;
19
+ export interface MethodContext<IS extends z.Schema<any>, C> extends RequestContext {
20
+ controller: C;
21
+ headers: ReturnType<typeof HeaderUtil.parse>;
22
+ input: z.infer<IS>;
23
+ url: string;
24
+ }
25
+ export type MethodCallContext<IS extends z.Schema<any>, C> = Omit<MethodContext<IS, C>, 'input'>;
26
+ export type MethodCallback<IS extends z.Schema<any>, OS extends z.Schema<any>, C> = (context: MethodContext<IS, C>) => Promise<z.infer<OS>>;
27
+ declare class MethodConfig<IS extends z.Schema<any>, OS extends z.Schema<any>, C> {
28
+ readonly name: string;
29
+ readonly options: MethodRegisterOptions<IS, OS>;
30
+ protected readonly callback: MethodCallback<IS, OS, C>;
31
+ constructor(name: string, options: MethodRegisterOptions<IS, OS>, callback: MethodCallback<IS, OS, C>);
32
+ call(callContext: MethodCallContext<IS, C>): Promise<z.TypeOf<OS>>;
33
+ }
34
+ declare class MethodPool {
35
+ protected readonly methods: Map<string, MethodConfig<any, any, any>>;
36
+ registerMethod<IS extends z.Schema<any>, OS extends z.Schema<any>, C>(name: string, options: MethodRegisterOptions<IS, OS>, callback: MethodCallback<IS, OS, C>): void;
37
+ getCallFn(name: string): ((callContext: MethodCallContext<any, any>) => Promise<any>) | null;
38
+ getAuthAdapters(name: string): Constructor<AuthAdapter>[] | null | undefined;
39
+ getOpenAPIPathsObject(group?: string): PathsObject;
40
+ }
4
41
  export declare function isHerbalController(target: Function): boolean;
5
42
  export declare function getControllerName(target: Function): any;
6
- export interface HerbalControllerOptions {
43
+ export interface HerbalControllerOptions<C> {
44
+ ControllerClass: Constructor<C>;
7
45
  prefix?: string;
8
46
  useHeadGuards?: Constructor<any>[];
9
47
  useTailGuards?: Constructor<any>[];
48
+ methods?: (register: MethodRegisterFn<C>) => void;
10
49
  }
11
50
  export interface ControllerUtilCreateOptions {
12
51
  prefix?: string;
@@ -14,9 +53,11 @@ export interface ControllerUtilCreateOptions {
14
53
  getTraceId?: (request: ExpressRequest) => string;
15
54
  }
16
55
  export declare class ControllerUtil {
56
+ static getPool(targetPrototype: object): MethodPool | null;
17
57
  static create(createOptions?: ControllerUtilCreateOptions): {
18
- (options?: HerbalControllerOptions): ClassDecorator;
58
+ <C>(options: HerbalControllerOptions<C>): ClassDecorator;
19
59
  isHerbalController: typeof isHerbalController;
20
60
  getControllerName: typeof getControllerName;
21
61
  };
22
62
  }
63
+ export {};
@@ -87,6 +87,124 @@ 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
89
  var decorators_1 = require("../decorators");
90
+ var zod_1 = require("zod");
91
+ var zod_openapi_1 = require("zod-openapi");
92
+ var METHOD_POOL = Symbol();
93
+ var MethodConfig = (function () {
94
+ function MethodConfig(name, options, callback) {
95
+ this.name = name;
96
+ this.options = options;
97
+ this.callback = callback;
98
+ }
99
+ MethodConfig.prototype.call = function (callContext) {
100
+ var _a, _b, _c, _d, _e, _f;
101
+ return __awaiter(this, void 0, void 0, function () {
102
+ var inputSchema, outputSchema, parsedBody_1, input, rawResponse_1, response, error_1;
103
+ return __generator(this, function (_g) {
104
+ switch (_g.label) {
105
+ case 0:
106
+ inputSchema = this.options.inputSchema;
107
+ outputSchema = this.options.outputSchema;
108
+ _g.label = 1;
109
+ case 1:
110
+ _g.trys.push([1, 3, , 4]);
111
+ parsedBody_1 = _.attempt(function () { return JSON.parse((callContext === null || callContext === void 0 ? void 0 : callContext.rawBody) || ''); });
112
+ input = _.attempt(function () { return (parsedBody_1 instanceof Error ? undefined : inputSchema.parse(parsedBody_1)); });
113
+ if (input instanceof zod_1.ZodError) {
114
+ throw new common_1.BadRequestException({
115
+ from: 'request',
116
+ invalidParams: (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.issues) === null || _a === void 0 ? void 0 : _a.map) === null || _b === void 0 ? void 0 : _b.call(_a, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _c !== void 0 ? _c : [],
117
+ });
118
+ }
119
+ else if (input instanceof Error)
120
+ throw input;
121
+ return [4, this.callback(__assign(__assign({}, callContext), { input: input }))];
122
+ case 2:
123
+ rawResponse_1 = _g.sent();
124
+ response = _.attempt(function () { return outputSchema.parse(rawResponse_1); });
125
+ if (response instanceof zod_1.ZodError) {
126
+ throw new common_1.BadRequestException({
127
+ from: 'response',
128
+ invalidParams: (_f = (_e = (_d = response === null || response === void 0 ? void 0 : response.issues) === null || _d === void 0 ? void 0 : _d.map) === null || _e === void 0 ? void 0 : _e.call(_d, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _f !== void 0 ? _f : [],
129
+ });
130
+ }
131
+ else if (response instanceof Error)
132
+ throw response;
133
+ return [2, response];
134
+ case 3:
135
+ error_1 = _g.sent();
136
+ throw error_1;
137
+ case 4: return [2];
138
+ }
139
+ });
140
+ });
141
+ };
142
+ return MethodConfig;
143
+ }());
144
+ var MethodPool = (function () {
145
+ function MethodPool() {
146
+ this.methods = new Map();
147
+ }
148
+ MethodPool.prototype.registerMethod = function (name, options, callback) {
149
+ if (string_util_class_1.StringUtil.isFalsyString(name))
150
+ return;
151
+ if (name.includes('/'))
152
+ throw new Error("Method name cannot contain slashes: ".concat(name));
153
+ this.methods.set(name, new MethodConfig(name, options, callback));
154
+ };
155
+ MethodPool.prototype.getCallFn = function (name) {
156
+ var config = this.methods.get(name);
157
+ if (!(config instanceof MethodConfig))
158
+ return null;
159
+ return config.call.bind(config);
160
+ };
161
+ MethodPool.prototype.getAuthAdapters = function (name) {
162
+ var config = this.methods.get(name);
163
+ if (!(config instanceof MethodConfig))
164
+ return null;
165
+ return config.options.authAdapters;
166
+ };
167
+ MethodPool.prototype.getOpenAPIPathsObject = function (group) {
168
+ var result = {};
169
+ Array.from(this.methods.entries()).forEach(function (_a) {
170
+ var _b;
171
+ var name = _a[0], config = _a[1];
172
+ var defaultGroupName = "".concat(Date.now(), "_").concat(Math.random().toString(16).slice(2));
173
+ var currentGroupName = string_util_class_1.StringUtil.isFalsyString(group) ? defaultGroupName : group;
174
+ var clientGroups = typeof config.options.clientGroups === 'function'
175
+ ? config.options.clientGroups(defaultGroupName)
176
+ : (_b = config === null || config === void 0 ? void 0 : config.options) === null || _b === void 0 ? void 0 : _b.clientGroups;
177
+ if (Array.isArray(clientGroups) && !clientGroups.includes(currentGroupName))
178
+ return;
179
+ result["/".concat(name)] = {
180
+ post: {
181
+ requestBody: {
182
+ description: 'Request body for method ' + name,
183
+ required: true,
184
+ content: {
185
+ 'application/json': {
186
+ schema: (0, zod_openapi_1.createSchema)(config.options.inputSchema).schema,
187
+ },
188
+ },
189
+ },
190
+ responses: {
191
+ '200': {
192
+ description: 'Response for method ' + name,
193
+ content: {
194
+ 'application/json': (0, zod_openapi_1.createSchema)(zod_1.z.object({
195
+ data: config.options.outputSchema,
196
+ token: zod_1.z.string().nullable(),
197
+ })),
198
+ },
199
+ },
200
+ },
201
+ },
202
+ };
203
+ });
204
+ return result;
205
+ };
206
+ return MethodPool;
207
+ }());
90
208
  var IS_HERBAL_CONTROLLER = Symbol();
91
209
  var CONTROLLER_NAME = Symbol();
92
210
  function isHerbalController(target) {
@@ -160,12 +278,12 @@ function HerbalGuard(options) {
160
278
  }
161
279
  HerbalGuardMixin.prototype.canActivate = function (context) {
162
280
  var _a, e_1, _b, _c;
163
- var _d, _e, _f, _g, _h, _j, _k;
281
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m;
164
282
  return __awaiter(this, void 0, void 0, function () {
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;
283
+ var sequelizeInstance, transaction, request, response, traceId, chunks, _o, request_1, request_1_1, chunk, e_1_1, _p, parsedBody, rawHandlerName, handlerPropertype, handlerName, authAdapters, error_2, _i, authAdapters_1, AuthAdapterClass, adapter, authenticateResult, error_3, _q;
166
284
  var _this = this;
167
- return __generator(this, function (_p) {
168
- switch (_p.label) {
285
+ return __generator(this, function (_r) {
286
+ switch (_r.label) {
169
287
  case 0:
170
288
  sequelizeInstance = _.attempt(function () { return _this.ref.get(sequelize_typescript_1.Sequelize, { strict: false }); });
171
289
  transaction = undefined;
@@ -178,40 +296,39 @@ function HerbalGuard(options) {
178
296
  traceId = uuid_util_class_1.UUIDUtil.generateV4();
179
297
  request.traceId = traceId;
180
298
  request.methodName = request.url.split('/').pop();
181
- request.moduleRef = this.ref;
182
299
  response.setHeader(headers_constant_1.HEADERS.TRACE_ID, traceId);
183
300
  chunks = [];
184
- _p.label = 1;
301
+ _r.label = 1;
185
302
  case 1:
186
- _p.trys.push([1, 14, , 15]);
187
- _p.label = 2;
303
+ _r.trys.push([1, 14, , 15]);
304
+ _r.label = 2;
188
305
  case 2:
189
- _p.trys.push([2, 7, 8, 13]);
190
- _l = true, request_1 = __asyncValues(request);
191
- _p.label = 3;
306
+ _r.trys.push([2, 7, 8, 13]);
307
+ _o = true, request_1 = __asyncValues(request);
308
+ _r.label = 3;
192
309
  case 3: return [4, request_1.next()];
193
310
  case 4:
194
- if (!(request_1_1 = _p.sent(), _a = request_1_1.done, !_a)) return [3, 6];
311
+ if (!(request_1_1 = _r.sent(), _a = request_1_1.done, !_a)) return [3, 6];
195
312
  _c = request_1_1.value;
196
- _l = false;
313
+ _o = false;
197
314
  chunk = _c;
198
315
  chunks.push(chunk);
199
- _p.label = 5;
316
+ _r.label = 5;
200
317
  case 5:
201
- _l = true;
318
+ _o = true;
202
319
  return [3, 3];
203
320
  case 6: return [3, 13];
204
321
  case 7:
205
- e_1_1 = _p.sent();
322
+ e_1_1 = _r.sent();
206
323
  e_1 = { error: e_1_1 };
207
324
  return [3, 13];
208
325
  case 8:
209
- _p.trys.push([8, , 11, 12]);
210
- if (!(!_l && !_a && (_b = request_1.return))) return [3, 10];
326
+ _r.trys.push([8, , 11, 12]);
327
+ if (!(!_o && !_a && (_b = request_1.return))) return [3, 10];
211
328
  return [4, _b.call(request_1)];
212
329
  case 9:
213
- _p.sent();
214
- _p.label = 10;
330
+ _r.sent();
331
+ _r.label = 10;
215
332
  case 10: return [3, 12];
216
333
  case 11:
217
334
  if (e_1) throw e_1.error;
@@ -219,7 +336,7 @@ function HerbalGuard(options) {
219
336
  case 12: return [7];
220
337
  case 13: return [3, 15];
221
338
  case 14:
222
- _m = _p.sent();
339
+ _p = _r.sent();
223
340
  return [3, 15];
224
341
  case 15:
225
342
  parsedBody = _.attempt(function () { return Buffer.concat(chunks).toString('utf8'); });
@@ -233,21 +350,23 @@ function HerbalGuard(options) {
233
350
  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
351
  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
352
  handlerName = string_util_class_1.StringUtil.isFalsyString(rawHandlerName) ? request.methodName : rawHandlerName;
236
- authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters(handlerPropertype, handlerName);
353
+ authAdapters = (_j = (_h = ControllerUtil.getPool(handlerPropertype)) === null || _h === void 0 ? void 0 : _h.getAuthAdapters) === null || _j === void 0 ? void 0 : _j.call(_h, handlerName);
354
+ if (authAdapters === null)
355
+ authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters(handlerPropertype, handlerName);
237
356
  if (!(!(sequelizeInstance instanceof Error) && !decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName))) return [3, 20];
238
- _p.label = 16;
357
+ _r.label = 16;
239
358
  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); }))];
359
+ _r.trys.push([16, 18, , 19]);
360
+ 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); }))];
242
361
  case 17:
243
- transaction = _p.sent();
362
+ transaction = _r.sent();
244
363
  request.transaction = transaction;
245
364
  this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Started transaction for route: ").concat(handlerName));
246
365
  return [3, 19];
247
366
  case 18:
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));
367
+ error_2 = _r.sent();
368
+ if (error_2 instanceof Error) {
369
+ this.getLogger().error("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Failed to start transaction: ").concat(error_2 === null || error_2 === void 0 ? void 0 : error_2.message, "\n").concat(error_2 === null || error_2 === void 0 ? void 0 : error_2.stack));
251
370
  }
252
371
  return [3, 19];
253
372
  case 19: return [3, 21];
@@ -255,12 +374,12 @@ function HerbalGuard(options) {
255
374
  if (decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName)) {
256
375
  this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Transaction is disabled for this route: ").concat(handlerName));
257
376
  }
258
- _p.label = 21;
377
+ _r.label = 21;
259
378
  case 21:
260
- _p.trys.push([21, 27, , 32]);
379
+ _r.trys.push([21, 27, , 32]);
261
380
  if (!(Array.isArray(authAdapters) && authAdapters.length > 0)) return [3, 26];
262
381
  _i = 0, authAdapters_1 = authAdapters;
263
- _p.label = 22;
382
+ _r.label = 22;
264
383
  case 22:
265
384
  if (!(_i < authAdapters_1.length)) return [3, 25];
266
385
  AuthAdapterClass = authAdapters_1[_i];
@@ -269,7 +388,7 @@ function HerbalGuard(options) {
269
388
  return [3, 24];
270
389
  return [4, adapter.authenticate(transaction)];
271
390
  case 23:
272
- authenticateResult = _p.sent();
391
+ authenticateResult = _r.sent();
273
392
  if (!authenticateResult)
274
393
  return [3, 25];
275
394
  request.authenticateResult = __assign({ AuthenticatorClass: AuthAdapterClass }, authenticateResult);
@@ -280,21 +399,21 @@ function HerbalGuard(options) {
280
399
  case 25: throw new common_2.UnauthorizedException();
281
400
  case 26: return [3, 32];
282
401
  case 27:
283
- error_2 = _p.sent();
284
- _p.label = 28;
402
+ error_3 = _r.sent();
403
+ _r.label = 28;
285
404
  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));
405
+ _r.trys.push([28, 30, , 31]);
406
+ if (error_3 instanceof Error) {
407
+ this.getLogger().error("Got error when handling route: ".concat(error_3 === null || error_3 === void 0 ? void 0 : error_3.message, " ").concat(error_3 === null || error_3 === void 0 ? void 0 : error_3.stack));
289
408
  }
290
- return [4, ((_k = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _k === void 0 ? void 0 : _k.call(transaction))];
409
+ return [4, ((_m = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _m === void 0 ? void 0 : _m.call(transaction))];
291
410
  case 29:
292
- _p.sent();
411
+ _r.sent();
293
412
  return [3, 31];
294
413
  case 30:
295
- _o = _p.sent();
414
+ _q = _r.sent();
296
415
  return [3, 31];
297
- case 31: throw error_2;
416
+ case 31: throw error_3;
298
417
  case 32: return [2, true];
299
418
  }
300
419
  });
@@ -321,10 +440,17 @@ function HerbalGuard(options) {
321
440
  var ControllerUtil = (function () {
322
441
  function ControllerUtil() {
323
442
  }
443
+ ControllerUtil.getPool = function (targetPrototype) {
444
+ var pool = Reflect.getMetadata(METHOD_POOL, targetPrototype);
445
+ if (!(pool instanceof MethodPool))
446
+ return null;
447
+ return pool;
448
+ };
324
449
  ControllerUtil.create = function (createOptions) {
325
450
  function Controller(options) {
326
451
  return function (target) {
327
452
  var _a;
453
+ var methodPool = new MethodPool();
328
454
  var finalPrefix = string_util_class_1.StringUtil.isFalsyString(options === null || options === void 0 ? void 0 : options.prefix)
329
455
  ? string_util_class_1.StringUtil.isFalsyString(createOptions === null || createOptions === void 0 ? void 0 : createOptions.prefix)
330
456
  ? ''
@@ -332,10 +458,18 @@ var ControllerUtil = (function () {
332
458
  : options.prefix;
333
459
  var controllerName = _.camelCase(target.name.replace(/Controller$/g, ''));
334
460
  finalPrefix += "".concat(((_a = finalPrefix === null || finalPrefix === void 0 ? void 0 : finalPrefix.endsWith) === null || _a === void 0 ? void 0 : _a.call(finalPrefix, '/')) ? '' : '/').concat(controllerName);
461
+ var register = function (name, options, callback) {
462
+ if (string_util_class_1.StringUtil.isFalsyString(name) || typeof callback !== 'function')
463
+ return;
464
+ methodPool.registerMethod(name, options, callback);
465
+ };
335
466
  if (!finalPrefix.startsWith('/'))
336
467
  finalPrefix = "/".concat(finalPrefix);
337
468
  Reflect.defineMetadata(IS_HERBAL_CONTROLLER, true, target.prototype);
338
469
  Reflect.defineMetadata(CONTROLLER_NAME, controllerName, target.prototype);
470
+ Reflect.defineMetadata(METHOD_POOL, methodPool, target.prototype);
471
+ if (typeof (options === null || options === void 0 ? void 0 : options.methods) === 'function')
472
+ options.methods(register);
339
473
  (0, common_1.Controller)(finalPrefix)(target);
340
474
  (0, common_1.UseInterceptors)(ControllerInterceptor)(target);
341
475
  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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-norantec/herbal",
3
- "version": "1.0.2-alpha.20",
3
+ "version": "1.0.2-alpha.22",
4
4
  "description": "Herbal is a builder and toolchain for Nest.js applications",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,44 +0,0 @@
1
- import 'reflect-metadata';
2
- import { z } from 'zod';
3
- import { AuthAdapter } from '../abstracts';
4
- import { HeaderUtil } from '@open-norantec/utilities/dist/header-util.class';
5
- import { Constructor } from 'type-fest';
6
- import { Type } from '@nestjs/common';
7
- import { RequestContext } from '../types';
8
- import { PathsObject } from 'zod-openapi/dist/openapi3-ts/dist/model/openapi31';
9
- type ClientGroups = Array<string> | null | undefined;
10
- type ClienttGroupsFactory = (defaultGroupName: string) => ClientGroups;
11
- export interface MethodOptions<IS extends z.Schema<any>, OS extends z.Schema<any>> {
12
- inputSchema: IS;
13
- outputSchema: OS;
14
- authAdapters?: AuthAdapter[];
15
- clientGroups?: ClientGroups | ClienttGroupsFactory;
16
- disableTransaction?: boolean;
17
- }
18
- export type DependencyGetter = <T>(dependency: Constructor<T>) => T;
19
- export interface MethodContext<IS extends z.Schema<any>> extends Omit<RequestContext, 'moduleRef'> {
20
- headers: ReturnType<typeof HeaderUtil.parse>;
21
- input: z.infer<IS>;
22
- url: string;
23
- getProvider: <TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol) => TResult;
24
- }
25
- export type MethodCallContext<IS extends z.Schema<any>> = Omit<MethodContext<IS>, 'input'>;
26
- export type MethodCallback<IS extends z.Schema<any>, OS extends z.Schema<any>> = (context: MethodContext<IS>) => Promise<z.infer<OS>>;
27
- declare class MethodConfig<IS extends z.Schema<any>, OS extends z.Schema<any>> {
28
- readonly name: string;
29
- readonly options: MethodOptions<IS, OS>;
30
- protected readonly callback: MethodCallback<IS, OS>;
31
- constructor(name: string, options: MethodOptions<IS, OS>, callback: MethodCallback<IS, OS>);
32
- call(callContext: MethodCallContext<IS>): Promise<z.TypeOf<OS>>;
33
- }
34
- declare class MethodPool {
35
- protected readonly methods: Map<string, MethodConfig<any, any>>;
36
- registerMethod<IS extends z.Schema<any>, OS extends z.Schema<any>>(name: string, options: MethodOptions<IS, OS>, callback: MethodCallback<IS, OS>): void;
37
- getCallFn(name: string): any;
38
- getOpenAPIPathsObject(group?: string): PathsObject;
39
- }
40
- export declare function Method<IS extends z.Schema<any>, OS extends z.Schema<any>>(...parameters: Parameters<typeof MethodPool.prototype.registerMethod<IS, OS>>): ClassDecorator;
41
- export declare namespace Method {
42
- var getPool: (targetPrototype: object) => MethodPool | null;
43
- }
44
- export {};
@@ -1,185 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- Object.defineProperty(exports, "__esModule", { value: true });
50
- exports.Method = void 0;
51
- require("reflect-metadata");
52
- var zod_1 = require("zod");
53
- var utilities_1 = require("@open-norantec/utilities");
54
- var common_1 = require("@nestjs/common");
55
- var _ = require("lodash");
56
- var zod_openapi_1 = require("zod-openapi");
57
- var METHOD_POOL = Symbol();
58
- var MethodConfig = (function () {
59
- function MethodConfig(name, options, callback) {
60
- this.name = name;
61
- this.options = options;
62
- this.callback = callback;
63
- }
64
- MethodConfig.prototype.call = function (callContext) {
65
- var _a, _b, _c, _d, _e, _f;
66
- return __awaiter(this, void 0, void 0, function () {
67
- var parsedBody_1, input, rawResponse_1, response, error_1;
68
- var _this = this;
69
- return __generator(this, function (_g) {
70
- switch (_g.label) {
71
- case 0:
72
- _g.trys.push([0, 2, , 3]);
73
- parsedBody_1 = _.attempt(function () { return JSON.parse((callContext === null || callContext === void 0 ? void 0 : callContext.rawBody) || ''); });
74
- input = _.attempt(function () {
75
- return parsedBody_1 instanceof Error ? undefined : _this.options.inputSchema.parse(parsedBody_1);
76
- });
77
- if (input instanceof zod_1.ZodError) {
78
- throw new common_1.BadRequestException({
79
- from: 'request',
80
- invalidParams: (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.issues) === null || _a === void 0 ? void 0 : _a.map) === null || _b === void 0 ? void 0 : _b.call(_a, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _c !== void 0 ? _c : [],
81
- });
82
- }
83
- else if (input instanceof Error)
84
- throw input;
85
- return [4, this.callback(__assign(__assign({}, callContext), { input: input }))];
86
- case 1:
87
- rawResponse_1 = _g.sent();
88
- response = _.attempt(function () { return _this.options.outputSchema.parse(rawResponse_1); });
89
- if (response instanceof zod_1.ZodError) {
90
- throw new common_1.BadRequestException({
91
- from: 'response',
92
- invalidParams: (_f = (_e = (_d = response === null || response === void 0 ? void 0 : response.issues) === null || _d === void 0 ? void 0 : _d.map) === null || _e === void 0 ? void 0 : _e.call(_d, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _f !== void 0 ? _f : [],
93
- });
94
- }
95
- else if (response instanceof Error)
96
- throw response;
97
- return [2, response];
98
- case 2:
99
- error_1 = _g.sent();
100
- throw error_1;
101
- case 3: return [2];
102
- }
103
- });
104
- });
105
- };
106
- return MethodConfig;
107
- }());
108
- var MethodPool = (function () {
109
- function MethodPool() {
110
- this.methods = new Map();
111
- }
112
- MethodPool.prototype.registerMethod = function (name, options, callback) {
113
- if (utilities_1.StringUtil.isFalsyString(name))
114
- return;
115
- if (name.includes('/'))
116
- throw new Error("Method name cannot contain slashes: ".concat(name));
117
- this.methods.set(name, new MethodConfig(name, options, callback));
118
- };
119
- MethodPool.prototype.getCallFn = function (name) {
120
- var _a;
121
- var callFn = (_a = this.methods.get(name)) === null || _a === void 0 ? void 0 : _a.call;
122
- return typeof callFn === 'function' ? callFn.bind(this) : null;
123
- };
124
- MethodPool.prototype.getOpenAPIPathsObject = function (group) {
125
- var result = {};
126
- Array.from(this.methods.entries()).forEach(function (_a) {
127
- var _b;
128
- var name = _a[0], config = _a[1];
129
- var defaultGroupName = "".concat(Date.now(), "_").concat(Math.random().toString(16).slice(2));
130
- var currentGroupName = utilities_1.StringUtil.isFalsyString(group) ? defaultGroupName : group;
131
- var clientGroups = typeof config.options.clientGroups === 'function'
132
- ? config.options.clientGroups(defaultGroupName)
133
- : (_b = config === null || config === void 0 ? void 0 : config.options) === null || _b === void 0 ? void 0 : _b.clientGroups;
134
- if (Array.isArray(clientGroups) && !clientGroups.includes(currentGroupName))
135
- return;
136
- result["/".concat(name)] = {
137
- post: {
138
- requestBody: {
139
- description: 'Request body for method ' + name,
140
- required: true,
141
- content: {
142
- 'application/json': {
143
- schema: (0, zod_openapi_1.createSchema)(config.options.inputSchema).schema,
144
- },
145
- },
146
- },
147
- responses: {
148
- '200': {
149
- description: 'Response for method ' + name,
150
- content: {
151
- 'application/json': (0, zod_openapi_1.createSchema)(zod_1.z.object({
152
- data: config.options.outputSchema,
153
- token: zod_1.z.string().nullable(),
154
- })),
155
- },
156
- },
157
- },
158
- },
159
- };
160
- });
161
- return result;
162
- };
163
- return MethodPool;
164
- }());
165
- function Method() {
166
- var parameters = [];
167
- for (var _i = 0; _i < arguments.length; _i++) {
168
- parameters[_i] = arguments[_i];
169
- }
170
- return function (target) {
171
- var pool = Reflect.getMetadata(METHOD_POOL, target.prototype);
172
- if (!(pool instanceof MethodPool)) {
173
- pool = new MethodPool();
174
- Reflect.defineMetadata(METHOD_POOL, pool, target.prototype);
175
- }
176
- pool.registerMethod.apply(pool, parameters);
177
- };
178
- }
179
- exports.Method = Method;
180
- Method.getPool = function (targetPrototype) {
181
- var pool = Reflect.getMetadata(METHOD_POOL, targetPrototype);
182
- if (!(pool instanceof MethodPool))
183
- return null;
184
- return pool;
185
- };