nuxt-og-image 3.0.0-rc.52 → 3.0.0-rc.53

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 (33) hide show
  1. package/dist/client/200.html +10 -10
  2. package/dist/client/404.html +10 -10
  3. package/dist/client/_nuxt/-hLHpAOl.js +1 -0
  4. package/dist/client/_nuxt/3Yx8WcR-.js +1 -0
  5. package/dist/client/_nuxt/{gCeFpf9t.js → B561T8eW.js} +1 -1
  6. package/dist/client/_nuxt/{DggdVF2v.js → CQ1WWl9n.js} +1 -1
  7. package/dist/client/_nuxt/CudBhkk3.js +1 -0
  8. package/dist/client/_nuxt/{7fd6vGzb.js → DBeuZS66.js} +1 -1
  9. package/dist/client/_nuxt/{a72dLM4M.js → DZWTOXyg.js} +1 -1
  10. package/dist/client/_nuxt/{A1WiD9SJ.js → DaCkt_J7.js} +1 -1
  11. package/dist/client/_nuxt/{BUNvBuCY.js → Dk5M0e7R.js} +63 -63
  12. package/dist/client/_nuxt/builds/latest.json +1 -1
  13. package/dist/client/_nuxt/builds/meta/7e516fcf-301f-4df9-8a57-a4bd3951d194.json +1 -0
  14. package/dist/client/_nuxt/{DwCYcAX8.js → crZ1QlHm.js} +1 -1
  15. package/dist/client/index.html +10 -10
  16. package/dist/module.json +5 -1
  17. package/dist/runtime/nitro/og-image/satori/font.mjs +10 -4
  18. package/dist/runtime/nitro/og-image/satori/plugins/classes.mjs +2 -2
  19. package/dist/runtime/nitro/og-image/satori/plugins/emojis.mjs +1 -1
  20. package/dist/runtime/nitro/og-image/satori/plugins/encoding.mjs +2 -2
  21. package/dist/runtime/nitro/og-image/satori/plugins/flex.mjs +1 -1
  22. package/dist/runtime/nitro/og-image/satori/plugins/imageSrc.mjs +30 -27
  23. package/dist/runtime/nitro/og-image/satori/utils.d.ts +1 -1
  24. package/dist/runtime/nitro/og-image/satori/utils.mjs +9 -5
  25. package/dist/runtime/nitro/og-image/satori/vnodes.mjs +5 -3
  26. package/dist/runtime/pure.d.ts +1 -1
  27. package/dist/runtime/pure.mjs +17 -7
  28. package/dist/runtime/types.d.ts +1 -1
  29. package/package.json +36 -36
  30. package/dist/client/_nuxt/BG_OyJVq.js +0 -1
  31. package/dist/client/_nuxt/C3YqBJkQ.js +0 -1
  32. package/dist/client/_nuxt/CrjQeCwm.js +0 -1
  33. package/dist/client/_nuxt/builds/meta/a4ad9cab-b4b9-4011-ba26-b8768422faa5.json +0 -1
@@ -1 +1 @@
1
- {"id":"a4ad9cab-b4b9-4011-ba26-b8768422faa5","timestamp":1712483878292}
1
+ {"id":"7e516fcf-301f-4df9-8a57-a4bd3951d194","timestamp":1714367108725}
@@ -0,0 +1 @@
1
+ {"id":"7e516fcf-301f-4df9-8a57-a4bd3951d194","timestamp":1714367108725,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -1 +1 @@
1
- import{g as m,h as f,i as I,j as r,r as d,o as x,c as v,n as _,_ as S}from"./BUNvBuCY.js";const g=m({__name:"IconCSS",props:{name:{type:String,required:!0},size:{type:String,default:""}},setup(u){f(e=>({"0dfa3482":p.value}));const t=I(),s=u,l=r(()=>{var e,n;return(n=(e=t.nuxtIcon)==null?void 0:e.aliases)!=null&&n[s.name]?t.nuxtIcon.aliases[s.name]:s.name}),c=r(()=>d(l.value)),p=r(()=>{var o,a;const e=(a=(o=t.nuxtIcon)==null?void 0:o.iconifyApiOptions)==null?void 0:a.url;if(e)try{new URL(e)}catch{console.warn("Nuxt IconCSS: Invalid custom Iconify API URL");return}return`url('${e||"https://api.iconify.design"}/${c.value.prefix}/${c.value.name}.svg')`}),i=r(()=>{var n,o,a;if(!s.size&&typeof((n=t.nuxtIcon)==null?void 0:n.size)=="boolean"&&!((o=t.nuxtIcon)!=null&&o.size))return;const e=s.size||((a=t.nuxtIcon)==null?void 0:a.size)||"1em";return String(Number(e))===e?`${e}px`:e});return(e,n)=>(x(),v("span",{style:_({width:i.value,height:i.value})},null,4))}}),h=S(g,[["__scopeId","data-v-ae73b16e"]]);export{h as default};
1
+ import{g as m,h as f,i as I,j as r,r as d,o as x,c as v,n as _,_ as S}from"./Dk5M0e7R.js";const g=m({__name:"IconCSS",props:{name:{type:String,required:!0},size:{type:String,default:""}},setup(u){f(e=>({"0dfa3482":p.value}));const t=I(),s=u,l=r(()=>{var e,n;return(n=(e=t.nuxtIcon)==null?void 0:e.aliases)!=null&&n[s.name]?t.nuxtIcon.aliases[s.name]:s.name}),c=r(()=>d(l.value)),p=r(()=>{var o,a;const e=(a=(o=t.nuxtIcon)==null?void 0:o.iconifyApiOptions)==null?void 0:a.url;if(e)try{new URL(e)}catch{console.warn("Nuxt IconCSS: Invalid custom Iconify API URL");return}return`url('${e||"https://api.iconify.design"}/${c.value.prefix}/${c.value.name}.svg')`}),i=r(()=>{var n,o,a;if(!s.size&&typeof((n=t.nuxtIcon)==null?void 0:n.size)=="boolean"&&!((o=t.nuxtIcon)!=null&&o.size))return;const e=s.size||((a=t.nuxtIcon)==null?void 0:a.size)||"1em";return String(Number(e))===e?`${e}px`:e});return(e,n)=>(x(),v("span",{style:_({width:i.value,height:i.value})},null,4))}}),h=S(g,[["__scopeId","data-v-ae73b16e"]]);export{h as default};
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html><html><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.CyZsr2dM.css">
4
- <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BUNvBuCY.js">
4
+ <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/Dk5M0e7R.js">
5
5
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DXFkqnOI.js">
6
6
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/D6NljDpC.js">
7
7
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CowR2XfX.js">
@@ -63,7 +63,7 @@
63
63
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/RgJsN3zu.js">
64
64
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DCAtC51B.js">
65
65
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DnhXxWz-.js">
66
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/C3YqBJkQ.js">
66
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/-hLHpAOl.js">
67
67
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DfeQjIbs.js">
68
68
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/sQpxpyUs.js">
69
69
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/D6pmzCqS.js">
@@ -88,7 +88,7 @@
88
88
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DUdlC5k_.js">
89
89
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/C5gCGmDW.js">
90
90
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DAGYewaG.js">
91
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BG_OyJVq.js">
91
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CudBhkk3.js">
92
92
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DZqG9GXz.js">
93
93
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DmDrTTlz.js">
94
94
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BR6CMsBL.js">
@@ -165,7 +165,7 @@
165
165
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DzPyIVdT.js">
166
166
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BxwAa5i0.js">
167
167
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/C_8Fx7bH.js">
168
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/7fd6vGzb.js">
168
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DBeuZS66.js">
169
169
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BT9ZzGyQ.js">
170
170
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DnLUQrgA.js">
171
171
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DCdPDLy4.js">
@@ -226,14 +226,14 @@
226
226
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BBDuFDsq.js">
227
227
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/eJfcURhx.js">
228
228
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BSB_bK09.js">
229
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CrjQeCwm.js">
230
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DggdVF2v.js">
231
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/A1WiD9SJ.js">
229
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/3Yx8WcR-.js">
230
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CQ1WWl9n.js">
231
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DaCkt_J7.js">
232
232
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DFF-wSSt.js">
233
233
  <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-404.BRldFSII.css">
234
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/gCeFpf9t.js">
234
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/B561T8eW.js">
235
235
  <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-500.D8yw_IbC.css">
236
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/a72dLM4M.js">
237
- <script type="module" src="/__nuxt-og-image/_nuxt/BUNvBuCY.js" crossorigin></script><script>"use strict";(()=>{const a=window,e=document.documentElement,c=window.localStorage,d=["dark","light"],n=c&&c.getItem&&c.getItem("nuxt-color-mode")||"system";let l=n==="system"?f():n;const i=e.getAttribute("data-color-mode-forced");i&&(l=i),r(l),a["__NUXT_COLOR_MODE__"]={preference:n,value:l,getColorScheme:f,addColorScheme:r,removeColorScheme:u};function r(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function u(o){const t=""+o+"",s="";e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp(t,"g"),""),s&&e.removeAttribute("data-"+s)}function m(o){return a.matchMedia("(prefers-color-scheme"+o+")")}function f(){if(a.matchMedia&&m("").media!=="not all"){for(const o of d)if(m(":"+o).matches)return o}return"light"}})();
236
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DZWTOXyg.js">
237
+ <script type="module" src="/__nuxt-og-image/_nuxt/Dk5M0e7R.js" crossorigin></script><script>"use strict";(()=>{const a=window,e=document.documentElement,c=window.localStorage,d=["dark","light"],n=c&&c.getItem&&c.getItem("nuxt-color-mode")||"system";let l=n==="system"?f():n;const i=e.getAttribute("data-color-mode-forced");i&&(l=i),r(l),a["__NUXT_COLOR_MODE__"]={preference:n,value:l,getColorScheme:f,addColorScheme:r,removeColorScheme:u};function r(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function u(o){const t=""+o+"",s="";e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp(t,"g"),""),s&&e.removeAttribute("data-"+s)}function m(o){return a.matchMedia("(prefers-color-scheme"+o+")")}function f(){if(a.matchMedia&&m("").media!=="not all"){for(const o of d)if(m(":"+o).matches)return o}return"light"}})();
238
238
  </script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"_errors":1,"serverRendered":2,"data":3,"state":4,"once":5},{},false,{},{},["Set"]]</script>
239
239
  <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.json CHANGED
@@ -5,5 +5,9 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "3.0.0-rc.51"
8
+ "version": "3.0.0-rc.52",
9
+ "builder": {
10
+ "@nuxt/module-builder": "0.6.0",
11
+ "unbuild": "2.0.0"
12
+ }
9
13
  }
@@ -16,10 +16,16 @@ export async function loadFont({ e }, font) {
16
16
  }
17
17
  let data;
18
18
  if (font.path) {
19
- data = await e.$fetch(font.path, {
20
- baseURL: useNitroOrigin(e),
21
- responseType: "arrayBuffer"
22
- });
19
+ if (import.meta.dev || import.meta.prerender) {
20
+ const key = `root:public${font.path.replace("./", ":").replace("/", ":")}`;
21
+ if (await useStorage().hasItem(key))
22
+ data = await useStorage().getItemRaw(key);
23
+ } else {
24
+ data = await e.$fetch(font.path, {
25
+ baseURL: useNitroOrigin(e),
26
+ responseType: "arrayBuffer"
27
+ });
28
+ }
23
29
  } else {
24
30
  data = await e.$fetch(`/__og-image__/font/${name}/${weight}.ttf`, {
25
31
  responseType: "arrayBuffer",
@@ -2,14 +2,14 @@ import { defineSatoriTransformer } from "../utils.mjs";
2
2
  export default defineSatoriTransformer([
3
3
  {
4
4
  filter: (node) => !!node.props?.class && !node.props?.tw,
5
- transform: async (node) => {
5
+ transform(node) {
6
6
  node.props.tw = node.props.class;
7
7
  node.props.tw = node.props.tw.replace(/icon|inline-style/g, "");
8
8
  }
9
9
  },
10
10
  {
11
11
  filter: (node) => !!node.props?.style?.display,
12
- transform: async (node) => {
12
+ transform(node) {
13
13
  if (["inline-block", "inline"].includes(node.props.style.display))
14
14
  delete node.props.style.display;
15
15
  }
@@ -6,7 +6,7 @@ export default defineSatoriTransformer([
6
6
  // need to make sure parent div has flex for the emoji to render inline
7
7
  {
8
8
  filter: (node) => ["div", "p"].includes(node.type) && Array.isArray(node.props?.children) && node.props.children.some(isEmojiFilter),
9
- transform: async (node) => {
9
+ transform: (node) => {
10
10
  node.props.style = node.props.style || {};
11
11
  node.props.style.display = "flex";
12
12
  node.props.style.alignItems = "center";
@@ -4,13 +4,13 @@ export default defineSatoriTransformer([
4
4
  // clean up
5
5
  {
6
6
  filter: (node) => node.props?.["data-v-inspector"],
7
- transform: async (node) => {
7
+ transform: (node) => {
8
8
  delete node.props["data-v-inspector"];
9
9
  }
10
10
  },
11
11
  {
12
12
  filter: (node) => typeof node.props?.children === "string",
13
- transform: async (node) => {
13
+ transform: (node) => {
14
14
  node.props.children = decodeHtml(node.props.children);
15
15
  }
16
16
  }
@@ -1,7 +1,7 @@
1
1
  import { defineSatoriTransformer } from "../utils.mjs";
2
2
  export default defineSatoriTransformer({
3
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) => {
4
+ transform: (node) => {
5
5
  node.props.style = node.props.style || {};
6
6
  node.props.style.display = "flex";
7
7
  if (!node.props?.class?.includes("flex-"))
@@ -3,6 +3,11 @@ import sizeOf from "image-size";
3
3
  import { defineSatoriTransformer } from "../utils.mjs";
4
4
  import { toBase64Image } from "../../../../pure.mjs";
5
5
  import { useNitroOrigin, useStorage } from "#imports";
6
+ async function resolveLocalFilePathImage(src) {
7
+ const key = `root:public${src.replace("./", ":").replace("/", ":")}`;
8
+ if (await useStorage().hasItem(key))
9
+ return await useStorage().getItemRaw(key);
10
+ }
6
11
  export default defineSatoriTransformer([
7
12
  // fix <img src="">
8
13
  {
@@ -14,9 +19,7 @@ export default defineSatoriTransformer([
14
19
  let imageBuffer;
15
20
  if (isRelative) {
16
21
  if (import.meta.prerender || import.meta.dev) {
17
- const key = `root:public${src.replace("./", ":").replace("/", ":")}`;
18
- if (await useStorage().hasItem(key))
19
- imageBuffer = await useStorage().getItemRaw(key);
22
+ imageBuffer = await resolveLocalFilePathImage(src);
20
23
  } else {
21
24
  imageBuffer = await e.$fetch(src, {
22
25
  baseURL: useNitroOrigin(e),
@@ -24,35 +27,38 @@ export default defineSatoriTransformer([
24
27
  }).catch(() => {
25
28
  });
26
29
  }
27
- } else {
30
+ if (imageBuffer)
31
+ node.props.src = toBase64Image(imageBuffer);
32
+ } else if (!src.startsWith("data:")) {
28
33
  imageBuffer = await $fetch(src, {
29
34
  responseType: "arrayBuffer"
30
35
  }).catch(() => {
31
36
  });
32
37
  }
33
- if (imageBuffer)
34
- imageBuffer = Buffer.from(imageBuffer);
35
- if (imageBuffer) {
36
- node.props.src = toBase64Image(src, imageBuffer);
38
+ if (imageBuffer && (!node.props.width || !node.props.height)) {
37
39
  try {
38
40
  const imageSize = sizeOf(imageBuffer);
39
41
  dimensions = { width: imageSize.width, height: imageSize.height };
40
42
  } catch (e2) {
41
43
  }
42
- }
43
- if (dimensions?.width && dimensions?.height) {
44
- const naturalAspectRatio = dimensions.width / dimensions.height;
45
- if (node.props.width && !node.props.height) {
46
- node.props.height = Math.round(node.props.width / naturalAspectRatio);
47
- } else if (node.props.height && !node.props.width) {
48
- node.props.width = Math.round(node.props.height * naturalAspectRatio);
49
- } else if (!node.props.width && !node.props.height) {
50
- node.props.width = dimensions.width;
51
- node.props.height = dimensions.height;
44
+ if (dimensions?.width && dimensions?.height) {
45
+ const naturalAspectRatio = dimensions.width / dimensions.height;
46
+ if (node.props.width && !node.props.height) {
47
+ node.props.height = Math.round(node.props.width / naturalAspectRatio);
48
+ } else if (node.props.height && !node.props.width) {
49
+ node.props.width = Math.round(node.props.height * naturalAspectRatio);
50
+ } else if (!node.props.width && !node.props.height) {
51
+ node.props.width = dimensions.width;
52
+ node.props.height = dimensions.height;
53
+ }
52
54
  }
53
55
  }
54
- if (node.props.src.startsWith("/")) {
55
- node.props.src = `${withBase(src, `${useNitroOrigin(e)}`)}?${Date.now()}`;
56
+ if (typeof node.props.src === "string" && node.props.src.startsWith("/")) {
57
+ if (imageBuffer) {
58
+ node.props.src = toBase64Image(imageBuffer);
59
+ } else {
60
+ node.props.src = `${withBase(src, `${useNitroOrigin(e)}`)}?${Date.now()}`;
61
+ }
56
62
  }
57
63
  }
58
64
  },
@@ -65,13 +71,10 @@ export default defineSatoriTransformer([
65
71
  const isRelative = src?.startsWith("/");
66
72
  if (isRelative) {
67
73
  if (import.meta.prerender || import.meta.dev) {
68
- const key = `root:public${src.replace("./", ":").replace("/", ":")}`;
69
- if (await useStorage().hasItem(key)) {
70
- const imageBuffer = await useStorage().getItemRaw(key);
71
- if (imageBuffer) {
72
- const base64 = toBase64Image(src, Buffer.from(imageBuffer));
73
- node.props.style.backgroundImage = `url(${base64})`;
74
- }
74
+ const imageBuffer = await resolveLocalFilePathImage(src);
75
+ if (imageBuffer) {
76
+ const base64 = toBase64Image(Buffer.from(imageBuffer));
77
+ node.props.style.backgroundImage = `url(${base64})`;
75
78
  }
76
79
  } else {
77
80
  node.props.style.backgroundImage = `url(${withBase(src, `${useNitroOrigin(e)}`)}?${Date.now()})`;
@@ -1,3 +1,3 @@
1
1
  import type { OgImageRenderEventContext, SatoriTransformer, VNode } from '../../../types';
2
- export declare function walkSatoriTree(e: OgImageRenderEventContext, node: VNode, plugins: (SatoriTransformer | SatoriTransformer[])[]): Promise<void>;
2
+ export declare function walkSatoriTree(e: OgImageRenderEventContext, node: VNode, plugins: (SatoriTransformer | SatoriTransformer[])[]): (void | Promise<void>)[];
3
3
  export declare function defineSatoriTransformer(transformer: SatoriTransformer | SatoriTransformer[]): SatoriTransformer | SatoriTransformer[];
@@ -1,19 +1,23 @@
1
- export async function walkSatoriTree(e, node, plugins) {
1
+ export function walkSatoriTree(e, node, plugins) {
2
+ const promises = [];
2
3
  if (!node.props?.children || !Array.isArray(node.props.children))
3
- return;
4
+ return promises;
4
5
  if (node.props.children.length === 0) {
5
6
  delete node.props.children;
6
- return;
7
+ return promises;
7
8
  }
8
9
  for (const child of node.props.children || []) {
9
10
  if (child) {
10
11
  for (const plugin of plugins.flat()) {
11
12
  if (plugin.filter(child))
12
- await plugin.transform(child, e);
13
+ promises.push(plugin.transform(child, e));
13
14
  }
14
- await walkSatoriTree(e, child, plugins);
15
+ promises.push(
16
+ ...walkSatoriTree(e, child, plugins)
17
+ );
15
18
  }
16
19
  }
20
+ return promises;
17
21
  }
18
22
  export function defineSatoriTransformer(transformer) {
19
23
  return transformer;
@@ -21,13 +21,15 @@ export async function createVNodes(ctx) {
21
21
  }
22
22
  const template = `<div style="position: relative; display: flex; margin: 0 auto; width: ${ctx.options.width}px; height: ${ctx.options.height}px; overflow: hidden;">${html}</div>`;
23
23
  const satoriTree = convertHtmlToSatori(template);
24
- await walkSatoriTree(ctx, satoriTree, [
25
- unocss,
24
+ walkSatoriTree(ctx, satoriTree, [
26
25
  emojis,
27
26
  classes,
28
- imageSrc,
29
27
  flex,
30
28
  encoding
31
29
  ]);
30
+ await Promise.all(walkSatoriTree(ctx, satoriTree, [
31
+ unocss,
32
+ imageSrc
33
+ ]));
32
34
  return satoriTree;
33
35
  }
@@ -1,5 +1,5 @@
1
1
  import type { InputFontConfig, OgImageOptions, ResolvedFontConfig } from './types';
2
- export declare function toBase64Image(fileName: string, data: string | ArrayBuffer): string;
2
+ export declare function toBase64Image(data: string | ArrayBuffer): string;
3
3
  export declare function isInternalRoute(path: string): boolean;
4
4
  export declare function separateProps(options: OgImageOptions | undefined, ignoreKeys?: string[]): {
5
5
  props: Record<string, any>;
@@ -1,12 +1,22 @@
1
1
  import { defu } from "defu";
2
- export function toBase64Image(fileName, data) {
2
+ function detectBase64MimeType(data) {
3
+ const signatures = {
4
+ "R0lGODdh": "image/gif",
5
+ "R0lGODlh": "image/gif",
6
+ "iVBORw0KGgo": "image/png",
7
+ "/9j/": "image/jpeg",
8
+ "UklGR": "image/webp",
9
+ "AAABAA": "image/x-icon"
10
+ };
11
+ for (const s in signatures) {
12
+ if (data.indexOf(s) === 0)
13
+ return signatures[s];
14
+ }
15
+ return "image/svg+xml";
16
+ }
17
+ export function toBase64Image(data) {
3
18
  const base64 = typeof data === "string" ? data : Buffer.from(data).toString("base64");
4
- let type = "image/jpeg";
5
- const ext = fileName.split(".").pop();
6
- if (ext === "svg")
7
- type = "image/svg+xml";
8
- else if (ext === "png")
9
- type = "image/png";
19
+ const type = detectBase64MimeType(base64);
10
20
  return `data:${type};base64,${base64}`;
11
21
  }
12
22
  export function isInternalRoute(path) {
@@ -153,7 +153,7 @@ export type OgImagePageScreenshotOptions = Omit<OgImageOptions, 'html' | 'render
153
153
  export type VNode = ReturnType<typeof html>;
154
154
  export interface SatoriTransformer {
155
155
  filter: (node: VNode) => boolean;
156
- transform: (node: VNode, e: OgImageRenderEventContext) => Promise<void>;
156
+ transform: (node: VNode, e: OgImageRenderEventContext) => Promise<void> | void;
157
157
  }
158
158
  export interface SocialPreviewMetaData {
159
159
  twitter?: Record<string, string>;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "3.0.0-rc.52",
5
- "packageManager": "pnpm@8.15.6",
4
+ "version": "3.0.0-rc.53",
5
+ "packageManager": "pnpm@9.0.6",
6
6
  "description": "Enlightened OG Image generation for Nuxt.",
7
7
  "author": {
8
8
  "website": "https://harlanzw.com",
@@ -21,26 +21,26 @@
21
21
  },
22
22
  "exports": {
23
23
  ".": {
24
- "types": "./dist/types.d.ts",
24
+ "types": "./dist/module.d.ts",
25
25
  "import": "./dist/module.mjs",
26
26
  "require": "./dist/module.cjs"
27
27
  }
28
28
  },
29
29
  "main": "./dist/module.cjs",
30
- "types": "./dist/types.d.ts",
30
+ "types": "./dist/module.d.ts",
31
31
  "files": [
32
32
  "dist",
33
33
  "virtual.d.ts"
34
34
  ],
35
35
  "dependencies": {
36
- "@css-inline/css-inline": "0.14.0",
37
- "@css-inline/css-inline-wasm": "0.14.0",
38
- "@nuxt/devtools-kit": "^1.1.5",
36
+ "@css-inline/css-inline": "0.14.1",
37
+ "@css-inline/css-inline-wasm": "0.14.1",
38
+ "@nuxt/devtools-kit": "^1.2.0",
39
39
  "@nuxt/kit": "^3.11.2",
40
40
  "@resvg/resvg-js": "^2.6.2",
41
41
  "@resvg/resvg-wasm": "^2.6.2",
42
- "@unocss/core": "0.59.0",
43
- "@unocss/preset-wind": "0.59.0",
42
+ "@unocss/core": "0.59.4",
43
+ "@unocss/preset-wind": "0.59.4",
44
44
  "@vueuse/core": "^10.9.0",
45
45
  "chrome-launcher": "^1.1.1",
46
46
  "defu": "^6.1.4",
@@ -48,7 +48,7 @@
48
48
  "flatted": "^3.3.1",
49
49
  "floating-vue": "5.2.2",
50
50
  "image-size": "^1.1.1",
51
- "json-editor-vue": "^0.13.0",
51
+ "json-editor-vue": "^0.15.0",
52
52
  "nuxt-icon": "^0.6.10",
53
53
  "nuxt-site-config": "^2.2.12",
54
54
  "nuxt-site-config-kit": "^2.2.12",
@@ -56,56 +56,56 @@
56
56
  "ofetch": "^1.3.4",
57
57
  "ohash": "^1.1.3",
58
58
  "pathe": "^1.1.2",
59
- "pkg-types": "^1.0.3",
60
- "playwright-core": "^1.43.0",
59
+ "pkg-types": "^1.1.0",
60
+ "playwright-core": "^1.43.1",
61
61
  "radix3": "^1.1.2",
62
62
  "satori": "0.10.13",
63
63
  "satori-html": "^0.3.2",
64
- "shiki": "^1.2.4",
64
+ "shiki": "^1.3.0",
65
65
  "sirv": "^2.0.4",
66
66
  "splitpanes": "^3.1.5",
67
67
  "std-env": "^3.7.0",
68
68
  "terminate": "^2.6.1",
69
69
  "ufo": "^1.5.3",
70
70
  "unwasm": "^0.3.9",
71
- "vanilla-jsoneditor": "^0.23.1",
71
+ "vanilla-jsoneditor": "^0.23.2",
72
72
  "yoga-wasm-web": "^0.3.3"
73
73
  },
74
74
  "devDependencies": {
75
- "@antfu/eslint-config": "^2.12.2",
76
- "@headlessui/vue": "^1.7.19",
75
+ "@antfu/eslint-config": "^2.16.0",
76
+ "@headlessui/vue": "^1.7.21",
77
77
  "@iconify-json/carbon": "^1.1.31",
78
78
  "@iconify-json/logos": "^1.1.42",
79
79
  "@iconify-json/noto": "^1.1.18",
80
80
  "@iconify-json/ri": "^1.1.20",
81
- "@iconify-json/tabler": "^1.1.109",
81
+ "@iconify-json/tabler": "^1.1.110",
82
82
  "@img/sharp-linux-x64": "0.33.3",
83
83
  "@nuxt/content": "^2.12.1",
84
- "@nuxt/devtools": "1.1.5",
85
- "@nuxt/devtools-ui-kit": "^1.1.5",
86
- "@nuxt/module-builder": "^0.5.5",
87
- "@nuxt/test-utils": "3.12.0",
88
- "@nuxt/ui": "^2.15.1",
89
- "@nuxtjs/color-mode": "^3.3.3",
84
+ "@nuxt/devtools": "1.2.0",
85
+ "@nuxt/devtools-ui-kit": "^1.2.0",
86
+ "@nuxt/module-builder": "^0.6.0",
87
+ "@nuxt/test-utils": "3.12.1",
88
+ "@nuxt/ui": "^2.15.2",
89
+ "@nuxtjs/color-mode": "^3.4.1",
90
90
  "@nuxtjs/eslint-config-typescript": "^12.1.0",
91
- "@nuxtjs/i18n": "^8.3.0",
92
- "@nuxtjs/tailwindcss": "^6.11.4",
93
- "@unocss/nuxt": "0.59.0",
94
- "@unocss/preset-icons": "0.59.0",
95
- "@unocss/preset-uno": "0.59.0",
96
- "@unocss/runtime": "0.59.0",
91
+ "@nuxtjs/i18n": "^8.3.1",
92
+ "@nuxtjs/tailwindcss": "^6.12.0",
93
+ "@unocss/nuxt": "0.59.4",
94
+ "@unocss/preset-icons": "0.59.4",
95
+ "@unocss/preset-uno": "0.59.4",
96
+ "@unocss/runtime": "0.59.4",
97
97
  "@vueuse/nuxt": "^10.9.0",
98
98
  "bumpp": "^9.4.0",
99
- "eslint": "9.0.0",
99
+ "eslint": "9.1.1",
100
100
  "jest-image-snapshot": "^6.4.0",
101
101
  "nuxt": "^3.11.2",
102
102
  "nuxt-icon": "0.6.10",
103
- "playwright": "^1.43.0",
104
- "sass": "^1.74.1",
103
+ "playwright": "^1.43.1",
104
+ "sass": "^1.75.0",
105
105
  "sharp": "^0.33.3",
106
- "typescript": "^5.4.4",
107
- "unocss": "0.59.0",
108
- "vitest": "^1.4.0"
106
+ "typescript": "^5.4.5",
107
+ "unocss": "0.59.4",
108
+ "vitest": "^1.5.2"
109
109
  },
110
110
  "build": {
111
111
  "externals": [
@@ -129,6 +129,6 @@
129
129
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare .playground && nuxi prepare client",
130
130
  "release": "pnpm build && bumpp && pnpm -r publish --no-git-checks",
131
131
  "typecheck": "tsc --noEmit",
132
- "test": "vitest"
132
+ "test": "vitest integration/endpoints"
133
133
  }
134
134
  }
@@ -1 +0,0 @@
1
- const e=Object.freeze({displayName:"HashiCorp HCL",fileTypes:["hcl"],name:"hcl",patterns:[{include:"#comments"},{include:"#attribute_definition"},{include:"#block"},{include:"#expressions"}],repository:{attribute_access:{begin:"\\.(?!\\*)",beginCaptures:{0:{name:"keyword.operator.accessor.hcl"}},comment:"Matches traversal attribute access such as .attr",end:"[[:alpha:]][\\w-]*|\\d*",endCaptures:{0:{patterns:[{comment:"Attribute name",match:"(?!null|false|true)[[:alpha:]][\\w-]*",name:"variable.other.member.hcl"},{comment:"Optional attribute index",match:"\\d+",name:"constant.numeric.integer.hcl"}]}}},attribute_definition:{captures:{1:{name:"punctuation.section.parens.begin.hcl"},2:{name:"variable.other.readwrite.hcl"},3:{name:"punctuation.section.parens.end.hcl"},4:{name:"keyword.operator.assignment.hcl"}},comment:'Identifier "=" with optional parens',match:"(\\()?(\\b(?!null\\b|false\\b|true\\b)[[:alpha:]][[:alnum:]_-]*)(\\))?\\s*(\\=(?!\\=|\\>))\\s*",name:"variable.declaration.hcl"},attribute_splat:{begin:"\\.",beginCaptures:{0:{name:"keyword.operator.accessor.hcl"}},comment:"Legacy attribute-only splat",end:"\\*",endCaptures:{0:{name:"keyword.operator.splat.hcl"}}},block:{begin:"([\\w][\\-\\w]*)([^?{\\r\\n]*)(\\{)",beginCaptures:{1:{patterns:[{comment:"Block type",match:"\\b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\\b",name:"entity.name.type.hcl"}]},2:{patterns:[{comment:"Block label (String Literal)",match:'\\"[^\\"\\r\\n]*\\"',name:"variable.other.enummember.hcl"},{comment:"Block label (Indentifier)",match:"[[:alpha:]][[:alnum:]_-]*",name:"variable.other.enummember.hcl"}]},3:{name:"punctuation.section.block.begin.hcl"}},comment:'This will match HCL blocks like `thing1 "one" "two" {` or `thing2 {`',end:"\\}",endCaptures:{0:{name:"punctuation.section.block.end.hcl"}},name:"meta.block.hcl",patterns:[{include:"#comments"},{include:"#attribute_definition"},{include:"#expressions"},{include:"#block"}]},block_inline_comments:{begin:"/\\*",captures:{0:{name:"punctuation.definition.comment.hcl"}},comment:"Inline comments start with the /* sequence and end with the */ sequence, and may have any characters within except the ending sequence. An inline comment is considered equivalent to a whitespace sequence",end:"\\*/",name:"comment.block.hcl"},brackets:{begin:"\\[",beginCaptures:{0:{name:"punctuation.section.brackets.begin.hcl"}},end:"\\]",endCaptures:{0:{name:"punctuation.section.brackets.end.hcl"}},patterns:[{comment:"Splat operator",match:"\\*",name:"keyword.operator.splat.hcl"},{include:"#comma"},{include:"#comments"},{include:"#inline_for_expression"},{include:"#inline_if_expression"},{include:"#expressions"},{include:"#local_identifiers"}]},char_escapes:{comment:"Character Escapes",match:'\\\\[nrt"\\\\]|\\\\u(\\h{8}|\\h{4})',name:"constant.character.escape.hcl"},comma:{comment:"Commas - used in certain expressions",match:"\\,",name:"punctuation.separator.hcl"},comments:{patterns:[{include:"#hash_line_comments"},{include:"#double_slash_line_comments"},{include:"#block_inline_comments"}]},double_slash_line_comments:{begin:"//",captures:{0:{name:"punctuation.definition.comment.hcl"}},comment:"Line comments start with // sequence and end with the next newline sequence. A line comment is considered equivalent to a newline sequence",end:"$\\n?",name:"comment.line.double-slash.hcl"},expressions:{patterns:[{include:"#literal_values"},{include:"#operators"},{include:"#tuple_for_expression"},{include:"#object_for_expression"},{include:"#brackets"},{include:"#objects"},{include:"#attribute_access"},{include:"#attribute_splat"},{include:"#functions"},{include:"#parens"}]},for_expression_body:{patterns:[{comment:"in keyword",match:"\\bin\\b",name:"keyword.operator.word.hcl"},{comment:"if keyword",match:"\\bif\\b",name:"keyword.control.conditional.hcl"},{match:"\\:",name:"keyword.operator.hcl"},{include:"#expressions"},{include:"#comments"},{include:"#comma"},{include:"#local_identifiers"}]},functions:{begin:"([:\\-\\w]+)(\\()",beginCaptures:{1:{patterns:[{match:"\\b[[:alpha:]][\\w_-]*::([[:alpha:]][\\w_-]*::)?[[:alpha:]][\\w_-]*\\b",name:"support.function.namespaced.hcl"},{match:"\\b[[:alpha:]][\\w_-]*\\b",name:"support.function.builtin.hcl"}]},2:{name:"punctuation.section.parens.begin.hcl"}},comment:"Built-in function calls",end:"\\)",endCaptures:{0:{name:"punctuation.section.parens.end.hcl"}},name:"meta.function-call.hcl",patterns:[{include:"#comments"},{include:"#expressions"},{include:"#comma"}]},hash_line_comments:{begin:"#",captures:{0:{name:"punctuation.definition.comment.hcl"}},comment:"Line comments start with # sequence and end with the next newline sequence. A line comment is considered equivalent to a newline sequence",end:"$\\n?",name:"comment.line.number-sign.hcl"},hcl_type_keywords:{comment:"Type keywords known to HCL.",match:"\\b(any|string|number|bool|list|set|map|tuple|object)\\b",name:"storage.type.hcl"},heredoc:{begin:"(\\<\\<\\-?)\\s*(\\w+)\\s*$",beginCaptures:{1:{name:"keyword.operator.heredoc.hcl"},2:{name:"keyword.control.heredoc.hcl"}},comment:"String Heredoc",end:"^\\s*\\2\\s*$",endCaptures:{0:{name:"keyword.control.heredoc.hcl"}},name:"string.unquoted.heredoc.hcl",patterns:[{include:"#string_interpolation"}]},inline_for_expression:{begin:"(for)\\b",beginCaptures:{1:{name:"keyword.control.hcl"}},end:"\\n",patterns:[{match:"\\=\\>",name:"storage.type.function.hcl"},{include:"#for_expression_body"}]},inline_if_expression:{begin:"(if)\\b",beginCaptures:{1:{name:"keyword.control.conditional.hcl"}},end:"\\n",patterns:[{include:"#expressions"},{include:"#comments"},{include:"#comma"},{include:"#local_identifiers"}]},language_constants:{comment:"Language Constants",match:"\\b(true|false|null)\\b",name:"constant.language.hcl"},literal_values:{patterns:[{include:"#numeric_literals"},{include:"#language_constants"},{include:"#string_literals"},{include:"#heredoc"},{include:"#hcl_type_keywords"}]},local_identifiers:{comment:"Local Identifiers",match:"\\b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\\b",name:"variable.other.readwrite.hcl"},numeric_literals:{patterns:[{captures:{1:{name:"punctuation.separator.exponent.hcl"}},comment:"Integer, no fraction, optional exponent",match:"\\b\\d+([Ee][+-]?)\\d+\\b",name:"constant.numeric.float.hcl"},{captures:{1:{name:"punctuation.separator.decimal.hcl"},2:{name:"punctuation.separator.exponent.hcl"}},comment:"Integer, fraction, optional exponent",match:"\\b\\d+(\\.)\\d+(?:([Ee][+-]?)\\d+)?\\b",name:"constant.numeric.float.hcl"},{comment:"Integers",match:"\\b\\d+\\b",name:"constant.numeric.integer.hcl"}]},object_for_expression:{begin:"(\\{)\\s?(for)\\b",beginCaptures:{1:{name:"punctuation.section.braces.begin.hcl"},2:{name:"keyword.control.hcl"}},end:"\\}",endCaptures:{0:{name:"punctuation.section.braces.end.hcl"}},patterns:[{match:"\\=\\>",name:"storage.type.function.hcl"},{include:"#for_expression_body"}]},object_key_values:{patterns:[{include:"#comments"},{include:"#literal_values"},{include:"#operators"},{include:"#tuple_for_expression"},{include:"#object_for_expression"},{include:"#heredoc"},{include:"#functions"}]},objects:{begin:"\\{",beginCaptures:{0:{name:"punctuation.section.braces.begin.hcl"}},end:"\\}",endCaptures:{0:{name:"punctuation.section.braces.end.hcl"}},name:"meta.braces.hcl",patterns:[{include:"#comments"},{include:"#objects"},{include:"#inline_for_expression"},{include:"#inline_if_expression"},{captures:{1:{name:"meta.mapping.key.hcl variable.other.readwrite.hcl"},2:{name:"keyword.operator.assignment.hcl"}},comment:"Literal, named object key",match:"\\b((?!null|false|true)[[:alpha:]][[:alnum:]_-]*)\\s*(\\=(?!=))\\s*"},{captures:{1:{name:"meta.mapping.key.hcl string.quoted.double.hcl"},2:{name:"punctuation.definition.string.begin.hcl"},3:{name:"punctuation.definition.string.end.hcl"},4:{name:"keyword.operator.hcl"}},comment:"String object key",match:'^\\s*((").*("))\\s*(\\=)\\s*'},{begin:"^\\s*\\(",beginCaptures:{0:{name:"punctuation.section.parens.begin.hcl"}},comment:"Computed object key (any expression between parens)",end:"(\\))\\s*(=|:)\\s*",endCaptures:{1:{name:"punctuation.section.parens.end.hcl"},2:{name:"keyword.operator.hcl"}},name:"meta.mapping.key.hcl",patterns:[{include:"#attribute_access"},{include:"#attribute_splat"}]},{include:"#object_key_values"}]},operators:{patterns:[{match:"\\>\\=",name:"keyword.operator.hcl"},{match:"\\<\\=",name:"keyword.operator.hcl"},{match:"\\=\\=",name:"keyword.operator.hcl"},{match:"\\!\\=",name:"keyword.operator.hcl"},{match:"\\+",name:"keyword.operator.arithmetic.hcl"},{match:"\\-",name:"keyword.operator.arithmetic.hcl"},{match:"\\*",name:"keyword.operator.arithmetic.hcl"},{match:"\\/",name:"keyword.operator.arithmetic.hcl"},{match:"\\%",name:"keyword.operator.arithmetic.hcl"},{match:"\\&\\&",name:"keyword.operator.logical.hcl"},{match:"\\|\\|",name:"keyword.operator.logical.hcl"},{match:"\\!",name:"keyword.operator.logical.hcl"},{match:"\\>",name:"keyword.operator.hcl"},{match:"\\<",name:"keyword.operator.hcl"},{match:"\\?",name:"keyword.operator.hcl"},{match:"\\.\\.\\.",name:"keyword.operator.hcl"},{match:"\\:",name:"keyword.operator.hcl"},{match:"\\=\\>",name:"keyword.operator.hcl"}]},parens:{begin:"\\(",beginCaptures:{0:{name:"punctuation.section.parens.begin.hcl"}},comment:"Parens - matched *after* function syntax",end:"\\)",endCaptures:{0:{name:"punctuation.section.parens.end.hcl"}},patterns:[{include:"#comments"},{include:"#expressions"}]},string_interpolation:{begin:"(?<![%$])([%$]{)",beginCaptures:{1:{name:"keyword.other.interpolation.begin.hcl"}},comment:"String interpolation",end:"\\}",endCaptures:{0:{name:"keyword.other.interpolation.end.hcl"}},name:"meta.interpolation.hcl",patterns:[{comment:"Trim left whitespace",match:"\\~\\s",name:"keyword.operator.template.left.trim.hcl"},{comment:"Trim right whitespace",match:"\\s\\~",name:"keyword.operator.template.right.trim.hcl"},{comment:"if/else/endif and for/in/endfor directives",match:"\\b(if|else|endif|for|in|endfor)\\b",name:"keyword.control.hcl"},{include:"#expressions"},{include:"#local_identifiers"}]},string_literals:{begin:'"',beginCaptures:{0:{name:"punctuation.definition.string.begin.hcl"}},comment:"Strings",end:'"',endCaptures:{0:{name:"punctuation.definition.string.end.hcl"}},name:"string.quoted.double.hcl",patterns:[{include:"#string_interpolation"},{include:"#char_escapes"}]},tuple_for_expression:{begin:"(\\[)\\s?(for)\\b",beginCaptures:{1:{name:"punctuation.section.brackets.begin.hcl"},2:{name:"keyword.control.hcl"}},end:"\\]",endCaptures:{0:{name:"punctuation.section.brackets.end.hcl"}},patterns:[{include:"#for_expression_body"}]}},scopeName:"source.hcl"});var n=[e];export{n as default};