nuxt-og-image 3.0.0-beta.9 → 3.0.0-rc.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 +4 -4
- package/dist/client/200.html +6 -5
- package/dist/client/404.html +6 -5
- package/dist/client/_nuxt/IconCSS.bca1abaf.js +1 -0
- package/dist/client/_nuxt/IconCSS.f0b56d3e.css +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/c430c582-423d-48d2-8592-39b7bfd61658.json +1 -0
- package/dist/client/_nuxt/entry.a30f63d0.css +1 -0
- package/dist/client/_nuxt/entry.f2e056ce.js +108 -0
- package/dist/client/_nuxt/{error-404.18456c20.js → error-404.1b7ec865.js} +1 -1
- package/dist/client/_nuxt/{error-500.a3e12514.js → error-500.1f097e6f.js} +1 -1
- package/dist/client/_nuxt/vanilla-picker-NKbIFE8h.23409a58.js +8 -0
- package/dist/client/index.html +6 -5
- package/dist/module.d.mts +63 -48
- package/dist/module.d.ts +63 -48
- package/dist/module.json +2 -2
- package/dist/module.mjs +346 -166
- package/dist/runtime/cache.d.ts +7 -10
- package/dist/runtime/cache.mjs +40 -27
- package/dist/runtime/components/OgImage/OgImage.d.ts +5 -0
- package/dist/runtime/components/OgImage/{index.mjs → OgImage.mjs} +1 -1
- package/dist/runtime/components/OgImage/OgImageScreenshot.d.ts +5 -0
- package/dist/runtime/components/OgImage/{Screenshot.mjs → OgImageScreenshot.mjs} +1 -1
- package/dist/runtime/components/Templates/{Official → Community}/BrandedLogo.vue +3 -2
- package/dist/runtime/components/Templates/Community/Nuxt.vue +6 -5
- package/dist/runtime/components/Templates/Community/NuxtSeo.vue +137 -0
- package/dist/runtime/components/Templates/Community/Pergel.vue +104 -0
- package/dist/runtime/components/Templates/{Official → Community}/SimpleBlog.vue +7 -5
- package/dist/runtime/components/Templates/Community/UnJs.vue +108 -0
- package/dist/runtime/components/Templates/{Official → Community}/Wave.vue +3 -2
- package/dist/runtime/components/Templates/{Official → Community}/WithEmoji.vue +3 -2
- package/dist/runtime/composables/defineOgImage.d.ts +2 -23
- package/dist/runtime/composables/defineOgImage.mjs +33 -117
- package/dist/runtime/composables/defineOgImageComponent.d.ts +3 -0
- package/dist/runtime/composables/defineOgImageComponent.mjs +8 -0
- package/dist/runtime/composables/defineOgImageScreenshot.d.ts +2 -0
- package/dist/runtime/composables/defineOgImageScreenshot.mjs +13 -0
- package/dist/runtime/core/bindings/css-inline/node.d.ts +2 -5
- package/dist/runtime/core/bindings/css-inline/node.mjs +2 -10
- package/dist/runtime/core/bindings/resvg/wasm-fs.d.ts +40 -0
- package/dist/runtime/core/bindings/resvg/wasm-fs.mjs +6 -0
- package/dist/runtime/core/bindings/resvg/wasm.mjs +2 -5
- package/dist/runtime/core/bindings/satori/wasm-fs.mjs +13 -0
- package/dist/runtime/core/bindings/satori/wasm.d.ts +6 -0
- package/dist/runtime/core/bindings/satori/wasm.mjs +14 -0
- package/dist/runtime/core/cache/emojis.d.ts +1 -0
- package/dist/runtime/core/cache/emojis.mjs +5 -0
- package/dist/runtime/core/cache/fonts.d.ts +3 -0
- package/dist/runtime/core/cache/fonts.mjs +6 -0
- package/dist/runtime/core/cache/htmlPayload.d.ts +5 -0
- package/dist/runtime/core/cache/htmlPayload.mjs +6 -0
- package/dist/runtime/core/cache/prerender.d.ts +1 -5
- package/dist/runtime/core/cache/prerender.mjs +1 -2
- package/dist/runtime/core/env/assets.d.ts +0 -1
- package/dist/runtime/core/env/assets.mjs +0 -4
- package/dist/runtime/core/font/fetch.d.ts +2 -3
- package/dist/runtime/core/font/fetch.mjs +26 -19
- package/dist/runtime/core/html/applyEmojis.d.ts +3 -0
- package/dist/runtime/core/html/applyEmojis.mjs +37 -0
- package/dist/runtime/core/html/applyInlineCss.d.ts +3 -0
- package/dist/runtime/core/html/applyInlineCss.mjs +32 -0
- package/dist/runtime/core/html/devIframeTemplate.d.ts +2 -0
- package/dist/runtime/core/html/{fetch.mjs → devIframeTemplate.mjs} +33 -42
- package/dist/runtime/core/html/fetchIsland.d.ts +3 -0
- package/dist/runtime/core/html/fetchIsland.mjs +17 -0
- package/dist/runtime/core/options/fetch.d.ts +1 -1
- package/dist/runtime/core/options/fetch.mjs +10 -5
- package/dist/runtime/core/renderers/chromium/index.mjs +12 -15
- package/dist/runtime/core/renderers/chromium/screenshot.d.ts +2 -3
- package/dist/runtime/core/renderers/chromium/screenshot.mjs +20 -15
- package/dist/runtime/core/renderers/satori/index.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/index.mjs +51 -25
- package/dist/runtime/core/renderers/satori/instances.d.ts +3 -0
- package/dist/runtime/core/renderers/satori/instances.mjs +15 -0
- package/dist/runtime/core/renderers/satori/plugins/emojis.mjs +15 -13
- package/dist/runtime/core/renderers/satori/plugins/imageSrc.mjs +60 -30
- package/dist/runtime/core/renderers/satori/plugins/unocss.d.ts +2 -0
- package/dist/runtime/core/renderers/satori/plugins/unocss.mjs +45 -0
- package/dist/runtime/core/renderers/satori/utils.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/vnodes.d.ts +2 -3
- package/dist/runtime/core/renderers/satori/vnodes.mjs +16 -6
- package/dist/runtime/core/utils/resolveRendererContext.d.ts +2 -6
- package/dist/runtime/core/utils/resolveRendererContext.mjs +47 -29
- package/dist/runtime/core/utils/wasm.d.ts +3 -0
- package/dist/runtime/core/utils/wasm.mjs +16 -0
- package/dist/runtime/nitro/plugins/nuxt-content.mjs +7 -6
- package/dist/runtime/nitro/plugins/prerender.d.ts +1 -1
- package/dist/runtime/nitro/plugins/prerender.mjs +20 -18
- package/dist/runtime/nitro/utils.d.ts +2 -0
- package/dist/runtime/nitro/utils.mjs +17 -0
- package/dist/runtime/nuxt/plugins/og-image-canonical-urls.server.mjs +43 -0
- package/dist/runtime/nuxt/plugins/route-rule-og-image.server.mjs +16 -51
- package/dist/runtime/nuxt/utils.d.ts +3 -0
- package/dist/runtime/nuxt/utils.mjs +69 -0
- package/dist/runtime/server/routes/__og-image__/debug.json.d.ts +2 -3
- package/dist/runtime/server/routes/__og-image__/debug.json.mjs +5 -7
- package/dist/runtime/server/routes/__og-image__/image.mjs +88 -0
- package/dist/runtime/types.d.ts +96 -27
- package/dist/runtime/utils.d.ts +4 -0
- package/dist/runtime/utils.mjs +11 -0
- package/dist/runtime/utils.pure.d.ts +6 -0
- package/dist/runtime/utils.pure.mjs +63 -0
- package/package.json +33 -38
- package/virtual.d.ts +49 -0
- package/dist/client/_nuxt/IconCSS.05a4ab6a.js +0 -1
- package/dist/client/_nuxt/IconCSS.8f429b14.css +0 -1
- package/dist/client/_nuxt/builds/meta/ce33a6eb-5cc2-4c46-8618-9befaa3f226c.json +0 -1
- package/dist/client/_nuxt/entry.434c2c45.css +0 -1
- package/dist/client/_nuxt/entry.d927023c.js +0 -137
- package/dist/client/grid.png +0 -0
- package/dist/runtime/components/OgImage/Cached.d.ts +0 -5
- package/dist/runtime/components/OgImage/Cached.mjs +0 -10
- package/dist/runtime/components/OgImage/Dynamic.d.ts +0 -8
- package/dist/runtime/components/OgImage/Dynamic.mjs +0 -10
- package/dist/runtime/components/OgImage/Screenshot.d.ts +0 -6
- package/dist/runtime/components/OgImage/Static.d.ts +0 -8
- package/dist/runtime/components/OgImage/Static.mjs +0 -10
- package/dist/runtime/components/OgImage/WithoutCache.d.ts +0 -5
- package/dist/runtime/components/OgImage/WithoutCache.mjs +0 -10
- package/dist/runtime/components/OgImage/index.d.ts +0 -5
- package/dist/runtime/components/Templates/Official/Fallback.vue +0 -147
- package/dist/runtime/core/bindings/css-inline/mock.d.ts +0 -5
- package/dist/runtime/core/bindings/css-inline/mock.mjs +0 -3
- package/dist/runtime/core/bindings/satori/yoga-wasm.mjs +0 -7
- package/dist/runtime/core/bindings/sharp/wasm.d.ts +0 -2
- package/dist/runtime/core/bindings/sharp/wasm.mjs +0 -2
- package/dist/runtime/core/font/cache.d.ts +0 -1
- package/dist/runtime/core/font/cache.mjs +0 -1
- package/dist/runtime/core/html/fetch.d.ts +0 -3
- package/dist/runtime/core/options/normalise.d.ts +0 -2
- package/dist/runtime/core/options/normalise.mjs +0 -26
- package/dist/runtime/core/renderers/satori/fonts.d.ts +0 -3
- package/dist/runtime/core/renderers/satori/fonts.mjs +0 -8
- package/dist/runtime/nuxt/plugins/nuxt-content-canonical-urls.mjs +0 -29
- package/dist/runtime/public-assets/__nuxt_og_image__/browser-provider-not-supported.png +0 -0
- package/dist/runtime/server/routes/__og-image__/image-[path]-og.[extension].mjs +0 -45
- package/dist/runtime/utilts.d.ts +0 -2
- package/dist/runtime/utilts.mjs +0 -8
- /package/dist/runtime/core/bindings/satori/{yoga-wasm.d.ts → wasm-fs.d.ts} +0 -0
- /package/dist/runtime/nuxt/plugins/{nuxt-content-canonical-urls.d.ts → og-image-canonical-urls.server.d.ts} +0 -0
- /package/dist/runtime/{public-assets-optional/inter-font → server/assets}/inter-latin-ext-400-normal.woff +0 -0
- /package/dist/runtime/{public-assets-optional/inter-font → server/assets}/inter-latin-ext-700-normal.woff +0 -0
- /package/dist/runtime/server/routes/__og-image__/{image-[path]-og.[extension].d.ts → image.d.ts} +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { H3Error, createError, defineEventHandler, getQuery, setHeader } from "h3";
|
|
2
|
+
import { resolveRendererContext } from "../../../core/utils/resolveRendererContext.mjs";
|
|
3
|
+
import { fetchIsland } from "../../../core/html/fetchIsland.mjs";
|
|
4
|
+
import { devIframeTemplate } from "../../../core/html/devIframeTemplate.mjs";
|
|
5
|
+
import { applyInlineCss } from "../../../core/html/applyInlineCss.mjs";
|
|
6
|
+
import { useOgImageBufferCache } from "../../../cache.mjs";
|
|
7
|
+
import { useOgImageRuntimeConfig } from "../../../utils.mjs";
|
|
8
|
+
import { useSiteConfig } from "#imports";
|
|
9
|
+
export default defineEventHandler(async (e) => {
|
|
10
|
+
const ctx = await resolveRendererContext(e);
|
|
11
|
+
if (ctx instanceof H3Error)
|
|
12
|
+
return ctx;
|
|
13
|
+
const { isDebugJsonPayload, extension, options, renderer } = ctx;
|
|
14
|
+
const { debug, baseCacheKey } = useOgImageRuntimeConfig();
|
|
15
|
+
const compatibilityHints = [];
|
|
16
|
+
if (isDebugJsonPayload) {
|
|
17
|
+
const queryExtension = getQuery(e).extension || ctx.options.extension;
|
|
18
|
+
if (["jpeg", "jpg"].includes(queryExtension) && options.renderer === "satori")
|
|
19
|
+
compatibilityHints.push("Converting PNGs to JPEGs requires Sharp which only runs on Node based systems.");
|
|
20
|
+
if (options.renderer === "chromium")
|
|
21
|
+
compatibilityHints.push("Using Chromium to generate images is only supported in Node based environments. It's recommended to only use this if you're prerendering");
|
|
22
|
+
if (options.component !== "PageScreenshot" && await applyInlineCss(ctx, await fetchIsland(ctx)))
|
|
23
|
+
compatibilityHints.push("Inlining CSS is only supported in Node based environments.");
|
|
24
|
+
setHeader(e, "Content-Type", "application/json");
|
|
25
|
+
return {
|
|
26
|
+
compatibilityHints,
|
|
27
|
+
cacheKey: ctx.key,
|
|
28
|
+
options: ctx.options,
|
|
29
|
+
siteConfig: useSiteConfig(e),
|
|
30
|
+
...options.renderer === "satori" ? await renderer.debug(ctx) : void 0
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
switch (extension) {
|
|
34
|
+
case "html":
|
|
35
|
+
setHeader(e, "Content-Type", `text/html`);
|
|
36
|
+
return devIframeTemplate(ctx);
|
|
37
|
+
case "svg":
|
|
38
|
+
if (!debug && !import.meta.dev) {
|
|
39
|
+
return createError({
|
|
40
|
+
statusCode: 404
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (ctx.renderer.name !== "satori") {
|
|
44
|
+
return createError({
|
|
45
|
+
statusCode: 400,
|
|
46
|
+
statusMessage: `Generating ${extension}'s with ${renderer.name} is not supported.`
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
setHeader(e, "Content-Type", `image/svg+xml`);
|
|
50
|
+
return (await ctx.renderer.debug(ctx)).svg;
|
|
51
|
+
case "png":
|
|
52
|
+
case "jpeg":
|
|
53
|
+
case "jpg":
|
|
54
|
+
if (!renderer.supportedFormats.includes(extension)) {
|
|
55
|
+
return createError({
|
|
56
|
+
statusCode: 400,
|
|
57
|
+
statusMessage: `Generating ${extension}'s with ${renderer.name} is not supported.`
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
setHeader(e, "Content-Type", `image/${extension === "jpg" ? "jpeg" : extension}`);
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
return createError({
|
|
64
|
+
statusCode: 400,
|
|
65
|
+
statusMessage: `Invalid request for og.${extension}.`
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const cacheApi = await useOgImageBufferCache(ctx, {
|
|
69
|
+
cacheMaxAgeSeconds: ctx.options.cacheMaxAgeSeconds,
|
|
70
|
+
baseCacheKey
|
|
71
|
+
});
|
|
72
|
+
if (typeof cacheApi === "undefined")
|
|
73
|
+
return;
|
|
74
|
+
let image = cacheApi.cachedItem;
|
|
75
|
+
if (!image) {
|
|
76
|
+
image = await renderer.createImage(ctx);
|
|
77
|
+
if (image instanceof H3Error)
|
|
78
|
+
return image;
|
|
79
|
+
if (!image) {
|
|
80
|
+
return createError({
|
|
81
|
+
statusCode: 500,
|
|
82
|
+
statusMessage: `Failed to generate og.${extension}.`
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
await cacheApi.update(image);
|
|
86
|
+
}
|
|
87
|
+
return image;
|
|
88
|
+
});
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { Buffer } from 'node:buffer';
|
|
3
1
|
import type { html } from 'satori-html';
|
|
4
2
|
import type { H3Error, H3Event } from 'h3';
|
|
5
3
|
import type { ResvgRenderOptions } from '@resvg/resvg-js';
|
|
6
4
|
import type { SatoriOptions } from 'satori';
|
|
5
|
+
import type { AllowedComponentProps, Component, ComponentCustomProps, VNodeProps } from '@vue/runtime-core';
|
|
6
|
+
import type { SharpOptions } from 'sharp';
|
|
7
|
+
import type { NitroApp, WasmOptions } from 'nitropack';
|
|
8
|
+
import type { OgImageComponents } from '#nuxt-og-image/components';
|
|
9
|
+
export interface OgImageRenderEventContext {
|
|
10
|
+
e: H3Event;
|
|
11
|
+
extension: 'png' | 'jpeg' | 'jpg' | 'svg' | 'html' | 'json';
|
|
12
|
+
key: string;
|
|
13
|
+
basePath: string;
|
|
14
|
+
renderer: Renderer;
|
|
15
|
+
options: OgImageOptions;
|
|
16
|
+
isDebugJsonPayload: boolean;
|
|
17
|
+
_nitro: NitroApp;
|
|
18
|
+
}
|
|
19
|
+
export type IconifyEmojiIconSets = 'twemoji' | 'noto' | 'fluent-emoji' | 'fluent-emoji-flat' | 'fluent-emoji-high-contrast' | 'noto-v1' | 'emojione' | 'emojione-monotone' | 'emojione-v1' | 'streamline-emojis' | 'openmoji';
|
|
20
|
+
export interface OgImageRuntimeConfig {
|
|
21
|
+
version: string;
|
|
22
|
+
satoriOptions: SatoriOptions;
|
|
23
|
+
resvgOptions: ResvgRenderOptions;
|
|
24
|
+
sharpOptions: SharpOptions;
|
|
25
|
+
defaults: OgImageOptions;
|
|
26
|
+
debug: boolean;
|
|
27
|
+
baseCacheKey: string;
|
|
28
|
+
fonts: FontConfig[];
|
|
29
|
+
hasNuxtIcon: boolean;
|
|
30
|
+
colorPreference: 'light' | 'dark';
|
|
31
|
+
}
|
|
7
32
|
export interface OgImageComponent {
|
|
8
33
|
path?: string;
|
|
9
34
|
pascalName: string;
|
|
10
35
|
kebabName: string;
|
|
11
36
|
hash: string;
|
|
12
|
-
category: 'app' | '
|
|
37
|
+
category: 'app' | 'community' | 'pro';
|
|
13
38
|
credits?: string;
|
|
14
39
|
}
|
|
15
40
|
export interface ScreenshotOptions {
|
|
@@ -33,49 +58,93 @@ export interface ScreenshotOptions {
|
|
|
33
58
|
*/
|
|
34
59
|
delay?: number;
|
|
35
60
|
}
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
61
|
+
export type OgImagePrebuilt = {
|
|
62
|
+
url: string;
|
|
63
|
+
} & Pick<OgImageOptions, 'width' | 'height' | 'alt'>;
|
|
64
|
+
export type DefineOgImageInput = OgImageOptions | OgImagePrebuilt | false;
|
|
65
|
+
export interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
|
|
40
66
|
/**
|
|
41
|
-
*
|
|
67
|
+
* The width of the screenshot.
|
|
68
|
+
*
|
|
69
|
+
* @default 1200
|
|
42
70
|
*/
|
|
43
|
-
|
|
71
|
+
width?: number;
|
|
72
|
+
/**
|
|
73
|
+
* The height of the screenshot.
|
|
74
|
+
*
|
|
75
|
+
* @default 630
|
|
76
|
+
*/
|
|
77
|
+
height?: number;
|
|
78
|
+
/**
|
|
79
|
+
* The alt text for the image.
|
|
80
|
+
*/
|
|
81
|
+
alt?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Use a prebuilt image instead of generating one.
|
|
84
|
+
*
|
|
85
|
+
* Should be an absolute URL.
|
|
86
|
+
*/
|
|
87
|
+
url?: string;
|
|
88
|
+
/**
|
|
89
|
+
* The name of the component to render.
|
|
90
|
+
*/
|
|
91
|
+
component?: T | string;
|
|
92
|
+
/**
|
|
93
|
+
* Props to pass to the component.
|
|
94
|
+
*/
|
|
95
|
+
props?: OgImageComponents[T] | Record<string, any>;
|
|
96
|
+
renderer?: 'chromium' | 'satori';
|
|
97
|
+
extension?: 'png' | 'jpeg' | 'jpg';
|
|
98
|
+
emojis?: IconifyEmojiIconSets;
|
|
44
99
|
/**
|
|
45
100
|
* Provide a static HTML template to render the OG Image instead of a component.
|
|
46
101
|
*/
|
|
47
102
|
html?: string;
|
|
48
|
-
cache?: boolean;
|
|
49
|
-
cacheKey?: string;
|
|
50
103
|
resvg?: ResvgRenderOptions;
|
|
51
104
|
satori?: SatoriOptions;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
[key: string]: any;
|
|
57
|
-
}
|
|
58
|
-
export interface RuntimeOgImageOptions extends Omit<OgImageOptions, 'extension'> {
|
|
59
|
-
extension: 'png' | 'jpeg' | 'jpg' | 'svg' | 'json' | 'html';
|
|
60
|
-
path: string;
|
|
105
|
+
screenshot?: Partial<ScreenshotOptions>;
|
|
106
|
+
sharp?: SharpOptions;
|
|
107
|
+
fonts?: InputFontConfig[];
|
|
108
|
+
cacheMaxAgeSeconds?: number;
|
|
61
109
|
}
|
|
62
110
|
export interface FontConfig {
|
|
63
111
|
name: string;
|
|
64
|
-
weight
|
|
112
|
+
weight?: string | number;
|
|
65
113
|
path?: string;
|
|
114
|
+
key?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface ResolvedFontConfig extends FontConfig {
|
|
117
|
+
cacheKey: string;
|
|
118
|
+
data?: BufferSource;
|
|
119
|
+
}
|
|
120
|
+
export type InputFontConfig = (`${string}:${number}` | string | FontConfig);
|
|
121
|
+
export interface RuntimeCompatibilitySchema {
|
|
122
|
+
chromium: 'node' | false;
|
|
123
|
+
['css-inline']: 'node' | false;
|
|
124
|
+
resvg: 'node' | 'wasm' | 'wasm-fs' | false;
|
|
125
|
+
satori: 'node' | 'wasm' | 'wasm-fs' | false;
|
|
126
|
+
sharp: 'node' | false;
|
|
127
|
+
wasm?: WasmOptions;
|
|
128
|
+
}
|
|
129
|
+
export type CompatibilityFlags = Partial<Omit<RuntimeCompatibilitySchema, 'wasm'>>;
|
|
130
|
+
export interface CompatibilityFlagEnvOverrides {
|
|
131
|
+
dev?: CompatibilityFlags;
|
|
132
|
+
runtime?: CompatibilityFlags;
|
|
133
|
+
prerender?: CompatibilityFlags;
|
|
66
134
|
}
|
|
67
|
-
export type
|
|
68
|
-
|
|
69
|
-
extension: Omit<RuntimeOgImageOptions['extension'], 'html'>;
|
|
135
|
+
export type RendererOptions = Omit<OgImageOptions, 'extension'> & {
|
|
136
|
+
extension: Omit<OgImageOptions['extension'], 'html'>;
|
|
70
137
|
};
|
|
71
138
|
export interface Renderer {
|
|
72
139
|
name: 'chromium' | 'satori';
|
|
73
140
|
supportedFormats: Partial<RendererOptions['extension']>[];
|
|
74
|
-
createImage: (e:
|
|
141
|
+
createImage: (e: OgImageRenderEventContext) => Promise<H3Error | BufferSource | void>;
|
|
142
|
+
debug: (e: OgImageRenderEventContext) => Promise<Record<string, any>>;
|
|
75
143
|
}
|
|
76
|
-
export type
|
|
144
|
+
export type ExtractComponentProps<T extends Component> = T extends new (...args: any) => any ? Omit<InstanceType<T>['$props'], keyof ComponentCustomProps | keyof VNodeProps | keyof AllowedComponentProps> : never;
|
|
145
|
+
export type OgImagePageScreenshotOptions = Omit<OgImageOptions, 'html' | 'renderer' | 'component' | 'satori' | 'resvg' | 'sharp'>;
|
|
77
146
|
export type VNode = ReturnType<typeof html>;
|
|
78
147
|
export interface SatoriTransformer {
|
|
79
148
|
filter: (node: VNode) => boolean;
|
|
80
|
-
transform: (node: VNode, e:
|
|
149
|
+
transform: (node: VNode, e: OgImageRenderEventContext) => Promise<void>;
|
|
81
150
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { OgImageOptions, OgImageRuntimeConfig } from './types';
|
|
2
|
+
export * from './utils.pure';
|
|
3
|
+
export declare function getOgImagePath(pagePath: string, _options?: Partial<OgImageOptions>): string;
|
|
4
|
+
export declare function useOgImageRuntimeConfig(): OgImageRuntimeConfig;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { joinURL } from "ufo";
|
|
2
|
+
import { defu } from "defu";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
|
+
export * from "./utils.pure.mjs";
|
|
5
|
+
export function getOgImagePath(pagePath, _options) {
|
|
6
|
+
const options = defu(_options, useOgImageRuntimeConfig().defaults);
|
|
7
|
+
return joinURL("/__og-image__/image", pagePath, `og.${options.extension}`);
|
|
8
|
+
}
|
|
9
|
+
export function useOgImageRuntimeConfig() {
|
|
10
|
+
return useRuntimeConfig()["nuxt-og-image"];
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { InputFontConfig, OgImageOptions, ResolvedFontConfig } from './types';
|
|
2
|
+
export declare function isInternalRoute(path: string): boolean;
|
|
3
|
+
export declare function separateProps(options: OgImageOptions | undefined, ignoreKeys?: string[]): {
|
|
4
|
+
props: Record<string, any>;
|
|
5
|
+
};
|
|
6
|
+
export declare function normaliseFontInput(fonts: InputFontConfig[]): ResolvedFontConfig[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { defu } from "defu";
|
|
2
|
+
export function isInternalRoute(path) {
|
|
3
|
+
const lastSegment = path.split("/").pop() || path;
|
|
4
|
+
return lastSegment.includes(".") || path.startsWith("/__") || path.startsWith("@");
|
|
5
|
+
}
|
|
6
|
+
function filterIsOgImageOption(key) {
|
|
7
|
+
const keys = [
|
|
8
|
+
"url",
|
|
9
|
+
"extension",
|
|
10
|
+
"width",
|
|
11
|
+
"height",
|
|
12
|
+
"fonts",
|
|
13
|
+
"alt",
|
|
14
|
+
"props",
|
|
15
|
+
"renderer",
|
|
16
|
+
"html",
|
|
17
|
+
"component",
|
|
18
|
+
"renderer",
|
|
19
|
+
"emojis",
|
|
20
|
+
"satori",
|
|
21
|
+
"resvg",
|
|
22
|
+
"sharp",
|
|
23
|
+
"screenshot",
|
|
24
|
+
"cacheMaxAgeSeconds"
|
|
25
|
+
];
|
|
26
|
+
return keys.includes(key);
|
|
27
|
+
}
|
|
28
|
+
export function separateProps(options, ignoreKeys = []) {
|
|
29
|
+
options = options || {};
|
|
30
|
+
const _props = defu(options.props, Object.fromEntries(
|
|
31
|
+
Object.entries({ ...options }).filter(([k]) => !filterIsOgImageOption(k) && !ignoreKeys.includes(k))
|
|
32
|
+
));
|
|
33
|
+
const props = {};
|
|
34
|
+
Object.entries(_props).forEach(([key, val]) => {
|
|
35
|
+
props[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = val;
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
...Object.fromEntries(
|
|
39
|
+
Object.entries({ ...options }).filter(([k]) => filterIsOgImageOption(k) || ignoreKeys.includes(k))
|
|
40
|
+
),
|
|
41
|
+
props
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function normaliseFontInput(fonts) {
|
|
45
|
+
return fonts.map((f) => {
|
|
46
|
+
if (typeof f === "string") {
|
|
47
|
+
const [name, weight] = f.split(":");
|
|
48
|
+
return {
|
|
49
|
+
cacheKey: f,
|
|
50
|
+
name,
|
|
51
|
+
weight: weight || "400",
|
|
52
|
+
style: "normal",
|
|
53
|
+
path: void 0
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
cacheKey: f.key || `${f.name}:${f.weight}`,
|
|
58
|
+
style: "normal",
|
|
59
|
+
weight: 400,
|
|
60
|
+
...f
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-og-image",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-
|
|
5
|
-
"packageManager": "pnpm@8.
|
|
4
|
+
"version": "3.0.0-rc.1",
|
|
5
|
+
"packageManager": "pnpm@8.12.0",
|
|
6
6
|
"description": "Enlightened OG Image generation for Nuxt.",
|
|
7
|
+
"author": {
|
|
8
|
+
"website": "https://harlanzw.com",
|
|
9
|
+
"name": "Harlan Wilton",
|
|
10
|
+
"url": "harlan@harlanzw.com"
|
|
11
|
+
},
|
|
7
12
|
"license": "MIT",
|
|
8
13
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
9
14
|
"homepage": "https://github.com/harlan-zw/nuxt-og-image#readme",
|
|
@@ -24,82 +29,72 @@
|
|
|
24
29
|
"main": "./dist/module.cjs",
|
|
25
30
|
"types": "./dist/types.d.ts",
|
|
26
31
|
"files": [
|
|
27
|
-
"dist"
|
|
32
|
+
"dist",
|
|
33
|
+
"virtual.d.ts"
|
|
28
34
|
],
|
|
29
|
-
"resolutions": {
|
|
30
|
-
"nitropack": "npm:nitropack-nightly@2.8.1-28352923.b53e001"
|
|
31
|
-
},
|
|
32
35
|
"dependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
35
|
-
"@nuxt/devtools-kit": "^1.0.4",
|
|
36
|
+
"@iconify-json/noto": "^1.1.17",
|
|
37
|
+
"@nuxt/devtools-kit": "^1.0.5",
|
|
36
38
|
"@nuxt/kit": "^3.8.2",
|
|
37
39
|
"@resvg/resvg-js": "^2.6.0",
|
|
38
40
|
"@resvg/resvg-wasm": "^2.6.0",
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
41
|
-
"
|
|
42
|
-
"chalk": "^5.3.0",
|
|
41
|
+
"@unocss/core": "^0.58.0",
|
|
42
|
+
"@unocss/preset-wind": "^0.58.0",
|
|
43
|
+
"@vueuse/core": "^10.7.0",
|
|
43
44
|
"chrome-launcher": "^1.1.0",
|
|
44
45
|
"css-inline": "^0.11.0",
|
|
45
46
|
"defu": "^6.1.3",
|
|
46
47
|
"execa": "^8.0.1",
|
|
47
|
-
"fast-glob": "^3.3.2",
|
|
48
|
-
"flatted": "^3.2.9",
|
|
49
48
|
"floating-vue": "2.0.0-beta.24",
|
|
50
|
-
"fs-extra": "^11.2.0",
|
|
51
|
-
"globby": "^14.0.0",
|
|
52
49
|
"image-size": "^1.0.2",
|
|
53
|
-
"launch-editor": "^2.6.1",
|
|
54
50
|
"nuxt-site-config": "^1.6.6",
|
|
55
51
|
"nuxt-site-config-kit": "^1.6.6",
|
|
56
52
|
"nypm": "^0.3.3",
|
|
57
53
|
"ofetch": "^1.3.3",
|
|
58
54
|
"ohash": "^1.1.3",
|
|
59
55
|
"pathe": "^1.1.1",
|
|
60
|
-
"playwright-core": "^1.40.
|
|
56
|
+
"playwright-core": "^1.40.1",
|
|
61
57
|
"radix3": "^1.1.0",
|
|
62
58
|
"satori": "0.10.11",
|
|
63
59
|
"satori-html": "^0.3.2",
|
|
64
|
-
"sharp": "0.33.0-rc.2",
|
|
65
60
|
"sirv": "^2.0.3",
|
|
66
|
-
"std-env": "^3.
|
|
67
|
-
"svg2png-wasm": "^1.4.1",
|
|
61
|
+
"std-env": "^3.6.0",
|
|
68
62
|
"terminate": "^2.6.1",
|
|
69
|
-
"tinyws": "^0.1.0",
|
|
70
|
-
"twemoji": "^14.0.2",
|
|
71
63
|
"ufo": "^1.3.2",
|
|
72
|
-
"vue-component-meta": "^1.8.22",
|
|
73
|
-
"ws": "^8.14.2",
|
|
74
64
|
"yoga-wasm-web": "^0.3.3"
|
|
75
65
|
},
|
|
76
66
|
"devDependencies": {
|
|
77
|
-
"
|
|
78
|
-
"@antfu/eslint-config": "2.1.1",
|
|
79
|
-
"@img/sharp-linux-x64": "0.33.0-rc.2",
|
|
67
|
+
"@antfu/eslint-config": "2.4.3",
|
|
80
68
|
"@nuxt/content": "^2.9.0",
|
|
81
|
-
"@nuxt/devtools": "1.0.
|
|
69
|
+
"@nuxt/devtools": "1.0.5",
|
|
82
70
|
"@nuxt/module-builder": "^0.5.4",
|
|
83
71
|
"@nuxt/test-utils": "3.8.1",
|
|
72
|
+
"@nuxt/ui": "^2.11.0",
|
|
84
73
|
"@nuxtjs/eslint-config-typescript": "^12.1.0",
|
|
85
|
-
"@nuxtjs/i18n": "8.0.0-rc.
|
|
86
|
-
"@
|
|
74
|
+
"@nuxtjs/i18n": "8.0.0-rc.8",
|
|
75
|
+
"@nuxtjs/tailwindcss": "^6.10.1",
|
|
76
|
+
"@unocss/nuxt": "^0.58.0",
|
|
87
77
|
"bumpp": "^9.2.0",
|
|
88
|
-
"eslint": "8.
|
|
89
|
-
"jest-image-snapshot": "^6.
|
|
78
|
+
"eslint": "8.55.0",
|
|
79
|
+
"jest-image-snapshot": "^6.3.0",
|
|
90
80
|
"nuxt": "^3.8.2",
|
|
91
|
-
"nuxt-icon": "0.6.
|
|
92
|
-
"playwright": "^1.40.
|
|
81
|
+
"nuxt-icon": "0.6.7",
|
|
82
|
+
"playwright": "^1.40.1",
|
|
93
83
|
"sass": "^1.69.5",
|
|
94
|
-
"
|
|
84
|
+
"sharp": "^0.33.0",
|
|
85
|
+
"vitest": "^1.0.2"
|
|
95
86
|
},
|
|
96
87
|
"build": {
|
|
97
88
|
"externals": [
|
|
98
89
|
"h3",
|
|
99
|
-
"nitropack"
|
|
90
|
+
"nitropack",
|
|
91
|
+
"@vue/runtime-core",
|
|
92
|
+
"#nuxt-og-image/components",
|
|
93
|
+
"sharp"
|
|
100
94
|
]
|
|
101
95
|
},
|
|
102
96
|
"scripts": {
|
|
97
|
+
"stub": "nuxt-build-module build --stub",
|
|
103
98
|
"build": "pnpm dev:prepare && pnpm build:module && pnpm build:client",
|
|
104
99
|
"build:client": "nuxi generate client",
|
|
105
100
|
"build:module": "nuxt-build-module build",
|
package/virtual.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
declare module '#nuxt-og-image/components' {
|
|
2
|
+
import type { Component } from 'vue'
|
|
3
|
+
|
|
4
|
+
const components: Record<string, Component>
|
|
5
|
+
export default components
|
|
6
|
+
}
|
|
7
|
+
declare module '#nuxt-og-image/renderers/satori' {
|
|
8
|
+
import type Renderer from './src/runtime/types'
|
|
9
|
+
|
|
10
|
+
const renderer: Renderer | { __unenv__: true } | undefined
|
|
11
|
+
export default renderer
|
|
12
|
+
}
|
|
13
|
+
declare module '#nuxt-og-image/renderers/chromium' {
|
|
14
|
+
import type Renderer from './src/runtime/types'
|
|
15
|
+
|
|
16
|
+
const renderer: Renderer | { __unenv__: true } | undefined
|
|
17
|
+
export default renderer
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare module '#nuxt-og-image/bindings/satori' {
|
|
21
|
+
const satori: typeof import('satori').satori
|
|
22
|
+
export default satori
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare module '#nuxt-og-image/bindings/resvg' {
|
|
26
|
+
interface WasmResvg {
|
|
27
|
+
initWasmPromise: Promise<void>
|
|
28
|
+
Resvg: import('resvg').Resvg
|
|
29
|
+
}
|
|
30
|
+
const instance: WasmResvg
|
|
31
|
+
export default instance
|
|
32
|
+
}
|
|
33
|
+
declare module '#nuxt-og-image/bindings/chromium' {
|
|
34
|
+
export const createBrowser: () => Promise<Browser | void>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare module '#nuxt-og-image/bindings/css-inline' {
|
|
38
|
+
import type _CssInline from 'css-inline'
|
|
39
|
+
|
|
40
|
+
const cssInline: _CssInline
|
|
41
|
+
export default cssInline
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare module '#nuxt-og-image/bindings/sharp' {
|
|
45
|
+
import type _sharp from 'sharp'
|
|
46
|
+
|
|
47
|
+
const sharp: _sharp
|
|
48
|
+
export default sharp
|
|
49
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{g as _,h as m,i as f,j as c,r as d,o as I,c as v,n as x,_ as S}from"./entry.d927023c.js";const y=_({__name:"IconCSS",props:{name:{type:String,required:!0},size:{type:String,default:""}},setup(u){m(e=>({f4b1dbd8:p.value}));const t=f(),s=u,l=c(()=>{var e,n;return(n=(e=t.nuxtIcon)==null?void 0:e.aliases)!=null&&n[s.name]?t.nuxtIcon.aliases[s.name]:s.name}),r=c(()=>d(l.value)),p=c(()=>{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"}/${r.value.prefix}/${r.value.name}.svg')`}),i=c(()=>{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)=>(I(),v("span",{style:x({width:i.value,height:i.value})},null,4))}});const C=S(y,[["__scopeId","data-v-2408e4e8"]]);export{C as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
span[data-v-2408e4e8]{background-color:currentColor;display:inline-block;-webkit-mask-image:var(--f4b1dbd8);mask-image:var(--f4b1dbd8);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;vertical-align:middle}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"ce33a6eb-5cc2-4c46-8618-9befaa3f226c","timestamp":1701255996639,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|