nuxt-og-image 6.7.1 → 6.7.3

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.
Files changed (35) hide show
  1. package/dist/chunks/tw4.cjs +7 -7
  2. package/dist/chunks/tw4.mjs +7 -7
  3. package/dist/chunks/uno.cjs +6 -6
  4. package/dist/chunks/uno.mjs +6 -6
  5. package/dist/cli.cjs +5 -12
  6. package/dist/cli.mjs +3 -10
  7. package/dist/devtools/lib/og-image/shared/urlEncoding.ts +5 -4
  8. package/dist/module.cjs +5 -5
  9. package/dist/module.json +1 -1
  10. package/dist/module.mjs +5 -5
  11. package/dist/runtime/app/plugins/__zero-runtime/og-image-canonical-urls.server.js +4 -6
  12. package/dist/runtime/app/plugins/__zero-runtime/route-rule-og-image.server.js +4 -6
  13. package/dist/runtime/app/plugins/og-image-canonical-urls.server.d.ts +1 -2
  14. package/dist/runtime/app/plugins/og-image-canonical-urls.server.js +1 -7
  15. package/dist/runtime/app/plugins/route-rule-og-image.server.d.ts +1 -2
  16. package/dist/runtime/app/plugins/route-rule-og-image.server.js +1 -7
  17. package/dist/runtime/app/utils/plugins.d.ts +2 -3
  18. package/dist/runtime/app/utils/plugins.js +5 -5
  19. package/dist/runtime/server/og-image/context.js +3 -3
  20. package/dist/runtime/server/og-image/takumi/nodes.d.ts +2 -1
  21. package/dist/runtime/server/og-image/takumi/nodes.js +16 -7
  22. package/dist/runtime/server/util/cache.js +2 -2
  23. package/dist/runtime/server/util/kit.js +2 -2
  24. package/dist/runtime/shared/hash.d.ts +10 -0
  25. package/dist/runtime/shared/hash.js +5 -0
  26. package/dist/runtime/shared/urlEncoding.d.ts +3 -2
  27. package/dist/runtime/shared/urlEncoding.js +9 -9
  28. package/dist/shared/{nuxt-og-image.BCK8Adm4.cjs → nuxt-og-image.BRBtdkUp.cjs} +570 -81
  29. package/dist/shared/{nuxt-og-image.Pfj5JkJd.mjs → nuxt-og-image.Bv8VSGTj.mjs} +499 -10
  30. package/dist/shared/nuxt-og-image.CJa2KCie.mjs +189 -0
  31. package/dist/shared/nuxt-og-image.CMYbz66P.cjs +193 -0
  32. package/package.json +43 -41
  33. package/types/virtual.d.ts +9 -0
  34. package/dist/shared/nuxt-og-image.DQkJQHaN.cjs +0 -689
  35. package/dist/shared/nuxt-og-image.LgUGeaz-.mjs +0 -660
@@ -4,23 +4,20 @@ const promises = require('node:fs/promises');
4
4
  const node_url = require('node:url');
5
5
  const exsolve = require('exsolve');
6
6
  const pathe = require('pathe');
7
- const module$1 = require('../shared/nuxt-og-image.BCK8Adm4.cjs');
7
+ const module$1 = require('../shared/nuxt-og-image.BRBtdkUp.cjs');
8
8
  require('node:crypto');
9
9
  require('node:fs');
10
10
  require('@nuxt/kit');
11
11
  require('defu');
12
+ require('fnv1a-64');
12
13
  require('nuxt-site-config/kit');
13
- require('ohash');
14
14
  require('pkg-types');
15
15
  require('std-env');
16
16
  require('oxc-walker');
17
- require('../shared/nuxt-og-image.DQkJQHaN.cjs');
18
- require('magicast');
19
- require('magicast/helpers');
20
- require('../../dist/runtime/logger.js');
21
- require('nypm');
22
17
  require('nuxtseo-shared/kit');
18
+ require('../../dist/runtime/logger.js');
23
19
  require('chrome-launcher');
20
+ require('nypm');
24
21
  require('nuxtseo-shared/devtools');
25
22
  require('unstorage');
26
23
  require('unstorage/drivers/fs-lite');
@@ -33,6 +30,9 @@ require('@vue/compiler-sfc');
33
30
  require('ofetch');
34
31
  require('ultrahtml');
35
32
  require('../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
33
+ require('../shared/nuxt-og-image.CMYbz66P.cjs');
34
+ require('magicast');
35
+ require('magicast/helpers');
36
36
 
37
37
  const RE_GRADIENT_STOP_PREFIX = /^(from|via|to)-/;
38
38
  const RE_COLOR_SHADE = /^(.+)-(\d+)$/;
@@ -2,23 +2,20 @@ import { readFile } from 'node:fs/promises';
2
2
  import { pathToFileURL } from 'node:url';
3
3
  import { resolveModulePath } from 'exsolve';
4
4
  import { dirname, join } from 'pathe';
5
- import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, i as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, l as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.Pfj5JkJd.mjs';
5
+ import { e as extractVariantBaseClasses, r as resolveVariantPrefixes, h as resolveExtractedVars, i as resolveVarsDeep, s as simplifyCss, p as postProcessStyles, l as loadLightningCss, a as extractCssVars, c as extractUniversalVars, d as extractPerClassVars, g as extractVarsFromCss, f as extractClassStyles } from '../shared/nuxt-og-image.Bv8VSGTj.mjs';
6
6
  import 'node:crypto';
7
7
  import 'node:fs';
8
8
  import '@nuxt/kit';
9
9
  import 'defu';
10
+ import 'fnv1a-64';
10
11
  import 'nuxt-site-config/kit';
11
- import 'ohash';
12
12
  import 'pkg-types';
13
13
  import 'std-env';
14
14
  import 'oxc-walker';
15
- import '../shared/nuxt-og-image.LgUGeaz-.mjs';
16
- import 'magicast';
17
- import 'magicast/helpers';
18
- import '../../dist/runtime/logger.js';
19
- import 'nypm';
20
15
  import 'nuxtseo-shared/kit';
16
+ import '../../dist/runtime/logger.js';
21
17
  import 'chrome-launcher';
18
+ import 'nypm';
22
19
  import 'nuxtseo-shared/devtools';
23
20
  import 'unstorage';
24
21
  import 'unstorage/drivers/fs-lite';
@@ -31,6 +28,9 @@ import '@vue/compiler-sfc';
31
28
  import 'ofetch';
32
29
  import 'ultrahtml';
33
30
  import '../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
31
+ import '../shared/nuxt-og-image.CJa2KCie.mjs';
32
+ import 'magicast';
33
+ import 'magicast/helpers';
34
34
 
35
35
  const RE_GRADIENT_STOP_PREFIX = /^(from|via|to)-/;
36
36
  const RE_COLOR_SHADE = /^(.+)-(\d+)$/;
@@ -3,23 +3,20 @@
3
3
  const promises = require('node:fs/promises');
4
4
  const defu = require('defu');
5
5
  const logger_js = require('../../dist/runtime/logger.js');
6
- const module$1 = require('../shared/nuxt-og-image.BCK8Adm4.cjs');
6
+ const module$1 = require('../shared/nuxt-og-image.BRBtdkUp.cjs');
7
7
  require('node:crypto');
8
8
  require('node:fs');
9
9
  require('node:url');
10
10
  require('@nuxt/kit');
11
+ require('fnv1a-64');
11
12
  require('nuxt-site-config/kit');
12
- require('ohash');
13
13
  require('pathe');
14
14
  require('pkg-types');
15
15
  require('std-env');
16
16
  require('oxc-walker');
17
- require('../shared/nuxt-og-image.DQkJQHaN.cjs');
18
- require('magicast');
19
- require('magicast/helpers');
20
- require('nypm');
21
17
  require('nuxtseo-shared/kit');
22
18
  require('chrome-launcher');
19
+ require('nypm');
23
20
  require('nuxtseo-shared/devtools');
24
21
  require('unstorage');
25
22
  require('unstorage/drivers/fs-lite');
@@ -33,6 +30,9 @@ require('ofetch');
33
30
  require('ultrahtml');
34
31
  require('../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
35
32
  require('exsolve');
33
+ require('../shared/nuxt-og-image.CMYbz66P.cjs');
34
+ require('magicast');
35
+ require('magicast/helpers');
36
36
 
37
37
  const RE_SVG_DATA_URL = /url\("data:image\/svg\+xml[;,]([^"]+)"\)/;
38
38
  const RE_UTF8_PREFIX = /^utf8,/;
@@ -1,23 +1,20 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { defu } from 'defu';
3
3
  import { logger } from '../../dist/runtime/logger.js';
4
- import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.Pfj5JkJd.mjs';
4
+ import { e as extractVariantBaseClasses, s as simplifyCss, a as extractCssVars, b as extractPropertyInitialValues, c as extractUniversalVars, d as extractPerClassVars, f as extractClassStyles, p as postProcessStyles, r as resolveVariantPrefixes, g as extractVarsFromCss, h as resolveExtractedVars } from '../shared/nuxt-og-image.Bv8VSGTj.mjs';
5
5
  import 'node:crypto';
6
6
  import 'node:fs';
7
7
  import 'node:url';
8
8
  import '@nuxt/kit';
9
+ import 'fnv1a-64';
9
10
  import 'nuxt-site-config/kit';
10
- import 'ohash';
11
11
  import 'pathe';
12
12
  import 'pkg-types';
13
13
  import 'std-env';
14
14
  import 'oxc-walker';
15
- import '../shared/nuxt-og-image.LgUGeaz-.mjs';
16
- import 'magicast';
17
- import 'magicast/helpers';
18
- import 'nypm';
19
15
  import 'nuxtseo-shared/kit';
20
16
  import 'chrome-launcher';
17
+ import 'nypm';
21
18
  import 'nuxtseo-shared/devtools';
22
19
  import 'unstorage';
23
20
  import 'unstorage/drivers/fs-lite';
@@ -31,6 +28,9 @@ import 'ofetch';
31
28
  import 'ultrahtml';
32
29
  import '../../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
33
30
  import 'exsolve';
31
+ import '../shared/nuxt-og-image.CJa2KCie.mjs';
32
+ import 'magicast';
33
+ import 'magicast/helpers';
34
34
 
35
35
  const RE_SVG_DATA_URL = /url\("data:image\/svg\+xml[;,]([^"]+)"\)/;
36
36
  const RE_UTF8_PREFIX = /^utf8,/;
package/dist/cli.cjs CHANGED
@@ -10,14 +10,10 @@ const nypm = require('nypm');
10
10
  const oxcWalker = require('oxc-walker');
11
11
  const pathe = require('pathe');
12
12
  const ultrahtml = require('ultrahtml');
13
- const dependencies = require('./shared/nuxt-og-image.DQkJQHaN.cjs');
13
+ const fonts = require('./shared/nuxt-og-image.CMYbz66P.cjs');
14
14
  require('magicast');
15
15
  require('magicast/helpers');
16
16
  require('../dist/runtime/logger.js');
17
- require('std-env');
18
- require('defu');
19
- require('nuxtseo-shared/kit');
20
- require('chrome-launcher');
21
17
 
22
18
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
23
19
  function _interopNamespaceCompat(e) {
@@ -193,14 +189,11 @@ const RENDERERS = [
193
189
  }
194
190
  ];
195
191
  const EDGE_PRESETS = ["cloudflare", "cloudflare-pages", "cloudflare-module", "vercel-edge", "netlify-edge"];
196
- function getRendererDeps(renderer, isEdge, options = {}) {
192
+ function getRendererDeps(renderer, isEdge) {
197
193
  switch (renderer) {
198
194
  case "satori":
199
195
  return isEdge ? ["satori", "@resvg/resvg-js", "@resvg/resvg-wasm"] : ["satori", "@resvg/resvg-js"];
200
196
  case "takumi":
201
- if (options.installSpec) {
202
- return isEdge ? [dependencies.TAKUMI_CORE_INSTALL_SPEC, dependencies.TAKUMI_WASM_INSTALL_SPEC] : [dependencies.TAKUMI_CORE_INSTALL_SPEC];
203
- }
204
197
  return isEdge ? ["@takumi-rs/core", "@takumi-rs/wasm"] : ["@takumi-rs/core"];
205
198
  case "browser":
206
199
  return isEdge ? [] : ["playwright-core"];
@@ -561,7 +554,7 @@ async function installRendererDeps(renderers, isEdge) {
561
554
  const pmName = pm?.name || "npm";
562
555
  const allDeps = [];
563
556
  for (const renderer of renderers) {
564
- allDeps.push(...getRendererDeps(renderer, isEdge, { installSpec: true }));
557
+ allDeps.push(...getRendererDeps(renderer, isEdge));
565
558
  }
566
559
  const uniqueDeps = [...new Set(allDeps)];
567
560
  if (uniqueDeps.length === 0)
@@ -713,7 +706,7 @@ async function runMigrate(args2) {
713
706
  if (dryRun) {
714
707
  p__namespace.log.info(`Would remove defaults.component: '${migrationCheck.defaultComponentName}'`);
715
708
  } else {
716
- const result = await dependencies.migrateDefaultsComponent(cwd).catch((err) => {
709
+ const result = await fonts.migrateDefaultsComponent(cwd).catch((err) => {
717
710
  p__namespace.log.warn(`Failed to migrate defaults.component: ${err.message}`);
718
711
  return { migrated: false, componentName: null, message: err.message };
719
712
  });
@@ -727,7 +720,7 @@ async function runMigrate(args2) {
727
720
  if (dryRun) {
728
721
  p__namespace.log.info("Would migrate ogImage.fonts to @nuxt/fonts config");
729
722
  } else {
730
- const result = await dependencies.migrateFontsConfig(cwd).catch((err) => {
723
+ const result = await fonts.migrateFontsConfig(cwd).catch((err) => {
731
724
  p__namespace.log.warn(`Failed to migrate fonts config: ${err.message}`);
732
725
  return { migrated: false, message: err.message };
733
726
  });
package/dist/cli.mjs CHANGED
@@ -8,14 +8,10 @@ import { detectPackageManager, removeDependency, addDependency } from 'nypm';
8
8
  import { parseAndWalk } from 'oxc-walker';
9
9
  import { dirname, resolve, join, relative, basename } from 'pathe';
10
10
  import { parse, walkSync, ELEMENT_NODE } from 'ultrahtml';
11
- import { m as migrateDefaultsComponent, a as migrateFontsConfig, T as TAKUMI_CORE_INSTALL_SPEC, b as TAKUMI_WASM_INSTALL_SPEC } from './shared/nuxt-og-image.LgUGeaz-.mjs';
11
+ import { m as migrateDefaultsComponent, a as migrateFontsConfig } from './shared/nuxt-og-image.CJa2KCie.mjs';
12
12
  import 'magicast';
13
13
  import 'magicast/helpers';
14
14
  import '../dist/runtime/logger.js';
15
- import 'std-env';
16
- import 'defu';
17
- import 'nuxtseo-shared/kit';
18
- import 'chrome-launcher';
19
15
 
20
16
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
21
17
  const communityDir = resolve(__dirname$1, "runtime/app/components/Templates/Community");
@@ -176,14 +172,11 @@ const RENDERERS = [
176
172
  }
177
173
  ];
178
174
  const EDGE_PRESETS = ["cloudflare", "cloudflare-pages", "cloudflare-module", "vercel-edge", "netlify-edge"];
179
- function getRendererDeps(renderer, isEdge, options = {}) {
175
+ function getRendererDeps(renderer, isEdge) {
180
176
  switch (renderer) {
181
177
  case "satori":
182
178
  return isEdge ? ["satori", "@resvg/resvg-js", "@resvg/resvg-wasm"] : ["satori", "@resvg/resvg-js"];
183
179
  case "takumi":
184
- if (options.installSpec) {
185
- return isEdge ? [TAKUMI_CORE_INSTALL_SPEC, TAKUMI_WASM_INSTALL_SPEC] : [TAKUMI_CORE_INSTALL_SPEC];
186
- }
187
180
  return isEdge ? ["@takumi-rs/core", "@takumi-rs/wasm"] : ["@takumi-rs/core"];
188
181
  case "browser":
189
182
  return isEdge ? [] : ["playwright-core"];
@@ -544,7 +537,7 @@ async function installRendererDeps(renderers, isEdge) {
544
537
  const pmName = pm?.name || "npm";
545
538
  const allDeps = [];
546
539
  for (const renderer of renderers) {
547
- allDeps.push(...getRendererDeps(renderer, isEdge, { installSpec: true }));
540
+ allDeps.push(...getRendererDeps(renderer, isEdge));
548
541
  }
549
542
  const uniqueDeps = [...new Set(allDeps)];
550
543
  if (uniqueDeps.length === 0)
@@ -1,4 +1,4 @@
1
- import { hash } from 'ohash'
1
+ import { digest } from 'ohash/crypto'
2
2
 
3
3
  /**
4
4
  * URL encoding for OG image options (Cloudinary/IPX style)
@@ -421,11 +421,12 @@ export function buildOgImageUrl(
421
421
  }
422
422
 
423
423
  /**
424
- * Sign encoded params using a keyed hash (ohash, cross-runtime compatible).
425
- * Returns first 16 chars of the base64url hash for URL brevity.
424
+ * Sign encoded params using a keyed SHA-256 digest (cross-runtime, sync).
425
+ * Returns first 16 chars of the base64url digest for URL brevity.
426
+ * Must stay cryptographic — a fast hash here would make signatures forgeable.
426
427
  */
427
428
  export function signEncodedParams(encoded: string, secret: string): string {
428
- return hash(`${secret}:${encoded}`).slice(0, 16)
429
+ return digest(`${secret}:${encoded}`).slice(0, 16)
429
430
  }
430
431
 
431
432
  /**
package/dist/module.cjs CHANGED
@@ -6,16 +6,17 @@ require('node:fs/promises');
6
6
  require('node:url');
7
7
  require('@nuxt/kit');
8
8
  require('defu');
9
+ require('fnv1a-64');
9
10
  require('nuxt-site-config/kit');
10
- require('ohash');
11
11
  require('pathe');
12
12
  require('pkg-types');
13
13
  require('std-env');
14
- const module$1 = require('./shared/nuxt-og-image.BCK8Adm4.cjs');
15
- require('./shared/nuxt-og-image.DQkJQHaN.cjs');
14
+ const module$1 = require('./shared/nuxt-og-image.BRBtdkUp.cjs');
16
15
  require('nuxtseo-shared/kit');
17
16
  require('../dist/runtime/logger.js');
18
17
  require('oxc-walker');
18
+ require('chrome-launcher');
19
+ require('nypm');
19
20
  require('nuxtseo-shared/devtools');
20
21
  require('unstorage');
21
22
  require('unstorage/drivers/fs-lite');
@@ -29,10 +30,9 @@ require('ofetch');
29
30
  require('ultrahtml');
30
31
  require('../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js');
31
32
  require('exsolve');
33
+ require('./shared/nuxt-og-image.CMYbz66P.cjs');
32
34
  require('magicast');
33
35
  require('magicast/helpers');
34
- require('nypm');
35
- require('chrome-launcher');
36
36
 
37
37
 
38
38
 
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "nuxt": ">=3.16.0"
5
5
  },
6
6
  "configKey": "ogImage",
7
- "version": "6.7.1",
7
+ "version": "6.7.3",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -4,16 +4,17 @@ import 'node:fs/promises';
4
4
  import 'node:url';
5
5
  import '@nuxt/kit';
6
6
  import 'defu';
7
+ import 'fnv1a-64';
7
8
  import 'nuxt-site-config/kit';
8
- import 'ohash';
9
9
  import 'pathe';
10
10
  import 'pkg-types';
11
11
  import 'std-env';
12
- export { m as default } from './shared/nuxt-og-image.Pfj5JkJd.mjs';
13
- import './shared/nuxt-og-image.LgUGeaz-.mjs';
12
+ export { m as default } from './shared/nuxt-og-image.Bv8VSGTj.mjs';
14
13
  import 'nuxtseo-shared/kit';
15
14
  import '../dist/runtime/logger.js';
16
15
  import 'oxc-walker';
16
+ import 'chrome-launcher';
17
+ import 'nypm';
17
18
  import 'nuxtseo-shared/devtools';
18
19
  import 'unstorage';
19
20
  import 'unstorage/drivers/fs-lite';
@@ -27,7 +28,6 @@ import 'ofetch';
27
28
  import 'ultrahtml';
28
29
  import '../dist/runtime/server/og-image/core/transforms/emojis/emoji-utils.js';
29
30
  import 'exsolve';
31
+ import './shared/nuxt-og-image.CJa2KCie.mjs';
30
32
  import 'magicast';
31
33
  import 'magicast/helpers';
32
- import 'nypm';
33
- import 'chrome-launcher';
@@ -1,9 +1,7 @@
1
1
  import { defineNuxtPlugin } from "#app";
2
- import { ogImageCanonicalUrls as setup } from "../../utils/plugins.js";
3
- export default defineNuxtPlugin({
4
- setup(nuxtApp) {
5
- if (import.meta.dev || import.meta.prerender) {
6
- setup(nuxtApp);
7
- }
2
+ import { ogImageCanonicalUrls } from "../../utils/plugins.js";
3
+ export default defineNuxtPlugin((nuxtApp) => {
4
+ if (import.meta.dev || import.meta.prerender) {
5
+ return ogImageCanonicalUrls(nuxtApp);
8
6
  }
9
7
  });
@@ -1,9 +1,7 @@
1
1
  import { defineNuxtPlugin } from "#app";
2
- import { routeRuleOgImage as setup } from "../../utils/plugins.js";
3
- export default defineNuxtPlugin({
4
- setup(nuxtApp) {
5
- if (import.meta.dev || import.meta.prerender) {
6
- setup(nuxtApp);
7
- }
2
+ import { routeRuleOgImage } from "../../utils/plugins.js";
3
+ export default defineNuxtPlugin((nuxtApp) => {
4
+ if (import.meta.dev || import.meta.prerender) {
5
+ return routeRuleOgImage(nuxtApp);
8
6
  }
9
7
  });
@@ -1,2 +1 @@
1
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
- export default _default;
1
+ export { ogImageCanonicalUrls as default } from '../utils/plugins.js';
@@ -1,7 +1 @@
1
- import { defineNuxtPlugin } from "#app";
2
- import { ogImageCanonicalUrls as setup } from "../utils/plugins.js";
3
- export default defineNuxtPlugin({
4
- setup(nuxtApp) {
5
- setup(nuxtApp);
6
- }
7
- });
1
+ export { ogImageCanonicalUrls as default } from "../utils/plugins.js";
@@ -1,2 +1 @@
1
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
- export default _default;
1
+ export { routeRuleOgImage as default } from '../utils/plugins.js';
@@ -1,7 +1 @@
1
- import { defineNuxtPlugin } from "#app";
2
- import { routeRuleOgImage as setup } from "../utils/plugins.js";
3
- export default defineNuxtPlugin({
4
- setup(nuxtApp) {
5
- setup(nuxtApp);
6
- }
7
- });
1
+ export { routeRuleOgImage as default } from "../utils/plugins.js";
@@ -1,3 +1,2 @@
1
- import type { NuxtSSRContext } from '#app/nuxt';
2
- export declare function ogImageCanonicalUrls(nuxtApp: NuxtSSRContext['nuxt']): void;
3
- export declare function routeRuleOgImage(nuxtApp: NuxtSSRContext['nuxt']): void;
1
+ export declare const ogImageCanonicalUrls: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
+ export declare const routeRuleOgImage: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
@@ -3,12 +3,12 @@ import { defu } from "defu";
3
3
  import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
4
4
  import { parseURL, withoutBase } from "ufo";
5
5
  import { toValue } from "vue";
6
- import { useRequestEvent } from "#app";
6
+ import { defineNuxtPlugin, useRequestEvent } from "#app";
7
7
  import { withSiteUrl } from "#site-config/app/composables";
8
8
  import { createOgImageMeta, getOgImagePath } from "../../app/utils.js";
9
9
  import { isInternalRoute } from "../../shared.js";
10
10
  const RE_COMMA = /,/g;
11
- export function ogImageCanonicalUrls(nuxtApp) {
11
+ export const ogImageCanonicalUrls = defineNuxtPlugin((nuxtApp) => {
12
12
  nuxtApp.hooks.hook("app:rendered", async (ctx) => {
13
13
  const { ssrContext } = ctx;
14
14
  const e = useRequestEvent();
@@ -52,8 +52,8 @@ export function ogImageCanonicalUrls(nuxtApp) {
52
52
  }
53
53
  });
54
54
  });
55
- }
56
- export function routeRuleOgImage(nuxtApp) {
55
+ });
56
+ export const routeRuleOgImage = defineNuxtPlugin((nuxtApp) => {
57
57
  nuxtApp.hooks.hook("app:rendered", async (ctx) => {
58
58
  const { ssrContext } = ctx;
59
59
  const e = useRequestEvent();
@@ -92,4 +92,4 @@ export function routeRuleOgImage(nuxtApp) {
92
92
  prerenderPaths.set(ogKey, prerenderPath);
93
93
  }
94
94
  });
95
- }
95
+ });
@@ -1,7 +1,6 @@
1
1
  import { defu } from "defu";
2
2
  import { createError, getQuery } from "h3";
3
3
  import { useNitroApp } from "nitropack/runtime";
4
- import { hash } from "ohash";
5
4
  import { parseURL, withoutLeadingSlash, withoutTrailingSlash, withQuery } from "ufo";
6
5
  import { normalizeKey } from "unstorage";
7
6
  import { prerenderOptionsCache } from "#og-image-cache";
@@ -9,6 +8,7 @@ import { getSiteConfig } from "#site-config/server/composables/getSiteConfig";
9
8
  import { createSitePathResolver } from "#site-config/server/composables/utils";
10
9
  import { logger } from "../../logger.js";
11
10
  import { decodeOgImageParams, extractEncodedSegment, sanitizeProps, separateProps, verifyOgImageSignature } from "../../shared.js";
11
+ import { hashKey } from "../../shared/hash.js";
12
12
  import { autoEjectCommunityTemplate } from "../util/auto-eject.js";
13
13
  import { createNitroRouteRuleMatcher } from "../util/kit.js";
14
14
  import { normaliseOptions } from "../util/options.js";
@@ -28,10 +28,10 @@ export function resolvePathCacheKey(e, path, resolvedOptions) {
28
28
  import.meta.prerender ? "" : siteConfig.url
29
29
  ];
30
30
  if (resolvedOptions)
31
- hashParts.push(hash(resolvedOptions));
31
+ hashParts.push(hashKey(resolvedOptions));
32
32
  return [
33
33
  !basePath || basePath === "/" ? "index" : basePath,
34
- hash(hashParts)
34
+ hashKey(hashParts)
35
35
  ].join(":");
36
36
  }
37
37
  export async function resolveContext(e) {
@@ -1,3 +1,4 @@
1
1
  import type { Node } from '@takumi-rs/helpers';
2
- import type { OgImageRenderEventContext } from '../../../types.js';
2
+ import type { OgImageRenderEventContext, VNode } from '../../../types.js';
3
3
  export declare function createTakumiNodes(ctx: OgImageRenderEventContext): Promise<Node>;
4
+ export declare function vnodeToTakumiNode(vnode: VNode, inheritedFontSize: number, inheritedColor?: string): Promise<Node>;
@@ -43,8 +43,13 @@ function extractFontSize(props, style) {
43
43
  }
44
44
  return void 0;
45
45
  }
46
- async function vnodeToTakumiNode(vnode, inheritedFontSize) {
46
+ function extractColor(style) {
47
+ const color = style?.color;
48
+ return typeof color === "string" && color ? color : void 0;
49
+ }
50
+ export async function vnodeToTakumiNode(vnode, inheritedFontSize, inheritedColor) {
47
51
  const { style, children, class: cls, tw, src, ...rest } = vnode.props;
52
+ const nodeColor = extractColor(style) ?? inheritedColor;
48
53
  const baseMetadata = {
49
54
  tw: tw || cls || void 0,
50
55
  style
@@ -56,7 +61,7 @@ async function vnodeToTakumiNode(vnode, inheritedFontSize) {
56
61
  return {
57
62
  ...baseMetadata,
58
63
  type: "image",
59
- src: vnodeToHtmlString(vnode),
64
+ src: vnodeToHtmlString(vnode, nodeColor),
60
65
  // When em/rem + explicit parent font size → resolve to px.
61
66
  // When em/rem + default font size → leave undefined (takumi handles natively).
62
67
  // Otherwise → use standard resolution chain (numeric attrs → style → viewBox).
@@ -99,7 +104,7 @@ async function vnodeToTakumiNode(vnode, inheritedFontSize) {
99
104
  const takumiChildren = [];
100
105
  for (const child of children) {
101
106
  if (child && typeof child === "object")
102
- takumiChildren.push(await vnodeToTakumiNode(child, childFontSize));
107
+ takumiChildren.push(await vnodeToTakumiNode(child, childFontSize, nodeColor));
103
108
  else if (typeof child === "string" && child.trim())
104
109
  takumiChildren.push({ type: "text", text: child.trim() });
105
110
  }
@@ -114,9 +119,13 @@ async function vnodeToTakumiNode(vnode, inheritedFontSize) {
114
119
  type: "container"
115
120
  };
116
121
  }
117
- function vnodeToHtmlString(vnode) {
122
+ function resolveCurrentColor(value, color) {
123
+ return color && typeof value === "string" && value.toLowerCase() === "currentcolor" ? color : value;
124
+ }
125
+ function vnodeToHtmlString(vnode, inheritedColor) {
118
126
  const { style, children, ...attrs } = vnode.props;
119
127
  const attrParts = [];
128
+ const nodeColor = extractColor(style) ?? inheritedColor;
120
129
  const kebabCase = (str) => str.replace(RE_UPPERCASE, (m) => `-${m.toLowerCase()}`);
121
130
  if (vnode.type === "svg") {
122
131
  if (!attrs.xmlns)
@@ -138,7 +147,7 @@ function vnodeToHtmlString(vnode) {
138
147
  return val;
139
148
  };
140
149
  if (style && typeof style === "object") {
141
- const styleStr = Object.entries(style).filter(([_, v]) => v !== void 0 && v !== null && v !== "").map(([k, v]) => `${kebabCase(k)}:${resolveValue(v)}`).join(";");
150
+ const styleStr = Object.entries(style).filter(([_, v]) => v !== void 0 && v !== null && v !== "").map(([k, v]) => `${kebabCase(k)}:${resolveValue(resolveCurrentColor(v, nodeColor))}`).join(";");
142
151
  if (styleStr)
143
152
  attrParts.push(`style="${styleStr.replace(RE_DQUOTE, "&quot;")}"`);
144
153
  } else if (typeof style === "string") {
@@ -148,14 +157,14 @@ function vnodeToHtmlString(vnode) {
148
157
  if (key === "tw" || key === "class" || val == null)
149
158
  continue;
150
159
  const finalKey = SVG_CAMEL_ATTR_VALUES.has(key) ? key : kebabCase(key);
151
- attrParts.push(`${finalKey}="${String(resolveValue(val)).replace(RE_DQUOTE, "&quot;")}"`);
160
+ attrParts.push(`${finalKey}="${String(resolveValue(resolveCurrentColor(val, nodeColor))).replace(RE_DQUOTE, "&quot;")}"`);
152
161
  }
153
162
  const open = attrParts.length ? `<${vnode.type} ${attrParts.join(" ")}>` : `<${vnode.type}>`;
154
163
  const inner = Array.isArray(children) ? children.map((c) => {
155
164
  if (typeof c === "string")
156
165
  return c.replace(RE_AMP, "&amp;").replace(RE_LT, "&lt;").replace(RE_GT, "&gt;");
157
166
  if (c && typeof c === "object")
158
- return vnodeToHtmlString(c);
167
+ return vnodeToHtmlString(c, nodeColor);
159
168
  return "";
160
169
  }).join("") : typeof children === "string" ? children.replace(RE_AMP, "&amp;").replace(RE_LT, "&lt;").replace(RE_GT, "&gt;") : "";
161
170
  return `${open}${inner}</${vnode.type}>`;
@@ -1,6 +1,6 @@
1
+ import { fnv1a64Base36 } from "fnv1a-64";
1
2
  import { createError, getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3";
2
3
  import { useStorage } from "nitropack/runtime";
3
- import { digest } from "ohash";
4
4
  import { withTrailingSlash } from "ufo";
5
5
  import { prefixStorage } from "unstorage";
6
6
  import { logger } from "../../logger.js";
@@ -83,7 +83,7 @@ export async function useOgImageBufferCache(ctx, options) {
83
83
  const headers = {
84
84
  // avoid multi-tenancy cache issues
85
85
  "Vary": "accept-encoding, host",
86
- "etag": `W/"${digest(value)}"`,
86
+ "etag": `W/"${fnv1a64Base36(value)}"`,
87
87
  "last-modified": (/* @__PURE__ */ new Date()).toUTCString(),
88
88
  "cache-control": `public, max-age=${maxAge}, s-maxage=${maxAge}, immutable`
89
89
  };
@@ -1,11 +1,11 @@
1
1
  import { defu } from "defu";
2
2
  import { useRuntimeConfig } from "nitropack/runtime";
3
- import { hash } from "ohash";
4
3
  import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
5
4
  import { withoutBase, withoutTrailingSlash } from "ufo";
5
+ import { getIslandHash } from "#og-image/island-hash";
6
6
  export { withoutQuery } from "nuxtseo-shared/utils";
7
7
  export function fetchIsland(e, component, props, timeout) {
8
- const hashId = hash([component, props, {}, void 0]).replace(/[-_]/g, "");
8
+ const hashId = getIslandHash({ name: component, props });
9
9
  const signal = timeout ? AbortSignal.timeout(timeout) : void 0;
10
10
  return e.$fetch(`/__nuxt_island/${component}_${hashId}.json`, {
11
11
  params: {
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hash an arbitrary value into a short, stable string key.
3
+ *
4
+ * Values are serialized to a canonical representation (equal structures hash
5
+ * equally regardless of key order), then digested with fnv1a-64. Matches the
6
+ * approach Nuxt uses for `useAsyncData`/`useFetch` keys.
7
+ *
8
+ * Non-cryptographic — never use for signatures or integrity checks.
9
+ */
10
+ export declare function hashKey(value: unknown): string;
@@ -0,0 +1,5 @@
1
+ import { fnv1a64Base36 } from "fnv1a-64";
2
+ import { identify } from "object-identity";
3
+ export function hashKey(value) {
4
+ return fnv1a64Base36(identify(value));
5
+ }
@@ -38,8 +38,9 @@ export interface BuildOgImageUrlResult {
38
38
  */
39
39
  export declare function buildOgImageUrl(options: Record<string, any>, extension?: string, isStatic?: boolean, defaults?: Record<string, any>, secret?: string): BuildOgImageUrlResult;
40
40
  /**
41
- * Sign encoded params using a keyed hash (ohash, cross-runtime compatible).
42
- * Returns first 16 chars of the base64url hash for URL brevity.
41
+ * Sign encoded params using a keyed SHA-256 digest (cross-runtime, sync).
42
+ * Returns first 16 chars of the base64url digest for URL brevity.
43
+ * Must stay cryptographic — a fast hash here would make signatures forgeable.
43
44
  */
44
45
  export declare function signEncodedParams(encoded: string, secret: string): string;
45
46
  /**