framework-do-dede 5.5.5 → 6.0.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 +79 -32
- package/dist/application/controller.d.ts +2 -2
- package/dist/application/controller.js +31 -6
- package/dist/domain/index.d.ts +2 -1
- package/dist/domain/index.js +2 -1
- package/dist/domain/optional.d.ts +13 -0
- package/dist/domain/optional.js +47 -0
- package/dist/http/controller.handler.js +4 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/infra/model/model.d.ts +5 -5
- package/dist/infra/model/model.js +5 -1
- package/dist/interface/validation/class-validator.d.ts +1 -1
- package/dist/protocols/model.d.ts +6 -0
- package/dist/protocols/model.js +2 -0
- package/dist/protocols/repository.d.ts +7 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ bun run example/express_app/server.ts
|
|
|
40
40
|
## Quickstart
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
import { Controller, Get, Post, UseCase, Dede } from './src';
|
|
43
|
+
import { Controller, Get, Post, UseCase, Dede, Optional } from './src';
|
|
44
44
|
|
|
45
45
|
@Controller('/hello')
|
|
46
46
|
class HelloController {
|
|
@@ -63,6 +63,9 @@ class HelloUseCase extends UseCase<{ name?: string }, { message: string }> {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
const maybeName = Optional.ofNullable(process.env.DEFAULT_NAME);
|
|
67
|
+
const defaultName = maybeName.orElseUndefined();
|
|
68
|
+
|
|
66
69
|
const app = await Dede.create({
|
|
67
70
|
framework: { use: 'express', port: 3000 },
|
|
68
71
|
registries: []
|
|
@@ -218,6 +221,7 @@ vira:
|
|
|
218
221
|
### Middlewares
|
|
219
222
|
|
|
220
223
|
Middlewares devem implementar `execute(input: Input<any>)`. Podem ser classe, factory ou instancia.
|
|
224
|
+
Podem ser aplicados no controller (valem para todas as rotas) e/ou no método.
|
|
221
225
|
|
|
222
226
|
```ts
|
|
223
227
|
import { Middleware, UseMiddleware, UseMiddlewares, Input } from './src';
|
|
@@ -228,7 +232,14 @@ class AuthMiddleware implements Middleware {
|
|
|
228
232
|
}
|
|
229
233
|
}
|
|
230
234
|
|
|
235
|
+
class LoggerMiddleware implements Middleware {
|
|
236
|
+
async execute(input: Input<any>) {
|
|
237
|
+
input.context.logged = true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
231
241
|
@Controller('/secure')
|
|
242
|
+
@UseMiddleware(LoggerMiddleware)
|
|
232
243
|
class SecureController {
|
|
233
244
|
@Get()
|
|
234
245
|
@UseMiddleware(AuthMiddleware)
|
|
@@ -332,53 +343,65 @@ class CreatePhotoUseCase extends UseCase<void, void> {
|
|
|
332
343
|
|
|
333
344
|
### Entity e Model
|
|
334
345
|
|
|
335
|
-
Entities sao dominio puro.
|
|
346
|
+
Entities sao dominio puro. `Model` vive na borda e faz o mapeamento banco <-> model, alem de converter `Entity` <-> `Model`. Repositorios trabalham com `Model`, nao com `Entity`.
|
|
336
347
|
|
|
337
348
|
```ts
|
|
338
349
|
import { Entity, Model, model, column } from './src';
|
|
339
350
|
|
|
340
|
-
|
|
341
|
-
private readonly id: string;
|
|
342
|
-
private readonly name: string;
|
|
343
|
-
private readonly amount: number;
|
|
344
|
-
|
|
345
|
-
constructor(id: string, name: string, amount: number) {
|
|
346
|
-
super();
|
|
347
|
-
this.id = id;
|
|
348
|
-
this.name = name;
|
|
349
|
-
this.amount = amount;
|
|
350
|
-
this.generateGetters();
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
type OrderTable = 'orders';
|
|
351
|
+
type UserTable = 'users';
|
|
355
352
|
|
|
356
|
-
@model<
|
|
357
|
-
class
|
|
353
|
+
@model<UserTable>('users')
|
|
354
|
+
class UserModel extends Model<UserTable, User> {
|
|
358
355
|
@column('id')
|
|
359
356
|
id!: string;
|
|
360
357
|
|
|
361
|
-
@column('
|
|
358
|
+
@column('email2')
|
|
359
|
+
email!: string;
|
|
360
|
+
|
|
362
361
|
name!: string;
|
|
362
|
+
password?: string;
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
|
|
364
|
+
fromEntity(user: User): this {
|
|
365
|
+
this.id = user.getId();
|
|
366
|
+
this.email = user.getEmail();
|
|
367
|
+
this.name = user.getName();
|
|
368
|
+
return this;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
toEntity(): User {
|
|
372
|
+
return new User(this);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
366
375
|
|
|
367
|
-
|
|
376
|
+
class User extends Entity {
|
|
377
|
+
private readonly id: string;
|
|
378
|
+
private readonly email: string;
|
|
379
|
+
private readonly name: string;
|
|
380
|
+
|
|
381
|
+
constructor(model: UserModel) {
|
|
368
382
|
super();
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
383
|
+
this.id = model.id;
|
|
384
|
+
this.email = model.email;
|
|
385
|
+
this.name = model.name;
|
|
386
|
+
this.generateGetters();
|
|
374
387
|
}
|
|
375
388
|
}
|
|
376
389
|
```
|
|
377
390
|
|
|
391
|
+
Carregando do banco:
|
|
392
|
+
|
|
393
|
+
```ts
|
|
394
|
+
const row = result[0] ?? null;
|
|
395
|
+
const model = row ? new UserModel().fromModel(row) : null;
|
|
396
|
+
return Optional.ofNullable(model);
|
|
397
|
+
```
|
|
398
|
+
|
|
378
399
|
Regras principais:
|
|
379
400
|
|
|
380
401
|
- `Model` guarda metadados de coluna (via `@column`) e nome da tabela (via `@model`)
|
|
381
|
-
-
|
|
402
|
+
- `fromModel` aplica o mapeamento coluna -> propriedade e ignora `null/undefined` (retorna o proprio model)
|
|
403
|
+
- `fromEntity` / `toEntity` fazem a conversao entity <-> model
|
|
404
|
+
- `Entity` recebe o `Model` no construtor (acoplamento forte na borda)
|
|
382
405
|
- `generateGetters()` cria getters para campos (ex.: `getName`, `isActive`, `hasProfile`), mesmo quando o valor não foi definido.
|
|
383
406
|
|
|
384
407
|
### Storage Gateway
|
|
@@ -470,16 +493,40 @@ Quando um erro e lancado, o handler padroniza a resposta. Erros de dominio (`App
|
|
|
470
493
|
|
|
471
494
|
Interfaces tipadas para padrao de repositorio:
|
|
472
495
|
|
|
473
|
-
- `
|
|
474
|
-
- `
|
|
496
|
+
- `Optional<T>` (helper inspirado em micronaut/spring)
|
|
497
|
+
- `RepositoryModel` (base para o acoplamento do repositorio com Model)
|
|
498
|
+
- `RepositoryCreate<T extends RepositoryModel>`
|
|
499
|
+
- `RepositoryUpdate<T extends RepositoryModel>`
|
|
475
500
|
- `RepositoryRemove`
|
|
476
|
-
- `RepositoryRestore<T extends
|
|
501
|
+
- `RepositoryRestore<T extends RepositoryModel>`
|
|
477
502
|
- `RepositoryRemoveBy<T>`
|
|
478
503
|
- `RepositoryRestoreBy<T>`
|
|
479
504
|
- `RepositoryExistsBy<T>`
|
|
480
505
|
- `RepositoryNotExistsBy<T>`
|
|
481
506
|
- `RepositoryPagination<T>`
|
|
482
507
|
|
|
508
|
+
`RepositoryRestore` e `RepositoryRestoreBy` retornam `Optional<T>` para desacoplar a mensagem de erro do repositório:
|
|
509
|
+
|
|
510
|
+
```ts
|
|
511
|
+
import { Optional } from './src';
|
|
512
|
+
|
|
513
|
+
class UserRepository {
|
|
514
|
+
async restore(id: string): Promise<Optional<UserModel>> {
|
|
515
|
+
const result = await this.orm
|
|
516
|
+
.select()
|
|
517
|
+
.from(userTable)
|
|
518
|
+
.where(eq(userTable.id, id));
|
|
519
|
+
|
|
520
|
+
const row = result[0] ?? null;
|
|
521
|
+
const model = row ? new UserModel().fromModel(row) : null;
|
|
522
|
+
return Optional.ofNullable(model);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
const user = await repo.restore('1').orElseThrow('Usuario nao encontrado');
|
|
527
|
+
const userByEmail = await repo.restoreByEmail('a@b.com').orElseNull();
|
|
528
|
+
```
|
|
529
|
+
|
|
483
530
|
## Exemplos
|
|
484
531
|
|
|
485
532
|
### Express
|
|
@@ -31,8 +31,8 @@ export declare function Controller(basePath?: string): (target: any) => void;
|
|
|
31
31
|
export declare function Tracing<R>(tracer: Tracer<R>): (target: any, propertyKey?: string) => void;
|
|
32
32
|
export declare function Version(version: number): (target: any, propertyKey?: string) => void;
|
|
33
33
|
export declare function PresetIgnore(ignorePrefix?: boolean, ignoreVersion?: boolean): (target: any, propertyKey?: string) => void;
|
|
34
|
-
export declare function UseMiddleware(middlewareClass: MiddlewareDefinition): (target: any, propertyKey
|
|
35
|
-
export declare function UseMiddlewares(middlewareClasses: MiddlewareDefinition[]): (target: any, propertyKey
|
|
34
|
+
export declare function UseMiddleware(middlewareClass: MiddlewareDefinition): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
|
|
35
|
+
export declare function UseMiddlewares(middlewareClasses: MiddlewareDefinition[]): (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) => void;
|
|
36
36
|
export declare function Post(config?: {
|
|
37
37
|
path?: string;
|
|
38
38
|
statusCode?: number;
|
|
@@ -52,15 +52,31 @@ export function UseMiddleware(middlewareClass) {
|
|
|
52
52
|
if (typeof middlewareClass === 'function' && isClass(middlewareClass) && !middlewareClass.prototype?.execute) {
|
|
53
53
|
throw new FrameworkError('Middleware must implement execute()');
|
|
54
54
|
}
|
|
55
|
+
const metadataTarget = propertyKey ? target : target;
|
|
56
|
+
const metadataKey = propertyKey ?? undefined;
|
|
55
57
|
if (typeof middlewareClass === 'function' && middlewareClass.prototype?.execute) {
|
|
56
|
-
const middlewares =
|
|
58
|
+
const middlewares = metadataKey
|
|
59
|
+
? Reflect.getMetadata('middlewares', metadataTarget, metadataKey) || []
|
|
60
|
+
: Reflect.getMetadata('middlewares', metadataTarget) || [];
|
|
57
61
|
middlewares.push(middlewareClass);
|
|
58
|
-
|
|
62
|
+
if (metadataKey) {
|
|
63
|
+
Reflect.defineMetadata('middlewares', middlewares, metadataTarget, metadataKey);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
Reflect.defineMetadata('middlewares', middlewares, metadataTarget);
|
|
67
|
+
}
|
|
59
68
|
return;
|
|
60
69
|
}
|
|
61
|
-
const middlewares =
|
|
70
|
+
const middlewares = metadataKey
|
|
71
|
+
? Reflect.getMetadata('middlewares', metadataTarget, metadataKey) || []
|
|
72
|
+
: Reflect.getMetadata('middlewares', metadataTarget) || [];
|
|
62
73
|
middlewares.push(middlewareClass);
|
|
63
|
-
|
|
74
|
+
if (metadataKey) {
|
|
75
|
+
Reflect.defineMetadata('middlewares', middlewares, metadataTarget, metadataKey);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
Reflect.defineMetadata('middlewares', middlewares, metadataTarget);
|
|
79
|
+
}
|
|
64
80
|
};
|
|
65
81
|
}
|
|
66
82
|
export function UseMiddlewares(middlewareClasses) {
|
|
@@ -73,9 +89,18 @@ export function UseMiddlewares(middlewareClasses) {
|
|
|
73
89
|
throw new FrameworkError('Middleware must implement execute()');
|
|
74
90
|
}
|
|
75
91
|
}
|
|
76
|
-
const
|
|
92
|
+
const metadataTarget = propertyKey ? target : target;
|
|
93
|
+
const metadataKey = propertyKey ?? undefined;
|
|
94
|
+
const existingMiddlewares = metadataKey
|
|
95
|
+
? Reflect.getMetadata('middlewares', metadataTarget, metadataKey) || []
|
|
96
|
+
: Reflect.getMetadata('middlewares', metadataTarget) || [];
|
|
77
97
|
existingMiddlewares.push(...middlewareClasses);
|
|
78
|
-
|
|
98
|
+
if (metadataKey) {
|
|
99
|
+
Reflect.defineMetadata('middlewares', existingMiddlewares, metadataTarget, metadataKey);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
Reflect.defineMetadata('middlewares', existingMiddlewares, metadataTarget);
|
|
103
|
+
}
|
|
79
104
|
};
|
|
80
105
|
}
|
|
81
106
|
export function Post(config = {}) {
|
package/dist/domain/index.d.ts
CHANGED
package/dist/domain/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type OptionalError = Error | string | (() => Error);
|
|
2
|
+
export declare class Optional<T> {
|
|
3
|
+
private readonly value;
|
|
4
|
+
private constructor();
|
|
5
|
+
static of<T>(value: T): Optional<T>;
|
|
6
|
+
static ofNullable<T>(value: T | null | undefined): Optional<T>;
|
|
7
|
+
isPresent(): boolean;
|
|
8
|
+
isEmpty(): boolean;
|
|
9
|
+
get(): T;
|
|
10
|
+
orElseNull(): T | null;
|
|
11
|
+
orElseUndefined(): T | undefined;
|
|
12
|
+
orElseThrow(error?: OptionalError): T;
|
|
13
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export class Optional {
|
|
2
|
+
constructor(value) {
|
|
3
|
+
this.value = value;
|
|
4
|
+
}
|
|
5
|
+
static of(value) {
|
|
6
|
+
if (value === null || value === undefined) {
|
|
7
|
+
throw new Error('Optional.of() cannot be null or undefined');
|
|
8
|
+
}
|
|
9
|
+
return new Optional(value);
|
|
10
|
+
}
|
|
11
|
+
static ofNullable(value) {
|
|
12
|
+
return new Optional(value);
|
|
13
|
+
}
|
|
14
|
+
isPresent() {
|
|
15
|
+
return this.value !== null && this.value !== undefined;
|
|
16
|
+
}
|
|
17
|
+
isEmpty() {
|
|
18
|
+
return !this.isPresent();
|
|
19
|
+
}
|
|
20
|
+
get() {
|
|
21
|
+
if (!this.isPresent()) {
|
|
22
|
+
throw new Error('Optional is empty');
|
|
23
|
+
}
|
|
24
|
+
return this.value;
|
|
25
|
+
}
|
|
26
|
+
orElseNull() {
|
|
27
|
+
return this.isPresent() ? this.value : null;
|
|
28
|
+
}
|
|
29
|
+
orElseUndefined() {
|
|
30
|
+
return this.isPresent() ? this.value : undefined;
|
|
31
|
+
}
|
|
32
|
+
orElseThrow(error) {
|
|
33
|
+
if (this.isPresent()) {
|
|
34
|
+
return this.value;
|
|
35
|
+
}
|
|
36
|
+
if (typeof error === 'function') {
|
|
37
|
+
throw error();
|
|
38
|
+
}
|
|
39
|
+
if (typeof error === 'string') {
|
|
40
|
+
throw new Error(error);
|
|
41
|
+
}
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
throw new Error('Optional is empty');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -98,10 +98,12 @@ export default class ControllerHandler {
|
|
|
98
98
|
let tracer = Reflect.getMetadata('tracer', controller) || null;
|
|
99
99
|
const controllerVersion = Reflect.getMetadata('version', controller);
|
|
100
100
|
const controllerPresetIgnore = Reflect.getMetadata('presetIgnore', controller);
|
|
101
|
+
const controllerMiddlewares = Reflect.getMetadata('middlewares', controller) || [];
|
|
101
102
|
const instance = new controller();
|
|
102
103
|
for (const methodName of methodNames) {
|
|
103
104
|
const routeConfig = Reflect.getMetadata('route', controller.prototype, methodName);
|
|
104
|
-
const
|
|
105
|
+
const methodMiddlewares = Reflect.getMetadata('middlewares', controller.prototype, methodName) || [];
|
|
106
|
+
const middlewares = [...controllerMiddlewares, ...methodMiddlewares];
|
|
105
107
|
const responseType = Reflect.getMetadata('responseType', controller.prototype, methodName) || 'json';
|
|
106
108
|
tracer = Reflect.getMetadata('tracer', controller.prototype, methodName) || tracer;
|
|
107
109
|
const methodVersion = Reflect.getMetadata('version', controller.prototype, methodName);
|
|
@@ -128,7 +130,7 @@ export default class ControllerHandler {
|
|
|
128
130
|
tracer
|
|
129
131
|
},
|
|
130
132
|
responseType,
|
|
131
|
-
middlewares: middlewares ? middlewares.map(middleware => this.resolveMiddleware(middleware)) : [],
|
|
133
|
+
middlewares: middlewares.length ? middlewares.map(middleware => this.resolveMiddleware(middleware)) : [],
|
|
132
134
|
});
|
|
133
135
|
}
|
|
134
136
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ import { Container, DefaultContainer, Inject, setDefaultContainer } from './infr
|
|
|
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
|
+
import { Optional } from './domain/optional';
|
|
6
7
|
import type { ValidatorDefinition } from './interface/validation/validator';
|
|
7
8
|
import type { StorageGateway, Event, EventPayload } from './application';
|
|
9
|
+
import { RepositoryModel } from './protocols/model';
|
|
8
10
|
import type { RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryExistsBy, RepositoryRestore, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination } from './protocols/repository';
|
|
9
|
-
export { Controller, Post, Get, Put, Delete, Patch, Input, Version, PresetIgnore, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Transform, Model, model, column, UseCase, DecorateUseCase, Hook, BeforeHook, AfterHook, HookBefore, HookAfter, 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 };
|
|
11
|
+
export { Controller, Post, Get, Put, Delete, Patch, Input, Version, PresetIgnore, Middleware, UseMiddleware, UseMiddlewares, Tracer, Tracing, TracerData, Entity, Restrict, VirtualProperty, GetterPrefix, Transform, Model, model, column, UseCase, DecorateUseCase, Hook, BeforeHook, AfterHook, HookBefore, HookAfter, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, Options, Register, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError, Optional, RepositoryModel, RepositoryCreate, RepositoryUpdate, RepositoryRemove, RepositoryRemoveBy, RepositoryRestore, RepositoryExistsBy, RepositoryRestoreBy, RepositoryNotExistsBy, RepositoryPagination };
|
|
10
12
|
export type { ValidatorDefinition, StorageGateway, Event, EventPayload };
|
package/dist/index.js
CHANGED
|
@@ -16,4 +16,6 @@ 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
|
-
|
|
19
|
+
import { Optional } from './domain/optional';
|
|
20
|
+
import { RepositoryModel } from './protocols/model';
|
|
21
|
+
export { Controller, Post, Get, Put, Delete, Patch, Version, PresetIgnore, UseMiddleware, UseMiddlewares, Tracing, Entity, Restrict, VirtualProperty, GetterPrefix, Transform, Model, model, column, UseCase, DecorateUseCase, Hook, BeforeHook, AfterHook, HookBefore, HookAfter, Storage, CacheGateway, EventDispatcher, Inject, Container, DefaultContainer, setDefaultContainer, Dede, ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest, InternalServerError, CustomServerError, AppError, Optional, RepositoryModel };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RepositoryModel } from "../../protocols/model";
|
|
2
2
|
export type ColumnDefinition = {
|
|
3
3
|
column: string;
|
|
4
4
|
property: string;
|
|
5
5
|
};
|
|
6
|
-
export declare abstract class Model<TTable = string> {
|
|
6
|
+
export declare abstract class Model<TTable = string, TEntity = any> extends RepositoryModel<TEntity> {
|
|
7
7
|
table: TTable;
|
|
8
8
|
columns: ColumnDefinition[];
|
|
9
9
|
[property: string]: any;
|
|
10
|
-
fromModel(input: Record<string, any>):
|
|
11
|
-
abstract fromEntity(entity:
|
|
10
|
+
fromModel(input: Record<string, any> | null | undefined): this;
|
|
11
|
+
abstract fromEntity(entity: TEntity): this;
|
|
12
12
|
toModel(): Record<string, any>;
|
|
13
|
-
abstract toEntity():
|
|
13
|
+
abstract toEntity(): TEntity;
|
|
14
14
|
}
|
|
15
15
|
export declare function model<TTable>(table: TTable): (target: any) => void;
|
|
16
16
|
export declare function column(columnName: string): (target: any, propertyKey: string) => void;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { RepositoryModel } from "../../protocols/model";
|
|
2
|
+
export class Model extends RepositoryModel {
|
|
2
3
|
fromModel(input) {
|
|
4
|
+
if (input === null || input === undefined) {
|
|
5
|
+
return this;
|
|
6
|
+
}
|
|
3
7
|
const columns = this.columns ?? [];
|
|
4
8
|
const columnByName = new Map(columns.map((column) => [column.column, column.property]));
|
|
5
9
|
for (const [property, value] of Object.entries(input)) {
|
|
@@ -5,4 +5,4 @@ export type ValidationErrorOptions = {
|
|
|
5
5
|
errorName?: string;
|
|
6
6
|
validatorOptions?: ValidatorOptions;
|
|
7
7
|
};
|
|
8
|
-
export declare function validateWithClassValidator<T extends object>(dtoClass: new () => T, input:
|
|
8
|
+
export declare function validateWithClassValidator<T extends object>(dtoClass: new () => T, input: Record<string, any>, options?: ValidationErrorOptions): Promise<T & Record<string, any>>;
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Optional } from "../domain";
|
|
2
|
+
import { RepositoryModel } from "../protocols/model";
|
|
3
|
+
export interface RepositoryCreate<T extends RepositoryModel> {
|
|
3
4
|
create(input: T): Promise<void>;
|
|
4
5
|
}
|
|
5
|
-
export interface RepositoryUpdate<T extends
|
|
6
|
+
export interface RepositoryUpdate<T extends RepositoryModel> {
|
|
6
7
|
update(input: T): Promise<void>;
|
|
7
8
|
}
|
|
8
9
|
export interface RepositoryRemove {
|
|
9
10
|
remove(id: string | number): Promise<void>;
|
|
10
11
|
}
|
|
11
|
-
export interface RepositoryRestore<T extends
|
|
12
|
-
restore(id: string | number): Promise<T
|
|
12
|
+
export interface RepositoryRestore<T extends RepositoryModel> {
|
|
13
|
+
restore(id: string | number): Promise<Optional<T>>;
|
|
13
14
|
}
|
|
14
15
|
export type RepositoryRemoveBy<T> = {
|
|
15
16
|
[K in keyof T & string as `removeBy${Capitalize<K>}`]: (value: T[K]) => Promise<void>;
|
|
16
17
|
};
|
|
17
18
|
export type RepositoryRestoreBy<T> = {
|
|
18
|
-
[K in keyof T & string as `restoreBy${Capitalize<K>}`]: (value: T[K]) => Promise<
|
|
19
|
+
[K in keyof T & string as `restoreBy${Capitalize<K>}`]: (value: T[K]) => Promise<Optional<T>>;
|
|
19
20
|
};
|
|
20
21
|
export type RepositoryExistsBy<T> = {
|
|
21
22
|
[K in keyof T & string as `existsBy${Capitalize<K>}`]: (value: T[K]) => Promise<boolean>;
|