framework-do-dede 3.4.0 → 4.0.1

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 (43) hide show
  1. package/README.md +77 -14
  2. package/dist/application/controller.d.ts +6 -2
  3. package/dist/application/controller.js +10 -18
  4. package/dist/application/index.d.ts +1 -1
  5. package/dist/application/index.js +1 -1
  6. package/dist/application/services.d.ts +2 -1
  7. package/dist/application/services.js +3 -3
  8. package/dist/dede.d.ts +10 -1
  9. package/dist/dede.js +30 -9
  10. package/dist/domain/entity.d.ts +4 -0
  11. package/dist/domain/entity.js +25 -0
  12. package/dist/domain/errors/app-error.d.ts +12 -0
  13. package/dist/domain/errors/app-error.js +14 -0
  14. package/dist/domain/errors/http-errors.d.ts +42 -0
  15. package/dist/domain/errors/http-errors.js +40 -0
  16. package/dist/domain/index.d.ts +2 -0
  17. package/dist/domain/index.js +2 -0
  18. package/dist/http/controller.handler.d.ts +4 -5
  19. package/dist/http/controller.handler.js +27 -119
  20. package/dist/http/errors/server.d.ts +2 -28
  21. package/dist/http/errors/server.js +2 -49
  22. package/dist/http/http-server.d.ts +2 -0
  23. package/dist/http/http-server.js +1 -1
  24. package/dist/http/index.d.ts +2 -2
  25. package/dist/http/index.js +2 -2
  26. package/dist/index.d.ts +4 -3
  27. package/dist/index.js +4 -3
  28. package/dist/infra/di/registry.d.ts +4 -6
  29. package/dist/infra/di/registry.js +8 -10
  30. package/dist/{application → infra/serialization}/entity.d.ts +3 -1
  31. package/dist/{application → infra/serialization}/entity.js +7 -25
  32. package/dist/interface/errors/http-error-mapper.d.ts +10 -0
  33. package/dist/interface/errors/http-error-mapper.js +31 -0
  34. package/dist/interface/http/middleware-executor.d.ts +10 -0
  35. package/dist/interface/http/middleware-executor.js +33 -0
  36. package/dist/interface/http/request-mapper.d.ts +21 -0
  37. package/dist/interface/http/request-mapper.js +55 -0
  38. package/dist/interface/validation/class-validator.d.ts +6 -0
  39. package/dist/interface/validation/class-validator.js +28 -0
  40. package/dist/interface/validation/validator.d.ts +5 -0
  41. package/dist/interface/validation/validator.js +1 -0
  42. package/dist/protocols/repository.d.ts +1 -1
  43. package/package.json +5 -2
@@ -1,10 +1,14 @@
1
- import { InternalServerError, ServerError } from "../http";
2
- import { flushControllers, getControllers } from "../application/controller";
3
1
  import { FrameworkError } from "../http/errors/framework";
4
- import { CustomServerError } from "./errors/server";
2
+ import { HttpRequestMapper } from "../interface/http/request-mapper";
3
+ import { MiddlewareExecutor } from "../interface/http/middleware-executor";
4
+ import { HttpErrorMapper } from "../interface/errors/http-error-mapper";
5
+ import { validateWithClassValidator } from "../interface/validation/class-validator";
5
6
  export default class ControllerHandler {
6
- constructor(httpServer, port) {
7
- for (const { handler, middlewares, method, route, statusCode, params, query, headers, body, bodyFilter, responseType } of this.registryControllers()) {
7
+ constructor(httpServer, controllers = []) {
8
+ this.requestMapper = new HttpRequestMapper();
9
+ this.middlewareExecutor = new MiddlewareExecutor();
10
+ this.errorMapper = new HttpErrorMapper();
11
+ for (const { handler, middlewares, validator, method, route, statusCode, params, query, headers, body, bodyFilter, responseType } of this.registryControllers(controllers)) {
8
12
  httpServer.register({
9
13
  method,
10
14
  route,
@@ -14,6 +18,7 @@ export default class ControllerHandler {
14
18
  query,
15
19
  headers,
16
20
  middlewares,
21
+ validator,
17
22
  responseType
18
23
  }, async (input) => {
19
24
  let requestedAt = new Date();
@@ -25,23 +30,26 @@ export default class ControllerHandler {
25
30
  let middlewaresExecuted = [];
26
31
  try {
27
32
  startTime = performance.now();
28
- const filterParams = this.filter(input.params, params);
29
- const filterQueryParams = this.filter(input.query, query);
30
- const filterHeaders = this.filter(input.headers, headers);
31
- const normalizeBody = this.normalizeBracketNotation(input.body);
32
- let filterBody = this.filter(normalizeBody, body);
33
- if (bodyFilter !== 'restrict') {
34
- filterBody = { ...normalizeBody, ...filterBody };
33
+ request = this.requestMapper.map(input, { params, query, headers, body, bodyFilter });
34
+ if (validator) {
35
+ if (typeof validator === 'function') {
36
+ await validateWithClassValidator(validator, request.data);
37
+ }
38
+ else if (typeof validator.validate === 'function') {
39
+ await validator.validate(request.data);
40
+ }
41
+ else {
42
+ throw new FrameworkError('Validator must be a class or implement validate()');
43
+ }
35
44
  }
36
- mergedParams = { ...filterHeaders, ...filterParams, ...filterQueryParams, ...filterBody };
37
- request = { data: mergedParams, context: {} };
38
- middlewaresExecuted = await this.executeMiddlewares(middlewares, request);
45
+ mergedParams = request.data;
46
+ middlewaresExecuted = await this.middlewareExecutor.execute(middlewares, request);
39
47
  const response = await handler.instance[handler.methodName](request);
40
48
  endTime = performance.now();
41
49
  return response;
42
50
  }
43
51
  catch (error) {
44
- capturedError = this.extractError(error, httpServer);
52
+ capturedError = this.errorMapper.map(error, httpServer);
45
53
  input.setStatus(capturedError.statusCode);
46
54
  endTime = performance.now();
47
55
  if (capturedError?.custom) {
@@ -70,42 +78,10 @@ export default class ControllerHandler {
70
78
  }
71
79
  });
72
80
  }
73
- httpServer.listen(port);
74
81
  }
75
- async executeMiddlewares(middlewares = [], request) {
76
- const executed = [];
77
- if (middlewares && middlewares.length > 0) {
78
- for (const middleware of middlewares) {
79
- let startTime = 0;
80
- let endTime = 0;
81
- let elapsedTime;
82
- try {
83
- startTime = performance.now();
84
- const middlewareResult = await middleware.execute(request);
85
- request.context = Object.assign(request.context, middlewareResult);
86
- endTime = performance.now();
87
- elapsedTime = `${(endTime - startTime).toFixed(2)} ms`;
88
- executed.push({
89
- elapsedTime,
90
- middleware: middleware.constructor.name
91
- });
92
- }
93
- catch (error) {
94
- elapsedTime = `${(endTime - startTime).toFixed(2)} ms`;
95
- executed.push({
96
- elapsedTime,
97
- middleware: middleware.constructor.name,
98
- error
99
- });
100
- throw error;
101
- }
102
- }
103
- }
104
- return executed;
105
- }
106
- registryControllers() {
82
+ registryControllers(controllersList) {
107
83
  const controllers = [];
108
- for (const controller of getControllers()) {
84
+ for (const controller of controllersList) {
109
85
  const basePath = Reflect.getMetadata('basePath', controller);
110
86
  const methodNames = Object.getOwnPropertyNames(controller.prototype).filter(method => method !== 'constructor');
111
87
  let tracer = Reflect.getMetadata('tracer', controller) || null;
@@ -124,6 +100,7 @@ export default class ControllerHandler {
124
100
  body: routeConfig.body,
125
101
  bodyFilter: routeConfig.bodyFilter,
126
102
  statusCode: routeConfig.statusCode,
103
+ validator: routeConfig.validator,
127
104
  handler: {
128
105
  instance,
129
106
  methodName,
@@ -134,7 +111,6 @@ export default class ControllerHandler {
134
111
  });
135
112
  }
136
113
  }
137
- flushControllers();
138
114
  return controllers;
139
115
  }
140
116
  resolveMiddleware(middleware) {
@@ -158,72 +134,4 @@ export default class ControllerHandler {
158
134
  }
159
135
  return middleware;
160
136
  }
161
- filter(params, filterParams) {
162
- const filter = {};
163
- for (const paramName of filterParams || []) {
164
- const [paramNameFiltered, type] = paramName.split('|');
165
- let value = params[paramName] || params[paramNameFiltered];
166
- if (!value)
167
- continue;
168
- if (type === 'boolean')
169
- value = value === 'true';
170
- if (type === 'integer') {
171
- value = value.replace(/[^0-9]/g, '');
172
- value = value ? parseInt(value) : 0;
173
- }
174
- if (type === 'string')
175
- value = value.toString();
176
- if (type === 'number')
177
- value = parseFloat(value);
178
- filter[paramNameFiltered] = value;
179
- }
180
- return filter;
181
- }
182
- extractError(error, httpServer) {
183
- if (error instanceof ServerError) {
184
- return {
185
- message: error.message,
186
- statusCode: error.getStatusCode()
187
- };
188
- }
189
- if (error instanceof CustomServerError) {
190
- return {
191
- ...error.getCustom(),
192
- statusCode: error.getStatusCode(),
193
- custom: true
194
- };
195
- }
196
- const debugError = {
197
- sourceUrl: error.sourceURL,
198
- line: error.line,
199
- column: error.column,
200
- };
201
- error = new InternalServerError(error.message, httpServer.getDefaultMessageError());
202
- return {
203
- message: error.message,
204
- statusCode: error.getStatusCode(),
205
- unexpectedError: error instanceof InternalServerError ? error.getUnexpectedError() : undefined,
206
- ...debugError
207
- };
208
- }
209
- normalizeBracketNotation(data) {
210
- if (!data || typeof data !== "object")
211
- return data;
212
- const normalized = {};
213
- for (const [rawKey, value] of Object.entries(data)) {
214
- const key = String(rawKey);
215
- const match = key.match(/^([^\[\]]+)\[([^\[\]]+)\]$/);
216
- if (match) {
217
- const parent = match[1];
218
- const child = match[2];
219
- if (!normalized[parent] || typeof normalized[parent] !== "object") {
220
- normalized[parent] = {};
221
- }
222
- normalized[parent][child] = value;
223
- continue;
224
- }
225
- normalized[key] = value;
226
- }
227
- return normalized;
228
- }
229
137
  }
@@ -1,8 +1,5 @@
1
- export declare abstract class ServerError extends Error {
2
- private statusCode;
3
- constructor(message: string, statusCode: number);
4
- getStatusCode(): number;
5
- }
1
+ export { AppError as ServerError } from "../../domain/errors/app-error";
2
+ export { BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, InternalServerError } from "../../domain/errors/http-errors";
6
3
  export declare class CustomServerError extends Error {
7
4
  private statusCode;
8
5
  private custom;
@@ -10,26 +7,3 @@ export declare class CustomServerError extends Error {
10
7
  getStatusCode(): number;
11
8
  getCustom(): any;
12
9
  }
13
- export declare class NotFound extends ServerError {
14
- constructor(message: string);
15
- }
16
- export declare class Forbidden extends ServerError {
17
- constructor(message: string);
18
- }
19
- export declare class UnprocessableEntity extends ServerError {
20
- constructor(message: string);
21
- }
22
- export declare class Conflict extends ServerError {
23
- constructor(message: string);
24
- }
25
- export declare class Unauthorized extends ServerError {
26
- constructor(message: string);
27
- }
28
- export declare class BadRequest extends ServerError {
29
- constructor(message: string);
30
- }
31
- export declare class InternalServerError extends ServerError {
32
- private unexpectedError;
33
- constructor(unexpectedError: string, defaultMessage?: string);
34
- getUnexpectedError(): string;
35
- }
@@ -1,13 +1,5 @@
1
- export class ServerError extends Error {
2
- constructor(message, statusCode) {
3
- super(message);
4
- this.name = this.constructor.name;
5
- this.statusCode = statusCode;
6
- }
7
- getStatusCode() {
8
- return this.statusCode;
9
- }
10
- }
1
+ export { AppError as ServerError } from "../../domain/errors/app-error";
2
+ export { BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, InternalServerError } from "../../domain/errors/http-errors";
11
3
  export class CustomServerError extends Error {
12
4
  constructor(custom, statusCode, nameError = '') {
13
5
  super();
@@ -22,42 +14,3 @@ export class CustomServerError extends Error {
22
14
  return this.custom;
23
15
  }
24
16
  }
25
- export class NotFound extends ServerError {
26
- constructor(message) {
27
- super(message, 404);
28
- }
29
- }
30
- export class Forbidden extends ServerError {
31
- constructor(message) {
32
- super(message, 403);
33
- }
34
- }
35
- export class UnprocessableEntity extends ServerError {
36
- constructor(message) {
37
- super(message, 422);
38
- }
39
- }
40
- export class Conflict extends ServerError {
41
- constructor(message) {
42
- super(message, 409);
43
- }
44
- }
45
- export class Unauthorized extends ServerError {
46
- constructor(message) {
47
- super(message, 401);
48
- }
49
- }
50
- export class BadRequest extends ServerError {
51
- constructor(message) {
52
- super(message, 400);
53
- }
54
- }
55
- export class InternalServerError extends ServerError {
56
- constructor(unexpectedError, defaultMessage = 'Ops, An unexpected error occurred') {
57
- super(defaultMessage, 500);
58
- this.unexpectedError = unexpectedError;
59
- }
60
- getUnexpectedError() {
61
- return this.unexpectedError;
62
- }
63
- }
@@ -1,4 +1,5 @@
1
1
  import { Middleware, Tracer } from "../application/controller";
2
+ import type { ValidatorLike } from "../interface/validation/validator";
2
3
  export type Request = {
3
4
  data: any;
4
5
  context: any;
@@ -15,6 +16,7 @@ export type HttpServerParams = {
15
16
  };
16
17
  responseType: 'json' | 'text' | 'html';
17
18
  middlewares?: Middleware[];
19
+ validator?: ValidatorLike;
18
20
  statusCode?: number;
19
21
  params?: string[];
20
22
  query?: string[];
@@ -53,7 +53,7 @@ export default class HttpServer {
53
53
  express(httpServerParams, route, handler) {
54
54
  const method = httpServerParams.method;
55
55
  this.framework[method](route, async (request, res) => {
56
- request.headers['ip'] = request.ipç;
56
+ request.headers['ip'] = request.ip;
57
57
  res.status(httpServerParams.statusCode ?? 200);
58
58
  const output = await handler({
59
59
  setStatus: (statusCode) => res.status(statusCode),
@@ -1,3 +1,3 @@
1
1
  import HttpServer from "./http-server";
2
- import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError } from "./errors/server";
3
- export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer, InternalServerError };
2
+ import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from "./errors/server";
3
+ export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer, InternalServerError, CustomServerError };
@@ -1,3 +1,3 @@
1
1
  import HttpServer from "./http-server";
2
- import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError } from "./errors/server";
3
- export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer, InternalServerError };
2
+ import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from "./errors/server";
3
+ export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer, InternalServerError, CustomServerError };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Post, Get, Put, Delete, Patch, Controller, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, UseCase, DecorateUseCase, Storage, StorageGateway } from "./application";
2
- import { Inject } from './infra/di/registry';
2
+ import { Container, DefaultContainer, Inject, setDefaultContainer } from './infra/di/registry';
3
3
  import { Dede, type Options, Register } from './dede';
4
- import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError } from './http/errors/server';
4
+ import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from './http/errors/server';
5
+ import { AppError } from './domain/errors/app-error';
5
6
  import type { RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryExistsBy, RepositoryRestore, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination } from './protocols/repository';
6
- export { Controller, Post, Get, Put, Delete, Patch, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, UseCase, DecorateUseCase, Storage, StorageGateway, Inject, Dede, Options, Register, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryRestore, RepositoryExistsBy, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination };
7
+ export { Controller, Post, Get, Put, Delete, Patch, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, UseCase, DecorateUseCase, Storage, StorageGateway, Inject, Container, DefaultContainer, setDefaultContainer, Dede, Options, Register, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryRestore, RepositoryExistsBy, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination };
package/dist/index.js CHANGED
@@ -10,7 +10,8 @@ UseCase, DecorateUseCase,
10
10
  // usecase
11
11
  // storage
12
12
  Storage } from "./application";
13
- import { Inject } from './infra/di/registry';
13
+ import { Container, DefaultContainer, Inject, setDefaultContainer } from './infra/di/registry';
14
14
  import { Dede } from './dede';
15
- import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError } from './http/errors/server';
16
- export { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, UseCase, DecorateUseCase, Storage, Inject, Dede, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError };
15
+ import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from './http/errors/server';
16
+ import { AppError } from './domain/errors/app-error';
17
+ export { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, UseCase, DecorateUseCase, Storage, Inject, Container, DefaultContainer, setDefaultContainer, Dede, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError };
@@ -1,11 +1,9 @@
1
- declare class ComponentRegistry {
2
- private static instance;
1
+ export declare class Container {
3
2
  private dependencies;
4
- static getInstance(): ComponentRegistry;
5
3
  load(name: string, dependency: any): void;
6
4
  inject(name: string): any;
7
5
  remove(name: string): void;
8
6
  }
9
- export declare const Registry: ComponentRegistry;
10
- export declare function Inject(name: string): (target: any, propertyKey: string) => void;
11
- export {};
7
+ export declare let DefaultContainer: Container;
8
+ export declare function setDefaultContainer(container: Container): void;
9
+ export declare function Inject(name: string, container?: Container): (target: any, propertyKey: string) => void;
@@ -1,13 +1,7 @@
1
- class ComponentRegistry {
1
+ export class Container {
2
2
  constructor() {
3
3
  this.dependencies = new Map();
4
4
  }
5
- static getInstance() {
6
- if (!this.instance) {
7
- this.instance = new ComponentRegistry();
8
- }
9
- return this.instance;
10
- }
11
5
  load(name, dependency) {
12
6
  this.dependencies.set(name, dependency);
13
7
  }
@@ -20,12 +14,16 @@ class ComponentRegistry {
20
14
  this.dependencies.delete(name);
21
15
  }
22
16
  }
23
- export const Registry = ComponentRegistry.getInstance();
24
- export function Inject(name) {
17
+ export let DefaultContainer = new Container();
18
+ export function setDefaultContainer(container) {
19
+ DefaultContainer = container;
20
+ }
21
+ export function Inject(name, container) {
25
22
  return function (target, propertyKey) {
26
23
  target[propertyKey] = new Proxy({}, {
27
24
  get(_, propertyKey) {
28
- const dependency = Registry.inject(name);
25
+ const resolvedContainer = container ?? DefaultContainer;
26
+ const dependency = resolvedContainer.inject(name);
29
27
  return dependency[propertyKey];
30
28
  }
31
29
  });
@@ -1,4 +1,5 @@
1
- export declare abstract class Entity {
1
+ import { Entity as DomainEntity } from "../../domain/entity";
2
+ export declare abstract class SerializableEntity extends DomainEntity {
2
3
  [x: string]: any;
3
4
  private buildRawEntityObject;
4
5
  private getEntityHooks;
@@ -17,5 +18,6 @@ export declare function Restrict(): (target: any, propertyKey: string) => void;
17
18
  export declare function VirtualProperty(propertyName: string): (target: any, methodName: string) => void;
18
19
  export declare function Serialize(callback: (value: any) => any): PropertyDecorator;
19
20
  export declare function GetterPrefix(prefix: string): (target: any, propertyKey: string) => void;
21
+ export { SerializableEntity as Entity };
20
22
  export declare function BeforeToEntity(): MethodDecorator;
21
23
  export declare function AfterToEntity(): MethodDecorator;
@@ -1,4 +1,5 @@
1
- export class Entity {
1
+ import { Entity as DomainEntity } from "../../domain/entity";
2
+ export class SerializableEntity extends DomainEntity {
2
3
  buildRawEntityObject() {
3
4
  const result = {};
4
5
  for (const [propName] of Object.entries(this)) {
@@ -14,7 +15,7 @@ export class Entity {
14
15
  getEntityHooks(hookKey) {
15
16
  const hooks = [];
16
17
  let current = this.constructor;
17
- while (current && current !== Entity) {
18
+ while (current && current !== SerializableEntity) {
18
19
  const currentHooks = current[hookKey];
19
20
  if (currentHooks && currentHooks.length) {
20
21
  hooks.unshift(...currentHooks);
@@ -103,7 +104,7 @@ export class Entity {
103
104
  if (value === undefined)
104
105
  continue;
105
106
  // @ts-ignore
106
- if (propertiesConfigs && propertiesConfigs[propName]?.serialize && (value || valueIsZero)) {
107
+ if (propertiesConfigs && propertiesConfigs[propName]?.serialize && (value || value === 0)) {
107
108
  const serializedValue = await propertiesConfigs[propName].serialize(value);
108
109
  if (serializedValue && typeof serializedValue === 'object' && !Array.isArray(serializedValue)) {
109
110
  const entries = Object.entries(serializedValue);
@@ -181,27 +182,7 @@ export class Entity {
181
182
  return result;
182
183
  }
183
184
  generateGetters() {
184
- for (const property of Object.keys(this)) {
185
- if (typeof this[property] === 'function')
186
- continue;
187
- let prefixName = null;
188
- // @ts-ignore
189
- if (this.constructor.propertiesConfigs && this.constructor.propertiesConfigs[property] && this.constructor.propertiesConfigs[property].prefix) {
190
- // @ts-ignore
191
- prefixName = this.constructor.propertiesConfigs[property].prefix;
192
- }
193
- else {
194
- const isBoolean = this[property] ? typeof this[property] === 'boolean' : false;
195
- prefixName = isBoolean ? 'is' : 'get';
196
- }
197
- let getterName = null;
198
- if (property[0]) {
199
- getterName = `${prefixName}${property[0].toUpperCase()}${property.slice(1)}`;
200
- if (this[getterName])
201
- continue;
202
- this[getterName] = () => this[property];
203
- }
204
- }
185
+ super.generateGetters();
205
186
  }
206
187
  }
207
188
  export function Restrict() {
@@ -240,10 +221,11 @@ const loadPropertiesConfig = (target, propertyKey) => {
240
221
  const BEFORE_TO_ENTITY = Symbol('beforeToEntity');
241
222
  const AFTER_TO_ENTITY = Symbol('afterToEntity');
242
223
  const assertEntityDecoratorTarget = (target, decoratorName) => {
243
- if (!Entity.prototype.isPrototypeOf(target)) {
224
+ if (!SerializableEntity.prototype.isPrototypeOf(target)) {
244
225
  throw new Error(`${decoratorName} can only be used on Entity classes`);
245
226
  }
246
227
  };
228
+ export { SerializableEntity as Entity };
247
229
  export function BeforeToEntity() {
248
230
  return function (target, propertyKey) {
249
231
  assertEntityDecoratorTarget(target, 'BeforeToEntity');
@@ -0,0 +1,10 @@
1
+ import type HttpServer from '../../http/http-server';
2
+ export type MappedError = {
3
+ message: string;
4
+ statusCode: number;
5
+ custom?: boolean;
6
+ unexpectedError?: string;
7
+ };
8
+ export declare class HttpErrorMapper {
9
+ map(error: any, httpServer: HttpServer): MappedError;
10
+ }
@@ -0,0 +1,31 @@
1
+ import { AppError } from '../../domain/errors/app-error';
2
+ import { InternalServerError } from '../../domain/errors/http-errors';
3
+ export class HttpErrorMapper {
4
+ map(error, httpServer) {
5
+ if (error instanceof AppError) {
6
+ return {
7
+ message: error.message,
8
+ statusCode: error.getStatusCode()
9
+ };
10
+ }
11
+ if (error && typeof error.getStatusCode === 'function' && typeof error.getCustom === 'function') {
12
+ return {
13
+ ...error.getCustom(),
14
+ statusCode: error.getStatusCode(),
15
+ custom: true
16
+ };
17
+ }
18
+ const debugError = {
19
+ sourceUrl: error?.sourceURL,
20
+ line: error?.line,
21
+ column: error?.column,
22
+ };
23
+ const internal = new InternalServerError(error?.message || 'Unexpected error', httpServer.getDefaultMessageError());
24
+ return {
25
+ message: internal.message,
26
+ statusCode: internal.getStatusCode(),
27
+ unexpectedError: internal.getUnexpectedError(),
28
+ ...debugError
29
+ };
30
+ }
31
+ }
@@ -0,0 +1,10 @@
1
+ import type { Request } from "../../http/http-server";
2
+ import type { Middleware } from "../../application/controller";
3
+ export type ExecutedMiddleware = {
4
+ elapsedTime: string;
5
+ middleware: string;
6
+ error?: any;
7
+ };
8
+ export declare class MiddlewareExecutor {
9
+ execute(middlewares: Middleware[] | undefined, request: Request): Promise<ExecutedMiddleware[]>;
10
+ }
@@ -0,0 +1,33 @@
1
+ export class MiddlewareExecutor {
2
+ async execute(middlewares = [], request) {
3
+ const executed = [];
4
+ if (middlewares && middlewares.length > 0) {
5
+ for (const middleware of middlewares) {
6
+ let startTime = 0;
7
+ let endTime = 0;
8
+ let elapsedTime;
9
+ try {
10
+ startTime = performance.now();
11
+ const middlewareResult = await middleware.execute(request);
12
+ request.context = Object.assign(request.context, middlewareResult);
13
+ endTime = performance.now();
14
+ elapsedTime = `${(endTime - startTime).toFixed(2)} ms`;
15
+ executed.push({
16
+ elapsedTime,
17
+ middleware: middleware.constructor.name,
18
+ });
19
+ }
20
+ catch (error) {
21
+ elapsedTime = `${(endTime - startTime).toFixed(2)} ms`;
22
+ executed.push({
23
+ elapsedTime,
24
+ middleware: middleware.constructor.name,
25
+ error,
26
+ });
27
+ throw error;
28
+ }
29
+ }
30
+ }
31
+ return executed;
32
+ }
33
+ }
@@ -0,0 +1,21 @@
1
+ import type { Request } from "../../http/http-server";
2
+ type BodyFilter = 'none' | 'restrict';
3
+ type RouteInputConfig = {
4
+ params?: string[];
5
+ query?: string[];
6
+ headers?: string[];
7
+ body?: string[];
8
+ bodyFilter?: BodyFilter;
9
+ };
10
+ type HttpInput = {
11
+ headers: any;
12
+ body: any;
13
+ params: any;
14
+ query: any;
15
+ };
16
+ export declare class HttpRequestMapper {
17
+ map(input: HttpInput, config: RouteInputConfig): Request;
18
+ private filter;
19
+ private normalizeBracketNotation;
20
+ }
21
+ export {};