nuxt-og-image 2.0.0-beta.52 → 2.0.0-beta.54

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 (49) hide show
  1. package/dist/client/200.html +2 -2
  2. package/dist/client/404.html +2 -2
  3. package/dist/client/_nuxt/{IconCSS.73da91e8.js → IconCSS.3275c98c.js} +1 -1
  4. package/dist/client/_nuxt/{ImageLoader.1dc2da65.js → ImageLoader.f8c23aba.js} +1 -1
  5. package/dist/client/_nuxt/{entry.9627f7dd.js → entry.10f3a36e.js} +2 -2
  6. package/dist/client/_nuxt/{error-404.e8b1a738.js → error-404.cc80c5f1.js} +1 -1
  7. package/dist/client/_nuxt/{error-500.34be4bd8.js → error-500.dc06de67.js} +1 -1
  8. package/dist/client/_nuxt/{error-component.4733114a.js → error-component.a2873650.js} +2 -2
  9. package/dist/client/_nuxt/{index.35b0e13d.js → index.8f17abab.js} +1 -1
  10. package/dist/client/_nuxt/{options.bd244bf2.js → options.9ec6995d.js} +1 -1
  11. package/dist/client/_nuxt/{png.765461fb.js → png.3d951d00.js} +1 -1
  12. package/dist/client/_nuxt/{shiki.474ce6f4.js → shiki.31e8f44a.js} +1 -1
  13. package/dist/client/_nuxt/{svg.1511e50d.js → svg.6ca87cf3.js} +1 -1
  14. package/dist/client/_nuxt/{vnodes.4f695971.js → vnodes.0022f1ec.js} +1 -1
  15. package/dist/client/index.html +2 -2
  16. package/dist/client/options/index.html +2 -2
  17. package/dist/client/png/index.html +2 -2
  18. package/dist/client/svg/index.html +2 -2
  19. package/dist/client/vnodes/index.html +2 -2
  20. package/dist/module.json +1 -1
  21. package/dist/runtime/nitro/middleware/og.png.mjs +2 -2
  22. package/dist/runtime/nitro/providers/png/resvg-node.d.ts +2 -3
  23. package/dist/runtime/nitro/providers/png/resvg-wasm.d.ts +2 -3
  24. package/dist/runtime/nitro/providers/png/resvg-wasm.mjs +1 -1
  25. package/dist/runtime/nitro/providers/png/svg2png.d.ts +2 -3
  26. package/dist/runtime/nitro/providers/png/svg2png.mjs +1 -1
  27. package/dist/runtime/nitro/providers/satori/yoga-wasm.d.ts +2 -3
  28. package/dist/runtime/nitro/providers/satori/yoga-wasm.mjs +1 -1
  29. package/dist/runtime/nitro/renderers/browser.mjs +3 -6
  30. package/dist/runtime/nitro/renderers/satori/index.mjs +15 -19
  31. package/dist/runtime/nitro/renderers/satori/plugins/emojis.d.ts +1 -1
  32. package/dist/runtime/nitro/renderers/satori/plugins/emojis.mjs +21 -23
  33. package/dist/runtime/nitro/renderers/satori/plugins/encoding.d.ts +1 -1
  34. package/dist/runtime/nitro/renderers/satori/plugins/encoding.mjs +5 -7
  35. package/dist/runtime/nitro/renderers/satori/plugins/flex.d.ts +1 -1
  36. package/dist/runtime/nitro/renderers/satori/plugins/flex.mjs +8 -10
  37. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.d.ts +1 -1
  38. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.mjs +42 -32
  39. package/dist/runtime/nitro/renderers/satori/plugins/twClasses.d.ts +1 -1
  40. package/dist/runtime/nitro/renderers/satori/plugins/twClasses.mjs +5 -7
  41. package/dist/runtime/nitro/renderers/satori/utils.d.ts +4 -5
  42. package/dist/runtime/nitro/renderers/satori/utils.mjs +7 -9
  43. package/dist/runtime/nitro/routes/options.d.ts +2 -2
  44. package/dist/runtime/nitro/routes/options.mjs +8 -3
  45. package/dist/runtime/nitro/routes/svg.mjs +2 -2
  46. package/dist/runtime/nitro/routes/vnode.mjs +2 -2
  47. package/dist/runtime/nitro/utils.d.ts +9 -6
  48. package/dist/runtime/nitro/utils.mjs +17 -9
  49. package/package.json +6 -5
@@ -1,5 +1,4 @@
1
1
  import { html as convertHtmlToSatori } from "satori-html";
2
- import { parseURL } from "ufo";
3
2
  import { loadFont, walkSatoriTree } from "./utils.mjs";
4
3
  import imageSrc from "./plugins/imageSrc.mjs";
5
4
  import twClasses from "./plugins/twClasses.mjs";
@@ -18,40 +17,37 @@ function loadFonts(baseURL, fonts) {
18
17
  }
19
18
  const SatoriRenderer = {
20
19
  name: "satori",
21
- createPng: async function createPng(baseUrl, options) {
22
- const svg = await this.createSvg(baseUrl, options);
20
+ createPng: async function createPng(options) {
21
+ const svg = await this.createSvg(options);
23
22
  const pngCreator = await loadPngCreator();
24
- return pngCreator(svg, { baseUrl, ...options });
23
+ return pngCreator(svg, options);
25
24
  },
26
- createVNode: async function createVNode(baseUrl, options) {
27
- const url = parseURL(baseUrl);
25
+ createVNode: async function createVNode(options) {
28
26
  const html = await globalThis.$fetch("/api/og-image-html", {
29
27
  params: {
30
- path: url.pathname,
28
+ path: options.path,
31
29
  options: JSON.stringify(options)
32
30
  }
33
31
  });
34
32
  const body = html.match(/<body[^>]*>([\s\S]*)<\/body>/)?.[1] || "";
35
33
  const satoriTree = convertHtmlToSatori(body);
36
- await walkSatoriTree(url, satoriTree, [
37
- // @todo add user land support
38
- emojis(url),
39
- twClasses(url),
40
- imageSrc(url),
41
- flex(url),
42
- encoding(url)
43
- ]);
34
+ await walkSatoriTree(satoriTree, [
35
+ emojis,
36
+ twClasses,
37
+ imageSrc,
38
+ flex,
39
+ encoding
40
+ ], options);
44
41
  return satoriTree;
45
42
  },
46
- createSvg: async function createSvg(baseUrl, options) {
43
+ createSvg: async function createSvg(options) {
47
44
  const { fonts, satoriOptions } = useRuntimeConfig()["nuxt-og-image"];
48
- const vnodes = await this.createVNode(baseUrl, options);
45
+ const vnodes = await this.createVNode(options);
49
46
  if (!satoriFonts.length)
50
- satoriFonts.push(...await loadFonts(baseUrl, fonts));
47
+ satoriFonts.push(...await loadFonts(options.requestOrigin, fonts));
51
48
  const satori = await loadSatori();
52
49
  return await satori(vnodes, {
53
50
  ...satoriOptions,
54
- baseUrl,
55
51
  fonts: satoriFonts,
56
52
  embedFont: true,
57
53
  width: options.width,
@@ -1,2 +1,2 @@
1
- declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
1
+ declare const _default: import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
2
2
  export default _default;
@@ -2,27 +2,25 @@ import { defineSatoriTransformer } from "../utils.mjs";
2
2
  function isEmojiFilter(node) {
3
3
  return node.type === "img" && node.props?.class?.includes("emoji");
4
4
  }
5
- export default defineSatoriTransformer(() => {
6
- return [
7
- // need to make sure parent div has flex for the emoji to render inline
8
- {
9
- filter: (node) => node.type === "div" && Array.isArray(node.props?.children) && node.props.children.some(isEmojiFilter),
10
- transform: async (node) => {
11
- node.props.style = node.props.style || {};
12
- node.props.style.display = "flex";
13
- node.props.style.alignItems = "center";
14
- }
15
- },
16
- {
17
- filter: isEmojiFilter,
18
- transform: async (node) => {
19
- node.props.style = node.props.style || {};
20
- node.props.style.height = "1em";
21
- node.props.style.width = "1em";
22
- node.props.style.margin = "0 .3em 0 .3em";
23
- node.props.style.verticalAlign = "0.1em";
24
- node.props.class = "";
25
- }
5
+ export default defineSatoriTransformer([
6
+ // need to make sure parent div has flex for the emoji to render inline
7
+ {
8
+ filter: (node) => node.type === "div" && Array.isArray(node.props?.children) && node.props.children.some(isEmojiFilter),
9
+ transform: async (node) => {
10
+ node.props.style = node.props.style || {};
11
+ node.props.style.display = "flex";
12
+ node.props.style.alignItems = "center";
26
13
  }
27
- ];
28
- });
14
+ },
15
+ {
16
+ filter: isEmojiFilter,
17
+ transform: async (node) => {
18
+ node.props.style = node.props.style || {};
19
+ node.props.style.height = "1em";
20
+ node.props.style.width = "1em";
21
+ node.props.style.margin = "0 .3em 0 .3em";
22
+ node.props.style.verticalAlign = "0.1em";
23
+ node.props.class = "";
24
+ }
25
+ }
26
+ ]);
@@ -1,2 +1,2 @@
1
- declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
1
+ declare const _default: import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
2
2
  export default _default;
@@ -1,10 +1,8 @@
1
1
  import { defineSatoriTransformer } from "../utils.mjs";
2
2
  import { decodeHtml } from "../../../utils-pure.mjs";
3
- export default defineSatoriTransformer(() => {
4
- return {
5
- filter: (node) => typeof node.props?.children === "string",
6
- transform: async (node) => {
7
- node.props.children = decodeHtml(node.props.children);
8
- }
9
- };
3
+ export default defineSatoriTransformer({
4
+ filter: (node) => typeof node.props?.children === "string",
5
+ transform: async (node) => {
6
+ node.props.children = decodeHtml(node.props.children);
7
+ }
10
8
  });
@@ -1,2 +1,2 @@
1
- declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
1
+ declare const _default: import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
2
2
  export default _default;
@@ -1,12 +1,10 @@
1
1
  import { defineSatoriTransformer } from "../utils.mjs";
2
- export default defineSatoriTransformer(() => {
3
- return {
4
- filter: (node) => node.type === "div" && (Array.isArray(node.props?.children) && node.props?.children.length >= 1) && (!node.props.style?.display && !node.props?.class?.includes("hidden")),
5
- transform: async (node) => {
6
- node.props.style = node.props.style || {};
7
- node.props.style.display = "flex";
8
- if (!node.props?.class?.includes("flex-"))
9
- node.props.style.flexDirection = "column";
10
- }
11
- };
2
+ export default defineSatoriTransformer({
3
+ filter: (node) => node.type === "div" && (Array.isArray(node.props?.children) && node.props?.children.length >= 1) && (!node.props.style?.display && !node.props?.class?.includes("hidden")),
4
+ transform: async (node) => {
5
+ node.props.style = node.props.style || {};
6
+ node.props.style.display = "flex";
7
+ if (!node.props?.class?.includes("flex-"))
8
+ node.props.style.flexDirection = "column";
9
+ }
12
10
  });
@@ -1,2 +1,2 @@
1
- declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
1
+ declare const _default: import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
2
2
  export default _default;
@@ -1,40 +1,50 @@
1
+ import { Buffer } from "node:buffer";
1
2
  import { withBase } from "ufo";
3
+ import sizeOf from "image-size";
2
4
  import { defineSatoriTransformer } from "../utils.mjs";
3
- import { readPublicAssetBase64 } from "../../../utils.mjs";
4
- export default defineSatoriTransformer((url) => {
5
- return {
6
- filter: (node) => node.type === "img",
7
- transform: async (node) => {
8
- const src = node.props?.src;
9
- if (src && src.startsWith("/")) {
10
- let updated = false;
11
- const file = await readPublicAssetBase64(src);
12
- if (file) {
13
- node.props.src = file;
5
+ import { readPublicAssetBase64, toBase64Image } from "../../../utils.mjs";
6
+ export default defineSatoriTransformer({
7
+ filter: (node) => node.type === "img",
8
+ transform: async (node, options) => {
9
+ const src = node.props?.src;
10
+ if (src && src.startsWith("/")) {
11
+ let updated = false;
12
+ const file = await readPublicAssetBase64(src);
13
+ let dimensions;
14
+ if (file) {
15
+ node.props.src = file.src;
16
+ dimensions = { width: file.width, height: file.height };
17
+ updated = true;
18
+ }
19
+ if (!updated) {
20
+ let valid = true;
21
+ const response = await globalThis.$fetch(src, {
22
+ responseType: "arrayBuffer",
23
+ baseURL: options.requestOrigin
24
+ }).catch(() => {
25
+ valid = false;
26
+ });
27
+ if (valid) {
28
+ node.props.src = toBase64Image(src, response);
29
+ const imageSize = await sizeOf(Buffer.from(response));
30
+ dimensions = { width: imageSize.width, height: imageSize.height };
14
31
  updated = true;
15
32
  }
16
- if (!updated) {
17
- try {
18
- const response = await globalThis.$fetch(src);
19
- node.props.src = response.arrayBuffer();
20
- updated = true;
21
- } catch (e) {
22
- }
23
- }
24
- if (!updated) {
25
- try {
26
- const response = await globalThis.$fetch.raw(src);
27
- if (response.status === 200) {
28
- node.props.src = response.arrayBuffer();
29
- updated = true;
30
- }
31
- } catch (e) {
32
- }
33
- }
34
- if (!updated) {
35
- node.props.src = `${withBase(src, `${url.protocol}//${url.host}`)}?${Date.now()}`;
33
+ }
34
+ if (dimensions?.width && dimensions?.height) {
35
+ const naturalAspectRatio = dimensions.width / dimensions.height;
36
+ if (node.props.width && !node.props.height) {
37
+ node.props.height = Math.round(node.props.width / naturalAspectRatio);
38
+ } else if (node.props.height && !node.props.width) {
39
+ node.props.width = Math.round(node.props.height * naturalAspectRatio);
40
+ } else if (!node.props.width && !node.props.height) {
41
+ node.props.width = dimensions.width;
42
+ node.props.height = dimensions.height;
36
43
  }
37
44
  }
45
+ if (!updated) {
46
+ node.props.src = `${withBase(src, `${options.requestOrigin}`)}?${Date.now()}`;
47
+ }
38
48
  }
39
- };
49
+ }
40
50
  });
@@ -1,2 +1,2 @@
1
- declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
1
+ declare const _default: import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
2
2
  export default _default;
@@ -1,9 +1,7 @@
1
1
  import { defineSatoriTransformer } from "../utils.mjs";
2
- export default defineSatoriTransformer(() => {
3
- return {
4
- filter: (node) => !!node.props?.class && !node.props?.tw,
5
- transform: async (node) => {
6
- node.props.tw = node.props.class;
7
- }
8
- };
2
+ export default defineSatoriTransformer({
3
+ filter: (node) => !!node.props?.class && !node.props?.tw,
4
+ transform: async (node) => {
5
+ node.props.tw = node.props.class;
6
+ }
9
7
  });
@@ -1,5 +1,4 @@
1
- import type { ParsedURL } from 'ufo';
2
- import type { FontConfig, SatoriTransformer, VNode } from '../../../../types';
3
- export declare function loadFont(baseURL: string, font: FontConfig): Promise<any>;
4
- export declare function walkSatoriTree(url: ParsedURL, node: VNode, plugins: (SatoriTransformer | SatoriTransformer[])[]): Promise<void>;
5
- export declare function defineSatoriTransformer(transformer: (url: ParsedURL) => SatoriTransformer | SatoriTransformer[]): (url: ParsedURL) => SatoriTransformer | SatoriTransformer[];
1
+ import type { FontConfig, RuntimeOgImageOptions, SatoriTransformer, VNode } from '../../../../types';
2
+ export declare function loadFont(requestOrigin: string, font: FontConfig): Promise<any>;
3
+ export declare function walkSatoriTree(node: VNode, plugins: (SatoriTransformer | SatoriTransformer[])[], props: RuntimeOgImageOptions): Promise<void>;
4
+ export declare function defineSatoriTransformer(transformer: SatoriTransformer | SatoriTransformer[]): SatoriTransformer | SatoriTransformer[];
@@ -2,15 +2,13 @@ import { Buffer } from "node:buffer";
2
2
  import { base64ToArrayBuffer, readPublicAsset } from "../../utils.mjs";
3
3
  import { useStorage } from "#imports";
4
4
  const cachedFonts = {};
5
- export async function loadFont(baseURL, font) {
6
- let fontKey = font;
7
- if (typeof font === "object")
8
- fontKey = `${font.name}:${font.weight}`;
5
+ export async function loadFont(requestOrigin, font) {
6
+ const fontKey = `${font.name}:${font.weight}`;
7
+ const storageKey = `assets:nuxt-og-image:font:${fontKey}`;
9
8
  if (cachedFonts[fontKey])
10
9
  return cachedFonts[fontKey];
11
10
  const [name, weight] = fontKey.split(":");
12
11
  let data;
13
- const storageKey = `assets:nuxt-og-imagee:font:${fontKey}`;
14
12
  if (await useStorage().hasItem(storageKey))
15
13
  data = base64ToArrayBuffer(await useStorage().getItem(storageKey));
16
14
  if (!data && name === "Inter" && ["400", "700"].includes(weight)) {
@@ -22,7 +20,7 @@ export async function loadFont(baseURL, font) {
22
20
  try {
23
21
  data = await globalThis.$fetch(font.path, {
24
22
  responseType: "arrayBuffer",
25
- baseURL
23
+ baseURL: requestOrigin
26
24
  });
27
25
  } catch {
28
26
  }
@@ -40,7 +38,7 @@ export async function loadFont(baseURL, font) {
40
38
  await useStorage().setItem(storageKey, Buffer.from(data).toString("base64"));
41
39
  return cachedFonts[fontKey];
42
40
  }
43
- export async function walkSatoriTree(url, node, plugins) {
41
+ export async function walkSatoriTree(node, plugins, props) {
44
42
  if (!node.props?.children)
45
43
  return;
46
44
  if (Array.isArray(node.props.children) && node.props.children.length === 0) {
@@ -51,9 +49,9 @@ export async function walkSatoriTree(url, node, plugins) {
51
49
  if (child) {
52
50
  for (const plugin of plugins.flat()) {
53
51
  if (plugin.filter(child))
54
- await plugin.transform(child);
52
+ await plugin.transform(child, props);
55
53
  }
56
- await walkSatoriTree(url, child, plugins);
54
+ await walkSatoriTree(child, plugins, props);
57
55
  }
58
56
  }
59
57
  }
@@ -1,3 +1,3 @@
1
- import type { OgImageOptions } from '../../../types';
2
- declare const _default: import("h3").EventHandler<false | OgImageOptions>;
1
+ import type { RuntimeOgImageOptions } from '../../../types';
2
+ declare const _default: import("h3").EventHandler<false | RuntimeOgImageOptions>;
3
3
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import { createError, defineEventHandler, getQuery } from "h3";
2
2
  import { withoutBase } from "ufo";
3
3
  import { defu } from "defu";
4
- import { extractOgImageOptions } from "../utils.mjs";
4
+ import { extractOgImageOptions, useHostname } from "../utils.mjs";
5
5
  import { getRouteRules } from "#internal/nitro";
6
6
  import { useRuntimeConfig } from "#imports";
7
7
  export default defineEventHandler(async (e) => {
@@ -32,6 +32,11 @@ export default defineEventHandler(async (e) => {
32
32
  if (routeRules === false)
33
33
  return false;
34
34
  const { defaults } = useRuntimeConfig()["nuxt-og-image"];
35
- const result = defu(extractedPayload, routeRules, { path }, defaults);
36
- return result;
35
+ return defu(
36
+ extractedPayload,
37
+ routeRules,
38
+ // runtime options
39
+ { path, requestOrigin: useHostname(e) },
40
+ defaults
41
+ );
37
42
  });
@@ -1,6 +1,6 @@
1
1
  import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
2
  import { withBase } from "ufo";
3
- import { fetchOptions, useHostname } from "../utils.mjs";
3
+ import { fetchOptions } from "../utils.mjs";
4
4
  import { useProvider } from "#nuxt-og-image/provider";
5
5
  import { useRuntimeConfig } from "#imports";
6
6
  export default defineEventHandler(async (e) => {
@@ -15,5 +15,5 @@ export default defineEventHandler(async (e) => {
15
15
  statusMessage: `Provider ${options.provider} is missing.`
16
16
  });
17
17
  }
18
- return provider.createSvg(withBase(path, useHostname(e)), options);
18
+ return provider.createSvg(options);
19
19
  });
@@ -1,6 +1,6 @@
1
1
  import { createError, defineEventHandler, getQuery, setHeader } from "h3";
2
2
  import { withBase } from "ufo";
3
- import { fetchOptions, useHostname } from "../utils.mjs";
3
+ import { fetchOptions } from "../utils.mjs";
4
4
  import { useProvider } from "#nuxt-og-image/provider";
5
5
  import { useRuntimeConfig } from "#imports";
6
6
  export default defineEventHandler(async (e) => {
@@ -15,5 +15,5 @@ export default defineEventHandler(async (e) => {
15
15
  statusMessage: `Provider ${options.provider} is missing.`
16
16
  });
17
17
  }
18
- return provider.createVNode(withBase(path, useHostname(e)), options);
18
+ return provider.createVNode(options);
19
19
  });
@@ -1,15 +1,18 @@
1
1
  /// <reference types="node" />
2
2
  import { Buffer } from 'node:buffer';
3
3
  import type { H3Event } from 'h3';
4
- import type { OgImageOptions } from '../../types';
4
+ import type { RuntimeOgImageOptions } from '../../types';
5
5
  export * from './util-hostname';
6
6
  export declare function wasmLoader(asyncModuleLoad: Promise<any> | Buffer | string, fallback: string): {
7
- load(options: {
8
- baseUrl: string;
9
- }): Promise<any>;
7
+ load(options: RuntimeOgImageOptions): Promise<any>;
10
8
  };
11
- export declare function fetchOptions(e: H3Event, path: string): Promise<OgImageOptions>;
9
+ export declare function fetchOptions(e: H3Event, path: string): Promise<RuntimeOgImageOptions>;
12
10
  export declare function base64ToArrayBuffer(base64: string): ArrayBuffer;
13
11
  export declare function readPublicAsset(file: string, encoding?: BufferEncoding): Promise<string | Buffer | undefined>;
14
- export declare function readPublicAssetBase64(file: string): Promise<string | undefined>;
12
+ export declare function readPublicAssetBase64(file: string): Promise<{
13
+ src: string;
14
+ width?: number;
15
+ height?: number;
16
+ } | undefined>;
17
+ export declare function toBase64Image(fileName: string, data: string | ArrayBuffer): string;
15
18
  export * from './utils-pure';
@@ -3,6 +3,7 @@ import { Buffer } from "node:buffer";
3
3
  import { getQuery } from "h3";
4
4
  import { join } from "pathe";
5
5
  import { prefixStorage } from "unstorage";
6
+ import sizeOf from "image-size";
6
7
  import { useRuntimeConfig, useStorage } from "#imports";
7
8
  export * from "./util-hostname.mjs";
8
9
  export function wasmLoader(asyncModuleLoad, fallback) {
@@ -27,8 +28,7 @@ export function wasmLoader(asyncModuleLoad, fallback) {
27
28
  wasm = Buffer.from(wasm, "base64");
28
29
  }
29
30
  if (!wasm) {
30
- const url = new URL(options.baseUrl);
31
- wasm = await (await globalThis.$fetch(fallback, { baseURL: url.origin })).arrayBuffer();
31
+ wasm = await (await globalThis.$fetch(fallback, { baseURL: options.requestOrigin })).arrayBuffer();
32
32
  wasm = Buffer.from(wasm);
33
33
  }
34
34
  resolve(wasm);
@@ -85,14 +85,22 @@ export async function readPublicAsset(file, encoding) {
85
85
  }
86
86
  export async function readPublicAssetBase64(file) {
87
87
  const base64 = await readPublicAsset(file, "base64");
88
+ const dimensions = await sizeOf(Buffer.from(base64, "base64"));
88
89
  if (base64) {
89
- let type = "image/jpeg";
90
- const ext = file.split(".").pop();
91
- if (ext === "svg")
92
- type = "image/svg+xml";
93
- else if (ext === "png")
94
- type = "image/png";
95
- return `data:${type};base64,${base64}`;
90
+ return {
91
+ src: toBase64Image(file, base64),
92
+ ...dimensions
93
+ };
96
94
  }
97
95
  }
96
+ export function toBase64Image(fileName, data) {
97
+ const base64 = typeof data === "string" ? data : Buffer.from(data).toString("base64");
98
+ let type = "image/jpeg";
99
+ const ext = fileName.split(".").pop();
100
+ if (ext === "svg")
101
+ type = "image/svg+xml";
102
+ else if (ext === "png")
103
+ type = "image/png";
104
+ return `data:${type};base64,${base64}`;
105
+ }
98
106
  export * from "./utils-pure.mjs";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.52",
4
+ "version": "2.0.0-beta.54",
5
5
  "packageManager": "pnpm@8.6.0",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -39,6 +39,7 @@
39
39
  "flatted": "^3.2.7",
40
40
  "fs-extra": "^11.1.1",
41
41
  "globby": "^13.1.4",
42
+ "image-size": "^1.0.2",
42
43
  "inline-css": "^4.0.2",
43
44
  "launch-editor": "^2.6.0",
44
45
  "nuxt-icon": "^0.4.1",
@@ -47,7 +48,7 @@
47
48
  "ofetch": "^1.1.0",
48
49
  "ohash": "^1.1.2",
49
50
  "pathe": "^1.1.1",
50
- "playwright-core": "^1.34.3",
51
+ "playwright-core": "^1.35.0",
51
52
  "radix3": "^1.0.1",
52
53
  "satori": "0.10.1",
53
54
  "satori-html": "^0.3.2",
@@ -62,16 +63,16 @@
62
63
  },
63
64
  "devDependencies": {
64
65
  "@antfu/eslint-config": "^0.39.5",
65
- "@nuxt/devtools-edge": "0.5.5-28099668.306c6a5",
66
+ "@nuxt/devtools-edge": "0.5.5-28104076.594a352",
66
67
  "@nuxt/module-builder": "^0.4.0",
67
68
  "@nuxt/test-utils": "3.5.3",
68
69
  "@nuxtjs/eslint-config-typescript": "^12.0.0",
69
- "@types/ws": "^8.5.4",
70
+ "@types/ws": "^8.5.5",
70
71
  "bumpp": "^9.1.1",
71
72
  "eslint": "8.42.0",
72
73
  "jest-image-snapshot": "^6.1.0",
73
74
  "nuxt": "^3.5.3",
74
- "sass": "^1.62.1",
75
+ "sass": "^1.63.3",
75
76
  "vitest": "^0.32.0"
76
77
  },
77
78
  "resolutions": {