nuxt-og-image 3.0.0-beta.10 → 3.0.0-beta.14
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 +5 -5
- package/dist/client/404.html +5 -5
- package/dist/client/_nuxt/{IconCSS.389cad49.js → IconCSS.59f1542b.js} +1 -1
- package/dist/client/_nuxt/IconCSS.7e8f1f7b.css +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/4222eee5-f71e-4425-9403-92637db48893.json +1 -0
- package/dist/client/_nuxt/entry.03caefbf.js +137 -0
- package/dist/client/_nuxt/entry.3a009184.css +1 -0
- package/dist/client/_nuxt/{error-404.91508473.js → error-404.8bab7a15.js} +1 -1
- package/dist/client/_nuxt/{error-500.b66f3aae.js → error-500.b72200bc.js} +1 -1
- package/dist/client/index.html +5 -5
- package/dist/module.d.mts +40 -23
- package/dist/module.d.ts +40 -23
- package/dist/module.json +2 -2
- package/dist/module.mjs +68 -53
- package/dist/runtime/cache.d.ts +7 -10
- package/dist/runtime/cache.mjs +38 -26
- package/dist/runtime/components/OgImage/OgImage.d.ts +5 -0
- package/dist/runtime/components/OgImage/{index.mjs → OgImage.mjs} +1 -1
- package/dist/runtime/components/OgImage/Screenshot.d.ts +3 -4
- package/dist/runtime/components/OgImage/Screenshot.mjs +1 -1
- package/dist/runtime/components/Templates/Official/SimpleBlog.vue +1 -0
- package/dist/runtime/composables/defineOgImage.d.ts +2 -23
- package/dist/runtime/composables/defineOgImage.mjs +32 -115
- package/dist/runtime/composables/defineOgImageComponent.d.ts +3 -0
- package/dist/runtime/composables/defineOgImageComponent.mjs +8 -0
- package/dist/runtime/composables/defineOgImagePageScreenshot.d.ts +2 -0
- package/dist/runtime/composables/defineOgImagePageScreenshot.mjs +14 -0
- package/dist/runtime/core/bindings/css-inline/node.d.ts +2 -5
- package/dist/runtime/core/bindings/css-inline/node.mjs +2 -10
- package/dist/runtime/core/bindings/resvg/wasm.mjs +2 -5
- package/dist/runtime/core/bindings/satori/wasm.mjs +7 -0
- package/dist/runtime/core/cache/emojis.d.ts +1 -0
- package/dist/runtime/core/cache/emojis.mjs +5 -0
- package/dist/runtime/core/cache/htmlPayload.d.ts +5 -0
- package/dist/runtime/core/cache/htmlPayload.mjs +6 -0
- package/dist/runtime/core/cache/prerender.d.ts +1 -1
- package/dist/runtime/core/font/fetch.d.ts +2 -3
- package/dist/runtime/core/font/fetch.mjs +10 -4
- package/dist/runtime/core/html/applyEmojis.d.ts +3 -0
- package/dist/runtime/core/html/applyEmojis.mjs +37 -0
- package/dist/runtime/core/html/applyInlineCss.d.ts +3 -0
- package/dist/runtime/core/html/applyInlineCss.mjs +32 -0
- package/dist/runtime/core/html/devIframeTemplate.d.ts +2 -0
- package/dist/runtime/core/html/{fetch.mjs → devIframeTemplate.mjs} +8 -31
- package/dist/runtime/core/html/fetchIsland.d.ts +3 -0
- package/dist/runtime/core/html/fetchIsland.mjs +17 -0
- package/dist/runtime/core/options/fetch.d.ts +1 -1
- package/dist/runtime/core/options/fetch.mjs +10 -5
- package/dist/runtime/core/options/normalise.d.ts +2 -2
- package/dist/runtime/core/renderers/chromium/index.mjs +6 -7
- package/dist/runtime/core/renderers/chromium/screenshot.d.ts +2 -3
- package/dist/runtime/core/renderers/chromium/screenshot.mjs +5 -4
- package/dist/runtime/core/renderers/satori/fonts.d.ts +2 -2
- package/dist/runtime/core/renderers/satori/fonts.mjs +2 -2
- package/dist/runtime/core/renderers/satori/index.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/index.mjs +21 -18
- package/dist/runtime/core/renderers/satori/instances.d.ts +3 -0
- package/dist/runtime/core/renderers/satori/instances.mjs +15 -0
- package/dist/runtime/core/renderers/satori/plugins/emojis.mjs +15 -13
- package/dist/runtime/core/renderers/satori/plugins/imageSrc.mjs +8 -4
- package/dist/runtime/core/renderers/satori/utils.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/vnodes.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/vnodes.mjs +14 -6
- package/dist/runtime/core/utils/resolveRendererContext.d.ts +2 -6
- package/dist/runtime/core/utils/resolveRendererContext.mjs +34 -21
- package/dist/runtime/core/utils/wasm.d.ts +1 -0
- package/dist/runtime/core/utils/wasm.mjs +6 -0
- package/dist/runtime/nitro/plugins/nuxt-content.mjs +2 -2
- package/dist/runtime/nitro/plugins/prerender.mjs +2 -2
- package/dist/runtime/nuxt/plugins/nuxt-content-canonical-urls.mjs +1 -1
- package/dist/runtime/nuxt/plugins/route-rule-og-image.server.mjs +14 -47
- package/dist/runtime/nuxt/utils.d.ts +2 -0
- package/dist/runtime/nuxt/utils.mjs +55 -0
- package/dist/runtime/server/routes/__og-image__/debug.json.d.ts +0 -2
- package/dist/runtime/server/routes/__og-image__/debug.json.mjs +2 -7
- package/dist/runtime/server/routes/__og-image__/image.mjs +86 -0
- package/dist/runtime/types.d.ts +57 -24
- package/dist/runtime/utils.d.ts +3 -0
- package/dist/runtime/utils.mjs +11 -0
- package/package.json +17 -32
- package/virtual.d.ts +49 -0
- package/dist/client/_nuxt/IconCSS.8f429b14.css +0 -1
- package/dist/client/_nuxt/builds/meta/3185e4a0-6b15-4476-b2f3-85ef31d35fc6.json +0 -1
- package/dist/client/_nuxt/entry.434c2c45.css +0 -1
- package/dist/client/_nuxt/entry.e62f04d6.js +0 -137
- package/dist/client/grid.png +0 -0
- package/dist/runtime/components/OgImage/Cached.d.ts +0 -5
- package/dist/runtime/components/OgImage/Cached.mjs +0 -10
- package/dist/runtime/components/OgImage/Dynamic.d.ts +0 -8
- package/dist/runtime/components/OgImage/Dynamic.mjs +0 -10
- package/dist/runtime/components/OgImage/Static.d.ts +0 -8
- package/dist/runtime/components/OgImage/Static.mjs +0 -10
- package/dist/runtime/components/OgImage/WithoutCache.d.ts +0 -5
- package/dist/runtime/components/OgImage/WithoutCache.mjs +0 -10
- package/dist/runtime/components/OgImage/index.d.ts +0 -5
- package/dist/runtime/core/bindings/css-inline/mock.d.ts +0 -5
- package/dist/runtime/core/bindings/css-inline/mock.mjs +0 -3
- package/dist/runtime/core/bindings/satori/yoga-wasm.mjs +0 -7
- package/dist/runtime/core/bindings/sharp/wasm.d.ts +0 -2
- package/dist/runtime/core/bindings/sharp/wasm.mjs +0 -2
- package/dist/runtime/core/html/fetch.d.ts +0 -3
- package/dist/runtime/server/routes/__og-image__/image-[path]-og.[extension].mjs +0 -45
- package/dist/runtime/utilts.d.ts +0 -2
- package/dist/runtime/utilts.mjs +0 -8
- /package/dist/runtime/core/bindings/satori/{yoga-wasm.d.ts → wasm.d.ts} +0 -0
- /package/dist/runtime/server/routes/__og-image__/{image-[path]-og.[extension].d.ts → image.d.ts} +0 -0
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import { useNuxt, createResolver, addTemplate, defineNuxtModule, useLogger, hasNuxtModule, addServerPlugin, addPlugin, addServerHandler, addImports, addComponentsDir, addComponent } from '@nuxt/kit';
|
|
3
|
+
import { useNuxt, createResolver, addTemplate, resolvePath, defineNuxtModule, useLogger, hasNuxtModule, addServerPlugin, addPlugin, addServerHandler, addImports, addComponentsDir, addComponent } from '@nuxt/kit';
|
|
4
4
|
import { installNuxtSiteConfig } from 'nuxt-site-config-kit';
|
|
5
5
|
import { provider, env } from 'std-env';
|
|
6
6
|
import { hash } from 'ohash';
|
|
@@ -8,8 +8,10 @@ import { relative } from 'pathe';
|
|
|
8
8
|
import 'nypm';
|
|
9
9
|
import { defu } from 'defu';
|
|
10
10
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
11
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { createHash } from 'node:crypto';
|
|
11
13
|
|
|
12
|
-
const version = "3.0.0-beta.
|
|
14
|
+
const version = "3.0.0-beta.14";
|
|
13
15
|
|
|
14
16
|
const autodetectableProviders = {
|
|
15
17
|
azure_static: "azure",
|
|
@@ -32,8 +34,7 @@ const NodeRuntime = {
|
|
|
32
34
|
"resvg": "node",
|
|
33
35
|
"satori": "node",
|
|
34
36
|
"sharp": "node"
|
|
35
|
-
}
|
|
36
|
-
wasmStrategy: "import"
|
|
37
|
+
}
|
|
37
38
|
};
|
|
38
39
|
const cloudflare = {
|
|
39
40
|
bindings: {
|
|
@@ -42,8 +43,8 @@ const cloudflare = {
|
|
|
42
43
|
"resvg": "wasm",
|
|
43
44
|
"satori": "node",
|
|
44
45
|
"sharp": false
|
|
45
|
-
}
|
|
46
|
-
|
|
46
|
+
}
|
|
47
|
+
// nitro configures wasm
|
|
47
48
|
};
|
|
48
49
|
const awsLambda = {
|
|
49
50
|
bindings: {
|
|
@@ -52,8 +53,7 @@ const awsLambda = {
|
|
|
52
53
|
"resvg": "node",
|
|
53
54
|
"satori": "node",
|
|
54
55
|
"sharp": "node"
|
|
55
|
-
}
|
|
56
|
-
wasmStrategy: "inline"
|
|
56
|
+
}
|
|
57
57
|
};
|
|
58
58
|
const RuntimeCompatibility = {
|
|
59
59
|
"nitro-dev": NodeRuntime,
|
|
@@ -66,8 +66,7 @@ const RuntimeCompatibility = {
|
|
|
66
66
|
"resvg": "wasm",
|
|
67
67
|
"satori": "node",
|
|
68
68
|
"sharp": "node"
|
|
69
|
-
}
|
|
70
|
-
wasmStrategy: "inline"
|
|
69
|
+
}
|
|
71
70
|
},
|
|
72
71
|
"aws-lambda": awsLambda,
|
|
73
72
|
"netlify": awsLambda,
|
|
@@ -79,19 +78,25 @@ const RuntimeCompatibility = {
|
|
|
79
78
|
"satori": "node",
|
|
80
79
|
"sharp": false
|
|
81
80
|
},
|
|
82
|
-
|
|
81
|
+
wasm: {
|
|
82
|
+
rollup: {
|
|
83
|
+
targetEnv: "auto-inline"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
83
86
|
},
|
|
84
87
|
"vercel": awsLambda,
|
|
85
88
|
"vercel-edge": {
|
|
86
89
|
bindings: {
|
|
87
90
|
"chromium": false,
|
|
88
|
-
"css-inline":
|
|
91
|
+
"css-inline": false,
|
|
89
92
|
"resvg": "wasm",
|
|
90
93
|
"satori": "node",
|
|
91
|
-
"sharp":
|
|
94
|
+
"sharp": false
|
|
92
95
|
},
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
wasm: {
|
|
97
|
+
// lowers workers kb size
|
|
98
|
+
esmImport: true
|
|
99
|
+
}
|
|
95
100
|
},
|
|
96
101
|
"cloudflare-pages": cloudflare,
|
|
97
102
|
"cloudflare": cloudflare
|
|
@@ -132,18 +137,15 @@ function applyNitroPresetCompatibility(nitroConfig, options) {
|
|
|
132
137
|
applyBinding("satori"),
|
|
133
138
|
applyBinding("resvg"),
|
|
134
139
|
applyBinding("sharp"),
|
|
140
|
+
applyBinding("css-inline"),
|
|
135
141
|
nitroConfig.alias || {}
|
|
136
142
|
);
|
|
137
|
-
|
|
138
|
-
if (target === "netlify-edge") {
|
|
139
|
-
nitroConfig.wasm = nitroConfig.wasm || {};
|
|
140
|
-
nitroConfig.wasm.rollup = nitroConfig.wasm.rollup || {};
|
|
141
|
-
nitroConfig.wasm.rollup.targetEnv = "auto-inline";
|
|
142
|
-
}
|
|
143
|
-
if (target.includes("edge") || target.includes("cloudflare")) {
|
|
143
|
+
if (Object.values(compatibility.bindings).includes("wasm")) {
|
|
144
144
|
nitroConfig.experimental = nitroConfig.experimental || {};
|
|
145
145
|
nitroConfig.experimental.wasm = true;
|
|
146
146
|
}
|
|
147
|
+
nitroConfig.rollupConfig = nitroConfig.rollupConfig || {};
|
|
148
|
+
nitroConfig.wasm = defu(compatibility.wasm, nitroConfig.wasm);
|
|
147
149
|
return compatibility;
|
|
148
150
|
}
|
|
149
151
|
|
|
@@ -272,13 +274,27 @@ async function setupBuildHandler(config, resolve, nuxt = useNuxt()) {
|
|
|
272
274
|
nitroConfig.alias["utf-8-validate"] = "unenv/runtime/mock/proxy-cjs";
|
|
273
275
|
nitroConfig.alias.queue = "unenv/runtime/mock/proxy-cjs";
|
|
274
276
|
});
|
|
277
|
+
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
278
|
+
nitro.hooks.hook("compiled", async (_nitro) => {
|
|
279
|
+
const configuredEntry = nitro.options.rollupConfig?.output.entryFileNames;
|
|
280
|
+
const serverEntry = resolve(_nitro.options.output.serverDir, typeof configuredEntry === "string" ? configuredEntry : "index.mjs");
|
|
281
|
+
const contents = await readFile(serverEntry, "utf-8");
|
|
282
|
+
const wasmSource = await readFile(await resolvePath("@resvg/resvg-wasm/index_bg.wasm"));
|
|
283
|
+
const wasmHash = sha1(wasmSource);
|
|
284
|
+
const postfix = _nitro.options.preset === "vercel-edge" ? "?module" : "";
|
|
285
|
+
await writeFile(serverEntry, contents.replaceAll('"@resvg/resvg-wasm/index_bg.wasm"', `"./wasm/index_bg-${wasmHash}.wasm${postfix}"`), { encoding: "utf-8" });
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function sha1(source) {
|
|
290
|
+
return createHash("sha1").update(source).digest("hex").slice(0, 16);
|
|
275
291
|
}
|
|
276
292
|
|
|
277
293
|
const module = defineNuxtModule({
|
|
278
294
|
meta: {
|
|
279
295
|
name: "nuxt-og-image",
|
|
280
296
|
compatibility: {
|
|
281
|
-
nuxt: "^3.
|
|
297
|
+
nuxt: "^3.8.2",
|
|
282
298
|
bridge: false
|
|
283
299
|
},
|
|
284
300
|
configKey: "ogImage"
|
|
@@ -287,13 +303,13 @@ const module = defineNuxtModule({
|
|
|
287
303
|
return {
|
|
288
304
|
enabled: true,
|
|
289
305
|
defaults: {
|
|
306
|
+
emojis: "noto",
|
|
290
307
|
renderer: "satori",
|
|
291
308
|
component: "Fallback",
|
|
292
309
|
width: 1200,
|
|
293
310
|
height: 600,
|
|
294
|
-
cache: true,
|
|
295
311
|
// default is to cache the image for 1 day (24 hours)
|
|
296
|
-
|
|
312
|
+
cacheMaxAgeSeconds: 60 * 60 * 24 * 3
|
|
297
313
|
},
|
|
298
314
|
componentDirs: ["OgImage", "OgImageTemplate"],
|
|
299
315
|
runtimeSatori: true,
|
|
@@ -318,9 +334,17 @@ const module = defineNuxtModule({
|
|
|
318
334
|
const { resolve } = createResolver(import.meta.url);
|
|
319
335
|
const preset = resolveNitroPreset(nuxt.options.nitro);
|
|
320
336
|
const compatibility = getPresetNitroPresetCompatibility(preset);
|
|
321
|
-
config.defaults.extension
|
|
322
|
-
|
|
337
|
+
const userConfiguredExtension = config.defaults.extension;
|
|
338
|
+
config.defaults.extension = userConfiguredExtension || "jpg";
|
|
339
|
+
if (!compatibility.bindings.sharp && config.defaults.renderer !== "chromium") {
|
|
340
|
+
if (userConfiguredExtension && ["jpeg", "jpg"].includes(userConfiguredExtension))
|
|
341
|
+
logger.warn("The sharp runtime is not available for this target, disabling sharp and using png instead.");
|
|
323
342
|
config.defaults.extension = "png";
|
|
343
|
+
}
|
|
344
|
+
if (config.runtimeBrowser && !compatibility.bindings.chromium) {
|
|
345
|
+
logger.warn("The Chromium runtime is not available for this target, disabling runtimeBrowser.");
|
|
346
|
+
config.runtimeBrowser = false;
|
|
347
|
+
}
|
|
324
348
|
await installNuxtSiteConfig();
|
|
325
349
|
if (hasNuxtModule("@nuxt/content")) {
|
|
326
350
|
addServerPlugin(resolve("./runtime/nitro/plugins/nuxt-content"));
|
|
@@ -344,24 +368,13 @@ const module = defineNuxtModule({
|
|
|
344
368
|
addServerHandler({
|
|
345
369
|
lazy: true,
|
|
346
370
|
route: "/__og-image__/image/**",
|
|
347
|
-
handler: resolve("./runtime/server/routes/__og-image__/image
|
|
371
|
+
handler: resolve("./runtime/server/routes/__og-image__/image")
|
|
348
372
|
});
|
|
349
373
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
350
|
-
[
|
|
351
|
-
// deprecated
|
|
352
|
-
"Dynamic",
|
|
353
|
-
"Static",
|
|
354
|
-
// new
|
|
355
|
-
"index",
|
|
356
|
-
"Cached",
|
|
357
|
-
"Component",
|
|
358
|
-
"WithoutCache",
|
|
359
|
-
"Screenshot"
|
|
360
|
-
].forEach((name) => {
|
|
361
|
-
name = name === "index" ? "defineOgImage" : `defineOgImage${name}`;
|
|
374
|
+
["defineOgImage", "defineOgImageComponent", "defineOgImageScreenshot"].forEach((name) => {
|
|
362
375
|
addImports({
|
|
363
376
|
name,
|
|
364
|
-
from: resolve(
|
|
377
|
+
from: resolve(`./runtime/composables/${name}`)
|
|
365
378
|
});
|
|
366
379
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"].push(name);
|
|
367
380
|
});
|
|
@@ -374,18 +387,12 @@ const module = defineNuxtModule({
|
|
|
374
387
|
island: true
|
|
375
388
|
});
|
|
376
389
|
[
|
|
377
|
-
// deprecated
|
|
378
|
-
"Static",
|
|
379
|
-
"Dynamic",
|
|
380
390
|
// new
|
|
381
|
-
"
|
|
382
|
-
"
|
|
383
|
-
"WithoutCache",
|
|
384
|
-
"Screenshot"
|
|
391
|
+
"OgImage",
|
|
392
|
+
"OgImageScreenshot"
|
|
385
393
|
].forEach((name) => {
|
|
386
394
|
addComponent({
|
|
387
|
-
|
|
388
|
-
name: name === "index" ? "OgImage" : `OgImage${name}`,
|
|
395
|
+
name,
|
|
389
396
|
filePath: resolve(`./runtime/components/OgImage/${name}`)
|
|
390
397
|
});
|
|
391
398
|
});
|
|
@@ -443,12 +450,13 @@ const module = defineNuxtModule({
|
|
|
443
450
|
return `
|
|
444
451
|
declare module 'nitropack' {
|
|
445
452
|
interface NitroRouteRules {
|
|
446
|
-
ogImage?: false | import('${typesPath}').OgImageOptions
|
|
453
|
+
ogImage?: false | import('${typesPath}').OgImageOptions & Record<string, any>
|
|
447
454
|
}
|
|
448
455
|
interface NitroRouteConfig {
|
|
449
|
-
ogImage?: false | import('${typesPath}').OgImageOptions
|
|
456
|
+
ogImage?: false | import('${typesPath}').OgImageOptions & Record<string, any>
|
|
450
457
|
}
|
|
451
458
|
}
|
|
459
|
+
|
|
452
460
|
declare module '#nuxt-og-image/components' {
|
|
453
461
|
export interface OgImageComponents {
|
|
454
462
|
${componentImports}
|
|
@@ -456,6 +464,11 @@ ${componentImports}
|
|
|
456
464
|
}
|
|
457
465
|
`;
|
|
458
466
|
});
|
|
467
|
+
const cacheEnabled = typeof config.runtimeCacheStorage !== "undefined" && config.runtimeCacheStorage !== false;
|
|
468
|
+
const runtimeCacheStorage = typeof config.runtimeCacheStorage === "boolean" ? "default" : config.runtimeCacheStorage.driver;
|
|
469
|
+
let baseCacheKey = runtimeCacheStorage === "default" ? `/cache/nuxt-og-image@${version}` : `/nuxt-og-image@${version}`;
|
|
470
|
+
if (!cacheEnabled)
|
|
471
|
+
baseCacheKey = false;
|
|
459
472
|
nuxt.hooks.hook("modules:done", async () => {
|
|
460
473
|
nuxt.hooks.callHook("og-image:config", config);
|
|
461
474
|
const normalisedFonts = config.fonts.map((f) => {
|
|
@@ -486,8 +499,10 @@ ${componentImports}
|
|
|
486
499
|
runtimeBrowser: config.runtimeBrowser,
|
|
487
500
|
// @ts-expect-error runtime type
|
|
488
501
|
defaults: config.defaults,
|
|
502
|
+
debug: config.debug,
|
|
489
503
|
// avoid adding credentials
|
|
490
|
-
|
|
504
|
+
// @ts-expect-error runtime type
|
|
505
|
+
baseCacheKey,
|
|
491
506
|
// convert the fonts to uniform type to fix ts issue
|
|
492
507
|
fonts: normalisedFonts,
|
|
493
508
|
hasNuxtIcon: hasNuxtModule("nuxt-icon")
|
package/dist/runtime/cache.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
skipRestore?: boolean;
|
|
8
|
-
}): Promise<{
|
|
9
|
-
cachedItem: false | T;
|
|
1
|
+
import type { H3EventOgImageRender } from './core/utils/resolveRendererContext';
|
|
2
|
+
export declare function useOgImageBufferCache(ctx: H3EventOgImageRender, options: {
|
|
3
|
+
baseCacheKey: string | false;
|
|
4
|
+
cacheMaxAgeSeconds?: number;
|
|
5
|
+
}): Promise<void | {
|
|
6
|
+
cachedItem: false | BufferSource;
|
|
10
7
|
enabled: boolean;
|
|
11
|
-
update: (
|
|
8
|
+
update: (image: BufferSource) => Promise<void>;
|
|
12
9
|
}>;
|
package/dist/runtime/cache.mjs
CHANGED
|
@@ -1,45 +1,57 @@
|
|
|
1
1
|
import { prefixStorage } from "unstorage";
|
|
2
|
-
import { getQuery, setHeader } from "h3";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const cache = prefixStorage(useStorage(),
|
|
10
|
-
const key =
|
|
11
|
-
|
|
12
|
-
let xCacheExpires = 0;
|
|
13
|
-
const newExpires = Date.now() + (options.cacheTtl || 0);
|
|
14
|
-
const purge = typeof getQuery(e).purge !== "undefined";
|
|
2
|
+
import { getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3";
|
|
3
|
+
import { withTrailingSlash } from "ufo";
|
|
4
|
+
import { hash } from "ohash";
|
|
5
|
+
import { useStorage } from "#imports";
|
|
6
|
+
export async function useOgImageBufferCache(ctx, options) {
|
|
7
|
+
const maxAge = Number(options.cacheMaxAgeSeconds);
|
|
8
|
+
const enabled = maxAge > 0;
|
|
9
|
+
const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/"));
|
|
10
|
+
const key = ctx.key;
|
|
11
|
+
const purge = typeof getQuery(ctx.e).purge !== "undefined";
|
|
15
12
|
let cachedItem = false;
|
|
16
|
-
if (
|
|
17
|
-
const { value, expiresAt } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() }));
|
|
13
|
+
if (enabled && await cache.hasItem(key).catch(() => false)) {
|
|
14
|
+
const { value, expiresAt, headers } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() }));
|
|
18
15
|
if (purge) {
|
|
19
|
-
xCacheHeader = "PURGE";
|
|
20
|
-
xCacheExpires = newExpires;
|
|
21
16
|
await cache.removeItem(key).catch(() => {
|
|
22
17
|
});
|
|
23
18
|
} else if (expiresAt > Date.now()) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
cachedItem = Buffer.from(value, "base64");
|
|
20
|
+
if (handleCacheHeaders(ctx.e, {
|
|
21
|
+
modifiedTime: new Date(headers["last-modified"]),
|
|
22
|
+
etag: headers.etag,
|
|
23
|
+
maxAge
|
|
24
|
+
}))
|
|
25
|
+
return;
|
|
26
|
+
setHeaders(ctx.e, headers);
|
|
27
27
|
} else {
|
|
28
|
-
xCacheHeader = "MISS";
|
|
29
|
-
xCacheExpires = expiresAt;
|
|
30
28
|
await cache.removeItem(key).catch(() => {
|
|
31
29
|
});
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
|
-
if (
|
|
35
|
-
setHeader(e,
|
|
36
|
-
setHeader(e,
|
|
32
|
+
if (!enabled) {
|
|
33
|
+
setHeader(ctx.e, "Cache-Control", "no-cache, no-store, must-revalidate");
|
|
34
|
+
setHeader(ctx.e, "Pragma", "no-cache");
|
|
35
|
+
setHeader(ctx.e, "Expires", "0");
|
|
37
36
|
}
|
|
38
37
|
return {
|
|
39
38
|
enabled,
|
|
40
39
|
cachedItem,
|
|
41
40
|
async update(item) {
|
|
42
|
-
|
|
41
|
+
const value = Buffer.from(item).toString("base64");
|
|
42
|
+
const headers = {
|
|
43
|
+
// avoid multi-tenancy cache issues
|
|
44
|
+
"Vary": "accept-encoding, host",
|
|
45
|
+
"etag": `W/"${hash(value)}"`,
|
|
46
|
+
"last-modified": (/* @__PURE__ */ new Date()).toUTCString(),
|
|
47
|
+
"cache-control": `public, s-maxage=${maxAge}, stale-while-revalidate`
|
|
48
|
+
};
|
|
49
|
+
setHeaders(ctx.e, headers);
|
|
50
|
+
enabled && await cache.setItem(key, {
|
|
51
|
+
value,
|
|
52
|
+
headers,
|
|
53
|
+
expiresAt: Date.now() + maxAge * 1e3
|
|
54
|
+
});
|
|
43
55
|
}
|
|
44
56
|
};
|
|
45
57
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { OgImageOptions } from '../../types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<OgImageOptions<"Fallback">, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<OgImageOptions<"Fallback">>, {
|
|
3
|
+
props?: any;
|
|
4
|
+
}, {}>;
|
|
5
|
+
export default _default;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const _default: import("vue").DefineComponent<
|
|
3
|
-
|
|
4
|
-
[x: number]: any;
|
|
1
|
+
import type { OgImagePageScreenshotOptions } from '../../types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<OgImagePageScreenshotOptions, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<OgImagePageScreenshotOptions>, {
|
|
3
|
+
props?: any;
|
|
5
4
|
}, {}>;
|
|
6
5
|
export default _default;
|
|
@@ -1,23 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import type { OgImageComponents } from '#nuxt-og-image/components';
|
|
4
|
-
export declare function defineOgImageScreenshot(options?: OgImageScreenshotOptions): void;
|
|
5
|
-
/**
|
|
6
|
-
* @param options
|
|
7
|
-
* @deprecated Use `defineOgImage` or `defineOgImageCached` instead
|
|
8
|
-
*/
|
|
9
|
-
export declare function defineOgImageStatic(options?: OgImageOptions): void;
|
|
10
|
-
export declare function defineOgImageCached(options?: OgImageOptions): void;
|
|
11
|
-
export declare function defineOgImageWithoutCache(options?: OgImageOptions): void;
|
|
12
|
-
/**
|
|
13
|
-
* @param options
|
|
14
|
-
* @deprecated Use `defineOgImageWithoutCache` instead
|
|
15
|
-
*/
|
|
16
|
-
export declare function defineOgImageDynamic(options?: OgImageOptions): void;
|
|
17
|
-
type OgImagePrebuilt = {
|
|
18
|
-
url: string;
|
|
19
|
-
} & Pick<OgImageOptions, 'width' | 'height' | 'alt'>;
|
|
20
|
-
type ExtractComponentProps<T extends Component> = T extends new (...args: any) => any ? Omit<InstanceType<T>['$props'], keyof ComponentCustomProps | keyof VNodeProps | keyof AllowedComponentProps> : never;
|
|
21
|
-
export declare function defineOgImageComponent<T extends keyof OgImageComponents>(component: T, props: ExtractComponentProps<OgImageComponents[T]>, options?: OgImageOptions): void;
|
|
22
|
-
export declare function defineOgImage(_options?: OgImagePrebuilt | OgImageOptions): void;
|
|
23
|
-
export {};
|
|
1
|
+
import type { DefineOgImageInput } from '../types';
|
|
2
|
+
export declare function defineOgImage(_options?: DefineOgImageInput): void;
|
|
@@ -1,124 +1,41 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import { appendHeader } from "h3";
|
|
3
|
-
import {
|
|
3
|
+
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
|
|
4
|
+
import { withoutBase } from "ufo";
|
|
5
|
+
import { getOgImagePath } from "../utils.mjs";
|
|
4
6
|
import { normaliseOptions } from "../core/options/normalise.mjs";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
import { createOgImageMeta } from "../nuxt/utils.mjs";
|
|
8
|
+
import { useNuxtApp, useRequestEvent, useRouter, useRuntimeConfig } from "#imports";
|
|
9
|
+
export function defineOgImage(_options = {}) {
|
|
10
|
+
if (!import.meta.server)
|
|
11
|
+
return;
|
|
12
|
+
const nuxtApp = useNuxtApp();
|
|
13
|
+
const ogImageInstances = nuxtApp.ssrContext._ogImageInstances || [];
|
|
14
|
+
const basePath = useRouter().currentRoute.value?.path;
|
|
15
|
+
const _routeRulesMatcher = toRouteMatcher(
|
|
16
|
+
createRadixRouter({ routes: useRuntimeConfig().nitro?.routeRules })
|
|
17
|
+
);
|
|
18
|
+
const routeRules = defu({}, ..._routeRulesMatcher.matchAll(
|
|
19
|
+
withoutBase(basePath.split("?")[0], useRuntimeConfig().app.baseURL)
|
|
20
|
+
).reverse()).ogImage;
|
|
21
|
+
if (!_options || nuxtApp.ssrContext?.event.context._nitro?.routeRules?.ogImage === false || typeof routeRules !== "undefined" && routeRules === false) {
|
|
22
|
+
ogImageInstances.forEach((e) => {
|
|
23
|
+
e.dispose();
|
|
24
|
+
});
|
|
25
|
+
nuxtApp.ssrContext._ogImageInstances = void 0;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const options = normaliseOptions({
|
|
29
|
+
..._options
|
|
17
30
|
});
|
|
18
|
-
}
|
|
19
|
-
export function defineOgImageStatic(options = {}) {
|
|
20
|
-
return defineOgImageCached(options);
|
|
21
|
-
}
|
|
22
|
-
export function defineOgImageCached(options = {}) {
|
|
23
31
|
const { defaults } = useRuntimeConfig()["nuxt-og-image"];
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
export function defineOgImageWithoutCache(options = {}) {
|
|
32
|
-
return defineOgImage({
|
|
33
|
-
...options,
|
|
34
|
-
cache: false,
|
|
35
|
-
cacheTtl: 0
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
export function defineOgImageDynamic(options = {}) {
|
|
39
|
-
return defineOgImageWithoutCache(options);
|
|
40
|
-
}
|
|
41
|
-
export function defineOgImageComponent(component, props, options = {}) {
|
|
42
|
-
defineOgImage({
|
|
43
|
-
component,
|
|
44
|
-
...props,
|
|
45
|
-
...options
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
export function defineOgImage(_options = {}) {
|
|
49
|
-
if (import.meta.server) {
|
|
50
|
-
if (_options.url) {
|
|
51
|
-
const type = _options.url.endsWith(".png") ? "image/png" : "image/jpeg";
|
|
52
|
-
const meta2 = [
|
|
53
|
-
{ property: "og:image", content: _options.url },
|
|
54
|
-
{ property: "og:image:type", content: type },
|
|
55
|
-
{ name: "twitter:card", content: "summary_large_image" },
|
|
56
|
-
{ name: "twitter:image:src", content: _options.url }
|
|
57
|
-
];
|
|
58
|
-
if (_options.width) {
|
|
59
|
-
meta2.push({ property: "og:image:width", content: _options.width });
|
|
60
|
-
meta2.push({ name: "twitter:image:width", content: _options.width });
|
|
61
|
-
}
|
|
62
|
-
if (_options.height) {
|
|
63
|
-
meta2.push({ property: "og:image:height", content: _options.height });
|
|
64
|
-
meta2.push({ name: "twitter:image:height", content: _options.height });
|
|
65
|
-
}
|
|
66
|
-
if (_options.alt) {
|
|
67
|
-
meta2.push({ property: "og:image:alt", content: _options.alt });
|
|
68
|
-
meta2.push({ name: "twitter:image:alt", content: _options.alt });
|
|
69
|
-
}
|
|
70
|
-
useServerHead({ meta: meta2 }, {
|
|
71
|
-
// after async scripts when capo.js is enabled
|
|
72
|
-
tagPriority: 35
|
|
73
|
-
});
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const { defaults } = useRuntimeConfig()["nuxt-og-image"];
|
|
77
|
-
const options = normaliseOptions(_options);
|
|
78
|
-
const optionsWithDefault = defu(options, defaults);
|
|
79
|
-
const path = getOgImagePath(useRouter().currentRoute.value?.path, optionsWithDefault.extension);
|
|
80
|
-
const src = withSiteUrl(path);
|
|
32
|
+
const resolvedOptions = normaliseOptions(defu(options, routeRules, defaults));
|
|
33
|
+
if (_options.url) {
|
|
34
|
+
createOgImageMeta(null, options, resolvedOptions, nuxtApp.ssrContext);
|
|
35
|
+
} else {
|
|
36
|
+
const path = getOgImagePath(basePath, resolvedOptions);
|
|
81
37
|
if (import.meta.prerender)
|
|
82
38
|
appendHeader(useRequestEvent(), "x-nitro-prerender", path);
|
|
83
|
-
|
|
84
|
-
{ property: "og:image", content: src },
|
|
85
|
-
{ property: "og:image:width", content: optionsWithDefault.width },
|
|
86
|
-
{ property: "og:image:height", content: optionsWithDefault.height },
|
|
87
|
-
{ property: "og:image:type", content: `image/${optionsWithDefault.extension}` }
|
|
88
|
-
];
|
|
89
|
-
if (optionsWithDefault.alt)
|
|
90
|
-
meta.push({ property: "og:image:alt", content: optionsWithDefault.alt });
|
|
91
|
-
meta.push(...[
|
|
92
|
-
{ name: "twitter:card", content: "summary_large_image" },
|
|
93
|
-
{ name: "twitter:image:src", content: src },
|
|
94
|
-
{ name: "twitter:image:width", content: optionsWithDefault.width },
|
|
95
|
-
{ name: "twitter:image:height", content: optionsWithDefault.height }
|
|
96
|
-
]);
|
|
97
|
-
if (optionsWithDefault.alt)
|
|
98
|
-
meta.push({ name: "twitter:image:alt", content: optionsWithDefault.alt });
|
|
99
|
-
useServerHead({
|
|
100
|
-
meta,
|
|
101
|
-
script: [
|
|
102
|
-
{
|
|
103
|
-
id: "nuxt-og-image-options",
|
|
104
|
-
type: "application/json",
|
|
105
|
-
processTemplateParams: true,
|
|
106
|
-
innerHTML: () => {
|
|
107
|
-
const payload = {
|
|
108
|
-
title: "%s"
|
|
109
|
-
};
|
|
110
|
-
Object.entries(options).forEach(([key, val]) => {
|
|
111
|
-
payload[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = val;
|
|
112
|
-
});
|
|
113
|
-
return payload;
|
|
114
|
-
},
|
|
115
|
-
// we want this to be last in our head
|
|
116
|
-
tagPosition: "bodyClose"
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
}, {
|
|
120
|
-
// after async scripts when capo.js is enabled
|
|
121
|
-
tagPriority: 35
|
|
122
|
-
});
|
|
39
|
+
createOgImageMeta(path, options, resolvedOptions, nuxtApp.ssrContext);
|
|
123
40
|
}
|
|
124
41
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ExtractComponentProps, OgImageOptions } from '../types';
|
|
2
|
+
import type { OgImageComponents } from '#nuxt-og-image/components';
|
|
3
|
+
export declare function defineOgImageComponent<T extends keyof OgImageComponents>(component: T, props: ExtractComponentProps<OgImageComponents[T]>, options?: OgImageOptions): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineOgImage, useRouter } from "#imports";
|
|
2
|
+
export function defineOgImageScreenshot(options = {}) {
|
|
3
|
+
const router = useRouter();
|
|
4
|
+
const route = router.currentRoute.value?.path || "";
|
|
5
|
+
return defineOgImage({
|
|
6
|
+
alt: `Web page screenshot${route ? ` of ${route}` : ""}.`,
|
|
7
|
+
renderer: "chromium",
|
|
8
|
+
extension: "jpeg",
|
|
9
|
+
component: "PageScreenshot",
|
|
10
|
+
// this is an alias
|
|
11
|
+
cache: true,
|
|
12
|
+
...options
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
return inline(html, {
|
|
4
|
-
...options,
|
|
5
|
-
load_remote_stylesheets: false,
|
|
6
|
-
keep_style_tags: false
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
nodeFn.__mock = false;
|
|
10
|
-
export default nodeFn;
|
|
1
|
+
import cssInline from "css-inline";
|
|
2
|
+
export default cssInline;
|