Last active
May 29, 2020 10:00
-
-
Save noxify/7f3085b400991535ef997dedaacf2b1d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
. | |
|-src | |
| |-components | |
| |-layouts | |
| |-templates | |
| |-assets | |
| | |-remoteImages | |
| | | |- image.png ( <-- my example image which is used in the code below ) | |
| |-pages | |
|-packages | |
| |-gridsome-plugin-remote-image | |
| | |-gridsome.server.js ( <-- package-gridsome.server.js ) | |
|-gridsome.config.js ( <-- root-gridsome.config.js ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs') | |
const path = require('path') | |
const crypto = require('crypto') | |
const imageType = require('image-type') | |
const imageDownload = require('image-download') | |
const validate = require('validate.js') | |
const chalk = require('chalk') | |
const _ = require('lodash') | |
class ImageDownloader { | |
constructor(api, options) { | |
this.options = options; | |
this.api = api; | |
//initialize the `loadImage` event and make | |
//it available before we run the `onBootstrap` command | |
this.initializeEvent(api); | |
//create a new type `Images` which is required | |
//for array support | |
//also add a new field to the defined collection | |
//to store the downloaded images | |
api.createSchema(({ addSchemaTypes }) => { | |
const fieldType = this.getFieldType(api, options); | |
this.generateSchemaType(addSchemaTypes, fieldType); | |
}); | |
//run the plugin code, after gridsome finished all their work ( right? ) | |
api.onBootstrap(() => this.loadImages()) | |
} | |
/** | |
* Create a new event via the gridsome plugin api | |
* reference: node_modules/gridsome/lib/app/PluginAPI.js | |
*/ | |
initializeEvent(api) { | |
api._on('loadImage', this.runDownloader) | |
} | |
/** | |
* Run the defined event with the required | |
* arguments - i have no clue why `this` is not available | |
* but I'm too tired to check this in detail... | |
* Defining the needed methods is fine for me :) | |
*/ | |
async loadImages() { | |
await this.run('loadImage', null, { | |
getFieldType: this.getFieldType, | |
getRemoteImage: this.getRemoteImage, | |
updateNodes: this.updateNodes, | |
options: this.options | |
}) | |
} | |
/** | |
* Defined in `initializeEvent` | |
* Called via `loadImages` | |
*/ | |
async runDownloader(plugin, api) { | |
const fieldType = plugin.getFieldType(api, plugin.options); | |
await plugin.updateNodes(api, fieldType, plugin.options) | |
} | |
getFieldType(api, options) { | |
const nodeCollection = api._app.store.getCollection(options.typeName); | |
let findQuery = {}; | |
//details about this definition can be found here | |
//https://github.com/techfort/LokiJS/wiki/Query-Examples#find-operator-examples- | |
findQuery[options.sourceField] = { | |
'$exists': true | |
}; | |
const node = nodeCollection.findNode(findQuery); | |
//we're using the lodash get functionality | |
//to allow a dot notation in the source field name | |
return (node) ? typeof _.get(node, options.sourceField) : false; | |
} | |
generateSchemaType(addSchemaTypes, fieldType) { | |
const schemaType = (fieldType == 'string') ? 'Image' : '[Images]'; | |
addSchemaTypes( | |
` | |
type Images { | |
image: Image | |
} | |
` | |
); | |
//extend the existing schema | |
addSchemaTypes( | |
` | |
type ${this.options.typeName} implements Node @infer { | |
${this.options.targetField}: ${schemaType} | |
} | |
` | |
); | |
} | |
async updateNodes(api, fieldType, options) { | |
var collection = api._app.store.getCollection(options.typeName); | |
collection.data().forEach(async function (node) { | |
if (_.get(node,options.sourceField)) { | |
//const imagePaths = await that.getRemoteImage(node, fieldType); | |
const image = path.resolve( | |
options.targetPath, | |
`image.png` | |
) | |
const imagePaths = [image]; | |
if( fieldType == 'string' ) { | |
node[options.targetField] = imagePaths[0]; | |
} else { | |
node[options.targetField] = _.map(imagePaths, function(imagePath) { | |
return { | |
image: imagePath | |
}; | |
}); | |
} | |
var res = collection.updateNode(node); | |
} | |
}) | |
} | |
/********************** | |
* Helpers | |
**********************/ | |
/** | |
* Copied from node_modules/gridsome/lib/app/Plugins.js | |
*/ | |
async run(eventName, cb, ...args) { | |
if (!this.api._app.plugins._listeners[eventName]) return [] | |
const results = [] | |
for (const entry of this.api._app.plugins._listeners[eventName]) { | |
if (entry.options.once && entry.done) continue | |
const { api, handler } = entry | |
const result = typeof cb === 'function' | |
? await handler(cb(api)) | |
: await handler(...args, api) | |
results.push(result) | |
entry.done = true | |
} | |
return results | |
} | |
validateOptions(options = {}) { | |
const contraintOption = { | |
presence: { | |
allowEmpty: false | |
} | |
}; | |
const constraints = { | |
typeName: contraintOption, | |
sourceField: contraintOption, | |
targetField: contraintOption, | |
targetPath: contraintOption | |
}; | |
const validationResult = validate(options, constraints, { | |
format: "flat" | |
}); | |
return validationResult; | |
} | |
} | |
module.exports = ImageDownloader |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
siteName: 'Gridsome', | |
plugins: [ | |
{ | |
use: '@gridsome/source-contentful', | |
options: { | |
space: 'XXXX', // required | |
accessToken: 'XXX', // required | |
host: 'cdn.contentful.com', | |
environment: 'master', | |
typeName: 'Contentful' | |
} | |
}, | |
{ | |
use: '~/packages/gridsome-plugin-remote-image', | |
options: { | |
'typeName' : 'ContentfulAsset', | |
'sourceField': 'file.url', | |
'targetField': 'imageDownloaded', | |
'targetPath': './src/assets/remoteImages' | |
} | |
} | |
], | |
templates : { | |
ContentfulArticles: '/contentful/:title' | |
}, | |
transformer : { | |
remark: {} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment