import get from 'lodash/get' import reduce from 'lodash/reduce' import { computed, toValue, type MaybeRefOrGetter } from 'vue' import config from '@/config' /** * Default share values resolved once from the configuration and the document * meta tags. Network-specific overrides (e.g. `facebook_title`) are layered on * top of these when building a network's values. */ export interface MetaValuesMap { url: string title?: string description?: string facebook_title?: string facebook_description?: string facebook_media?: string } /** * Resolves the share values handed to each social link. * * Default values are read from the library configuration and, unless disabled, * from the page meta tags. Consumer-provided `values` win over those defaults, * and {@link UseSharingOptionsReturn.valuesFor} picks the most specific value * for a network (e.g. `facebook_title` before the generic `title`). * * @param url - URL being shared (plain value, ref, or getter). * @param values - Consumer share values, generic or network-prefixed; may be reactive. * @param valuesKeys - Keys to inject into each social link (plain value, ref, or getter). * @param noMeta - When true, skip reading defaults from the document meta tags. * @returns The resolved default `metaValues` plus a `valuesFor(network)` builder. * @example * // Internal composable — import via relative path inside the library. * */ export function useSharingOptions( url: MaybeRefOrGetter, values: MaybeRefOrGetter> = () => ({}), valuesKeys: MaybeRefOrGetter = () => ['url', 'title', 'description', 'media', 'user'], noMeta: MaybeRefOrGetter = false ) { // Read a default value from the page meta tags, falling back to the config. // When meta reading is disabled or no selector is given, use the config only. function defaultValueFor(key: string, metaSelector?: string): string | undefined { if (toValue(noMeta) || !metaSelector) { return config.get(key) ?? undefined } return get(document.head.querySelector(metaSelector), 'content', config.get(key) ?? undefined) } const metaValues = computed((): MetaValuesMap => { return { url: toValue(url) ?? '', title: defaultValueFor('sharing-options.title'), description: defaultValueFor('sharing-options.description', 'meta[name="description"]'), facebook_title: defaultValueFor('sharing-options.facebook_title', 'meta[property="og:title"]'), facebook_description: defaultValueFor('sharing-options.description', 'meta[property="og:description"]'), facebook_media: defaultValueFor('sharing-options.media', 'meta[property="og:image"]') } }) // Build the values for a network, preferring its prefixed key (e.g. // `facebook_title`) and falling back to the generic key (`title`). function valuesFor(network: string): Record { const resolvedValues: Record = { ...metaValues.value, ...toValue(values) } return reduce( toValue(valuesKeys), (res: Record, key) => { const value = get(resolvedValues, `${network}_${key}`, resolvedValues[key]) res[key] = value == null ? '' : String(value) return res }, {} ) } return { metaValues, valuesFor } } export default useSharingOptions