/* global defineEventHandler, createError, readBody, setResponseStatus */ import { createValidationError, handleRecursedValidationError } from "../utils/validation"; import { database as db } from "../utils/database"; import getRequestingUser from "../utils/getRequestingUser"; import { getOrder } from "./orders/[id].get"; import Snowflake from "~/utils/snowflake"; type importedProduct = { name: string | null, link: string, price_imported: number, price: number, } type work = { offer: string, price: number, notes: string | null, is_fulfilled: boolean | 0 | 1, } type order = { client: string, // user: string, is_draft: boolean | 0 | 1, imported_products: Array, work: Array, }; export function checkIsWork( value: any, patch: Patch, ): value is Patch extends true ? Partial : work { const errors = new Map(); if (typeof value !== "object") { throw createError({ message: "Invalid body", statusCode: 400, }); } if (!(typeof value.offer === "string" || (patch && value.offer === undefined))) errors.set("offer", "is not string"); if (!(typeof value.price === "number" || (patch && value.price === undefined))) errors.set("price", "is not price"); if (!(typeof value.notes === "string" || value.notes === null || (patch && value.notes === undefined))) errors.set("notes", "is not string or null"); if (!(typeof value.is_fulfilled === "boolean" || value.is_fulfilled === 0 || value.is_fulfilled === 1 || (patch && value.is_fulfilled === undefined))) errors.set("is_fulfilled", "is not boolean"); if (errors.size !== 0) throw createValidationError(errors); return true; } export function checkIsImportedProduct( value: any, patch: Patch, ): value is Patch extends true ? Partial : importedProduct { const errors = new Map(); if (typeof value !== "object") { throw createError({ message: "Invalid body", statusCode: 400, }); } if (!(typeof value.name === "string" || value.name === null || (patch && value.name === undefined))) errors.set("name", "is not string or null"); if (!(typeof value.link === "string" || (patch && value.name === undefined))) errors.set("link", "is not string"); if (!(typeof value.price_imported === "number" || (patch && value.name === undefined))) errors.set("price_imported", "is not number"); if (!(typeof value.price || (patch && value.price === undefined))) errors.set("price", "is not number"); if (errors.size !== 0) throw createValidationError(errors); return true; } export function checkIsOrder( value: any, patch: Patch, ): value is Patch extends true ? Partial> : order { const errors = new Map(); if (typeof value !== "object") { throw createError({ message: "Invalid body", statusCode: 400, }); } if (!(typeof value.client === "string" || (patch && value.client === undefined))) errors.set("client", "is not string"); if (!(typeof value.is_draft === "boolean" || value.is_draft === 0 || value.is_draft === 1 || (patch && value.is_draft === undefined))) errors.set("is_draft", "is not boolean"); if (!(value.imported_products instanceof Array)) errors.set("imported_products", "is not array"); else if (patch && value.imported_products !== undefined) errors.set("imported_products", "cannot patch from order"); if (!(value.work instanceof Array)) errors.set("work", "is not array"); else if (patch && value.work !== undefined) errors.set("work", "cannot patch from order"); if (!patch) { const importedProducts = value.imported_products; if (importedProducts instanceof Array) { for (const i in importedProducts) { try { checkIsImportedProduct(importedProducts[i], patch); } catch (e) { handleRecursedValidationError(e, errors, `imported_products[${i}]`); } } } const work = value.work; if (work instanceof Array) { for (const i in work) { try { checkIsWork(work[i], patch); } catch (e) { handleRecursedValidationError(e, errors, `work[${i}]`); } } } } if (errors.size !== 0) throw createValidationError(errors); return true; } export default defineEventHandler(async (e) => { const body = await readBody(e); const id = new Snowflake().toString(); const user = await getRequestingUser(e); if (!checkIsOrder(body, false)) throw createError({ message: "Invalid body", statusCode: 400 }); const database = await db.new(); await database.beginTransaction(); await database.query( ["INSERT INTO", "`orders`", "VALUES", "(?, ?, ?, ?)", ].join(" "), [id, body.client, user.id, body.is_draft], ); const promises: Array> = []; for (const i of body.imported_products) { promises.push(database.query( ["INSERT INTO", "`imported_products`", "VALUES", "(?, ?, ?, ?, ?, ?)", ].join(" "), [new Snowflake().toString(), id, i.name, i.link, i.price_imported, i.price], )); } for (const i of body.work) { promises.push(database.query( ["INSERT INTO", "`work`", "VALUES", "(?, ?, ?, ?, ?, ?)", ].join(" "), [new Snowflake().toString(), id, i.offer, i.price, i.notes, i.is_fulfilled], )); } await Promise.all(promises); await database.commit(); setResponseStatus(e, 201); return getOrder(id); });