From 87d72be3faaa3f6c31e30e3c5cfbd5c328e4d672 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 15 Apr 2021 16:04:22 +0200 Subject: [PATCH] Refactor api functions --- src/api.ts | 137 ++++++++++++++++----------------------------- src/views/Home.vue | 2 +- 2 files changed, 49 insertions(+), 90 deletions(-) diff --git a/src/api.ts b/src/api.ts index f12fd0a..d046fb0 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,107 +1,57 @@ import Cookies from "js-cookie"; +type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH"; + class APIError extends Error { constructor(message: string, public readonly errors: unknown) { super(message); } } -class Model { - static async fetch( - method: "get" | "post", - endpoint: string, - item_callback: (item: any) => any - ) { - const init = { - headers: new Headers(), - method: method, - //body: JSON.stringify({}) - }; - const csrfToken = Cookies.get("csrftoken"); - if (csrfToken != undefined) { - init.headers.set("X-CSRFToken", csrfToken); - } - init.headers.set("Accept", "application/json"); - init.headers.set("Content-Type", "application/json"); - const response = await fetch(`/api/${endpoint}`, init); - const dataOrErrors: Array = await response.json(); - if (response.status === 200) { - return dataOrErrors.map(item_callback); - } else { - throw new APIError(response.statusText, dataOrErrors); - } +async function request( + method: HTTPMethod, + endpoint: string, + successStatus: number, + data: any, + authToken?: string +) { + const init = { + headers: new Headers(), + method: method, + body: JSON.stringify(data), + }; + const csrfToken = Cookies.get("csrftoken"); + if (csrfToken != undefined) { + init.headers.set("X-CSRFToken", csrfToken); } - - static async create(endpoint: string, data: any) { - const init = { - headers: new Headers(), - method: "post", - body: JSON.stringify(data), - }; - const csrfToken = Cookies.get("csrftoken"); - if (csrfToken != undefined) { - init.headers.set("X-CSRFToken", csrfToken); - } - init.headers.set("Accept", "application/json"); - init.headers.set("Content-Type", "application/json"); - const response = await fetch(`/api/${endpoint}/`, init); - const dataOrErrors = await response.json(); - if (response.status === 200) { - return dataOrErrors; - } else { - throw new APIError(response.statusText, dataOrErrors); - } + if (authToken != undefined) { + init.headers.set("Authentication", authToken); } - - protected async put(endpoint: string, token: string, data: any) { - const init = { - headers: new Headers(), - method: "PATCH", - body: JSON.stringify(data), - }; - const csrfToken = Cookies.get("csrftoken"); - if (csrfToken != undefined) { - init.headers.set("X-CSRFToken", csrfToken); - } - init.headers.set("Authorization", `Token ${token}`); - init.headers.set("Accept", "application/json"); - init.headers.set("Content-Type", "application/json"); - const response = await fetch(`/api/${endpoint}/`, init); - const dataOrErrors = await response.json(); - if (response.status === 200) { - return dataOrErrors; - } else { - throw new APIError(response.statusText, dataOrErrors); - } + init.headers.set("Accept", "application/json"); + init.headers.set("Content-Type", "application/json"); + const response = await fetch(`/api/${endpoint}/`, init); + const dataOrErrors = await response.json(); + if (response.status === successStatus) { + return dataOrErrors; + } else { + throw new APIError(response.statusText, dataOrErrors); } } -interface UserData { - email: string; - password: string; - username: string | undefined; - confidant_email: string | undefined; -} - -export class User extends Model implements UserData { - public isAuthenticated = false; +export class User { + private email: string | undefined; + private password: string | undefined; + private username: string | null = null; + private confidantEmail: string | null = null; + private isAuthenticated = false; private token = ""; - constructor( - public email: string, - public password: string, - public username: string | undefined, - public confidant_email: string | undefined - ) { - super(); - } - static async confirm(uid: string, token: string): Promise { - await super.create("users/activation", { uid, token }); + await request("POST", "users/activation", 204, { uid, token }); } async login(): Promise { - const response = await Model.create("token/login", { + const response = await request("POST", "token/login", 200, { email: this.email, password: this.password, }); @@ -110,12 +60,21 @@ export class User extends Model implements UserData { } async save(): Promise { - await super.put("users/me", this.token, { - username: this.username, - }); + await request( + "PATCH", + "users/me", + 200, + { + username: this.username, + }, + this.token + ); } async signup(): Promise { - await Model.create("users", { email: this.email, password: this.password }); + await request("POST", "users", 201, { + email: this.email, + password: this.password, + }); } } diff --git a/src/views/Home.vue b/src/views/Home.vue index b1788e3..862ec6d 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -26,7 +26,7 @@ import UserTable from "@/components/UserTable.vue"; @Component({ components: { UserTable, LoginForm } }) export default class Home extends Vue { private isConfirmation = false; - private user = new User("", "", undefined, undefined); + private user = new User(); private async created() { if (this.$route.name === "Confirm") this.isConfirmation = true;