From 7f336560770c11adef09e2bcccdffbbf987bf9da Mon Sep 17 00:00:00 2001 From: Lucie <25330882+lihbr@users.noreply.github.com> Date: Fri, 29 Nov 2024 05:11:24 -0500 Subject: [PATCH] fix(prismic): use unsplash image proxy where necessary (#1614) --- src/runtime/providers/prismic.ts | 27 +++++++++++---------------- src/runtime/providers/unsplash.ts | 2 +- test/providers.ts | 6 ++++++ test/unit/providers.test.ts | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/runtime/providers/prismic.ts b/src/runtime/providers/prismic.ts index 3d48a91ac..9889b9545 100644 --- a/src/runtime/providers/prismic.ts +++ b/src/runtime/providers/prismic.ts @@ -1,24 +1,19 @@ -import { joinURL, parseQuery, parseURL, stringifyQuery } from 'ufo' +import { getQuery, withBase, withQuery } from 'ufo' import type { ProviderGetImage } from '../../module' import { operationsGenerator } from './imgix' +import { getImage as getUnsplashImage, unsplashCDN } from './unsplash' -const PRISMIC_IMGIX_BUCKET = 'https://images.prismic.io' +export const prismicCDN = 'https://images.prismic.io/' -// Prismic image bucket is left configurable in order to test on other environments -export const getImage: ProviderGetImage = ( - src, - { modifiers = {}, baseURL = PRISMIC_IMGIX_BUCKET } = {}, -) => { - const operations = operationsGenerator(modifiers) - - const parsedURL = parseURL(src) +export const getImage: ProviderGetImage = (src, { modifiers = {}, baseURL = prismicCDN } = {}, ctx) => { + // Some images served by Prismic are from unsplash, so we use the unsplash provider for those + if (src.startsWith(unsplashCDN)) { + return getUnsplashImage(src, { modifiers }, ctx) + } + const operations = operationsGenerator(modifiers) + // withQuery requires query parameters as an object, so I parse the modifiers into an object with getQuery return { - url: joinURL( - baseURL, - parsedURL.pathname + '?' - // Remove duplicated keys, prioritizing override from developers - + stringifyQuery(Object.assign(parseQuery(parsedURL.search), parseQuery(operations))), - ), + url: withQuery(withBase(src, baseURL), getQuery('?' + operations)), } } diff --git a/src/runtime/providers/unsplash.ts b/src/runtime/providers/unsplash.ts index 325918b98..7b3925113 100644 --- a/src/runtime/providers/unsplash.ts +++ b/src/runtime/providers/unsplash.ts @@ -4,7 +4,7 @@ import { getQuery, withBase, withQuery } from 'ufo' import type { ProviderGetImage } from '../../module' import { operationsGenerator } from './imgix' -const unsplashCDN = 'https://images.unsplash.com/' +export const unsplashCDN = 'https://images.unsplash.com/' export const getImage: ProviderGetImage = (src, { modifiers = {}, baseURL = unsplashCDN } = {}) => { const operations = operationsGenerator(modifiers) diff --git a/test/providers.ts b/test/providers.ts index 7dcabc0f9..25b03692c 100644 --- a/test/providers.ts +++ b/test/providers.ts @@ -19,6 +19,7 @@ export const images = [ netlifyLargeMedia: { url: '/test.png' }, prepr: { url: 'https://projectName.stream.prepr.io/image-test-300x450-png' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=100' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=100' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?auto=format' }, contentful: { url: '/test.png' }, cloudimage: { url: 'https://demo.cloudimg.io/v7/test.png' }, @@ -54,6 +55,7 @@ export const images = [ netlifyLargeMedia: { url: '/test.png?w=200&nf_resize=fit' }, prepr: { url: 'https://projectName.stream.prepr.io/w_200/image-test-300x450-png' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=100' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=100' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&auto=format' }, contentful: { url: '/test.png?w=200' }, cloudimage: { url: 'https://demo.cloudimg.io/v7/test.png?width=200' }, @@ -89,6 +91,7 @@ export const images = [ netlifyLargeMedia: { url: '/test.png?h=200&nf_resize=fit' }, prepr: { url: 'https://projectName.stream.prepr.io/h_200/image-test-300x450-png' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=200' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=200' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?h=200&auto=format' }, contentful: { url: '/test.png?h=200' }, cloudimage: { url: 'https://demo.cloudimg.io/v7/test.png?height=200' }, @@ -123,6 +126,7 @@ export const images = [ netlifyImageCdn: { url: '/.netlify/images?w=200&h=200&url=%2Ftest.png' }, netlifyLargeMedia: { url: '/test.png?w=200&h=200&nf_resize=fit' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200' }, prepr: { url: 'https://projectName.stream.prepr.io/w_200,h_200/image-test-300x450-png' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&auto=format' }, contentful: { url: '/test.png?w=200&h=200' }, @@ -158,6 +162,7 @@ export const images = [ netlifyImageCdn: { url: '/.netlify/images?w=200&h=200&fit=contain&url=%2Ftest.png' }, netlifyLargeMedia: { url: '/test.png?w=200&h=200&nf_resize=fit' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill' }, prepr: { url: 'https://projectName.stream.prepr.io/w_200,h_200,fit_contain/image-test-300x450-png' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&fit=fill&auto=format&bg=ffffff' }, contentful: { url: '/test.png?w=200&h=200&fit=fill' }, @@ -193,6 +198,7 @@ export const images = [ netlifyImageCdn: { url: '/.netlify/images?w=200&h=200&fit=contain&fm=jpg&url=%2Ftest.png' }, netlifyLargeMedia: { url: '/test.png?w=200&h=200&nf_resize=fit' }, prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill&fm=jpeg' }, + prismicUnsplash: { url: 'https://images.unsplash.com/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill&fm=jpeg' }, sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&fit=fill&fm=jpg&bg=ffffff' }, prepr: { url: 'https://projectName.stream.prepr.io/w_200,h_200,fit_contain,format_jpg/image-test-300x450-png' }, contentful: { url: '/test.png?w=200&h=200&fit=fill&fm=jpg' }, diff --git a/test/unit/providers.test.ts b/test/unit/providers.test.ts index 28fae695f..7c44812a7 100644 --- a/test/unit/providers.test.ts +++ b/test/unit/providers.test.ts @@ -337,6 +337,21 @@ describe('Providers', () => { } }) + it('prismic (unsplash)', () => { + const providerOptions = { + baseURL: '', // Use empty base URL for the sake of simplicity + } + + const EXISTING_QUERY_PARAMETERS + = '?auto=compress,format&rect=0,0,200,200&w=100&h=100' + + for (const image of images) { + const [, modifiers] = image.args + const generated = prismic.getImage(`${image.prismicUnsplash.url.split('?').shift()}${EXISTING_QUERY_PARAMETERS}`, { modifiers, ...providerOptions }, emptyContext) + expect(generated).toMatchObject(image.prismicUnsplash) + } + }) + it('sanity', () => { const providerOptions = { baseURL: '',