nuxt-og-image 6.7.5 → 6.7.7
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/LICENSE.md +6 -0
- package/dist/chunks/decode.mjs +1087 -0
- package/dist/chunks/tw4.mjs +2 -2
- package/dist/chunks/uno.mjs +19 -5
- package/dist/module.d.ts +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -2
- package/dist/runtime/app/utils/plugins.js +4 -10
- package/dist/runtime/server/og-image/bindings/browser/chrome-launcher.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/browser/cloudflare.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/browser/on-demand.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/browser/playwright.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.js +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.js +6 -7
- package/dist/runtime/server/og-image/bindings/font-assets/node.d.ts +2 -2
- package/dist/runtime/server/og-image/bindings/font-assets/node.js +2 -3
- package/dist/runtime/server/og-image/bindings/resvg/node-dev.js +18 -64
- package/dist/runtime/server/og-image/bindings/takumi/node-dev.js +26 -83
- package/dist/runtime/server/og-image/bindings/worker-queue.d.ts +34 -0
- package/dist/runtime/server/og-image/bindings/worker-queue.js +150 -0
- package/dist/runtime/server/og-image/browser/renderer.js +1 -1
- package/dist/runtime/server/og-image/browser/screenshot.js +2 -1
- package/dist/runtime/server/og-image/context.d.ts +1 -1
- package/dist/runtime/server/og-image/context.js +2 -3
- package/dist/runtime/server/og-image/core/plugins/imageSrc.js +1 -1
- package/dist/runtime/server/og-image/core/transforms/emojis/local.d.ts +2 -17
- package/dist/runtime/server/og-image/core/transforms/emojis/local.js +1 -1
- package/dist/runtime/server/og-image/devtools.d.ts +1 -1
- package/dist/runtime/server/og-image/devtools.js +1 -1
- package/dist/runtime/server/og-image/font-source.d.ts +3 -12
- package/dist/runtime/server/og-image/font-source.js +1 -4
- package/dist/runtime/server/og-image/fonts.d.ts +1 -8
- package/dist/runtime/server/og-image/fonts.js +1 -1
- package/dist/runtime/server/og-image/takumi/renderer.js +2 -2
- package/dist/runtime/server/og-image/templates/html.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/__zero-runtime/image.d.ts +1 -1
- package/dist/runtime/server/routes/__zero-runtime/image.js +1 -1
- package/dist/runtime/server/routes/debug.json.d.ts +1 -10
- package/dist/runtime/server/routes/debug.json.js +1 -1
- package/dist/runtime/server/routes/image.d.ts +1 -1
- package/dist/runtime/server/routes/image.js +1 -1
- package/dist/runtime/server/routes/resolve.d.ts +1 -1
- package/dist/runtime/server/routes/resolve.js +3 -2
- package/dist/runtime/server/util/cache.d.ts +1 -6
- package/dist/runtime/server/util/cache.js +2 -2
- package/dist/runtime/server/util/cloudflare.d.ts +1 -1
- package/dist/runtime/server/util/cloudflareAssets.d.ts +1 -1
- package/dist/runtime/server/util/cloudflareAssets.js +1 -1
- package/dist/runtime/server/util/eventHandlers.d.ts +1 -1
- package/dist/runtime/server/util/eventHandlers.js +1 -1
- package/dist/runtime/server/util/fetchLocalAsset.d.ts +2 -2
- package/dist/runtime/server/util/fetchLocalAsset.js +2 -1
- package/dist/runtime/server/util/kit.d.ts +7 -3
- package/dist/runtime/server/util/kit.js +4 -18
- package/dist/runtime/server/util/options.js +1 -1
- package/dist/runtime/server/util/query.d.ts +1 -1
- package/dist/runtime/server/utils.d.ts +1 -1
- package/dist/runtime/server/utils.js +1 -1
- package/dist/runtime/types.d.ts +12 -10
- package/dist/shared/{nuxt-og-image.D3mV8OQ9.mjs → nuxt-og-image.BMHzg1Vz.mjs} +334 -155
- package/package.json +49 -39
- package/types/virtual.d.ts +15 -0
- package/dist/chunks/tw4.cjs +0 -493
- package/dist/chunks/uno.cjs +0 -234
- package/dist/cli.cjs +0 -1345
- package/dist/cli.d.cts +0 -1
- package/dist/content.cjs +0 -21
- package/dist/content.d.cts +0 -16
- package/dist/module.cjs +0 -39
- package/dist/module.d.cts +0 -219
- package/dist/shared/nuxt-og-image.CMYbz66P.cjs +0 -193
- package/dist/shared/nuxt-og-image.Cctpuv4O.cjs +0 -5867
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
function toError(reason) {
|
|
2
|
+
return reason instanceof Error ? reason : new Error(String(reason));
|
|
3
|
+
}
|
|
4
|
+
function parseWorkerEvent(message) {
|
|
5
|
+
if (!message || typeof message !== "object" || !("_tag" in message))
|
|
6
|
+
return;
|
|
7
|
+
if (message._tag === "ready")
|
|
8
|
+
return { _tag: "ready" };
|
|
9
|
+
if (message._tag !== "response" || !("id" in message) || typeof message.id !== "number" || !("payload" in message))
|
|
10
|
+
return;
|
|
11
|
+
return { _tag: "response", id: message.id, payload: message.payload };
|
|
12
|
+
}
|
|
13
|
+
export function parseWorkerTimeout(value, fallback = 3e4) {
|
|
14
|
+
const timeout = Number(value);
|
|
15
|
+
return Number.isSafeInteger(timeout) && timeout > 0 ? timeout : fallback;
|
|
16
|
+
}
|
|
17
|
+
export function createWorkerQueue(options) {
|
|
18
|
+
const maxAttempts = options.maxAttempts ?? 2;
|
|
19
|
+
const queue = [];
|
|
20
|
+
let active = { _tag: "idle" };
|
|
21
|
+
let workerState = { _tag: "stopped" };
|
|
22
|
+
let requestId = 0;
|
|
23
|
+
let workerGeneration = 0;
|
|
24
|
+
let stopped = false;
|
|
25
|
+
function stopWorker() {
|
|
26
|
+
if (workerState._tag === "stopped")
|
|
27
|
+
return;
|
|
28
|
+
const state = workerState;
|
|
29
|
+
workerState = { _tag: "stopped" };
|
|
30
|
+
if (state._tag === "starting")
|
|
31
|
+
clearTimeout(state.timer);
|
|
32
|
+
state.worker.removeAllListeners();
|
|
33
|
+
void state.worker.terminate().catch(() => {
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function takeActive() {
|
|
37
|
+
if (active._tag === "idle")
|
|
38
|
+
return;
|
|
39
|
+
const state = active;
|
|
40
|
+
active = { _tag: "idle" };
|
|
41
|
+
if (state._tag === "running")
|
|
42
|
+
clearTimeout(state.timer);
|
|
43
|
+
return state.job;
|
|
44
|
+
}
|
|
45
|
+
function continueQueue() {
|
|
46
|
+
queueMicrotask(processQueue);
|
|
47
|
+
}
|
|
48
|
+
function failWorker(reason, failedWorker) {
|
|
49
|
+
if (failedWorker && (workerState._tag === "stopped" || workerState.worker !== failedWorker))
|
|
50
|
+
return;
|
|
51
|
+
stopWorker();
|
|
52
|
+
const job = takeActive();
|
|
53
|
+
if (job) {
|
|
54
|
+
if (job.attempts < maxAttempts) {
|
|
55
|
+
job.attempts++;
|
|
56
|
+
queue.unshift(job);
|
|
57
|
+
} else {
|
|
58
|
+
job.reject(toError(reason));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
continueQueue();
|
|
62
|
+
}
|
|
63
|
+
function startWorker() {
|
|
64
|
+
let newWorker;
|
|
65
|
+
try {
|
|
66
|
+
newWorker = options.createWorker();
|
|
67
|
+
} catch (error) {
|
|
68
|
+
failWorker(error);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const generation = ++workerGeneration;
|
|
72
|
+
const timer = setTimeout(() => {
|
|
73
|
+
failWorker(new Error(`${options.label} worker startup timed out after ${options.startupTimeout}ms`), newWorker);
|
|
74
|
+
}, options.startupTimeout);
|
|
75
|
+
workerState = { _tag: "starting", generation, timer, worker: newWorker };
|
|
76
|
+
newWorker.on("message", (value) => {
|
|
77
|
+
if (workerState._tag === "stopped" || workerState.worker !== newWorker)
|
|
78
|
+
return;
|
|
79
|
+
const message = parseWorkerEvent(value);
|
|
80
|
+
if (!message)
|
|
81
|
+
return;
|
|
82
|
+
if (message._tag === "ready") {
|
|
83
|
+
if (workerState._tag !== "starting")
|
|
84
|
+
return;
|
|
85
|
+
clearTimeout(workerState.timer);
|
|
86
|
+
workerState = { _tag: "ready", generation, worker: newWorker };
|
|
87
|
+
dispatchActive();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (active._tag !== "running" || active.job.id !== message.id)
|
|
91
|
+
return;
|
|
92
|
+
const job = takeActive();
|
|
93
|
+
job.resolve(message.payload);
|
|
94
|
+
processQueue();
|
|
95
|
+
});
|
|
96
|
+
newWorker.on("error", (error) => failWorker(error, newWorker));
|
|
97
|
+
newWorker.on("exit", (code) => failWorker(new Error(`${options.label} worker exited with code ${code}`), newWorker));
|
|
98
|
+
newWorker.unref();
|
|
99
|
+
}
|
|
100
|
+
function dispatchActive() {
|
|
101
|
+
if (active._tag !== "waiting" || workerState._tag !== "ready")
|
|
102
|
+
return;
|
|
103
|
+
const job = active.job;
|
|
104
|
+
const state = workerState;
|
|
105
|
+
const timer = setTimeout(() => {
|
|
106
|
+
if (active._tag !== "running" || active.job !== job)
|
|
107
|
+
return;
|
|
108
|
+
stopWorker();
|
|
109
|
+
takeActive().reject(new Error(`${options.label} render timed out after ${options.executionTimeout}ms`));
|
|
110
|
+
continueQueue();
|
|
111
|
+
}, options.executionTimeout);
|
|
112
|
+
active = { _tag: "running", job, timer };
|
|
113
|
+
try {
|
|
114
|
+
state.worker.postMessage(job.buildMessage({ id: job.id, generation: state.generation }));
|
|
115
|
+
} catch (error) {
|
|
116
|
+
stopWorker();
|
|
117
|
+
takeActive().reject(toError(error));
|
|
118
|
+
continueQueue();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function processQueue() {
|
|
122
|
+
if (stopped || active._tag !== "idle")
|
|
123
|
+
return;
|
|
124
|
+
const job = queue.shift();
|
|
125
|
+
if (!job)
|
|
126
|
+
return;
|
|
127
|
+
active = { _tag: "waiting", job };
|
|
128
|
+
if (workerState._tag === "stopped")
|
|
129
|
+
startWorker();
|
|
130
|
+
else if (workerState._tag === "ready")
|
|
131
|
+
dispatchActive();
|
|
132
|
+
}
|
|
133
|
+
function enqueue(buildMessage) {
|
|
134
|
+
if (stopped)
|
|
135
|
+
return Promise.reject(new Error(`${options.label} worker queue is shut down`));
|
|
136
|
+
return new Promise((resolve, reject) => {
|
|
137
|
+
queue.push({ id: ++requestId, buildMessage, resolve, reject, attempts: 1 });
|
|
138
|
+
processQueue();
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function shutdown() {
|
|
142
|
+
stopped = true;
|
|
143
|
+
stopWorker();
|
|
144
|
+
const error = new Error(`${options.label} worker terminated`);
|
|
145
|
+
takeActive()?.reject(error);
|
|
146
|
+
for (const job of queue.splice(0))
|
|
147
|
+
job.reject(error);
|
|
148
|
+
}
|
|
149
|
+
return { enqueue, shutdown };
|
|
150
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { withQuery } from "ufo";
|
|
2
2
|
import { toValue } from "vue";
|
|
3
|
+
import { fetchWithEvent } from "#nuxtseo/nitro";
|
|
3
4
|
import { getNitroOrigin } from "#site-config/server/composables";
|
|
4
5
|
import { buildOgImageUrl } from "../../../shared.js";
|
|
5
6
|
import { getFetchTimeout } from "../../util/fetchTimeout.js";
|
|
@@ -77,7 +78,7 @@ export async function createScreenshot({ basePath, e, options, extension, timing
|
|
|
77
78
|
logger.warn("The `html` option is deprecated and will be removed in the next major version. Use a Vue component instead.");
|
|
78
79
|
}
|
|
79
80
|
if (import.meta.prerender && !options.html) {
|
|
80
|
-
options.html = await timings.measure("html-fetch", () => e
|
|
81
|
+
options.html = await timings.measure("html-fetch", () => fetchWithEvent(e, path, { timeout: getFetchTimeout(runtimeConfig) }).catch((err) => {
|
|
81
82
|
void err;
|
|
82
83
|
return void 0;
|
|
83
84
|
}));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { H3Error, H3Event } from 'h3';
|
|
1
|
+
import type { H3Error, H3Event } from '#nuxtseo/h3';
|
|
2
2
|
import type { OgImageRenderEventContext } from '../../types.js';
|
|
3
3
|
export declare function resolvePathCacheKey(e: H3Event, path: string, resolvedOptions?: Record<string, any>): string;
|
|
4
4
|
export declare function resolveContext(e: H3Event): Promise<H3Error | OgImageRenderEventContext>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
|
-
import { createError } from "h3";
|
|
3
|
-
import { useNitroApp } from "nitropack/runtime";
|
|
4
2
|
import { parseURL, withoutLeadingSlash, withoutTrailingSlash, withQuery } from "ufo";
|
|
5
3
|
import { normalizeKey } from "unstorage";
|
|
4
|
+
import { createError } from "#nuxtseo/h3";
|
|
5
|
+
import { useNitroApp } from "#nuxtseo/nitro";
|
|
6
6
|
import { prerenderOptionsCache } from "#og-image-cache";
|
|
7
7
|
import { getSiteConfig } from "#site-config/server/composables/getSiteConfig";
|
|
8
8
|
import { createSitePathResolver } from "#site-config/server/composables/utils";
|
|
@@ -202,7 +202,6 @@ export async function resolveContext(e) {
|
|
|
202
202
|
basePath,
|
|
203
203
|
options: normalised.options,
|
|
204
204
|
timings,
|
|
205
|
-
// @ts-expect-error hookable v6
|
|
206
205
|
_nitro: useNitroApp()
|
|
207
206
|
};
|
|
208
207
|
const hookTimeout = runtimeConfig.security?.renderTimeout ?? 15e3;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useStorage } from "nitropack/runtime";
|
|
2
1
|
import { withBase, withoutLeadingSlash } from "ufo";
|
|
2
|
+
import { useStorage } from "#nuxtseo/nitro";
|
|
3
3
|
import { getNitroOrigin } from "#site-config/server/composables/getNitroOrigin";
|
|
4
4
|
import { toBase64Image } from "../../../../shared.js";
|
|
5
5
|
import { decodeHtml } from "../../../util/encoding.js";
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import type { OgImageRenderEventContext } from '../../../../../types.js';
|
|
2
|
-
interface IconsData {
|
|
3
|
-
icons: Record<string, {
|
|
4
|
-
body: string;
|
|
5
|
-
width?: number;
|
|
6
|
-
height?: number;
|
|
7
|
-
}>;
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
}
|
|
1
|
+
import type { OgImageIconsData, OgImageRenderEventContext } from '../../../../../types.js';
|
|
11
2
|
declare module '#og-image-virtual/iconify-json-icons.mjs' {
|
|
12
|
-
function loadIcons(): Promise<
|
|
13
|
-
}
|
|
14
|
-
declare module 'nitropack/types' {
|
|
15
|
-
interface NitroApp {
|
|
16
|
-
_ogImageIconsData?: IconsData;
|
|
17
|
-
}
|
|
3
|
+
function loadIcons(): Promise<OgImageIconsData>;
|
|
18
4
|
}
|
|
19
5
|
/**
|
|
20
6
|
* Service function to get emoji SVGs from local iconify JSON files
|
|
@@ -23,4 +9,3 @@ declare module 'nitropack/types' {
|
|
|
23
9
|
* Icons are loaded lazily on first use to avoid 24MB+ memory at startup
|
|
24
10
|
*/
|
|
25
11
|
export declare function getEmojiSvg(ctx: OgImageRenderEventContext, emojiChar: string): Promise<string | null>;
|
|
26
|
-
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useNitroApp } from "
|
|
1
|
+
import { useNitroApp } from "#nuxtseo/nitro";
|
|
2
2
|
import { getEmojiCodePoint, getEmojiIconNames } from "./emoji-utils.js";
|
|
3
3
|
function wrapDefsElements(body) {
|
|
4
4
|
const defsElements = ["linearGradient", "radialGradient", "filter", "clipPath", "mask", "pattern"];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse } from "devalue";
|
|
2
|
-
import { createError } from "h3";
|
|
2
|
+
import { createError } from "#nuxtseo/h3";
|
|
3
3
|
import { htmlPayloadCache } from "#og-image-cache";
|
|
4
4
|
import { extractSocialPreviewTags } from "../../pure.js";
|
|
5
5
|
import { logger } from "../util/logger.js";
|
|
@@ -3,24 +3,15 @@ export declare function fontFormat(src: string): FontFormat;
|
|
|
3
3
|
/**
|
|
4
4
|
* Pick the src to actually load for a parsed font entry.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* subset would hide non-latin glyphs (devanagari, CJK) the static file covers.
|
|
9
|
-
* - Variable fonts (entries carrying `weightRange`) are an exception: the per-weight static
|
|
10
|
-
* `satoriSrc` would discard the wght axis, leaving the runtime to stair-step requested
|
|
11
|
-
* weights through whatever weights fontless happened to download (e.g. requested 400 maps
|
|
12
|
-
* to the closest available static, often 100 or 700, with a hard jump in the middle).
|
|
13
|
-
* Keep the variable WOFF2 primary src so takumi can vary the axis at render time.
|
|
14
|
-
* - Otherwise, uses the primary src when the renderer can parse its format, falling back to
|
|
15
|
-
* satoriSrc as a static alternative when the primary format is unsupported (satori + WOFF2).
|
|
6
|
+
* Uses the primary source when the renderer supports it, preserving WOFF2
|
|
7
|
+
* subsets and variable axes for Takumi. Otherwise it uses the Satori fallback.
|
|
16
8
|
*
|
|
17
9
|
* Returns null when no src on this entry can be parsed by the renderer.
|
|
18
10
|
*/
|
|
19
11
|
export declare function selectFontSource(f: {
|
|
20
12
|
src: string;
|
|
21
13
|
satoriSrc?: string;
|
|
22
|
-
|
|
23
|
-
}, supportedFormats: Set<FontFormat>, preferStatic: boolean): {
|
|
14
|
+
}, supportedFormats: Set<FontFormat>): {
|
|
24
15
|
src: string;
|
|
25
16
|
isStaticFallback: boolean;
|
|
26
17
|
} | null;
|
|
@@ -7,12 +7,9 @@ export function fontFormat(src) {
|
|
|
7
7
|
return "otf";
|
|
8
8
|
return "ttf";
|
|
9
9
|
}
|
|
10
|
-
export function selectFontSource(f, supportedFormats
|
|
10
|
+
export function selectFontSource(f, supportedFormats) {
|
|
11
11
|
const primarySupported = supportedFormats.has(fontFormat(f.src));
|
|
12
12
|
const satoriSupported = !!(f.satoriSrc && supportedFormats.has(fontFormat(f.satoriSrc)));
|
|
13
|
-
const isVariable = !!f.weightRange;
|
|
14
|
-
if (preferStatic && !isVariable && satoriSupported && f.satoriSrc !== f.src)
|
|
15
|
-
return { src: f.satoriSrc, isStaticFallback: true };
|
|
16
13
|
if (primarySupported)
|
|
17
14
|
return { src: f.src, isStaticFallback: false };
|
|
18
15
|
if (satoriSupported)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { H3Event } from 'h3';
|
|
1
|
+
import type { H3Event } from '#nuxtseo/h3';
|
|
2
2
|
import type { OgImageRenderEventContext, RuntimeFontConfig } from '../../types.js';
|
|
3
3
|
import type { FontFormat } from './font-source.js';
|
|
4
4
|
export { buildSubsetFamilyChain, renameSubsetFonts, resolveSubsetChain } from './font-subsets.js';
|
|
@@ -16,13 +16,6 @@ export interface LoadFontsOptions {
|
|
|
16
16
|
fontFamilyOverride?: string;
|
|
17
17
|
/** Codepoints present in the template — fonts whose unicodeRange doesn't intersect are skipped */
|
|
18
18
|
codepoints?: Set<number>;
|
|
19
|
-
/**
|
|
20
|
-
* Prefer the static satoriSrc (full TTF/WOFF from fontless) over the primary src
|
|
21
|
-
* (subset WOFF2 from @nuxt/fonts) when both are usable. Takumi uses this so non-Latin
|
|
22
|
-
* glyphs (devanagari, CJK, etc.) render — @nuxt/fonts CSS often only ships latin
|
|
23
|
-
* subsets for a family, but the fontless static file contains the full glyph set.
|
|
24
|
-
*/
|
|
25
|
-
preferStatic?: boolean;
|
|
26
19
|
}
|
|
27
20
|
export declare function loadAllFontsDebug(component?: string): {
|
|
28
21
|
component: string | undefined;
|
|
@@ -97,7 +97,7 @@ export async function loadAllFonts(event, options) {
|
|
|
97
97
|
}
|
|
98
98
|
const resolved = [];
|
|
99
99
|
for (const f of fonts) {
|
|
100
|
-
const selection = selectFontSource(f, options.supportedFormats
|
|
100
|
+
const selection = selectFontSource(f, options.supportedFormats);
|
|
101
101
|
if (selection)
|
|
102
102
|
resolved.push({ font: f, ...selection });
|
|
103
103
|
}
|
|
@@ -187,7 +187,7 @@ async function createImage(event, format) {
|
|
|
187
187
|
const { fontFamilyOverride, defaultFont } = getDefaultFontFamily(options);
|
|
188
188
|
const nodes = await createTakumiNodes(event);
|
|
189
189
|
const codepoints = extractCodepoints(nodes);
|
|
190
|
-
const fonts = await timings.measure("font-load", () => loadFontsForRenderer(event, { supportedFormats: /* @__PURE__ */ new Set(["ttf", "woff2"]),
|
|
190
|
+
const fonts = await timings.measure("font-load", () => loadFontsForRenderer(event, { supportedFormats: /* @__PURE__ */ new Set(["ttf", "woff2"]), component: options.component, fontFamilyOverride: fontFamilyOverride || defaultFont, codepoints }));
|
|
191
191
|
const fontEntries = dedupeFontsByBinary(fonts);
|
|
192
192
|
const hookTimeout = event.runtimeConfig.security?.renderTimeout ?? 15e3;
|
|
193
193
|
await withTimeout(
|
|
@@ -293,7 +293,7 @@ const TakumiRenderer = {
|
|
|
293
293
|
async debug(e) {
|
|
294
294
|
const [vnodes, fonts] = await Promise.all([
|
|
295
295
|
createTakumiNodes(e),
|
|
296
|
-
loadFontsForRenderer(e, { supportedFormats: /* @__PURE__ */ new Set(["ttf", "woff2"]),
|
|
296
|
+
loadFontsForRenderer(e, { supportedFormats: /* @__PURE__ */ new Set(["ttf", "woff2"]), component: e.options.component })
|
|
297
297
|
]);
|
|
298
298
|
return {
|
|
299
299
|
vnodes,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHead, renderSSRHead } from "@unhead/vue/server";
|
|
2
|
-
import { createError } from "h3";
|
|
2
|
+
import { createError } from "#nuxtseo/h3";
|
|
3
3
|
import resolvedFonts from "#og-image/fonts";
|
|
4
4
|
import { fetchIsland } from "../../util/kit.js";
|
|
5
5
|
import { applyEmojis } from "../core/transforms/emojis/index.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: any;
|
|
2
2
|
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parse } from "devalue";
|
|
2
|
-
import { appendResponseHeader } from "h3";
|
|
3
|
-
import { defineNitroPlugin } from "nitropack/runtime";
|
|
4
2
|
import { parseURL } from "ufo";
|
|
3
|
+
import { appendResponseHeader } from "#nuxtseo/h3";
|
|
4
|
+
import { defineNitroPlugin } from "#nuxtseo/nitro";
|
|
5
5
|
import { prerenderOptionsCache } from "#og-image-cache";
|
|
6
6
|
import { createSitePathResolver } from "#site-config/server/composables/utils";
|
|
7
7
|
import { isInternalRoute } from "../../shared.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: any;
|
|
2
2
|
export default _default;
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
2
|
-
siteConfigUrl: string;
|
|
3
|
-
origin: string;
|
|
4
|
-
componentNames: any;
|
|
5
|
-
runtimeConfig: import("../../types.js").OgImageRuntimeConfig;
|
|
6
|
-
compatibility: any;
|
|
7
|
-
resolvedFonts: any;
|
|
8
|
-
availableFonts: any;
|
|
9
|
-
fontRequirements: any;
|
|
10
|
-
}>>;
|
|
1
|
+
declare const _default: any;
|
|
11
2
|
export default _default;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineEventHandler, setHeader } from "h3";
|
|
1
|
+
import { defineEventHandler, setHeader } from "#nuxtseo/h3";
|
|
2
2
|
import { componentNames } from "#og-image-virtual/component-names.mjs";
|
|
3
3
|
import compatibility from "#og-image/compatibility";
|
|
4
4
|
import { fontRequirements } from "#og-image/font-requirements";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: any;
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default:
|
|
1
|
+
declare const _default: any;
|
|
2
2
|
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createError, defineEventHandler, getRequestHost, sendRedirect } from "h3";
|
|
2
1
|
import { parseURL, withLeadingSlash, withQuery } from "ufo";
|
|
2
|
+
import { createError, defineEventHandler, getRequestHost, sendRedirect } from "#nuxtseo/h3";
|
|
3
|
+
import { fetchWithEvent } from "#nuxtseo/nitro";
|
|
3
4
|
import { getSiteConfig } from "#site-config/server/composables/getSiteConfig";
|
|
4
5
|
import { isInternalRoute } from "../../shared.js";
|
|
5
6
|
import { getEventQuery } from "../util/query.js";
|
|
@@ -98,7 +99,7 @@ export default defineEventHandler(async (event) => {
|
|
|
98
99
|
forwardQuery[k] = v;
|
|
99
100
|
}
|
|
100
101
|
const fetchPath = withQuery(withLeadingSlash(targetPath), forwardQuery);
|
|
101
|
-
const html = await event
|
|
102
|
+
const html = await fetchWithEvent(event, fetchPath, {
|
|
102
103
|
headers: { accept: "text/html" },
|
|
103
104
|
responseType: "text"
|
|
104
105
|
}).catch((err) => {
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import type { H3Error } from 'h3';
|
|
1
|
+
import type { H3Error } from '#nuxtseo/h3';
|
|
2
2
|
import type { OgImageRenderEventContext } from '../../types.js';
|
|
3
|
-
declare module 'nitropack/types' {
|
|
4
|
-
interface NitroApp {
|
|
5
|
-
_ogImageCacheBackendWarned?: boolean;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
3
|
export declare function useOgImageBufferCache(ctx: OgImageRenderEventContext, options: {
|
|
9
4
|
baseCacheKey: string | false;
|
|
10
5
|
cacheMaxAgeSeconds?: number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fnv1a64Base36 } from "fnv1a-64";
|
|
2
|
-
import { createError, handleCacheHeaders, setHeader, setHeaders } from "h3";
|
|
3
|
-
import { useStorage } from "nitropack/runtime";
|
|
4
2
|
import { withTrailingSlash } from "ufo";
|
|
5
3
|
import { prefixStorage } from "unstorage";
|
|
4
|
+
import { createError, handleCacheHeaders, setHeader, setHeaders } from "#nuxtseo/h3";
|
|
5
|
+
import { useStorage } from "#nuxtseo/nitro";
|
|
6
6
|
import { logger } from "../../logger.js";
|
|
7
7
|
import { getEventQuery } from "./query.js";
|
|
8
8
|
function safeCompare(a, b) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { H3Event } from 'h3';
|
|
1
|
+
import type { H3Event } from '#nuxtseo/h3';
|
|
2
2
|
export declare function imageEventHandler(e: H3Event): Promise<any>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createError, getRequestHost, H3Error, setHeader } from "h3";
|
|
1
|
+
import { createError, getRequestHost, H3Error, setHeader } from "#nuxtseo/h3";
|
|
2
2
|
import { getSiteConfig } from "#site-config/server/composables/getSiteConfig";
|
|
3
3
|
import { logger } from "../../logger.js";
|
|
4
4
|
import { getBuildCachedImage, setBuildCachedImage } from "../og-image/cache/buildCache.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { H3Event } from 'h3';
|
|
1
|
+
import type { H3Event } from '#nuxtseo/h3';
|
|
2
2
|
export interface FetchLocalAssetOptions {
|
|
3
3
|
fetchTimeout: number;
|
|
4
4
|
headers?: Record<string, string>;
|
|
@@ -14,7 +14,7 @@ export interface FetchLocalAssetOptions {
|
|
|
14
14
|
/**
|
|
15
15
|
* Resolve a same-origin asset path to bytes, trying (in order):
|
|
16
16
|
* 1. Cloudflare Workers ASSETS binding
|
|
17
|
-
* 2. Nitro localFetch
|
|
17
|
+
* 2. Nitro localFetch through the event-aware bridge, which resolves dynamic routes too
|
|
18
18
|
* 3. External `$fetch` to the Nitro origin (opt-in)
|
|
19
19
|
*
|
|
20
20
|
* All steps share a single `AbortSignal.timeout(fetchTimeout)` so a broken
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { $fetch } from "ofetch";
|
|
2
|
+
import { fetchWithEvent } from "#nuxtseo/nitro";
|
|
2
3
|
import { getNitroOrigin } from "#site-config/server/composables";
|
|
3
4
|
import { tryCloudflareAssetsFetch } from "./cloudflareAssets.js";
|
|
4
5
|
export async function fetchLocalAsset(event, path, options) {
|
|
@@ -18,7 +19,7 @@ export async function fetchLocalAsset(event, path, options) {
|
|
|
18
19
|
}));
|
|
19
20
|
if (result || expired)
|
|
20
21
|
return result;
|
|
21
|
-
result = await race(event
|
|
22
|
+
result = await race(fetchWithEvent(event, path, {
|
|
22
23
|
responseType: "arrayBuffer",
|
|
23
24
|
signal: deadline,
|
|
24
25
|
timeout: fetchTimeout,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { H3Event } from 'h3';
|
|
2
|
-
import type { NitroRouteRules } from 'nitropack';
|
|
3
1
|
import type { NuxtIslandResponse } from 'nuxt/app';
|
|
2
|
+
import type { H3Event } from '#nuxtseo/h3';
|
|
3
|
+
import type { OgImageOptions } from '../../types.js';
|
|
4
|
+
interface OgImageRouteRules {
|
|
5
|
+
ogImage?: false | OgImageOptions & Record<string, any>;
|
|
6
|
+
}
|
|
4
7
|
export declare function fetchIsland(e: H3Event, component: string, props: Record<string, any>, timeout?: number): Promise<NuxtIslandResponse>;
|
|
5
|
-
export declare function createNitroRouteRuleMatcher(): ((path: string) =>
|
|
8
|
+
export declare function createNitroRouteRuleMatcher(): ((path: string) => OgImageRouteRules);
|
|
9
|
+
export {};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRuntimeConfig } from "
|
|
3
|
-
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
|
|
4
|
-
import { withoutBase, withoutTrailingSlash } from "ufo";
|
|
1
|
+
import { createNitroRouteRuleMatcher as createRouteRuleMatcher } from "nuxtseo-shared/server";
|
|
2
|
+
import { fetchWithEvent, useRuntimeConfig } from "#nuxtseo/nitro";
|
|
5
3
|
import { getIslandHash } from "#og-image/island-hash";
|
|
6
4
|
export function fetchIsland(e, component, props, timeout) {
|
|
7
5
|
const hashId = getIslandHash({ name: component, props });
|
|
8
6
|
const signal = timeout ? AbortSignal.timeout(timeout) : void 0;
|
|
9
|
-
return e
|
|
7
|
+
return fetchWithEvent(e, `/__nuxt_island/${component}_${hashId}.json`, {
|
|
10
8
|
params: {
|
|
11
9
|
props: JSON.stringify(props)
|
|
12
10
|
},
|
|
@@ -15,17 +13,5 @@ export function fetchIsland(e, component, props, timeout) {
|
|
|
15
13
|
});
|
|
16
14
|
}
|
|
17
15
|
export function createNitroRouteRuleMatcher() {
|
|
18
|
-
|
|
19
|
-
const _routeRulesMatcher = toRouteMatcher(
|
|
20
|
-
createRadixRouter({
|
|
21
|
-
routes: Object.fromEntries(
|
|
22
|
-
Object.entries(nitro?.routeRules || {}).map(([path, rules]) => [withoutTrailingSlash(path), rules])
|
|
23
|
-
)
|
|
24
|
-
})
|
|
25
|
-
);
|
|
26
|
-
return (path) => {
|
|
27
|
-
return defu({}, ..._routeRulesMatcher.matchAll(
|
|
28
|
-
withoutBase(withoutTrailingSlash(path.split("?")[0]), app.baseURL)
|
|
29
|
-
).reverse());
|
|
30
|
-
};
|
|
16
|
+
return createRouteRuleMatcher(useRuntimeConfig());
|
|
31
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createError } from "h3";
|
|
1
|
+
import { createError } from "#nuxtseo/h3";
|
|
2
2
|
import { componentNames } from "#og-image-virtual/component-names.mjs";
|
|
3
3
|
const RENDERER_SUFFIXES = ["satori", "browser", "takumi"];
|
|
4
4
|
const RE_RENDERER_SUFFIX_DOT = /\.?(satori|browser|takumi)$/i;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
1
|
import { joinURL } from "ufo";
|
|
2
|
+
import { useRuntimeConfig } from "#nuxtseo/nitro";
|
|
3
3
|
import { componentNames } from "#og-image-virtual/component-names.mjs";
|
|
4
4
|
import { buildOgImageUrl } from "../shared.js";
|
|
5
5
|
import { getCloudflareEnv } from "./util/cloudflare.js";
|