nuxt-og-image 3.0.0-beta.3 → 3.0.0-beta.30
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/README.md +3 -3
- package/dist/client/200.html +5 -5
- package/dist/client/404.html +5 -5
- package/dist/client/_nuxt/{IconCSS.e8427024.js → IconCSS.157c2ef5.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/2f3b82b2-c809-4818-a70e-0a9fa0dde8cb.json +1 -0
- package/dist/client/_nuxt/entry.74866e06.js +137 -0
- package/dist/client/_nuxt/entry.f47d0628.css +1 -0
- package/dist/client/_nuxt/{error-404.b1c8e4c8.js → error-404.d663cd65.js} +1 -1
- package/dist/client/_nuxt/{error-500.6b97e3ab.js → error-500.8c184504.js} +1 -1
- package/dist/client/index.html +5 -5
- package/dist/module.d.mts +43 -25
- package/dist/module.d.ts +43 -25
- package/dist/module.json +2 -2
- package/dist/module.mjs +146 -93
- package/dist/runtime/cache.d.ts +7 -10
- package/dist/runtime/cache.mjs +40 -27
- 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/OgImageScreenshot.d.ts +5 -0
- package/dist/runtime/components/OgImage/{Screenshot.mjs → OgImageScreenshot.mjs} +1 -1
- package/dist/runtime/components/Templates/{Official → Community}/BrandedLogo.vue +3 -2
- package/dist/runtime/components/Templates/Community/Nuxt.vue +6 -5
- package/dist/runtime/components/Templates/Community/NuxtSeo.vue +137 -0
- package/dist/runtime/components/Templates/{Official → Community}/SimpleBlog.vue +7 -5
- package/dist/runtime/components/Templates/Community/UnJs.vue +108 -0
- package/dist/runtime/components/Templates/{Official → Community}/Wave.vue +3 -2
- package/dist/runtime/components/Templates/{Official → Community}/WithEmoji.vue +3 -2
- package/dist/runtime/composables/defineOgImage.d.ts +2 -23
- package/dist/runtime/composables/defineOgImage.mjs +33 -116
- package/dist/runtime/composables/defineOgImageComponent.d.ts +3 -0
- package/dist/runtime/composables/defineOgImageComponent.mjs +8 -0
- package/dist/runtime/composables/defineOgImageScreenshot.d.ts +2 -0
- package/dist/runtime/composables/defineOgImageScreenshot.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 -3
- 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 +20 -8
- 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} +33 -42
- 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/options/normalise.mjs +3 -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 +25 -22
- 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/plugins/unocss.d.ts +2 -0
- package/dist/runtime/core/renderers/satori/plugins/unocss.mjs +38 -0
- 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 +16 -6
- package/dist/runtime/core/utils/resolveRendererContext.d.ts +2 -6
- package/dist/runtime/core/utils/resolveRendererContext.mjs +46 -23
- package/dist/runtime/core/utils/wasm.d.ts +1 -0
- package/dist/runtime/core/utils/wasm.mjs +10 -0
- package/dist/runtime/nitro/plugins/nuxt-content.mjs +3 -4
- package/dist/runtime/nitro/plugins/prerender.d.ts +1 -1
- package/dist/runtime/nitro/plugins/prerender.mjs +13 -5
- package/dist/runtime/nuxt/plugins/og-image-canonical-urls.server.mjs +31 -0
- package/dist/runtime/nuxt/plugins/route-rule-og-image.server.mjs +16 -50
- package/dist/runtime/nuxt/utils.d.ts +2 -0
- package/dist/runtime/nuxt/utils.mjs +53 -0
- package/dist/runtime/server/routes/__og-image__/debug.json.d.ts +1 -3
- package/dist/runtime/server/routes/__og-image__/debug.json.mjs +4 -8
- package/dist/runtime/server/routes/__og-image__/image.mjs +87 -0
- package/dist/runtime/types.d.ts +74 -25
- package/dist/runtime/utils.d.ts +4 -0
- package/dist/runtime/utils.mjs +11 -0
- package/dist/runtime/utils.pure.d.ts +5 -0
- package/dist/runtime/utils.pure.mjs +43 -0
- package/package.json +27 -29
- package/virtual.d.ts +49 -0
- package/dist/client/_nuxt/IconCSS.8f429b14.css +0 -1
- package/dist/client/_nuxt/builds/meta/af7b6f15-8224-4a19-bb3a-f685b2b145c3.json +0 -1
- package/dist/client/_nuxt/entry.434c2c45.css +0 -1
- package/dist/client/_nuxt/entry.8ea61ef1.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/Screenshot.d.ts +0 -6
- 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/components/Templates/Official/Fallback.vue +0 -147
- 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/nuxt/plugins/nuxt-content-canonical-urls.mjs +0 -29
- 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/nuxt/plugins/{nuxt-content-canonical-urls.d.ts → og-image-canonical-urls.server.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,15 +1,17 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import { useNuxt, createResolver, addTemplate,
|
|
3
|
+
import { loadNuxtModuleInstance, useNuxt, createResolver, addTemplate, resolvePath, defineNuxtModule, useLogger, hasNuxtModule, addServerPlugin, addServerHandler, addImports, addComponentsDir, addComponent, addPlugin } from '@nuxt/kit';
|
|
4
4
|
import { installNuxtSiteConfig } from 'nuxt-site-config-kit';
|
|
5
|
-
import { provider, env } from 'std-env';
|
|
5
|
+
import { provider, env, isDevelopment } from 'std-env';
|
|
6
6
|
import { hash } from 'ohash';
|
|
7
|
-
import { relative } from 'pathe';
|
|
8
|
-
import 'nypm';
|
|
7
|
+
import { relative, dirname } from 'pathe';
|
|
9
8
|
import { defu } from 'defu';
|
|
9
|
+
import 'nypm';
|
|
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.30";
|
|
13
15
|
|
|
14
16
|
const autodetectableProviders = {
|
|
15
17
|
azure_static: "azure",
|
|
@@ -32,18 +34,19 @@ 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: {
|
|
40
41
|
"chromium": false,
|
|
41
|
-
"css-inline":
|
|
42
|
+
"css-inline": false,
|
|
42
43
|
"resvg": "wasm",
|
|
43
44
|
"satori": "node",
|
|
44
45
|
"sharp": false
|
|
45
46
|
},
|
|
46
|
-
|
|
47
|
+
wasm: {
|
|
48
|
+
esmImport: true
|
|
49
|
+
}
|
|
47
50
|
};
|
|
48
51
|
const awsLambda = {
|
|
49
52
|
bindings: {
|
|
@@ -52,8 +55,7 @@ const awsLambda = {
|
|
|
52
55
|
"resvg": "node",
|
|
53
56
|
"satori": "node",
|
|
54
57
|
"sharp": "node"
|
|
55
|
-
}
|
|
56
|
-
wasmStrategy: "inline"
|
|
58
|
+
}
|
|
57
59
|
};
|
|
58
60
|
const RuntimeCompatibility = {
|
|
59
61
|
"nitro-dev": NodeRuntime,
|
|
@@ -62,45 +64,48 @@ const RuntimeCompatibility = {
|
|
|
62
64
|
"stackblitz": {
|
|
63
65
|
bindings: {
|
|
64
66
|
"chromium": false,
|
|
65
|
-
"css-inline":
|
|
67
|
+
"css-inline": false,
|
|
66
68
|
"resvg": "wasm",
|
|
67
|
-
"satori": "
|
|
68
|
-
"sharp":
|
|
69
|
+
"satori": "wasm",
|
|
70
|
+
"sharp": false
|
|
69
71
|
},
|
|
70
|
-
|
|
72
|
+
wasm: {
|
|
73
|
+
rollup: {
|
|
74
|
+
targetEnv: "auto-inline",
|
|
75
|
+
sync: ["@resvg/resvg-wasm/index_bg.wasm"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
71
78
|
},
|
|
72
79
|
"aws-lambda": awsLambda,
|
|
73
80
|
"netlify": awsLambda,
|
|
74
81
|
"netlify-edge": {
|
|
75
82
|
bindings: {
|
|
76
83
|
"chromium": false,
|
|
77
|
-
"css-inline":
|
|
84
|
+
"css-inline": false,
|
|
78
85
|
"resvg": "wasm",
|
|
79
86
|
"satori": "node",
|
|
80
|
-
"sharp":
|
|
87
|
+
"sharp": false
|
|
81
88
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"resvg": "wasm",
|
|
89
|
-
"satori": "node",
|
|
90
|
-
"sharp": "node"
|
|
91
|
-
},
|
|
92
|
-
wasmStrategy: "inline"
|
|
89
|
+
wasm: {
|
|
90
|
+
rollup: {
|
|
91
|
+
targetEnv: "auto-inline",
|
|
92
|
+
sync: ["@resvg/resvg-wasm/index_bg.wasm"]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
93
95
|
},
|
|
96
|
+
"vercel": awsLambda,
|
|
94
97
|
"vercel-edge": {
|
|
95
98
|
bindings: {
|
|
96
99
|
"chromium": false,
|
|
97
|
-
"css-inline":
|
|
100
|
+
"css-inline": false,
|
|
98
101
|
"resvg": "wasm",
|
|
99
102
|
"satori": "node",
|
|
100
|
-
"sharp":
|
|
103
|
+
"sharp": false
|
|
101
104
|
},
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
wasm: {
|
|
106
|
+
// lowers workers kb size
|
|
107
|
+
esmImport: true
|
|
108
|
+
}
|
|
104
109
|
},
|
|
105
110
|
"cloudflare-pages": cloudflare,
|
|
106
111
|
"cloudflare": cloudflare
|
|
@@ -141,15 +146,37 @@ function applyNitroPresetCompatibility(nitroConfig, options) {
|
|
|
141
146
|
applyBinding("satori"),
|
|
142
147
|
applyBinding("resvg"),
|
|
143
148
|
applyBinding("sharp"),
|
|
149
|
+
applyBinding("css-inline"),
|
|
144
150
|
nitroConfig.alias || {}
|
|
145
151
|
);
|
|
146
|
-
if (
|
|
147
|
-
nitroConfig.
|
|
148
|
-
nitroConfig.
|
|
152
|
+
if (Object.values(compatibility.bindings).includes("wasm")) {
|
|
153
|
+
nitroConfig.experimental = nitroConfig.experimental || {};
|
|
154
|
+
nitroConfig.experimental.wasm = true;
|
|
149
155
|
}
|
|
156
|
+
nitroConfig.rollupConfig = nitroConfig.rollupConfig || {};
|
|
157
|
+
nitroConfig.wasm = defu(compatibility.wasm, nitroConfig.wasm);
|
|
150
158
|
return compatibility;
|
|
151
159
|
}
|
|
152
160
|
|
|
161
|
+
async function getNuxtModuleOptions(module, nuxt = useNuxt()) {
|
|
162
|
+
const moduleMeta = (typeof module === "string" ? { name: module } : await module.getMeta?.()) || {};
|
|
163
|
+
const { nuxtModule } = await loadNuxtModuleInstance(module, nuxt);
|
|
164
|
+
let moduleEntry;
|
|
165
|
+
for (const m of nuxt.options.modules) {
|
|
166
|
+
if (Array.isArray(m) && m.length >= 2) {
|
|
167
|
+
const _module = m[0];
|
|
168
|
+
const _moduleEntryName = typeof _module === "string" ? _module : (await _module.getMeta?.())?.name || "";
|
|
169
|
+
if (_moduleEntryName === moduleMeta.name)
|
|
170
|
+
moduleEntry = m;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
let inlineOptions = {};
|
|
174
|
+
if (moduleEntry)
|
|
175
|
+
inlineOptions = moduleEntry[1];
|
|
176
|
+
if (nuxtModule.getOptions)
|
|
177
|
+
return nuxtModule.getOptions(inlineOptions, nuxt);
|
|
178
|
+
return inlineOptions;
|
|
179
|
+
}
|
|
153
180
|
function extendTypes(module, template) {
|
|
154
181
|
const nuxt = useNuxt();
|
|
155
182
|
const { resolve } = createResolver(import.meta.url);
|
|
@@ -226,8 +253,8 @@ function setupDevToolsUI(options, resolve, nuxt = useNuxt()) {
|
|
|
226
253
|
function setupDevHandler(options, resolve, nuxt = useNuxt()) {
|
|
227
254
|
nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
|
|
228
255
|
nitroConfig.alias["#nuxt-og-image/renderers/satori"] = options.runtimeSatori ? resolve("./runtime/core/renderers/satori") : "unenv/runtime/mock/empty";
|
|
229
|
-
nitroConfig.alias["#nuxt-og-image/renderers/chromium"] = options.
|
|
230
|
-
applyNitroPresetCompatibility(nitroConfig, { resolve });
|
|
256
|
+
nitroConfig.alias["#nuxt-og-image/renderers/chromium"] = options.runtimeChromium ? resolve("./runtime/core/renderers/chromium") : "unenv/runtime/mock/empty";
|
|
257
|
+
applyNitroPresetCompatibility(nitroConfig, { resolve, compatibility: options.runtimeCompatibility });
|
|
231
258
|
});
|
|
232
259
|
}
|
|
233
260
|
|
|
@@ -251,12 +278,13 @@ function setupGenerateHandler(options, resolve, nuxt = useNuxt()) {
|
|
|
251
278
|
}
|
|
252
279
|
|
|
253
280
|
function setupPrerenderHandler(options, resolve, nuxt = useNuxt()) {
|
|
254
|
-
addServerPlugin(resolve("./runtime/nitro/plugins/prerender.ts"));
|
|
255
281
|
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
256
282
|
nitro.hooks.hook("prerender:config", async (nitroConfig) => {
|
|
257
283
|
nitroConfig.alias["#nuxt-og-image/renderers/satori"] = resolve("./runtime/core/renderers/satori");
|
|
258
284
|
nitroConfig.alias["#nuxt-og-image/renderers/chromium"] = resolve("./runtime/core/renderers/chromium");
|
|
259
285
|
applyNitroPresetCompatibility(nitroConfig, { resolve });
|
|
286
|
+
nitroConfig.wasm = nitroConfig.wasm || {};
|
|
287
|
+
nitroConfig.wasm.esmImport = false;
|
|
260
288
|
});
|
|
261
289
|
});
|
|
262
290
|
}
|
|
@@ -267,20 +295,41 @@ async function setupBuildHandler(config, resolve, nuxt = useNuxt()) {
|
|
|
267
295
|
nuxt.options.nitro.storage["og-image"] = config.runtimeCacheStorage;
|
|
268
296
|
nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
|
|
269
297
|
nitroConfig.alias["#nuxt-og-image/renderers/satori"] = config.runtimeSatori ? resolve("./runtime/core/renderers/satori") : "unenv/runtime/mock/empty";
|
|
270
|
-
nitroConfig.alias["#nuxt-og-image/renderers/chromium"] = config.
|
|
298
|
+
nitroConfig.alias["#nuxt-og-image/renderers/chromium"] = config.runtimeChromium ? resolve("./runtime/core/renderers/chromium") : "unenv/runtime/mock/empty";
|
|
271
299
|
applyNitroPresetCompatibility(nitroConfig, { resolve, compatibility: config.runtimeCompatibility });
|
|
272
300
|
nitroConfig.alias.electron = "unenv/runtime/mock/proxy-cjs";
|
|
273
301
|
nitroConfig.alias.bufferutil = "unenv/runtime/mock/proxy-cjs";
|
|
274
302
|
nitroConfig.alias["utf-8-validate"] = "unenv/runtime/mock/proxy-cjs";
|
|
275
303
|
nitroConfig.alias.queue = "unenv/runtime/mock/proxy-cjs";
|
|
276
304
|
});
|
|
305
|
+
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
306
|
+
nitro.hooks.hook("compiled", async (_nitro) => {
|
|
307
|
+
const target = resolveNitroPreset(_nitro.options);
|
|
308
|
+
const compatibility = getPresetNitroPresetCompatibility(target);
|
|
309
|
+
if (compatibility.wasm?.esmImport !== true)
|
|
310
|
+
return;
|
|
311
|
+
const configuredEntry = nitro.options.rollupConfig?.output.entryFileNames;
|
|
312
|
+
let serverEntry = resolve(_nitro.options.output.serverDir, typeof configuredEntry === "string" ? configuredEntry : "index.mjs");
|
|
313
|
+
if (target === "cloudflare-pages")
|
|
314
|
+
serverEntry = resolve(dirname(serverEntry), "./chunks/wasm.mjs");
|
|
315
|
+
const contents = await readFile(serverEntry, "utf-8");
|
|
316
|
+
const resvgHash = sha1(await readFile(await resolvePath("@resvg/resvg-wasm/index_bg.wasm")));
|
|
317
|
+
const yogaHash = sha1(await readFile(await resolvePath("yoga-wasm-web/dist/yoga.wasm")));
|
|
318
|
+
const postfix = target === "vercel-edge" ? "?module" : "";
|
|
319
|
+
const path = target === "cloudflare-pages" ? `../wasm/` : `./wasm/`;
|
|
320
|
+
await writeFile(serverEntry, contents.replaceAll('"@resvg/resvg-wasm/index_bg.wasm"', `"${path}index_bg-${resvgHash}.wasm${postfix}"`).replaceAll('"yoga-wasm-web/dist/yoga.wasm"', `"${path}yoga-${yogaHash}.wasm${postfix}"`), { encoding: "utf-8" });
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
function sha1(source) {
|
|
325
|
+
return createHash("sha1").update(source).digest("hex").slice(0, 16);
|
|
277
326
|
}
|
|
278
327
|
|
|
279
328
|
const module = defineNuxtModule({
|
|
280
329
|
meta: {
|
|
281
330
|
name: "nuxt-og-image",
|
|
282
331
|
compatibility: {
|
|
283
|
-
nuxt: "^3.
|
|
332
|
+
nuxt: "^3.8.2",
|
|
284
333
|
bridge: false
|
|
285
334
|
},
|
|
286
335
|
configKey: "ogImage"
|
|
@@ -289,21 +338,20 @@ const module = defineNuxtModule({
|
|
|
289
338
|
return {
|
|
290
339
|
enabled: true,
|
|
291
340
|
defaults: {
|
|
341
|
+
emojis: "noto",
|
|
292
342
|
renderer: "satori",
|
|
293
|
-
component: "
|
|
343
|
+
component: "NuxtSeo",
|
|
294
344
|
width: 1200,
|
|
295
345
|
height: 600,
|
|
296
|
-
cache: true,
|
|
297
346
|
// default is to cache the image for 1 day (24 hours)
|
|
298
|
-
|
|
347
|
+
cacheMaxAgeSeconds: 60 * 60 * 24 * 3
|
|
299
348
|
},
|
|
300
349
|
componentDirs: ["OgImage", "OgImageTemplate"],
|
|
301
|
-
runtimeSatori: true,
|
|
302
|
-
runtimeBrowser: nuxt.options.dev,
|
|
303
350
|
fonts: [],
|
|
304
351
|
runtimeCacheStorage: true,
|
|
305
|
-
|
|
306
|
-
|
|
352
|
+
runtimeSatori: true,
|
|
353
|
+
runtimeChromium: nuxt.options.dev,
|
|
354
|
+
debug: isDevelopment
|
|
307
355
|
};
|
|
308
356
|
},
|
|
309
357
|
async setup(config, nuxt) {
|
|
@@ -320,14 +368,20 @@ const module = defineNuxtModule({
|
|
|
320
368
|
const { resolve } = createResolver(import.meta.url);
|
|
321
369
|
const preset = resolveNitroPreset(nuxt.options.nitro);
|
|
322
370
|
const compatibility = getPresetNitroPresetCompatibility(preset);
|
|
323
|
-
config.defaults.extension
|
|
324
|
-
|
|
371
|
+
const userConfiguredExtension = config.defaults.extension;
|
|
372
|
+
config.defaults.extension = userConfiguredExtension || "jpg";
|
|
373
|
+
if (!compatibility.bindings.sharp && config.defaults.renderer !== "chromium") {
|
|
374
|
+
if (userConfiguredExtension && ["jpeg", "jpg"].includes(userConfiguredExtension))
|
|
375
|
+
logger.warn("The sharp runtime is not available for this target, disabling sharp and using png instead.");
|
|
325
376
|
config.defaults.extension = "png";
|
|
377
|
+
}
|
|
378
|
+
if (config.runtimeChromium && !compatibility.bindings.chromium) {
|
|
379
|
+
logger.warn("The Chromium runtime is not available for this target, disabling runtimeChromium.");
|
|
380
|
+
config.runtimeChromium = false;
|
|
381
|
+
}
|
|
326
382
|
await installNuxtSiteConfig();
|
|
327
|
-
if (hasNuxtModule("@nuxt/content"))
|
|
383
|
+
if (hasNuxtModule("@nuxt/content"))
|
|
328
384
|
addServerPlugin(resolve("./runtime/nitro/plugins/nuxt-content"));
|
|
329
|
-
addPlugin(resolve("./runtime/nuxt/plugins/nuxt-content-canonical-urls"));
|
|
330
|
-
}
|
|
331
385
|
if (!config.fonts.length)
|
|
332
386
|
config.fonts = ["Inter:400", "Inter:700"];
|
|
333
387
|
nuxt.options.experimental.componentIslands = true;
|
|
@@ -346,52 +400,34 @@ const module = defineNuxtModule({
|
|
|
346
400
|
addServerHandler({
|
|
347
401
|
lazy: true,
|
|
348
402
|
route: "/__og-image__/image/**",
|
|
349
|
-
handler: resolve("./runtime/server/routes/__og-image__/image
|
|
403
|
+
handler: resolve("./runtime/server/routes/__og-image__/image")
|
|
350
404
|
});
|
|
351
405
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
352
|
-
[
|
|
353
|
-
// deprecated
|
|
354
|
-
"Dynamic",
|
|
355
|
-
"Static",
|
|
356
|
-
// new
|
|
357
|
-
"index",
|
|
358
|
-
"Cached",
|
|
359
|
-
"Component",
|
|
360
|
-
"WithoutCache",
|
|
361
|
-
"Screenshot"
|
|
362
|
-
].forEach((name) => {
|
|
363
|
-
name = name === "index" ? "defineOgImage" : `defineOgImage${name}`;
|
|
406
|
+
["defineOgImage", "defineOgImageComponent", "defineOgImageScreenshot"].forEach((name) => {
|
|
364
407
|
addImports({
|
|
365
408
|
name,
|
|
366
|
-
from: resolve(
|
|
409
|
+
from: resolve(`./runtime/composables/${name}`)
|
|
367
410
|
});
|
|
368
411
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"].push(name);
|
|
369
412
|
});
|
|
370
413
|
await addComponentsDir({
|
|
371
414
|
path: resolve("./runtime/components/Templates/Community"),
|
|
372
|
-
island: true
|
|
373
|
-
|
|
374
|
-
await addComponentsDir({
|
|
375
|
-
path: resolve("./runtime/components/Templates/Official"),
|
|
376
|
-
island: true
|
|
415
|
+
island: true,
|
|
416
|
+
watch: true
|
|
377
417
|
});
|
|
378
418
|
[
|
|
379
|
-
// deprecated
|
|
380
|
-
"Static",
|
|
381
|
-
"Dynamic",
|
|
382
419
|
// new
|
|
383
|
-
"
|
|
384
|
-
"
|
|
385
|
-
"WithoutCache",
|
|
386
|
-
"Screenshot"
|
|
420
|
+
"OgImage",
|
|
421
|
+
"OgImageScreenshot"
|
|
387
422
|
].forEach((name) => {
|
|
388
423
|
addComponent({
|
|
389
|
-
|
|
390
|
-
|
|
424
|
+
name,
|
|
425
|
+
global: true,
|
|
391
426
|
filePath: resolve(`./runtime/components/OgImage/${name}`)
|
|
392
427
|
});
|
|
393
428
|
});
|
|
394
|
-
addPlugin(resolve("./runtime/nuxt/plugins/route-rule-og-image.server"));
|
|
429
|
+
addPlugin({ mode: "server", src: resolve("./runtime/nuxt/plugins/route-rule-og-image.server") });
|
|
430
|
+
addPlugin({ mode: "server", src: resolve("./runtime/nuxt/plugins/og-image-canonical-urls.server") });
|
|
395
431
|
const ogImageComponentCtx = { components: [] };
|
|
396
432
|
nuxt.hook("components:extend", (components) => {
|
|
397
433
|
ogImageComponentCtx.components = [];
|
|
@@ -409,8 +445,6 @@ const module = defineNuxtModule({
|
|
|
409
445
|
let category = "app";
|
|
410
446
|
if (component.filePath.includes(resolve("./runtime/components/Templates/Community")))
|
|
411
447
|
category = "community";
|
|
412
|
-
else if (component.filePath.includes(resolve("./runtime/components/Templates/Official")))
|
|
413
|
-
category = "official";
|
|
414
448
|
const componentFile = fs.readFileSync(component.filePath, "utf-8");
|
|
415
449
|
const credits = componentFile.split("\n").find((line) => line.startsWith(" * @credits"))?.replace("* @credits", "").trim();
|
|
416
450
|
ogImageComponentCtx.components.push({
|
|
@@ -437,6 +471,16 @@ const module = defineNuxtModule({
|
|
|
437
471
|
nuxt.options.nitro.virtual["#nuxt-og-image/component-names.mjs"] = () => {
|
|
438
472
|
return `export const componentNames = ${JSON.stringify(ogImageComponentCtx.components)}`;
|
|
439
473
|
};
|
|
474
|
+
let unoCssConfig = { theme: {} };
|
|
475
|
+
nuxt.hook("tailwindcss:config", (tailwindConfig) => {
|
|
476
|
+
unoCssConfig = defu(tailwindConfig.theme.extend, { ...tailwindConfig.theme || {}, extend: void 0 });
|
|
477
|
+
});
|
|
478
|
+
nuxt.hook("unocss:config", (_unoCssConfig) => {
|
|
479
|
+
unoCssConfig = { ..._unoCssConfig.theme };
|
|
480
|
+
});
|
|
481
|
+
nuxt.options.nitro.virtual["#nuxt-og-image/unocss-config.mjs"] = () => {
|
|
482
|
+
return `export const theme = ${JSON.stringify(unoCssConfig)}`;
|
|
483
|
+
};
|
|
440
484
|
extendTypes("nuxt-og-image", ({ typesPath }) => {
|
|
441
485
|
const componentImports = ogImageComponentCtx.components.map((component) => {
|
|
442
486
|
const relativeComponentPath = relative(resolve(nuxt.options.rootDir, nuxt.options.buildDir, "module"), component.path);
|
|
@@ -445,12 +489,13 @@ const module = defineNuxtModule({
|
|
|
445
489
|
return `
|
|
446
490
|
declare module 'nitropack' {
|
|
447
491
|
interface NitroRouteRules {
|
|
448
|
-
ogImage?: false | import('${typesPath}').OgImageOptions
|
|
492
|
+
ogImage?: false | import('${typesPath}').OgImageOptions & Record<string, any>
|
|
449
493
|
}
|
|
450
494
|
interface NitroRouteConfig {
|
|
451
|
-
ogImage?: false | import('${typesPath}').OgImageOptions
|
|
495
|
+
ogImage?: false | import('${typesPath}').OgImageOptions & Record<string, any>
|
|
452
496
|
}
|
|
453
497
|
}
|
|
498
|
+
|
|
454
499
|
declare module '#nuxt-og-image/components' {
|
|
455
500
|
export interface OgImageComponents {
|
|
456
501
|
${componentImports}
|
|
@@ -458,6 +503,11 @@ ${componentImports}
|
|
|
458
503
|
}
|
|
459
504
|
`;
|
|
460
505
|
});
|
|
506
|
+
const cacheEnabled = typeof config.runtimeCacheStorage !== "undefined" && config.runtimeCacheStorage !== false;
|
|
507
|
+
const runtimeCacheStorage = typeof config.runtimeCacheStorage === "boolean" ? "default" : config.runtimeCacheStorage.driver;
|
|
508
|
+
let baseCacheKey = runtimeCacheStorage === "default" ? `/cache/nuxt-og-image@${version}` : `/nuxt-og-image@${version}`;
|
|
509
|
+
if (!cacheEnabled)
|
|
510
|
+
baseCacheKey = false;
|
|
461
511
|
nuxt.hooks.hook("modules:done", async () => {
|
|
462
512
|
nuxt.hooks.callHook("og-image:config", config);
|
|
463
513
|
const normalisedFonts = config.fonts.map((f) => {
|
|
@@ -478,6 +528,9 @@ ${componentImports}
|
|
|
478
528
|
nuxt.options.nitro.prerender.routes.push(`/__og-image__/font/${name}/${weight}.ttf`);
|
|
479
529
|
});
|
|
480
530
|
}
|
|
531
|
+
let colorPreference = hasNuxtModule("@nuxtjs/color-mode") ? (await getNuxtModuleOptions("@nuxtjs/color-mode")).preference : "light";
|
|
532
|
+
if (!colorPreference || !["dark", "light"].includes(colorPreference))
|
|
533
|
+
colorPreference = "light";
|
|
481
534
|
nuxt.options.runtimeConfig["nuxt-og-image"] = {
|
|
482
535
|
version,
|
|
483
536
|
// binding options
|
|
@@ -485,18 +538,17 @@ ${componentImports}
|
|
|
485
538
|
resvgOptions: config.resvgOptions || {},
|
|
486
539
|
sharpOptions: config.sharpOptions || {},
|
|
487
540
|
runtimeSatori: config.runtimeSatori,
|
|
488
|
-
|
|
489
|
-
// @ts-expect-error runtime type
|
|
541
|
+
runtimeChromium: config.runtimeChromium,
|
|
490
542
|
defaults: config.defaults,
|
|
543
|
+
debug: config.debug,
|
|
491
544
|
// avoid adding credentials
|
|
492
|
-
|
|
545
|
+
baseCacheKey,
|
|
493
546
|
// convert the fonts to uniform type to fix ts issue
|
|
494
547
|
fonts: normalisedFonts,
|
|
495
|
-
hasNuxtIcon: hasNuxtModule("nuxt-icon")
|
|
548
|
+
hasNuxtIcon: hasNuxtModule("nuxt-icon"),
|
|
549
|
+
colorPreference
|
|
496
550
|
};
|
|
497
551
|
});
|
|
498
|
-
nuxt.options.nitro.experimental = nuxt.options.nitro.experimental || {};
|
|
499
|
-
nuxt.options.nitro.experimental.wasm = true;
|
|
500
552
|
if (nuxt.options.dev) {
|
|
501
553
|
setupDevHandler(config, resolve);
|
|
502
554
|
setupDevToolsUI(config, resolve);
|
|
@@ -505,8 +557,9 @@ ${componentImports}
|
|
|
505
557
|
} else if (nuxt.options.build) {
|
|
506
558
|
await setupBuildHandler(config, resolve);
|
|
507
559
|
}
|
|
508
|
-
if (nuxt.options.nitro.prerender?.routes || nuxt.options._generate)
|
|
509
|
-
|
|
560
|
+
if (nuxt.options.nitro.prerender?.routes?.length || nuxt.options.nitro.prerender?.crawlLinks || nuxt.options._generate)
|
|
561
|
+
addServerPlugin(resolve("./runtime/nitro/plugins/prerender.ts"));
|
|
562
|
+
setupPrerenderHandler(config, resolve);
|
|
510
563
|
}
|
|
511
564
|
});
|
|
512
565
|
|
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 './types';
|
|
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,58 @@
|
|
|
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
|
-
let xCacheHeader = "DISABLED";
|
|
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 = !import.meta.dev && import.meta.env.MODE !== "test" && maxAge > 0;
|
|
9
|
+
const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/"));
|
|
10
|
+
const key = ctx.key;
|
|
15
11
|
let cachedItem = false;
|
|
16
|
-
if (
|
|
17
|
-
const { value, expiresAt } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() }));
|
|
18
|
-
if (purge) {
|
|
19
|
-
xCacheHeader = "PURGE";
|
|
20
|
-
xCacheExpires = newExpires;
|
|
12
|
+
if (enabled && await cache.hasItem(key).catch(() => false)) {
|
|
13
|
+
const { value, expiresAt, headers } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() }));
|
|
14
|
+
if (typeof getQuery(ctx.e).purge !== "undefined") {
|
|
21
15
|
await cache.removeItem(key).catch(() => {
|
|
22
16
|
});
|
|
23
17
|
} else if (expiresAt > Date.now()) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
cachedItem = Buffer.from(value, "base64");
|
|
19
|
+
if (handleCacheHeaders(ctx.e, {
|
|
20
|
+
modifiedTime: new Date(headers["last-modified"]),
|
|
21
|
+
etag: headers.etag,
|
|
22
|
+
maxAge
|
|
23
|
+
}))
|
|
24
|
+
return;
|
|
25
|
+
setHeaders(ctx.e, headers);
|
|
27
26
|
} else {
|
|
28
|
-
xCacheHeader = "MISS";
|
|
29
|
-
xCacheExpires = expiresAt;
|
|
30
27
|
await cache.removeItem(key).catch(() => {
|
|
31
28
|
});
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
|
-
if (
|
|
35
|
-
setHeader(e,
|
|
36
|
-
setHeader(e,
|
|
31
|
+
if (!enabled) {
|
|
32
|
+
setHeader(ctx.e, "Cache-Control", "no-cache, no-store, must-revalidate");
|
|
33
|
+
setHeader(ctx.e, "Pragma", "no-cache");
|
|
34
|
+
setHeader(ctx.e, "Expires", "0");
|
|
37
35
|
}
|
|
38
36
|
return {
|
|
39
37
|
enabled,
|
|
40
38
|
cachedItem,
|
|
41
39
|
async update(item) {
|
|
42
|
-
|
|
40
|
+
if (!enabled)
|
|
41
|
+
return;
|
|
42
|
+
const value = Buffer.from(item).toString("base64");
|
|
43
|
+
const headers = {
|
|
44
|
+
// avoid multi-tenancy cache issues
|
|
45
|
+
"Vary": "accept-encoding, host",
|
|
46
|
+
"etag": `W/"${hash(value)}"`,
|
|
47
|
+
"last-modified": (/* @__PURE__ */ new Date()).toUTCString(),
|
|
48
|
+
"cache-control": `public, s-maxage=${maxAge}, stale-while-revalidate`
|
|
49
|
+
};
|
|
50
|
+
setHeaders(ctx.e, headers);
|
|
51
|
+
await cache.setItem(key, {
|
|
52
|
+
value,
|
|
53
|
+
headers,
|
|
54
|
+
expiresAt: Date.now() + maxAge * 1e3
|
|
55
|
+
});
|
|
43
56
|
}
|
|
44
57
|
};
|
|
45
58
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { OgImageOptions } from '../../types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<OgImageOptions<"NuxtSeo">, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<OgImageOptions<"NuxtSeo">>, {
|
|
3
|
+
props?: any;
|
|
4
|
+
}, {}>;
|
|
5
|
+
export default _default;
|
|
@@ -0,0 +1,5 @@
|
|
|
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;
|
|
4
|
+
}, {}>;
|
|
5
|
+
export default _default;
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* @credits NuxtLabs <https://nuxtlabs.com/>
|
|
4
4
|
* @see https://github.com/nuxt/nuxt.com/blob/main/components/OgImage/OgImageDocs.vue
|
|
5
5
|
*/
|
|
6
|
+
import { computed } from 'vue'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
withDefaults(defineProps<{ title?: string, description?: string, headline?: string }>(), {
|
|
8
|
+
const props = withDefaults(defineProps<{ title?: string, description?: string, headline?: string }>(), {
|
|
10
9
|
title: 'title',
|
|
11
10
|
description: 'description',
|
|
12
11
|
headline: 'headline',
|
|
13
12
|
})
|
|
13
|
+
|
|
14
|
+
const title = computed(() => props.title.slice(0, 60))
|
|
14
15
|
</script>
|
|
15
16
|
|
|
16
17
|
<template>
|
|
@@ -43,11 +44,11 @@ withDefaults(defineProps<{ title?: string, description?: string, headline?: stri
|
|
|
43
44
|
</defs>
|
|
44
45
|
</svg>
|
|
45
46
|
|
|
46
|
-
<div class="w-[
|
|
47
|
+
<div class="w-[600px] pl-[100px]">
|
|
47
48
|
<p v-if="headline" class="uppercase text-[24px] text-[#00DC82] mb-4 font-semibold">
|
|
48
49
|
{{ headline }}
|
|
49
50
|
</p>
|
|
50
|
-
<h1 class="m-0 text-[75px] font-semibold mb-4 text-white flex items-center">
|
|
51
|
+
<h1 class="w-[600px] m-0 text-[75px] font-semibold mb-4 text-white flex items-center">
|
|
51
52
|
<span>{{ title }}</span>
|
|
52
53
|
</h1>
|
|
53
54
|
<p class="text-[32px] text-[#E4E4E7] leading-tight">
|