diff --git a/packages/gatsby-source-contentful/.gitignore b/packages/gatsby-source-contentful/.gitignore index 7310660e91080..1a46274e77c91 100644 --- a/packages/gatsby-source-contentful/.gitignore +++ b/packages/gatsby-source-contentful/.gitignore @@ -1,7 +1,4 @@ -/gatsby-node.js -/fragments.js -/extend-node-type.js -/normalize.js -/fetch.js /__tests__ /yarn.lock +/*.js +!index.js diff --git a/packages/gatsby-source-contentful/index.js b/packages/gatsby-source-contentful/index.js index e89c38a7a07c4..c3b803dbe9304 100644 --- a/packages/gatsby-source-contentful/index.js +++ b/packages/gatsby-source-contentful/index.js @@ -1 +1 @@ -// no-op +module.exports.schemes = require(`./schemes.js`) diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/extend-node-type.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/extend-node-type.js.snap index 7cd690f2081a7..77808f0c3c676 100644 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/extend-node-type.js.snap +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/extend-node-type.js.snap @@ -19,7 +19,7 @@ Object { "aspectRatio": 1.1278195488721805, "baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg", "height": 399, - "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill", + "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&bg=rgb%3A000000", "width": 450, } `; @@ -43,11 +43,11 @@ Object { "aspectRatio": 1.1278195488721805, "baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg", "height": 399, - "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill", - "srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill 1x, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50&fit=fill 1.5x, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50&fit=fill 2x, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50&fit=fill 3x", + "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&bg=rgb%3A000000", + "srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&fit=fill&bg=rgb%3A000000 1x, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50&fit=fill&bg=rgb%3A000000 1.5x, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50&fit=fill&bg=rgb%3A000000 2x, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50&fit=fill&bg=rgb%3A000000 3x", "width": 450, } `; @@ -70,16 +70,16 @@ Object { exports[`contentful extend node type resolveResponsiveSizes generates responsive sizes data for images using all options 1`] = ` Object { - "aspectRatio": 0.75, + "aspectRatio": 1.1278195488721805, "baseUrl": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg", "sizes": "(max-width: 450px) 100vw, 450px", - "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50", - "srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=113&h=100&q=50 113w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=225&h=200&q=50 225w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50 450w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50 675w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50 900w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50 1350w, -//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=4500&h=3990&q=50 4500w", + "src": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&bg=rgb%3A000000", + "srcSet": "//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=113&h=100&q=50&bg=rgb%3A000000 113w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=225&h=200&q=50&bg=rgb%3A000000 225w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=450&h=399&q=50&bg=rgb%3A000000 450w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=675&h=599&q=50&bg=rgb%3A000000 675w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=900&h=798&q=50&bg=rgb%3A000000 900w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=1350&h=1197&q=50&bg=rgb%3A000000 1350w, +//images.contentful.com/ubriaw6jfhm1/10TkaLheGeQG6qQGqWYqUI/5421d3108cbb699561acabd594fa2cb0/ryugj83mqwa1asojwtwb.jpg?w=4500&h=3990&q=50&bg=rgb%3A000000 4500w", } `; diff --git a/packages/gatsby-source-contentful/src/__tests__/extend-node-type.js b/packages/gatsby-source-contentful/src/__tests__/extend-node-type.js index 8df1edf9e67a1..88268d0783b0c 100644 --- a/packages/gatsby-source-contentful/src/__tests__/extend-node-type.js +++ b/packages/gatsby-source-contentful/src/__tests__/extend-node-type.js @@ -51,6 +51,7 @@ describe(`contentful extend node type`, () => { width: 450, height: 399, quality: 50, + background: `rgb:000000`, }) expect(resp.srcSet.length).toBeGreaterThan(1) expect(resp).toMatchSnapshot() @@ -96,6 +97,7 @@ describe(`contentful extend node type`, () => { maxWidth: 450, maxHeight: 399, quality: 50, + background: `rgb:000000`, }) expect(resp.srcSet.length).toBeGreaterThan(1) expect(resp).toMatchSnapshot() @@ -117,6 +119,7 @@ describe(`contentful extend node type`, () => { width: 450, height: 399, quality: 50, + background: `rgb:000000`, }) expect(resp).toMatchSnapshot() }) diff --git a/packages/gatsby-source-contentful/src/extend-node-type.js b/packages/gatsby-source-contentful/src/extend-node-type.js index c0c638df42a6c..2141ae8c751b8 100644 --- a/packages/gatsby-source-contentful/src/extend-node-type.js +++ b/packages/gatsby-source-contentful/src/extend-node-type.js @@ -5,66 +5,16 @@ const { GraphQLString, GraphQLInt, GraphQLFloat, - GraphQLEnumType, } = require(`graphql`) const qs = require(`qs`) const base64Img = require(`base64-img`) const _ = require(`lodash`) -const ImageFormatType = new GraphQLEnumType({ - name: `ContentfulImageFormat`, - values: { - NO_CHANGE: { value: `` }, - JPG: { value: `jpg` }, - PNG: { value: `png` }, - WEBP: { value: `webp` }, - }, -}) - -const ImageResizingBehavior = new GraphQLEnumType({ - name: `ImageResizingBehavior`, - values: { - NO_CHANGE: { - value: ``, - }, - PAD: { - value: `pad`, - description: `Same as the default resizing, but adds padding so that the generated image has the specified dimensions.`, - }, - - CROP: { - value: `crop`, - description: `Crop a part of the original image to match the specified size.`, - }, - FILL: { - value: `fill`, - description: `Crop the image to the specified dimensions, if the original image is smaller than these dimensions, then the image will be upscaled.`, - }, - THUMB: { - value: `thumb`, - description: `When used in association with the f parameter below, creates a thumbnail from the image based on a focus area.`, - }, - SCALE: { - value: `scale`, - description: `Scale the image regardless of the original aspect ratio.`, - }, - }, -}) - -const ImageCropFocusType = new GraphQLEnumType({ - name: `ContentfulImageCropFocus`, - values: { - TOP: { value: `top` }, - TOP_LEFT: { value: `top_left` }, - TOP_RIGHT: { value: `top_right` }, - BOTTOM: { value: `bottom` }, - BOTTOM_RIGHT: { value: `bottom_left` }, - BOTTOM_LEFT: { value: `bottom_right` }, - RIGHT: { value: `right` }, - LEFT: { value: `left` }, - FACES: { value: `faces` }, - }, -}) +const { + ImageFormatType, + ImageResizingBehavior, + ImageCropFocusType, +} = require(`./schemes`) const isImage = image => _.includes( @@ -110,9 +60,10 @@ const createUrl = (imgUrl, options = {}) => { h: options.height, fl: options.jpegProgressive ? `progressive` : null, q: options.quality, - fm: options.toFormat ? options.toFormat : ``, - fit: options.resizingBehavior ? options.resizingBehavior : ``, - f: options.cropFocus ? options.cropFocus : ``, + fm: options.toFormat || ``, + fit: options.resizingBehavior || ``, + f: options.cropFocus || ``, + bg: options.background || ``, }, _.identity ) @@ -195,7 +146,7 @@ const resolveResponsiveResolution = (image, options) => { } return { - aspectRatio: aspectRatio, + aspectRatio: desiredAspectRatio, baseUrl, width: Math.round(options.width), height: Math.round(pickedHeight), @@ -265,7 +216,7 @@ const resolveResponsiveSizes = (image, options) => { .join(`,\n`) return { - aspectRatio: aspectRatio, + aspectRatio: desiredAspectRatio, baseUrl, src: createUrl(baseUrl, { ...options, @@ -389,6 +340,10 @@ exports.extendNodeType = ({ type }) => { type: ImageCropFocusType, defaultValue: null, }, + background: { + type: GraphQLString, + defaultValue: null, + }, }, resolve: (image, options, context) => Promise.resolve(resolveResponsiveResolution(image, options)).then( @@ -475,6 +430,10 @@ exports.extendNodeType = ({ type }) => { type: ImageCropFocusType, defaultValue: null, }, + background: { + type: GraphQLString, + defaultValue: null, + }, sizes: { type: GraphQLString, }, @@ -530,6 +489,10 @@ exports.extendNodeType = ({ type }) => { type: ImageCropFocusType, defaultValue: null, }, + background: { + type: GraphQLString, + defaultValue: null, + }, }, resolve(image, options, context) { return resolveResponsiveResolution(image, options) @@ -578,6 +541,10 @@ exports.extendNodeType = ({ type }) => { sizes: { type: GraphQLString, }, + background: { + type: GraphQLString, + defaultValue: null, + }, }, resolve(image, options, context) { return resolveResponsiveSizes(image, options) @@ -626,6 +593,10 @@ exports.extendNodeType = ({ type }) => { type: ImageCropFocusType, defaultValue: null, }, + background: { + type: GraphQLString, + defaultValue: null, + }, }, resolve(image, options, context) { return resolveResize(image, options) diff --git a/packages/gatsby-source-contentful/src/schemes.js b/packages/gatsby-source-contentful/src/schemes.js new file mode 100644 index 0000000000000..b00675da1b56a --- /dev/null +++ b/packages/gatsby-source-contentful/src/schemes.js @@ -0,0 +1,64 @@ +const { + GraphQLEnumType, +} = require(`graphql`) + +const ImageFormatType = new GraphQLEnumType({ + name: `ContentfulImageFormat`, + values: { + NO_CHANGE: { value: `` }, + JPG: { value: `jpg` }, + PNG: { value: `png` }, + WEBP: { value: `webp` }, + }, +}) + +const ImageResizingBehavior = new GraphQLEnumType({ + name: `ImageResizingBehavior`, + values: { + NO_CHANGE: { + value: ``, + }, + PAD: { + value: `pad`, + description: `Same as the default resizing, but adds padding so that the generated image has the specified dimensions.`, + }, + + CROP: { + value: `crop`, + description: `Crop a part of the original image to match the specified size.`, + }, + FILL: { + value: `fill`, + description: `Crop the image to the specified dimensions, if the original image is smaller than these dimensions, then the image will be upscaled.`, + }, + THUMB: { + value: `thumb`, + description: `When used in association with the f parameter below, creates a thumbnail from the image based on a focus area.`, + }, + SCALE: { + value: `scale`, + description: `Scale the image regardless of the original aspect ratio.`, + }, + }, +}) + +const ImageCropFocusType = new GraphQLEnumType({ + name: `ContentfulImageCropFocus`, + values: { + TOP: { value: `top` }, + TOP_LEFT: { value: `top_left` }, + TOP_RIGHT: { value: `top_right` }, + BOTTOM: { value: `bottom` }, + BOTTOM_RIGHT: { value: `bottom_left` }, + BOTTOM_LEFT: { value: `bottom_right` }, + RIGHT: { value: `right` }, + LEFT: { value: `left` }, + FACES: { value: `faces` }, + }, +}) + +module.exports = { + ImageFormatType, + ImageResizingBehavior, + ImageCropFocusType, +}