diff --git a/packages/gatsby-source-contentful/package.json b/packages/gatsby-source-contentful/package.json index bb0b476b933c1..cdc655044d403 100644 --- a/packages/gatsby-source-contentful/package.json +++ b/packages/gatsby-source-contentful/package.json @@ -11,15 +11,13 @@ "@contentful/rich-text-react-renderer": "^14.1.2", "@contentful/rich-text-types": "^14.1.2", "@hapi/joi": "^15.1.1", - "axios": "^0.21.0", - "base64-img": "^1.0.4", - "bluebird": "^3.7.2", "chalk": "^4.1.0", "contentful": "^8.1.7", "fs-extra": "^9.0.1", "gatsby-core-utils": "^1.9.0-next.0", "gatsby-plugin-utils": "^0.8.0-next.1", "gatsby-source-filesystem": "^2.10.0-next.1", + "got": "^9.6.0", "is-online": "^8.5.1", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.20", diff --git a/packages/gatsby-source-contentful/src/cache-image.js b/packages/gatsby-source-contentful/src/cache-image.js index 714e08ef32f50..2cc19325050fb 100644 --- a/packages/gatsby-source-contentful/src/cache-image.js +++ b/packages/gatsby-source-contentful/src/cache-image.js @@ -1,8 +1,8 @@ +const fs = require(`fs`) const crypto = require(`crypto`) const { resolve, parse } = require(`path`) -const axios = require(`axios`) -const { pathExists, createWriteStream } = require(`fs-extra`) +const got = require(`got`) const inFlightImageCache = new Map() @@ -48,28 +48,28 @@ module.exports = async function cacheImage(store, image, options) { const absolutePath = resolve(CACHE_DIR, `${name}-${optionsHash}${ext}`) // Query the filesystem for file existence - const alreadyExists = await pathExists(absolutePath) + const alreadyExists = await fs.promises + .access(absolutePath, fs.constants.F_OK) + .then(() => true) + .catch(() => false) + // Whether the file exists or not, if we are downloading it then await const inFlight = inFlightImageCache.get(absolutePath) if (inFlight) { await inFlight } else if (!alreadyExists) { // File doesn't exist and is not being download yet - const downloadPromise = new Promise(async (resolve, reject) => { + const downloadPromise = new Promise(async () => { const previewUrl = `http:${url}?${params.join(`&`)}` - const response = await axios({ - method: `get`, - url: previewUrl, - responseType: `stream`, - }) - const file = createWriteStream(absolutePath) - response.data.pipe(file) - file.on(`finish`, resolve) - file.on(`error`, reject) + const imageBuffer = await got(previewUrl).buffer() + + return fs.promises.writeFile(absolutePath, imageBuffer) }) inFlightImageCache.set(absolutePath, downloadPromise) + await downloadPromise + // When the file is downloaded, remove the promise from the cache inFlightImageCache.delete(absolutePath) } diff --git a/packages/gatsby-source-contentful/src/extend-node-type.js b/packages/gatsby-source-contentful/src/extend-node-type.js index 2a29aa0791755..c662c32adfa11 100644 --- a/packages/gatsby-source-contentful/src/extend-node-type.js +++ b/packages/gatsby-source-contentful/src/extend-node-type.js @@ -2,7 +2,6 @@ const fs = require(`fs`) const path = require(`path`) const crypto = require(`crypto`) -const Promise = require(`bluebird`) const { GraphQLObjectType, GraphQLBoolean, @@ -11,8 +10,8 @@ const { GraphQLFloat, GraphQLNonNull, } = require(`gatsby/graphql`) +const got = require(`got`) const qs = require(`qs`) -const base64Img = require(`base64-img`) const cacheImage = require(`./cache-image`) @@ -58,7 +57,7 @@ const isImage = image => ) // Note: this may return a Promise, body (sync), or null -const getBase64Image = imageProps => { +const getBase64Image = async imageProps => { if (!imageProps) { return null } @@ -103,28 +102,25 @@ 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 imageBuffer = await got(requestUrl).buffer() + const body = imageBuffer.toString(`base64`) - inFlightBase64Cache.set(requestUrl, promise) + try { + const promise = fs.promises.writeFile(cacheFile, body) - return promise.then(body => { - inFlightBase64Cache.delete(requestUrl) - resolvedBase64Cache.set(requestUrl, body) - return body - }) + inFlightBase64Cache.set(requestUrl, promise) + + return promise.then(() => { + inFlightBase64Cache.delete(requestUrl) + resolvedBase64Cache.set(requestUrl, 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 getBasicImageProps = (image, args) => { @@ -403,9 +399,7 @@ const fixedNodeType = ({ name, getTracedSVG }) => { fields: { base64: { type: GraphQLString, - resolve(imageProps) { - return getBase64Image(imageProps) - }, + resolve: getBase64Image, }, tracedSVG: { type: GraphQLString, @@ -500,9 +494,7 @@ const fluidNodeType = ({ name, getTracedSVG }) => { fields: { base64: { type: GraphQLString, - resolve(imageProps) { - return getBase64Image(imageProps) - }, + resolve: getBase64Image, }, tracedSVG: { type: GraphQLString, @@ -647,9 +639,7 @@ exports.extendNodeType = ({ type, store, cache, getNodesByType }) => { fields: { base64: { type: GraphQLString, - resolve(imageProps) { - return getBase64Image(imageProps) - }, + resolve: getBase64Image, }, tracedSVG: { type: GraphQLString,