Refactor project structure and update dependencies
This commit is contained in:
130
nuxt/app/plugins/app.ts
Normal file
130
nuxt/app/plugins/app.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import { ofetch } from 'ofetch'
|
||||
import type { FetchOptions } from 'ofetch'
|
||||
|
||||
export default defineNuxtPlugin({
|
||||
name: 'app',
|
||||
enforce: 'default',
|
||||
parallel: true,
|
||||
async setup(nuxtApp) {
|
||||
const config = useRuntimeConfig()
|
||||
const auth = useAuthStore()
|
||||
|
||||
nuxtApp.provide('storage', (path: string): string => {
|
||||
if (!path) return ''
|
||||
|
||||
return path.startsWith('http://') || path.startsWith('https://')
|
||||
? path
|
||||
: config.public.storageBase + path
|
||||
})
|
||||
|
||||
function buildHeaders(headers: HeadersInit = {}): HeadersInit {
|
||||
// Initial headers with Accept
|
||||
const initialHeaders = {
|
||||
...headers,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
|
||||
// Conditionally add server-specific headers
|
||||
if (import.meta.server) {
|
||||
const serverHeaders = {
|
||||
referer: useRequestURL().toString(),
|
||||
...useRequestHeaders(['x-forwarded-for', 'user-agent', 'referer']),
|
||||
}
|
||||
Object.assign(initialHeaders, serverHeaders)
|
||||
}
|
||||
|
||||
// Conditionally add authorization header if logged in
|
||||
if (auth.isLoggedIn) {
|
||||
const authHeaders = {
|
||||
Authorization: `Bearer ${auth.token}`,
|
||||
}
|
||||
Object.assign(initialHeaders, authHeaders)
|
||||
}
|
||||
|
||||
return initialHeaders
|
||||
}
|
||||
|
||||
function buildBaseURL(baseURL: string): string {
|
||||
if (baseURL) return baseURL
|
||||
|
||||
return import.meta.server
|
||||
? config.apiLocal + config.public.apiPrefix
|
||||
: config.public.apiBase + config.public.apiPrefix
|
||||
}
|
||||
|
||||
function buildSecureMethod(options: FetchOptions): void {
|
||||
if (import.meta.server) return
|
||||
|
||||
const method = options.method?.toLowerCase() ?? 'get'
|
||||
|
||||
if (options.body instanceof FormData && method === 'put') {
|
||||
options.method = 'POST'
|
||||
options.body.append('_method', 'PUT')
|
||||
}
|
||||
}
|
||||
|
||||
function isRequestWithAuth(baseURL: string, path: string): boolean {
|
||||
return !baseURL
|
||||
&& !path.startsWith('/_nuxt')
|
||||
&& !path.startsWith('http://')
|
||||
&& !path.startsWith('https://')
|
||||
}
|
||||
|
||||
globalThis.$fetch = ofetch.create({
|
||||
retry: false,
|
||||
|
||||
onRequest({ request, options }) {
|
||||
if (!isRequestWithAuth(options.baseURL ?? '', request.toString())) return
|
||||
|
||||
options.credentials = 'include'
|
||||
|
||||
options.baseURL = buildBaseURL(options.baseURL ?? '')
|
||||
options.headers = buildHeaders(options.headers)
|
||||
|
||||
buildSecureMethod(options)
|
||||
},
|
||||
|
||||
onRequestError({ error }) {
|
||||
if (import.meta.server) return
|
||||
|
||||
if (error.name === 'AbortError') return
|
||||
|
||||
useToast().add({
|
||||
icon: 'i-heroicons-exclamation-circle-solid',
|
||||
color: 'red',
|
||||
title: error.message ?? 'Something went wrong',
|
||||
})
|
||||
},
|
||||
|
||||
onResponseError({ response }) {
|
||||
if (response.status === 401) {
|
||||
if (auth.isLoggedIn) {
|
||||
auth.token = ''
|
||||
auth.user = {} as User
|
||||
}
|
||||
|
||||
if (import.meta.client) {
|
||||
useToast().add({
|
||||
title: 'Please log in to continue',
|
||||
icon: 'i-heroicons-exclamation-circle-solid',
|
||||
color: 'primary',
|
||||
})
|
||||
}
|
||||
}
|
||||
else if (response.status !== 422) {
|
||||
if (import.meta.client) {
|
||||
useToast().add({
|
||||
icon: 'i-heroicons-exclamation-circle-solid',
|
||||
color: 'red',
|
||||
title: response._data?.message ?? response.statusText ?? 'Something went wrong',
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
} as FetchOptions)
|
||||
|
||||
if (auth.isLoggedIn) {
|
||||
await auth.fetchUser()
|
||||
}
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user