From 62f002a501d49a3098d45ad4003168756199834c Mon Sep 17 00:00:00 2001 From: kevin olson Date: Sun, 8 Oct 2023 06:05:02 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20api=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/header/HeaderProfile.vue | 6 +- client/lib/api.ts | 67 ++++++++++------------ client/middleware/auth.global.ts | 2 +- client/pages/index.vue | 7 ++- client/types/api.d.ts | 9 +-- client/types/models.d.ts | 1 + readme.md | 10 ++-- 7 files changed, 46 insertions(+), 56 deletions(-) diff --git a/client/components/header/HeaderProfile.vue b/client/components/header/HeaderProfile.vue index df1d584..ba59962 100644 --- a/client/components/header/HeaderProfile.vue +++ b/client/components/header/HeaderProfile.vue @@ -30,11 +30,7 @@ const profileGroup = [ { icon: 'i-mdi-logout', label: 'Logout', - click: async () => { - await useApi().logout() - useToast().add({ icon: 'i-mdi-logout', title: 'Logged out', }) - - } + click: async () => await useApi().logout() }, ], ] diff --git a/client/lib/api.ts b/client/lib/api.ts index d307bfb..8d8aa09 100644 --- a/client/lib/api.ts +++ b/client/lib/api.ts @@ -1,6 +1,9 @@ import type { Notification } from '@nuxt/ui/dist/runtime/types' import { reactive, ref } from 'vue' +import { NitroFetchRequest, $Fetch } from "nitropack"; + + import Echo from 'laravel-echo' import Pusher from 'pusher-js' import { NuxtApp } from '#app' @@ -65,6 +68,7 @@ export default class Api { constructor(config: AuthConfig) { this.config = { ...authConfigDefaults, ...config } } + setNuxtApp(nuxtApp:NuxtApp) { this.nuxtApp = nuxtApp } @@ -110,73 +114,61 @@ export default class Api { Object.assign(this.$user, result.user) this.setEcho() if (!discreet) - useToast().add({ icon: 'i-mdi-check-bold', color: 'green', title: 'Login Successful' }) + useToast().add({ icon: 'i-mdi-check-bold', color: 'green', title: 'Login Successful', timeout: 1 }) if (result.action && result.action.action === 'redirect') return result.action.url return this.config.redirect.login } - private fetchOptions(params?: SearchParameters, method = 'GET') { - const fetchOptions = this.config.fetchOptions - fetchOptions.headers = { - Accept: 'application/json', - Authorization: `Bearer ${this.token.value || ''}`, - Referer: this.config.webURL, - } - fetchOptions.method = method - fetchOptions.onRequest = () => this.nuxtApp?.callHook('page:start') - fetchOptions.onResponse = () => this.nuxtApp?.callHook('page:finish') - fetchOptions.onResponseError = this.toastError - delete this.config.fetchOptions.body - delete this.config.fetchOptions.params - if (params) { - if (method === 'POST' || method === 'PUT') - this.config.fetchOptions.body = params - else - this.config.fetchOptions.params = params - } - return this.config.fetchOptions + public fetch (params?: SearchParameters, method = 'GET'): $Fetch { + const nuxtApp = this.nuxtApp + return $fetch.create({ + baseURL: this.config.apiURL, + method, + params: method === 'GET' ? params : undefined, + body: ['POST','PUT'].includes(method) ? params : undefined, + headers: {Accept: 'application/json', Authorization: `Bearer ${this.token.value}`}, + onRequest() { nuxtApp?.callHook('page:start') }, + onResponse() { nuxtApp?.callHook('page:finish') }, + }) } + public async setUser(): Promise { try { - const result = await $fetch('/me', this.fetchOptions()) + const result = await this.index('/me') if (!result || !result.status || result.status !== 'success') return false Object.assign(this.$user, result.data) - } catch (e) { this.invalidate() } + } catch (e) { console.log(this.token.value, e.response._data) } this.setEcho() return true } - public async index(endpoint: string, params?: SearchParameters): Promise { - return await $fetch(endpoint, this.fetchOptions(params)) - } - - public async get(endpoint: string, params?: SearchParameters): Promise { - return await $fetch(endpoint, this.fetchOptions(params)) + public async index(endpoint: string, params?: SearchParameters): Promise { + return await this.fetch(params)(endpoint) } public async update(endpoint: string, params?: SearchParameters): Promise { - return await $fetch(endpoint, this.fetchOptions(params, 'PUT')) + return await this.fetch(params, 'PUT')(endpoint) } public async store(endpoint: string, params?: SearchParameters): Promise { - return await $fetch(endpoint, this.fetchOptions(params, 'POST')) + return await this.fetch(params, 'POST')(endpoint) } public async delete(endpoint: string, params?: SearchParameters): Promise { - return await $fetch(endpoint, this.fetchOptions(params, 'DELETE')) + return await this.fetch(params, 'DELETE')(endpoint) } public async attempt(token: string | string[]): Promise { if (Array.isArray(token)) token = token.join('') - return (await $fetch(`/login/${token}`, this.fetchOptions())).data + return (await this.fetch([])(`/login/${token}`)).data } - public upload(url: string, params?: SearchParameters) { - return $fetch(url, { method: 'PUT', body: params }) + public upload(endpoint: string, params?: SearchParameters) { + return this.fetch(params, 'PUT')(endpoint) } public async toastError(error: any): Promise { @@ -202,8 +194,7 @@ export default class Api { if (error.response?._data.exception) { useToast().add({ - ui: {'width': 'sm:w-1/2'}, - icon: 'i-mdi-alert', + icon: 'i-mdi-document', color: 'red', title: ` [${error.response._data.exception}]
@@ -226,7 +217,7 @@ export default class Api { public async logout(): Promise { if (this.$echo) this.$echo.disconnect() - const response = (await $fetch('/logout', this.fetchOptions())) + const response = (await this.fetch([])('/logout')) useToast().add({ icon: 'i-mdi-check-bold', color: 'green', title: response.data.message, timeout: 1 }) await this.invalidate() } diff --git a/client/middleware/auth.global.ts b/client/middleware/auth.global.ts index 81844e5..8f862c3 100644 --- a/client/middleware/auth.global.ts +++ b/client/middleware/auth.global.ts @@ -1,11 +1,11 @@ import Menu from '@/lib/menu' export default defineNuxtRouteMiddleware(async (to, from) => { - await useLnUtils().sleep(100) const api = useApi() await api.checkUser() const menu = new Menu(api) const item = menu.items().find(item => item.to === to.path) + // console.log(`loggedIn: ${ api.loggedIn.value } - ${ api.$user.name }`) if (item && item.gated === true && api.loggedIn.value === false) { useToast().add({ icon: 'i-mdi-lock', color: 'red', title: 'Access Denied', }) return navigateTo('/') diff --git a/client/pages/index.vue b/client/pages/index.vue index ad9d3b5..fcb4ec0 100644 --- a/client/pages/index.vue +++ b/client/pages/index.vue @@ -4,14 +4,15 @@ setCrumbs([{ name: 'List of Users', to: '/', icon: 'i-mdi-account-group' }]) const loading = ref(false) -const users = ref(undefined) +const users = ref() const get = async () => { loading.value = true users.value = undefined - users.value = await useApi().index('/example', { count: 9 }) + users.value = await useApi().index('/example', { count: 9 }) as models.UserResults loading.value = false } -const error = async () => await useApi().get('/error') + +const error = async () => await useApi().index('/error') const start = () => { useNuxtApp().callHook('page:start').catch(() => { }) diff --git a/client/types/api.d.ts b/client/types/api.d.ts index 64e707b..b01b430 100644 --- a/client/types/api.d.ts +++ b/client/types/api.d.ts @@ -5,21 +5,22 @@ declare global { options: Record params: Record } + interface MetApiData { success: boolean type: 'success' | 'failure' message: string data: unknown } - export interface MetApiResponse { + + export interface MetApiResponse { + status: 'success' | 'failure' benchmark: number success: boolean - message: string - type: 'success' | 'failure' query: MetApiQuery data: MetApiData - } + export type Me = Modify export interface MetApiResults { diff --git a/client/types/models.d.ts b/client/types/models.d.ts index a391403..3555025 100644 --- a/client/types/models.d.ts +++ b/client/types/models.d.ts @@ -38,6 +38,7 @@ declare global { notifications: DatabaseNotifications } export type Users = User[] + export type UserResult = Modify export type UserResults = Modify } diff --git a/readme.md b/readme.md index cfd013f..86d7997 100644 --- a/readme.md +++ b/readme.md @@ -39,18 +39,18 @@ ### Installation * clone from GitHub -* run `yarn` and `composer install` to install all of your deps +* run `pnpm i` and `composer install` to install all of your deps * copy `.env.example` to `.env` and configure it to your likings * TL;DR ```bash -git clone git@github.com:fumeapp/laranuxt.git; cd laranuxt; yarn; c****omposer install; cp .env.example .env; +git clone git@github.com:fumeapp/laranuxt.git; cd laranuxt; pnpm i; composer install; cp .env.example .env; ``` * Feel free to delete excess media in `/resources/` ### Local Environment -* run `yarn dev` in one terminal for our nuxt dev setup -* run `yarn api` (alias for `./artisan serve`) in another terminal for our laravel API +* run `pnpm run dev` in one terminal for our nuxt dev setup +* run `pnpm run api` (alias for `./artisan serve`) in another terminal for our laravel API ### Api and Authentication @@ -68,7 +68,7 @@ console.log(api.$user.name); const redirect = await api.login(result) if (redirect) await router.push({path: redirect}) ``` -* Once logged on, you have the boolean `api.loggedIn` and the object `api.$user` +* Once logged on, you have the ref `api.loggedIn` and the object `api.$user` ```html User Avatar ```