nuxt-og-image 5.1.12 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/cli.mjs +2 -0
- package/dist/chunks/tw4-classes.cjs +116 -0
- package/dist/chunks/tw4-classes.mjs +113 -0
- package/dist/chunks/tw4-generator.cjs +118 -0
- package/dist/chunks/tw4-generator.mjs +110 -0
- package/dist/cli.cjs +333 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +330 -0
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_fonts/0xp3SbCWC1OhX7q1-uF6kilMZFm-alJNkUtkLTPCy_A-tN9KwPUWhhXvtqh74sU9FIkI4W6hsbm85r0X24hjOfM.woff2 +0 -0
- package/dist/client/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-D6hedAgqRfOCLZzaShnyeAvlEnMzk4Wm7g9WDKWFHIc.woff +0 -0
- package/dist/client/_fonts/4HA9tc4y8BVQeLXvLn3JgQqilAj1xrAnUSprQGHIPSw-ZPswEL_UDOYaxTLQDUySPjoOHDxhD83pD19HMfKfK9s.woff2 +0 -0
- package/dist/client/_fonts/Bmul3LaKlc7BUKqJHE_UmEoF40Sg_2ga52yJjwyDcKs-TnYmYl1DNYkiWMu0Vx49DakCPBuiCCj9zoLIuQjUdKY.woff2 +0 -0
- package/dist/client/_fonts/DfgmjWGpWte3Q3a54Nevr_BYmMM5YEJXRI1CdI2VwO0-ox5RadQfCyVTmKl_hubTaIJjtRw9oaQz2GDBeZR6l1M.woff2 +0 -0
- package/dist/client/_fonts/Lc_5lWuBuZcZ166p1-s-mnGkMJwIYJE_QDCkws8iCkI-r45Qbm2hCykrfOZ0kowz__uTTTUOPDN9hz34QcRNTY4.woff2 +0 -0
- package/dist/client/_fonts/iEvApgDRmzKzNqOYocBTrmcHZmuGAJloawKDP1S0nyE-T3oc_9We24QGwfw5naik4cM0g7VxylWVaQwKm4dy3cw.woff2 +0 -0
- package/dist/client/_nuxt/0kYTU2a7.js +2 -0
- package/dist/client/_nuxt/B0QDx5EE.js +2 -0
- package/dist/client/_nuxt/BKqzYw6x.js +3 -0
- package/dist/client/_nuxt/C-Ivr2Rl.js +1 -0
- package/dist/client/_nuxt/CLgn8DCr.js +1 -0
- package/dist/client/_nuxt/CwWm-XE3.js +1 -0
- package/dist/client/_nuxt/D9eL2h5z.js +1 -0
- package/dist/client/_nuxt/DJXHIJSq.js +1 -0
- package/dist/client/_nuxt/DVnX3Z-O.js +1 -0
- package/dist/client/_nuxt/DXObZt09.js +184 -0
- package/dist/client/_nuxt/Dxi6QG7I.js +1 -0
- package/dist/client/_nuxt/E8AZ6HoH.js +1 -0
- package/dist/client/_nuxt/IFrameLoader.CGrV1TpP.css +1 -0
- package/dist/client/_nuxt/JAMwWy1K.js +3864 -0
- package/dist/client/_nuxt/OSectionBlock.BVHnMsIr.css +1 -0
- package/dist/client/_nuxt/PONEy9N-.js +1 -0
- package/dist/client/_nuxt/UdkqSAsD.js +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/5205806b-8e5a-41ea-90c0-9cd83a75fc0a.json +1 -0
- package/dist/client/_nuxt/entry.BEExJd9R.css +2 -0
- package/dist/client/_nuxt/error-404.B79WD2X-.css +1 -0
- package/dist/client/_nuxt/error-500.DT3Sd0Wu.css +1 -0
- package/dist/client/_nuxt/pages.eW3hi7XF.css +1 -0
- package/dist/client/_nuxt/templates.dUiUBaip.css +1 -0
- package/dist/client/_payload.json +1 -0
- package/dist/client/debug/_payload.json +1 -0
- package/dist/client/debug/index.html +1 -0
- package/dist/client/docs/_payload.json +1 -0
- package/dist/client/docs/index.html +1 -0
- package/dist/client/fonts/HubotSans-Regular.woff2 +0 -0
- package/dist/client/index.html +1 -1
- package/dist/client/templates/_payload.json +1 -0
- package/dist/client/templates/index.html +1 -0
- package/dist/content.cjs +6 -6
- package/dist/content.d.cts +13 -13
- package/dist/content.d.mts +13 -13
- package/dist/content.d.ts +13 -13
- package/dist/content.mjs +1 -1
- package/dist/module.cjs +36 -1025
- package/dist/module.d.cts +63 -23
- package/dist/module.d.mts +63 -23
- package/dist/module.d.ts +63 -23
- package/dist/module.json +1 -1
- package/dist/module.mjs +32 -1007
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.d.vue.ts +14 -0
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.vue +51 -0
- package/dist/runtime/app/components/Templates/Community/Brutalist.satori.vue.d.ts +14 -0
- package/dist/runtime/app/components/Templates/Community/{Frame.vue.d.ts → Frame.satori.d.vue.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/Frame.satori.vue +71 -0
- package/dist/runtime/app/components/Templates/Community/{Frame.d.vue.ts → Frame.satori.vue.d.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.vue +70 -0
- package/dist/runtime/app/components/Templates/Community/Newspaper.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Nuxt.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/{Nuxt.vue → Nuxt.satori.vue} +3 -3
- package/dist/runtime/app/components/Templates/Community/Nuxt.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.vue +69 -0
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Pergel.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/{Pergel.vue → Pergel.satori.vue} +14 -11
- package/dist/runtime/app/components/Templates/Community/Pergel.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.vue +64 -0
- package/dist/runtime/app/components/Templates/Community/Retro.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.d.vue.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.vue +60 -0
- package/dist/runtime/app/components/Templates/Community/SaaS.satori.vue.d.ts +12 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.d.vue.ts +9 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.vue +38 -0
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.satori.vue.d.ts +9 -0
- package/dist/runtime/app/components/Templates/Community/{UnJs.d.vue.ts → UnJs.satori.d.vue.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/{UnJs.vue → UnJs.satori.vue} +41 -33
- package/dist/runtime/app/components/Templates/Community/{UnJs.vue.d.ts → UnJs.satori.vue.d.ts} +2 -2
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.d.vue.ts +13 -0
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.vue +27 -0
- package/dist/runtime/app/components/Templates/Community/WithEmoji.satori.vue.d.ts +13 -0
- package/dist/runtime/app/composables/_defineOgImageRaw.d.ts +6 -0
- package/dist/runtime/app/composables/_defineOgImageRaw.js +70 -0
- package/dist/runtime/app/composables/defineOgImage.d.ts +14 -2
- package/dist/runtime/app/composables/defineOgImage.js +13 -42
- package/dist/runtime/app/composables/defineOgImageComponent.d.ts +5 -1
- package/dist/runtime/app/composables/defineOgImageComponent.js +4 -5
- package/dist/runtime/app/composables/defineOgImageScreenshot.d.ts +1 -1
- package/dist/runtime/app/composables/defineOgImageScreenshot.js +2 -2
- package/dist/runtime/app/composables/mock.d.ts +7 -4
- package/dist/runtime/app/composables/mock.js +4 -4
- package/dist/runtime/app/utils/plugins.js +22 -28
- package/dist/runtime/app/utils.d.ts +15 -1
- package/dist/runtime/app/utils.js +74 -46
- package/dist/runtime/pure.d.ts +7 -0
- package/dist/runtime/pure.js +105 -0
- package/dist/runtime/server/og-image/bindings/css-inline/wasm-fs.d.ts +3 -2
- package/dist/runtime/server/og-image/bindings/css-inline/wasm.d.ts +3 -2
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/cloudflare.js +22 -0
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/dev-prerender.js +49 -0
- package/dist/runtime/server/og-image/bindings/font-assets/node.d.ts +3 -0
- package/dist/runtime/server/og-image/bindings/font-assets/node.js +14 -0
- package/dist/runtime/server/og-image/bindings/resvg/node-dev.d.ts +5 -0
- package/dist/runtime/server/og-image/bindings/resvg/node-dev.js +70 -0
- package/dist/runtime/server/og-image/bindings/satori/wasm-fs.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/satori/wasm-fs.js +4 -8
- package/dist/runtime/server/og-image/bindings/satori/wasm.d.ts +1 -1
- package/dist/runtime/server/og-image/bindings/satori/wasm.js +4 -9
- package/dist/runtime/server/og-image/bindings/takumi/node.d.ts +6 -0
- package/dist/runtime/server/og-image/bindings/takumi/node.js +5 -0
- package/dist/runtime/server/og-image/bindings/takumi/wasm.d.ts +6 -0
- package/dist/runtime/server/og-image/bindings/takumi/wasm.js +6 -0
- package/dist/runtime/server/og-image/cache/buildCache.d.ts +16 -0
- package/dist/runtime/server/og-image/cache/buildCache.js +48 -0
- package/dist/runtime/server/og-image/cache/lru.d.ts +2 -2
- package/dist/runtime/server/og-image/cache/lru.js +3 -3
- package/dist/runtime/server/og-image/cache/mock.d.ts +1 -2
- package/dist/runtime/server/og-image/cache/mock.js +0 -1
- package/dist/runtime/server/og-image/chromium/screenshot.js +4 -3
- package/dist/runtime/server/og-image/context.d.ts +2 -3
- package/dist/runtime/server/og-image/context.js +56 -195
- package/dist/runtime/server/og-image/devtools.d.ts +10 -0
- package/dist/runtime/server/og-image/devtools.js +74 -0
- package/dist/runtime/server/og-image/fonts.d.ts +6 -0
- package/dist/runtime/server/og-image/fonts.js +41 -0
- package/dist/runtime/server/og-image/instances.d.ts +1 -0
- package/dist/runtime/server/og-image/instances.js +5 -0
- package/dist/runtime/server/og-image/satori/instances.d.ts +1 -36
- package/dist/runtime/server/og-image/satori/plugins/emojis.js +83 -4
- package/dist/runtime/server/og-image/satori/plugins/encoding.js +11 -1
- package/dist/runtime/server/og-image/satori/plugins/imageSrc.js +5 -1
- package/dist/runtime/server/og-image/satori/plugins/twClasses.js +35 -0
- package/dist/runtime/server/og-image/satori/renderer.js +16 -53
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-names-minimal.d.ts +1 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-names-minimal.js +223 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.d.ts +45 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/emoji-utils.js +13 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/fetch.d.ts +6 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/fetch.js +38 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/index.d.ts +7 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/index.js +64 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/local.d.ts +7 -0
- package/dist/runtime/server/og-image/satori/transforms/emojis/local.js +32 -0
- package/dist/runtime/server/og-image/satori/utils.js +5 -4
- package/dist/runtime/server/og-image/satori/vnodes.js +7 -6
- package/dist/runtime/server/og-image/takumi/instances.d.ts +1 -0
- package/dist/runtime/server/og-image/takumi/instances.js +6 -0
- package/dist/runtime/server/og-image/takumi/nodes.d.ts +12 -0
- package/dist/runtime/server/og-image/takumi/nodes.js +86 -0
- package/dist/runtime/server/og-image/takumi/renderer.d.ts +3 -0
- package/dist/runtime/server/og-image/takumi/renderer.js +45 -0
- package/dist/runtime/server/og-image/templates/html.js +32 -23
- package/dist/runtime/server/plugins/prerender.d.ts +1 -1
- package/dist/runtime/server/plugins/prerender.js +17 -7
- package/dist/runtime/server/util/auto-eject.d.ts +2 -0
- package/dist/runtime/server/util/auto-eject.js +30 -0
- package/dist/runtime/server/util/eventHandlers.d.ts +0 -1
- package/dist/runtime/server/util/eventHandlers.js +15 -85
- package/dist/runtime/server/util/options.d.ts +7 -2
- package/dist/runtime/server/util/options.js +40 -6
- package/dist/runtime/server/util/wasm.d.ts +1 -1
- package/dist/runtime/server/utils.d.ts +6 -2
- package/dist/runtime/server/utils.js +12 -8
- package/dist/runtime/shared/urlEncoding.d.ts +64 -0
- package/dist/runtime/shared/urlEncoding.js +194 -0
- package/dist/runtime/shared.d.ts +4 -9
- package/dist/runtime/shared.js +31 -50
- package/dist/runtime/types.d.ts +71 -25
- package/dist/shared/nuxt-og-image.DroaQ3v-.cjs +2852 -0
- package/dist/shared/nuxt-og-image.HMyihp-D.mjs +2825 -0
- package/dist/types.d.mts +2 -0
- package/package.json +119 -56
- package/types/virtual.d.ts +7 -1
- package/dist/client/_nuxt/B8PEiB0p.js +0 -1
- package/dist/client/_nuxt/CD9VIl4i.js +0 -4062
- package/dist/client/_nuxt/CI_lqgv7.js +0 -1
- package/dist/client/_nuxt/CVO1_9PV.js +0 -1
- package/dist/client/_nuxt/Cp-IABpG.js +0 -1
- package/dist/client/_nuxt/D0r3Knsf.js +0 -1
- package/dist/client/_nuxt/Dz8kdfgF.js +0 -1
- package/dist/client/_nuxt/builds/meta/71b0f7ea-9aae-4c28-bbd9-8eea71b82dfb.json +0 -1
- package/dist/client/_nuxt/entry.DNM8P-MU.css +0 -1
- package/dist/client/_nuxt/error-404.C2mGI6Vt.css +0 -1
- package/dist/client/_nuxt/error-500.ClHbVBiL.css +0 -1
- package/dist/client/_nuxt/l5rcX3cq.js +0 -8
- package/dist/runtime/app/components/OgImage/OgImage.d.ts +0 -3
- package/dist/runtime/app/components/OgImage/OgImage.js +0 -10
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.d.vue.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue +0 -22
- package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue.d.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/Frame.vue +0 -58
- package/dist/runtime/app/components/Templates/Community/Nuxt.d.vue.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/Nuxt.vue.d.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.d.vue.ts +0 -15
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue +0 -103
- package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue.d.ts +0 -15
- package/dist/runtime/app/components/Templates/Community/Pergel.d.vue.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/Pergel.vue.d.ts +0 -12
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.d.vue.ts +0 -9
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue +0 -27
- package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue.d.ts +0 -9
- package/dist/runtime/app/components/Templates/Community/Wave.d.vue.ts +0 -11
- package/dist/runtime/app/components/Templates/Community/Wave.vue +0 -28
- package/dist/runtime/app/components/Templates/Community/Wave.vue.d.ts +0 -11
- package/dist/runtime/app/components/Templates/Community/WithEmoji.d.vue.ts +0 -13
- package/dist/runtime/app/components/Templates/Community/WithEmoji.vue +0 -21
- package/dist/runtime/app/components/Templates/Community/WithEmoji.vue.d.ts +0 -13
- package/dist/runtime/assets/Inter-normal-400.ttf.base64 +0 -1
- package/dist/runtime/assets/Inter-normal-700.ttf.base64 +0 -1
- package/dist/runtime/server/og-image/satori/font.d.ts +0 -3
- package/dist/runtime/server/og-image/satori/font.js +0 -40
- package/dist/runtime/server/og-image/satori/plugins/unocss.js +0 -55
- package/dist/runtime/server/og-image/satori/transforms/emojis.d.ts +0 -3
- package/dist/runtime/server/og-image/satori/transforms/emojis.js +0 -3595
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.d.ts +0 -2
- package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.js +0 -9
- package/dist/runtime/server/plugins/nuxt-content-v2.d.ts +0 -2
- package/dist/runtime/server/plugins/nuxt-content-v2.js +0 -5
- package/dist/runtime/server/routes/__zero-runtime/font.d.ts +0 -2
- package/dist/runtime/server/routes/__zero-runtime/font.js +0 -8
- package/dist/runtime/server/routes/font.d.ts +0 -2
- package/dist/runtime/server/routes/font.js +0 -3
- package/dist/runtime/server/util/plugins.d.ts +0 -2
- package/dist/runtime/server/util/plugins.js +0 -56
- /package/dist/runtime/server/og-image/satori/plugins/{unocss.d.ts → twClasses.d.ts} +0 -0
|
@@ -1,11 +1,90 @@
|
|
|
1
|
+
import { getEmojiSvg } from "#og-image/emoji-transform";
|
|
2
|
+
import { html as convertHtmlToSatori } from "satori-html";
|
|
3
|
+
import { RE_MATCH_EMOJIS } from "../transforms/emojis/emoji-utils.js";
|
|
1
4
|
import { defineSatoriTransformer } from "../utils.js";
|
|
2
|
-
function
|
|
5
|
+
function isEmojiSvg(node) {
|
|
3
6
|
return node.type === "svg" && typeof node.props?.["data-emoji"] !== "undefined";
|
|
4
7
|
}
|
|
5
8
|
export default defineSatoriTransformer([
|
|
6
|
-
//
|
|
9
|
+
// Transform text nodes that contain emojis to replace them with SVG nodes
|
|
7
10
|
{
|
|
8
|
-
filter: (node) =>
|
|
11
|
+
filter: (node) => {
|
|
12
|
+
if (typeof node.props?.children !== "string")
|
|
13
|
+
return false;
|
|
14
|
+
RE_MATCH_EMOJIS.lastIndex = 0;
|
|
15
|
+
return RE_MATCH_EMOJIS.test(node.props.children);
|
|
16
|
+
},
|
|
17
|
+
transform: async (node, ctx) => {
|
|
18
|
+
const text = node.props.children;
|
|
19
|
+
RE_MATCH_EMOJIS.lastIndex = 0;
|
|
20
|
+
const matches = [...text.matchAll(RE_MATCH_EMOJIS)];
|
|
21
|
+
if (!matches.length)
|
|
22
|
+
return;
|
|
23
|
+
const children = [];
|
|
24
|
+
let lastIndex = 0;
|
|
25
|
+
for (const match of matches) {
|
|
26
|
+
const emoji = match[0];
|
|
27
|
+
const emojiIndex = match.index;
|
|
28
|
+
if (emojiIndex > lastIndex) {
|
|
29
|
+
const beforeText = text.slice(lastIndex, emojiIndex);
|
|
30
|
+
if (beforeText)
|
|
31
|
+
children.push(beforeText);
|
|
32
|
+
}
|
|
33
|
+
const svg = await getEmojiSvg(ctx, emoji);
|
|
34
|
+
if (svg) {
|
|
35
|
+
const parsedNode = convertHtmlToSatori(svg);
|
|
36
|
+
const nodeChildren = parsedNode?.props?.children;
|
|
37
|
+
if (nodeChildren?.[0]) {
|
|
38
|
+
const svgNode = nodeChildren[0];
|
|
39
|
+
if (svgNode.props) {
|
|
40
|
+
svgNode.props["data-emoji"] = true;
|
|
41
|
+
const existingStyle = svgNode.props.style || {};
|
|
42
|
+
if (existingStyle.display === "inline-block")
|
|
43
|
+
delete existingStyle.display;
|
|
44
|
+
svgNode.props.style = {
|
|
45
|
+
...existingStyle,
|
|
46
|
+
width: "1em",
|
|
47
|
+
height: "1em"
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
children.push(svgNode);
|
|
51
|
+
} else {
|
|
52
|
+
children.push(emoji);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
children.push(emoji);
|
|
56
|
+
}
|
|
57
|
+
lastIndex = emojiIndex + emoji.length;
|
|
58
|
+
}
|
|
59
|
+
if (lastIndex < text.length) {
|
|
60
|
+
const afterText = text.slice(lastIndex);
|
|
61
|
+
if (afterText)
|
|
62
|
+
children.push(afterText);
|
|
63
|
+
}
|
|
64
|
+
if (children.length >= 1) {
|
|
65
|
+
const vnodeChildren = children.map((child) => {
|
|
66
|
+
if (typeof child === "string") {
|
|
67
|
+
return {
|
|
68
|
+
type: "div",
|
|
69
|
+
props: {
|
|
70
|
+
children: child
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return child;
|
|
75
|
+
});
|
|
76
|
+
node.props.children = vnodeChildren;
|
|
77
|
+
node.props.style = node.props.style || {};
|
|
78
|
+
node.props.style.display = "flex";
|
|
79
|
+
node.props.style.alignItems = "center";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
// Keep the existing logic for styling containers with emoji SVGs
|
|
84
|
+
{
|
|
85
|
+
filter: (node) => ["div", "p"].includes(node.type) && Array.isArray(node.props?.children) && node.props.children.some(
|
|
86
|
+
(child) => child.type === "svg" && child.props?.["data-emoji"] || isEmojiSvg(child)
|
|
87
|
+
),
|
|
9
88
|
transform: (node) => {
|
|
10
89
|
node.props.style = node.props.style || {};
|
|
11
90
|
node.props.style.display = "flex";
|
|
@@ -19,7 +98,7 @@ export default defineSatoriTransformer([
|
|
|
19
98
|
}
|
|
20
99
|
};
|
|
21
100
|
}
|
|
22
|
-
if (child.props
|
|
101
|
+
if (child.props?.class?.includes("emoji"))
|
|
23
102
|
delete child.props.class;
|
|
24
103
|
return child;
|
|
25
104
|
});
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import { decodeHtml } from "../../../util/encoding.js";
|
|
2
2
|
import { defineSatoriTransformer } from "../utils.js";
|
|
3
3
|
export default defineSatoriTransformer([
|
|
4
|
-
// clean up
|
|
4
|
+
// clean up vue inspector data attributes
|
|
5
5
|
{
|
|
6
6
|
filter: (node) => node.props?.["data-v-inspector"],
|
|
7
7
|
transform: (node) => {
|
|
8
8
|
delete node.props["data-v-inspector"];
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
+
// decode HTML entities in string children
|
|
11
12
|
{
|
|
12
13
|
filter: (node) => typeof node.props?.children === "string",
|
|
13
14
|
transform: (node) => {
|
|
14
15
|
node.props.children = decodeHtml(node.props.children);
|
|
15
16
|
}
|
|
17
|
+
},
|
|
18
|
+
// decode HTML entities in array children (text nodes with siblings)
|
|
19
|
+
{
|
|
20
|
+
filter: (node) => Array.isArray(node.props?.children),
|
|
21
|
+
transform: (node) => {
|
|
22
|
+
node.props.children = node.props.children.map(
|
|
23
|
+
(child) => typeof child === "string" ? decodeHtml(child) : child
|
|
24
|
+
);
|
|
25
|
+
}
|
|
16
26
|
}
|
|
17
27
|
]);
|
|
@@ -9,7 +9,7 @@ import { defineSatoriTransformer } from "../utils.js";
|
|
|
9
9
|
async function resolveLocalFilePathImage(publicStoragePath, src) {
|
|
10
10
|
const normalizedSrc = withoutLeadingSlash(
|
|
11
11
|
src.replace("_nuxt/@fs/", "").replace("_nuxt/", "").replace("./", "")
|
|
12
|
-
);
|
|
12
|
+
).replaceAll("/", ":");
|
|
13
13
|
const key = `${publicStoragePath}:${normalizedSrc}`;
|
|
14
14
|
if (await useStorage().hasItem(key))
|
|
15
15
|
return await useStorage().getItemRaw(key);
|
|
@@ -54,6 +54,10 @@ export default defineSatoriTransformer([
|
|
|
54
54
|
}).catch(() => {
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
if (typeof node.props.width === "string")
|
|
58
|
+
node.props.width = Number(node.props.width) || void 0;
|
|
59
|
+
if (typeof node.props.height === "string")
|
|
60
|
+
node.props.height = Number(node.props.height) || void 0;
|
|
57
61
|
if (imageBuffer && (!node.props.width || !node.props.height)) {
|
|
58
62
|
try {
|
|
59
63
|
const imageSize = sizeOf(imageBuffer);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { tw4Breakpoints } from "#og-image-virtual/tw4-theme.mjs";
|
|
2
|
+
import { defineSatoriTransformer } from "../utils.js";
|
|
3
|
+
const DEFAULT_BREAKPOINTS = {
|
|
4
|
+
"sm": 640,
|
|
5
|
+
"md": 768,
|
|
6
|
+
"lg": 1024,
|
|
7
|
+
"xl": 1280,
|
|
8
|
+
"2xl": 1536
|
|
9
|
+
};
|
|
10
|
+
const BREAKPOINTS = { ...DEFAULT_BREAKPOINTS, ...tw4Breakpoints };
|
|
11
|
+
const RESPONSIVE_PREFIX_RE = /^(sm|md|lg|xl|2xl):(.+)$/;
|
|
12
|
+
export default defineSatoriTransformer({
|
|
13
|
+
filter: (node) => !!node.props?.class,
|
|
14
|
+
transform: (node, ctx) => {
|
|
15
|
+
const classes = node.props.class || "";
|
|
16
|
+
const renderWidth = Number(ctx.options.width) || 1200;
|
|
17
|
+
const processedClasses = [];
|
|
18
|
+
for (const token of classes.split(" ").filter((c) => c.trim())) {
|
|
19
|
+
const match = token.match(RESPONSIVE_PREFIX_RE);
|
|
20
|
+
if (match) {
|
|
21
|
+
const bp = match[1];
|
|
22
|
+
const baseClass = match[2];
|
|
23
|
+
const breakpointWidth = BREAKPOINTS[bp];
|
|
24
|
+
if (breakpointWidth && renderWidth >= breakpointWidth) {
|
|
25
|
+
processedClasses.push(baseClass);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
processedClasses.push(token);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const twClasses = processedClasses.join(" ");
|
|
32
|
+
node.props.tw = twClasses;
|
|
33
|
+
node.props.class = twClasses;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
@@ -1,59 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { theme } from "#og-image-virtual/unocss-config.mjs";
|
|
1
|
+
import { tw4FontVars } from "#og-image-virtual/tw4-theme.mjs";
|
|
3
2
|
import compatibility from "#og-image/compatibility";
|
|
4
3
|
import { defu } from "defu";
|
|
5
4
|
import { sendError } from "h3";
|
|
6
|
-
import { normaliseFontInput } from "../../../shared.js";
|
|
7
5
|
import { useOgImageRuntimeConfig } from "../../utils.js";
|
|
8
|
-
import {
|
|
6
|
+
import { loadAllFonts } from "../fonts.js";
|
|
9
7
|
import { useResvg, useSatori, useSharp } from "./instances.js";
|
|
10
8
|
import { createVNodes } from "./vnodes.js";
|
|
11
|
-
const fontPromises = {};
|
|
12
|
-
async function resolveFonts(event) {
|
|
13
|
-
const { fonts } = useOgImageRuntimeConfig();
|
|
14
|
-
const normalisedFonts = normaliseFontInput([...event.options.fonts || [], ...fonts]);
|
|
15
|
-
const localFontPromises = [];
|
|
16
|
-
const preloadedFonts = [];
|
|
17
|
-
if (fontCache) {
|
|
18
|
-
for (const font of normalisedFonts) {
|
|
19
|
-
if (await fontCache.hasItem(font.cacheKey)) {
|
|
20
|
-
font.data = await fontCache.getItemRaw(font.cacheKey) || void 0;
|
|
21
|
-
preloadedFonts.push(font);
|
|
22
|
-
} else {
|
|
23
|
-
if (!fontPromises[font.cacheKey]) {
|
|
24
|
-
fontPromises[font.cacheKey] = loadFont(event, font).then(async (_font) => {
|
|
25
|
-
if (_font?.data)
|
|
26
|
-
await fontCache?.setItemRaw(_font.cacheKey, _font.data);
|
|
27
|
-
return _font;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
localFontPromises.push(fontPromises[font.cacheKey]);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
const awaitedFonts = await Promise.all(localFontPromises);
|
|
35
|
-
return [...preloadedFonts, ...awaitedFonts].map((_f) => {
|
|
36
|
-
return { name: _f.name, data: _f.data, style: _f.style, weight: Number(_f.weight) };
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
9
|
export async function createSvg(event) {
|
|
40
10
|
const { options } = event;
|
|
41
11
|
const { satoriOptions: _satoriOptions } = useOgImageRuntimeConfig();
|
|
42
12
|
const [satori, vnodes, fonts] = await Promise.all([
|
|
43
13
|
useSatori(),
|
|
44
14
|
createVNodes(event),
|
|
45
|
-
|
|
15
|
+
loadAllFonts(event.e, { supportsWoff2: false })
|
|
46
16
|
]);
|
|
47
17
|
await event._nitro.hooks.callHook("nuxt-og-image:satori:vnodes", vnodes, event);
|
|
18
|
+
const fontFamily = {};
|
|
19
|
+
if (tw4FontVars["font-sans"])
|
|
20
|
+
fontFamily.sans = tw4FontVars["font-sans"];
|
|
21
|
+
if (tw4FontVars["font-serif"])
|
|
22
|
+
fontFamily.serif = tw4FontVars["font-serif"];
|
|
23
|
+
if (tw4FontVars["font-mono"])
|
|
24
|
+
fontFamily.mono = tw4FontVars["font-mono"];
|
|
48
25
|
const satoriOptions = defu(options.satori, _satoriOptions, {
|
|
49
26
|
fonts,
|
|
50
|
-
tailwindConfig: { theme },
|
|
27
|
+
tailwindConfig: Object.keys(fontFamily).length ? { theme: { fontFamily } } : void 0,
|
|
51
28
|
embedFont: true,
|
|
52
29
|
width: options.width,
|
|
53
30
|
height: options.height
|
|
54
31
|
});
|
|
55
32
|
return satori(vnodes, satoriOptions).catch((err) => {
|
|
56
|
-
return sendError(event.e, err,
|
|
33
|
+
return sendError(event.e, err, true);
|
|
57
34
|
});
|
|
58
35
|
}
|
|
59
36
|
async function createPng(event) {
|
|
@@ -61,23 +38,16 @@ async function createPng(event) {
|
|
|
61
38
|
const svg = await createSvg(event);
|
|
62
39
|
if (!svg)
|
|
63
40
|
throw new Error("Failed to create SVG");
|
|
41
|
+
const options = defu(event.options.resvg, resvgOptions);
|
|
64
42
|
const Resvg = await useResvg();
|
|
65
|
-
const resvg = new Resvg(svg,
|
|
66
|
-
event.options.resvg,
|
|
67
|
-
resvgOptions
|
|
68
|
-
));
|
|
43
|
+
const resvg = new Resvg(svg, options);
|
|
69
44
|
const pngData = resvg.render();
|
|
70
45
|
return pngData.asPng();
|
|
71
46
|
}
|
|
72
47
|
async function createJpeg(event) {
|
|
73
48
|
const { sharpOptions } = useOgImageRuntimeConfig();
|
|
74
49
|
if (compatibility.sharp === false) {
|
|
75
|
-
|
|
76
|
-
throw new Error("Sharp dependency is not accessible. Please check you have it installed and are using a compatible runtime.");
|
|
77
|
-
} else {
|
|
78
|
-
console.error("Sharp dependency is not accessible. Please check you have it installed and are using a compatible runtime. Falling back to png.");
|
|
79
|
-
}
|
|
80
|
-
return createPng(event);
|
|
50
|
+
throw new Error("Sharp dependency is not accessible. Please check you have it installed and are using a compatible runtime.");
|
|
81
51
|
}
|
|
82
52
|
const svg = await createSvg(event);
|
|
83
53
|
if (!svg) {
|
|
@@ -85,15 +55,8 @@ async function createJpeg(event) {
|
|
|
85
55
|
}
|
|
86
56
|
const svgBuffer = Buffer.from(svg);
|
|
87
57
|
const sharp = await useSharp().catch(() => {
|
|
88
|
-
|
|
89
|
-
throw new Error("Sharp dependency could not be loaded. Please check you have it installed and are using a compatible runtime.");
|
|
90
|
-
}
|
|
91
|
-
return null;
|
|
58
|
+
throw new Error("Sharp dependency could not be loaded. Please check you have it installed and are using a compatible runtime.");
|
|
92
59
|
});
|
|
93
|
-
if (!sharp) {
|
|
94
|
-
console.error("Sharp dependency is not accessible. Please check you have it installed and are using a compatible runtime. Falling back to png.");
|
|
95
|
-
return createPng(event);
|
|
96
|
-
}
|
|
97
60
|
const options = defu(event.options.sharp, sharpOptions);
|
|
98
61
|
return sharp(svgBuffer, options).jpeg(options).toBuffer();
|
|
99
62
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const EMOJI_CODEPOINT_TO_NAME: Record<string, string>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
export const EMOJI_CODEPOINT_TO_NAME = {
|
|
2
|
+
// Faces - most popular
|
|
3
|
+
"1f600": "grinning-face",
|
|
4
|
+
"1f603": "grinning-face-with-big-eyes",
|
|
5
|
+
"1f604": "grinning-face-with-smiling-eyes",
|
|
6
|
+
"1f601": "beaming-face-with-smiling-eyes",
|
|
7
|
+
"1f606": "grinning-squinting-face",
|
|
8
|
+
"1f605": "grinning-face-with-sweat",
|
|
9
|
+
"1f602": "face-with-tears-of-joy",
|
|
10
|
+
"1f923": "rolling-on-the-floor-laughing",
|
|
11
|
+
"1f60a": "smiling-face-with-smiling-eyes",
|
|
12
|
+
"1f607": "smiling-face-with-halo",
|
|
13
|
+
"1f970": "smiling-face-with-hearts",
|
|
14
|
+
"1f60d": "smiling-face-with-heart-eyes",
|
|
15
|
+
"1f929": "star-struck",
|
|
16
|
+
"1f618": "face-blowing-a-kiss",
|
|
17
|
+
"1f617": "kissing-face",
|
|
18
|
+
"1f619": "kissing-face-with-smiling-eyes",
|
|
19
|
+
"1f61a": "kissing-face-with-closed-eyes",
|
|
20
|
+
"1f60b": "face-savoring-food",
|
|
21
|
+
"1f61b": "face-with-tongue",
|
|
22
|
+
"1f61c": "winking-face-with-tongue",
|
|
23
|
+
"1f92a": "zany-face",
|
|
24
|
+
"1f61d": "squinting-face-with-tongue",
|
|
25
|
+
"1f911": "money-mouth-face",
|
|
26
|
+
"1f917": "smiling-face-with-open-hands",
|
|
27
|
+
"1f92d": "face-with-hand-over-mouth",
|
|
28
|
+
"1f92b": "shushing-face",
|
|
29
|
+
"1f914": "thinking-face",
|
|
30
|
+
"1f910": "zipper-mouth-face",
|
|
31
|
+
"1f928": "face-with-raised-eyebrow",
|
|
32
|
+
"1f610": "neutral-face",
|
|
33
|
+
"1f611": "expressionless-face",
|
|
34
|
+
"1f636": "face-without-mouth",
|
|
35
|
+
"1f60f": "smirking-face",
|
|
36
|
+
"1f612": "unamused-face",
|
|
37
|
+
"1f644": "face-with-rolling-eyes",
|
|
38
|
+
"1f62c": "grimacing-face",
|
|
39
|
+
"1f925": "lying-face",
|
|
40
|
+
"1f60c": "relieved-face",
|
|
41
|
+
"1f614": "pensive-face",
|
|
42
|
+
"1f62a": "sleepy-face",
|
|
43
|
+
"1f924": "drooling-face",
|
|
44
|
+
"1f634": "sleeping-face",
|
|
45
|
+
"1f637": "face-with-medical-mask",
|
|
46
|
+
"1f912": "face-with-thermometer",
|
|
47
|
+
"1f915": "face-with-head-bandage",
|
|
48
|
+
"1f922": "nauseated-face",
|
|
49
|
+
"1f92e": "face-vomiting",
|
|
50
|
+
"1f927": "sneezing-face",
|
|
51
|
+
"1f975": "hot-face",
|
|
52
|
+
"1f976": "cold-face",
|
|
53
|
+
"1f974": "woozy-face",
|
|
54
|
+
"1f635": "knocked-out-face",
|
|
55
|
+
"1f92f": "exploding-head",
|
|
56
|
+
"1f920": "cowboy-hat-face",
|
|
57
|
+
"1f973": "partying-face",
|
|
58
|
+
"1f60e": "smiling-face-with-sunglasses",
|
|
59
|
+
"1f913": "nerd-face",
|
|
60
|
+
"1f9d0": "face-with-monocle",
|
|
61
|
+
// Gestures
|
|
62
|
+
"1f44b": "waving-hand",
|
|
63
|
+
"1f44d": "thumbs-up",
|
|
64
|
+
"1f44e": "thumbs-down",
|
|
65
|
+
"1f44f": "clapping-hands",
|
|
66
|
+
"1f64c": "raising-hands",
|
|
67
|
+
"1f64f": "folded-hands",
|
|
68
|
+
"1f4aa": "flexed-biceps",
|
|
69
|
+
"270c": "victory-hand",
|
|
70
|
+
"1f91e": "crossed-fingers",
|
|
71
|
+
"1f918": "sign-of-the-horns",
|
|
72
|
+
"1f919": "call-me-hand",
|
|
73
|
+
"1f448": "backhand-index-pointing-left",
|
|
74
|
+
"1f449": "backhand-index-pointing-right",
|
|
75
|
+
"1f446": "backhand-index-pointing-up",
|
|
76
|
+
"1f447": "backhand-index-pointing-down",
|
|
77
|
+
"261d": "index-pointing-up",
|
|
78
|
+
"270b": "raised-hand",
|
|
79
|
+
"1f91a": "raised-back-of-hand",
|
|
80
|
+
"1f590": "hand-with-fingers-splayed",
|
|
81
|
+
"1f596": "vulcan-salute",
|
|
82
|
+
"1f44c": "ok-hand",
|
|
83
|
+
// Hearts & Symbols
|
|
84
|
+
"2764": "red-heart",
|
|
85
|
+
"1f9e1": "orange-heart",
|
|
86
|
+
"1f49b": "yellow-heart",
|
|
87
|
+
"1f49a": "green-heart",
|
|
88
|
+
"1f499": "blue-heart",
|
|
89
|
+
"1f49c": "purple-heart",
|
|
90
|
+
"1f5a4": "black-heart",
|
|
91
|
+
"1f90d": "white-heart",
|
|
92
|
+
"1f90e": "brown-heart",
|
|
93
|
+
"1f494": "broken-heart",
|
|
94
|
+
"1f495": "two-hearts",
|
|
95
|
+
"1f496": "sparkling-heart",
|
|
96
|
+
"1f497": "growing-heart",
|
|
97
|
+
"1f498": "heart-with-arrow",
|
|
98
|
+
"1f49d": "heart-with-ribbon",
|
|
99
|
+
"1f49e": "revolving-hearts",
|
|
100
|
+
"1f49f": "heart-decoration",
|
|
101
|
+
// Popular Objects & Symbols
|
|
102
|
+
"1f680": "rocket",
|
|
103
|
+
"26a1": "high-voltage",
|
|
104
|
+
"1f525": "fire",
|
|
105
|
+
"2728": "sparkles",
|
|
106
|
+
"1f31f": "glowing-star",
|
|
107
|
+
"2b50": "star",
|
|
108
|
+
"1f4a5": "collision",
|
|
109
|
+
"1f4a1": "light-bulb",
|
|
110
|
+
"1f389": "party-popper",
|
|
111
|
+
"1f38a": "confetti-ball",
|
|
112
|
+
"1f381": "wrapped-gift",
|
|
113
|
+
"1f3c6": "trophy",
|
|
114
|
+
"1f3c5": "1st-place-medal",
|
|
115
|
+
"1f947": "1st-place-medal",
|
|
116
|
+
"1f4af": "hundred-points",
|
|
117
|
+
"2705": "check-mark-button",
|
|
118
|
+
"274c": "cross-mark",
|
|
119
|
+
"2714": "check-mark",
|
|
120
|
+
"2795": "plus",
|
|
121
|
+
"2796": "minus",
|
|
122
|
+
"2716": "multiply",
|
|
123
|
+
"27a1": "right-arrow",
|
|
124
|
+
"2b05": "left-arrow",
|
|
125
|
+
"2b06": "up-arrow",
|
|
126
|
+
"2b07": "down-arrow",
|
|
127
|
+
// Tech & Work
|
|
128
|
+
"1f4bb": "laptop",
|
|
129
|
+
"1f4f1": "mobile-phone",
|
|
130
|
+
"2699": "gear",
|
|
131
|
+
"1f527": "wrench",
|
|
132
|
+
"1f528": "hammer",
|
|
133
|
+
"1f529": "nut-and-bolt",
|
|
134
|
+
"1f6e0": "hammer-and-wrench",
|
|
135
|
+
"1f4e6": "package",
|
|
136
|
+
"1f4dd": "memo",
|
|
137
|
+
"1f4c8": "chart-increasing",
|
|
138
|
+
"1f4c9": "chart-decreasing",
|
|
139
|
+
"1f4ca": "bar-chart",
|
|
140
|
+
"1f4cb": "clipboard",
|
|
141
|
+
"1f4cc": "pushpin",
|
|
142
|
+
"1f4cd": "round-pushpin",
|
|
143
|
+
"1f4ce": "paperclip",
|
|
144
|
+
"1f4cf": "straight-ruler",
|
|
145
|
+
"1f4d0": "triangular-ruler",
|
|
146
|
+
"1f50d": "magnifying-glass-tilted-left",
|
|
147
|
+
"1f50e": "magnifying-glass-tilted-right",
|
|
148
|
+
"1f512": "locked",
|
|
149
|
+
"1f513": "unlocked",
|
|
150
|
+
// Nature & Weather
|
|
151
|
+
"2600": "sun",
|
|
152
|
+
"1f31e": "sun-with-face",
|
|
153
|
+
"1f319": "crescent-moon",
|
|
154
|
+
"1f308": "rainbow",
|
|
155
|
+
"2601": "cloud",
|
|
156
|
+
"26c5": "sun-behind-cloud",
|
|
157
|
+
"1f327": "cloud-with-rain",
|
|
158
|
+
"26c8": "cloud-with-lightning-and-rain",
|
|
159
|
+
"1f329": "cloud-with-lightning",
|
|
160
|
+
"2744": "snowflake",
|
|
161
|
+
"1f4a7": "droplet",
|
|
162
|
+
"1f30a": "water-wave",
|
|
163
|
+
// Animals
|
|
164
|
+
"1f436": "dog-face",
|
|
165
|
+
"1f431": "cat-face",
|
|
166
|
+
"1f42d": "mouse-face",
|
|
167
|
+
"1f430": "rabbit-face",
|
|
168
|
+
"1f43b": "bear",
|
|
169
|
+
"1f43c": "panda",
|
|
170
|
+
"1f428": "koala",
|
|
171
|
+
"1f42f": "tiger-face",
|
|
172
|
+
"1f981": "lion",
|
|
173
|
+
"1f984": "unicorn",
|
|
174
|
+
"1f98b": "butterfly",
|
|
175
|
+
"1f41d": "honeybee",
|
|
176
|
+
"1f577": "spider",
|
|
177
|
+
"1f427": "penguin",
|
|
178
|
+
"1f426": "bird",
|
|
179
|
+
"1f985": "eagle",
|
|
180
|
+
"1f419": "octopus",
|
|
181
|
+
"1f422": "turtle",
|
|
182
|
+
"1f40d": "snake",
|
|
183
|
+
"1f409": "dragon",
|
|
184
|
+
"1f432": "dragon-face",
|
|
185
|
+
// Food
|
|
186
|
+
"1f34e": "red-apple",
|
|
187
|
+
"1f34a": "tangerine",
|
|
188
|
+
"1f34b": "lemon",
|
|
189
|
+
"1f34c": "banana",
|
|
190
|
+
"1f34d": "pineapple",
|
|
191
|
+
"1f347": "grapes",
|
|
192
|
+
"1f353": "strawberry",
|
|
193
|
+
"1f352": "cherries",
|
|
194
|
+
"1f351": "peach",
|
|
195
|
+
"1f349": "watermelon",
|
|
196
|
+
"1f96d": "mango",
|
|
197
|
+
"1f951": "avocado",
|
|
198
|
+
"1f955": "carrot",
|
|
199
|
+
"1f33d": "ear-of-corn",
|
|
200
|
+
"1f336": "hot-pepper",
|
|
201
|
+
"1f355": "pizza",
|
|
202
|
+
"1f354": "hamburger",
|
|
203
|
+
"1f35f": "french-fries",
|
|
204
|
+
"1f32d": "hot-dog",
|
|
205
|
+
"1f32e": "taco",
|
|
206
|
+
"1f32f": "burrito",
|
|
207
|
+
"1f37f": "popcorn",
|
|
208
|
+
"1f36a": "cookie",
|
|
209
|
+
"1f382": "birthday-cake",
|
|
210
|
+
"1f370": "shortcake",
|
|
211
|
+
"1f36b": "chocolate-bar",
|
|
212
|
+
"1f36c": "candy",
|
|
213
|
+
"1f36d": "lollipop",
|
|
214
|
+
"1f369": "doughnut",
|
|
215
|
+
"1f366": "soft-ice-cream",
|
|
216
|
+
"1f36f": "honey-pot",
|
|
217
|
+
"2615": "hot-beverage",
|
|
218
|
+
"1f375": "teacup-without-handle",
|
|
219
|
+
"1f37a": "beer-mug",
|
|
220
|
+
"1f37b": "clinking-beer-mugs",
|
|
221
|
+
"1f377": "wine-glass",
|
|
222
|
+
"1f378": "cocktail-glass"
|
|
223
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emoji Unicode to name mapping utilities
|
|
3
|
+
*
|
|
4
|
+
* This file provides utilities for converting Unicode emoji characters to their
|
|
5
|
+
* corresponding Iconify icon names.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Regular expression to match emoji sequences including multi-codepoint emojis.
|
|
9
|
+
*
|
|
10
|
+
* This regex handles:
|
|
11
|
+
* - Single emoji characters (😀)
|
|
12
|
+
* - Emoji with variation selectors (❤️)
|
|
13
|
+
* - Emoji with skin tone modifiers (👋🏽)
|
|
14
|
+
* - ZWJ sequences like family emojis (👨👩👧)
|
|
15
|
+
* - Flag sequences (🇺🇸, 🏳️🌈)
|
|
16
|
+
* - Keycap sequences (1️⃣, #️⃣)
|
|
17
|
+
*
|
|
18
|
+
* Important: Uses \p{Extended_Pictographic} instead of \p{Emoji} to avoid matching
|
|
19
|
+
* plain digits (0-9), # and * which are technically emoji-capable but shouldn't
|
|
20
|
+
* be treated as emojis when appearing alone.
|
|
21
|
+
*
|
|
22
|
+
* Pattern breakdown:
|
|
23
|
+
* - \p{Extended_Pictographic} matches pictographic emoji characters
|
|
24
|
+
* - [\d#*]\uFE0F\u20E3 matches keycap sequences (digit/hash/asterisk + variation selector + combining enclosing keycap)
|
|
25
|
+
* - \p{Regional_Indicator}{2} matches flag emoji pairs
|
|
26
|
+
* - \p{Emoji_Modifier} handles skin tone modifiers
|
|
27
|
+
* - \uFE0F is variation selector for emoji presentation
|
|
28
|
+
* - \u200D is Zero Width Joiner for combining emojis
|
|
29
|
+
*/
|
|
30
|
+
export declare const RE_MATCH_EMOJIS: RegExp;
|
|
31
|
+
/**
|
|
32
|
+
* Gets possible Iconify icon names for a given Unicode emoji
|
|
33
|
+
*
|
|
34
|
+
* @param codePoint The Unicode code point as a hex string (e.g., "1f44b" or "2764-fe0f")
|
|
35
|
+
* @param _emojiSet The emoji set to use (currently only noto is fully supported)
|
|
36
|
+
* @returns An array of possible icon names to try
|
|
37
|
+
*/
|
|
38
|
+
export declare function getEmojiIconNames(codePoint: string, _emojiSet: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Gets the code point(s) for a Unicode emoji character/sequence
|
|
41
|
+
*
|
|
42
|
+
* @param emoji The emoji character (e.g., "👋" or "👨👩👧")
|
|
43
|
+
* @returns Hex code point(s) joined by dash (e.g., "1f44b" or "1f468-200d-1f469-200d-1f467")
|
|
44
|
+
*/
|
|
45
|
+
export declare function getEmojiCodePoint(emoji: string): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EMOJI_CODEPOINT_TO_NAME } from "./emoji-names-minimal.js";
|
|
2
|
+
export const RE_MATCH_EMOJIS = /(?:\p{Extended_Pictographic}|[\d#*]\uFE0F\u20E3|\p{Regional_Indicator}{2})(?:\p{Emoji_Modifier}|\uFE0F|\u200D[\p{Extended_Pictographic}\p{Emoji}])*/gu;
|
|
3
|
+
export function getEmojiIconNames(codePoint, _emojiSet) {
|
|
4
|
+
const baseCodePoint = codePoint.replace(/-fe0f$/i, "");
|
|
5
|
+
const knownName = EMOJI_CODEPOINT_TO_NAME[codePoint] || EMOJI_CODEPOINT_TO_NAME[baseCodePoint];
|
|
6
|
+
if (knownName) {
|
|
7
|
+
return [knownName];
|
|
8
|
+
}
|
|
9
|
+
return [codePoint, baseCodePoint, `u${baseCodePoint}`].filter((v, i, a) => a.indexOf(v) === i);
|
|
10
|
+
}
|
|
11
|
+
export function getEmojiCodePoint(emoji) {
|
|
12
|
+
return [...emoji].map((char) => char.codePointAt(0).toString(16)).join("-");
|
|
13
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OgImageRenderEventContext } from '../../../../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service function to fetch emoji SVGs from the iconify API
|
|
4
|
+
* This does not perform HTML replacement - that's handled by the AST plugin
|
|
5
|
+
*/
|
|
6
|
+
export declare function getEmojiSvg(ctx: OgImageRenderEventContext, emojiChar: string): Promise<string | null>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { emojiCache } from "#og-image-cache";
|
|
2
|
+
import { $fetch } from "ofetch";
|
|
3
|
+
import { getEmojiCodePoint, getEmojiIconNames } from "./emoji-utils.js";
|
|
4
|
+
export async function getEmojiSvg(ctx, emojiChar) {
|
|
5
|
+
const codePoint = getEmojiCodePoint(emojiChar);
|
|
6
|
+
const possibleNames = getEmojiIconNames(codePoint, ctx.options.emojis);
|
|
7
|
+
let svg = null;
|
|
8
|
+
for (const iconName of possibleNames) {
|
|
9
|
+
const key = ["1", ctx.options.emojis, iconName].join("|");
|
|
10
|
+
if (await emojiCache.hasItem(key)) {
|
|
11
|
+
svg = await emojiCache.getItem(key);
|
|
12
|
+
if (svg)
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (!svg) {
|
|
17
|
+
for (const iconName of possibleNames) {
|
|
18
|
+
try {
|
|
19
|
+
svg = await $fetch(`https://api.iconify.design/${ctx.options.emojis}/${iconName}.svg`, {
|
|
20
|
+
responseType: "text",
|
|
21
|
+
retry: 2,
|
|
22
|
+
retryDelay: 500
|
|
23
|
+
});
|
|
24
|
+
if (svg && svg !== "404") {
|
|
25
|
+
const key = ["1", ctx.options.emojis, iconName].join("|");
|
|
26
|
+
await emojiCache.setItem(key, svg);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
svg = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (svg) {
|
|
35
|
+
return svg.replace("<svg ", '<svg data-emoji style="margin: 0 .05em 0 .15em; vertical-align: -0.1em;" ');
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NuxtIslandResponse } from 'nuxt/app';
|
|
2
|
+
import type { OgImageRenderEventContext } from '../../../../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Apply emoji transformations to island HTML content.
|
|
5
|
+
* Replaces emoji characters with inline SVG elements.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyEmojis(ctx: OgImageRenderEventContext, island: NuxtIslandResponse): Promise<void>;
|