@open-norantec/herbal 1.0.2-alpha.21 → 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) {
@@ -162,7 +280,7 @@ function HerbalGuard(options) {
162
280
  var _a, e_1, _b, _c;
163
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, _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;
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
285
  return __generator(this, function (_r) {
168
286
  switch (_r.label) {
@@ -178,7 +296,6 @@ 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
301
  _r.label = 1;
@@ -233,7 +350,7 @@ 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 = (_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);
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);
237
354
  if (authAdapters === null)
238
355
  authAdapters = auth_adapter_decorator_1.AuthAdapters.getAdapters(handlerPropertype, handlerName);
239
356
  if (!(!(sequelizeInstance instanceof Error) && !decorators_1.NoTransaction.isDisabled(handlerPropertype, handlerName))) return [3, 20];
@@ -247,9 +364,9 @@ function HerbalGuard(options) {
247
364
  this.getLogger().log("[trace:".concat(request === null || request === void 0 ? void 0 : request.traceId, ":transaction] Started transaction for route: ").concat(handlerName));
248
365
  return [3, 19];
249
366
  case 18:
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));
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));
253
370
  }
254
371
  return [3, 19];
255
372
  case 19: return [3, 21];
@@ -282,12 +399,12 @@ function HerbalGuard(options) {
282
399
  case 25: throw new common_2.UnauthorizedException();
283
400
  case 26: return [3, 32];
284
401
  case 27:
285
- error_2 = _r.sent();
402
+ error_3 = _r.sent();
286
403
  _r.label = 28;
287
404
  case 28:
288
405
  _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));
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));
291
408
  }
292
409
  return [4, ((_m = transaction === null || transaction === void 0 ? void 0 : transaction.rollback) === null || _m === void 0 ? void 0 : _m.call(transaction))];
293
410
  case 29:
@@ -296,7 +413,7 @@ function HerbalGuard(options) {
296
413
  case 30:
297
414
  _q = _r.sent();
298
415
  return [3, 31];
299
- case 31: throw error_2;
416
+ case 31: throw error_3;
300
417
  case 32: return [2, true];
301
418
  }
302
419
  });
@@ -323,10 +440,17 @@ function HerbalGuard(options) {
323
440
  var ControllerUtil = (function () {
324
441
  function ControllerUtil() {
325
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
+ };
326
449
  ControllerUtil.create = function (createOptions) {
327
450
  function Controller(options) {
328
451
  return function (target) {
329
452
  var _a;
453
+ var methodPool = new MethodPool();
330
454
  var finalPrefix = string_util_class_1.StringUtil.isFalsyString(options === null || options === void 0 ? void 0 : options.prefix)
331
455
  ? string_util_class_1.StringUtil.isFalsyString(createOptions === null || createOptions === void 0 ? void 0 : createOptions.prefix)
332
456
  ? ''
@@ -334,10 +458,18 @@ var ControllerUtil = (function () {
334
458
  : options.prefix;
335
459
  var controllerName = _.camelCase(target.name.replace(/Controller$/g, ''));
336
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
+ };
337
466
  if (!finalPrefix.startsWith('/'))
338
467
  finalPrefix = "/".concat(finalPrefix);
339
468
  Reflect.defineMetadata(IS_HERBAL_CONTROLLER, true, target.prototype);
340
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);
341
473
  (0, common_1.Controller)(finalPrefix)(target);
342
474
  (0, common_1.UseInterceptors)(ControllerInterceptor)(target);
343
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.21",
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,45 +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?: Constructor<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): ((callContext: MethodCallContext<any>) => Promise<any>) | null;
38
- getAuthAdapters(name: string): Constructor<AuthAdapter>[] | null | undefined;
39
- getOpenAPIPathsObject(group?: string): PathsObject;
40
- }
41
- export declare function Method<IS extends z.Schema<any>, OS extends z.Schema<any>>(...parameters: Parameters<typeof MethodPool.prototype.registerMethod<IS, OS>>): ClassDecorator;
42
- export declare namespace Method {
43
- var getPool: (targetPrototype: object) => MethodPool | null;
44
- }
45
- export {};
@@ -1,193 +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 inputSchema, outputSchema, parsedBody_1, input, rawResponse_1, response, error_1;
68
- return __generator(this, function (_g) {
69
- switch (_g.label) {
70
- case 0:
71
- inputSchema = this.options.inputSchema;
72
- outputSchema = this.options.outputSchema;
73
- _g.label = 1;
74
- case 1:
75
- _g.trys.push([1, 3, , 4]);
76
- parsedBody_1 = _.attempt(function () { return JSON.parse((callContext === null || callContext === void 0 ? void 0 : callContext.rawBody) || ''); });
77
- input = _.attempt(function () { return (parsedBody_1 instanceof Error ? undefined : inputSchema.parse(parsedBody_1)); });
78
- if (input instanceof zod_1.ZodError) {
79
- throw new common_1.BadRequestException({
80
- from: 'request',
81
- 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 : [],
82
- });
83
- }
84
- else if (input instanceof Error)
85
- throw input;
86
- return [4, this.callback(__assign(__assign({}, callContext), { input: input }))];
87
- case 2:
88
- rawResponse_1 = _g.sent();
89
- response = _.attempt(function () { return outputSchema.parse(rawResponse_1); });
90
- if (response instanceof zod_1.ZodError) {
91
- throw new common_1.BadRequestException({
92
- from: 'response',
93
- 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 : [],
94
- });
95
- }
96
- else if (response instanceof Error)
97
- throw response;
98
- return [2, response];
99
- case 3:
100
- error_1 = _g.sent();
101
- throw error_1;
102
- case 4: return [2];
103
- }
104
- });
105
- });
106
- };
107
- return MethodConfig;
108
- }());
109
- var MethodPool = (function () {
110
- function MethodPool() {
111
- this.methods = new Map();
112
- }
113
- MethodPool.prototype.registerMethod = function (name, options, callback) {
114
- if (utilities_1.StringUtil.isFalsyString(name))
115
- return;
116
- if (name.includes('/'))
117
- throw new Error("Method name cannot contain slashes: ".concat(name));
118
- this.methods.set(name, new MethodConfig(name, options, callback));
119
- };
120
- MethodPool.prototype.getCallFn = function (name) {
121
- var config = this.methods.get(name);
122
- if (!(config instanceof MethodConfig))
123
- return null;
124
- return config.call.bind(config);
125
- };
126
- MethodPool.prototype.getAuthAdapters = function (name) {
127
- var config = this.methods.get(name);
128
- if (!(config instanceof MethodConfig))
129
- return null;
130
- return config.options.authAdapters;
131
- };
132
- MethodPool.prototype.getOpenAPIPathsObject = function (group) {
133
- var result = {};
134
- Array.from(this.methods.entries()).forEach(function (_a) {
135
- var _b;
136
- var name = _a[0], config = _a[1];
137
- var defaultGroupName = "".concat(Date.now(), "_").concat(Math.random().toString(16).slice(2));
138
- var currentGroupName = utilities_1.StringUtil.isFalsyString(group) ? defaultGroupName : group;
139
- var clientGroups = typeof config.options.clientGroups === 'function'
140
- ? config.options.clientGroups(defaultGroupName)
141
- : (_b = config === null || config === void 0 ? void 0 : config.options) === null || _b === void 0 ? void 0 : _b.clientGroups;
142
- if (Array.isArray(clientGroups) && !clientGroups.includes(currentGroupName))
143
- return;
144
- result["/".concat(name)] = {
145
- post: {
146
- requestBody: {
147
- description: 'Request body for method ' + name,
148
- required: true,
149
- content: {
150
- 'application/json': {
151
- schema: (0, zod_openapi_1.createSchema)(config.options.inputSchema).schema,
152
- },
153
- },
154
- },
155
- responses: {
156
- '200': {
157
- description: 'Response for method ' + name,
158
- content: {
159
- 'application/json': (0, zod_openapi_1.createSchema)(zod_1.z.object({
160
- data: config.options.outputSchema,
161
- token: zod_1.z.string().nullable(),
162
- })),
163
- },
164
- },
165
- },
166
- },
167
- };
168
- });
169
- return result;
170
- };
171
- return MethodPool;
172
- }());
173
- function Method() {
174
- var parameters = [];
175
- for (var _i = 0; _i < arguments.length; _i++) {
176
- parameters[_i] = arguments[_i];
177
- }
178
- return function (target) {
179
- var pool = Reflect.getMetadata(METHOD_POOL, target.prototype);
180
- if (!(pool instanceof MethodPool)) {
181
- pool = new MethodPool();
182
- Reflect.defineMetadata(METHOD_POOL, pool, target.prototype);
183
- }
184
- pool.registerMethod.apply(pool, parameters);
185
- };
186
- }
187
- exports.Method = Method;
188
- Method.getPool = function (targetPrototype) {
189
- var pool = Reflect.getMetadata(METHOD_POOL, targetPrototype);
190
- if (!(pool instanceof MethodPool))
191
- return null;
192
- return pool;
193
- };