nicwands.com/src/composables/useStrapi.js
2026-06-08 14:45:19 -04:00

142 lines
3.5 KiB
JavaScript

import { inject, ref } from 'vue'
// Base composable to access the Strapi client
const getStrapiClient = () => {
const client = inject('strapi')
if (!client)
throw new Error(
'Strapi client not initialized. Did you install the plugin?',
)
return client
}
// Merge default and user options
const mergeOptions = (userOptions = {}) => {
return { pLevel: '5', ...userOptions }
}
// Singleton instance for global data
let globalInstance = null
/**
* Use the global singleton data with caching
* This composable ensures the global data is only fetched once,
* even when called from multiple places
* @param {object} options - optional query options
*/
export const useStrapiGlobal = async (options = {}) => {
// Return existing instance if already fetched
if (globalInstance) {
return globalInstance
}
// Create new instance
const data = ref(null)
const loading = ref(true)
const error = ref(null)
const client = getStrapiClient()
// Store the instance before making the request
globalInstance = { data, loading, error }
try {
const response = await client
.single('global')
.find(mergeOptions(options))
data.value = response.data
} catch (err) {
error.value = err
console.error(err)
// Reset instance on error so it can be retried
globalInstance = null
} finally {
loading.value = false
}
return globalInstance
}
/**
* Reset the global singleton cache
* Useful for forcing a refetch of global data
*/
export const resetStrapiGlobal = () => {
globalInstance = null
}
/**
* Use a singleton content type
* @param {string} uid - Strapi singleton UID
* @param {object} options - optional query options
*/
export const useStrapiSingle = async (uid, options = {}) => {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
const client = getStrapiClient()
try {
const response = await client.single(uid).find(mergeOptions(options))
data.value = response.data
} catch (err) {
error.value = err
console.error(err)
} finally {
loading.value = false
}
return { data, loading, error }
}
/**
* Use a single entry by ID
* @param {string} contentType
* @param {number|string} id
* @param {object} options - optional query options
*/
export const useStrapiOne = async (contentType, id, options = {}) => {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
const client = getStrapiClient()
try {
const response = await client
.entity(contentType)
.findOne({ id, ...mergeOptions(options) })
data.value = response.data
} catch (err) {
error.value = err
console.error(err)
} finally {
loading.value = false
}
return { data, loading, error }
}
/**
* Use a collection of entries
* @param {string} contentType
* @param {object} options - optional query options
*/
export const useStrapiMany = async (contentType, options = {}) => {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
const client = getStrapiClient()
try {
const response = await client
.entity(contentType)
.find(mergeOptions(options))
data.value = response.data
} catch (err) {
error.value = err
console.error(err)
} finally {
loading.value = false
}
return { data, loading, error }
}