plutin 1.2.0 → 1.2.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.
- package/dist/core/decorators/controller-http-decorator.cjs +1 -3
- package/dist/core/decorators/controller-http-decorator.cjs.map +1 -1
- package/dist/core/decorators/controller-http-decorator.js +1 -3
- package/dist/core/decorators/controller-http-decorator.js.map +1 -1
- package/dist/core/http/base-controller.cjs +1 -1
- package/dist/core/http/base-controller.cjs.map +1 -1
- package/dist/core/http/base-controller.js +1 -3
- package/dist/core/http/base-controller.js.map +1 -1
- package/dist/index.cjs +159 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +157 -4
- package/dist/index.js.map +1 -1
- package/dist/infra/adapters/http/express-adapter.cjs +5 -1
- package/dist/infra/adapters/http/express-adapter.cjs.map +1 -1
- package/dist/infra/adapters/http/express-adapter.d.cts +1 -1
- package/dist/infra/adapters/http/express-adapter.d.ts +1 -1
- package/dist/infra/adapters/http/express-adapter.js +1 -1
- package/dist/infra/adapters/http/express-adapter.js.map +1 -1
- package/dist/infra/adapters/http/fastify-adapter.cjs +5 -1
- package/dist/infra/adapters/http/fastify-adapter.cjs.map +1 -1
- package/dist/infra/adapters/http/fastify-adapter.d.cts +1 -1
- package/dist/infra/adapters/http/fastify-adapter.d.ts +1 -1
- package/dist/infra/adapters/http/fastify-adapter.js +1 -1
- package/dist/infra/adapters/http/fastify-adapter.js.map +1 -1
- package/dist/infra/adapters/http/validate-controller-metadata.cjs.map +1 -1
- package/dist/infra/adapters/http/validate-controller-metadata.js.map +1 -1
- package/dist/infra/adapters/notifications/notification-factory.cjs.map +1 -1
- package/dist/infra/adapters/notifications/notification-factory.js.map +1 -1
- package/dist/infra/adapters/validators/zod/index.cjs.map +1 -1
- package/dist/infra/adapters/validators/zod/index.js.map +1 -1
- package/dist/infra/adapters/validators/zod/zod-validator.cjs.map +1 -1
- package/dist/infra/adapters/validators/zod/zod-validator.js.map +1 -1
- package/dist/infra/env/index.cjs +1 -1
- package/dist/infra/env/index.cjs.map +1 -1
- package/dist/infra/env/index.js +3 -1
- package/dist/infra/env/index.js.map +1 -1
- package/package.json +2 -10
|
@@ -25,9 +25,6 @@ __export(controller_http_decorator_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(controller_http_decorator_exports);
|
|
27
27
|
|
|
28
|
-
// src/core/http/base-controller.ts
|
|
29
|
-
var import_reflect_metadata2 = require("reflect-metadata");
|
|
30
|
-
|
|
31
28
|
// src/core/decorators/dependency-container.ts
|
|
32
29
|
var import_reflect_metadata = require("reflect-metadata");
|
|
33
30
|
var DependencyContainer = class {
|
|
@@ -180,6 +177,7 @@ var ValidationError = class extends Error {
|
|
|
180
177
|
};
|
|
181
178
|
|
|
182
179
|
// src/core/http/base-controller.ts
|
|
180
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
183
181
|
var BaseController = class {
|
|
184
182
|
static {
|
|
185
183
|
__name(this, "BaseController");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/decorators/controller-http-decorator.ts","../../../src/core/http/base-controller.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts"],"sourcesContent":["import { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { BaseController } from '../http/base-controller'\nimport type { MethodType } from '../http/http'\n\ntype Props = {\n method: MethodType\n path: string\n middlewares?: MiddlewareFunction[]\n}\n\nexport function Controller({\n method,\n path,\n middlewares = [],\n}: Props): ClassDecorator {\n return (target: any) => {\n if (!(target.prototype instanceof BaseController)) {\n throw new Error(\n `The class ${target.name} should extends abstract class BaseController`\n )\n }\n\n Reflect.defineMetadata(\n 'route',\n { method, path: `/api/${path}`, middlewares },\n target\n )\n }\n}\n","import 'reflect-metadata'\n\nimport { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { IErrorNotifier } from './error-notifier'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n"],"mappings":"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","names":["import_reflect_metadata","DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle","Controller","method","path","middlewares","target","prototype","BaseController","Error","name","Reflect","defineMetadata"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/decorators/controller-http-decorator.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts","../../../src/core/http/base-controller.ts"],"sourcesContent":["import { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { BaseController } from '../http/base-controller'\nimport type { MethodType } from '../http/http'\n\ntype Props = {\n method: MethodType\n path: string\n middlewares?: MiddlewareFunction[]\n}\n\nexport function Controller({\n method,\n path,\n middlewares = [],\n}: Props): ClassDecorator {\n return (target: any) => {\n if (!(target.prototype instanceof BaseController)) {\n throw new Error(\n `The class ${target.name} should extends abstract class BaseController`\n )\n }\n\n Reflect.defineMetadata(\n 'route',\n { method, path: `/api/${path}`, middlewares },\n target\n )\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n","import { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\n\nimport { IErrorNotifier } from './error-notifier'\n\nimport 'reflect-metadata'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n"],"mappings":"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","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","import_reflect_metadata","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle","Controller","method","path","middlewares","target","prototype","BaseController","Error","name","Reflect","defineMetadata"]}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
-
// src/core/http/base-controller.ts
|
|
5
|
-
import "reflect-metadata";
|
|
6
|
-
|
|
7
4
|
// src/core/decorators/dependency-container.ts
|
|
8
5
|
import "reflect-metadata";
|
|
9
6
|
var DependencyContainer = class {
|
|
@@ -156,6 +153,7 @@ var ValidationError = class extends Error {
|
|
|
156
153
|
};
|
|
157
154
|
|
|
158
155
|
// src/core/http/base-controller.ts
|
|
156
|
+
import "reflect-metadata";
|
|
159
157
|
var BaseController = class {
|
|
160
158
|
static {
|
|
161
159
|
__name(this, "BaseController");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/http/base-controller.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts","../../../src/core/decorators/controller-http-decorator.ts"],"sourcesContent":["import 'reflect-metadata'\n\nimport { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { IErrorNotifier } from './error-notifier'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n","import { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { BaseController } from '../http/base-controller'\nimport type { MethodType } from '../http/http'\n\ntype Props = {\n method: MethodType\n path: string\n middlewares?: MiddlewareFunction[]\n}\n\nexport function Controller({\n method,\n path,\n middlewares = [],\n}: Props): ClassDecorator {\n return (target: any) => {\n if (!(target.prototype instanceof BaseController)) {\n throw new Error(\n `The class ${target.name} should extends abstract class BaseController`\n )\n }\n\n Reflect.defineMetadata(\n 'route',\n { method, path: `/api/${path}`, middlewares },\n target\n )\n }\n}\n"],"mappings":"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","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle","Controller","method","path","middlewares","target","prototype","BaseController","Error","name","Reflect","defineMetadata"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts","../../../src/core/http/base-controller.ts","../../../src/core/decorators/controller-http-decorator.ts"],"sourcesContent":["import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n","import { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\n\nimport { IErrorNotifier } from './error-notifier'\n\nimport 'reflect-metadata'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { BaseController } from '../http/base-controller'\nimport type { MethodType } from '../http/http'\n\ntype Props = {\n method: MethodType\n path: string\n middlewares?: MiddlewareFunction[]\n}\n\nexport function Controller({\n method,\n path,\n middlewares = [],\n}: Props): ClassDecorator {\n return (target: any) => {\n if (!(target.prototype instanceof BaseController)) {\n throw new Error(\n `The class ${target.name} should extends abstract class BaseController`\n )\n }\n\n Reflect.defineMetadata(\n 'route',\n { method, path: `/api/${path}`, middlewares },\n target\n )\n }\n}\n"],"mappings":";;;;AAAA,OAAO;AAQA,IAAMA,sBAAN,MAAMA;EARb,OAQaA;;;EACX,OAAOC,WAAW,oBAAIC,IAAAA;EACtB,OAAOC,aAAa,oBAAID,IAAAA;EAExB,OAAOE,SACLC,OACAC,SACAC,SACA;AACA,SAAKN,SAASO,IAAIH,OAAO;MACvBI,MAAM;MACNH;MACAI,WAAWH,QAAQG;IACrB,CAAA;EACF;EAEA,OAAOC,cAAiBN,OAAeO,OAAU;AAC/C,SAAKX,SAASO,IAAIH,OAAO;MAAEI,MAAM;MAASG;IAAM,CAAA;EAClD;EAEA,OAAOC,QAAWC,QAAqB;AACrC,UAAMC,aAAaC,QAAQC,YAAY,qBAAqBH,MAAAA,KAAW,CAAA;AAEvE,UAAMI,iBACJF,QAAQG,eAAe,iBAAiBL,MAAAA,KAAW,CAAC;AAEtD,UAAMM,SAASL,WAAWM,IAAI,CAACC,GAAQC,UAAAA;AACrC,YAAMlB,QAAQa,eAAeK,KAAAA;AAE7B,UAAI,CAAClB,OAAO;AACV,cAAM,IAAImB,MACR,6CAA6CD,KAAAA,OAAYT,OAAOW,IAAI,EAAE;MAE1E;AAEA,aAAO,KAAKC,aAAarB,KAAAA;IAC3B,CAAA;AAEA,WAAO,IAAIS,OAAAA,GAAUM,MAAAA;EACvB;EAEA,OAAOM,aAAarB,OAAoB;AACtC,UAAMsB,eAAe,KAAK1B,SAAS2B,IAAIvB,KAAAA;AAEvC,QAAI,CAACsB,cAAc;AACjB,YAAM,IAAIH,MACR,IAAInB,KAAAA,wDAA6D;IAErE;AAEA,QAAIsB,aAAalB,SAAS,SAAS;AACjC,aAAOkB,aAAaf;IACtB;AAEA,UAAM,EAAEN,SAASI,UAAS,IAAKiB;AAE/B,QAAIjB,WAAW;AACb,UAAI,CAAC,KAAKP,WAAW0B,IAAIxB,KAAAA,GAAQ;AAC/B,cAAMyB,WAAW,KAAKjB,QAAQP,OAAAA;AAC9B,aAAKH,WAAWK,IAAIH,OAAOyB,QAAAA;MAC7B;AACA,aAAO,KAAK3B,WAAWyB,IAAIvB,KAAAA;IAC7B;AAEA,WAAO,KAAKQ,QAAQP,OAAAA;EACtB;AACF;;;ACpDO,IAAKyB,eAAAA,yBAAAA,eAAAA;;;;;;SAAAA;;;;ACpBZ,IAAqBC,mBAArB,cAA8CC,MAAAA;EAF9C,OAE8CA;;;EAC5CC;EAEAC,YAAYC,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKF,QAAQ;MACXG,MAAM;MACNC,WAAWC,aAAaC;MACxBJ;MACAK,YAAY,oBAAIC,KAAAA;IAClB;EACF;AACF;;;ACVA,IAAqBC,gBAArB,cAAoEC,MAAAA;EAJpE,OAIoEA;;;EAClEC;EACAC;EAEAC,YAAYD,eAAwB;AAClC,UAAM,0BAAA;AACN,SAAKA,gBAAgBA;AACrB,SAAKD,QAAQ;MACXG,MAAM;MACNC,WAAWC,aAAaC;MACxBC,SAAS,KAAKA;MACdC,YAAY,oBAAIC,KAAAA;IAClB;EACF;AACF;;;AChBA,IAAqBC,cAArB,cAAyCC,MAAAA;EAFzC,OAEyCA;;;EACvCC;EAEAC,YAAYC,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKF,QAAQ;MACXG,MAAM;MACNC,WAAWC,aAAaC;MACxBJ;MACAK,YAAY,oBAAIC,KAAAA;IAClB;EACF;AACF;;;ACZA,IAAqBC,aAArB,cAAwCC,MAAAA;EAFxC,OAEwCA;;;EACtCC;EAEAC,YAAYC,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKF,QAAQ;MACXG,MAAM;MACNC,WAAWC,aAAaC;MACxBJ;MACAK,YAAY,oBAAIC,KAAAA;IAClB;EACF;AACF;;;ACRA,IAAqBC,kBAArB,cAA6CC,MAAAA;EAN7C,OAM6CA;;;EAC3CC;EAEAC,YAAYC,QAAuB;AACjC,UAAM,kBAAA;AACN,SAAKF,QAAQ;MACXG,MAAM;MACNC,WAAWC,aAAaC;MACxBC,SAAS;MACTC,YAAY,oBAAIC,KAAAA;MAChBP;IACF;EACF;AACF;;;ACTA,OAAO;AAkCA,IAAeQ,iBAAf,MAAeA;EA5CtB,OA4CsBA;;;EACDC;EAInBC,cAAc;AACZ,SAAKD,gBAAgBE,oBAAoBC,aAAa,gBAAA;EACxD;EAEUC,QAAWC,KAAmB;AACtC,WAAO;MACLC,MAAM;MACNC,MAAM;QAAEA,MAAMF;MAAI;IACpB;EACF;EAEUG,YAAsB;AAC9B,WAAO;MACLF,MAAM;MACNC,MAAME;IACR;EACF;EAEUC,QAAWL,KAAmB;AACtC,WAAO;MACLC,MAAM;MACNC,MAAMF,MAAM;QAAEE,MAAMF;MAAI,IAAII;IAC9B;EACF;EAEUE,UAAaN,KAAmB;AACxC,WAAO;MACLC,MAAM;MACNC,MAAMF;IACR;EACF;EAEUO,kBAAkBC,SAAgC;AAC1D,WAAO;MACLC,KAAKC,QAAQD,IAAIE;MACjBH,SAAS;QACPI,MAAMJ,QAAQI;QACdC,SAASL,QAAQK;QACjBC,QAAQN,QAAQM;QAChBC,OAAOP,QAAQO;MACjB;IACF;EACF;EAEA,MAAaC,QAAQC,OAAcC,SAA0C;AAC3E,QAAID,iBAAiBE,eAAe;AAClC,aAAO;QACLlB,MAAMgB,MAAMG,MAAMnB;QAClBC,MAAM;UACJmB,SAASJ,MAAMI;UACfC,WAAWL,MAAMG,MAAME;UACvBC,YAAYN,MAAMG,MAAMG;UACxBC,OAAOC,MAAMC,QAAQT,MAAMU,aAAa,IACpCV,MAAMU,gBACN;YAACV,MAAMU;;QACb;MACF;IACF;AAEA,QACEV,iBAAiBW,eACjBX,iBAAiBY,oBACjBZ,iBAAiBa,YACjB;AACA,aAAO;QACL7B,MAAMgB,MAAMG,MAAMnB;QAClBC,MAAM;UACJmB,SAASJ,MAAMI;UACfC,WAAWL,MAAMG,MAAME;UACvBC,YAAYN,MAAMG,MAAMG;QAC1B;MACF;IACF;AAEA,QAAIN,iBAAiBc,iBAAiB;AACpC,aAAO;QACL9B,MAAMgB,MAAMG,MAAMnB;QAClBC,MAAM;UACJmB,SAASJ,MAAMG,MAAMC;UACrBC,WAAWL,MAAMG,MAAME;UACvBC,YAAYN,MAAMG,MAAMG;UACxBS,QAAQf,MAAMG,MAAMY;QACtB;MACF;IACF;AAEA,QAAItB,QAAQD,IAAIwB,qBAAqB;AACnC,YAAM,KAAKtC,cAAcuC,OAAOjB,OAAOC,OAAAA;IACzC;AAEA,WAAO;MACLjB,MAAM;MACNC,MAAM;QACJD,MAAM;QACNoB,SAAS;MACX;IACF;EACF;EAEA,MAAac,QAAQ3B,SAAqC;AACxD,UAAM4B,gBAAgBC,QAAQC,YAAY,SAAS,KAAK1C,WAAW;AAEnE,QAAI,CAACwC,eAAe;AAClB,YAAM,IAAIN,WAAW,2BAAA;IACvB;AAEA,UAAMS,cAAoCH,cAAcG,eAAe,CAAA;AAEvE,QAAIC,mBAAmBhC;AAEvB,QAAI+B,YAAYE,QAAQ;AACtB,iBAAWC,cAAcH,aAAa;AACpCC,2BAAmB,MAAME,WAAWF,gBAAAA;MACtC;IACF;AAEA,WAAO,MAAM,KAAKG,OAAOH,gBAAAA;EAC3B;AACF;;;AC7JO,SAASI,WAAW,EACzBC,QACAC,MACAC,cAAc,CAAA,EAAE,GACV;AACN,SAAO,CAACC,WAAAA;AACN,QAAI,EAAEA,OAAOC,qBAAqBC,iBAAiB;AACjD,YAAM,IAAIC,MACR,aAAaH,OAAOI,IAAI,+CAA+C;IAE3E;AAEAC,YAAQC,eACN,SACA;MAAET;MAAQC,MAAM,QAAQA,IAAAA;MAAQC;IAAY,GAC5CC,MAAAA;EAEJ;AACF;AAlBgBJ;","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle","Controller","method","path","middlewares","target","prototype","BaseController","Error","name","Reflect","defineMetadata"]}
|
|
@@ -24,7 +24,6 @@ __export(base_controller_exports, {
|
|
|
24
24
|
BaseController: () => BaseController
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(base_controller_exports);
|
|
27
|
-
var import_reflect_metadata2 = require("reflect-metadata");
|
|
28
27
|
|
|
29
28
|
// src/core/decorators/dependency-container.ts
|
|
30
29
|
var import_reflect_metadata = require("reflect-metadata");
|
|
@@ -178,6 +177,7 @@ var ValidationError = class extends Error {
|
|
|
178
177
|
};
|
|
179
178
|
|
|
180
179
|
// src/core/http/base-controller.ts
|
|
180
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
181
181
|
var BaseController = class {
|
|
182
182
|
static {
|
|
183
183
|
__name(this, "BaseController");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/http/base-controller.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts"],"sourcesContent":["import 'reflect-metadata'\n\nimport { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { IErrorNotifier } from './error-notifier'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n"],"mappings":"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","names":["import_reflect_metadata","DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/http/base-controller.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts"],"sourcesContent":["import { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\n\nimport { IErrorNotifier } from './error-notifier'\n\nimport 'reflect-metadata'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n"],"mappings":"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","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","import_reflect_metadata","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle"]}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
-
// src/core/http/base-controller.ts
|
|
5
|
-
import "reflect-metadata";
|
|
6
|
-
|
|
7
4
|
// src/core/decorators/dependency-container.ts
|
|
8
5
|
import "reflect-metadata";
|
|
9
6
|
var DependencyContainer = class {
|
|
@@ -156,6 +153,7 @@ var ValidationError = class extends Error {
|
|
|
156
153
|
};
|
|
157
154
|
|
|
158
155
|
// src/core/http/base-controller.ts
|
|
156
|
+
import "reflect-metadata";
|
|
159
157
|
var BaseController = class {
|
|
160
158
|
static {
|
|
161
159
|
__name(this, "BaseController");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/http/base-controller.ts","../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts"],"sourcesContent":["import 'reflect-metadata'\n\nimport { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\nimport { IErrorNotifier } from './error-notifier'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n","import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n"],"mappings":"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","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/decorators/dependency-container.ts","../../../src/core/errors/api-common-error.ts","../../../src/core/errors/application-error.ts","../../../src/core/errors/conflict-error.ts","../../../src/core/errors/domain-error.ts","../../../src/core/errors/infra-error.ts","../../../src/core/errors/validation-error.ts","../../../src/core/http/base-controller.ts"],"sourcesContent":["import 'reflect-metadata'\n\ntype Class<T = any> = new (...args: any[]) => T\n\ntype Registration =\n | { type: 'class'; myClass: Class; singleton: boolean }\n | { type: 'value'; value: any }\n\nexport class DependencyContainer {\n static registry = new Map<string, Registration>()\n static singletons = new Map<string, any>()\n\n static register<T>(\n token: string,\n myClass: Class<T>,\n options: { singleton: boolean }\n ) {\n this.registry.set(token, {\n type: 'class',\n myClass,\n singleton: options.singleton,\n })\n }\n\n static registerValue<T>(token: string, value: T) {\n this.registry.set(token, { type: 'value', value })\n }\n\n static resolve<T>(target: Class<T>): T {\n const paramTypes = Reflect.getMetadata('design:paramtypes', target) || []\n\n const injectMetadata: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', target) || {}\n\n const params = paramTypes.map((_: any, index: number) => {\n const token = injectMetadata[index]\n\n if (!token) {\n throw new Error(\n `Missing @Inject token for parameter index ${index} in ${target.name}`\n )\n }\n\n return this.resolveToken(token)\n })\n\n return new target(...params)\n }\n\n static resolveToken(token: string): any {\n const registration = this.registry.get(token)\n\n if (!registration) {\n throw new Error(\n `\"${token}\" not registered. Please register it in the container.`\n )\n }\n\n if (registration.type === 'value') {\n return registration.value\n }\n\n const { myClass, singleton } = registration\n\n if (singleton) {\n if (!this.singletons.has(token)) {\n const instance = this.resolve(myClass)\n this.singletons.set(token, instance)\n }\n return this.singletons.get(token)\n }\n\n return this.resolve(myClass)\n }\n}\n\nexport function Inject(token: string): ParameterDecorator {\n return (\n target: object,\n _propertyKey: string | symbol | undefined,\n parameterIndex: number\n ): void => {\n const constructor =\n typeof target === 'function' ? target : target.constructor\n\n const existingInjectedParams: Record<number, string> =\n Reflect.getOwnMetadata('inject:params', constructor) || {}\n\n existingInjectedParams[parameterIndex] = token\n\n Reflect.defineMetadata('inject:params', existingInjectedParams, constructor)\n }\n}\n","export type PropertiesError = {\n receivedValue?: any\n type: string\n message: string\n property: string | number | undefined\n propertyType?: string\n path?: string\n}\n\nexport type CommonError = {\n location: string\n propertyErrors?: PropertiesError[]\n}\n\nexport type ApiCommonError = {\n code: number\n occurredAt: Date\n message: string\n errorCode: string\n errors?: CommonError[]\n}\n\nexport enum ApiErrorEnum {\n DOMAIN = 'ERR001',\n APPLICATION = 'ERR002',\n INFRA = 'ERR003',\n HTTP_CLIENT = 'ERR004',\n VALIDATOR = 'ERR005',\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class ApplicationError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.APPLICATION,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\ntype ConflictProps = { id: string; [key: string]: unknown }\n\nexport default class ConflictError<T extends ConflictProps> extends Error {\n props: ApiCommonError\n conflictProps: T | T[]\n\n constructor(conflictProps: T | T[]) {\n super('Resource already exists.')\n this.conflictProps = conflictProps\n this.props = {\n code: 409,\n errorCode: ApiErrorEnum.APPLICATION,\n message: this.message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class DomainError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.DOMAIN,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import { type ApiCommonError, ApiErrorEnum } from './api-common-error'\n\nexport default class InfraError extends Error {\n props: ApiCommonError\n\n constructor(message: string) {\n super(message)\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.INFRA,\n message,\n occurredAt: new Date(),\n }\n }\n}\n","import {\n type ApiCommonError,\n ApiErrorEnum,\n type CommonError,\n} from './api-common-error'\n\nexport default class ValidationError extends Error {\n props: ApiCommonError\n\n constructor(errors: CommonError[]) {\n super('Validation Error')\n this.props = {\n code: 400,\n errorCode: ApiErrorEnum.VALIDATOR,\n message: 'Validation Error',\n occurredAt: new Date(),\n errors,\n }\n }\n}\n","import { DependencyContainer } from '../../core/decorators/dependency-container'\nimport ApplicationError from '../../core/errors/application-error'\nimport ConflictError from '../../core/errors/conflict-error'\nimport DomainError from '../../core/errors/domain-error'\nimport InfraError from '../../core/errors/infra-error'\nimport ValidationError from '../../core/errors/validation-error'\nimport { MiddlewareFunction } from '../../infra/adapters/validators/zod/zod-validator'\n\nimport { IErrorNotifier } from './error-notifier'\n\nimport 'reflect-metadata'\n\ntype AnyObject = Record<string, any>\n\nexport type Request = {\n body: AnyObject\n params: AnyObject\n headers: AnyObject\n query: AnyObject\n}\n\nexport type Response = {\n code: number\n data: any\n}\n\nexport type ContextError = {\n env: string\n user?: {\n id?: string\n name?: string\n email?: string\n }\n request?: {\n method?: string\n requestId?: string\n url?: string\n headers?: any\n query?: any\n body?: any\n params?: any\n }\n}\n\nexport abstract class BaseController {\n protected readonly errorNotifier: IErrorNotifier\n\n abstract handle<T>(request: T | Request): Promise<Response>\n\n constructor() {\n this.errorNotifier = DependencyContainer.resolveToken('IErrorNotifier')\n }\n\n protected success<T>(dto?: T): Response {\n return {\n code: 200,\n data: { data: dto },\n }\n }\n\n protected noContent(): Response {\n return {\n code: 204,\n data: undefined,\n }\n }\n\n protected created<T>(dto?: T): Response {\n return {\n code: 201,\n data: dto ? { data: dto } : undefined,\n }\n }\n\n protected paginated<T>(dto?: T): Response {\n return {\n code: 200,\n data: dto,\n }\n }\n\n protected buildContextError(request: Request): ContextError {\n return {\n env: process.env.ENVIRONMENT as string,\n request: {\n body: request.body,\n headers: request.headers,\n params: request.params,\n query: request.query,\n },\n }\n }\n\n public async failure(error: Error, context: ContextError): Promise<Response> {\n if (error instanceof ConflictError) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n items: Array.isArray(error.conflictProps)\n ? error.conflictProps\n : [error.conflictProps],\n },\n }\n }\n\n if (\n error instanceof DomainError ||\n error instanceof ApplicationError ||\n error instanceof InfraError\n ) {\n return {\n code: error.props.code,\n data: {\n message: error.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n },\n }\n }\n\n if (error instanceof ValidationError) {\n return {\n code: error.props.code,\n data: {\n message: error.props.message,\n errorCode: error.props.errorCode,\n occurredAt: error.props.occurredAt,\n errors: error.props.errors,\n },\n }\n }\n\n if (process.env.SHOULD_NOTIFY_ERROR) {\n await this.errorNotifier.notify(error, context)\n }\n\n return {\n code: 500,\n data: {\n code: 500,\n message: 'Server failed. Contact the administrator!',\n },\n }\n }\n\n public async execute(request: Request): Promise<Response> {\n const routeMetadata = Reflect.getMetadata('route', this.constructor)\n\n if (!routeMetadata) {\n throw new InfraError('Route metadata not found.')\n }\n\n const middlewares: MiddlewareFunction[] = routeMetadata.middlewares || []\n\n let processedRequest = request\n\n if (middlewares.length) {\n for (const middleware of middlewares) {\n processedRequest = await middleware(processedRequest)\n }\n }\n\n return await this.handle(processedRequest)\n }\n}\n"],"mappings":"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","names":["DependencyContainer","registry","Map","singletons","register","token","myClass","options","set","type","singleton","registerValue","value","resolve","target","paramTypes","Reflect","getMetadata","injectMetadata","getOwnMetadata","params","map","_","index","Error","name","resolveToken","registration","get","has","instance","ApiErrorEnum","ApplicationError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","APPLICATION","occurredAt","Date","ConflictError","Error","props","conflictProps","constructor","code","errorCode","ApiErrorEnum","APPLICATION","message","occurredAt","Date","DomainError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","DOMAIN","occurredAt","Date","InfraError","Error","props","constructor","message","code","errorCode","ApiErrorEnum","INFRA","occurredAt","Date","ValidationError","Error","props","constructor","errors","code","errorCode","ApiErrorEnum","VALIDATOR","message","occurredAt","Date","BaseController","errorNotifier","constructor","DependencyContainer","resolveToken","success","dto","code","data","noContent","undefined","created","paginated","buildContextError","request","env","process","ENVIRONMENT","body","headers","params","query","failure","error","context","ConflictError","props","message","errorCode","occurredAt","items","Array","isArray","conflictProps","DomainError","ApplicationError","InfraError","ValidationError","errors","SHOULD_NOTIFY_ERROR","notify","execute","routeMetadata","Reflect","getMetadata","middlewares","processedRequest","length","middleware","handle"]}
|
package/dist/index.cjs
CHANGED
|
@@ -448,6 +448,8 @@ __export(src_exports, {
|
|
|
448
448
|
DependencyContainer: () => DependencyContainer,
|
|
449
449
|
DiscordNotifier: () => DiscordNotifier,
|
|
450
450
|
Entity: () => Entity,
|
|
451
|
+
ExpressAdapter: () => ExpressAdapter,
|
|
452
|
+
FastifyAdapter: () => FastifyAdapter,
|
|
451
453
|
Inject: () => Inject,
|
|
452
454
|
NotificationErrorInMemory: () => NotificationErrorInMemory,
|
|
453
455
|
NotificationFactory: () => NotificationFactory,
|
|
@@ -461,9 +463,6 @@ __export(src_exports, {
|
|
|
461
463
|
});
|
|
462
464
|
module.exports = __toCommonJS(src_exports);
|
|
463
465
|
|
|
464
|
-
// src/core/http/base-controller.ts
|
|
465
|
-
var import_reflect_metadata2 = require("reflect-metadata");
|
|
466
|
-
|
|
467
466
|
// src/core/decorators/dependency-container.ts
|
|
468
467
|
var import_reflect_metadata = require("reflect-metadata");
|
|
469
468
|
var DependencyContainer = class {
|
|
@@ -625,6 +624,7 @@ var ValidationError = class extends Error {
|
|
|
625
624
|
};
|
|
626
625
|
|
|
627
626
|
// src/core/http/base-controller.ts
|
|
627
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
628
628
|
var BaseController = class {
|
|
629
629
|
static {
|
|
630
630
|
__name(this, "BaseController");
|
|
@@ -935,13 +935,164 @@ __name(getTakeAndSkip, "getTakeAndSkip");
|
|
|
935
935
|
var import_cors = __toESM(require("cors"), 1);
|
|
936
936
|
var import_express = __toESM(require("express"), 1);
|
|
937
937
|
|
|
938
|
+
// src/infra/adapters/http/response-error-code.ts
|
|
939
|
+
var ErrorResponseCode = /* @__PURE__ */ function(ErrorResponseCode2) {
|
|
940
|
+
ErrorResponseCode2["NO_CONTENT_BODY"] = "B001";
|
|
941
|
+
ErrorResponseCode2["NO_CONTENT_ERROR"] = "B002";
|
|
942
|
+
return ErrorResponseCode2;
|
|
943
|
+
}({});
|
|
944
|
+
|
|
938
945
|
// src/infra/adapters/http/validate-controller-metadata.ts
|
|
939
946
|
var import_reflect_metadata3 = require("reflect-metadata");
|
|
947
|
+
function validateControllerMetadata(controller) {
|
|
948
|
+
const metadata = Reflect.getMetadata("route", controller.constructor);
|
|
949
|
+
if (!metadata) {
|
|
950
|
+
throw new Error(`Controller ${controller.constructor.name} not have metadata. Need to add decorator.`);
|
|
951
|
+
}
|
|
952
|
+
return {
|
|
953
|
+
metadata
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
__name(validateControllerMetadata, "validateControllerMetadata");
|
|
957
|
+
|
|
958
|
+
// src/infra/adapters/http/express-adapter.ts
|
|
959
|
+
var ExpressAdapter = class {
|
|
960
|
+
static {
|
|
961
|
+
__name(this, "ExpressAdapter");
|
|
962
|
+
}
|
|
963
|
+
env;
|
|
964
|
+
instance;
|
|
965
|
+
server;
|
|
966
|
+
constructor(env) {
|
|
967
|
+
this.env = env;
|
|
968
|
+
this.instance = (0, import_express.default)();
|
|
969
|
+
this.instance.use((0, import_cors.default)());
|
|
970
|
+
this.instance.use(import_express.default.json({
|
|
971
|
+
limit: "10mb"
|
|
972
|
+
}));
|
|
973
|
+
this.instance.use(import_express.default.urlencoded({
|
|
974
|
+
limit: "10mb",
|
|
975
|
+
extended: false
|
|
976
|
+
}));
|
|
977
|
+
this.instance.disable("x-powered-by");
|
|
978
|
+
}
|
|
979
|
+
registerRoute(controllerClass) {
|
|
980
|
+
const { metadata } = validateControllerMetadata(controllerClass);
|
|
981
|
+
this.instance[metadata.method](metadata.path, async (request, response) => {
|
|
982
|
+
const requestData = {
|
|
983
|
+
body: request.body,
|
|
984
|
+
params: request.params,
|
|
985
|
+
headers: request.headers,
|
|
986
|
+
query: request.query
|
|
987
|
+
};
|
|
988
|
+
try {
|
|
989
|
+
const output = await controllerClass.execute(requestData);
|
|
990
|
+
response.status(output.code || 204).json(output.data || {
|
|
991
|
+
code: ErrorResponseCode.NO_CONTENT_BODY
|
|
992
|
+
});
|
|
993
|
+
} catch (err) {
|
|
994
|
+
const error = await controllerClass.failure(err, {
|
|
995
|
+
env: this.env.ENVIRONMENT,
|
|
996
|
+
request: {
|
|
997
|
+
body: requestData.body,
|
|
998
|
+
headers: requestData.headers,
|
|
999
|
+
params: request.params,
|
|
1000
|
+
query: requestData.query,
|
|
1001
|
+
url: metadata.path,
|
|
1002
|
+
method: metadata.method
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
response.status(error.code).json(error.data || {
|
|
1006
|
+
error: ErrorResponseCode.NO_CONTENT_ERROR
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
async startServer(port) {
|
|
1012
|
+
return new Promise((resolve) => {
|
|
1013
|
+
this.server = this.instance.listen(port, () => {
|
|
1014
|
+
console.log(`\u{1F680} Server is running on PORT ${port}`);
|
|
1015
|
+
resolve();
|
|
1016
|
+
});
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
async closeServer() {
|
|
1020
|
+
return new Promise((resolve, reject) => {
|
|
1021
|
+
if (this.server) {
|
|
1022
|
+
this.server.close((err) => {
|
|
1023
|
+
if (err)
|
|
1024
|
+
return reject(err);
|
|
1025
|
+
resolve();
|
|
1026
|
+
});
|
|
1027
|
+
} else {
|
|
1028
|
+
resolve();
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
940
1033
|
|
|
941
1034
|
// src/infra/adapters/http/fastify-adapter.ts
|
|
942
1035
|
var import_cors2 = __toESM(require("@fastify/cors"), 1);
|
|
943
1036
|
var import_fastify = __toESM(require("fastify"), 1);
|
|
944
1037
|
var import_qs = __toESM(require("qs"), 1);
|
|
1038
|
+
var FastifyAdapter = class {
|
|
1039
|
+
static {
|
|
1040
|
+
__name(this, "FastifyAdapter");
|
|
1041
|
+
}
|
|
1042
|
+
env;
|
|
1043
|
+
instance;
|
|
1044
|
+
constructor(env) {
|
|
1045
|
+
this.env = env;
|
|
1046
|
+
this.instance = (0, import_fastify.default)({
|
|
1047
|
+
bodyLimit: 10 * 1024 * 1024,
|
|
1048
|
+
querystringParser: (str) => import_qs.default.parse(str)
|
|
1049
|
+
});
|
|
1050
|
+
this.instance.register(import_cors2.default);
|
|
1051
|
+
}
|
|
1052
|
+
registerRoute(controllerClass) {
|
|
1053
|
+
const { metadata } = validateControllerMetadata(controllerClass);
|
|
1054
|
+
this.instance[metadata.method](metadata.path, async (request, reply) => {
|
|
1055
|
+
const requestData = {
|
|
1056
|
+
body: request.body,
|
|
1057
|
+
params: request.params,
|
|
1058
|
+
headers: request.headers,
|
|
1059
|
+
query: request.query
|
|
1060
|
+
};
|
|
1061
|
+
try {
|
|
1062
|
+
const output = await controllerClass.execute(requestData);
|
|
1063
|
+
return reply.status(output.code || 200).send(output.data || {
|
|
1064
|
+
code: ErrorResponseCode.NO_CONTENT_BODY
|
|
1065
|
+
});
|
|
1066
|
+
} catch (err) {
|
|
1067
|
+
const error = await controllerClass.failure(err, {
|
|
1068
|
+
env: this.env.ENVIRONMENT,
|
|
1069
|
+
request: {
|
|
1070
|
+
body: requestData.body,
|
|
1071
|
+
headers: requestData.headers,
|
|
1072
|
+
params: request.params,
|
|
1073
|
+
query: requestData.query,
|
|
1074
|
+
url: metadata.path,
|
|
1075
|
+
method: metadata.method
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
return reply.status(error.code || 200).send(error.data || {
|
|
1079
|
+
code: ErrorResponseCode.NO_CONTENT_ERROR
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
async startServer(port) {
|
|
1085
|
+
await this.instance.listen({
|
|
1086
|
+
port
|
|
1087
|
+
});
|
|
1088
|
+
if (this.env.NODE_ENV !== "test") {
|
|
1089
|
+
console.log(`\u{1F680} Server is running on PORT ${port}`);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
async closeServer() {
|
|
1093
|
+
await this.instance.close();
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
945
1096
|
|
|
946
1097
|
// src/infra/adapters/notifications/discord.ts
|
|
947
1098
|
var import_discord_webhook_node = require("discord-webhook-node");
|
|
@@ -1228,13 +1379,15 @@ function zodValidator(schema) {
|
|
|
1228
1379
|
}
|
|
1229
1380
|
__name(zodValidator, "zodValidator");
|
|
1230
1381
|
|
|
1382
|
+
// src/infra/env/index.ts
|
|
1383
|
+
var import_zod = require("zod");
|
|
1384
|
+
|
|
1231
1385
|
// node_modules/dotenv/config.js
|
|
1232
1386
|
(function() {
|
|
1233
1387
|
require_main().config(Object.assign({}, require_env_options(), require_cli_options()(process.argv)));
|
|
1234
1388
|
})();
|
|
1235
1389
|
|
|
1236
1390
|
// src/infra/env/index.ts
|
|
1237
|
-
var import_zod = require("zod");
|
|
1238
1391
|
var baseEnvSchema = import_zod.z.object({
|
|
1239
1392
|
NODE_ENV: import_zod.z.enum([
|
|
1240
1393
|
"test",
|
|
@@ -1260,6 +1413,8 @@ var baseEnvSchema = import_zod.z.object({
|
|
|
1260
1413
|
DependencyContainer,
|
|
1261
1414
|
DiscordNotifier,
|
|
1262
1415
|
Entity,
|
|
1416
|
+
ExpressAdapter,
|
|
1417
|
+
FastifyAdapter,
|
|
1263
1418
|
Inject,
|
|
1264
1419
|
NotificationErrorInMemory,
|
|
1265
1420
|
NotificationFactory,
|