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 } }