Skip to content

Commit

Permalink
fix(gatsby-source-contentful): Improve base64 placeholders (#29034)
Browse files Browse the repository at this point in the history
* fix: prevent huge images from being embedded as base64

* fix: replace unmaintained base64-img with native solutions

fixes #24679

* fixup! fix: replace unmaintained base64-img with native solutions

* fixup! fix: prevent huge images from being embedded as base64
  • Loading branch information
axe312ger committed Jan 15, 2021
1 parent 18b5f30 commit f23ba4b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 26 deletions.
2 changes: 0 additions & 2 deletions packages/gatsby-source-contentful/package.json
Expand Up @@ -12,8 +12,6 @@
"@contentful/rich-text-types": "^14.1.2",
"@hapi/joi": "^15.1.1",
"axios": "^0.21.1",
"base64-img": "^1.0.4",
"bluebird": "^3.7.2",
"chalk": "^4.1.0",
"contentful": "^8.1.7",
"fs-extra": "^9.0.1",
Expand Down
54 changes: 30 additions & 24 deletions packages/gatsby-source-contentful/src/extend-node-type.js
Expand Up @@ -2,7 +2,7 @@ const fs = require(`fs`)
const path = require(`path`)
const crypto = require(`crypto`)

const Promise = require(`bluebird`)
const axios = require(`axios`)
const {
GraphQLObjectType,
GraphQLBoolean,
Expand All @@ -12,7 +12,6 @@ const {
GraphQLNonNull,
} = require(`gatsby/graphql`)
const qs = require(`qs`)
const base64Img = require(`base64-img`)

const cacheImage = require(`./cache-image`)

Expand Down Expand Up @@ -63,6 +62,11 @@ const getBase64Image = imageProps => {
return null
}

// We only support images that are delivered through Contentful's Image API
if (imageProps.baseUrl.indexOf(`images.ctfassets.net`) === -1) {
return null
}

const requestUrl = `https:${imageProps.baseUrl}?w=20`

// Prefer to return data sync if we already have it
Expand Down Expand Up @@ -98,20 +102,28 @@ const getBase64Image = imageProps => {
})
}

const promise = new Promise((resolve, reject) => {
base64Img.requestBase64(requestUrl, (a, b, body) => {
// TODO: against dogma, confirm whether writeFileSync is indeed slower
fs.promises
.writeFile(cacheFile, body)
.then(() => resolve(body))
.catch(e => {
console.error(
`Contentful:getBase64Image: failed to write ${body.length} bytes remotely fetched from \`${requestUrl}\` to: \`${cacheFile}\`\nError: ${e}`
)
reject(e)
})
const loadImage = async () => {
const imageResponse = await axios.get(requestUrl, {
responseType: `arraybuffer`,
})
})

const base64 = Buffer.from(imageResponse.data, `binary`).toString(`base64`)

const body = `data:image/jpeg;base64,${base64}`

try {
// TODO: against dogma, confirm whether writeFileSync is indeed slower
await fs.promises.writeFile(cacheFile, body)
return body
} catch (e) {
console.error(
`Contentful:getBase64Image: failed to write ${body.length} bytes remotely fetched from \`${requestUrl}\` to: \`${cacheFile}\`\nError: ${e}`
)
throw e
}
}

const promise = loadImage()

inFlightBase64Cache.set(requestUrl, promise)

Expand Down Expand Up @@ -398,9 +410,7 @@ const fixedNodeType = ({ name, getTracedSVG }) => {
fields: {
base64: {
type: GraphQLString,
resolve(imageProps) {
return getBase64Image(imageProps)
},
resolve: getBase64Image,
},
tracedSVG: {
type: GraphQLString,
Expand Down Expand Up @@ -495,9 +505,7 @@ const fluidNodeType = ({ name, getTracedSVG }) => {
fields: {
base64: {
type: GraphQLString,
resolve(imageProps) {
return getBase64Image(imageProps)
},
resolve: getBase64Image,
},
tracedSVG: {
type: GraphQLString,
Expand Down Expand Up @@ -642,9 +650,7 @@ exports.extendNodeType = ({ type, store, cache, getNodesByType }) => {
fields: {
base64: {
type: GraphQLString,
resolve(imageProps) {
return getBase64Image(imageProps)
},
resolve: getBase64Image,
},
tracedSVG: {
type: GraphQLString,
Expand Down

0 comments on commit f23ba4b

Please sign in to comment.