Skip to content

Commit

Permalink
feat: add contentful provider (#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
ykzts authored Sep 5, 2021
1 parent ce66fa7 commit 3eccba6
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 6 deletions.
18 changes: 18 additions & 0 deletions docs/content/en/4.providers/contentful.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Contentful Provider
description: 'Nuxt Image has first class integration with Contentful'
navigation:
title: Contentful
---

Integration between [Contentful](https://www.contentful.com/) and the image module.

To use this provider you just need to specify the base url of your service in Contentful.

```js{}[nuxt.config.js]
export default {
image: {
contentful: {}
}
}
```
1 change: 1 addition & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default <NuxtConfig> {
cloudinary: {
baseURL: 'https://res.cloudinary.com/nuxt/image/upload/'
},
contentful: {},
fastly: {
baseURL: 'https://www.fastly.io'
},
Expand Down
20 changes: 20 additions & 0 deletions playground/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ export const providers: Provider[] = [
}
]
},
// Contentful
{
name: 'contentful',
samples: [
{
src: '//images.ctfassets.net/fbr4i5aajb0w/6y0psij2o02YIwGScEo4kS/1b3f09b8fcedece1d17ea58417b55eb4/photo-1421986527537-888d998adb74.jpeg'
},
{
src: '//images.ctfassets.net/fbr4i5aajb0w/6y0psij2o02YIwGScEo4kS/1b3f09b8fcedece1d17ea58417b55eb4/photo-1421986527537-888d998adb74.jpeg',
width: 200,
height: 133
},
{
src: '//images.ctfassets.net/fbr4i5aajb0w/6y0psij2o02YIwGScEo4kS/1b3f09b8fcedece1d17ea58417b55eb4/photo-1421986527537-888d998adb74.jpeg',
width: 200,
height: 200,
fit: 'contain'
}
]
},
// Fastly
{
name: 'fastly',
Expand Down
1 change: 1 addition & 0 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ipxSetup } from './ipx'

const BuiltInProviders = [
'cloudinary',
'contentful',
'fastly',
'glide',
'imagekit',
Expand Down
43 changes: 43 additions & 0 deletions src/runtime/providers/contentful.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { withBase, parseURL } from 'ufo'
import type { ProviderGetImage } from 'src'
import { createOperationsGenerator } from '~image'

// https://www.contentful.com/developers/docs/references/images-api/
const contentfulCDN = 'https://images.ctfassets.net'

export const operationsGenerator = createOperationsGenerator({
keyMap: {
format: 'fm',
width: 'w',
height: 'h',
focus: 'f',
radius: 'r',
quality: 'q',
background: 'bg'
},
valueMap: {
format: {
jpeg: 'jpg'
},
fit: {
cover: 'crop',
contain: 'fill',
fill: 'scale',
thumbnail: 'thumb'
}
},
joinWith: '&',
formatter: (key, value) => `${key}=${value}`
})

export const getImage: ProviderGetImage = (src, { modifiers = {}, baseURL = contentfulCDN } = {}) => {
const operations = operationsGenerator(modifiers)

const { pathname } = parseURL(src)
const path = pathname + (operations ? ('?' + operations) : '')
const url = withBase(path, baseURL)

return {
url
}
}
1 change: 1 addition & 0 deletions src/types/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface InputProvider<T = any> {

export interface ImageProviders {
cloudinary?: any
contentful?: any
fastly?: any
glide?: any
imagekit?: any
Expand Down
18 changes: 12 additions & 6 deletions test/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const images = [
imagekit: { url: '/test.png' },
netlify: { url: '/test.png' },
prismic: { url: '/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' }
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?auto=format' },
contentful: { url: '/test.png' }
},
{
args: ['/test.png', { width: 200 }],
Expand All @@ -25,7 +26,8 @@ export const images = [
imagekit: { url: '/test.png?tr=w-200' },
netlify: { url: '/test.png?w=200&nf_resize=fit' },
prismic: { url: '/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' }
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&auto=format' },
contentful: { url: '/test.png?w=200' }
},
{
args: ['/test.png', { height: 200 }],
Expand All @@ -39,7 +41,8 @@ export const images = [
imagekit: { url: '/test.png?tr=h-200' },
netlify: { url: '/test.png?h=200&nf_resize=fit' },
prismic: { url: '/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' }
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?h=200&auto=format' },
contentful: { url: '/test.png?h=200' }
},
{
args: ['/test.png', { width: 200, height: 200 }],
Expand All @@ -53,7 +56,8 @@ export const images = [
imagekit: { url: '/test.png?tr=w-200,h-200' },
netlify: { 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' },
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&auto=format' }
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' }
},
{
args: ['/test.png', { width: 200, height: 200, fit: 'contain' }],
Expand All @@ -67,7 +71,8 @@ export const images = [
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize' },
netlify: { 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' },
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&fit=fill&auto=format&bg=ffffff' }
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' }
},
{
args: ['/test.png', { width: 200, height: 200, fit: 'contain', format: 'jpeg' }],
Expand All @@ -81,7 +86,8 @@ export const images = [
imagekit: { url: '/test.png?tr=w-200,h-200,cm-pad_resize,f-jpeg' },
netlify: { 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' },
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&fit=fill&fm=jpg&bg=ffffff' }
sanity: { url: 'https://cdn.sanity.io/images/projectid/production/test-300x450.png?w=200&h=200&fit=fill&fm=jpg&bg=ffffff' },
contentful: { url: '/test.png?w=200&h=200&fit=fill&fm=jpg' }
}
] as const

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

const emptyContext = { options: {} } as any

Expand Down Expand Up @@ -199,4 +200,16 @@ describe('Providers', () => {
expect(generated).toMatchObject(image.sanity)
}
})

test('contentful', () => {
const providerOptions = {
baseURL: ''
}

for (const image of images) {
const [src, modifiers] = image.args
const generated = contentful.getImage(src, { modifiers, ...providerOptions }, emptyContext)
expect(generated).toMatchObject(image.contentful)
}
})
})

0 comments on commit 3eccba6

Please sign in to comment.