UNPKG

nuxt-og-image

Version:

Enlightened OG Image generation for Nuxt.

174 lines (173 loc) 5.87 kB
import type { OgImageComponents } from '#og-image/components'; import type { ResvgRenderOptions } from '@resvg/resvg-js'; import type { UnoGenerator } from '@unocss/core'; import type { AllowedComponentProps, Component, ComponentCustomProps, VNodeProps } from '@vue/runtime-core'; import type { H3Error, H3Event } from 'h3'; import type { NitroOptions } from 'nitropack'; import type { NitroApp } from 'nitropack/types'; import type { SatoriOptions } from 'satori'; import type { html } from 'satori-html'; import type { JpegOptions, SharpOptions } from 'sharp'; import type { Ref } from 'vue'; export interface OgImageRenderEventContext { unocss: UnoGenerator; e: H3Event; extension: 'png' | 'jpeg' | 'jpg' | 'svg' | 'html' | 'json'; key: string; basePath: string; renderer: Renderer; options: OgImageOptions; isDebugJsonPayload: boolean; publicStoragePath: string; runtimeConfig: OgImageRuntimeConfig; _nitro: NitroApp; } export type IconifyEmojiIconSets = 'twemoji' | 'noto' | 'fluent-emoji' | 'fluent-emoji-flat' | 'fluent-emoji-high-contrast' | 'noto-v1' | 'emojione' | 'emojione-monotone' | 'emojione-v1' | 'streamline-emojis' | 'openmoji'; export interface OgImageRuntimeConfig { version: string; satoriOptions: SatoriOptions; resvgOptions: ResvgRenderOptions; sharpOptions: SharpOptions; publicStoragePath: string; defaults: OgImageOptions; debug: boolean; baseCacheKey: string; fonts: FontConfig[]; hasNuxtIcon: boolean; colorPreference: 'light' | 'dark'; isNuxtContentDocumentDriven: boolean; strictNuxtContentPaths: boolean; zeroRuntime: boolean; componentDirs?: string[]; app: { baseURL: string; }; } export interface OgImageComponent { path?: string; pascalName: string; kebabName: string; hash: string; category: 'app' | 'community' | 'pro'; credits?: string; } export interface ScreenshotOptions { colorScheme?: 'dark' | 'light'; selector?: string; mask?: string; /** * The width of the screenshot. * * @default 1200 */ width: number; /** * The height of the screenshot. * * @default 630 */ height: number; /** * How long to wait before taking the screenshot. Useful for waiting for animations. */ delay?: number; } export interface OgImagePrebuilt extends OgImageOptions { } export type DefineOgImageInput = OgImageOptions | OgImagePrebuilt | false; export interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> { /** * The width of the screenshot. * * @default 1200 */ width?: number | (() => number) | Ref<number>; /** * The height of the screenshot. * * @default 630 */ height?: number | (() => number) | Ref<number>; /** * The alt text for the image. */ alt?: string | (() => string) | Ref<string>; /** * Use a prebuilt image instead of generating one. * * Should be an absolute URL. */ url?: string | (() => string) | Ref<string>; /** * The name of the component to render. */ component?: T | string; /** * Props to pass to the component. */ props?: OgImageComponents[T] | Record<string, any>; renderer?: 'chromium' | 'satori'; extension?: 'png' | 'jpeg' | 'jpg'; emojis?: IconifyEmojiIconSets; /** * Provide a static HTML template to render the OG Image instead of a component. */ html?: string; resvg?: ResvgRenderOptions; satori?: SatoriOptions; screenshot?: Partial<ScreenshotOptions>; sharp?: SharpOptions & JpegOptions; fonts?: InputFontConfig[]; cacheMaxAgeSeconds?: number; /** * @internal */ _query?: Record<string, any>; } export interface FontConfig { name: string; style?: 'normal' | 'ital'; weight?: string | number; path?: string; key?: string; absolutePath?: boolean; } export interface ResolvedFontConfig extends FontConfig { cacheKey: string; data?: BufferSource; } export type InputFontConfig = (`${string}:${number}` | `${string}:${'normal' | 'ital'}:${number}` | string | FontConfig); export interface RuntimeCompatibilitySchema { chromium: 'chrome-launcher' | 'on-demand' | 'playwright' | false; ['css-inline']: 'node' | 'wasm' | 'wasm-fs' | false; resvg: 'node' | 'wasm' | 'wasm-fs' | false; satori: 'node' | 'wasm' | 'wasm-fs' | false; sharp: 'node' | false; wasm?: NitroOptions['wasm']; } export type CompatibilityFlags = Partial<Omit<RuntimeCompatibilitySchema, 'wasm'>>; export interface CompatibilityFlagEnvOverrides { dev?: CompatibilityFlags; runtime?: CompatibilityFlags; prerender?: CompatibilityFlags; } export type RendererOptions = Omit<OgImageOptions, 'extension'> & { extension: Omit<OgImageOptions['extension'], 'html'>; }; export interface Renderer { name: 'chromium' | 'satori'; supportedFormats: Partial<RendererOptions['extension']>[]; createImage: (e: OgImageRenderEventContext) => Promise<H3Error | BufferSource | void>; debug: (e: OgImageRenderEventContext) => Promise<Record<string, any>>; } export type ExtractComponentProps<T extends Component> = T extends new (...args: any) => any ? Omit<InstanceType<T>['$props'], keyof ComponentCustomProps | keyof VNodeProps | keyof AllowedComponentProps> : never; export type OgImagePageScreenshotOptions = Omit<OgImageOptions, 'html' | 'renderer' | 'component' | 'satori' | 'resvg' | 'sharp'>; export type VNode = ReturnType<typeof html>; export interface SatoriTransformer { filter: (node: VNode) => boolean; transform: (node: VNode, e: OgImageRenderEventContext) => Promise<void> | void; } export interface SocialPreviewMetaData { twitter?: Record<string, string>; og?: Record<string, string>; }