nuxt-og-image
Version:
Enlightened OG Image generation for Nuxt.
106 lines (105 loc) • 2.63 kB
JavaScript
import { defu } from "defu";
function detectBase64MimeType(data) {
const signatures = {
"R0lGODdh": "image/gif",
"R0lGODlh": "image/gif",
"iVBORw0KGgo": "image/png",
"/9j/": "image/jpeg",
"UklGR": "image/webp",
"AAABAA": "image/x-icon"
};
for (const s in signatures) {
if (data.startsWith(s)) {
return signatures[s];
}
}
return "image/svg+xml";
}
export function toBase64Image(data) {
const base64 = typeof data === "string" ? data : Buffer.from(data).toString("base64");
const type = detectBase64MimeType(base64);
return `data:${type};base64,${base64}`;
}
export function isInternalRoute(path) {
return path.startsWith("/_") || path.startsWith("@");
}
function filterIsOgImageOption(key) {
const keys = [
"url",
"extension",
"width",
"height",
"fonts",
"alt",
"props",
"renderer",
"html",
"component",
"renderer",
"emojis",
"_query",
"satori",
"resvg",
"sharp",
"screenshot",
"cacheMaxAgeSeconds"
];
return keys.includes(key);
}
export function separateProps(options, ignoreKeys = []) {
options = options || {};
const _props = defu(options.props, Object.fromEntries(
Object.entries({ ...options }).filter(([k]) => !filterIsOgImageOption(k) && !ignoreKeys.includes(k))
));
const props = {};
Object.entries(_props).forEach(([key, val]) => {
props[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = val;
});
return {
...Object.fromEntries(
Object.entries({ ...options }).filter(([k]) => filterIsOgImageOption(k) || ignoreKeys.includes(k))
),
props
};
}
export function normaliseFontInput(fonts) {
return fonts.map((f) => {
if (typeof f === "string") {
const vals = f.split(":");
const includesStyle = vals.length === 3;
let name, weight, style;
if (includesStyle) {
name = vals[0];
style = vals[1];
weight = vals[2];
} else {
name = vals[0];
weight = vals[1];
}
return {
cacheKey: f,
name,
weight: weight || 400,
style: style || "normal",
path: void 0
};
}
return {
cacheKey: f.key || `${f.name}:${f.style}:${f.weight}`,
style: "normal",
weight: 400,
...f
};
});
}
export function withoutQuery(path) {
return path.split("?")[0];
}
export function getExtension(path) {
path = withoutQuery(path);
const lastSegment = path.split("/").pop() || path;
const extension = lastSegment.split(".").pop() || lastSegment;
if (extension === "jpg")
return "jpeg";
return extension;
}