-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: domain & usecases implementation / project folder structure
- Loading branch information
1 parent
3a7f7e6
commit ac0b870
Showing
125 changed files
with
3,731 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"extends": "@rocketseat/eslint-config/node", | ||
"rules": { | ||
"no-useless-constructor": "off" | ||
} | ||
} | ||
"extends": "@rocketseat/eslint-config/node", | ||
"rules": { | ||
"no-useless-constructor": "off", | ||
"no-new": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Either, left, right } from '@/core/either' | ||
|
||
function doSomeThing(shouldSuccess: boolean): Either<string, number> { | ||
if (shouldSuccess) { | ||
return right(10) | ||
} else { | ||
return left('error') | ||
} | ||
} | ||
|
||
test('success result', () => { | ||
const result = doSomeThing(true) | ||
|
||
expect(result.isRight()).toBe(true) | ||
expect(result.isLeft()).toBe(false) | ||
}) | ||
|
||
test('error result', () => { | ||
const result = doSomeThing(false) | ||
|
||
expect(result.isLeft()).toBe(true) | ||
expect(result.isRight()).toBe(false) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Error | ||
export class Left<L, R> { | ||
readonly value: L | ||
|
||
constructor(value: L) { | ||
this.value = value | ||
} | ||
|
||
isRight(): this is Right<L, R> { | ||
return false | ||
} | ||
|
||
isLeft(): this is Left<L, R> { | ||
return true | ||
} | ||
} | ||
|
||
// Success | ||
export class Right<L, R> { | ||
readonly value: R | ||
|
||
constructor(value: R) { | ||
this.value = value | ||
} | ||
|
||
isRight(): this is Right<L, R> { | ||
return true | ||
} | ||
|
||
isLeft(): this is Left<L, R> { | ||
return false | ||
} | ||
} | ||
|
||
export type Either<L, R> = Left<L, R> | Right<L, R> | ||
|
||
export const left = <L, R>(value: L): Either<L, R> => { | ||
return new Left(value) | ||
} | ||
|
||
export const right = <L, R>(value: R): Either<L, R> => { | ||
return new Right(value) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { DomainEvents } from '@/core/events/domain-events' | ||
import { DomainEvent } from '../events/domain-event' | ||
import { Entity } from './entity' | ||
|
||
export abstract class AggregateRoot<Props> extends Entity<Props> { | ||
private _domainEvents: DomainEvent[] = [] | ||
|
||
get domainEvents(): DomainEvent[] { | ||
return this._domainEvents | ||
} | ||
|
||
protected addDomainEvent(domainEvent: DomainEvent): void { | ||
this._domainEvents.push(domainEvent) | ||
DomainEvents.markAggregateForDispatch(this) | ||
} | ||
|
||
public clearEvents() { | ||
this._domainEvents = [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { UniqueEntityID } from './unique-entity-id' | ||
|
||
export abstract class Entity<Props> { | ||
private _id: UniqueEntityID | ||
protected props: Props | ||
|
||
get id() { | ||
return this._id | ||
} | ||
|
||
protected constructor(props: Props, id?: UniqueEntityID) { | ||
this.props = props | ||
this._id = id ?? new UniqueEntityID() | ||
} | ||
|
||
public equals(entity: Entity<unknown>) { | ||
if (entity === this) { | ||
return true | ||
} | ||
|
||
if (entity.id === this._id) { | ||
return true | ||
} | ||
|
||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { randomUUID } from 'node:crypto' | ||
|
||
export class UniqueEntityID { | ||
private value: string | ||
|
||
toString() { | ||
return this.value | ||
} | ||
|
||
toValue() { | ||
return this.value | ||
} | ||
|
||
constructor(value?: string) { | ||
this.value = value ?? randomUUID() | ||
} | ||
|
||
public equals(id: UniqueEntityID) { | ||
return id.toValue() === this.value | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { WatchedList } from '@/core/entities/watched-list' | ||
|
||
class NumberWatchedList extends WatchedList<number> { | ||
compareItems(a: number, b: number): boolean { | ||
return a === b | ||
} | ||
} | ||
|
||
describe('watched list', () => { | ||
it('should be able to create a watched list with initial items', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
expect(list.currentItems).toHaveLength(3) | ||
}) | ||
|
||
it('should be able to add new items to the list', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
list.add(4) | ||
|
||
expect(list.currentItems).toHaveLength(4) | ||
expect(list.getNewItems()).toEqual([4]) | ||
}) | ||
|
||
it('should be able to remove items from the list', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
list.remove(2) | ||
|
||
expect(list.currentItems).toHaveLength(2) | ||
expect(list.getRemovedItems()).toEqual([2]) | ||
}) | ||
|
||
it('should be able to add an item even if it was removed before', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
list.remove(2) | ||
list.add(2) | ||
|
||
expect(list.currentItems).toHaveLength(3) | ||
|
||
expect(list.getRemovedItems()).toEqual([]) | ||
expect(list.getNewItems()).toEqual([]) | ||
}) | ||
|
||
it('should be able to remove an item even if it was added before', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
list.add(4) | ||
list.remove(4) | ||
|
||
expect(list.currentItems).toHaveLength(3) | ||
|
||
expect(list.getRemovedItems()).toEqual([]) | ||
expect(list.getNewItems()).toEqual([]) | ||
}) | ||
|
||
it('should be able to update watched list items', () => { | ||
const list = new NumberWatchedList([1, 2, 3]) | ||
|
||
list.update([1, 3, 5]) | ||
|
||
expect(list.getRemovedItems()).toEqual([2]) | ||
expect(list.getNewItems()).toEqual([5]) | ||
}) | ||
}) |
Oops, something went wrong.