Skip to content

Commit

Permalink
fix: handle undefined indices more accurately (#1451)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Aug 28, 2024
1 parent 92a6eee commit f58d9f5
Show file tree
Hide file tree
Showing 12 changed files with 25 additions and 20 deletions.
1 change: 1 addition & 0 deletions .nuxtrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
modules[]=@nuxt/test-utils/module
modules[]=@nuxt/image
typescript.tsConfig.compilerOptions.noUncheckedIndexedAccess=true
4 changes: 3 additions & 1 deletion src/runtime/components/NuxtImg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ onMounted(() => {
if (placeholder.value) {
const img = new Image()
img.src = mainSrc.value
if (mainSrc.value) {
img.src = mainSrc.value
}
if (props.sizes) {
img.sizes = sizes.value.sizes || ''
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/NuxtPicture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const legacyFormat = computed(() => {
return isTransparent.value ? 'png' : 'jpeg'
})
type Source = { src: string, srcset?: string, type?: string, sizes?: string }
type Source = { src?: string, srcset?: string, type?: string, sizes?: string }
const sources = computed<Source[]>(() => {
const formats = props.format?.split(',') || (originalFormat.value === 'svg' ? ['svg'] : ($img.options.format?.length ? [...$img.options.format] : ['webp']))
Expand Down
8 changes: 6 additions & 2 deletions src/runtime/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ function resolveImage(ctx: ImageCTX, input: string, options: ImageOptions): Reso
if (!provider.supportsAlias) {
for (const base in ctx.options.alias) {
if (input.startsWith(base)) {
input = joinURL(ctx.options.alias[base], input.substr(base.length))
const alias = ctx.options.alias[base]
if (alias) {
input = joinURL(alias, input.slice(base.length))
}
}
}
}
Expand Down Expand Up @@ -168,7 +171,8 @@ function getSizes(ctx: ImageCTX, input: string, opts: ImageSizesOptions): ImageS
// 'densities path'
for (const density of densities) {
const key = Object.keys(sizes)[0]
let variant = getSizesVariant(key, String(sizes[key]), height, hwRatio, ctx)

let variant = key ? getSizesVariant(key, String(sizes[key]), height, hwRatio, ctx) : undefined

// unable to resolve variant, fallback to default modifiers
if (variant === undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/providers/awsAmplify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ProviderGetImage } from '../../module'

export const getImage: ProviderGetImage = (src, { modifiers, baseURL = '/_amplify/image' } = {}, ctx) => {
const validWidths = Object.values(ctx.options.screens || {}).sort((a, b) => a - b)
const largestWidth = validWidths[validWidths.length - 1]
const largestWidth = validWidths[validWidths.length - 1] || 0
let width = Number(modifiers?.width || 0)

if (!width) {
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/providers/hygraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export function splitUpURL(url: string, baseURL: string) {

// get baseId
// -> cltsj3mii0pvd07vwb5cyh1ig
// @ts-expect-error fixing in separate PR
const baseId = bothIds.split('/')[0]

// get imageId
Expand Down Expand Up @@ -61,6 +62,7 @@ export function optimizeHygraphImage(baseURL: string, url: string, optimizations
}

const optim = `${optimBase}=${optimList.join(',')}`
// @ts-expect-error fixing in separate PR
const result = joinURL(baseURL, baseId, optim, quality, imageFormat, imageId)

return result
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/providers/vercel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { ProviderGetImage } from '../../module'

export const getImage: ProviderGetImage = (src, { modifiers, baseURL = '/_vercel/image' } = {}, ctx) => {
const validWidths = Object.values(ctx.options.screens || {}).sort((a, b) => a - b)
const largestWidth = validWidths[validWidths.length - 1]
const largestWidth = validWidths[validWidths.length - 1] || 0
let width = Number(modifiers?.width || 0)

if (!width) {
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function createOperationsGenerator({ formatter, keyMap, joinWith = '/', v
.map(([key, value]) => {
const mapper = map[key]
if (typeof mapper === 'function') {
value = mapper(modifiers[key])
value = mapper(modifiers[key]!)
}

key = typeof keyMap === 'function' ? keyMap(key) : key
Expand Down Expand Up @@ -128,10 +128,10 @@ export function parseSizes(input: Record<string, string | number> | string): Rec
for (const entry of input.split(/[\s,]+/).filter(e => e)) {
const s = entry.split(':')
if (s.length !== 2) {
sizes['1px'] = s[0].trim()
sizes['1px'] = s[0]!.trim()
}
else {
sizes[s[0].trim()] = s[1].trim()
sizes[s[0]!.trim()] = s[1]!.trim()
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions src/runtime/utils/prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,12 @@ export function prerenderStaticImages(src = '', srcset = '') {

const paths = [
src,
...srcset.split(', ').map(s => s.trim().split(' ')[0].trim()),
...srcset.split(', ').map(s => s.trim().split(' ')[0]!.trim()),
].filter(s => s && s.includes('/_ipx/'))

if (!paths.length) {
return
}

appendHeader(
useRequestEvent()!,
'x-nitro-prerender',
paths.map(p => encodeURIComponent(p)).join(', '),
)
appendHeader(useRequestEvent()!, 'x-nitro-prerender', paths.map(p => encodeURIComponent(p)).join(', '))
}
2 changes: 1 addition & 1 deletion src/types/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export interface ResolvedImage {
export interface ImageSizes {
srcset: string
sizes: string | undefined
src: string
src?: string
}

export interface Img {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/image.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ describe('Renders placeholder image', () => {
domSrc = wrapper.find('img').element.getAttribute('src')

expect(domSrc).toMatchInlineSnapshot('"/_ipx/s_200x200/image.png"')
expect(wrapper.emitted().load[0]).toStrictEqual([loadEvent])
expect(wrapper.emitted().load![0]).toStrictEqual([loadEvent])
})

it('props.placeholder with sizes', async () => {
Expand Down Expand Up @@ -246,7 +246,7 @@ describe('Renders placeholder image', () => {
sizes = wrapper.find('img').element.getAttribute('sizes')

expect(sizes).toMatchInlineSnapshot('"(max-width: 500px) 200px, (max-width: 900px) 500px, 900px"')
expect(wrapper.emitted().load[0]).toStrictEqual([loadEvent])
expect(wrapper.emitted().load![0]).toStrictEqual([loadEvent])
})

it('placeholder class can be set', async () => {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/picture.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('Renders simple image', () => {

it('props.src is picked up by getImage()', () => {
[['source', 'srcset', '/_ipx/f_webp&s_500x500/image.png'], ['img', 'src']].forEach(([element, attribute, customSrc]) => {
const domSrc = wrapper.find(element).element.getAttribute(attribute)
const domSrc = wrapper.find(element!).element.getAttribute(attribute!)
expect(domSrc).toContain(customSrc || src)
})
})
Expand Down Expand Up @@ -117,7 +117,7 @@ describe('Renders simple image', () => {
await nextTick()

;[['source', 'srcset', '/_ipx/f_webp&s_500x500/image.jpeg'], ['img', 'src']].forEach(([element, attribute, src]) => {
const domSrc = wrapper.find(element).element.getAttribute(attribute)
const domSrc = wrapper.find(element!).element.getAttribute(attribute!)
expect(domSrc).toContain(src || newSource)
})
})
Expand Down

0 comments on commit f58d9f5

Please sign in to comment.