nuxt-og-image 2.0.0-beta.43 → 2.0.0-beta.46
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 +5 -0
- package/dist/client/200.html +2 -2
- package/dist/client/404.html +2 -2
- package/dist/client/_nuxt/{IconCSS.b113975e.js → IconCSS.d8cd5733.js} +1 -1
- package/dist/client/_nuxt/{ImageLoader.b3f2fdfd.js → ImageLoader.3019a38e.js} +1 -1
- package/dist/client/_nuxt/{entry.c23ed2b6.js → entry.329bb907.js} +2 -2
- package/dist/client/_nuxt/{error-404.0002113d.js → error-404.ca83b642.js} +1 -1
- package/dist/client/_nuxt/{error-500.171ba3b2.js → error-500.bbb9f8d8.js} +1 -1
- package/dist/client/_nuxt/{error-component.bbb20371.js → error-component.ed0ea6d4.js} +2 -2
- package/dist/client/_nuxt/{index.b33d70ad.js → index.9dd699b9.js} +1 -1
- package/dist/client/_nuxt/{options.446a167e.js → options.406afdd7.js} +1 -1
- package/dist/client/_nuxt/{png.2c1d3085.js → png.0aee24aa.js} +1 -1
- package/dist/client/_nuxt/{shiki.caf1a928.js → shiki.faa60705.js} +1 -1
- package/dist/client/_nuxt/{svg.01d38cc1.js → svg.299f4cde.js} +1 -1
- package/dist/client/_nuxt/{vnodes.dbfaa416.js → vnodes.5ffe0cf0.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/options/index.html +2 -2
- package/dist/client/png/index.html +2 -2
- package/dist/client/svg/index.html +2 -2
- package/dist/client/vnodes/index.html +2 -2
- package/dist/module.d.ts +5 -4
- package/dist/module.json +1 -1
- package/dist/module.mjs +15 -4
- package/dist/runtime/components/OgImageBasic.island.vue +5 -0
- package/dist/runtime/nitro/renderers/satori/index.mjs +1 -9
- package/dist/runtime/nitro/renderers/satori/plugins/emojis.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/emojis.mjs +24 -9
- package/dist/runtime/nitro/renderers/satori/plugins/encoding.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/flex.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/plugins/twClasses.d.ts +1 -1
- package/dist/runtime/nitro/renderers/satori/utils.d.ts +2 -2
- package/dist/runtime/nitro/renderers/satori/utils.mjs +2 -2
- package/dist/runtime/nitro/routes/html.mjs +49 -20
- package/dist/runtime/nitro/util-hostname.mjs +7 -2
- package/package.json +10 -8
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { defineSatoriTransformer } from "../utils.mjs";
|
|
2
|
+
function isEmojiFilter(node) {
|
|
3
|
+
return node.type === "img" && node.props?.class?.includes("emoji");
|
|
4
|
+
}
|
|
2
5
|
export default defineSatoriTransformer(() => {
|
|
3
|
-
return
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
node.props
|
|
7
|
-
node
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
}
|
|
11
26
|
}
|
|
12
|
-
|
|
27
|
+
];
|
|
13
28
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer;
|
|
1
|
+
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer;
|
|
1
|
+
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer;
|
|
1
|
+
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer;
|
|
1
|
+
declare const _default: (url: import("ufo").ParsedURL) => import("../../../../../types").SatoriTransformer | import("../../../../../types").SatoriTransformer[];
|
|
2
2
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ParsedURL } from 'ufo';
|
|
2
2
|
import type { FontConfig, SatoriTransformer, VNode } from '../../../../types';
|
|
3
3
|
export declare function loadFont(baseURL: string, font: FontConfig): Promise<any>;
|
|
4
|
-
export declare function walkSatoriTree(url: ParsedURL, node: VNode, plugins: SatoriTransformer[]): Promise<void>;
|
|
5
|
-
export declare function defineSatoriTransformer(transformer: (url: ParsedURL) => SatoriTransformer): (url: ParsedURL) => SatoriTransformer;
|
|
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[];
|
|
@@ -16,7 +16,7 @@ export async function loadFont(baseURL, font) {
|
|
|
16
16
|
if (!data && name === "Inter" && ["400", "700"].includes(weight)) {
|
|
17
17
|
data = await readPublicAsset(`/inter-latin-ext-${weight}-normal.woff`);
|
|
18
18
|
}
|
|
19
|
-
if (
|
|
19
|
+
if (font.path) {
|
|
20
20
|
data = await readPublicAsset(font.path);
|
|
21
21
|
if (!data) {
|
|
22
22
|
try {
|
|
@@ -49,7 +49,7 @@ export async function walkSatoriTree(url, node, plugins) {
|
|
|
49
49
|
}
|
|
50
50
|
for (const child of node.props.children || []) {
|
|
51
51
|
if (child) {
|
|
52
|
-
for (const plugin of plugins) {
|
|
52
|
+
for (const plugin of plugins.flat()) {
|
|
53
53
|
if (plugin.filter(child))
|
|
54
54
|
await plugin.transform(child);
|
|
55
55
|
}
|
|
@@ -3,6 +3,8 @@ import { renderSSRHead } from "@unhead/ssr";
|
|
|
3
3
|
import { createHeadCore } from "@unhead/vue";
|
|
4
4
|
import { createError, defineEventHandler, getQuery, sendRedirect } from "h3";
|
|
5
5
|
import { hash } from "ohash";
|
|
6
|
+
import twemoji from "twemoji";
|
|
7
|
+
import inlineCss from "inline-css";
|
|
6
8
|
import { fetchOptions, useHostname } from "../utils.mjs";
|
|
7
9
|
import { useRuntimeConfig } from "#imports";
|
|
8
10
|
export default defineEventHandler(async (e) => {
|
|
@@ -40,11 +42,15 @@ export default defineEventHandler(async (e) => {
|
|
|
40
42
|
head.push(island.head);
|
|
41
43
|
let defaultFontFamily = "sans-serif";
|
|
42
44
|
const firstFont = fonts[0];
|
|
43
|
-
if (firstFont)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (firstFont)
|
|
46
|
+
defaultFontFamily = firstFont.name;
|
|
47
|
+
let html = island.html;
|
|
48
|
+
try {
|
|
49
|
+
html = twemoji.parse(html, {
|
|
50
|
+
folder: "svg",
|
|
51
|
+
ext: ".svg"
|
|
52
|
+
});
|
|
53
|
+
} catch (e2) {
|
|
48
54
|
}
|
|
49
55
|
head.push({
|
|
50
56
|
style: [
|
|
@@ -52,9 +58,9 @@ export default defineEventHandler(async (e) => {
|
|
|
52
58
|
// default font is the first font family
|
|
53
59
|
innerHTML: `body { font-family: '${defaultFontFamily.replace("+", " ")}', sans-serif; }`
|
|
54
60
|
},
|
|
55
|
-
|
|
61
|
+
{
|
|
56
62
|
innerHTML: `body {
|
|
57
|
-
transform: scale(${scale});
|
|
63
|
+
transform: scale(${scale || 1});
|
|
58
64
|
transform-origin: top left;
|
|
59
65
|
max-height: 100vh;
|
|
60
66
|
position: relative;
|
|
@@ -68,17 +74,15 @@ img.emoji {
|
|
|
68
74
|
width: 1em;
|
|
69
75
|
margin: 0 .05em 0 .1em;
|
|
70
76
|
vertical-align: -0.1em;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
...fonts.filter((font) => typeof font === "object").map((font) => {
|
|
75
|
-
const { name, weight, path: path2 } = font;
|
|
77
|
+
}`
|
|
78
|
+
},
|
|
79
|
+
...fonts.filter((font) => font.path).map((font) => {
|
|
76
80
|
return `
|
|
77
81
|
@font-face {
|
|
78
|
-
font-family: '${name}';
|
|
82
|
+
font-family: '${font.name}';
|
|
79
83
|
font-style: normal;
|
|
80
|
-
font-weight: ${weight};
|
|
81
|
-
src: url('${
|
|
84
|
+
font-weight: ${font.weight};
|
|
85
|
+
src: url('${font.path}') format('truetype');
|
|
82
86
|
}
|
|
83
87
|
`;
|
|
84
88
|
})
|
|
@@ -108,19 +112,44 @@ img.emoji {
|
|
|
108
112
|
rel: "stylesheet"
|
|
109
113
|
},
|
|
110
114
|
// have to add each weight as their own stylesheet
|
|
111
|
-
...fonts.filter((font) =>
|
|
112
|
-
const [name, weight] = font.split(":");
|
|
115
|
+
...fonts.filter((font) => !font.path).map((font) => {
|
|
113
116
|
return {
|
|
114
|
-
href: `https://fonts.googleapis.com/css2?family=${name}:wght@${weight}&display=swap`,
|
|
117
|
+
href: `https://fonts.googleapis.com/css2?family=${font.name}:wght@${font.weight}&display=swap`,
|
|
115
118
|
rel: "stylesheet"
|
|
116
119
|
};
|
|
117
120
|
})
|
|
118
121
|
]
|
|
119
122
|
});
|
|
120
123
|
const headChunk = await renderSSRHead(head);
|
|
121
|
-
|
|
124
|
+
let htmlTemplate = `<!DOCTYPE html>
|
|
122
125
|
<html ${headChunk.htmlAttrs}>
|
|
123
126
|
<head>${headChunk.headTags}</head>
|
|
124
|
-
<body ${headChunk.bodyAttrs}>${headChunk.bodyTagsOpen}<div style="position: relative; display: flex; margin: 0 auto; width: 1200px; height: 630px;">${
|
|
127
|
+
<body ${headChunk.bodyAttrs}>${headChunk.bodyTagsOpen}<div style="position: relative; display: flex; margin: 0 auto; width: 1200px; height: 630px;">${html}</div>${headChunk.bodyTags}</body>
|
|
125
128
|
</html>`;
|
|
129
|
+
const stylesheets = htmlTemplate.match(/<link rel="stylesheet" href=".*">/g);
|
|
130
|
+
if (stylesheets) {
|
|
131
|
+
for (const stylesheet of stylesheets) {
|
|
132
|
+
const href = stylesheet.match(/<link rel="stylesheet" href="(.*)">/)[1];
|
|
133
|
+
try {
|
|
134
|
+
if (stylesheet.includes("@nuxt/ui-templates")) {
|
|
135
|
+
htmlTemplate = htmlTemplate.replace(stylesheet, "");
|
|
136
|
+
} else {
|
|
137
|
+
const css = (await (await $fetch(href, {
|
|
138
|
+
baseURL: useHostname(e)
|
|
139
|
+
})).text()).replace(/\/\/# sourceMappingURL=.*/, "");
|
|
140
|
+
htmlTemplate = htmlTemplate.replace(stylesheet, `<style>${css}</style>`);
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
htmlTemplate = inlineCss(htmlTemplate, {
|
|
148
|
+
url: useHostname(e),
|
|
149
|
+
applyLinkTags: false,
|
|
150
|
+
removeLinkTags: false
|
|
151
|
+
});
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
return htmlTemplate;
|
|
126
155
|
});
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { getRequestHost, getRequestProtocol } from "h3";
|
|
2
|
-
import { withBase } from "ufo";
|
|
2
|
+
import { withBase, withoutProtocol } from "ufo";
|
|
3
3
|
import { useRuntimeConfig } from "#imports";
|
|
4
4
|
export function useHostname(e) {
|
|
5
5
|
const base = useRuntimeConfig().app.baseURL;
|
|
6
6
|
let host = getRequestHost(e);
|
|
7
7
|
if (host === "localhost")
|
|
8
8
|
host = process.env.NITRO_HOST || process.env.HOST || host;
|
|
9
|
-
|
|
9
|
+
let protocol = getRequestProtocol(e);
|
|
10
|
+
if (process.env.NUXT_VITE_NODE_OPTIONS) {
|
|
11
|
+
const envHost = JSON.parse(process.env.NUXT_VITE_NODE_OPTIONS).baseURL.replace("__nuxt_vite_node__", "");
|
|
12
|
+
host = withoutProtocol(envHost);
|
|
13
|
+
protocol = envHost.includes("https") ? "https" : "http";
|
|
14
|
+
}
|
|
10
15
|
const useHttp = process.dev || host.includes("127.0.0.1") || host.includes("localhost") || protocol === "http";
|
|
11
16
|
let port = host.includes(":") ? host.split(":").pop() : false;
|
|
12
17
|
if ((process.dev || process.env.prerender || host.includes("localhost")) && !port)
|
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.
|
|
4
|
+
"version": "2.0.0-beta.46",
|
|
5
5
|
"packageManager": "pnpm@8.6.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@nuxt/kit": "^3.5.
|
|
29
|
+
"@nuxt/kit": "^3.5.3",
|
|
30
30
|
"@resvg/resvg-js": "^2.4.1",
|
|
31
31
|
"@resvg/resvg-wasm": "^2.4.1",
|
|
32
32
|
"@types/fs-extra": "^11.0.1",
|
|
@@ -39,15 +39,17 @@
|
|
|
39
39
|
"flatted": "^3.2.7",
|
|
40
40
|
"fs-extra": "^11.1.1",
|
|
41
41
|
"globby": "^13.1.4",
|
|
42
|
+
"inline-css": "^4.0.2",
|
|
42
43
|
"launch-editor": "^2.6.0",
|
|
43
44
|
"nuxt-icon": "^0.4.1",
|
|
45
|
+
"nuxt-site-config": "^0.2.1",
|
|
44
46
|
"nypm": "^0.2.0",
|
|
45
47
|
"ofetch": "^1.0.1",
|
|
46
48
|
"ohash": "^1.1.2",
|
|
47
49
|
"pathe": "^1.1.1",
|
|
48
50
|
"playwright-core": "^1.34.3",
|
|
49
51
|
"radix3": "^1.0.1",
|
|
50
|
-
"satori": "0.
|
|
52
|
+
"satori": "0.10.1",
|
|
51
53
|
"satori-html": "^0.3.2",
|
|
52
54
|
"sirv": "^2.0.3",
|
|
53
55
|
"std-env": "^3.3.3",
|
|
@@ -59,16 +61,16 @@
|
|
|
59
61
|
"yoga-wasm-web": "^0.3.3"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@antfu/eslint-config": "^0.39.
|
|
63
|
-
"@nuxt/devtools-edge": "0.5.5-
|
|
64
|
+
"@antfu/eslint-config": "^0.39.5",
|
|
65
|
+
"@nuxt/devtools-edge": "0.5.5-28099668.306c6a5",
|
|
64
66
|
"@nuxt/module-builder": "^0.4.0",
|
|
65
|
-
"@nuxt/test-utils": "3.5.
|
|
67
|
+
"@nuxt/test-utils": "3.5.3",
|
|
66
68
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
|
67
69
|
"@types/ws": "^8.5.4",
|
|
68
|
-
"bumpp": "^9.1.
|
|
70
|
+
"bumpp": "^9.1.1",
|
|
69
71
|
"eslint": "8.42.0",
|
|
70
72
|
"jest-image-snapshot": "^6.1.0",
|
|
71
|
-
"nuxt": "^3.5.
|
|
73
|
+
"nuxt": "^3.5.3",
|
|
72
74
|
"vitest": "^0.31.4"
|
|
73
75
|
},
|
|
74
76
|
"resolutions": {
|