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 +36 -24
- package/dist/application/index.d.ts +3 -3
- package/dist/application/index.js +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/infra/model/model.d.ts +11 -4
- package/dist/infra/model/model.js +19 -0
- package/dist/infra/serialization/entity.d.ts +3 -5
- package/dist/infra/serialization/entity.js +14 -14
- package/dist/protocols/repository.d.ts +16 -20
- package/package.json +1 -1
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
|
|
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
|
|
260
|
+
class Order extends Entity {
|
|
261
261
|
private readonly id: string;
|
|
262
|
-
private readonly
|
|
262
|
+
private readonly name: string;
|
|
263
|
+
private readonly amount: number;
|
|
263
264
|
|
|
264
|
-
constructor(id: string,
|
|
265
|
+
constructor(id: string, name: string, amount: number) {
|
|
265
266
|
super();
|
|
266
267
|
this.id = id;
|
|
267
|
-
this.
|
|
268
|
+
this.name = name;
|
|
269
|
+
this.amount = amount;
|
|
268
270
|
this.generateGetters();
|
|
269
271
|
}
|
|
270
272
|
}
|
|
271
273
|
|
|
272
|
-
type
|
|
274
|
+
type OrderTable = 'orders';
|
|
273
275
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
|
|
280
|
-
|
|
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`
|
|
288
|
-
-
|
|
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
|
-
- `
|
|
381
|
-
- `
|
|
382
|
-
- `RepositoryUpdate<E extends Entity, M>`
|
|
393
|
+
- `RepositoryCreate<T extends Entity>`
|
|
394
|
+
- `RepositoryUpdate<T extends Entity>`
|
|
383
395
|
- `RepositoryRemove`
|
|
384
|
-
- `RepositoryRestore<
|
|
385
|
-
- `RepositoryRemoveBy<
|
|
386
|
-
- `RepositoryRestoreBy<
|
|
387
|
-
- `RepositoryExistsBy<
|
|
388
|
-
- `RepositoryNotExistsBy<
|
|
389
|
-
- `RepositoryPagination<
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
5
|
-
|
|
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
|
|
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
|
-
|
|
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]?.
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
18
|
-
const entries = Object.entries(
|
|
19
|
-
for (const [
|
|
20
|
-
let currentValue =
|
|
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[
|
|
23
|
+
result[transformedKey] = currentValue;
|
|
24
24
|
}
|
|
25
25
|
continue;
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
|
-
value =
|
|
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
|
-
|
|
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 (
|
|
51
|
-
value = propertiesConfigs[propName].
|
|
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
|
|
81
|
+
export function Transform(callback) {
|
|
82
82
|
return function (target, propertyKey) {
|
|
83
83
|
loadPropertiesConfig(target, propertyKey);
|
|
84
|
-
target.constructor.propertiesConfigs[propertyKey].
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
model: Model<E, M>;
|
|
2
|
+
export interface RepositoryCreate<T extends Entity> {
|
|
3
|
+
create(input: T): Promise<void>;
|
|
5
4
|
}
|
|
6
|
-
export interface
|
|
7
|
-
|
|
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<
|
|
16
|
-
restore(id: string | number): Promise<
|
|
11
|
+
export interface RepositoryRestore<T extends Entity> {
|
|
12
|
+
restore(id: string | number): Promise<T>;
|
|
17
13
|
}
|
|
18
|
-
export type RepositoryRemoveBy<
|
|
19
|
-
[K in keyof
|
|
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<
|
|
22
|
-
[K in keyof
|
|
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<
|
|
25
|
-
[K in keyof
|
|
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<
|
|
28
|
-
[K in keyof
|
|
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<
|
|
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<
|
|
33
|
+
}): Promise<T>;
|
|
38
34
|
}
|