From c25873158d8468534bbaab4426f8c926fe11ceb7 Mon Sep 17 00:00:00 2001 From: dm1sh Date: Thu, 15 Jul 2021 18:38:57 +0500 Subject: [PATCH] Added form file processing --- src/api.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++++ src/types/book.ts | 17 +++++++++------- 2 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 src/api.ts diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 0000000..cdd346f --- /dev/null +++ b/src/api.ts @@ -0,0 +1,50 @@ +import { IBook, optionalBookProps, requiredBookProps } from "./types/book"; + +const API_URL = import.meta.env.SNOWPACK_PUBLIC_API_URL; + +export const validState = (file: File | undefined): file is File => { + if (!file) throw new Error("Book file is required. Please, attach one"); + + if (!file.name.match(/\.(fb2|epub)/)) + throw new Error( + "Wrong file type. Only FB2 and Epub files are supported. \ + If you are trying to upload fb2.zip, please, uncopress it first." + ); + + if (file.size > 100 * 1024 * 1024) + throw new Error( + "File size is too big. Sorry, but parser is served on a rather cheap hosting, \ + so application can't handle such big files." + ); + + return true; +}; + +export const submitFile = async ( + file: File +): Promise<{ [key: string]: string }> => { + const body = new FormData(); + body.append("file", file); + + try { + const res = await fetch(API_URL + "/uploadfile/", { + method: "POST", + body, + }); + + return await res.json(); + } catch (err) { + console.log("Network error:", err.message); + throw err; + } +}; + +export const validateResponse = ( + content: Record +): content is IBook => { + for (const key of requiredBookProps) + if (!(key in content)) + throw new Error(`${key} is not specified in server response`); + + return true; +}; diff --git a/src/types/book.ts b/src/types/book.ts index f4d039e..1c267d9 100644 --- a/src/types/book.ts +++ b/src/types/book.ts @@ -1,7 +1,10 @@ -export interface IBook { - title: string; - author: string; - cover?: string; - content: string; - hash?: string; -} +export const requiredBookProps = ["title", "author", "content"] as const; +export const optionalBookProps = ["cover", "hash"] as const; + +export type IBook = + | { + [key in typeof requiredBookProps[number]]: string; + } + | { + [key in typeof optionalBookProps[number]]: string | undefined; + };