UNPKG

nuxt-og-image

Version:

Enlightened OG Image generation for Nuxt.

75 lines (74 loc) 2.46 kB
import { useStorage } from "#imports"; import { createError, getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3"; import { hash } from "ohash"; import { withTrailingSlash } from "ufo"; import { prefixStorage } from "unstorage"; export async function useOgImageBufferCache(ctx, options) { const maxAge = Number(options.cacheMaxAgeSeconds); let enabled = !import.meta.dev && import.meta.env.MODE !== "test" && maxAge > 0; const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/")); const key = ctx.key; let cachedItem = false; if (enabled) { const hasItem = await cache.hasItem(key).catch((e) => { enabled = false; return createError({ cause: e, statusCode: 500, statusMessage: `[Nuxt OG Image] Failed to connect to cache ${options.baseCacheKey}. Response from cache: ${e.message}` }); }); if (hasItem instanceof Error) return hasItem; if (hasItem) { const { value, expiresAt, headers } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() })); if (typeof getQuery(ctx.e).purge !== "undefined") { await cache.removeItem(key).catch(() => { }); } else if (expiresAt > Date.now()) { cachedItem = Buffer.from(value, "base64"); if (handleCacheHeaders(ctx.e, { modifiedTime: new Date(headers["last-modified"]), etag: headers.etag, maxAge })) { return; } setHeaders(ctx.e, headers); } else { await cache.removeItem(key).catch(() => { }); } } } if (!enabled) { setHeader(ctx.e, "Cache-Control", "no-cache, no-store, must-revalidate"); setHeader(ctx.e, "Pragma", "no-cache"); setHeader(ctx.e, "Expires", "0"); } return { enabled, cachedItem, async update(item) { if (!enabled) return; const value = Buffer.from(item).toString("base64"); const headers = { // avoid multi-tenancy cache issues "Vary": "accept-encoding, host", "etag": `W/"${hash(value)}"`, "last-modified": (/* @__PURE__ */ new Date()).toUTCString(), "cache-control": `public, s-maxage=${maxAge}, stale-while-revalidate` }; setHeaders(ctx.e, headers); await cache.setItem(key, { value, headers, expiresAt: Date.now() + maxAge * 1e3 }); } }; }