nuxt-og-image 2.0.0-beta.9 → 2.0.1
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 +18 -517
- package/dist/client/200.html +2 -2
- package/dist/client/404.html +2 -2
- package/dist/client/_nuxt/IconCSS.685477c5.js +1 -0
- package/dist/client/_nuxt/IconCSS.b41b9663.css +1 -0
- package/dist/client/_nuxt/ImageLoader.7571516f.css +1 -0
- package/dist/client/_nuxt/ImageLoader.fb4e5eb3.js +1 -0
- package/dist/client/_nuxt/entry.0fc037e0.js +143 -0
- package/dist/client/_nuxt/entry.1311cc29.css +1 -0
- package/dist/client/_nuxt/{error-404.02537f9e.js → error-404.068f19dd.js} +1 -1
- package/dist/client/_nuxt/error-404.f3dd5020.css +1 -0
- package/dist/client/_nuxt/error-500.06915589.css +1 -0
- package/dist/client/_nuxt/{error-500.a60bf0b5.js → error-500.4d72610e.js} +1 -1
- package/dist/client/_nuxt/index.33389497.js +1 -0
- package/dist/client/_nuxt/index.ffbea0a9.css +1 -0
- package/dist/client/_nuxt/options.e1a971ea.js +1 -0
- package/dist/client/_nuxt/png.110ab8f5.js +1 -0
- package/dist/client/_nuxt/{shiki.aace8ca2.js → shiki.3fe159de.js} +1 -1
- package/dist/client/_nuxt/svg.1a58cdf3.js +1 -0
- package/dist/client/_nuxt/vnodes.42fbc6e6.js +1 -0
- package/dist/client/index.html +2 -2
- package/dist/client/options/index.html +2 -2
- package/dist/client/png/index.html +2 -2
- package/dist/client/svg/index.html +2 -2
- package/dist/client/vnodes/index.html +2 -2
- package/dist/module.d.ts +117 -11
- package/dist/module.json +2 -2
- package/dist/module.mjs +391 -114
- package/dist/runtime/browserUtil.d.ts +1 -0
- package/dist/runtime/browserUtil.mjs +7 -5
- package/dist/runtime/components/{OgImageDynamic.d.ts → OgImage/Cached.d.ts} +2 -2
- package/dist/runtime/components/OgImage/Cached.mjs +10 -0
- package/dist/runtime/components/OgImage/Dynamic.d.ts +8 -0
- package/dist/runtime/components/{OgImageDynamic.mjs → OgImage/Dynamic.mjs} +3 -3
- package/dist/runtime/components/{OgImageScreenshot.d.ts → OgImage/Screenshot.d.ts} +2 -2
- package/dist/runtime/components/{OgImageScreenshot.mjs → OgImage/Screenshot.mjs} +2 -2
- package/dist/runtime/components/OgImage/Static.d.ts +8 -0
- package/dist/runtime/components/{OgImageStatic.mjs → OgImage/Static.mjs} +3 -3
- package/dist/runtime/components/{OgImageStatic.d.ts → OgImage/WithoutCache.d.ts} +2 -2
- package/dist/runtime/components/OgImage/WithoutCache.mjs +10 -0
- package/dist/runtime/components/OgImage/index.d.ts +5 -0
- package/dist/runtime/components/OgImage/index.mjs +10 -0
- package/dist/runtime/components/OgImageTemplate/Fallback.vue +156 -0
- package/dist/runtime/composables/defineOgImage.d.ts +12 -4
- package/dist/runtime/composables/defineOgImage.mjs +31 -49
- package/dist/runtime/composables/util.d.ts +2 -0
- package/dist/runtime/composables/util.mjs +26 -0
- package/dist/runtime/nitro/middleware/og.png.mjs +54 -8
- package/dist/runtime/nitro/plugins/prerender.d.ts +3 -0
- package/dist/runtime/nitro/plugins/prerender.mjs +28 -0
- package/dist/runtime/nitro/providers/browser/lambda.d.ts +1 -1
- package/dist/runtime/nitro/providers/browser/lambda.mjs +3 -3
- package/dist/runtime/nitro/providers/browser/{node.mjs → playwright.mjs} +0 -9
- package/dist/runtime/nitro/providers/browser/universal.d.ts +1 -0
- package/dist/runtime/nitro/providers/browser/universal.mjs +33 -0
- package/dist/runtime/nitro/providers/inline-css/mock.d.ts +5 -0
- package/dist/runtime/nitro/providers/inline-css/mock.mjs +3 -0
- package/dist/runtime/nitro/providers/inline-css/node.d.ts +5 -0
- package/dist/runtime/nitro/providers/inline-css/node.mjs +11 -0
- package/dist/runtime/nitro/providers/png/resvg-node.d.ts +4 -0
- package/dist/runtime/nitro/providers/png/resvg-node.mjs +6 -0
- package/dist/runtime/nitro/providers/png/resvg-wasm.d.ts +3 -0
- package/dist/runtime/nitro/providers/png/resvg-wasm.mjs +11 -0
- package/dist/runtime/nitro/providers/{svg2png/universal.d.ts → png/svg2png.d.ts} +2 -3
- package/dist/runtime/nitro/providers/png/svg2png.mjs +11 -0
- package/dist/runtime/nitro/providers/satori/{webworker.d.ts → yoga-wasm.d.ts} +2 -3
- package/dist/runtime/nitro/providers/satori/{webworker.mjs → yoga-wasm.mjs} +4 -5
- package/dist/runtime/nitro/renderers/browser.d.ts +2 -2
- package/dist/runtime/nitro/renderers/browser.mjs +14 -12
- package/dist/runtime/nitro/renderers/satori/index.d.ts +2 -2
- package/dist/runtime/nitro/renderers/satori/index.mjs +27 -32
- package/dist/runtime/nitro/renderers/satori/plugins/emojis.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/emojis.mjs +19 -6
- package/dist/runtime/nitro/renderers/satori/plugins/encoding.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/encoding.mjs +5 -7
- package/dist/runtime/nitro/renderers/satori/plugins/flex.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/flex.mjs +8 -10
- package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.mjs +45 -13
- package/dist/runtime/nitro/renderers/satori/plugins/twClasses.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/twClasses.mjs +5 -7
- package/dist/runtime/nitro/renderers/satori/utils.d.ts +4 -5
- package/dist/runtime/nitro/renderers/satori/utils.mjs +28 -17
- package/dist/runtime/nitro/routes/debug.d.ts +8 -0
- package/dist/runtime/nitro/routes/debug.mjs +14 -0
- package/dist/runtime/nitro/routes/font.mjs +2 -2
- package/dist/runtime/nitro/routes/html.mjs +102 -26
- package/dist/runtime/nitro/routes/options.d.ts +2 -2
- package/dist/runtime/nitro/routes/options.mjs +21 -20
- package/dist/runtime/nitro/routes/svg.mjs +2 -2
- package/dist/runtime/nitro/routes/vnode.mjs +2 -2
- package/dist/runtime/nitro/utils-pure.d.ts +0 -1
- package/dist/runtime/nitro/utils-pure.mjs +1 -4
- package/dist/runtime/nitro/utils.d.ts +11 -11
- package/dist/runtime/nitro/utils.mjs +67 -53
- package/dist/runtime/public-assets/__nuxt_og_image__/browser-provider-not-supported.png +0 -0
- package/dist/runtime/public-assets-optional/resvg/resvg.wasm +0 -0
- package/dist/types.d.ts +6 -0
- package/package.json +38 -27
- package/dist/client/_nuxt/IconCSS.ef0613e7.js +0 -1
- package/dist/client/_nuxt/ImageLoader.a4418cab.js +0 -1
- package/dist/client/_nuxt/entry.09f25aaf.css +0 -1
- package/dist/client/_nuxt/entry.fc9150b0.js +0 -5
- package/dist/client/_nuxt/error-404.1469f10f.css +0 -1
- package/dist/client/_nuxt/error-500.92b94fae.css +0 -1
- package/dist/client/_nuxt/error-component.8148b615.js +0 -3
- package/dist/client/_nuxt/index.80f38ec7.js +0 -1
- package/dist/client/_nuxt/options.cc3fd02b.js +0 -1
- package/dist/client/_nuxt/png.62758167.js +0 -1
- package/dist/client/_nuxt/svg.853cdaad.js +0 -1
- package/dist/client/_nuxt/vnodes.69b24963.js +0 -1
- package/dist/runtime/components/OgImageBasic.island.vue +0 -92
- package/dist/runtime/nitro/providers/svg2png/universal.mjs +0 -9
- /package/dist/runtime/nitro/providers/browser/{node.d.ts → playwright.d.ts} +0 -0
- /package/dist/runtime/nitro/providers/satori/{node.d.ts → default.d.ts} +0 -0
- /package/dist/runtime/nitro/providers/satori/{node.mjs → default.mjs} +0 -0
- /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-400-normal.woff +0 -0
- /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-700-normal.woff +0 -0
- /package/dist/runtime/{public-assets → public-assets-optional/svg2png}/svg2png.wasm +0 -0
- /package/dist/runtime/{public-assets → public-assets-optional/yoga}/yoga.wasm +0 -0
package/dist/module.mjs
CHANGED
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { defineNuxtModule,
|
|
2
|
+
import { useNuxt, addTemplate, defineNuxtModule, useLogger, createResolver, addServerHandler, addImports, addComponent, hasNuxtModule, addServerPlugin } from '@nuxt/kit';
|
|
3
3
|
import { execa } from 'execa';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import defu from 'defu';
|
|
6
6
|
import { toRouteMatcher, createRouter } from 'radix3';
|
|
7
7
|
import { withBase, joinURL } from 'ufo';
|
|
8
|
-
import { resolve, relative } from 'pathe';
|
|
8
|
+
import { resolve, relative, dirname } from 'pathe';
|
|
9
9
|
import { tinyws } from 'tinyws';
|
|
10
10
|
import sirv from 'sirv';
|
|
11
11
|
import { pathExists, copy, mkdirp } from 'fs-extra';
|
|
12
|
+
import { globby } from 'globby';
|
|
13
|
+
import { installNuxtSiteConfig, updateSiteConfig, requireSiteConfig } from 'nuxt-site-config-kit';
|
|
12
14
|
import { provider } from 'std-env';
|
|
13
|
-
import { $fetch } from 'ofetch';
|
|
14
15
|
import playwrightCore from 'playwright-core';
|
|
15
16
|
import { existsSync } from 'node:fs';
|
|
16
17
|
import { createBirpcGroup } from 'birpc';
|
|
17
18
|
import { stringify, parse } from 'flatted';
|
|
19
|
+
import { addDependency } from 'nypm';
|
|
18
20
|
|
|
19
21
|
async function createBrowser() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
if (process.dev || process.env.prerender) {
|
|
23
|
+
try {
|
|
24
|
+
const { Launcher } = await import(String("chrome-launcher"));
|
|
25
|
+
const chromePath = Launcher.getFirstInstallation();
|
|
26
|
+
return await playwrightCore.chromium.launch({
|
|
27
|
+
headless: true,
|
|
28
|
+
executablePath: chromePath
|
|
29
|
+
});
|
|
30
|
+
} catch (e) {
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
try {
|
|
30
34
|
return await playwrightCore.chromium.launch({
|
|
@@ -55,9 +59,9 @@ async function screenshot(browser, options) {
|
|
|
55
59
|
width: options.width || 1200,
|
|
56
60
|
height: options.height || 630
|
|
57
61
|
});
|
|
58
|
-
const isHtml = options.path
|
|
62
|
+
const isHtml = options.html || options.path?.startsWith("html:");
|
|
59
63
|
if (isHtml) {
|
|
60
|
-
const html = options.html || options.path
|
|
64
|
+
const html = options.html || options.path?.substring(5);
|
|
61
65
|
await page.evaluate((html2) => {
|
|
62
66
|
document.open("text/html");
|
|
63
67
|
document.write(html2);
|
|
@@ -66,12 +70,12 @@ async function screenshot(browser, options) {
|
|
|
66
70
|
await page.waitForLoadState("networkidle");
|
|
67
71
|
} else {
|
|
68
72
|
await page.goto(`${options.host}${options.path}`, {
|
|
69
|
-
timeout: 1e4,
|
|
73
|
+
timeout: process.env.prerender || process.dev ? 1e4 : 3500,
|
|
70
74
|
waitUntil: "networkidle"
|
|
71
75
|
});
|
|
72
76
|
}
|
|
73
77
|
const screenshotOptions = {
|
|
74
|
-
timeout: 1e4
|
|
78
|
+
timeout: process.env.prerender || process.dev ? 1e4 : 3500
|
|
75
79
|
};
|
|
76
80
|
if (options.delay)
|
|
77
81
|
await page.waitForTimeout(options.delay);
|
|
@@ -83,7 +87,9 @@ async function screenshot(browser, options) {
|
|
|
83
87
|
}
|
|
84
88
|
if (options.selector)
|
|
85
89
|
return await page.locator(options.selector).screenshot(screenshotOptions);
|
|
86
|
-
|
|
90
|
+
const screenshot2 = await page.screenshot(screenshotOptions);
|
|
91
|
+
await page.close();
|
|
92
|
+
return screenshot2;
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
function setupPlaygroundRPC(nuxt, config) {
|
|
@@ -170,7 +176,7 @@ function getBodyJson(req) {
|
|
|
170
176
|
|
|
171
177
|
function decodeHtml(html) {
|
|
172
178
|
return html.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/¢/g, "\xA2").replace(/£/g, "\xA3").replace(/¥/g, "\xA5").replace(/€/g, "\u20AC").replace(/©/g, "\xA9").replace(/®/g, "\xAE").replace(/"/g, '"').replace(/'/g, "'").replace(/'/g, "'").replace(///g, "/").replace(/&#([0-9]+);/g, (full, int) => {
|
|
173
|
-
return String.fromCharCode(parseInt(int));
|
|
179
|
+
return String.fromCharCode(Number.parseInt(int));
|
|
174
180
|
});
|
|
175
181
|
}
|
|
176
182
|
function decodeObjectHtmlEntities(obj) {
|
|
@@ -205,46 +211,213 @@ function extractOgImageOptions(html) {
|
|
|
205
211
|
return false;
|
|
206
212
|
}
|
|
207
213
|
|
|
214
|
+
const SVG2PNGWasmPlaceholder = '"/* NUXT_OG_IMAGE_SVG2PNG_WASM */"';
|
|
215
|
+
const YogaWasmPlaceholder = '"/* NUXT_OG_IMAGE_YOGA_WASM */"';
|
|
216
|
+
const ReSVGWasmPlaceholder = '"/* NUXT_OG_IMAGE_RESVG_WASM */"';
|
|
217
|
+
const Wasms = [
|
|
218
|
+
{
|
|
219
|
+
placeholder: SVG2PNGWasmPlaceholder,
|
|
220
|
+
path: "svg2png/svg2png.wasm",
|
|
221
|
+
file: "svg2png.wasm"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
placeholder: ReSVGWasmPlaceholder,
|
|
225
|
+
path: "resvg/resvg.wasm",
|
|
226
|
+
file: "resvg.wasm"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
placeholder: YogaWasmPlaceholder,
|
|
230
|
+
path: "yoga/yoga.wasm",
|
|
231
|
+
file: "yoga.wasm"
|
|
232
|
+
}
|
|
233
|
+
];
|
|
234
|
+
const DefaultRuntimeCompatibility = {
|
|
235
|
+
// node-server runtime
|
|
236
|
+
browser: "playwright",
|
|
237
|
+
satori: "default",
|
|
238
|
+
wasm: "fetch",
|
|
239
|
+
png: "resvg-node",
|
|
240
|
+
node: true
|
|
241
|
+
};
|
|
242
|
+
const RuntimeCompatibility = {
|
|
243
|
+
"nitro-dev": {
|
|
244
|
+
wasm: "fetch",
|
|
245
|
+
browser: "universal"
|
|
246
|
+
},
|
|
247
|
+
"stackblitz": {
|
|
248
|
+
browser: false,
|
|
249
|
+
satori: "yoga-wasm",
|
|
250
|
+
wasm: "inline",
|
|
251
|
+
png: "resvg-wasm"
|
|
252
|
+
},
|
|
253
|
+
"netlify": {
|
|
254
|
+
browser: "lambda",
|
|
255
|
+
wasm: "inline"
|
|
256
|
+
},
|
|
257
|
+
"netlify-edge": {
|
|
258
|
+
wasm: "inline",
|
|
259
|
+
png: "resvg-wasm",
|
|
260
|
+
node: false
|
|
261
|
+
},
|
|
262
|
+
"vercel": {
|
|
263
|
+
// exceeds 50mb limit
|
|
264
|
+
browser: false
|
|
265
|
+
},
|
|
266
|
+
"vercel-edge": {
|
|
267
|
+
browser: false,
|
|
268
|
+
wasm: "import",
|
|
269
|
+
wasmImportQuery: "?module",
|
|
270
|
+
png: "resvg-wasm",
|
|
271
|
+
node: false
|
|
272
|
+
},
|
|
273
|
+
"cloudflare-pages": {
|
|
274
|
+
browser: false,
|
|
275
|
+
wasm: "import",
|
|
276
|
+
png: "resvg-wasm",
|
|
277
|
+
node: false
|
|
278
|
+
},
|
|
279
|
+
"cloudflare": {
|
|
280
|
+
browser: false,
|
|
281
|
+
wasm: "import"
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const autodetectableProviders = {
|
|
286
|
+
azure_static: "azure",
|
|
287
|
+
cloudflare_pages: "cloudflare-pages",
|
|
288
|
+
netlify: "netlify",
|
|
289
|
+
stormkit: "stormkit",
|
|
290
|
+
vercel: "vercel",
|
|
291
|
+
cleavr: "cleavr",
|
|
292
|
+
stackblitz: "stackblitz"
|
|
293
|
+
};
|
|
294
|
+
const autodetectableStaticProviders = {
|
|
295
|
+
netlify: "netlify-static",
|
|
296
|
+
vercel: "vercel-static"
|
|
297
|
+
};
|
|
298
|
+
function detectTarget(options = {}) {
|
|
299
|
+
return options?.static ? autodetectableStaticProviders[provider] : autodetectableProviders[provider];
|
|
300
|
+
}
|
|
301
|
+
function getNitroPreset(nuxt = useNuxt()) {
|
|
302
|
+
return process.env.NITRO_PRESET || nuxt.options.nitro.preset || detectTarget() || "node-server";
|
|
303
|
+
}
|
|
304
|
+
function getNitroProviderCompatibility(defaults, nuxt = useNuxt()) {
|
|
305
|
+
let compatibility;
|
|
306
|
+
if (provider === "stackblitz") {
|
|
307
|
+
compatibility = RuntimeCompatibility.stackblitz;
|
|
308
|
+
} else if (nuxt.options.dev || nuxt.options._prepare || nuxt.options._generate) {
|
|
309
|
+
compatibility = {
|
|
310
|
+
wasm: "fetch",
|
|
311
|
+
browser: "universal"
|
|
312
|
+
};
|
|
313
|
+
} else {
|
|
314
|
+
const target = getNitroPreset(nuxt);
|
|
315
|
+
const lookup = RuntimeCompatibility[target];
|
|
316
|
+
if (lookup === false)
|
|
317
|
+
return false;
|
|
318
|
+
compatibility = lookup || {};
|
|
319
|
+
}
|
|
320
|
+
compatibility = defu(compatibility, defaults);
|
|
321
|
+
compatibility.inlineCss = compatibility.inlineCss || (compatibility.node ? "node" : "mock");
|
|
322
|
+
return compatibility;
|
|
323
|
+
}
|
|
324
|
+
function ensureDependencies(nuxt, dep) {
|
|
325
|
+
return Promise.all(dep.map((d) => {
|
|
326
|
+
return addDependency(d, { cwd: nuxt.options.rootDir });
|
|
327
|
+
}));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function extendTypes(module, template) {
|
|
331
|
+
const nuxt = useNuxt();
|
|
332
|
+
addTemplate({
|
|
333
|
+
filename: `${module}.d.ts`,
|
|
334
|
+
getContents: () => {
|
|
335
|
+
const s = template();
|
|
336
|
+
return `// Generated by ${module}
|
|
337
|
+
${s}
|
|
338
|
+
export {}
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
nuxt.hooks.hook("prepare:types", ({ references }) => {
|
|
343
|
+
references.push({ path: resolve(nuxt.options.buildDir, `${module}.d.ts`) });
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
208
347
|
const PATH = "/__nuxt_og_image__";
|
|
209
348
|
const PATH_ENTRY = `${PATH}/entry`;
|
|
210
349
|
const PATH_PLAYGROUND = `${PATH}/client`;
|
|
211
|
-
const edgeProvidersSupported = [
|
|
212
|
-
"cloudflare",
|
|
213
|
-
"vercel-edge",
|
|
214
|
-
"netlify-edge"
|
|
215
|
-
];
|
|
216
350
|
const module = defineNuxtModule({
|
|
217
351
|
meta: {
|
|
218
352
|
name: "nuxt-og-image",
|
|
219
353
|
compatibility: {
|
|
220
|
-
nuxt: "^3.
|
|
354
|
+
nuxt: "^3.6.1",
|
|
221
355
|
bridge: false
|
|
222
356
|
},
|
|
223
357
|
configKey: "ogImage"
|
|
224
358
|
},
|
|
225
359
|
defaults(nuxt) {
|
|
226
|
-
const siteUrl = process.env.NUXT_PUBLIC_SITE_URL || process.env.NUXT_SITE_URL || nuxt.options.runtimeConfig.public?.siteUrl || nuxt.options.runtimeConfig.siteUrl;
|
|
227
360
|
return {
|
|
228
|
-
|
|
229
|
-
forcePrerender: !nuxt.options.dev && nuxt.options._generate,
|
|
230
|
-
siteUrl,
|
|
361
|
+
enabled: true,
|
|
231
362
|
defaults: {
|
|
232
|
-
component: "
|
|
363
|
+
component: "OgImageTemplateFallback",
|
|
233
364
|
width: 1200,
|
|
234
|
-
height: 630
|
|
365
|
+
height: 630,
|
|
366
|
+
// default is to cache the image for 24 hours
|
|
367
|
+
cache: true,
|
|
368
|
+
cacheTtl: 24 * 60 * 60 * 1e3
|
|
235
369
|
},
|
|
236
|
-
|
|
237
|
-
|
|
370
|
+
runtimeCompatibility: DefaultRuntimeCompatibility,
|
|
371
|
+
componentDirs: ["OgImage", "OgImageTemplate"],
|
|
372
|
+
runtimeSatori: true,
|
|
373
|
+
runtimeBrowser: nuxt.options.dev,
|
|
238
374
|
fonts: [],
|
|
375
|
+
runtimeCacheStorage: true,
|
|
239
376
|
satoriOptions: {},
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
playground: process.env.NODE_ENV === "development" || nuxt.options.dev
|
|
377
|
+
playground: process.env.NODE_ENV === "development" || nuxt.options.dev,
|
|
378
|
+
debug: false
|
|
243
379
|
};
|
|
244
380
|
},
|
|
245
381
|
async setup(config, nuxt) {
|
|
382
|
+
const logger = useLogger("nuxt-og-image");
|
|
383
|
+
logger.level = config.debug || nuxt.options.debug ? 4 : 3;
|
|
384
|
+
if (config.enabled === false) {
|
|
385
|
+
logger.debug("The module is disabled, skipping setup.");
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
246
388
|
const { resolve } = createResolver(import.meta.url);
|
|
247
|
-
|
|
389
|
+
logger.debug("Using Nitro preset", getNitroPreset());
|
|
390
|
+
const nitroCompatibility = getNitroProviderCompatibility(config.runtimeCompatibility);
|
|
391
|
+
logger.debug("Nitro compatibility", nitroCompatibility);
|
|
392
|
+
const nitroTarget = process.env.NITRO_PRESET || nuxt.options.nitro.preset || provider;
|
|
393
|
+
if (!nitroCompatibility) {
|
|
394
|
+
logger.warn(`\`nuxt-og-image\` does not support the nitro preset \`${nitroTarget}\`. Please make an issue. `);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (!nitroCompatibility.browser && config.runtimeBrowser) {
|
|
398
|
+
config.runtimeBrowser = false;
|
|
399
|
+
logger.warn(`\`nuxt-og-image\` does not support the nitro target \`${nitroTarget}\` with the runtime browser. Set runtimeBrowser: false to stop seeing this.`);
|
|
400
|
+
}
|
|
401
|
+
if (config.runtimeBrowser && nitroCompatibility.browser === "lambda") {
|
|
402
|
+
logger.info(`\`nuxt-og-image\` is deploying to nitro target \`${nitroTarget}\` that installs extra dependencies.`);
|
|
403
|
+
await ensureDependencies(nuxt, ["puppeteer-core@14.1.1", "@sparticuz/chrome-aws-lambda@14.1.1"]);
|
|
404
|
+
}
|
|
405
|
+
await installNuxtSiteConfig();
|
|
406
|
+
await updateSiteConfig({
|
|
407
|
+
_context: "nuxt-og-image:config",
|
|
408
|
+
url: config.siteUrl || config.host
|
|
409
|
+
});
|
|
410
|
+
requireSiteConfig("nuxt-og-image", {
|
|
411
|
+
url: "Required to generate absolute URLs for the og:image."
|
|
412
|
+
}, { prerender: true });
|
|
413
|
+
nuxt.options.nitro.storage = nuxt.options.nitro.storage || {};
|
|
414
|
+
if (nuxt.options._generate) {
|
|
415
|
+
nuxt.options.nitro.storage["og-image"] = {
|
|
416
|
+
driver: "memory"
|
|
417
|
+
};
|
|
418
|
+
} else if (config.runtimeCacheStorage && !nuxt.options.dev && typeof config.runtimeCacheStorage === "object") {
|
|
419
|
+
nuxt.options.nitro.storage["og-image"] = config.runtimeCacheStorage;
|
|
420
|
+
}
|
|
248
421
|
if (!config.fonts.length)
|
|
249
422
|
config.fonts = ["Inter:400", "Inter:700"];
|
|
250
423
|
const distResolve = (p) => {
|
|
@@ -254,34 +427,27 @@ const module = defineNuxtModule({
|
|
|
254
427
|
return resolve(`../dist/${p}`);
|
|
255
428
|
};
|
|
256
429
|
nuxt.options.experimental.componentIslands = true;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
getContents: () => {
|
|
260
|
-
return `// Generated by nuxt-og-image
|
|
261
|
-
interface NuxtOgImageNitroRules {
|
|
430
|
+
extendTypes("nuxt-og-image", () => {
|
|
431
|
+
return `interface NuxtOgImageNitroRules {
|
|
262
432
|
ogImage?: false | Record<string, any>
|
|
263
433
|
}
|
|
264
434
|
declare module 'nitropack' {
|
|
265
435
|
interface NitroRouteRules extends NuxtOgImageNitroRules {}
|
|
266
436
|
interface NitroRouteConfig extends NuxtOgImageNitroRules {}
|
|
267
|
-
}
|
|
268
|
-
export {}
|
|
269
|
-
`;
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
nuxt.hooks.hook("prepare:types", ({ references }) => {
|
|
273
|
-
references.push({ path: resolve(nuxt.options.buildDir, "nuxt-og-image.d.ts") });
|
|
437
|
+
}`;
|
|
274
438
|
});
|
|
275
439
|
addServerHandler({
|
|
276
440
|
lazy: true,
|
|
277
441
|
handler: resolve("./runtime/nitro/middleware/og.png")
|
|
278
442
|
});
|
|
279
|
-
["html", "options", "svg", "vnode", "font"].forEach((type) => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
443
|
+
["html", "options", "svg", "vnode", "font", "debug"].forEach((type) => {
|
|
444
|
+
if (type !== "debug" || config.debug) {
|
|
445
|
+
addServerHandler({
|
|
446
|
+
lazy: true,
|
|
447
|
+
route: `/api/og-image-${type}`,
|
|
448
|
+
handler: resolve(`./runtime/nitro/routes/${type}`)
|
|
449
|
+
});
|
|
450
|
+
}
|
|
285
451
|
});
|
|
286
452
|
nuxt.hook("devtools:customTabs", (iframeTabs) => {
|
|
287
453
|
iframeTabs.push({
|
|
@@ -310,7 +476,17 @@ export {}
|
|
|
310
476
|
});
|
|
311
477
|
}
|
|
312
478
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"] = [];
|
|
313
|
-
[
|
|
479
|
+
[
|
|
480
|
+
// deprecated
|
|
481
|
+
"Dynamic",
|
|
482
|
+
"Static",
|
|
483
|
+
// new
|
|
484
|
+
"index",
|
|
485
|
+
"Cached",
|
|
486
|
+
"WithoutCache",
|
|
487
|
+
"Screenshot"
|
|
488
|
+
].forEach((name) => {
|
|
489
|
+
name = name === "index" ? "defineOgImage" : `defineOgImage${name}`;
|
|
314
490
|
addImports({
|
|
315
491
|
name,
|
|
316
492
|
from: resolve("./runtime/composables/defineOgImage")
|
|
@@ -318,104 +494,205 @@ export {}
|
|
|
318
494
|
nuxt.options.optimization.treeShake.composables.client["nuxt-og-image"].push(name);
|
|
319
495
|
});
|
|
320
496
|
await addComponent({
|
|
321
|
-
name: "
|
|
322
|
-
filePath: resolve("./runtime/components/
|
|
497
|
+
name: "OgImageTemplateFallback",
|
|
498
|
+
filePath: resolve("./runtime/components/OgImageTemplate/Fallback.vue"),
|
|
323
499
|
island: true
|
|
324
500
|
});
|
|
325
|
-
[
|
|
501
|
+
[
|
|
502
|
+
// deprecated
|
|
503
|
+
"Static",
|
|
504
|
+
"Dynamic",
|
|
505
|
+
// new
|
|
506
|
+
"index",
|
|
507
|
+
"Cached",
|
|
508
|
+
"WithoutCache",
|
|
509
|
+
"Screenshot"
|
|
510
|
+
].forEach((name) => {
|
|
326
511
|
addComponent({
|
|
327
|
-
|
|
328
|
-
|
|
512
|
+
global: hasNuxtModule("@nuxt/content"),
|
|
513
|
+
name: name === "index" ? "OgImage" : `OgImage${name}`,
|
|
514
|
+
filePath: resolve(`./runtime/components/OgImage/${name}`)
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
const ogImageComponents = [];
|
|
518
|
+
nuxt.hook("components:extend", (components) => {
|
|
519
|
+
components.forEach((component) => {
|
|
520
|
+
let valid = false;
|
|
521
|
+
config.componentDirs.forEach((dir) => {
|
|
522
|
+
if (component.pascalName.startsWith(dir) || component.kebabName.startsWith(dir))
|
|
523
|
+
valid = true;
|
|
524
|
+
});
|
|
525
|
+
if (valid) {
|
|
526
|
+
component.island = true;
|
|
527
|
+
component.mode = "server";
|
|
528
|
+
ogImageComponents.push({ pascalName: component.pascalName, kebabName: component.kebabName });
|
|
529
|
+
}
|
|
329
530
|
});
|
|
330
531
|
});
|
|
532
|
+
addTemplate({
|
|
533
|
+
filename: "og-image-component-names.mjs",
|
|
534
|
+
getContents() {
|
|
535
|
+
return `export const componentNames = ${JSON.stringify(ogImageComponents)}`;
|
|
536
|
+
},
|
|
537
|
+
options: { mode: "server" }
|
|
538
|
+
});
|
|
331
539
|
const runtimeDir = resolve("./runtime");
|
|
332
540
|
nuxt.options.build.transpile.push(runtimeDir);
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
541
|
+
addServerPlugin(resolve("./runtime/nitro/plugins/prerender"));
|
|
542
|
+
const customAssetDirs = [
|
|
543
|
+
// allows us to show custom error images
|
|
544
|
+
resolve("./runtime/public-assets")
|
|
337
545
|
];
|
|
546
|
+
if (config.runtimeSatori) {
|
|
547
|
+
if (config.fonts.includes("Inter:400"))
|
|
548
|
+
customAssetDirs.push(resolve("./runtime/public-assets-optional/inter-font"));
|
|
549
|
+
if (nitroCompatibility.png === "resvg-wasm" && nitroCompatibility.wasm === "fetch")
|
|
550
|
+
customAssetDirs.push(resolve("./runtime/public-assets-optional/resvg"));
|
|
551
|
+
else if (nitroCompatibility.png === "svg2png" && nitroCompatibility.wasm === "fetch")
|
|
552
|
+
customAssetDirs.push(resolve("./runtime/public-assets-optional/svg2png"));
|
|
553
|
+
if (nitroCompatibility.satori === "yoga-wasm")
|
|
554
|
+
customAssetDirs.push(resolve("./runtime/public-assets-optional/yoga"));
|
|
555
|
+
}
|
|
338
556
|
nuxt.hooks.hook("modules:done", async () => {
|
|
339
557
|
nuxt.hooks.callHook("og-image:config", config);
|
|
340
|
-
nuxt.options.runtimeConfig["nuxt-og-image"] = {
|
|
558
|
+
nuxt.options.runtimeConfig["nuxt-og-image"] = {
|
|
559
|
+
satoriOptions: config.satoriOptions,
|
|
560
|
+
runtimeSatori: config.runtimeSatori,
|
|
561
|
+
runtimeBrowser: config.runtimeBrowser,
|
|
562
|
+
// @ts-expect-error runtime type
|
|
563
|
+
defaults: config.defaults,
|
|
564
|
+
// avoid adding credentials
|
|
565
|
+
runtimeCacheStorage: typeof config.runtimeCacheStorage === "boolean" ? "default" : config.runtimeCacheStorage.driver,
|
|
566
|
+
// convert the fonts to uniform type to fix ts issue
|
|
567
|
+
fonts: config.fonts.map((f) => {
|
|
568
|
+
if (typeof f === "string") {
|
|
569
|
+
const [name, weight] = f.split(":");
|
|
570
|
+
return {
|
|
571
|
+
name,
|
|
572
|
+
weight
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
return f;
|
|
576
|
+
}),
|
|
577
|
+
assetDirs: [
|
|
578
|
+
resolve(nuxt.options.srcDir, nuxt.options.dir.public),
|
|
579
|
+
...customAssetDirs,
|
|
580
|
+
// always add runtime dirs for prerendering to work, these are just used as scan roots
|
|
581
|
+
resolve("./runtime/public-assets-optional/inter-font"),
|
|
582
|
+
resolve("./runtime/public-assets-optional/resvg"),
|
|
583
|
+
resolve("./runtime/public-assets-optional/yoga"),
|
|
584
|
+
resolve("./runtime/public-assets-optional/svg2png")
|
|
585
|
+
]
|
|
586
|
+
};
|
|
341
587
|
});
|
|
342
|
-
const useSatoriWasm = provider === "stackblitz";
|
|
343
588
|
nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
|
|
344
589
|
nitroConfig.externals = defu(nitroConfig.externals || {}, {
|
|
345
590
|
inline: [runtimeDir]
|
|
346
591
|
});
|
|
347
|
-
if (config.
|
|
592
|
+
if (config.runtimeBrowser) {
|
|
348
593
|
nitroConfig.alias = nitroConfig.alias || {};
|
|
349
594
|
nitroConfig.alias.electron = "unenv/runtime/mock/proxy-cjs";
|
|
350
595
|
nitroConfig.alias.bufferutil = "unenv/runtime/mock/proxy-cjs";
|
|
351
596
|
nitroConfig.alias["utf-8-validate"] = "unenv/runtime/mock/proxy-cjs";
|
|
352
597
|
}
|
|
598
|
+
if (nitroCompatibility.png === "resvg-wasm")
|
|
599
|
+
nitroConfig.alias["@resvg/resvg-js"] = "unenv/runtime/mock/proxy-cjs";
|
|
353
600
|
nitroConfig.publicAssets = nitroConfig.publicAssets || [];
|
|
354
|
-
|
|
601
|
+
customAssetDirs.forEach((dir) => {
|
|
602
|
+
nitroConfig.publicAssets.push({ dir, maxAge: 31536e3 });
|
|
603
|
+
});
|
|
355
604
|
const providerPath = `${runtimeDir}/nitro/providers`;
|
|
356
|
-
if (config.
|
|
357
|
-
nitroConfig.virtual["#nuxt-og-image/browser"] =
|
|
358
|
-
|
|
359
|
-
|
|
605
|
+
if (config.runtimeBrowser) {
|
|
606
|
+
nitroConfig.virtual["#nuxt-og-image/browser"] = `
|
|
607
|
+
let browser
|
|
360
608
|
export default async function() {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
` : `export default async function() {
|
|
364
|
-
return () => {}
|
|
609
|
+
browser = browser || await import('${providerPath}/browser/${nitroCompatibility.browser}').then((m) => m.default || m)
|
|
610
|
+
return browser
|
|
365
611
|
}
|
|
366
612
|
`;
|
|
367
613
|
}
|
|
368
|
-
if (config.
|
|
369
|
-
nitroConfig.virtual["#nuxt-og-image/satori"] = `import satori from '${providerPath}/satori/${
|
|
370
|
-
export default
|
|
614
|
+
if (config.runtimeSatori) {
|
|
615
|
+
nitroConfig.virtual["#nuxt-og-image/satori"] = `import satori from '${providerPath}/satori/${nitroCompatibility.satori}'
|
|
616
|
+
export default function() {
|
|
371
617
|
return satori
|
|
372
618
|
}`;
|
|
373
|
-
nitroConfig.virtual["#nuxt-og-image/
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
619
|
+
nitroConfig.virtual["#nuxt-og-image/png"] = `import png from '${providerPath}/png/${nitroCompatibility.png}'
|
|
620
|
+
export default function() {
|
|
621
|
+
return png
|
|
622
|
+
}
|
|
623
|
+
`;
|
|
624
|
+
nitroConfig.virtual["#nuxt-og-image/inline-css"] = `import inlineCss from '${providerPath}/inline-css/${nitroCompatibility.inlineCss || "mock"}'
|
|
625
|
+
export default function() {
|
|
626
|
+
return inlineCss
|
|
627
|
+
}
|
|
628
|
+
`;
|
|
378
629
|
}
|
|
379
630
|
nitroConfig.virtual["#nuxt-og-image/provider"] = `
|
|
380
|
-
import satori from '${relative(nuxt.options.rootDir, resolve("./runtime/nitro/renderers/satori"))}'
|
|
381
|
-
import browser from '${relative(nuxt.options.rootDir, resolve("./runtime/nitro/renderers/browser"))}'
|
|
631
|
+
${config.runtimeSatori ? `import satori from '${relative(nuxt.options.rootDir, resolve("./runtime/nitro/renderers/satori"))}'` : ""}
|
|
632
|
+
${config.runtimeBrowser ? `import browser from '${relative(nuxt.options.rootDir, resolve("./runtime/nitro/renderers/browser"))}'` : ""}
|
|
382
633
|
|
|
383
634
|
export async function useProvider(provider) {
|
|
384
635
|
if (provider === 'satori')
|
|
385
|
-
return satori
|
|
636
|
+
return ${config.runtimeSatori ? "satori" : "null"}
|
|
386
637
|
if (provider === 'browser')
|
|
387
|
-
return browser
|
|
638
|
+
return ${config.runtimeBrowser ? "browser" : "null"}
|
|
639
|
+
return null
|
|
388
640
|
}
|
|
389
641
|
`;
|
|
390
642
|
});
|
|
391
643
|
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
392
644
|
let screenshotQueue = [];
|
|
393
645
|
nitro.hooks.hook("compiled", async (_nitro) => {
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
646
|
+
if (!config.runtimeSatori || nuxt.options.dev)
|
|
647
|
+
return;
|
|
648
|
+
if (config.fonts.includes("Inter:400"))
|
|
649
|
+
await copy(resolve("./runtime/public-assets-optional/inter-font/inter-latin-ext-400-normal.woff"), resolve(_nitro.options.output.publicDir, "inter-latin-ext-400-normal.woff"));
|
|
650
|
+
if (config.fonts.includes("Inter:700"))
|
|
651
|
+
await copy(resolve("./runtime/public-assets-optional/inter-font/inter-latin-ext-700-normal.woff"), resolve(_nitro.options.output.publicDir, "inter-latin-ext-700-normal.woff"));
|
|
652
|
+
const configuredEntry = nitro.options.rollupConfig?.output.entryFileNames;
|
|
653
|
+
const wasmProviderPath = resolve(_nitro.options.output.serverDir, typeof configuredEntry === "string" ? configuredEntry : "index.mjs");
|
|
654
|
+
const paths = [wasmProviderPath];
|
|
655
|
+
const chunks = await globby([`${_nitro.options.output.serverDir}/chunks/**/*.mjs`], { absolute: true });
|
|
656
|
+
paths.push(...chunks);
|
|
657
|
+
for (const path of paths) {
|
|
658
|
+
if (!await pathExists(path))
|
|
659
|
+
continue;
|
|
660
|
+
let contents = await readFile(path, "utf-8");
|
|
661
|
+
let updated = false;
|
|
662
|
+
if (_nitro.options.preset.includes("vercel") && path === wasmProviderPath) {
|
|
663
|
+
contents = contents.replace(".cwd(),", '?.cwd || "/",');
|
|
664
|
+
updated = true;
|
|
401
665
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
666
|
+
if (_nitro.options.preset.includes("netlify") && path.endsWith("netlify.mjs")) {
|
|
667
|
+
const match = "// TODO: handle event.isBase64Encoded\n });";
|
|
668
|
+
contents = contents.replace(match, `${match}
|
|
669
|
+
|
|
670
|
+
const headers = normalizeOutgoingHeaders(r.headers);
|
|
671
|
+
// image buffers must be base64 encoded
|
|
672
|
+
if (Buffer.isBuffer(r.body) && headers["content-type"].startsWith("image/")) {
|
|
673
|
+
return {
|
|
674
|
+
statusCode: r.status,
|
|
675
|
+
headers,
|
|
676
|
+
body: r.body.toString("base64"),
|
|
677
|
+
isBase64Encoded: true
|
|
678
|
+
};
|
|
679
|
+
}`);
|
|
680
|
+
updated = true;
|
|
681
|
+
}
|
|
682
|
+
for (const wasm of Wasms) {
|
|
683
|
+
if (contents.includes(wasm.placeholder)) {
|
|
684
|
+
if (nitroCompatibility.wasm === "import") {
|
|
685
|
+
contents = contents.replace(wasm.placeholder, `import("./${wasm.file}${nitroCompatibility.wasmImportQuery || ""}").then(m => m.default || m)`);
|
|
686
|
+
await copy(resolve(`./runtime/public-assets-optional/${wasm.path}`), resolve(dirname(path), wasm.file));
|
|
687
|
+
} else if (nitroCompatibility.wasm === "inline") {
|
|
688
|
+
const wasmBuffer = await readFile(resolve(`./runtime/public-assets-optional/${wasm.path}`));
|
|
689
|
+
contents = contents.replace(wasm.placeholder, `Buffer.from("${wasmBuffer}", "base64")`);
|
|
690
|
+
}
|
|
691
|
+
updated = true;
|
|
417
692
|
}
|
|
418
693
|
}
|
|
694
|
+
if (updated)
|
|
695
|
+
await writeFile(path, contents, { encoding: "utf-8" });
|
|
419
696
|
}
|
|
420
697
|
});
|
|
421
698
|
const _routeRulesMatcher = toRouteMatcher(
|
|
@@ -437,7 +714,7 @@ export async function useProvider(provider) {
|
|
|
437
714
|
...extractedOptions,
|
|
438
715
|
...routeRules.ogImage || {}
|
|
439
716
|
};
|
|
440
|
-
if ((nuxt.options._generate || entry.
|
|
717
|
+
if ((nuxt.options._generate || entry.cache) && entry.provider === "browser")
|
|
441
718
|
screenshotQueue.push(entry);
|
|
442
719
|
});
|
|
443
720
|
if (nuxt.options.dev)
|
|
@@ -485,14 +762,14 @@ export async function useProvider(provider) {
|
|
|
485
762
|
});
|
|
486
763
|
}
|
|
487
764
|
if (entry.component)
|
|
488
|
-
entry.html = await
|
|
765
|
+
entry.html = await globalThis.$fetch(entry.path);
|
|
489
766
|
}
|
|
490
767
|
for (const k in screenshotQueue) {
|
|
491
768
|
const entry = screenshotQueue[k];
|
|
492
769
|
const start = Date.now();
|
|
493
770
|
let hasError = false;
|
|
494
|
-
const
|
|
495
|
-
const filename = joinURL(
|
|
771
|
+
const dirname2 = joinURL(nitro.options.output.publicDir, entry.route, "/__og_image__/");
|
|
772
|
+
const filename = joinURL(dirname2, "/og.png");
|
|
496
773
|
try {
|
|
497
774
|
const imgBuffer = await screenshot(browser, {
|
|
498
775
|
...config.defaults || {},
|
|
@@ -500,7 +777,7 @@ export async function useProvider(provider) {
|
|
|
500
777
|
host
|
|
501
778
|
});
|
|
502
779
|
try {
|
|
503
|
-
await mkdirp(
|
|
780
|
+
await mkdirp(dirname2);
|
|
504
781
|
} catch (e) {
|
|
505
782
|
}
|
|
506
783
|
await writeFile(filename, imgBuffer);
|