Skip to content

Instantly share code, notes, and snippets.

@johannschopplich
Last active September 22, 2023 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johannschopplich/21c4ca8bb0ed895c577dfc25d875a659 to your computer and use it in GitHub Desktop.
Save johannschopplich/21c4ca8bb0ed895c577dfc25d875a659 to your computer and use it in GitHub Desktop.
Nuxt API Party usage with auth store
import { useAuthStore } from '~/stores/auth'
export default defineNuxtPlugin(async () => {
const authStore = useAuthStore()
// Refresh the token once on the server
if (authStore.isLoggedIn && authStore.isTokenExpired()) {
await authStore.refresh()
}
})
import { useAuthStore } from '~/stores/auth'
import { toValue } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import type { MaybeRefOrGetter } from '@vueuse/core'
import type { ApiFetchOptions } from 'nuxt-api-party/dist/runtime/composables/$api'
import type { UseApiDataOptions } from 'nuxt-api-party/dist/runtime/composables/useApiData'
export async function $api<T = any>(
path: string,
opts: ApiFetchOptions & {
auth?: boolean
} = {}
) {
const { auth = true, ..._opts } = opts
const headers: HeadersInit = {
...headersToObject(_opts.headers),
}
if (auth) {
const authStore = useAuthStore()
if (authStore.isLoggedIn) {
if (authStore.isTokenExpired()) await authStore.refresh()
headers.Authorization = `Bearer ${authStore.accessToken}`
}
}
return await $realApi<T>(path, {
..._opts,
headers,
})
}
export async function useApiData<T = any>(
path: MaybeRefOrGetter<string>,
opts: UseApiDataOptions<T> & {
auth?: boolean
} = {}
) {
const { auth, ..._opts } = opts
const authStore = useAuthStore()
const { isLoggedIn } = storeToRefs(authStore)
if (
import.meta.client &&
auth &&
isLoggedIn.value &&
authStore.isTokenExpired()
) {
await authStore.refresh()
}
const asyncData = await useRealApiData<T>(path, {
..._opts,
headers: computed(() => ({
...headersToObject(toValue(_opts.headers)),
...(auth &&
isLoggedIn.value && {
Authorization: `Bearer ${authStore.accessToken}`,
}),
})),
// Instead of watching all fetch options implicitly,
// we watch only the ones we need
watch: false,
})
// Always watch the query
const fetchOptions = reactive({
query: _opts.query,
})
watch(fetchOptions, () => asyncData.refresh())
if (auth) {
watch(isLoggedIn, () => asyncData.refresh())
}
return asyncData
}
export function headersToObject(
headers: HeadersInit = {}
): Record<string, string> {
if (headers instanceof Headers || Array.isArray(headers)) {
return Object.fromEntries(headers)
}
return headers
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment