Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add prismic provider #269

Merged
merged 6 commits into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/en/3.providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ There are plenty of image service providers. Nuxt image has a generic way to wor
- [`Fastly`](/providers/fastly)
- [`Imgix`](/providers/imgix)
- [`IPX`](/providers/ipx) (selfhosted)
- [`Prismic`](/providers/prismic)
- [`Sanity`](/providers/sanity)
- [`Twicpics`](/providers/twicpics)
- [`Storyblok`](/providers/storyblok)
Expand Down
24 changes: 24 additions & 0 deletions docs/content/en/4.providers/prismic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
menuTitle: Prismic
title: Prismic Provider
description: 'Nuxt Image has first class integration with Prismic'
category: Providers
---

Integration between [Prismic](https://prismic.io/docs) and the image module.

To use this provider you just need to specify an empty object at `prismic` key in Nuxt Image options object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something along the lines of:

Suggested change
To use this provider you just need to specify an empty object at `prismic` key in Nuxt Image options object.
No specific configuration is required for Prismic support. You just need to specify `provider: 'prismic'` in your configuration to make it the default, or pass it directly when you need it, for example:
```html
<nuxt-img provider="prismic" src="..." />


```js{}[nuxt.config.js]
export default {
image: {
prismic: {}
}
}
```

<alert type="info">

Prismic allows content writer to manipulate images through its UI (cropping, rezising, etc.). To preserve that behavior this provider does not strip query parameters coming from Prismic. Instead it only overrides them when needed, keeping developers in control.

</alert>
1 change: 1 addition & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default <NuxtConfig> {
imagekit: {
baseURL: 'https://ik.imagekit.io/demo'
},
prismic: {},
sanity: {
projectId: 'j1o4tmjp'
},
Expand Down
49 changes: 36 additions & 13 deletions playground/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,34 @@ export const providers: Provider[] = [
}
]
},
// Sanity
// Fastly
{
name: 'sanity',
name: 'fastly',
samples: [
{ src: '/image.jpg' },
{ src: '/plant.jpeg' }
]
},
// Prismic
{
name: 'prismic',
samples: [
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg'
src: 'https://images.prismic.io/200629-sms-hoy/f596a543-d593-4296-9abd-3d3ac15f1e39_ray-hennessy-mpw37yXc_WQ-unsplash.jpg?auto=compress,format&w=600&h=900'
},
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg',
width: 200,
height: 200,
fit: 'crop'
src: 'https://images.prismic.io/200629-sms-hoy/f596a543-d593-4296-9abd-3d3ac15f1e39_ray-hennessy-mpw37yXc_WQ-unsplash.jpg?auto=compress,format&w=600&h=900',
width: 200
},
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg',
src: 'https://images.prismic.io/200629-sms-hoy/f596a543-d593-4296-9abd-3d3ac15f1e39_ray-hennessy-mpw37yXc_WQ-unsplash.jpg?auto=compress,format&w=600&h=900',
height: 200
},
{
src: 'https://images.prismic.io/200629-sms-hoy/f596a543-d593-4296-9abd-3d3ac15f1e39_ray-hennessy-mpw37yXc_WQ-unsplash.jpg?auto=compress,format&w=600&h=900',
width: 200,
height: 200,
fit: 'min'
fit: 'crop'
}
]
},
Expand All @@ -88,12 +98,25 @@ export const providers: Provider[] = [
{ src: '/football.jpg', width: 250, height: 400, focus: 'auto' }
]
},
// Fastly
// Sanity
{
name: 'fastly',
name: 'sanity',
samples: [
{ src: '/image.jpg' },
{ src: '/plant.jpeg' }
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg'
},
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg',
width: 200,
height: 200,
fit: 'crop'
},
{
src: 'image-7aa06723bb01a7a79055b6d6f5be80329a0e5b58-780x1170-jpg',
width: 200,
height: 200,
fit: 'min'
}
]
},
// Storyblok
Expand Down
1 change: 1 addition & 0 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const BuiltInProviders = [
'imagekit',
'imgix',
'ipx',
'prismic',
'sanity',
'static',
'twicpics',
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/providers/imgix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ProviderGetImage } from 'src'
import { joinURL } from 'ufo'
import { createOperationsGenerator } from '~image'

const operationsGenerator = createOperationsGenerator({
export const operationsGenerator = createOperationsGenerator({
keyMap: {
width: 'w',
height: 'h',
Expand Down
36 changes: 36 additions & 0 deletions src/runtime/providers/prismic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { ProviderGetImage } from 'src'
import { $URL, joinURL } from 'ufo'
import { operationsGenerator } from './imgix'

const PRISMIC_IMGIX_BUCKET = '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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perf: We serialize modifiers to operations and use parseQuery in return statement! (postponing since it is mostly a utility refactor for all providers with operationsGenerator)


// If there are already some query parameters set by Prismic
const joinOperator = src.includes('?') ? '&' : '?'
lihbr marked this conversation as resolved.
Show resolved Hide resolved

// Create URL object accordingly
const url = new $URL(
lihbr marked this conversation as resolved.
Show resolved Hide resolved
joinURL(
baseURL,
src.replace(new RegExp(`^${baseURL}`, 'i'), '') +
(operations ? (joinOperator + operations) : '')
)
)

// Remove duplicated keys, prioritizing override from developers
Object.entries(url.query).forEach(([k, v]) => {
lihbr marked this conversation as resolved.
Show resolved Hide resolved
if (Array.isArray(v)) {
url.query[k] = v.pop()
}
})

return {
url: url.toString()
}
}
1 change: 1 addition & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface ImageProviders {
fastly?: any
imagekit?: any
imgix?: any
prismic?: any
twicpics?: any
storyblok?: any,
ipx?: Partial<IPXOptions>
Expand Down
18 changes: 12 additions & 6 deletions test/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export const images = [
twicpics: { url: '/test.png' },
fastly: { url: '/test.png' },
imgix: { url: '/test.png' },
imagekit: { url: '/test.png' }
imagekit: { url: '/test.png' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=100' }
},
{
args: ['/test.png', { width: 200 }],
Expand All @@ -15,7 +16,8 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=200x-' },
fastly: { url: '/test.png?width=200' },
imgix: { url: '/test.png?w=200' },
imagekit: { url: '/test.png?tr=w-200' }
imagekit: { url: '/test.png?tr=w-200' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=100' }
},
{
args: ['/test.png', { height: 200 }],
Expand All @@ -24,7 +26,8 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=-x200' },
fastly: { url: '/test.png?height=200' },
imgix: { url: '/test.png?h=200' },
imagekit: { url: '/test.png?tr=h-200' }
imagekit: { url: '/test.png?tr=h-200' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=100&h=200' }
},
{
args: ['/test.png', { width: 200, height: 200 }],
Expand All @@ -33,7 +36,8 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/cover=200x200' },
fastly: { url: '/test.png?width=200&height=200' },
imgix: { url: '/test.png?w=200&h=200' },
imagekit: { url: '/test.png?tr=w-200,h-200' }
imagekit: { url: '/test.png?tr=w-200,h-200' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200' }
},
{
args: ['/test.png', { width: 200, height: 200, fit: 'contain' }],
Expand All @@ -42,7 +46,8 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/contain=200x200' },
fastly: { url: '/test.png?width=200&height=200&fit=bounds' },
imgix: { url: '/test.png?w=200&h=200&fit=fill' },
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize' }
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill' }
},
{
args: ['/test.png', { width: 200, height: 200, fit: 'contain', format: 'jpeg' }],
Expand All @@ -51,7 +56,8 @@ export const images = [
twicpics: { url: '/test.png?twic=v1/output=jpeg/contain=200x200' },
fastly: { url: '/test.png?width=200&height=200&fit=bounds&format=jpeg' },
imgix: { url: '/test.png?w=200&h=200&fit=fill&fm=jpeg' },
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize,f-jpeg' }
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize,f-jpeg' },
prismic: { url: '/test.png?auto=compress,format&rect=0,0,200,200&w=200&h=200&fit=fill&fm=jpeg' }
}
] as const

Expand Down
16 changes: 16 additions & 0 deletions test/unit/providers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as twicpics from '~/runtime/providers/twicpics'
import * as fastly from '~/runtime/providers/fastly'
import * as imgix from '~/runtime/providers/imgix'
import * as imagekit from '~/runtime/providers/imagekit'
import * as prismic from '~/runtime/providers/prismic'

describe('Providers', () => {
test('ipx', () => {
Expand Down Expand Up @@ -118,4 +119,19 @@ describe('Providers', () => {
expect(generated).toMatchObject(image.imagekit)
}
})

test('prismic', () => {
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 [src, modifiers] = image.args
const generated = prismic.getImage(`${src}${EXISTING_QUERY_PARAMETERS}`, { modifiers, ...providerOptions }, {} as any)
expect(generated).toMatchObject(image.prismic)
}
})
})