diff --git a/.prettierrc b/.prettierrc index 227d8d6..f685078 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,5 +2,5 @@ "trailingComma": "es5", "semi": false, "tabWidth": 2, - "single-quote": true + "singleQuote": true } diff --git a/package.json b/package.json index 219a0ad..cb49328 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "dependencies": { "axios": "^0.17.1", "gatsby-node-helpers": "^0.1.3", + "gatsby-source-filesystem": "^1.5.39", "lodash": "^4.17.4" }, "devDependencies": { @@ -47,8 +48,8 @@ "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.0", - "prettier": "^1.5.3", - "pre-commit": "^1.2.2" + "pre-commit": "^1.2.2", + "prettier": "^1.5.3" }, "pre-commit": [ "format" diff --git a/src/gatsby-node.js b/src/gatsby-node.js index 6085ddb..10a6b2a 100644 --- a/src/gatsby-node.js +++ b/src/gatsby-node.js @@ -2,12 +2,13 @@ import axios from 'axios' import fetchData from './fetch' import { Node } from './nodes' import { capitalize } from 'lodash' +import normalize from './normalize' exports.sourceNodes = async ( - { boundActionCreators }, + { store, boundActionCreators, cache }, { apiURL = 'http://localhost:1337', contentTypes = [], loginData = {} } ) => { - const { createNode } = boundActionCreators + const { createNode, touchNode } = boundActionCreators let jwtToken = null // Check if loginData is set. @@ -47,13 +48,21 @@ exports.sourceNodes = async ( ) // Execute the promises. - const data = await Promise.all(promises) + let entities = await Promise.all(promises) - // Create nodes. - contentTypes.forEach((contentType, i) => { - const items = data[i] + entities = await normalize.downloadMediaFiles({ + entities, + apiURL, + store, + cache, + createNode, + touchNode, + jwtToken, + }) - items.forEach(item => { + contentTypes.forEach((contentType, i) => { + const items = entities[i] + items.forEach((item, i) => { const node = Node(capitalize(contentType), item) createNode(node) }) diff --git a/src/normalize.js b/src/normalize.js new file mode 100644 index 0000000..52d4309 --- /dev/null +++ b/src/normalize.js @@ -0,0 +1,71 @@ +const { createRemoteFileNode } = require(`gatsby-source-filesystem`) + +// Downloads media from image type fields +exports.downloadMediaFiles = async ({ + entities, + apiURL, + store, + cache, + createNode, + touchNode, + jwtToken: auth, +}) => + Promise.all( + entities.map(async entity => { + for (let item of entity) { + // loop item over fields + for (const key of Object.keys(item)) { + const field = item[key] + // image fields have a mime property among other + // maybe should find a better test + if (field.hasOwnProperty('mime')) { + let fileNodeID + // using field on the cache key for multiple image field + const mediaDataCacheKey = `strapi-media-${item.id}-${key}` + const cacheMediaData = await cache.get(mediaDataCacheKey) + + // If we have cached media data and it wasn't modified, reuse + // previously created file node to not try to redownload + if ( + cacheMediaData && + field.updatedAt === cacheMediaData.updatedAt + ) { + fileNodeID = cacheMediaData.fileNodeID + touchNode(cacheMediaData.fileNodeID) + } + + // If we don't have cached data, download the file + if (!fileNodeID) { + try { + // full media url + const source_url = apiURL + field.url + const fileNode = await createRemoteFileNode({ + url: source_url, + store, + cache, + createNode, + auth, + }) + + // If we don't have cached data, download the file + if (fileNode) { + fileNodeID = fileNode.id + + await cache.set(mediaDataCacheKey, { + fileNodeID, + modified: field.updatedAt, + }) + } + } catch (e) { + // Ignore + } + } + if (fileNodeID) { + item[`${key}___NODE`] = fileNodeID + } + } + } + } + return entity + }) + )