nuxt-og-image 4.1.4 → 4.1.6

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.
@@ -1 +1 @@
1
- {"id":"ae36edbe-d750-4528-bc56-0a4f60b76f8a","timestamp":1739913275804}
1
+ {"id":"fd06485b-dbd3-44aa-a703-c6e9de356437","timestamp":1741095295308}
@@ -0,0 +1 @@
1
+ {"id":"fd06485b-dbd3-44aa-a703-c6e9de356437","timestamp":1741095295308,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -0,0 +1 @@
1
+ .spotlight[data-v-5616cafb]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-5616cafb]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-5616cafb]{background-color:#ffffff4d}.gradient-border[data-v-5616cafb]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-5616cafb]{background-color:#1414144d}.gradient-border[data-v-5616cafb]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-5616cafb]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-5616cafb]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-5616cafb]{position:fixed}.left-0[data-v-5616cafb]{left:0}.right-0[data-v-5616cafb]{right:0}.z-10[data-v-5616cafb]{z-index:10}.z-20[data-v-5616cafb]{z-index:20}.grid[data-v-5616cafb]{display:grid}.mb-16[data-v-5616cafb]{margin-bottom:4rem}.mb-8[data-v-5616cafb]{margin-bottom:2rem}.max-w-520px[data-v-5616cafb]{max-width:520px}.min-h-screen[data-v-5616cafb]{min-height:100vh}.w-full[data-v-5616cafb]{width:100%}.flex[data-v-5616cafb]{display:flex}.cursor-pointer[data-v-5616cafb]{cursor:pointer}.place-content-center[data-v-5616cafb]{place-content:center}.items-center[data-v-5616cafb]{align-items:center}.justify-center[data-v-5616cafb]{justify-content:center}.overflow-hidden[data-v-5616cafb]{overflow:hidden}.bg-white[data-v-5616cafb]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-5616cafb]{padding-left:1rem;padding-right:1rem}.px-8[data-v-5616cafb]{padding-left:2rem;padding-right:2rem}.py-2[data-v-5616cafb]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-5616cafb]{text-align:center}.text-8xl[data-v-5616cafb]{font-size:6rem;line-height:1}.text-xl[data-v-5616cafb]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-5616cafb]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-5616cafb]{font-weight:300}.font-medium[data-v-5616cafb]{font-weight:500}.leading-tight[data-v-5616cafb]{line-height:1.25}.font-sans[data-v-5616cafb]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-5616cafb]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-5616cafb]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-5616cafb]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-5616cafb]{padding-left:0;padding-right:0}.sm\:px-6[data-v-5616cafb]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-5616cafb]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-5616cafb]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-5616cafb]{font-size:1.25rem;line-height:1.75rem}}
@@ -0,0 +1 @@
1
+ .spotlight[data-v-18f13167]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-18f13167]{position:fixed}.-bottom-1\/2[data-v-18f13167]{bottom:-50%}.left-0[data-v-18f13167]{left:0}.right-0[data-v-18f13167]{right:0}.grid[data-v-18f13167]{display:grid}.mb-16[data-v-18f13167]{margin-bottom:4rem}.mb-8[data-v-18f13167]{margin-bottom:2rem}.h-1\/2[data-v-18f13167]{height:50%}.max-w-520px[data-v-18f13167]{max-width:520px}.min-h-screen[data-v-18f13167]{min-height:100vh}.place-content-center[data-v-18f13167]{place-content:center}.overflow-hidden[data-v-18f13167]{overflow:hidden}.bg-white[data-v-18f13167]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-18f13167]{padding-left:2rem;padding-right:2rem}.text-center[data-v-18f13167]{text-align:center}.text-8xl[data-v-18f13167]{font-size:6rem;line-height:1}.text-xl[data-v-18f13167]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-18f13167]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-18f13167]{font-weight:300}.font-medium[data-v-18f13167]{font-weight:500}.leading-tight[data-v-18f13167]{line-height:1.25}.font-sans[data-v-18f13167]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-18f13167]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-18f13167]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-18f13167]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-18f13167]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-18f13167]{font-size:2.25rem;line-height:2.5rem}}
@@ -1,15 +1,15 @@
1
1
  <!DOCTYPE html><html data-capo=""><head><meta charset="utf-8">
2
2
  <meta name="viewport" content="width=device-width, initial-scale=1">
3
3
  <link rel="stylesheet" href="/__nuxt-og-image/_nuxt/entry.BZSHFM_J.css" crossorigin>
4
- <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CfDoOVw0.js">
4
+ <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/JBzDG9IY.js">
5
5
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CVO1_9PV.js">
6
6
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/D0r3Knsf.js">
7
7
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DGRTSKzu.js">
8
8
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DTAJTTim.js">
9
9
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/B6E6ObS_.js">
10
- <link rel="prefetch" as="style" crossorigin href="/__nuxt-og-image/_nuxt/error-404.CGnoa_1h.css">
11
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/jxZXbuzO.js">
12
- <link rel="prefetch" as="style" crossorigin href="/__nuxt-og-image/_nuxt/error-500.BhZShif1.css">
13
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BZ1PubqM.js">
14
- <script type="module" src="/__nuxt-og-image/_nuxt/CfDoOVw0.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1739913287340,false]</script>
15
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildId:"ae36edbe-d750-4528-bc56-0a4f60b76f8a",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
10
+ <link rel="prefetch" as="style" crossorigin href="/__nuxt-og-image/_nuxt/error-404.BiS1A2ch.css">
11
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CwEDx-Kw.js">
12
+ <link rel="prefetch" as="style" crossorigin href="/__nuxt-og-image/_nuxt/error-500.CvF7md1_.css">
13
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/D5ioqy50.js">
14
+ <script type="module" src="/__nuxt-og-image/_nuxt/JBzDG9IY.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1741095305769,false]</script>
15
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildId:"fd06485b-dbd3-44aa-a703-c6e9de356437",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.cjs CHANGED
@@ -14,6 +14,8 @@ const unstorage = require('unstorage');
14
14
  const fsDriver = require('unstorage/drivers/fs');
15
15
  const node_crypto = require('node:crypto');
16
16
  const nypm = require('nypm');
17
+ const chromeLauncher = require('chrome-launcher');
18
+ const ofetch = require('ofetch');
17
19
  const node_path = require('node:path');
18
20
  const devtoolsKit = require('@nuxt/devtools-kit');
19
21
  const node_url = require('node:url');
@@ -21,8 +23,6 @@ const MagicString = require('magic-string');
21
23
  const stripLiteral = require('strip-literal');
22
24
  const unplugin = require('unplugin');
23
25
  const logger_js = require('../dist/runtime/logger.js');
24
- const chromeLauncher = require('chrome-launcher');
25
- const ofetch = require('ofetch');
26
26
 
27
27
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
28
28
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -43,6 +43,48 @@ const fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
43
43
  const fsDriver__default = /*#__PURE__*/_interopDefaultCompat(fsDriver);
44
44
  const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
45
45
 
46
+ const isUndefinedOrTruthy = (v) => typeof v === "undefined" || v !== false;
47
+ function checkLocalChrome() {
48
+ if (stdEnv.isCI)
49
+ return false;
50
+ let hasChromeLocally = false;
51
+ try {
52
+ hasChromeLocally = !!chromeLauncher.Launcher.getFirstInstallation();
53
+ } catch {
54
+ }
55
+ return hasChromeLocally;
56
+ }
57
+ async function hasResolvableDependency(dep) {
58
+ return await kit.resolvePath(dep, { fallbackToOriginal: true }).catch(() => null).then((r) => r && r !== dep);
59
+ }
60
+ async function downloadFont(font, storage, mirror) {
61
+ const { name, weight, style } = font;
62
+ const key = `${name}-${style}-${weight}.ttf.base64`;
63
+ if (await storage.hasItem(key))
64
+ return true;
65
+ const host = typeof mirror === "undefined" ? "fonts.googleapis.com" : mirror === true ? "fonts.font.im" : mirror;
66
+ const css = await ofetch.$fetch(`https://${host}/css2?family=${name}:${style === "ital" ? `ital,wght@1,${weight}` : `wght@${weight}`}`, {
67
+ timeout: 10 * 1e3,
68
+ // 10 second timeout
69
+ headers: {
70
+ // Make sure it returns TTF.
71
+ "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
72
+ }
73
+ }).catch(() => {
74
+ return false;
75
+ });
76
+ if (!css)
77
+ return false;
78
+ const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
79
+ if (ttfResource?.[1]) {
80
+ const buf = await ofetch.$fetch(ttfResource[1], { baseURL: host, responseType: "arrayBuffer" });
81
+ const base64Font = Buffer.from(buf).toString("base64");
82
+ await storage.setItem(key, base64Font);
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+
46
88
  const autodetectableProviders = {
47
89
  azure_static: "azure",
48
90
  cloudflare_pages: "cloudflare-pages",
@@ -159,8 +201,8 @@ function getPresetNitroPresetCompatibility(target) {
159
201
  async function applyNitroPresetCompatibility(nitroConfig, options) {
160
202
  const target = resolveNitroPreset(nitroConfig);
161
203
  const compatibility = getPresetNitroPresetCompatibility(target);
162
- const hasCssInlineNode = !!await kit.tryResolveModule("@css-inline/css-inline");
163
- const hasCssInlineWasm = !!await kit.tryResolveModule("@css-inline/css-inline-wasm");
204
+ const hasCssInlineNode = await hasResolvableDependency("@css-inline/css-inline");
205
+ const hasCssInlineWasm = await hasResolvableDependency("@css-inline/css-inline-wasm");
164
206
  const { resolve } = options;
165
207
  const satoriEnabled = typeof options.compatibility?.satori !== "undefined" ? !!options.compatibility.satori : !!compatibility.satori;
166
208
  const chromiumEnabled = typeof options.compatibility?.chromium !== "undefined" ? !!options.compatibility.chromium : !!compatibility.chromium;
@@ -504,48 +546,6 @@ function normaliseFontInput(fonts) {
504
546
  });
505
547
  }
506
548
 
507
- const isUndefinedOrTruthy = (v) => typeof v === "undefined" || v !== false;
508
- function checkLocalChrome() {
509
- if (stdEnv.isCI)
510
- return false;
511
- let hasChromeLocally = false;
512
- try {
513
- hasChromeLocally = !!chromeLauncher.Launcher.getFirstInstallation();
514
- } catch {
515
- }
516
- return hasChromeLocally;
517
- }
518
- async function checkPlaywrightDependency() {
519
- return !!await kit.tryResolveModule("playwright");
520
- }
521
- async function downloadFont(font, storage, mirror) {
522
- const { name, weight, style } = font;
523
- const key = `${name}-${style}-${weight}.ttf.base64`;
524
- if (await storage.hasItem(key))
525
- return true;
526
- const host = typeof mirror === "undefined" ? "fonts.googleapis.com" : mirror === true ? "fonts.font.im" : mirror;
527
- const css = await ofetch.$fetch(`https://${host}/css2?family=${name}:${style === "ital" ? `ital,wght@1,${weight}` : `wght@${weight}`}`, {
528
- timeout: 10 * 1e3,
529
- // 10 second timeout
530
- headers: {
531
- // Make sure it returns TTF.
532
- "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
533
- }
534
- }).catch(() => {
535
- return false;
536
- });
537
- if (!css)
538
- return false;
539
- const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
540
- if (ttfResource?.[1]) {
541
- const buf = await ofetch.$fetch(ttfResource[1], { baseURL: host, responseType: "arrayBuffer" });
542
- const base64Font = Buffer.from(buf).toString("base64");
543
- await storage.setItem(key, base64Font);
544
- return true;
545
- }
546
- return false;
547
- }
548
-
549
549
  const module$1 = kit.defineNuxtModule({
550
550
  meta: {
551
551
  name: "nuxt-og-image",
@@ -612,7 +612,7 @@ const module$1 = kit.defineNuxtModule({
612
612
  const hasConfiguredJpegs = userConfiguredExtension && ["jpeg", "jpg"].includes(userConfiguredExtension);
613
613
  if (!!config.sharpOptions || hasConfiguredJpegs && config.defaults.renderer !== "chromium") {
614
614
  isUsingSharp = true;
615
- const hasSharpDependency = !!await kit.tryResolveModule("sharp");
615
+ const hasSharpDependency = await hasResolvableDependency("sharp");
616
616
  if (hasSharpDependency && !targetCompatibility.sharp) {
617
617
  logger_js.logger.warn(`Rendering JPEGs requires sharp which does not work with ${preset}. Images will be rendered as PNG at runtime.`);
618
618
  config.compatibility = defu.defu(config.compatibility, {
@@ -632,7 +632,7 @@ const module$1 = kit.defineNuxtModule({
632
632
  });
633
633
  }
634
634
  const hasChromeLocally = checkLocalChrome();
635
- const hasPlaywrightDependency = await checkPlaywrightDependency();
635
+ const hasPlaywrightDependency = await hasResolvableDependency("playwright");
636
636
  const chromeCompatibilityFlags = {
637
637
  prerender: config.compatibility?.prerender?.chromium,
638
638
  dev: config.compatibility?.dev?.chromium,
@@ -819,7 +819,7 @@ const module$1 = kit.defineNuxtModule({
819
819
  const credits = componentFile.split("\n").find((line) => line.startsWith(" * @credits"))?.replace("* @credits", "").trim();
820
820
  ogImageComponentCtx.components.push({
821
821
  // purge cache when component changes
822
- hash: ohash.hash(componentFile),
822
+ hash: ohash.hash(componentFile).replaceAll("_", "-"),
823
823
  pascalName: component.pascalName,
824
824
  kebabName: component.kebabName,
825
825
  path: nuxt.options.dev ? component.filePath : void 0,
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "4.1.3",
8
+ "version": "4.1.5",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "0.8.4",
11
11
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,18 +1,20 @@
1
1
  import * as fs from 'node:fs';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { readFile, writeFile } from 'node:fs/promises';
4
- import { useNuxt, tryResolveModule, addTemplate, resolvePath, loadNuxtModuleInstance, createResolver, defineNuxtModule, addImports, addBuildPlugin, hasNuxtModule, hasNuxtModuleCompatibility, addServerPlugin, addServerHandler, addComponentsDir, addComponent, addPlugin } from '@nuxt/kit';
4
+ import { resolvePath, useNuxt, addTemplate, loadNuxtModuleInstance, createResolver, defineNuxtModule, addImports, addBuildPlugin, hasNuxtModule, hasNuxtModuleCompatibility, addServerPlugin, addServerHandler, addComponentsDir, addComponent, addPlugin } from '@nuxt/kit';
5
5
  import { defu } from 'defu';
6
6
  import { installNuxtSiteConfig } from 'nuxt-site-config/kit';
7
7
  import { hash } from 'ohash';
8
8
  import { dirname, relative as relative$1, isAbsolute, basename } from 'pathe';
9
9
  import { readPackageJSON } from 'pkg-types';
10
- import { provider, env, isCI, isDevelopment } from 'std-env';
10
+ import { isCI, provider, env, isDevelopment } from 'std-env';
11
11
  import { parseURL, parseQuery, withoutLeadingSlash } from 'ufo';
12
12
  import { createStorage } from 'unstorage';
13
13
  import fsDriver from 'unstorage/drivers/fs';
14
14
  import { createHash } from 'node:crypto';
15
15
  import { ensureDependencyInstalled } from 'nypm';
16
+ import { Launcher } from 'chrome-launcher';
17
+ import { $fetch } from 'ofetch';
16
18
  import { relative } from 'node:path';
17
19
  import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
18
20
  import { pathToFileURL } from 'node:url';
@@ -20,8 +22,48 @@ import MagicString from 'magic-string';
20
22
  import { stripLiteral } from 'strip-literal';
21
23
  import { createUnplugin } from 'unplugin';
22
24
  import { logger } from '../dist/runtime/logger.js';
23
- import { Launcher } from 'chrome-launcher';
24
- import { $fetch } from 'ofetch';
25
+
26
+ const isUndefinedOrTruthy = (v) => typeof v === "undefined" || v !== false;
27
+ function checkLocalChrome() {
28
+ if (isCI)
29
+ return false;
30
+ let hasChromeLocally = false;
31
+ try {
32
+ hasChromeLocally = !!Launcher.getFirstInstallation();
33
+ } catch {
34
+ }
35
+ return hasChromeLocally;
36
+ }
37
+ async function hasResolvableDependency(dep) {
38
+ return await resolvePath(dep, { fallbackToOriginal: true }).catch(() => null).then((r) => r && r !== dep);
39
+ }
40
+ async function downloadFont(font, storage, mirror) {
41
+ const { name, weight, style } = font;
42
+ const key = `${name}-${style}-${weight}.ttf.base64`;
43
+ if (await storage.hasItem(key))
44
+ return true;
45
+ const host = typeof mirror === "undefined" ? "fonts.googleapis.com" : mirror === true ? "fonts.font.im" : mirror;
46
+ const css = await $fetch(`https://${host}/css2?family=${name}:${style === "ital" ? `ital,wght@1,${weight}` : `wght@${weight}`}`, {
47
+ timeout: 10 * 1e3,
48
+ // 10 second timeout
49
+ headers: {
50
+ // Make sure it returns TTF.
51
+ "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
52
+ }
53
+ }).catch(() => {
54
+ return false;
55
+ });
56
+ if (!css)
57
+ return false;
58
+ const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
59
+ if (ttfResource?.[1]) {
60
+ const buf = await $fetch(ttfResource[1], { baseURL: host, responseType: "arrayBuffer" });
61
+ const base64Font = Buffer.from(buf).toString("base64");
62
+ await storage.setItem(key, base64Font);
63
+ return true;
64
+ }
65
+ return false;
66
+ }
25
67
 
26
68
  const autodetectableProviders = {
27
69
  azure_static: "azure",
@@ -139,8 +181,8 @@ function getPresetNitroPresetCompatibility(target) {
139
181
  async function applyNitroPresetCompatibility(nitroConfig, options) {
140
182
  const target = resolveNitroPreset(nitroConfig);
141
183
  const compatibility = getPresetNitroPresetCompatibility(target);
142
- const hasCssInlineNode = !!await tryResolveModule("@css-inline/css-inline");
143
- const hasCssInlineWasm = !!await tryResolveModule("@css-inline/css-inline-wasm");
184
+ const hasCssInlineNode = await hasResolvableDependency("@css-inline/css-inline");
185
+ const hasCssInlineWasm = await hasResolvableDependency("@css-inline/css-inline-wasm");
144
186
  const { resolve } = options;
145
187
  const satoriEnabled = typeof options.compatibility?.satori !== "undefined" ? !!options.compatibility.satori : !!compatibility.satori;
146
188
  const chromiumEnabled = typeof options.compatibility?.chromium !== "undefined" ? !!options.compatibility.chromium : !!compatibility.chromium;
@@ -484,48 +526,6 @@ function normaliseFontInput(fonts) {
484
526
  });
485
527
  }
486
528
 
487
- const isUndefinedOrTruthy = (v) => typeof v === "undefined" || v !== false;
488
- function checkLocalChrome() {
489
- if (isCI)
490
- return false;
491
- let hasChromeLocally = false;
492
- try {
493
- hasChromeLocally = !!Launcher.getFirstInstallation();
494
- } catch {
495
- }
496
- return hasChromeLocally;
497
- }
498
- async function checkPlaywrightDependency() {
499
- return !!await tryResolveModule("playwright");
500
- }
501
- async function downloadFont(font, storage, mirror) {
502
- const { name, weight, style } = font;
503
- const key = `${name}-${style}-${weight}.ttf.base64`;
504
- if (await storage.hasItem(key))
505
- return true;
506
- const host = typeof mirror === "undefined" ? "fonts.googleapis.com" : mirror === true ? "fonts.font.im" : mirror;
507
- const css = await $fetch(`https://${host}/css2?family=${name}:${style === "ital" ? `ital,wght@1,${weight}` : `wght@${weight}`}`, {
508
- timeout: 10 * 1e3,
509
- // 10 second timeout
510
- headers: {
511
- // Make sure it returns TTF.
512
- "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
513
- }
514
- }).catch(() => {
515
- return false;
516
- });
517
- if (!css)
518
- return false;
519
- const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
520
- if (ttfResource?.[1]) {
521
- const buf = await $fetch(ttfResource[1], { baseURL: host, responseType: "arrayBuffer" });
522
- const base64Font = Buffer.from(buf).toString("base64");
523
- await storage.setItem(key, base64Font);
524
- return true;
525
- }
526
- return false;
527
- }
528
-
529
529
  const module = defineNuxtModule({
530
530
  meta: {
531
531
  name: "nuxt-og-image",
@@ -592,7 +592,7 @@ const module = defineNuxtModule({
592
592
  const hasConfiguredJpegs = userConfiguredExtension && ["jpeg", "jpg"].includes(userConfiguredExtension);
593
593
  if (!!config.sharpOptions || hasConfiguredJpegs && config.defaults.renderer !== "chromium") {
594
594
  isUsingSharp = true;
595
- const hasSharpDependency = !!await tryResolveModule("sharp");
595
+ const hasSharpDependency = await hasResolvableDependency("sharp");
596
596
  if (hasSharpDependency && !targetCompatibility.sharp) {
597
597
  logger.warn(`Rendering JPEGs requires sharp which does not work with ${preset}. Images will be rendered as PNG at runtime.`);
598
598
  config.compatibility = defu(config.compatibility, {
@@ -612,7 +612,7 @@ const module = defineNuxtModule({
612
612
  });
613
613
  }
614
614
  const hasChromeLocally = checkLocalChrome();
615
- const hasPlaywrightDependency = await checkPlaywrightDependency();
615
+ const hasPlaywrightDependency = await hasResolvableDependency("playwright");
616
616
  const chromeCompatibilityFlags = {
617
617
  prerender: config.compatibility?.prerender?.chromium,
618
618
  dev: config.compatibility?.dev?.chromium,
@@ -799,7 +799,7 @@ const module = defineNuxtModule({
799
799
  const credits = componentFile.split("\n").find((line) => line.startsWith(" * @credits"))?.replace("* @credits", "").trim();
800
800
  ogImageComponentCtx.components.push({
801
801
  // purge cache when component changes
802
- hash: hash(componentFile),
802
+ hash: hash(componentFile).replaceAll("_", "-"),
803
803
  pascalName: component.pascalName,
804
804
  kebabName: component.kebabName,
805
805
  path: nuxt.options.dev ? component.filePath : void 0,
@@ -1,11 +1,15 @@
1
1
  import { componentNames } from "#build/nuxt-og-image/components.mjs";
2
- import { resolveUnrefHeadInput, useServerHead } from "@unhead/vue";
2
+ import { useHead } from "#imports";
3
+ import { resolveUnrefHeadInput } from "@unhead/vue";
3
4
  import { defu } from "defu";
4
5
  import { stringify } from "devalue";
5
6
  import { withQuery } from "ufo";
6
7
  import { unref } from "vue";
7
8
  import { generateMeta, separateProps } from "../shared.js";
8
9
  export function createOgImageMeta(src, input, resolvedOptions, ssrContext) {
10
+ if (import.meta.client) {
11
+ return;
12
+ }
9
13
  const _input = separateProps(defu(input, ssrContext._ogImagePayload));
10
14
  let url = src || input.url || resolvedOptions.url;
11
15
  if (!url)
@@ -34,11 +38,11 @@ export function createOgImageMeta(src, input, resolvedOptions, ssrContext) {
34
38
  tagPosition: "bodyClose"
35
39
  });
36
40
  }
37
- const instance = useServerHead({
41
+ const instance = useHead({
38
42
  script,
39
43
  meta
40
44
  }, {
41
- tagPriority: 35
45
+ tagPriority: "high"
42
46
  });
43
47
  ssrContext._ogImagePayload = _input;
44
48
  ssrContext._ogImageInstances.push(instance);
@@ -1,5 +1,6 @@
1
1
  import { htmlPayloadCache, prerenderOptionsCache } from "#og-image-cache";
2
2
  import { theme } from "#og-image-virtual/unocss-config.mjs";
3
+ import { useSiteConfig } from "#site-config/server/composables/useSiteConfig";
3
4
  import { createSitePathResolver } from "#site-config/server/composables/utils";
4
5
  import { createGenerator } from "@unocss/core";
5
6
  import presetWind from "@unocss/preset-wind3";
@@ -17,13 +18,15 @@ import { logger } from "../util/logger.js";
17
18
  import { normaliseOptions } from "../util/options.js";
18
19
  import { useChromiumRenderer, useSatoriRenderer } from "./instances.js";
19
20
  export function resolvePathCacheKey(e, path) {
20
- const siteConfig = e.context.siteConfig.get();
21
+ const siteConfig = useSiteConfig(e, {
22
+ resolveRefs: true
23
+ });
21
24
  const basePath = withoutTrailingSlash(withoutLeadingSlash(normalizeKey(path)));
22
25
  return [
23
26
  !basePath || basePath === "/" ? "index" : basePath,
24
27
  hash([
25
28
  basePath,
26
- siteConfig.url,
29
+ import.meta.prerender ? "" : siteConfig.url,
27
30
  hash(getQuery(e))
28
31
  ])
29
32
  ].join(":");
@@ -136,7 +139,7 @@ export function extractAndNormaliseOgImageOptions(html) {
136
139
  try {
137
140
  const payload2 = parse(_payload);
138
141
  Object.entries(payload2).forEach(([key, value]) => {
139
- if (!value)
142
+ if (!value && value !== 0)
140
143
  delete payload2[key];
141
144
  });
142
145
  options = payload2;
@@ -4,7 +4,7 @@ import { hash } from "ohash";
4
4
  import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
5
5
  import { withoutBase, withoutTrailingSlash } from "ufo";
6
6
  export function fetchIsland(e, component, props) {
7
- const hashId = hash([component, props]);
7
+ const hashId = hash([component, props]).replaceAll("_", "-");
8
8
  return e.$fetch(`/__nuxt_island/${component}_${hashId}.json`, {
9
9
  params: {
10
10
  props: JSON.stringify(props)
@@ -1,5 +1,6 @@
1
+ import type { Head } from '@unhead/vue';
1
2
  import type { OgImageOptions, OgImageRuntimeConfig } from './types.js';
2
3
  export * from './pure.js';
3
- export declare function generateMeta(url: string, resolvedOptions: OgImageOptions): import("@unhead/schema").Meta<import("@unhead/schema").UserTagConfigWithoutInnerContent>[];
4
+ export declare function generateMeta(url: string, resolvedOptions: OgImageOptions): Head['meta'];
4
5
  export declare function getOgImagePath(pagePath: string, _options?: Partial<OgImageOptions>): string;
5
6
  export declare function useOgImageRuntimeConfig(): OgImageRuntimeConfig;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "4.1.4",
4
+ "version": "4.1.6",
5
5
  "description": "Enlightened OG Image generation for Nuxt.",
6
6
  "author": {
7
7
  "website": "https://harlanzw.com",
@@ -47,80 +47,81 @@
47
47
  "engines": {
48
48
  "node": ">=18.0.0"
49
49
  },
50
+ "peerDependencies": {
51
+ "@unhead/vue": "^1.0.0 || ^2.0.0",
52
+ "unstorage": "^1.0.0"
53
+ },
50
54
  "dependencies": {
51
- "@nuxt/devtools-kit": "2.1.0",
55
+ "@nuxt/devtools-kit": "2.1.3",
52
56
  "@nuxt/kit": "^3.15.4",
53
57
  "@resvg/resvg-js": "^2.6.2",
54
58
  "@resvg/resvg-wasm": "^2.6.2",
59
+ "@unhead/ssr": "^1.11.20",
55
60
  "@unocss/core": "^66.0.0",
56
61
  "@unocss/preset-wind3": "^66.0.0",
57
62
  "chrome-launcher": "^1.1.2",
58
63
  "consola": "^3.4.0",
59
64
  "defu": "^6.1.4",
60
65
  "execa": "^9.5.2",
61
- "image-size": "^1.2.0",
66
+ "image-size": "^2.0.0",
62
67
  "magic-string": "^0.30.17",
63
- "nuxt-site-config": "^3.0.7",
64
- "nypm": "^0.5.2",
68
+ "nuxt-site-config": "^3.1.3",
69
+ "nypm": "^0.6.0",
65
70
  "ofetch": "^1.4.1",
66
- "ohash": "^1.1.4",
71
+ "ohash": "^2.0.10",
67
72
  "pathe": "^2.0.3",
68
- "pkg-types": "^1.3.1",
73
+ "pkg-types": "^2.1.0",
69
74
  "playwright-core": "^1.50.1",
70
75
  "radix3": "^1.1.2",
71
76
  "satori": "^0.12.1",
72
77
  "satori-html": "^0.3.2",
73
78
  "sirv": "^3.0.1",
74
- "std-env": "^3.8.0",
79
+ "std-env": "^3.8.1",
75
80
  "strip-literal": "^3.0.0",
76
81
  "ufo": "^1.5.4",
77
82
  "unplugin": "^2.2.0",
78
83
  "unwasm": "^0.3.9",
79
84
  "yoga-wasm-web": "^0.3.3"
80
85
  },
81
- "peerDependencies": {
82
- "unstorage": "^1.0.0"
83
- },
84
86
  "devDependencies": {
85
- "@antfu/eslint-config": "^4.3.0",
87
+ "@antfu/eslint-config": "^4.4.0",
86
88
  "@css-inline/css-inline": "^0.14.3",
87
89
  "@headlessui/vue": "^1.7.23",
88
- "@iconify-json/carbon": "^1.2.7",
90
+ "@iconify-json/carbon": "^1.2.8",
89
91
  "@iconify-json/logos": "^1.2.4",
90
92
  "@iconify-json/noto": "^1.2.2",
91
93
  "@iconify-json/ri": "^1.2.5",
92
94
  "@iconify-json/tabler": "^1.2.16",
93
95
  "@img/sharp-linux-x64": "0.33.5",
94
- "@nuxt/content": "^3.1.1",
95
- "@nuxt/devtools": "2.1.0",
96
- "@nuxt/devtools-ui-kit": "2.1.0",
96
+ "@nuxt/content": "^3.2.2",
97
+ "@nuxt/devtools": "2.1.3",
98
+ "@nuxt/devtools-ui-kit": "2.1.3",
97
99
  "@nuxt/icon": "^1.10.3",
98
100
  "@nuxt/image": "^1.9.0",
99
101
  "@nuxt/module-builder": "^0.8.4",
100
- "@nuxt/test-utils": "3.15.4",
102
+ "@nuxt/test-utils": "3.17.1",
101
103
  "@nuxt/ui": "^2.21.0",
102
104
  "@nuxtjs/color-mode": "^3.5.2",
103
105
  "@nuxtjs/eslint-config-typescript": "^12.1.0",
104
- "@nuxtjs/i18n": "^9.2.0",
106
+ "@nuxtjs/i18n": "^9.2.1",
105
107
  "@nuxtjs/tailwindcss": "^6.13.1",
106
108
  "@unocss/nuxt": "^66.0.0",
107
109
  "@unocss/preset-icons": "^66.0.0",
108
110
  "@unocss/runtime": "^66.0.0",
109
111
  "@vueuse/nuxt": "^12.7.0",
110
112
  "bumpp": "^10.0.3",
111
- "eslint": "9.20.1",
113
+ "eslint": "9.21.0",
112
114
  "jest-image-snapshot": "^6.4.0",
113
115
  "nuxt": "^3.15.4",
114
116
  "playwright": "^1.50.1",
115
- "sass": "^1.85.0",
117
+ "sass": "^1.85.1",
116
118
  "sharp": "^0.33.5",
117
119
  "typescript": "5.6.3",
118
120
  "unocss": "^66.0.0",
119
- "vitest": "^3.0.6"
121
+ "vitest": "^3.0.7"
120
122
  },
121
123
  "resolutions": {
122
- "typescript": "5.6.3",
123
- "vitest": "https://pkg.pr.new/vitest@7bfa70cffd5ecbaa356855b37dea5dc75a901eea"
124
+ "typescript": "5.6.3"
124
125
  },
125
126
  "scripts": {
126
127
  "stub": "nuxt-build-module build --stub && nuxt-module-build prepare",