nuxt-og-image 5.1.6 → 5.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/200.html +7 -7
- package/dist/client/404.html +7 -7
- package/dist/client/_nuxt/{TAjbzagq.js → BM0SGHtW.js} +1 -1
- package/dist/client/_nuxt/{Bi6Y3qqE.js → Cl0GRg1F.js} +130 -130
- package/dist/client/_nuxt/{eNJvB98b.js → DH3TEEXq.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/32731774-300b-4e2d-acf2-4e94bbd66b89.json +1 -0
- package/dist/client/_nuxt/error-404.CWHu2lpK.css +1 -0
- package/dist/client/_nuxt/error-500.xMt3qmEl.css +1 -0
- package/dist/client/index.html +7 -7
- package/dist/content.cjs +7 -5
- package/dist/content.d.cts +18 -2
- package/dist/content.d.mts +18 -2
- package/dist/content.d.ts +18 -2
- package/dist/content.mjs +7 -6
- package/dist/module.cjs +4 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +4 -3
- package/dist/runtime/app/components/OgImage/OgImage.js +1 -1
- package/dist/runtime/app/components/OgImage/OgImageScreenshot.js +1 -1
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue +2 -2
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue +2 -1
- package/dist/runtime/app/components/Templates/Community/UnJs.vue +1 -1
- package/dist/runtime/app/composables/defineOgImage.js +11 -23
- package/dist/runtime/app/composables/defineOgImageScreenshot.js +2 -1
- package/dist/runtime/app/plugins/__zero-runtime/og-image-canonical-urls.server.js +1 -1
- package/dist/runtime/app/plugins/__zero-runtime/route-rule-og-image.server.js +1 -1
- package/dist/runtime/app/plugins/og-image-canonical-urls.server.js +4 -2
- package/dist/runtime/app/plugins/route-rule-og-image.server.js +4 -2
- package/dist/runtime/app/utils/plugins.d.ts +3 -3
- package/dist/runtime/app/utils/plugins.js +13 -10
- package/dist/runtime/app/utils.d.ts +3 -1
- package/dist/runtime/app/utils.js +23 -5
- package/dist/runtime/server/og-image/bindings/chromium/on-demand.js +8 -3
- package/dist/runtime/server/og-image/chromium/screenshot.js +5 -4
- package/dist/runtime/server/og-image/context.js +13 -8
- package/dist/runtime/server/og-image/satori/font.js +4 -3
- package/dist/runtime/server/og-image/satori/plugins/flex.js +1 -1
- package/dist/runtime/server/og-image/satori/plugins/imageSrc.js +11 -6
- package/dist/runtime/server/og-image/satori/renderer.js +5 -2
- package/dist/runtime/server/og-image/satori/transforms/emojis.d.ts +2 -2
- package/dist/runtime/server/og-image/satori/transforms/inlineCss.d.ts +1 -1
- package/dist/runtime/server/og-image/satori/transforms/inlineCss.js +6 -5
- package/dist/runtime/server/og-image/templates/html.js +2 -1
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.d.ts +1 -1
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.js +1 -1
- package/dist/runtime/server/plugins/nuxt-content-v2.d.ts +1 -1
- package/dist/runtime/server/plugins/nuxt-content-v2.js +1 -1
- package/dist/runtime/server/plugins/prerender.d.ts +1 -1
- package/dist/runtime/server/plugins/prerender.js +2 -2
- package/dist/runtime/server/routes/debug.json.js +2 -2
- package/dist/runtime/server/util/cache.js +2 -2
- package/dist/runtime/server/util/eventHandlers.js +2 -1
- package/dist/runtime/server/util/kit.d.ts +1 -1
- package/dist/runtime/server/util/kit.js +1 -1
- package/dist/runtime/server/util/plugins.js +2 -1
- package/dist/runtime/server/utils.d.ts +4 -0
- package/dist/runtime/server/utils.js +20 -0
- package/dist/runtime/shared.d.ts +13 -4
- package/dist/runtime/shared.js +103 -17
- package/dist/runtime/types.d.ts +15 -1
- package/package.json +27 -25
- package/{virtual.d.ts → types/virtual.d.ts} +11 -2
- package/dist/client/_nuxt/builds/meta/0f0cd98d-a6ee-47bf-a7c6-e295b96f29b9.json +0 -1
- package/dist/client/_nuxt/error-404.t9BbLQhb.css +0 -1
- package/dist/client/_nuxt/error-500.Bj4Q9dL1.css +0 -1
- package/dist/runtime/pure.d.ts +0 -9
- package/dist/runtime/pure.js +0 -105
|
@@ -11,11 +11,12 @@ import { useNitroApp } from "nitropack/runtime";
|
|
|
11
11
|
import { hash } from "ohash";
|
|
12
12
|
import { parseURL, withoutLeadingSlash, withoutTrailingSlash, withQuery } from "ufo";
|
|
13
13
|
import { normalizeKey } from "unstorage";
|
|
14
|
-
import { separateProps
|
|
14
|
+
import { separateProps } from "../../shared.js";
|
|
15
15
|
import { decodeObjectHtmlEntities } from "../util/encoding.js";
|
|
16
16
|
import { createNitroRouteRuleMatcher } from "../util/kit.js";
|
|
17
17
|
import { logger } from "../util/logger.js";
|
|
18
18
|
import { normaliseOptions } from "../util/options.js";
|
|
19
|
+
import { useOgImageRuntimeConfig } from "../utils.js";
|
|
19
20
|
import { useChromiumRenderer, useSatoriRenderer } from "./instances.js";
|
|
20
21
|
export function resolvePathCacheKey(e, path) {
|
|
21
22
|
const siteConfig = useSiteConfig(e, {
|
|
@@ -248,16 +249,17 @@ async function fetchPathHtmlAndExtractOptions(e, path, key) {
|
|
|
248
249
|
}
|
|
249
250
|
if (!_payload) {
|
|
250
251
|
const payload2 = extractAndNormaliseOgImageOptions(html);
|
|
251
|
-
if (payload2
|
|
252
|
+
if (payload2 && typeof payload2 === "object" && payload2.socialPreview?.og?.image) {
|
|
253
|
+
const image = payload2.socialPreview.og.image;
|
|
252
254
|
const p = {
|
|
253
255
|
custom: true,
|
|
254
|
-
url:
|
|
256
|
+
url: typeof image === "string" ? image : image
|
|
255
257
|
};
|
|
256
|
-
if (
|
|
257
|
-
p.width =
|
|
258
|
+
if (typeof image === "object" && image["image:width"]) {
|
|
259
|
+
p.width = image["image:width"];
|
|
258
260
|
}
|
|
259
|
-
if (
|
|
260
|
-
p.height =
|
|
261
|
+
if (typeof image === "object" && image["image:height"]) {
|
|
262
|
+
p.height = image["image:height"];
|
|
261
263
|
}
|
|
262
264
|
return p;
|
|
263
265
|
}
|
|
@@ -274,5 +276,8 @@ async function fetchPathHtmlAndExtractOptions(e, path, key) {
|
|
|
274
276
|
value: payload
|
|
275
277
|
});
|
|
276
278
|
}
|
|
277
|
-
return payload
|
|
279
|
+
return typeof payload === "object" ? payload : createError({
|
|
280
|
+
statusCode: 500,
|
|
281
|
+
statusMessage: "[Nuxt OG Image] Invalid payload type."
|
|
282
|
+
});
|
|
278
283
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useNitroOrigin
|
|
1
|
+
import { useNitroOrigin } from "#site-config/server/composables";
|
|
2
|
+
import { useStorage } from "nitropack/runtime";
|
|
2
3
|
import { prefixStorage } from "unstorage";
|
|
3
4
|
export const assets = prefixStorage(useStorage(), "/assets");
|
|
4
5
|
export async function loadFont({ e, publicStoragePath }, font) {
|
|
@@ -11,7 +12,7 @@ export async function loadFont({ e, publicStoragePath }, font) {
|
|
|
11
12
|
const decoder = new TextDecoder();
|
|
12
13
|
fontData = decoder.decode(fontData);
|
|
13
14
|
}
|
|
14
|
-
font.data = Buffer.from(fontData, "base64");
|
|
15
|
+
font.data = Buffer.from(String(fontData), "base64");
|
|
15
16
|
return font;
|
|
16
17
|
}
|
|
17
18
|
let data;
|
|
@@ -19,7 +20,7 @@ export async function loadFont({ e, publicStoragePath }, font) {
|
|
|
19
20
|
if (import.meta.dev || import.meta.prerender) {
|
|
20
21
|
const key = `${publicStoragePath}${font.path.replace("./", ":").replace("/", ":")}`;
|
|
21
22
|
if (await useStorage().hasItem(key))
|
|
22
|
-
data = await useStorage().getItemRaw(key);
|
|
23
|
+
data = await useStorage().getItemRaw(key) || void 0;
|
|
23
24
|
} else {
|
|
24
25
|
data = await e.$fetch(font.path, {
|
|
25
26
|
baseURL: useNitroOrigin(e),
|
|
@@ -43,7 +43,7 @@ export default defineSatoriTransformer({
|
|
|
43
43
|
}
|
|
44
44
|
if (node.type === "div") {
|
|
45
45
|
node.props.style.display = "flex";
|
|
46
|
-
if (!node.props?.class?.includes("flex-") && node.props.children.some((child) => BLOCK_ELEMENTS.includes(child.type))) {
|
|
46
|
+
if (!node.props?.class?.includes("flex-") && Array.isArray(node.props.children) && node.props.children.some((child) => BLOCK_ELEMENTS.includes(child.type))) {
|
|
47
47
|
node.props.style.flexDirection = "column";
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { useNitroOrigin
|
|
1
|
+
import { useNitroOrigin } from "#site-config/server/composables/useNitroOrigin";
|
|
2
2
|
import sizeOf from "image-size";
|
|
3
|
+
import { useStorage } from "nitropack/runtime/storage";
|
|
3
4
|
import { withBase, withoutLeadingSlash } from "ufo";
|
|
4
|
-
import { toBase64Image } from "../../../../
|
|
5
|
+
import { toBase64Image } from "../../../../shared.js";
|
|
5
6
|
import { decodeHtml } from "../../../util/encoding.js";
|
|
6
7
|
import { logger } from "../../../util/logger.js";
|
|
7
8
|
import { defineSatoriTransformer } from "../utils.js";
|
|
@@ -41,8 +42,10 @@ export default defineSatoriTransformer([
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
|
-
if (imageBuffer)
|
|
45
|
-
|
|
45
|
+
if (imageBuffer) {
|
|
46
|
+
const buffer = imageBuffer instanceof ArrayBuffer ? imageBuffer : imageBuffer.buffer;
|
|
47
|
+
node.props.src = toBase64Image(buffer);
|
|
48
|
+
}
|
|
46
49
|
} else if (!src.startsWith("data:")) {
|
|
47
50
|
src = decodeHtml(src);
|
|
48
51
|
node.props.src = src;
|
|
@@ -71,7 +74,8 @@ export default defineSatoriTransformer([
|
|
|
71
74
|
}
|
|
72
75
|
if (typeof node.props.src === "string" && node.props.src.startsWith("/")) {
|
|
73
76
|
if (imageBuffer) {
|
|
74
|
-
|
|
77
|
+
const buffer = imageBuffer instanceof ArrayBuffer ? imageBuffer : imageBuffer.buffer;
|
|
78
|
+
node.props.src = toBase64Image(buffer);
|
|
75
79
|
} else {
|
|
76
80
|
node.props.src = `${withBase(src, `${useNitroOrigin(e)}`)}?${Date.now()}`;
|
|
77
81
|
}
|
|
@@ -90,7 +94,8 @@ export default defineSatoriTransformer([
|
|
|
90
94
|
const srcWithoutBase = src.replace(runtimeConfig.app.baseURL, "/");
|
|
91
95
|
const imageBuffer = await resolveLocalFilePathImage(publicStoragePath, srcWithoutBase);
|
|
92
96
|
if (imageBuffer) {
|
|
93
|
-
const
|
|
97
|
+
const buffer = imageBuffer instanceof ArrayBuffer ? imageBuffer : imageBuffer.buffer;
|
|
98
|
+
const base64 = toBase64Image(buffer);
|
|
94
99
|
node.props.style.backgroundImage = `url(${base64})`;
|
|
95
100
|
}
|
|
96
101
|
} else {
|
|
@@ -3,7 +3,8 @@ import { theme } from "#og-image-virtual/unocss-config.mjs";
|
|
|
3
3
|
import compatibility from "#og-image/compatibility";
|
|
4
4
|
import { defu } from "defu";
|
|
5
5
|
import { sendError } from "h3";
|
|
6
|
-
import { normaliseFontInput
|
|
6
|
+
import { normaliseFontInput } from "../../../shared.js";
|
|
7
|
+
import { useOgImageRuntimeConfig } from "../../utils.js";
|
|
7
8
|
import { loadFont } from "./font.js";
|
|
8
9
|
import { useResvg, useSatori, useSharp } from "./instances.js";
|
|
9
10
|
import { createVNodes } from "./vnodes.js";
|
|
@@ -16,7 +17,7 @@ async function resolveFonts(event) {
|
|
|
16
17
|
if (fontCache) {
|
|
17
18
|
for (const font of normalisedFonts) {
|
|
18
19
|
if (await fontCache.hasItem(font.cacheKey)) {
|
|
19
|
-
font.data = await fontCache.getItemRaw(font.cacheKey);
|
|
20
|
+
font.data = await fontCache.getItemRaw(font.cacheKey) || void 0;
|
|
20
21
|
preloadedFonts.push(font);
|
|
21
22
|
} else {
|
|
22
23
|
if (!fontPromises[font.cacheKey]) {
|
|
@@ -58,6 +59,8 @@ export async function createSvg(event) {
|
|
|
58
59
|
async function createPng(event) {
|
|
59
60
|
const { resvgOptions } = useOgImageRuntimeConfig();
|
|
60
61
|
const svg = await createSvg(event);
|
|
62
|
+
if (!svg)
|
|
63
|
+
throw new Error("Failed to create SVG");
|
|
61
64
|
const Resvg = await useResvg();
|
|
62
65
|
const resvg = new Resvg(svg, defu(
|
|
63
66
|
event.options.resvg,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { NuxtIslandResponse } from 'nuxt/
|
|
1
|
+
import type { NuxtIslandResponse } from 'nuxt/app';
|
|
2
2
|
import type { OgImageRenderEventContext } from '../../../../types.js';
|
|
3
|
-
export declare function applyEmojis(ctx: OgImageRenderEventContext, island: NuxtIslandResponse): Promise<
|
|
3
|
+
export declare function applyEmojis(ctx: OgImageRenderEventContext, island: NuxtIslandResponse): Promise<string | boolean>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { NuxtIslandResponse } from 'nuxt/
|
|
1
|
+
import type { NuxtIslandResponse } from 'nuxt/app';
|
|
2
2
|
import type { OgImageRenderEventContext } from '../../../../types.js';
|
|
3
3
|
export declare function applyInlineCss(ctx: OgImageRenderEventContext, island: NuxtIslandResponse): Promise<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useNitroOrigin } from "#
|
|
1
|
+
import { useNitroOrigin } from "#site-config/server/composables/useNitroOrigin";
|
|
2
2
|
import { createConsola } from "consola";
|
|
3
3
|
import { useCssInline } from "../instances.js";
|
|
4
4
|
export async function applyInlineCss(ctx, island) {
|
|
@@ -11,7 +11,7 @@ export async function applyInlineCss(ctx, island) {
|
|
|
11
11
|
}
|
|
12
12
|
let linksToCss = [];
|
|
13
13
|
if (import.meta.dev) {
|
|
14
|
-
|
|
14
|
+
const cssResults = componentInlineStyles.length ? await Promise.all(
|
|
15
15
|
componentInlineStyles.map((l) => {
|
|
16
16
|
const url = l.href.endsWith("lang.css") ? `${l.href}&hmr=false` : l.href;
|
|
17
17
|
return e.$fetch(url, {
|
|
@@ -19,14 +19,15 @@ export async function applyInlineCss(ctx, island) {
|
|
|
19
19
|
baseURL: useNitroOrigin(e)
|
|
20
20
|
}).then((res) => {
|
|
21
21
|
if (res.includes("__vite__css"))
|
|
22
|
-
return res.match(/__vite__css = "([^"]+)"/)?.[1];
|
|
22
|
+
return res.match(/__vite__css = "([^"]+)"/)?.[1] || "";
|
|
23
23
|
return res.trim().split("\n").filter((l2) => !l2.startsWith("//")).join("\n").trim();
|
|
24
24
|
}).catch(() => {
|
|
25
25
|
return "";
|
|
26
26
|
});
|
|
27
27
|
})
|
|
28
|
-
)
|
|
29
|
-
|
|
28
|
+
) : [];
|
|
29
|
+
linksToCss = cssResults;
|
|
30
|
+
css = [linksToCss.join("\n"), css].join("\n");
|
|
30
31
|
}
|
|
31
32
|
if (!css.trim().length)
|
|
32
33
|
return false;
|
|
@@ -2,8 +2,9 @@ import { theme } from "#og-image-virtual/unocss-config.mjs";
|
|
|
2
2
|
import { createHeadCore } from "@unhead/vue";
|
|
3
3
|
import { renderSSRHead } from "@unhead/vue/server";
|
|
4
4
|
import { createError } from "h3";
|
|
5
|
-
import { normaliseFontInput
|
|
5
|
+
import { normaliseFontInput } from "../../../shared.js";
|
|
6
6
|
import { fetchIsland } from "../../util/kit.js";
|
|
7
|
+
import { useOgImageRuntimeConfig } from "../../utils.js";
|
|
7
8
|
import { applyEmojis } from "../satori/transforms/emojis.js";
|
|
8
9
|
export async function html(ctx) {
|
|
9
10
|
const { options } = ctx;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: import("nitropack").NitroAppPlugin;
|
|
2
2
|
export default _default;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineNitroPlugin } from "#imports";
|
|
2
1
|
import { prerenderOptionsCache } from "#og-image-cache";
|
|
3
2
|
import { createSitePathResolver } from "#site-config/server/composables/utils";
|
|
3
|
+
import { defineNitroPlugin } from "nitropack/runtime";
|
|
4
4
|
import { parseURL } from "ufo";
|
|
5
|
-
import { isInternalRoute } from "../../
|
|
5
|
+
import { isInternalRoute } from "../../shared.js";
|
|
6
6
|
import { extractAndNormaliseOgImageOptions, resolvePathCacheKey } from "../og-image/context.js";
|
|
7
7
|
import { createNitroRouteRuleMatcher } from "../util/kit.js";
|
|
8
8
|
export default defineNitroPlugin(async (nitro) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useSiteConfig } from "#imports";
|
|
2
1
|
import { componentNames } from "#og-image-virtual/component-names.mjs";
|
|
3
2
|
import compatibility from "#og-image/compatibility";
|
|
3
|
+
import { useSiteConfig } from "#site-config/server/composables/useSiteConfig";
|
|
4
4
|
import { defineEventHandler, setHeader } from "h3";
|
|
5
|
-
import { useOgImageRuntimeConfig } from "
|
|
5
|
+
import { useOgImageRuntimeConfig } from "../utils.js";
|
|
6
6
|
export default defineEventHandler(async (e) => {
|
|
7
7
|
setHeader(e, "Content-Type", "application/json");
|
|
8
8
|
const runtimeConfig = useOgImageRuntimeConfig();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useStorage } from "#imports";
|
|
2
1
|
import { createError, getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3";
|
|
2
|
+
import { useStorage } from "nitropack/runtime";
|
|
3
3
|
import { hash } from "ohash";
|
|
4
4
|
import { withTrailingSlash } from "ufo";
|
|
5
5
|
import { prefixStorage } from "unstorage";
|
|
6
6
|
export async function useOgImageBufferCache(ctx, options) {
|
|
7
7
|
const maxAge = Number(options.cacheMaxAgeSeconds);
|
|
8
|
-
let enabled = !import.meta.dev && import.meta.env
|
|
8
|
+
let enabled = !import.meta.dev && import.meta.env?.MODE !== "test" && maxAge > 0;
|
|
9
9
|
const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/"));
|
|
10
10
|
const key = ctx.key;
|
|
11
11
|
let cachedItem = false;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createError, getQuery, H3Error, proxyRequest, sendRedirect, setHeader, setResponseHeader } from "h3";
|
|
2
2
|
import { parseURL } from "ufo";
|
|
3
|
-
import { normaliseFontInput
|
|
3
|
+
import { normaliseFontInput } from "../../shared.js";
|
|
4
4
|
import { resolveContext } from "../og-image/context.js";
|
|
5
5
|
import { assets } from "../og-image/satori/font.js";
|
|
6
6
|
import { html } from "../og-image/templates/html.js";
|
|
7
|
+
import { useOgImageRuntimeConfig } from "../utils.js";
|
|
7
8
|
import { useOgImageBufferCache } from "./cache.js";
|
|
8
9
|
export async function fontEventHandler(e) {
|
|
9
10
|
const path = parseURL(e.path).pathname;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { NitroRouteRules } from 'nitropack';
|
|
3
|
-
import type { NuxtIslandResponse } from 'nuxt/
|
|
3
|
+
import type { NuxtIslandResponse } from 'nuxt/app';
|
|
4
4
|
export declare function fetchIsland(e: H3Event, component: string, props: Record<string, any>): Promise<NuxtIslandResponse>;
|
|
5
5
|
export declare function withoutQuery(path: string): string;
|
|
6
6
|
export declare function createNitroRouteRuleMatcher(): ((path: string) => NitroRouteRules);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useRuntimeConfig } from "#imports";
|
|
2
1
|
import { defu } from "defu";
|
|
2
|
+
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
3
|
import { hash } from "ohash";
|
|
4
4
|
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
|
|
5
5
|
import { withoutBase, withoutTrailingSlash } from "ufo";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import { stringify } from "devalue";
|
|
3
3
|
import { withQuery } from "ufo";
|
|
4
|
-
import { generateMeta
|
|
4
|
+
import { generateMeta } from "../../shared.js";
|
|
5
|
+
import { getOgImagePath, useOgImageRuntimeConfig } from "../utils.js";
|
|
5
6
|
import { normaliseOptions } from "./options.js";
|
|
6
7
|
export function nuxtContentPlugin(nitroApp) {
|
|
7
8
|
const { isNuxtContentDocumentDriven, strictNuxtContentPaths, defaults } = useOgImageRuntimeConfig();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OgImageOptions, OgImageRuntimeConfig } from '#og-image/types';
|
|
2
|
+
import type { H3Event } from 'h3';
|
|
3
|
+
export declare function getOgImagePath(pagePath: string, _options?: Partial<OgImageOptions>): string;
|
|
4
|
+
export declare function useOgImageRuntimeConfig(e?: H3Event): OgImageRuntimeConfig;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
|
+
import { joinURL, withQuery } from "ufo";
|
|
3
|
+
export function getOgImagePath(pagePath, _options) {
|
|
4
|
+
const baseURL = useRuntimeConfig().app.baseURL;
|
|
5
|
+
const extension = _options?.extension || useOgImageRuntimeConfig().defaults.extension;
|
|
6
|
+
const path = joinURL("/", baseURL, `__og-image__/${import.meta.prerender ? "static" : "image"}`, pagePath, `og.${extension}`);
|
|
7
|
+
if (Object.keys(_options?._query || {}).length) {
|
|
8
|
+
return withQuery(path, _options._query);
|
|
9
|
+
}
|
|
10
|
+
return path;
|
|
11
|
+
}
|
|
12
|
+
export function useOgImageRuntimeConfig(e) {
|
|
13
|
+
const c = useRuntimeConfig(e);
|
|
14
|
+
return {
|
|
15
|
+
...c["nuxt-og-image"],
|
|
16
|
+
app: {
|
|
17
|
+
baseURL: c.app.baseURL
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
package/dist/runtime/shared.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { ResolvableMeta } from '@unhead/vue';
|
|
2
|
-
import type { OgImageOptions, OgImagePrebuilt,
|
|
3
|
-
export * from './pure.js';
|
|
2
|
+
import type { InputFontConfig, OgImageOptions, OgImagePrebuilt, ResolvedFontConfig } from './types.js';
|
|
4
3
|
export declare function generateMeta(url: OgImagePrebuilt['url'] | string, resolvedOptions: OgImageOptions | OgImagePrebuilt): ResolvableMeta[];
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
4
|
+
export declare function toBase64Image(data: string | ArrayBuffer): string;
|
|
5
|
+
export declare function isInternalRoute(path: string): boolean;
|
|
6
|
+
export declare function separateProps(options: OgImageOptions | undefined, ignoreKeys?: string[]): {
|
|
7
|
+
props: Record<string, any>;
|
|
8
|
+
};
|
|
9
|
+
export declare function normaliseFontInput(fonts: InputFontConfig[]): ResolvedFontConfig[];
|
|
10
|
+
export declare function withoutQuery(path: string): string;
|
|
11
|
+
export declare function getExtension(path: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated Please use `#og-image/app/utils` instead.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useOgImageRuntimeConfig(): {};
|
package/dist/runtime/shared.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { joinURL, withQuery } from "ufo";
|
|
1
|
+
import { defu } from "defu";
|
|
3
2
|
import { toValue } from "vue";
|
|
4
|
-
import { getExtension } from "./pure.js";
|
|
5
|
-
export * from "./pure.js";
|
|
6
3
|
export function generateMeta(url, resolvedOptions) {
|
|
7
4
|
const meta = [
|
|
8
5
|
{ property: "og:image", content: url },
|
|
@@ -26,21 +23,110 @@ export function generateMeta(url, resolvedOptions) {
|
|
|
26
23
|
}
|
|
27
24
|
return meta;
|
|
28
25
|
}
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
function detectBase64MimeType(data) {
|
|
27
|
+
const signatures = {
|
|
28
|
+
"R0lGODdh": "image/gif",
|
|
29
|
+
"R0lGODlh": "image/gif",
|
|
30
|
+
"iVBORw0KGgo": "image/png",
|
|
31
|
+
"/9j/": "image/jpeg",
|
|
32
|
+
"UklGR": "image/webp",
|
|
33
|
+
"AAABAA": "image/x-icon"
|
|
34
|
+
};
|
|
35
|
+
for (const s in signatures) {
|
|
36
|
+
if (data.startsWith(s)) {
|
|
37
|
+
return signatures[s];
|
|
38
|
+
}
|
|
35
39
|
}
|
|
36
|
-
return
|
|
40
|
+
return "image/svg+xml";
|
|
37
41
|
}
|
|
38
|
-
export function
|
|
39
|
-
const
|
|
42
|
+
export function toBase64Image(data) {
|
|
43
|
+
const base64 = typeof data === "string" ? data : Buffer.from(data).toString("base64");
|
|
44
|
+
const type = detectBase64MimeType(base64);
|
|
45
|
+
return `data:${type};base64,${base64}`;
|
|
46
|
+
}
|
|
47
|
+
export function isInternalRoute(path) {
|
|
48
|
+
return path.startsWith("/_") || path.startsWith("@");
|
|
49
|
+
}
|
|
50
|
+
function filterIsOgImageOption(key) {
|
|
51
|
+
const keys = [
|
|
52
|
+
"url",
|
|
53
|
+
"extension",
|
|
54
|
+
"width",
|
|
55
|
+
"height",
|
|
56
|
+
"fonts",
|
|
57
|
+
"alt",
|
|
58
|
+
"props",
|
|
59
|
+
"renderer",
|
|
60
|
+
"html",
|
|
61
|
+
"component",
|
|
62
|
+
"renderer",
|
|
63
|
+
"emojis",
|
|
64
|
+
"_query",
|
|
65
|
+
"satori",
|
|
66
|
+
"resvg",
|
|
67
|
+
"sharp",
|
|
68
|
+
"screenshot",
|
|
69
|
+
"cacheMaxAgeSeconds"
|
|
70
|
+
];
|
|
71
|
+
return keys.includes(key);
|
|
72
|
+
}
|
|
73
|
+
export function separateProps(options, ignoreKeys = []) {
|
|
74
|
+
options = options || {};
|
|
75
|
+
const _props = defu(options.props, Object.fromEntries(
|
|
76
|
+
Object.entries({ ...options }).filter(([k]) => !filterIsOgImageOption(k) && !ignoreKeys.includes(k))
|
|
77
|
+
));
|
|
78
|
+
const props = {};
|
|
79
|
+
Object.entries(_props).forEach(([key, val]) => {
|
|
80
|
+
props[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = val;
|
|
81
|
+
});
|
|
40
82
|
return {
|
|
41
|
-
...
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
...Object.fromEntries(
|
|
84
|
+
Object.entries({ ...options }).filter(([k]) => filterIsOgImageOption(k) || ignoreKeys.includes(k))
|
|
85
|
+
),
|
|
86
|
+
props
|
|
45
87
|
};
|
|
46
88
|
}
|
|
89
|
+
export function normaliseFontInput(fonts) {
|
|
90
|
+
return fonts.map((f) => {
|
|
91
|
+
if (typeof f === "string") {
|
|
92
|
+
const vals = f.split(":");
|
|
93
|
+
const includesStyle = vals.length === 3;
|
|
94
|
+
let name, weight, style;
|
|
95
|
+
if (includesStyle) {
|
|
96
|
+
name = vals[0];
|
|
97
|
+
style = vals[1];
|
|
98
|
+
weight = vals[2];
|
|
99
|
+
} else {
|
|
100
|
+
name = vals[0];
|
|
101
|
+
weight = vals[1];
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
cacheKey: f,
|
|
105
|
+
name,
|
|
106
|
+
weight: weight || 400,
|
|
107
|
+
style: style || "normal",
|
|
108
|
+
path: void 0
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
cacheKey: f.key || `${f.name}:${f.style}:${f.weight}`,
|
|
113
|
+
style: "normal",
|
|
114
|
+
weight: 400,
|
|
115
|
+
...f
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export function withoutQuery(path) {
|
|
120
|
+
return path.split("?")[0];
|
|
121
|
+
}
|
|
122
|
+
export function getExtension(path) {
|
|
123
|
+
path = withoutQuery(path);
|
|
124
|
+
const lastSegment = path.split("/").pop() || path;
|
|
125
|
+
const extension = lastSegment.split(".").pop() || lastSegment;
|
|
126
|
+
if (extension === "jpg")
|
|
127
|
+
return "jpeg";
|
|
128
|
+
return extension;
|
|
129
|
+
}
|
|
130
|
+
export function useOgImageRuntimeConfig() {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -119,6 +119,11 @@ export interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
|
|
|
119
119
|
sharp?: SharpOptions & JpegOptions;
|
|
120
120
|
fonts?: InputFontConfig[];
|
|
121
121
|
cacheMaxAgeSeconds?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Social preview metadata
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
socialPreview?: SocialPreviewMetaData;
|
|
122
127
|
/**
|
|
123
128
|
* @internal
|
|
124
129
|
*/
|
|
@@ -169,5 +174,14 @@ export interface SatoriTransformer {
|
|
|
169
174
|
}
|
|
170
175
|
export interface SocialPreviewMetaData {
|
|
171
176
|
twitter?: Record<string, string>;
|
|
172
|
-
og?: Record<string, string
|
|
177
|
+
og?: Record<string, string> & {
|
|
178
|
+
image?: string | {
|
|
179
|
+
'image:width'?: string | number;
|
|
180
|
+
'image:height'?: string | number;
|
|
181
|
+
[key: string]: any;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export interface RouteRulesOgImage extends Partial<OgImageOptions> {
|
|
186
|
+
[key: string]: any;
|
|
173
187
|
}
|