Last active
May 24, 2021 08:52
-
-
Save patroza/8f2d634b23e6efa01a244e9067bfe249 to your computer and use it in GitHub Desktop.
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
// 3. Presentation/Root | |
const start = () => { | |
const getCompletedTodosRequestHandler = async (ctx) => { | |
const result = await getCompletedTodosResolved(ctx.params.id) | |
ctx.body = JSON.stringify(result) | |
} | |
const completeTodoRequestHandler = async (ctx) => { | |
await completeTodoResolved(ctx.params.id) | |
ctx.status = 204 | |
} | |
const url = "some-url" | |
const getTodoApiResolved = getTodoApi(url) | |
const getTodosApiResolved = getTodosApi(url) | |
const saveTodoResolved = saveTodoApi(url) | |
const getCompletedTodosResolved = getCompletedTodos(getTodosApiResolved) | |
const completeTodoResolved = completeTodo(getTodoApiResolved, saveTodoResolved) | |
app.get("/users/:id/todos", getCompletedTodosRequestHandler) | |
app.post("/todos/:id/complete", completeTodoRequestHandler) | |
app.listen(3000) | |
} | |
//start() | |
// 3. Infra | |
let todoStubs = [ | |
{ id: 1, title: "Test", isCompleted: false, updatedAt: new Date(2020, 1, 1)}, | |
{ id: 2, title: "Test 2", isCompleted: true, updatedAt: new Date(2020, 1, 1)}, | |
] | |
const getTodosApi = (url: string) => async function (userId: number): Promise<Todo[]> { | |
return todoStubs | |
} | |
const getTodoApi = (url: string) => async function (todoId: number): Promise<Todo | undefined> { | |
return todoStubs.find(x => x.id === todoId) | |
} | |
const saveTodoApi = (url: string) => async function (todo: Todo): Promise<void> { | |
todoStubs = todoStubs.filter(x => x.id === todo.id).concat([todo]) | |
} | |
// 2. Application | |
const getCompletedTodos = (getTodos: ReturnType<typeof getTodosApi>) => | |
async function (userId: number): Promise<TodoView> { | |
const allTodos = await getTodos(userId) | |
const completedTodos = allTodos.filter(x => x.isCompleted) | |
return { | |
items: completedTodos, | |
userId, | |
} | |
} | |
const completeTodo = (getTodo: ReturnType<typeof getTodoApi>, saveTodo: ReturnType<typeof saveTodoApi>) => | |
async function (todoId: number): Promise<void> { | |
const todo = await getTodo(todoId) | |
const updatedTodo = complete(todo, new Date()) | |
await saveTodo(updatedTodo) | |
} | |
type TodoView = { | |
items: Todo[] | |
userId: number | |
} | |
// 1. Domain | |
type Todo = { | |
readonly id: number | |
readonly title: string | |
readonly isCompleted: boolean | |
readonly updatedAt: Date | |
} | |
const complete = (todo: Todo, currentDate: Date) => { | |
if (todo.isCompleted) { | |
throw new Error("already completed") | |
} | |
return { | |
...todo, | |
isCompleted: true, | |
updatedAt: currentDate, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment