diff --git a/server/api/auth/validate_token/.get.ts b/server/api/auth/validate_token/.get.ts index 6ccd80c..fcffdc2 100644 --- a/server/api/auth/validate_token/.get.ts +++ b/server/api/auth/validate_token/.get.ts @@ -21,7 +21,7 @@ export default defineEventHandler(async (event): Promise => { success: true, }; } catch (err) { - console.log(err); + console.warn(err); return { success: false, diff --git a/server/api/tags/.get.ts b/server/api/tags/.get.ts index 1fe52f0..ca13143 100644 --- a/server/api/tags/.get.ts +++ b/server/api/tags/.get.ts @@ -1,9 +1,8 @@ import type { Tag } from "~~/shared/types"; import { H3Error } from "h3"; -import { getTags } from "~~/server/utils/tags"; export default defineEventHandler(async (): Promise => { - const tags = await getTags(); + const tags = await Tags.getAll(); if (tags instanceof H3Error) throw tags; return tags; diff --git a/server/api/tags/.post.ts b/server/api/tags/.post.ts index 4bf6da7..4cb7173 100644 --- a/server/api/tags/.post.ts +++ b/server/api/tags/.post.ts @@ -1,5 +1,4 @@ import { H3Error } from "h3"; -import { updateOrAddTag } from "~~/server/utils/tags"; import { TagSchema, type Tag } from "~~/shared/types"; export default defineEventHandler(async (event): Promise => { @@ -7,9 +6,9 @@ export default defineEventHandler(async (event): Promise => { return TagSchema.parse(data) as Tag; }); - const tag = await updateOrAddTag(newTag); + const tag = await Tags.updateOrAdd(newTag); if (tag instanceof H3Error) throw tag; - sendTagsUpdate(); + TagEventStream.sendUpdate(); return tag; }); diff --git a/server/api/tags/[uuid].delete.ts b/server/api/tags/[uuid].delete.ts index 66ff662..fab39b4 100644 --- a/server/api/tags/[uuid].delete.ts +++ b/server/api/tags/[uuid].delete.ts @@ -1,5 +1,4 @@ import { H3Error } from "h3"; -import { deleteTag } from "~~/server/utils/tags"; import type { Tag, UUID } from "~~/shared/types"; export default defineEventHandler(async (event): Promise => { @@ -12,9 +11,9 @@ export default defineEventHandler(async (event): Promise => { message: `no uuid set - uuid:'${uuid}'`, }); - const tag = await deleteTag(uuid); + const tag = await Tags.delete(uuid); if (tag instanceof H3Error) throw tag; - sendTagsUpdate(); + TagEventStream.sendUpdate(); return tag; }); diff --git a/server/api/tags/sse.ts b/server/api/tags/sse.ts index 9f35c35..7e46606 100644 --- a/server/api/tags/sse.ts +++ b/server/api/tags/sse.ts @@ -1,9 +1,7 @@ -import { addTagEventStream } from "~~/server/utils/sse"; - export default defineEventHandler(async (event) => { const eventStream = createEventStream(event); - addTagEventStream(eventStream); + TagEventStream.addStream(eventStream); return eventStream.send(); }); diff --git a/server/api/todos/.get.ts b/server/api/todos/.get.ts index 01301a2..850d10d 100644 --- a/server/api/todos/.get.ts +++ b/server/api/todos/.get.ts @@ -2,7 +2,7 @@ import type { Todo } from "~~/shared/types"; import { H3Error } from "h3"; export default defineEventHandler(async (): Promise => { - const todos = await getTodos(); + const todos = await Todos.getAll(); if (todos instanceof H3Error) throw todos; return todos; diff --git a/server/api/todos/.post.ts b/server/api/todos/.post.ts index c165788..c4c1a2d 100644 --- a/server/api/todos/.post.ts +++ b/server/api/todos/.post.ts @@ -6,9 +6,9 @@ export default defineEventHandler(async (event): Promise => { return TodoSchema.parse(data) as Todo; }); - const todo = await updateOrAddTodo(newTodo); + const todo = await Todos.updateOrAdd(newTodo); if (todo instanceof H3Error) throw todo; - sendTodoUpdate(); + TodoEventStream.sendUpdate(); return todo; }); diff --git a/server/api/todos/[uuid].delete.ts b/server/api/todos/[uuid].delete.ts index 313045a..61a8260 100644 --- a/server/api/todos/[uuid].delete.ts +++ b/server/api/todos/[uuid].delete.ts @@ -11,9 +11,9 @@ export default defineEventHandler(async (event): Promise => { message: `no uuid set - uuid:'${uuid}'`, }); - const todo = await deleteTodo(uuid); + const todo = await Todos.delete(uuid); if (todo instanceof H3Error) throw todo; - sendTodoUpdate(); + TodoEventStream.sendUpdate(); return todo; }); diff --git a/server/api/todos/move.post.ts b/server/api/todos/move.post.ts index 547fd20..cde7837 100644 --- a/server/api/todos/move.post.ts +++ b/server/api/todos/move.post.ts @@ -1,5 +1,4 @@ import { H3Error } from "h3"; -import { moveTodo } from "~~/server/utils/todos"; import type { UUID } from "~~/shared/types"; export type moveTodoBody = { @@ -18,8 +17,8 @@ export default defineEventHandler(async (event) => { }); }); - const todo = await moveTodo(body.toMove, body.to); + const todo = await Todos.move(body.toMove, body.to); if (todo instanceof H3Error) throw todo; - sendTodoUpdate(); + TodoEventStream.sendUpdate(); }); diff --git a/server/api/todos/sse.ts b/server/api/todos/sse.ts index 045da3a..54ae61d 100644 --- a/server/api/todos/sse.ts +++ b/server/api/todos/sse.ts @@ -1,7 +1,7 @@ export default defineEventHandler(async (event) => { const eventStream = createEventStream(event); - addTodoEventStream(eventStream); + TodoEventStream.addStream(eventStream); return eventStream.send(); }); diff --git a/server/plugins/database.ts b/server/plugins/database.ts index b2cffa9..1b5c1de 100644 --- a/server/plugins/database.ts +++ b/server/plugins/database.ts @@ -1,5 +1,5 @@ -import { TAGS_KEY } from "../utils/tags"; -import { TODOS_KEY } from "../utils/todos"; +import { TAGS_KEY } from "../utils/db/tags"; +import { TODOS_KEY } from "../utils/db/todos"; import { getTestTags, getTestTodos } from "../utils/testData"; export default defineNitroPlugin(async () => { diff --git a/server/utils/db/tags.ts b/server/utils/db/tags.ts new file mode 100644 index 0000000..b4904a7 --- /dev/null +++ b/server/utils/db/tags.ts @@ -0,0 +1,58 @@ +import { H3Error } from "h3"; +import type { Tag, UUID } from "~~/shared/types"; + +export const TAGS_KEY = "tags"; + +export const Tags = { + KEY: "tags", + async getAll(): Promise { + const storage = useStorage(); + const tags = await storage.get(TAGS_KEY); + + if (!tags) + return createError({ + status: 500, + statusMessage: "Internal Server Error", + message: `no tags found`, + }); + + return tags; + }, + async updateOrAdd(tag: Tag): Promise { + const storage = useStorage(); + const tags = await Tags.getAll(); + + if (tags instanceof H3Error) return tags; + + const index = tags.findIndex((value) => value.uuid === tag.uuid); + + if (index === -1) { + tags.unshift(tag); + } else { + tags[index] = tag; + } + + await storage.set(TAGS_KEY, tags); + + return tag; + }, + async delete(uuid: UUID): Promise { + const storage = useStorage(); + const tags = await Tags.getAll(); + + if (tags instanceof H3Error) return tags; + + const index = tags.findIndex((value) => value.uuid === uuid); + if (index == -1) + return createError({ + status: 404, + statusMessage: "Not Found", + message: `Tag with with uuid ${uuid} not found`, + }); + + const todo = tags.splice(index, 1)[0]!; + await storage.set(TAGS_KEY, tags); + + return todo; + }, +}; diff --git a/server/utils/db/todos.ts b/server/utils/db/todos.ts new file mode 100644 index 0000000..11d7e39 --- /dev/null +++ b/server/utils/db/todos.ts @@ -0,0 +1,81 @@ +import { H3Error } from "h3"; +import type { Todo, UUID } from "~~/shared/types"; + +export const TODOS_KEY = "todos"; + +export const Todos = { + async getAll(): Promise { + const storage = useStorage(); + const todos = await storage.get(TODOS_KEY); + + if (!todos) + return createError({ + status: 500, + statusMessage: "Internal Server Error", + message: `no todos found`, + }); + + return todos; + }, + + async move(toMove: UUID, to: UUID): Promise { + const storage = useStorage(); + const todos = await Todos.getAll(); + + if (todos instanceof H3Error) return todos; + + const targetIndex = todos.findIndex((todo) => todo.uuid == to); + const movedIndex = todos.findIndex((todo) => todo.uuid == toMove); + + if (targetIndex === -1 || movedIndex === -1) + return createError({ + status: 404, + statusMessage: "Not Found", + message: `todo not found`, + }); + + const moved = todos.splice(movedIndex, 1)[0]!; + todos.splice(targetIndex, 0, moved); + + await storage.set(TODOS_KEY, todos); + }, + + async updateOrAdd(todo: Todo): Promise { + const storage = useStorage(); + const todos = await Todos.getAll(); + + if (todos instanceof H3Error) return todos; + + const index = todos.findIndex((value) => value.uuid === todo.uuid); + + if (index === -1) { + todos.push(todo); + } else { + todos[index] = todo; + } + + await storage.set(TODOS_KEY, todos); + + return todo; + }, + + async delete(uuid: UUID): Promise { + const storage = useStorage(); + const todos = await Todos.getAll(); + + if (todos instanceof H3Error) return todos; + + const index = todos.findIndex((value) => value.uuid === uuid); + if (index == -1) + return createError({ + status: 404, + statusMessage: "Not Found", + message: `Todo with with uuid ${uuid} not found`, + }); + + const todo = todos.splice(index, 1)[0]!; + await storage.set(TODOS_KEY, todos); + + return todo; + }, +}; diff --git a/server/utils/sse.ts b/server/utils/sse.ts index b62c4bf..49961ef 100644 --- a/server/utils/sse.ts +++ b/server/utils/sse.ts @@ -1,16 +1,26 @@ import type { EventStream } from "h3"; +export const TodoEventStream = { + addStream(eventStream: EventStream) { + addEventStream(todosEventStreams, eventStream); + }, + async sendUpdate() { + await publish(todosEventStreams, await Todos.getAll()); + }, +}; + +export const TagEventStream = { + addStream(eventStream: EventStream) { + addEventStream(tagsEventStreams, eventStream); + }, + async sendUpdate() { + await publish(tagsEventStreams, await Tags.getAll()); + }, +}; + const todosEventStreams: EventStream[] = []; const tagsEventStreams: EventStream[] = []; -export function addTodoEventStream(eventStream: EventStream) { - addEventStream(todosEventStreams, eventStream); -} - -export function addTagEventStream(eventStream: EventStream) { - addEventStream(tagsEventStreams, eventStream); -} - function addEventStream(eventStreams: EventStream[], eventStream: EventStream) { eventStreams.push(eventStream); @@ -20,14 +30,6 @@ function addEventStream(eventStreams: EventStream[], eventStream: EventStream) { }); } -export async function sendTodoUpdate() { - await publish(todosEventStreams, await getTodos()); -} - -export async function sendTagsUpdate() { - await publish(tagsEventStreams, await getTags()); -} - async function publish(eventStreams: EventStream[], data: object) { const json = JSON.stringify(data); diff --git a/server/utils/tags.ts b/server/utils/tags.ts deleted file mode 100644 index c9b0da6..0000000 --- a/server/utils/tags.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { H3Error } from "h3"; -import type { Tag, UUID } from "~~/shared/types"; - -export const TAGS_KEY = "tags"; - -export async function getTags(): Promise { - const storage = useStorage(); - const tags = await storage.get(TAGS_KEY); - - if (!tags) - return createError({ - status: 500, - statusMessage: "Internal Server Error", - message: `no tags found`, - }); - - return tags; -} - -export async function updateOrAddTag(tag: Tag): Promise { - const storage = useStorage(); - const tags = await getTags(); - - if (tags instanceof H3Error) return tags; - - const index = tags.findIndex((value) => value.uuid === tag.uuid); - - if (index === -1) { - tags.unshift(tag); - } else { - tags[index] = tag; - } - - await storage.set(TAGS_KEY, tags); - - return tag; -} - -export async function deleteTag(uuid: UUID): Promise { - const storage = useStorage(); - const tags = await getTags(); - - if (tags instanceof H3Error) return tags; - - const index = tags.findIndex((value) => value.uuid === uuid); - if (index == -1) - return createError({ - status: 404, - statusMessage: "Not Found", - message: `Tag with with uuid ${uuid} not found`, - }); - - const todo = tags.splice(index, 1)[0]!; - await storage.set(TAGS_KEY, tags); - - return todo; -} diff --git a/server/utils/todos.ts b/server/utils/todos.ts deleted file mode 100644 index 5bf7ae6..0000000 --- a/server/utils/todos.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { H3Error } from "h3"; -import type { Todo, UUID } from "~~/shared/types"; - -export const TODOS_KEY = "todos"; - -export async function getTodos(): Promise { - const storage = useStorage(); - const todos = await storage.get(TODOS_KEY); - - if (!todos) - return createError({ - status: 500, - statusMessage: "Internal Server Error", - message: `no todos found`, - }); - - return todos; -} - -export async function moveTodo( - toMove: UUID, - to: UUID, -): Promise { - const storage = useStorage(); - const todos = await getTodos(); - - if (todos instanceof H3Error) return todos; - - const targetIndex = todos.findIndex((todo) => todo.uuid == to); - const movedIndex = todos.findIndex((todo) => todo.uuid == toMove); - - if (targetIndex === -1 || movedIndex === -1) - return createError({ - status: 404, - statusMessage: "Not Found", - message: `todo not found`, - }); - - const moved = todos.splice(movedIndex, 1)[0]!; - todos.splice(targetIndex, 0, moved); - - await storage.set(TODOS_KEY, todos); -} - -export async function updateOrAddTodo(todo: Todo): Promise { - const storage = useStorage(); - const todos = await getTodos(); - - if (todos instanceof H3Error) return todos; - - const index = todos.findIndex((value) => value.uuid === todo.uuid); - - if (index === -1) { - todos.push(todo); - } else { - todos[index] = todo; - } - - await storage.set(TODOS_KEY, todos); - - return todo; -} - -export async function deleteTodo(uuid: UUID): Promise { - const storage = useStorage(); - const todos = await getTodos(); - - if (todos instanceof H3Error) return todos; - - const index = todos.findIndex((value) => value.uuid === uuid); - if (index == -1) - return createError({ - status: 404, - statusMessage: "Not Found", - message: `Todo with with uuid ${uuid} not found`, - }); - - const todo = todos.splice(index, 1)[0]!; - await storage.set(TODOS_KEY, todos); - - return todo; -}