framework-do-dede 5.0.0 → 5.2.0

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/README.md CHANGED
@@ -252,40 +252,53 @@ class CreateUserUseCase extends UseCase<{ name: string }, { id: string }> {
252
252
 
253
253
  ### Entity e Model
254
254
 
255
- Entities sao dominio puro. Use `Model` para converter entre Entity e o objeto do banco.
255
+ Entities sao dominio puro. Use `Model` para mapear coluna/property e construir o objeto de persistencia.
256
256
 
257
257
  ```ts
258
- import { Entity, Model } from './src';
258
+ import { Entity, Model, model, column } from './src';
259
259
 
260
- class User extends Entity {
260
+ class Order extends Entity {
261
261
  private readonly id: string;
262
- private readonly email: string;
262
+ private readonly name: string;
263
+ private readonly amount: number;
263
264
 
264
- constructor(id: string, email: string) {
265
+ constructor(id: string, name: string, amount: number) {
265
266
  super();
266
267
  this.id = id;
267
- this.email = email;
268
+ this.name = name;
269
+ this.amount = amount;
268
270
  this.generateGetters();
269
271
  }
270
272
  }
271
273
 
272
- type UserRow = { id: string; email: string };
274
+ type OrderTable = 'orders';
273
275
 
274
- class UserModel extends Model<User, UserRow> {
275
- toModel(entity: User): UserRow {
276
- return { id: entity.getId(), email: entity.getEmail() };
277
- }
276
+ @model<OrderTable>('orders')
277
+ class OrderModel extends Model<OrderTable> {
278
+ @column('id')
279
+ id!: string;
280
+
281
+ @column('name')
282
+ name!: string;
278
283
 
279
- toEntity(model: UserRow): User {
280
- return new User(model.id, model.email);
284
+ @column('amount')
285
+ amount!: number;
286
+
287
+ constructor(order?: Order) {
288
+ super();
289
+ if (order) {
290
+ this.id = order.getId();
291
+ this.name = order.getName();
292
+ this.amount = order.getAmount();
293
+ }
281
294
  }
282
295
  }
283
296
  ```
284
297
 
285
298
  Regras principais:
286
299
 
287
- - `Model` centraliza conversoes entre dominio e persistencia
288
- - use `toModel` e `toEntity`
300
+ - `Model` guarda metadados de coluna (via `@column`) e nome da tabela (via `@model`)
301
+ - a conversao entity -> model acontece no construtor do Model (ou em um factory)
289
302
  - `generateGetters()` cria getters para campos (ex.: `getName`, `isActive`, `hasProfile`)
290
303
 
291
304
  ### Storage Gateway
@@ -377,16 +390,15 @@ Quando um erro e lancado, o handler padroniza a resposta. Erros de dominio (`App
377
390
 
378
391
  Interfaces tipadas para padrao de repositorio:
379
392
 
380
- - `RepositoryModel<E extends Entity, M>`
381
- - `RepositoryCreate<E extends Entity, M>`
382
- - `RepositoryUpdate<E extends Entity, M>`
393
+ - `RepositoryCreate<T extends Entity>`
394
+ - `RepositoryUpdate<T extends Entity>`
383
395
  - `RepositoryRemove`
384
- - `RepositoryRestore<E extends Entity, M>`
385
- - `RepositoryRemoveBy<E>`
386
- - `RepositoryRestoreBy<E>`
387
- - `RepositoryExistsBy<E>`
388
- - `RepositoryNotExistsBy<E>`
389
- - `RepositoryPagination<E extends Entity, M>`
396
+ - `RepositoryRestore<T extends Entity>`
397
+ - `RepositoryRemoveBy<T>`
398
+ - `RepositoryRestoreBy<T>`
399
+ - `RepositoryExistsBy<T>`
400
+ - `RepositoryNotExistsBy<T>`
401
+ - `RepositoryPagination<T>`
390
402
 
391
403
  ## Exemplos
392
404
 
@@ -1,8 +1,8 @@
1
1
  import { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing, type Middleware, type Input, type Tracer, type TracerData } from './controller';
2
- import { Entity, Restrict, VirtualProperty, GetterPrefix, Serialize } from '../infra/serialization/entity';
3
- import { Model } from '../infra/model/model';
2
+ import { Entity, Restrict, VirtualProperty, GetterPrefix, Transform } from '../infra/serialization/entity';
3
+ import { Model, model, column } from '../infra/model/model';
4
4
  import { DecorateUseCase, UseCase } from './usecase';
5
- export { Controller, UseMiddleware, UseMiddlewares, Post, Get, Put, Delete, Patch, Tracing, DecorateUseCase, UseCase, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, Model, };
5
+ export { Controller, UseMiddleware, UseMiddlewares, Post, Get, Put, Delete, Patch, Tracing, DecorateUseCase, UseCase, Entity, Restrict, VirtualProperty, GetterPrefix, Transform, Model, model, column, };
6
6
  export { Storage, CacheGateway, EventDispatcher } from './services';
7
7
  export type { Middleware, Input, Tracer, TracerData };
8
8
  export type { StorageGateway } from './services';
@@ -1,6 +1,6 @@
1
1
  import { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing } from './controller';
2
- import { Entity, Restrict, VirtualProperty, GetterPrefix, Serialize } from '../infra/serialization/entity';
3
- import { Model } from '../infra/model/model';
2
+ import { Entity, Restrict, VirtualProperty, GetterPrefix, Transform } from '../infra/serialization/entity';
3
+ import { Model, model, column } from '../infra/model/model';
4
4
  import { DecorateUseCase, UseCase } from './usecase';
5
- export { Controller, UseMiddleware, UseMiddlewares, Post, Get, Put, Delete, Patch, Tracing, DecorateUseCase, UseCase, Entity, Restrict, VirtualProperty, GetterPrefix, Serialize, Model, };
5
+ export { Controller, UseMiddleware, UseMiddlewares, Post, Get, Put, Delete, Patch, Tracing, DecorateUseCase, UseCase, Entity, Restrict, VirtualProperty, GetterPrefix, Transform, Model, model, column, };
6
6
  export { Storage, CacheGateway, EventDispatcher } from './services';
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { Post, Get, Put, Delete, Patch, Controller, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Model, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher } from "./application";
1
+ import { Post, Get, Put, Delete, Patch, Controller, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Model, model, column, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher } from "./application";
2
2
  import { Container, DefaultContainer, Inject, setDefaultContainer } from './infra/di/registry';
3
3
  import { Dede, type Options, Register } from './dede';
4
4
  import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from './http/errors/server';
5
5
  import { AppError } from './domain/errors/app-error';
6
6
  import type { ValidatorDefinition } from './interface/validation/validator';
7
7
  import type { StorageGateway, Event, EventPayload } from './application';
8
- import type { RepositoryModel, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryExistsBy, RepositoryRestore, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination } from './protocols/repository';
9
- export { Controller, Post, Get, Put, Delete, Patch, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Model, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, Options, Register, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError, RepositoryModel, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryRestore, RepositoryExistsBy, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination };
8
+ import type { RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryExistsBy, RepositoryRestore, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination } from './protocols/repository';
9
+ export { Controller, Post, Get, Put, Delete, Patch, Input, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Model, model, column, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, Options, Register, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryRestore, RepositoryExistsBy, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination };
10
10
  export type { ValidatorDefinition, StorageGateway, Event, EventPayload };
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  Post, Get, Put, Delete, Patch, Controller, UseMiddleware, UseMiddlewares, Tracing,
4
4
  // controller
5
5
  // entity
6
- Entity, Restrict, VirtualProperty, GetterPrefix, Model,
6
+ Entity, Restrict, VirtualProperty, GetterPrefix, Model, model, column,
7
7
  // entity
8
8
  // usecase
9
9
  UseCase, DecorateUseCase,
@@ -16,4 +16,4 @@ import { Container, DefaultContainer, Inject, setDefaultContainer } from './infr
16
16
  import { Dede } from './dede';
17
17
  import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError } from './http/errors/server';
18
18
  import { AppError } from './domain/errors/app-error';
19
- export { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing, Entity, Restrict, VirtualProperty, GetterPrefix, Model, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError };
19
+ export { Controller, Post, Get, Put, Delete, Patch, UseMiddleware, UseMiddlewares, Tracing, Entity, Restrict, VirtualProperty, GetterPrefix, Model, model, column, UseCase, DecorateUseCase, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError };
@@ -1,5 +1,12 @@
1
- import { Entity } from '../../domain/entity';
2
- export declare abstract class Model<E extends Entity, D> {
3
- abstract toModel(entity: E): D;
4
- abstract toEntity(model: D): E;
1
+ export type ColumnDefinition = {
2
+ column: string;
3
+ property: string;
4
+ };
5
+ export declare abstract class Model<TTable = string> {
6
+ table: TTable;
7
+ columns: ColumnDefinition[];
8
+ [property: string]: any;
9
+ toPersistence(): Record<string, any>;
5
10
  }
11
+ export declare function model<TTable>(table: TTable): (target: any) => void;
12
+ export declare function column(columnName: string): (target: any, propertyKey: string) => void;
@@ -1,2 +1,21 @@
1
1
  export class Model {
2
+ toPersistence() {
3
+ const record = {};
4
+ const columns = this.columns ?? [];
5
+ for (const column of columns) {
6
+ record[column.column] = this[column.property];
7
+ }
8
+ return record;
9
+ }
10
+ }
11
+ export function model(table) {
12
+ return function (target) {
13
+ target.prototype.table = table;
14
+ };
15
+ }
16
+ export function column(columnName) {
17
+ return function (target, propertyKey) {
18
+ target.columns = target.columns || [];
19
+ target.columns.push({ column: columnName, property: propertyKey });
20
+ };
2
21
  }
@@ -1,13 +1,11 @@
1
1
  import { Entity as DomainEntity } from "../../domain/entity";
2
2
  export declare abstract class Entity extends DomainEntity {
3
3
  [x: string]: any;
4
- toEntity(): Record<string, any>;
5
- toData({ serialize }?: {
6
- serialize?: boolean;
7
- }): Record<string, any>;
4
+ from(): Record<string, any>;
5
+ to(transform?: boolean): Record<string, any>;
8
6
  protected generateGetters(): void;
9
7
  }
10
8
  export declare function Restrict(): (target: any, propertyKey: string) => void;
11
9
  export declare function VirtualProperty(propertyName: string): (target: any, methodName: string) => void;
12
- export declare function Serialize(callback: (value: any) => any): PropertyDecorator;
10
+ export declare function Transform(callback: (value: any) => any): PropertyDecorator;
13
11
  export declare function GetterPrefix(prefix: string): (target: any, propertyKey: string) => void;
@@ -1,6 +1,6 @@
1
1
  import { Entity as DomainEntity } from "../../domain/entity";
2
2
  export class Entity extends DomainEntity {
3
- toEntity() {
3
+ from() {
4
4
  // @ts-ignore
5
5
  const propertiesConfigs = this.constructor.propertiesConfigs;
6
6
  const result = {};
@@ -12,20 +12,20 @@ export class Entity extends DomainEntity {
12
12
  if (value === undefined)
13
13
  continue;
14
14
  // @ts-ignore
15
- if (propertiesConfigs && propertiesConfigs[propName]?.serialize && value) {
16
- const serializedValue = propertiesConfigs[propName].serialize(value);
17
- if (serializedValue && typeof serializedValue === 'object' && !Array.isArray(serializedValue)) {
18
- const entries = Object.entries(serializedValue);
19
- for (const [serializedKey, serializedPropValue] of entries) {
20
- let currentValue = serializedPropValue;
15
+ if (propertiesConfigs && propertiesConfigs[propName]?.transform && value) {
16
+ const transformedValue = propertiesConfigs[propName].transform(value);
17
+ if (transformedValue && typeof transformedValue === 'object' && !Array.isArray(transformedValue)) {
18
+ const entries = Object.entries(transformedValue);
19
+ for (const [transformedKey, transformedPropValue] of entries) {
20
+ let currentValue = transformedPropValue;
21
21
  if (!currentValue)
22
22
  currentValue = null;
23
- result[serializedKey] = currentValue;
23
+ result[transformedKey] = currentValue;
24
24
  }
25
25
  continue;
26
26
  }
27
27
  else {
28
- value = serializedValue;
28
+ value = transformedValue;
29
29
  }
30
30
  }
31
31
  if (value === undefined || value === null)
@@ -34,7 +34,7 @@ export class Entity extends DomainEntity {
34
34
  }
35
35
  return result;
36
36
  }
37
- toData({ serialize = false } = {}) {
37
+ to(transform = true) {
38
38
  // @ts-ignore
39
39
  const propertiesConfigs = this.constructor.propertiesConfigs;
40
40
  // @ts-ignore
@@ -47,8 +47,8 @@ export class Entity extends DomainEntity {
47
47
  continue;
48
48
  // @ts-ignore
49
49
  let value = this[propName];
50
- if (serialize && propertiesConfigs && propertiesConfigs[propName]?.serialize && value) {
51
- value = propertiesConfigs[propName].serialize(value);
50
+ if (transform && propertiesConfigs && propertiesConfigs[propName]?.transform && value) {
51
+ value = propertiesConfigs[propName].transform(value);
52
52
  }
53
53
  result[propName] = value;
54
54
  }
@@ -78,10 +78,10 @@ export function VirtualProperty(propertyName) {
78
78
  cls.virtualProperties[methodName] = propertyName;
79
79
  };
80
80
  }
81
- export function Serialize(callback) {
81
+ export function Transform(callback) {
82
82
  return function (target, propertyKey) {
83
83
  loadPropertiesConfig(target, propertyKey);
84
- target.constructor.propertiesConfigs[propertyKey].serialize = callback;
84
+ target.constructor.propertiesConfigs[propertyKey].transform = callback;
85
85
  };
86
86
  }
87
87
  export function GetterPrefix(prefix) {
@@ -1,38 +1,34 @@
1
1
  import { Entity } from "../domain";
2
- import { Model } from "../infra/model/model";
3
- export interface RepositoryModel<E extends Entity, M> {
4
- model: Model<E, M>;
2
+ export interface RepositoryCreate<T extends Entity> {
3
+ create(input: T): Promise<void>;
5
4
  }
6
- export interface RepositoryCreate<E extends Entity, M> extends RepositoryModel<E, M> {
7
- create(input: E): Promise<void>;
8
- }
9
- export interface RepositoryUpdate<E extends Entity, M> extends RepositoryModel<E, M> {
10
- update(input: E): Promise<void>;
5
+ export interface RepositoryUpdate<T extends Entity> {
6
+ update(input: T): Promise<void>;
11
7
  }
12
8
  export interface RepositoryRemove {
13
9
  remove(id: string | number): Promise<void>;
14
10
  }
15
- export interface RepositoryRestore<E extends Entity, M> extends RepositoryModel<E, M> {
16
- restore(id: string | number): Promise<E>;
11
+ export interface RepositoryRestore<T extends Entity> {
12
+ restore(id: string | number): Promise<T>;
17
13
  }
18
- export type RepositoryRemoveBy<E> = {
19
- [K in keyof E & string as `removeBy${Capitalize<K>}`]: (value: E[K]) => Promise<void>;
14
+ export type RepositoryRemoveBy<T> = {
15
+ [K in keyof T & string as `removeBy${Capitalize<K>}`]: (value: T[K]) => Promise<void>;
20
16
  };
21
- export type RepositoryRestoreBy<E> = {
22
- [K in keyof E & string as `restoreBy${Capitalize<K>}`]: (value: E[K]) => Promise<any>;
17
+ export type RepositoryRestoreBy<T> = {
18
+ [K in keyof T & string as `restoreBy${Capitalize<K>}`]: (value: T[K]) => Promise<any>;
23
19
  };
24
- export type RepositoryExistsBy<E> = {
25
- [K in keyof E & string as `existsBy${Capitalize<K>}`]: (value: E[K]) => Promise<boolean>;
20
+ export type RepositoryExistsBy<T> = {
21
+ [K in keyof T & string as `existsBy${Capitalize<K>}`]: (value: T[K]) => Promise<boolean>;
26
22
  };
27
- export type RepositoryNotExistsBy<E> = {
28
- [K in keyof E & string as `notExistsBy${Capitalize<K>}`]: (value: E[K]) => Promise<boolean>;
23
+ export type RepositoryNotExistsBy<T> = {
24
+ [K in keyof T & string as `notExistsBy${Capitalize<K>}`]: (value: T[K]) => Promise<boolean>;
29
25
  };
30
- export interface RepositoryPagination<E extends Entity, M> extends RepositoryModel<E, M> {
26
+ export interface RepositoryPagination<T> {
31
27
  restoreMany({ filter, pagination }: {
32
28
  filter?: Record<string, any>;
33
29
  pagination?: {
34
30
  offset: number;
35
31
  limit: number;
36
32
  };
37
- }): Promise<E[]>;
33
+ }): Promise<T>;
38
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framework-do-dede",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",