diff --git a/src/runtime/image.ts b/src/runtime/image.ts index 764d32268..fe72c6bbf 100644 --- a/src/runtime/image.ts +++ b/src/runtime/image.ts @@ -3,14 +3,14 @@ import { hasProtocol, parseURL, joinURL, withLeadingSlash } from 'ufo' import { imageMeta } from './utils/meta' import { checkDensities, parseDensities, parseSize, parseSizes } from './utils' import { prerenderStaticImages } from './utils/prerender' -import type { ImageOptions, ImageSizesOptions, CreateImageOptions, ResolvedImage, ImageCTX, $Img, ImageSizes, ImageSizesVariant, ConfiguredImageProviders } from '@nuxt/image' +import type { ImageOptions, CreateImageOptions, ResolvedImage, ImageCTX, $Img, ImageSizes, ImageSizesVariant, ConfiguredImageProviders } from '@nuxt/image' export function createImage(globalOptions: CreateImageOptions) { const ctx: ImageCTX = { options: globalOptions, } - const getImage: $Img['getImage'] = (input: string, options = {}) => { + const getImage = (input: string, options: ImageOptions = {}): ResolvedImage => { const image = resolveImage(ctx, input, options) // Prerender static images @@ -25,20 +25,20 @@ export function createImage(globalOptions: CreateImageOptions) { for (const presetName in globalOptions.presets) { $img[presetName] = ((source, modifiers, options) => - $img(source, modifiers, { ...globalOptions.presets[presetName], ...options })) as $Img[string] + $img(source, modifiers, { ...globalOptions.presets[presetName], ...options } as ImageOptions)) as $Img[string] } $img.options = globalOptions $img.getImage = getImage - $img.getMeta = ((input: string, options?: ImageOptions) => getMeta(ctx, input, options)) as $Img['getMeta'] - $img.getSizes = ((input: string, options: ImageSizesOptions) => getSizes(ctx, input, options)) as $Img['getSizes'] + $img.getMeta = ((input: string, options?: ImageOptions) => getMeta(ctx, input, options)) as $Img['getMeta'] + $img.getSizes = ((input: string, options?: ImageOptions) => getSizes(ctx, input, options)) as $Img['getSizes'] ctx.$img = $img as $Img return $img } -async function getMeta(ctx: ImageCTX, input: string, options?: ImageOptions) { +async function getMeta(ctx: ImageCTX, input: string, options?: ImageOptions) { const image = resolveImage(ctx, input, { ...options }) if (typeof image.getMeta === 'function') { @@ -49,7 +49,7 @@ async function getMeta(ctx: ImageCTX, input: string, options?: ImageOptions) { } } -function resolveImage(ctx: ImageCTX, input: string, options: ImageOptions): ResolvedImage { +function resolveImage(ctx: ImageCTX, input: string, options: ImageOptions): ResolvedImage { if (input && typeof input !== 'string') { throw new TypeError(`input must be a string (received ${typeof input}: ${JSON.stringify(input)})`) } @@ -124,9 +124,9 @@ function getPreset(ctx: ImageCTX, name?: string): ImageOptions { return ctx.options.presets[name] } -function getSizes(ctx: ImageCTX, input: string, opts: ImageSizesOptions): ImageSizes { +function getSizes(ctx: ImageCTX, input: string, opts?: ImageOptions): ImageSizes { // Merge preset options so preset-provided sizes/densities are respected - const preset = getPreset(ctx, opts.preset) + const preset = getPreset(ctx, opts?.preset) const merged = defu(opts, preset) const width = parseSize(merged.modifiers?.width) @@ -160,7 +160,7 @@ function getSizes(ctx: ImageCTX, input: string, opts: ImageSizesOptions): ImageS for (const density of densities) { srcsetVariants.push({ width: variant._cWidth * density, - src: getVariantSrc(ctx, input, opts, variant, density), + src: getVariantSrc(ctx, input, variant, density, opts), }) } } @@ -179,14 +179,14 @@ function getSizes(ctx: ImageCTX, input: string, opts: ImageSizesOptions): ImageS variant = { size: '', screenMaxWidth: 0, - _cWidth: opts.modifiers?.width as number, - _cHeight: opts.modifiers?.height as number, + _cWidth: opts?.modifiers?.width as number, + _cHeight: opts?.modifiers?.height as number, } } srcsetVariants.push({ width: density, - src: getVariantSrc(ctx, input, opts, variant, density), + src: getVariantSrc(ctx, input, variant, density, opts), }) } } @@ -232,10 +232,10 @@ function getSizesVariant(key: string, size: string, height: number | undefined, } } -function getVariantSrc(ctx: ImageCTX, input: string, opts: ImageSizesOptions, variant: ImageSizesVariant, density: number) { +function getVariantSrc(ctx: ImageCTX, input: string, variant: ImageSizesVariant, density: number, opts?: ImageOptions) { return ctx.$img!(input, { - ...opts.modifiers, + ...opts?.modifiers, width: variant._cWidth ? variant._cWidth * density : undefined, height: variant._cHeight ? variant._cHeight * density : undefined, }, diff --git a/src/types/image.ts b/src/types/image.ts index ae0f06ffc..4281eb505 100644 --- a/src/types/image.ts +++ b/src/types/image.ts @@ -19,17 +19,15 @@ export interface ResolvedImageModifiers extends ImageModifiers { type DefaultProvider = ProviderDefaults extends Record<'provider', unknown> ? ProviderDefaults['provider'] : never -export interface ImageOptions { - provider?: Provider +type Sizes = Record | string + +export interface ImageOptions { + provider?: TProvider preset?: string densities?: string modifiers?: Partial> - & ('modifiers' extends keyof ConfiguredImageProviders[Provider] ? ConfiguredImageProviders[Provider]['modifiers'] : Record) - sizes?: string | Record -} - -export interface ImageSizesOptions extends ImageOptions { - sizes: Record | string + & ('modifiers' extends keyof ConfiguredImageProviders[TProvider] ? ConfiguredImageProviders[TProvider]['modifiers'] : Record) + sizes?: Sizes } export type ProviderGetImage> = (src: string, options: Omit & { modifiers: Partial } & T, ctx: ImageCTX) => ResolvedImage @@ -84,11 +82,15 @@ export interface ImageSizes { } export interface Img { - (source: string, modifiers?: ImageOptions['modifiers'], options?: ImageOptions): ResolvedImage['url'] + ( + source: string, + modifiers?: ImageOptions['modifiers'], + options?: ImageOptions + ): ResolvedImage['url'] options: CreateImageOptions - getImage: (source: string, options?: ImageOptions) => ResolvedImage - getSizes: (source: string, options?: ImageOptions, sizes?: string[]) => ImageSizes - getMeta: (source: string, options?: ImageOptions) => Promise + getImage: (source: string, options?: ImageOptions) => ResolvedImage + getSizes: (source: string, options?: ImageOptions) => ImageSizes + getMeta: (source: string, options?: ImageOptions) => Promise } export type $Img = Img & {