nuxt-og-image 5.1.10 → 5.1.12

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 (195) hide show
  1. package/dist/client/200.html +1 -0
  2. package/dist/client/404.html +1 -0
  3. package/dist/client/_nuxt/B8PEiB0p.js +1 -0
  4. package/dist/client/_nuxt/CD9VIl4i.js +4062 -0
  5. package/dist/client/_nuxt/CI_lqgv7.js +1 -0
  6. package/dist/client/_nuxt/CVO1_9PV.js +1 -0
  7. package/dist/client/_nuxt/Cp-IABpG.js +1 -0
  8. package/dist/client/_nuxt/D0r3Knsf.js +1 -0
  9. package/dist/client/_nuxt/Dz8kdfgF.js +1 -0
  10. package/dist/client/_nuxt/builds/latest.json +1 -0
  11. package/dist/client/_nuxt/builds/meta/71b0f7ea-9aae-4c28-bbd9-8eea71b82dfb.json +1 -0
  12. package/dist/client/_nuxt/entry.DNM8P-MU.css +1 -0
  13. package/dist/client/_nuxt/error-404.C2mGI6Vt.css +1 -0
  14. package/dist/client/_nuxt/error-500.ClHbVBiL.css +1 -0
  15. package/dist/client/_nuxt/l5rcX3cq.js +8 -0
  16. package/dist/client/index.html +1 -0
  17. package/dist/content.cjs +22 -0
  18. package/dist/content.d.cts +46 -0
  19. package/dist/content.d.mts +46 -0
  20. package/dist/content.d.ts +46 -0
  21. package/dist/content.mjs +18 -0
  22. package/dist/module.cjs +1027 -0
  23. package/dist/module.d.cts +109 -0
  24. package/dist/module.d.mts +109 -0
  25. package/dist/module.d.ts +109 -0
  26. package/dist/module.json +12 -0
  27. package/dist/module.mjs +1007 -0
  28. package/dist/runtime/app/components/OgImage/OgImage.d.ts +3 -0
  29. package/dist/runtime/app/components/OgImage/OgImage.js +10 -0
  30. package/dist/runtime/app/components/OgImage/OgImageScreenshot.d.ts +3 -0
  31. package/dist/runtime/app/components/OgImage/OgImageScreenshot.js +10 -0
  32. package/dist/runtime/app/components/Templates/Community/BrandedLogo.d.vue.ts +13 -0
  33. package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue +22 -0
  34. package/dist/runtime/app/components/Templates/Community/BrandedLogo.vue.d.ts +13 -0
  35. package/dist/runtime/app/components/Templates/Community/Frame.d.vue.ts +21 -0
  36. package/dist/runtime/app/components/Templates/Community/Frame.vue +58 -0
  37. package/dist/runtime/app/components/Templates/Community/Frame.vue.d.ts +21 -0
  38. package/dist/runtime/app/components/Templates/Community/Nuxt.d.vue.ts +12 -0
  39. package/dist/runtime/app/components/Templates/Community/Nuxt.vue +179 -0
  40. package/dist/runtime/app/components/Templates/Community/Nuxt.vue.d.ts +12 -0
  41. package/dist/runtime/app/components/Templates/Community/NuxtSeo.d.vue.ts +15 -0
  42. package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue +103 -0
  43. package/dist/runtime/app/components/Templates/Community/NuxtSeo.vue.d.ts +15 -0
  44. package/dist/runtime/app/components/Templates/Community/Pergel.d.vue.ts +12 -0
  45. package/dist/runtime/app/components/Templates/Community/Pergel.vue +98 -0
  46. package/dist/runtime/app/components/Templates/Community/Pergel.vue.d.ts +12 -0
  47. package/dist/runtime/app/components/Templates/Community/SimpleBlog.d.vue.ts +9 -0
  48. package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue +27 -0
  49. package/dist/runtime/app/components/Templates/Community/SimpleBlog.vue.d.ts +9 -0
  50. package/dist/runtime/app/components/Templates/Community/UnJs.d.vue.ts +21 -0
  51. package/dist/runtime/app/components/Templates/Community/UnJs.vue +99 -0
  52. package/dist/runtime/app/components/Templates/Community/UnJs.vue.d.ts +21 -0
  53. package/dist/runtime/app/components/Templates/Community/Wave.d.vue.ts +11 -0
  54. package/dist/runtime/app/components/Templates/Community/Wave.vue +28 -0
  55. package/dist/runtime/app/components/Templates/Community/Wave.vue.d.ts +11 -0
  56. package/dist/runtime/app/components/Templates/Community/WithEmoji.d.vue.ts +13 -0
  57. package/dist/runtime/app/components/Templates/Community/WithEmoji.vue +21 -0
  58. package/dist/runtime/app/components/Templates/Community/WithEmoji.vue.d.ts +13 -0
  59. package/dist/runtime/app/composables/defineOgImage.d.ts +2 -0
  60. package/dist/runtime/app/composables/defineOgImage.js +43 -0
  61. package/dist/runtime/app/composables/defineOgImageComponent.d.ts +3 -0
  62. package/dist/runtime/app/composables/defineOgImageComponent.js +8 -0
  63. package/dist/runtime/app/composables/defineOgImageScreenshot.d.ts +2 -0
  64. package/dist/runtime/app/composables/defineOgImageScreenshot.js +14 -0
  65. package/dist/runtime/app/composables/mock.d.ts +5 -0
  66. package/dist/runtime/app/composables/mock.js +20 -0
  67. package/dist/runtime/app/plugins/__zero-runtime/og-image-canonical-urls.server.d.ts +2 -0
  68. package/dist/runtime/app/plugins/__zero-runtime/og-image-canonical-urls.server.js +9 -0
  69. package/dist/runtime/app/plugins/__zero-runtime/route-rule-og-image.server.d.ts +2 -0
  70. package/dist/runtime/app/plugins/__zero-runtime/route-rule-og-image.server.js +9 -0
  71. package/dist/runtime/app/plugins/og-image-canonical-urls.server.d.ts +2 -0
  72. package/dist/runtime/app/plugins/og-image-canonical-urls.server.js +7 -0
  73. package/dist/runtime/app/plugins/route-rule-og-image.server.d.ts +2 -0
  74. package/dist/runtime/app/plugins/route-rule-og-image.server.js +7 -0
  75. package/dist/runtime/app/utils/plugins.d.ts +3 -0
  76. package/dist/runtime/app/utils/plugins.js +92 -0
  77. package/dist/runtime/app/utils.d.ts +7 -0
  78. package/dist/runtime/app/utils.js +94 -0
  79. package/dist/runtime/assets/Inter-normal-400.ttf.base64 +1 -0
  80. package/dist/runtime/assets/Inter-normal-700.ttf.base64 +1 -0
  81. package/dist/runtime/logger.d.ts +2 -0
  82. package/dist/runtime/logger.js +8 -0
  83. package/dist/runtime/mock/empty.d.ts +2 -0
  84. package/dist/runtime/mock/empty.js +2 -0
  85. package/dist/runtime/mock/proxy-cjs.d.ts +2 -0
  86. package/dist/runtime/mock/proxy-cjs.js +2 -0
  87. package/dist/runtime/server/og-image/bindings/chromium/chrome-launcher.d.ts +2 -0
  88. package/dist/runtime/server/og-image/bindings/chromium/chrome-launcher.js +9 -0
  89. package/dist/runtime/server/og-image/bindings/chromium/on-demand.d.ts +2 -0
  90. package/dist/runtime/server/og-image/bindings/chromium/on-demand.js +40 -0
  91. package/dist/runtime/server/og-image/bindings/chromium/playwright.d.ts +2 -0
  92. package/dist/runtime/server/og-image/bindings/chromium/playwright.js +6 -0
  93. package/dist/runtime/server/og-image/bindings/css-inline/node.d.ts +8 -0
  94. package/dist/runtime/server/og-image/bindings/css-inline/node.js +7 -0
  95. package/dist/runtime/server/og-image/bindings/css-inline/wasm-fs.d.ts +7 -0
  96. package/dist/runtime/server/og-image/bindings/css-inline/wasm-fs.js +8 -0
  97. package/dist/runtime/server/og-image/bindings/css-inline/wasm.d.ts +7 -0
  98. package/dist/runtime/server/og-image/bindings/css-inline/wasm.js +7 -0
  99. package/dist/runtime/server/og-image/bindings/resvg/node.d.ts +6 -0
  100. package/dist/runtime/server/og-image/bindings/resvg/node.js +5 -0
  101. package/dist/runtime/server/og-image/bindings/resvg/wasm-fs.d.ts +40 -0
  102. package/dist/runtime/server/og-image/bindings/resvg/wasm-fs.js +6 -0
  103. package/dist/runtime/server/og-image/bindings/resvg/wasm.d.ts +40 -0
  104. package/dist/runtime/server/og-image/bindings/resvg/wasm.js +5 -0
  105. package/dist/runtime/server/og-image/bindings/satori/node.d.ts +6 -0
  106. package/dist/runtime/server/og-image/bindings/satori/node.js +5 -0
  107. package/dist/runtime/server/og-image/bindings/satori/wasm-fs.d.ts +6 -0
  108. package/dist/runtime/server/og-image/bindings/satori/wasm-fs.js +13 -0
  109. package/dist/runtime/server/og-image/bindings/satori/wasm.d.ts +6 -0
  110. package/dist/runtime/server/og-image/bindings/satori/wasm.js +13 -0
  111. package/dist/runtime/server/og-image/bindings/sharp/node.d.ts +2 -0
  112. package/dist/runtime/server/og-image/bindings/sharp/node.js +2 -0
  113. package/dist/runtime/server/og-image/cache/lru.d.ts +9 -0
  114. package/dist/runtime/server/og-image/cache/lru.js +15 -0
  115. package/dist/runtime/server/og-image/cache/mock.d.ts +9 -0
  116. package/dist/runtime/server/og-image/cache/mock.js +9 -0
  117. package/dist/runtime/server/og-image/chromium/renderer.d.ts +3 -0
  118. package/dist/runtime/server/og-image/chromium/renderer.js +24 -0
  119. package/dist/runtime/server/og-image/chromium/screenshot.d.ts +4 -0
  120. package/dist/runtime/server/og-image/chromium/screenshot.js +54 -0
  121. package/dist/runtime/server/og-image/context.d.ts +5 -0
  122. package/dist/runtime/server/og-image/context.js +283 -0
  123. package/dist/runtime/server/og-image/instances.d.ts +2 -0
  124. package/dist/runtime/server/og-image/instances.js +10 -0
  125. package/dist/runtime/server/og-image/satori/font.d.ts +3 -0
  126. package/dist/runtime/server/og-image/satori/font.js +40 -0
  127. package/dist/runtime/server/og-image/satori/instances.d.ts +41 -0
  128. package/dist/runtime/server/og-image/satori/instances.js +23 -0
  129. package/dist/runtime/server/og-image/satori/plugins/classes.d.ts +2 -0
  130. package/dist/runtime/server/og-image/satori/plugins/classes.js +17 -0
  131. package/dist/runtime/server/og-image/satori/plugins/emojis.d.ts +2 -0
  132. package/dist/runtime/server/og-image/satori/plugins/emojis.js +28 -0
  133. package/dist/runtime/server/og-image/satori/plugins/encoding.d.ts +2 -0
  134. package/dist/runtime/server/og-image/satori/plugins/encoding.js +17 -0
  135. package/dist/runtime/server/og-image/satori/plugins/flex.d.ts +2 -0
  136. package/dist/runtime/server/og-image/satori/plugins/flex.js +60 -0
  137. package/dist/runtime/server/og-image/satori/plugins/imageSrc.d.ts +2 -0
  138. package/dist/runtime/server/og-image/satori/plugins/imageSrc.js +107 -0
  139. package/dist/runtime/server/og-image/satori/plugins/nuxt-icon.d.ts +2 -0
  140. package/dist/runtime/server/og-image/satori/plugins/nuxt-icon.js +20 -0
  141. package/dist/runtime/server/og-image/satori/plugins/unocss.d.ts +2 -0
  142. package/dist/runtime/server/og-image/satori/plugins/unocss.js +55 -0
  143. package/dist/runtime/server/og-image/satori/renderer.d.ts +4 -0
  144. package/dist/runtime/server/og-image/satori/renderer.js +123 -0
  145. package/dist/runtime/server/og-image/satori/transforms/emojis.d.ts +3 -0
  146. package/dist/runtime/server/og-image/satori/transforms/emojis.js +3595 -0
  147. package/dist/runtime/server/og-image/satori/transforms/inlineCss.d.ts +3 -0
  148. package/dist/runtime/server/og-image/satori/transforms/inlineCss.js +51 -0
  149. package/dist/runtime/server/og-image/satori/utils.d.ts +3 -0
  150. package/dist/runtime/server/og-image/satori/utils.js +24 -0
  151. package/dist/runtime/server/og-image/satori/vnodes.d.ts +2 -0
  152. package/dist/runtime/server/og-image/satori/vnodes.js +40 -0
  153. package/dist/runtime/server/og-image/templates/html.d.ts +2 -0
  154. package/dist/runtime/server/og-image/templates/html.js +112 -0
  155. package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.d.ts +2 -0
  156. package/dist/runtime/server/plugins/__zero-runtime/nuxt-content-v2.js +9 -0
  157. package/dist/runtime/server/plugins/nuxt-content-v2.d.ts +2 -0
  158. package/dist/runtime/server/plugins/nuxt-content-v2.js +5 -0
  159. package/dist/runtime/server/plugins/prerender.d.ts +2 -0
  160. package/dist/runtime/server/plugins/prerender.js +38 -0
  161. package/dist/runtime/server/routes/__zero-runtime/font.d.ts +2 -0
  162. package/dist/runtime/server/routes/__zero-runtime/font.js +8 -0
  163. package/dist/runtime/server/routes/__zero-runtime/image.d.ts +2 -0
  164. package/dist/runtime/server/routes/__zero-runtime/image.js +8 -0
  165. package/dist/runtime/server/routes/debug.json.d.ts +7 -0
  166. package/dist/runtime/server/routes/debug.json.js +15 -0
  167. package/dist/runtime/server/routes/font.d.ts +2 -0
  168. package/dist/runtime/server/routes/font.js +3 -0
  169. package/dist/runtime/server/routes/image.d.ts +2 -0
  170. package/dist/runtime/server/routes/image.js +3 -0
  171. package/dist/runtime/server/tsconfig.json +3 -0
  172. package/dist/runtime/server/util/cache.d.ts +10 -0
  173. package/dist/runtime/server/util/cache.js +74 -0
  174. package/dist/runtime/server/util/encoding.d.ts +3 -0
  175. package/dist/runtime/server/util/encoding.js +15 -0
  176. package/dist/runtime/server/util/eventHandlers.d.ts +3 -0
  177. package/dist/runtime/server/util/eventHandlers.js +156 -0
  178. package/dist/runtime/server/util/kit.d.ts +6 -0
  179. package/dist/runtime/server/util/kit.js +32 -0
  180. package/dist/runtime/server/util/logger.d.ts +1 -0
  181. package/dist/runtime/server/util/logger.js +6 -0
  182. package/dist/runtime/server/util/options.d.ts +2 -0
  183. package/dist/runtime/server/util/options.js +18 -0
  184. package/dist/runtime/server/util/plugins.d.ts +2 -0
  185. package/dist/runtime/server/util/plugins.js +56 -0
  186. package/dist/runtime/server/util/wasm.d.ts +2 -0
  187. package/dist/runtime/server/util/wasm.js +16 -0
  188. package/dist/runtime/server/utils.d.ts +4 -0
  189. package/dist/runtime/server/utils.js +20 -0
  190. package/dist/runtime/shared.d.ts +15 -0
  191. package/dist/runtime/shared.js +132 -0
  192. package/dist/runtime/types.d.ts +187 -0
  193. package/dist/runtime/types.js +0 -0
  194. package/dist/types.d.mts +9 -0
  195. package/package.json +32 -32
@@ -0,0 +1,156 @@
1
+ import { createError, getQuery, H3Error, proxyRequest, sendRedirect, setHeader, setResponseHeader } from "h3";
2
+ import { parseURL } from "ufo";
3
+ import { normaliseFontInput } from "../../shared.js";
4
+ import { resolveContext } from "../og-image/context.js";
5
+ import { assets } from "../og-image/satori/font.js";
6
+ import { html } from "../og-image/templates/html.js";
7
+ import { useOgImageRuntimeConfig } from "../utils.js";
8
+ import { useOgImageBufferCache } from "./cache.js";
9
+ export async function fontEventHandler(e) {
10
+ const path = parseURL(e.path).pathname;
11
+ const { fonts } = useOgImageRuntimeConfig();
12
+ const key = path.split("/font/")[1];
13
+ if (key && key.includes(":")) {
14
+ const font2 = fonts.find((f) => f.key === key);
15
+ if (font2?.key && await assets.hasItem(font2.key)) {
16
+ let fontData = await assets.getItem(font2.key);
17
+ if (fontData instanceof Uint8Array) {
18
+ const decoder = new TextDecoder();
19
+ fontData = decoder.decode(fontData);
20
+ }
21
+ if (key.includes(".oft")) {
22
+ setResponseHeader(e, "Content-Type", "font/otf");
23
+ } else if (key.includes(".woff2")) {
24
+ setResponseHeader(e, "Content-Type", "font/woff2");
25
+ } else if (key.includes(".ttf")) {
26
+ setResponseHeader(e, "Content-Type", "font/ttf");
27
+ }
28
+ return Buffer.from(fontData, "base64");
29
+ }
30
+ }
31
+ const [_name, _weight] = String(key?.split(".")[0]).split("/");
32
+ if (!_name || !_weight)
33
+ return "Provide a font name and weight";
34
+ const name = String(_name[0]).toUpperCase() + _name.slice(1);
35
+ const weight = Math.round(Number.parseInt(_weight) / 100) * 100;
36
+ const config = useOgImageRuntimeConfig();
37
+ const normalisedFonts = normaliseFontInput(config.fonts);
38
+ let font;
39
+ if (typeof getQuery(e).font === "string")
40
+ font = JSON.parse(getQuery(e).font);
41
+ if (!font) {
42
+ font = normalisedFonts.find((font2) => {
43
+ return font2.name.toLowerCase() === name.toLowerCase() && weight === Number(font2.weight);
44
+ });
45
+ }
46
+ if (!font) {
47
+ return createError({
48
+ statusCode: 404,
49
+ statusMessage: `[Nuxt OG Image] Font ${name}:${weight} not found`
50
+ });
51
+ }
52
+ const css = await globalThis.$fetch(`https://fonts.googleapis.com/css2?family=${name}:wght@${weight}`, {
53
+ headers: {
54
+ // Make sure it returns TTF.
55
+ "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
56
+ }
57
+ });
58
+ if (!css) {
59
+ return createError({
60
+ statusCode: 500,
61
+ statusMessage: `[Nuxt OG Image] Invalid Google Font ${name}:${weight}`
62
+ });
63
+ }
64
+ const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
65
+ if (ttfResource?.[1])
66
+ return proxyRequest(e, ttfResource[1], {});
67
+ const woff2Resource = css.match(/src: url\((.+)\) format\('woff2'\)/);
68
+ if (woff2Resource?.[1])
69
+ return sendRedirect(e, woff2Resource[1]);
70
+ return createError({
71
+ statusCode: 500,
72
+ statusMessage: `[Nuxt OG Image] Malformed Google Font CSS ${css}`
73
+ });
74
+ }
75
+ export async function imageEventHandler(e) {
76
+ const ctx = await resolveContext(e);
77
+ if (ctx instanceof H3Error)
78
+ return ctx;
79
+ const { isDebugJsonPayload, extension, options, renderer } = ctx;
80
+ const { debug, baseCacheKey } = useOgImageRuntimeConfig();
81
+ const compatibilityHints = [];
82
+ if (isDebugJsonPayload) {
83
+ const queryExtension = getQuery(e).extension || ctx.options.extension;
84
+ if (["jpeg", "jpg"].includes(queryExtension) && options.renderer === "satori")
85
+ compatibilityHints.push("Converting PNGs to JPEGs requires Sharp which only runs on Node based systems.");
86
+ if (options.renderer === "chromium")
87
+ 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");
88
+ setHeader(e, "Content-Type", "application/json");
89
+ return {
90
+ siteConfig: {
91
+ url: e.context.siteConfig.get().url
92
+ },
93
+ compatibilityHints,
94
+ cacheKey: ctx.key,
95
+ options: ctx.options,
96
+ ...options.renderer === "satori" ? await renderer.debug(ctx) : void 0
97
+ };
98
+ }
99
+ switch (extension) {
100
+ case "html":
101
+ setHeader(e, "Content-Type", `text/html`);
102
+ return html(ctx);
103
+ case "svg":
104
+ if (!debug && !import.meta.dev) {
105
+ return createError({
106
+ statusCode: 404
107
+ });
108
+ }
109
+ if (ctx.renderer.name !== "satori") {
110
+ return createError({
111
+ statusCode: 400,
112
+ statusMessage: `[Nuxt OG Image] Generating ${extension}'s with ${renderer.name} is not supported.`
113
+ });
114
+ }
115
+ setHeader(e, "Content-Type", `image/svg+xml`);
116
+ return (await ctx.renderer.debug(ctx)).svg;
117
+ case "png":
118
+ case "jpeg":
119
+ case "jpg":
120
+ if (!renderer.supportedFormats.includes(extension)) {
121
+ return createError({
122
+ statusCode: 400,
123
+ statusMessage: `[Nuxt OG Image] Generating ${extension}'s with ${renderer.name} is not supported.`
124
+ });
125
+ }
126
+ setHeader(e, "Content-Type", `image/${extension === "jpg" ? "jpeg" : extension}`);
127
+ break;
128
+ default:
129
+ return createError({
130
+ statusCode: 400,
131
+ statusMessage: `[Nuxt OG Image] Invalid request for og.${extension}.`
132
+ });
133
+ }
134
+ const cacheApi = await useOgImageBufferCache(ctx, {
135
+ cacheMaxAgeSeconds: ctx.options.cacheMaxAgeSeconds,
136
+ baseCacheKey
137
+ });
138
+ if (typeof cacheApi === "undefined")
139
+ return;
140
+ if (cacheApi instanceof H3Error)
141
+ return cacheApi;
142
+ let image = cacheApi.cachedItem;
143
+ if (!image) {
144
+ image = await renderer.createImage(ctx);
145
+ if (image instanceof H3Error)
146
+ return image;
147
+ if (!image) {
148
+ return createError({
149
+ statusCode: 500,
150
+ statusMessage: `Failed to generate og.${extension}.`
151
+ });
152
+ }
153
+ await cacheApi.update(image);
154
+ }
155
+ return image;
156
+ }
@@ -0,0 +1,6 @@
1
+ import type { H3Event } from 'h3';
2
+ import type { NitroRouteRules } from 'nitropack';
3
+ import type { NuxtIslandResponse } from 'nuxt/app';
4
+ export declare function fetchIsland(e: H3Event, component: string, props: Record<string, any>): Promise<NuxtIslandResponse>;
5
+ export declare function withoutQuery(path: string): string | undefined;
6
+ export declare function createNitroRouteRuleMatcher(): ((path: string) => NitroRouteRules);
@@ -0,0 +1,32 @@
1
+ import { defu } from "defu";
2
+ import { useRuntimeConfig } from "nitropack/runtime";
3
+ import { hash } from "ohash";
4
+ import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
5
+ import { withoutBase, withoutTrailingSlash } from "ufo";
6
+ export function fetchIsland(e, component, props) {
7
+ const hashId = hash([component, props]).replaceAll("_", "-");
8
+ return e.$fetch(`/__nuxt_island/${component}_${hashId}.json`, {
9
+ params: {
10
+ props: JSON.stringify(props)
11
+ }
12
+ });
13
+ }
14
+ export function withoutQuery(path) {
15
+ return path.split("?")[0];
16
+ }
17
+ export function createNitroRouteRuleMatcher() {
18
+ const { nitro, app } = useRuntimeConfig();
19
+ const _routeRulesMatcher = toRouteMatcher(
20
+ createRadixRouter({
21
+ routes: Object.fromEntries(
22
+ Object.entries(nitro?.routeRules || {}).map(([path, rules]) => [withoutTrailingSlash(path), rules])
23
+ )
24
+ })
25
+ );
26
+ return (path) => {
27
+ return defu({}, ..._routeRulesMatcher.matchAll(
28
+ // radix3 does not support trailing slashes
29
+ withoutBase(withoutTrailingSlash(withoutQuery(path)), app.baseURL)
30
+ ).reverse());
31
+ };
32
+ }
@@ -0,0 +1 @@
1
+ export declare const logger: import("consola").ConsolaInstance;
@@ -0,0 +1,6 @@
1
+ import { createConsola } from "consola";
2
+ export const logger = createConsola({
3
+ defaults: {
4
+ tag: "Nuxt OG Image"
5
+ }
6
+ });
@@ -0,0 +1,2 @@
1
+ import type { DefineOgImageInput, OgImageOptions, OgImagePrebuilt } from '../../types.js';
2
+ export declare function normaliseOptions(_options: DefineOgImageInput): OgImageOptions | OgImagePrebuilt;
@@ -0,0 +1,18 @@
1
+ import { componentNames } from "#og-image-virtual/component-names.mjs";
2
+ export function normaliseOptions(_options) {
3
+ const options = { ..._options };
4
+ if (!options)
5
+ return options;
6
+ if (options.component && componentNames) {
7
+ const originalName = options.component;
8
+ for (const component of componentNames) {
9
+ if (component.pascalName.endsWith(originalName) || component.kebabName.endsWith(originalName)) {
10
+ options.component = component.pascalName;
11
+ break;
12
+ }
13
+ }
14
+ } else if (!options.component) {
15
+ options.component = componentNames[0]?.pascalName;
16
+ }
17
+ return options;
18
+ }
@@ -0,0 +1,2 @@
1
+ import type { NitroApp } from 'nitropack/runtime/app';
2
+ export declare function nuxtContentPlugin(nitroApp: NitroApp): void;
@@ -0,0 +1,56 @@
1
+ import { defu } from "defu";
2
+ import { stringify } from "devalue";
3
+ import { withQuery } from "ufo";
4
+ import { generateMeta } from "../../shared.js";
5
+ import { getOgImagePath, useOgImageRuntimeConfig } from "../utils.js";
6
+ import { normaliseOptions } from "./options.js";
7
+ export function nuxtContentPlugin(nitroApp) {
8
+ const { isNuxtContentDocumentDriven, strictNuxtContentPaths, defaults } = useOgImageRuntimeConfig();
9
+ nitroApp.hooks.hook("content:file:afterParse", async (content) => {
10
+ if (content._draft || content._extension !== "md" || content._partial || content.indexable === false || content.index === false)
11
+ return;
12
+ let path = content.path;
13
+ if (isNuxtContentDocumentDriven && !path)
14
+ path = content._path;
15
+ let shouldRenderOgImage = !!content.ogImage;
16
+ if (typeof content.ogImage === "undefined" && (strictNuxtContentPaths || typeof content.path !== "undefined")) {
17
+ shouldRenderOgImage = true;
18
+ }
19
+ if (path && shouldRenderOgImage) {
20
+ const ogImageConfig = (typeof content.ogImage === "object" ? content.ogImage : {}) || {};
21
+ const optionsWithDefault = defu(ogImageConfig, defaults);
22
+ let src = optionsWithDefault.url || getOgImagePath(path, optionsWithDefault);
23
+ if (optionsWithDefault._query && Object.keys(optionsWithDefault._query).length)
24
+ src = withQuery(src, { _query: optionsWithDefault._query });
25
+ const meta = generateMeta(src, ogImageConfig);
26
+ if (optionsWithDefault.url) {
27
+ content.head = defu({ meta }, content.head);
28
+ return content;
29
+ }
30
+ const payload = {
31
+ title: content.title,
32
+ excerpt: content.description || content.excerpt,
33
+ ...content.ogImage
34
+ };
35
+ Object.entries(ogImageConfig).forEach(([key, val]) => {
36
+ payload[key.replace(/-([a-z])/g, (g) => String(g[1]).toUpperCase())] = val;
37
+ });
38
+ content.head = defu({
39
+ script: [
40
+ {
41
+ id: "nuxt-og-image-overrides",
42
+ type: "application/json",
43
+ processTemplateParams: true,
44
+ innerHTML: stringify(normaliseOptions(payload)),
45
+ // we want this to be last in our head
46
+ tagPosition: "bodyClose",
47
+ tagPriority: 30
48
+ // slighty higher priority
49
+ }
50
+ ],
51
+ meta: generateMeta(src, optionsWithDefault)
52
+ }, content.head);
53
+ }
54
+ return content;
55
+ });
56
+ }
@@ -0,0 +1,2 @@
1
+ export declare function importWasm(input: any): Promise<any>;
2
+ export declare function readWasmFile(input: string): Promise<Buffer<ArrayBufferLike>>;
@@ -0,0 +1,16 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { resolvePath } from "mlly";
3
+ export async function importWasm(input) {
4
+ const _input = await input;
5
+ const _module = _input.default || _input;
6
+ if (typeof _module === "function") {
7
+ const fnRes = await _module();
8
+ const _instance = fnRes.instance || fnRes;
9
+ return _instance.exports || _instance || _module;
10
+ }
11
+ return _module;
12
+ }
13
+ export async function readWasmFile(input) {
14
+ const path = await resolvePath(input);
15
+ return readFile(path);
16
+ }
@@ -0,0 +1,4 @@
1
+ import type { OgImageOptions, OgImageRuntimeConfig } from '#og-image/types';
2
+ import type { H3Event } from 'h3';
3
+ export declare function getOgImagePath(pagePath: string, _options?: Partial<OgImageOptions>): string;
4
+ export declare function useOgImageRuntimeConfig(e?: H3Event): OgImageRuntimeConfig;
@@ -0,0 +1,20 @@
1
+ import { useRuntimeConfig } from "nitropack/runtime";
2
+ import { joinURL, withQuery } from "ufo";
3
+ export function getOgImagePath(pagePath, _options) {
4
+ const baseURL = useRuntimeConfig().app.baseURL;
5
+ const extension = _options?.extension || useOgImageRuntimeConfig().defaults.extension;
6
+ const path = joinURL("/", baseURL, `__og-image__/${import.meta.prerender ? "static" : "image"}`, pagePath, `og.${extension}`);
7
+ if (Object.keys(_options?._query || {}).length) {
8
+ return withQuery(path, _options._query);
9
+ }
10
+ return path;
11
+ }
12
+ export function useOgImageRuntimeConfig(e) {
13
+ const c = useRuntimeConfig(e);
14
+ return {
15
+ ...c["nuxt-og-image"],
16
+ app: {
17
+ baseURL: c.app.baseURL
18
+ }
19
+ };
20
+ }
@@ -0,0 +1,15 @@
1
+ import type { ResolvableMeta } from '@unhead/vue';
2
+ import type { InputFontConfig, OgImageOptions, OgImagePrebuilt, ResolvedFontConfig } from './types.js';
3
+ export declare function generateMeta(url: OgImagePrebuilt['url'] | string, resolvedOptions: OgImageOptions | OgImagePrebuilt): ResolvableMeta[];
4
+ export declare function toBase64Image(data: string | ArrayBuffer): string;
5
+ export declare function isInternalRoute(path: string): boolean;
6
+ export declare function separateProps(options: OgImageOptions | undefined, ignoreKeys?: string[]): {
7
+ props: Record<string, any>;
8
+ };
9
+ export declare function normaliseFontInput(fonts: InputFontConfig[]): ResolvedFontConfig[];
10
+ export declare function withoutQuery(path: string): string | undefined;
11
+ export declare function getExtension(path: string): string;
12
+ /**
13
+ * @deprecated Please use `#og-image/app/utils` instead.
14
+ */
15
+ export declare function useOgImageRuntimeConfig(): {};
@@ -0,0 +1,132 @@
1
+ import { defu } from "defu";
2
+ import { toValue } from "vue";
3
+ export function generateMeta(url, resolvedOptions) {
4
+ const meta = [
5
+ { property: "og:image", content: url },
6
+ { property: "og:image:type", content: () => `image/${getExtension(toValue(url)) || resolvedOptions.extension}` },
7
+ { name: "twitter:card", content: "summary_large_image" },
8
+ // we don't need this but avoids issue when using useSeoMeta({ twitterImage })
9
+ { name: "twitter:image", content: url },
10
+ { name: "twitter:image:src", content: url }
11
+ ];
12
+ if (resolvedOptions.width) {
13
+ meta.push({ property: "og:image:width", content: resolvedOptions.width });
14
+ meta.push({ name: "twitter:image:width", content: resolvedOptions.width });
15
+ }
16
+ if (resolvedOptions.height) {
17
+ meta.push({ property: "og:image:height", content: resolvedOptions.height });
18
+ meta.push({ name: "twitter:image:height", content: resolvedOptions.height });
19
+ }
20
+ if (resolvedOptions.alt) {
21
+ meta.push({ property: "og:image:alt", content: resolvedOptions.alt });
22
+ meta.push({ name: "twitter:image:alt", content: resolvedOptions.alt });
23
+ }
24
+ return meta;
25
+ }
26
+ function detectBase64MimeType(data) {
27
+ const signatures = {
28
+ "R0lGODdh": "image/gif",
29
+ "R0lGODlh": "image/gif",
30
+ "iVBORw0KGgo": "image/png",
31
+ "/9j/": "image/jpeg",
32
+ "UklGR": "image/webp",
33
+ "AAABAA": "image/x-icon"
34
+ };
35
+ for (const s in signatures) {
36
+ if (data.startsWith(s)) {
37
+ return signatures[s];
38
+ }
39
+ }
40
+ return "image/svg+xml";
41
+ }
42
+ export function toBase64Image(data) {
43
+ const base64 = typeof data === "string" ? data : Buffer.from(data).toString("base64");
44
+ const type = detectBase64MimeType(base64);
45
+ return `data:${type};base64,${base64}`;
46
+ }
47
+ export function isInternalRoute(path) {
48
+ return path.startsWith("/_") || path.startsWith("@");
49
+ }
50
+ function filterIsOgImageOption(key) {
51
+ const keys = [
52
+ "url",
53
+ "extension",
54
+ "width",
55
+ "height",
56
+ "fonts",
57
+ "alt",
58
+ "props",
59
+ "renderer",
60
+ "html",
61
+ "component",
62
+ "renderer",
63
+ "emojis",
64
+ "_query",
65
+ "satori",
66
+ "resvg",
67
+ "sharp",
68
+ "screenshot",
69
+ "cacheMaxAgeSeconds"
70
+ ];
71
+ return keys.includes(key);
72
+ }
73
+ export function separateProps(options, ignoreKeys = []) {
74
+ options = options || {};
75
+ const _props = defu(options.props, Object.fromEntries(
76
+ Object.entries({ ...options }).filter(([k]) => !filterIsOgImageOption(k) && !ignoreKeys.includes(k))
77
+ ));
78
+ const props = {};
79
+ Object.entries(_props).forEach(([key, val]) => {
80
+ props[key.replace(/-([a-z])/g, (g) => String(g[1]).toUpperCase())] = val;
81
+ });
82
+ return {
83
+ ...Object.fromEntries(
84
+ Object.entries({ ...options }).filter(([k]) => filterIsOgImageOption(k) || ignoreKeys.includes(k))
85
+ ),
86
+ props
87
+ };
88
+ }
89
+ export function normaliseFontInput(fonts) {
90
+ return fonts.map((f) => {
91
+ if (typeof f === "string") {
92
+ const vals = f.split(":");
93
+ const includesStyle = vals.length === 3;
94
+ let name, weight, style;
95
+ if (includesStyle) {
96
+ name = vals[0];
97
+ style = vals[1];
98
+ weight = vals[2];
99
+ } else {
100
+ name = vals[0];
101
+ weight = vals[1];
102
+ }
103
+ return {
104
+ cacheKey: f,
105
+ name,
106
+ weight: weight || 400,
107
+ style: style || "normal",
108
+ path: void 0
109
+ };
110
+ }
111
+ return {
112
+ cacheKey: f.key || `${f.name}:${f.style}:${f.weight}`,
113
+ style: "normal",
114
+ weight: 400,
115
+ ...f
116
+ };
117
+ });
118
+ }
119
+ export function withoutQuery(path) {
120
+ return path.split("?")[0];
121
+ }
122
+ export function getExtension(path) {
123
+ path = withoutQuery(path);
124
+ const lastSegment = path.split("/").pop() || path;
125
+ const extension = lastSegment.split(".").pop() || lastSegment;
126
+ if (extension === "jpg")
127
+ return "jpeg";
128
+ return extension;
129
+ }
130
+ export function useOgImageRuntimeConfig() {
131
+ return {};
132
+ }
@@ -0,0 +1,187 @@
1
+ import type { OgImageComponents } from '#og-image/components';
2
+ import type { ResvgRenderOptions } from '@resvg/resvg-js';
3
+ import type { UnoGenerator } from '@unocss/core';
4
+ import type { AllowedComponentProps, Component, ComponentCustomProps, VNodeProps } from '@vue/runtime-core';
5
+ import type { H3Error, H3Event } from 'h3';
6
+ import type { NitroOptions } from 'nitropack';
7
+ import type { NitroApp } from 'nitropack/types';
8
+ import type { SatoriOptions } from 'satori';
9
+ import type { html } from 'satori-html';
10
+ import type { JpegOptions, SharpOptions } from 'sharp';
11
+ import type { Ref } from 'vue';
12
+ export interface OgImageRenderEventContext {
13
+ unocss: UnoGenerator;
14
+ e: H3Event;
15
+ extension: 'png' | 'jpeg' | 'jpg' | 'svg' | 'html' | 'json';
16
+ key: string;
17
+ basePath: string;
18
+ renderer: Renderer;
19
+ options: OgImageOptions;
20
+ isDebugJsonPayload: boolean;
21
+ publicStoragePath: string;
22
+ runtimeConfig: OgImageRuntimeConfig;
23
+ _nitro: NitroApp;
24
+ }
25
+ export type IconifyEmojiIconSets = 'twemoji' | 'noto' | 'fluent-emoji' | 'fluent-emoji-flat' | 'fluent-emoji-high-contrast' | 'noto-v1' | 'emojione' | 'emojione-monotone' | 'emojione-v1' | 'streamline-emojis' | 'openmoji';
26
+ export interface OgImageRuntimeConfig {
27
+ version: string;
28
+ satoriOptions: SatoriOptions;
29
+ resvgOptions: ResvgRenderOptions;
30
+ sharpOptions: SharpOptions;
31
+ publicStoragePath: string;
32
+ defaults: OgImageOptions;
33
+ debug: boolean;
34
+ baseCacheKey: string;
35
+ fonts: FontConfig[];
36
+ hasNuxtIcon: boolean;
37
+ colorPreference: 'light' | 'dark';
38
+ isNuxtContentDocumentDriven: boolean;
39
+ strictNuxtContentPaths: boolean;
40
+ zeroRuntime: boolean;
41
+ componentDirs?: string[];
42
+ app: {
43
+ baseURL: string;
44
+ };
45
+ }
46
+ export interface OgImageComponent {
47
+ path?: string;
48
+ pascalName: string;
49
+ kebabName: string;
50
+ hash: string;
51
+ category: 'app' | 'community' | 'pro';
52
+ credits?: string;
53
+ }
54
+ export interface ScreenshotOptions {
55
+ colorScheme?: 'dark' | 'light';
56
+ selector?: string;
57
+ mask?: string;
58
+ /**
59
+ * The width of the screenshot.
60
+ *
61
+ * @default 1200
62
+ */
63
+ width: number;
64
+ /**
65
+ * The height of the screenshot.
66
+ *
67
+ * @default 630
68
+ */
69
+ height: number;
70
+ /**
71
+ * How long to wait before taking the screenshot. Useful for waiting for animations.
72
+ */
73
+ delay?: number;
74
+ }
75
+ export interface OgImagePrebuilt extends OgImageOptions {
76
+ }
77
+ export type DefineOgImageInput = OgImageOptions | OgImagePrebuilt | false;
78
+ export interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
79
+ /**
80
+ * The width of the screenshot.
81
+ *
82
+ * @default 1200
83
+ */
84
+ width?: number | (() => number) | Ref<number>;
85
+ /**
86
+ * The height of the screenshot.
87
+ *
88
+ * @default 630
89
+ */
90
+ height?: number | (() => number) | Ref<number>;
91
+ /**
92
+ * The alt text for the image.
93
+ */
94
+ alt?: string | (() => string) | Ref<string>;
95
+ /**
96
+ * Use a prebuilt image instead of generating one.
97
+ *
98
+ * Should be an absolute URL.
99
+ */
100
+ url?: string | (() => string) | Ref<string>;
101
+ /**
102
+ * The name of the component to render.
103
+ */
104
+ component?: T | string;
105
+ /**
106
+ * Props to pass to the component.
107
+ */
108
+ props?: OgImageComponents[T] | Record<string, any>;
109
+ renderer?: 'chromium' | 'satori';
110
+ extension?: 'png' | 'jpeg' | 'jpg';
111
+ emojis?: IconifyEmojiIconSets;
112
+ /**
113
+ * Provide a static HTML template to render the OG Image instead of a component.
114
+ */
115
+ html?: string;
116
+ resvg?: ResvgRenderOptions;
117
+ satori?: SatoriOptions;
118
+ screenshot?: Partial<ScreenshotOptions>;
119
+ sharp?: SharpOptions & JpegOptions;
120
+ fonts?: InputFontConfig[];
121
+ cacheMaxAgeSeconds?: number;
122
+ /**
123
+ * Social preview metadata
124
+ * @internal
125
+ */
126
+ socialPreview?: SocialPreviewMetaData;
127
+ /**
128
+ * @internal
129
+ */
130
+ _query?: Record<string, any>;
131
+ }
132
+ export interface FontConfig {
133
+ name: string;
134
+ style?: 'normal' | 'ital';
135
+ weight?: string | number;
136
+ path?: string;
137
+ key?: string;
138
+ absolutePath?: boolean;
139
+ }
140
+ export interface ResolvedFontConfig extends FontConfig {
141
+ cacheKey: string;
142
+ data?: BufferSource;
143
+ }
144
+ export type InputFontConfig = (`${string}:${number}` | `${string}:${'normal' | 'ital'}:${number}` | string | FontConfig);
145
+ export interface RuntimeCompatibilitySchema {
146
+ chromium: 'chrome-launcher' | 'on-demand' | 'playwright' | false;
147
+ ['css-inline']: 'node' | 'wasm' | 'wasm-fs' | false;
148
+ resvg: 'node' | 'wasm' | 'wasm-fs' | false;
149
+ satori: 'node' | 'wasm' | 'wasm-fs' | false;
150
+ sharp: 'node' | false;
151
+ wasm?: NitroOptions['wasm'];
152
+ }
153
+ export type CompatibilityFlags = Partial<Omit<RuntimeCompatibilitySchema, 'wasm'>>;
154
+ export interface CompatibilityFlagEnvOverrides {
155
+ dev?: CompatibilityFlags;
156
+ runtime?: CompatibilityFlags;
157
+ prerender?: CompatibilityFlags;
158
+ }
159
+ export type RendererOptions = Omit<OgImageOptions, 'extension'> & {
160
+ extension: Omit<OgImageOptions['extension'], 'html'>;
161
+ };
162
+ export interface Renderer {
163
+ name: 'chromium' | 'satori';
164
+ supportedFormats: Partial<RendererOptions['extension']>[];
165
+ createImage: (e: OgImageRenderEventContext) => Promise<H3Error | BufferSource | Buffer | Uint8Array | void | undefined>;
166
+ debug: (e: OgImageRenderEventContext) => Promise<Record<string, any>>;
167
+ }
168
+ export type ExtractComponentProps<T extends Component> = T extends new (...args: any) => any ? Omit<InstanceType<T>['$props'], keyof ComponentCustomProps | keyof VNodeProps | keyof AllowedComponentProps> : never;
169
+ export type OgImagePageScreenshotOptions = Omit<OgImageOptions, 'html' | 'renderer' | 'component' | 'satori' | 'resvg' | 'sharp'>;
170
+ export type VNode = ReturnType<typeof html>;
171
+ export interface SatoriTransformer {
172
+ filter: (node: VNode) => boolean;
173
+ transform: (node: VNode, e: OgImageRenderEventContext) => Promise<void> | void;
174
+ }
175
+ export interface SocialPreviewMetaData {
176
+ twitter?: Record<string, string>;
177
+ og?: Record<string, string> & {
178
+ image?: string | {
179
+ 'image:width'?: string | number;
180
+ 'image:height'?: string | number;
181
+ [key: string]: any;
182
+ };
183
+ };
184
+ }
185
+ export interface RouteRulesOgImage extends Partial<OgImageOptions> {
186
+ [key: string]: any;
187
+ }
File without changes