diff --git a/server/globalTypes.d.ts b/server/JSON.ts similarity index 55% rename from server/globalTypes.d.ts rename to server/JSON.ts index dd0aecc..8ffc049 100644 --- a/server/globalTypes.d.ts +++ b/server/JSON.ts @@ -7,14 +7,6 @@ type JSONValue = type JSONArray = Array; -type Maybe = { - just: T, - error: null, -} | { - just: null, - error: { message: string }, -}; - -interface JSONObject { +export interface JSONObject { [x: string]: JSONValue; } diff --git a/server/Maybe.ts b/server/Maybe.ts new file mode 100644 index 0000000..694c7ac --- /dev/null +++ b/server/Maybe.ts @@ -0,0 +1,2 @@ +export type Maybe = Just | { just?: never, error: { message: string }}; +export type Just = { just: T, error?: never }; diff --git a/server/StoccaTreRequest.ts b/server/StoccaTreRequest.ts index afd728d..a510e1c 100644 --- a/server/StoccaTreRequest.ts +++ b/server/StoccaTreRequest.ts @@ -3,4 +3,5 @@ export type HttpMethod = "POST" | "GET" | "PUT" | "DELETE"; export default interface StoccaTreRequest { method: HttpMethod, route: string, + body: string | null, } diff --git a/server/StoccaTreRequestHandler.ts b/server/StoccaTreRequestHandler.ts index 2524e28..a37f553 100644 --- a/server/StoccaTreRequestHandler.ts +++ b/server/StoccaTreRequestHandler.ts @@ -1,4 +1,6 @@ import StoccaTreRequest from "./StoccaTreRequest.ts"; +import {Maybe} from "./Maybe.ts"; +import {JSONObject} from "./JSON.ts"; export default interface StoccaTreRequestHandler { handleRequest(request: StoccaTreRequest): Promise>, diff --git a/server/config.json b/server/config.json new file mode 100644 index 0000000..faccf9b --- /dev/null +++ b/server/config.json @@ -0,0 +1,6 @@ +{ + "username": "root", + "port": 8080, + "hostname": "127.0.0.1", + "password": "sekna123jk" +} \ No newline at end of file diff --git a/server/database.ts b/server/database.ts index 8d81c78..01ed4d8 100644 --- a/server/database.ts +++ b/server/database.ts @@ -1,5 +1,6 @@ import { Client } from "https://deno.land/x/mysql/mod.ts"; -import config from "@/config.json" assert { type: "json" }; +import config from "./config.json" assert { type: "json" }; +import {Maybe} from "./Maybe.ts"; export type WithoutId = Omit; export interface StoccaTreDbConn { @@ -19,7 +20,6 @@ export default async function createNewDbConnection(): Promise const result = await mysqlClient.query(query); return { just: result as T, - error: null, }; } catch (e: unknown) { if (e && typeof (e as { message?: any }).message === "string") { @@ -29,7 +29,6 @@ export default async function createNewDbConnection(): Promise } } return { - just: null, error: { message: errMessage }, diff --git a/server/import_map.json b/server/import_map.json index 793eacd..899e37c 100644 --- a/server/import_map.json +++ b/server/import_map.json @@ -1,5 +1,4 @@ { "imports": { - "/": "./" } } diff --git a/server/main.ts b/server/main.ts index 06cdc4a..9b2f7fc 100644 --- a/server/main.ts +++ b/server/main.ts @@ -1,12 +1,9 @@ -import createNewDbConnection, {StoccaTreDbConn} from "/database.ts"; -import * as resources from "/resources/main.ts"; -import config from "/config.json" assert { type: "json" }; -import StoccaTreRequest, {HttpMethod} from "/StoccaTreRequest.ts"; -import StoccaTreRequestHandler from "/StoccaTreRequestHandler.ts"; - -const server = Deno.listen({ port: config.port ?? 8080 }); - -console.log(`Stocca Tre Server is running. Access it at: http://localhost:${ config.port }/`); +import createNewDbConnection, {StoccaTreDbConn} from "./database.ts"; +import * as resources from "./resources/main.ts"; +import config from "./config.json" assert { type: "json" }; +import StoccaTreRequest, {HttpMethod} from "./StoccaTreRequest.ts"; +import StoccaTreRequestHandler from "./StoccaTreRequestHandler.ts"; +import {JSONObject} from "./JSON.ts"; type StoccaTreApiBody = { data: JSONObject, @@ -19,41 +16,43 @@ function newStoccaTreApiBody(): StoccaTreApiBody { }; } -type StoccaTreServer = { +type StoccaTreServer = StoccaTreRequestHandler & { dbConnection: StoccaTreDbConn, - handleRequest(request: StoccaTreRequest): Promise>, } async function processRequest(server: StoccaTreServer, requestEvent: Deno.RequestEvent) { - const route = requestEvent.request.destination; - const requestMethod = requestEvent.request.method; - console.log(route, requestMethod); + const route = /^https?:\/\/[^\/]*(\/.*)$/.exec(requestEvent.request.url)?.[1] ?? "/"; + const requestBody = (await requestEvent.request.body?.getReader().read())?.value?.toString() ?? null; + console.log(requestBody); + const method: HttpMethod = requestEvent.request.method as HttpMethod; const body: StoccaTreApiBody = newStoccaTreApiBody(); - const maybeResult = await server.handleRequest({ + const result = await server.handleRequest({ route, - method: requestMethod as HttpMethod, + body: requestBody, + method, }); - if (maybeResult.error) { - await requestEvent.respondWith(Response.json({ ...body, error: `Internal server error: ${maybeResult.error.message}` }, { status: 500 })); + if (result.error) { + await requestEvent.respondWith(Response.json({ ...body, error: `Internal server error: ${result.error.message}` }, { status: 500 })); } else { - body.data = maybeResult.just; + body.data = result.just; await requestEvent.respondWith(Response.json(body, { status: 200 })); } } +const stoccaTreListener = Deno.listen({ port: config.port ?? 8080 }); + +console.log(`Stocca Tre Server is running. Access it at: http://localhost:${ config.port }/`); + const database = await createNewDbConnection(); const ingredientResource = new resources.IngredientResource(database); +const stoccaTreServer: StoccaTreServer = { + dbConnection: database, + handleRequest: (request: StoccaTreRequest) => ingredientResource.handleRequest(request), +}; -for await (const conn of server) { - await serveHttp(conn); -} - -async function serveHttp(conn: Deno.Conn) { +for await (const conn of stoccaTreListener) { const httpConn = Deno.serveHttp(conn); for await (const requestEvent of httpConn) { - await processRequest({ - dbConnection: database, - handleRequest: (request: StoccaTreRequest) => ingredientResource.handleRequest(request), - }, requestEvent); + await processRequest(stoccaTreServer, requestEvent); } } diff --git a/server/package.json b/server/package.json index f1a7e3e..3aae7f5 100644 --- a/server/package.json +++ b/server/package.json @@ -2,7 +2,7 @@ "name": "stocca-tre-server", "version": "0.0.1", "scripts": { - "start": "deno run --allow-net --import-map=importMap.json main.ts" + "start": "deno run --allow-net --import-map=import_map.json main.ts" }, "description": "Backend for StoccaTre", "author": "Daniel Ledda", diff --git a/server/resources/ingredient/IngredientCollection.ts b/server/resources/ingredient/IngredientCollection.ts index ea3a211..0b6bf3f 100644 --- a/server/resources/ingredient/IngredientCollection.ts +++ b/server/resources/ingredient/IngredientCollection.ts @@ -1,5 +1,6 @@ import {StoccaTreDbConn, WithoutId} from "../../database.ts"; import {IngredientModel} from "./IngredientModel.ts"; +import {Maybe} from "../../Maybe.ts"; export default class IngredientCollection { private dbConnection: StoccaTreDbConn; @@ -11,17 +12,16 @@ export default class IngredientCollection { } async addIngredient(ingredient: WithoutId): Promise { - const result = await this.dbConnection.query( + return await this.dbConnection.query( `INSERT INTO ingredients (id, name, displayName, displayNameDE) VALUES (NULL, '${ingredient.name}', '${ingredient.displayName}', '${ingredient.displayNameDE}');` ); - return result; } async getAllIngredients(): Promise>> { if (!this.allGotten) { const result = await this.dbConnection.query("SELECT * FROM ingredients"); - if (result.just) { - result.just.forEach((ingredient) => this.mapById.set(ingredient.id, ingredient)); + if (!result.error) { + result.just.forEach((ingredient: IngredientModel) => this.mapById.set(ingredient.id, ingredient)); } else { return result; } @@ -29,7 +29,6 @@ export default class IngredientCollection { } return { just: this.mapById.values(), - error: null, }; } } diff --git a/server/resources/ingredient/IngredientResource.ts b/server/resources/ingredient/IngredientResource.ts index 32f97f4..93d07f7 100644 --- a/server/resources/ingredient/IngredientResource.ts +++ b/server/resources/ingredient/IngredientResource.ts @@ -1,6 +1,9 @@ -import {StoccaTreDbConn} from "/database.ts"; -import IngredientCollection from "IngredientCollection.ts"; -import StoccaTreRequest from "/StoccaTreRequest.ts"; +import {StoccaTreDbConn} from "../../database.ts"; +import IngredientCollection from "./IngredientCollection.ts"; +import StoccaTreRequest from "../../StoccaTreRequest.ts"; +import {Maybe} from "../../Maybe.ts"; +import {JSONObject} from "../../JSON.ts"; +import {IngredientModel} from "./IngredientModel.ts"; export default class IngredientResource { private dbConnection: StoccaTreDbConn; @@ -11,20 +14,40 @@ export default class IngredientResource { this.collection = new IngredientCollection(dbConnection); } + static isIngredient(json: JSONObject): json is IngredientModel { + if (json) { + return true; + } + return false; + } + async handleRequest(request: StoccaTreRequest): Promise> { - return await this.allIngredients(request); + switch (request.route) { + case "/add": + if (request.method === "POST") { + const ingredient = JSON.parse(request.body ?? ""); + return await this.collection.addIngredient(JSON.parse(request.body)); + + + } + break; + case "/all": + return await this.allIngredients(request); + default: + break; + } + return { error: {message: "Invalid route" }}; } async allIngredients(request: StoccaTreRequest): Promise> { const getAllIngredientResult = await this.collection.getAllIngredients(); - if (!getAllIngredientResult.error) { - return getAllIngredientResult.just; + if (getAllIngredientResult.error) { + return getAllIngredientResult; } return { just: { ingredients: Array.from(getAllIngredientResult.just), }, - error: "", }; } } \ No newline at end of file diff --git a/server/tsconfig.json b/server/tsconfig.json deleted file mode 100644 index 9c962e8..0000000 --- a/server/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "allowJs": false, - "lib": [ "ES2021" ] - } -}