UNPKG

@viewdo/dxp-story-cli

Version:
260 lines (212 loc) 7.54 kB
//NPM Module Dependencies const fs = require('fs'); const mkdirp = require('mkdirp'); const isFunction = require('lodash/isFunction'); const colors = require("colors"); const watch = require('glob-watcher'); // Private Methods /** * Message for when this story's json is being built. * * @param {String} src - Source of this story's json to be made * @param {String} dest - Destination for this story's json */ const _startMessage = (src, dest) => { console.log(colors.cyan(`Creating story json from ${src} and ${src.indexOf('js') >= 0 ? 'building' : 'copying'} to ${dest}`)) } /** * Message for when this story's json is finish built. * * @param {String} src - Source of this story's json to be made * @param {String} dest - Destination for this story's json */ const _endMessage = (src, dest) => { console.log(colors.green(`Created story json from ${src} and ${src.indexOf('js') >= 0 ? 'building' : 'copying'} to ${dest}`)) } /** * Message for when this story's json has failed to built. * * @param {String} src - Source of this story's json to be made * @param {String} dest - Destination for this story's json */ const _errorMessage = (src, dest) => { console.log(colors.red(`Failed to created story json from ${src} and ${src.indexOf('js') >= 0 ? 'building' : 'copying'} to ${dest}, for the following reasons:`)) } /** * Creats the source and destination path to pipe the JSON file. * * @param {String} buildPath - directory where to put the JSON file * @param {Object} storyInfo - iVX Config settings for this particular story */ const _createJSONFileInfo = (buildPath, storyInfo) => { const { json: destJSONFileName = "story.json", source = {} } = storyInfo; const { json: srcJSONFileName, directory: srcPath } = source; const src = `${srcPath}/${srcJSONFileName}`; const dest = `${buildPath}/${destJSONFileName}`; return { src, dest, srcPath, buildPath } } /** * Creates a JSON string with indent of 4. * * @param {Object} obj */ const _createJSONString = (obj) => { return JSON.stringify(obj, null, 4) } /** * Clears the cached version of all the CommonJS modules that create the JSON * * @param {String} srcPath */ const _clearRequireCache = (srcPath) => { const cachedFiles = Object.keys(require.cache); cachedFiles.forEach(cacheFileName => { if ((cacheFileName.indexOf(srcPath.replace('./', ''))) || (cacheFileName.indexOf('_common/static-data') >= 0)) { delete require.cache[cacheFileName]; } }) } /** * Using the JSON settings from the story info, this will create and pipe * a JSON file with the json created from the source's json file. If the json * file is a function it will run the function to get the JSON. Otherwise, it will * set the json to add to file. * * @param {String} buildPath - directory where to put the JSON file * @param {Object} storyInfo - iVX Config settings for this particular story */ const _createJSONFile = (buildPath, storyInfo) => { const jsonFileInfo = _createJSONFileInfo(buildPath, storyInfo); const { src, dest, srcPath } = jsonFileInfo; const jsonCreatorPromise = new Promise((res) => { // TODO: Figure out how to do this programmatically const modifiedSrc = src.replace('./', '../../../../'); const jsonCreator = require(modifiedSrc); _startMessage(src, dest); let json = {}; if (isFunction(jsonCreator)) { json = jsonCreator(); } else { json = jsonCreator; } fs.access(buildPath, fs.constants.F_OK, (err) => { if (err) { mkdirp(buildPath, (err) => { fs.writeFile(dest, _createJSONString(json), err => { if (err) { _errorMessage(src, dest); console.log(err); return; } _endMessage(src, dest); _clearRequireCache(srcPath); res(); }); }); } else { fs.writeFile(dest, _createJSONString(json), err => { if (err) { _errorMessage(src, dest); console.log(err); return; } _clearRequireCache(srcPath); _endMessage(src, dest); res(); }); } }); }); return jsonCreatorPromise .catch((err) => { _errorMessage(src, dest); console.log(colors.red(err)); }); } const _createStoriesJSONBuildInfo = iVXConfig => { const { stories = {}, build: buildPath = "./" } = iVXConfig; const storyKeys = Object.keys(stories); if (storyKeys.length >= 1) { return storyKeys.map(storyKey => { const storyInfo = stories[storyKey]; const storyBuildPath = `${buildPath}/${storyKey}`; return { storyBuildPath, storyInfo } }); } return []; } const _getWatchFiles = (srcPath, src) => { return [ src, `${srcPath}/static-data/**/*.*`, `${srcPath}/index.json`, `_common/static-data/**/*.*`, `_common/metadata/**/*.*` ] } /** * Message to display when a file changes. * @param {String} filepath */ const _changeMessageStart = (filepath) => { console.log(colors.cyan(`Changes detected in file: ${filepath}`)); } const _changeMessageError = (filepath) => { console.log(colors.red(`Errors detected in file: ${filepath}`)); } const _watchJSONFiles = (buildPath, storyInfo, iVXConfig) => { const { src, srcPath } = _createJSONFileInfo(buildPath, storyInfo); const watchFolders = _getWatchFiles(srcPath, src); const watcher = watch(watchFolders); watcher.on('change', (path, stat) => { // _changeMessageStart(path); // _createJSONFile(buildPath, storyInfo) // .then(() => { // addStyleToJson(iVXConfig) // }) // .catch(err => { // _changeMessageError(err); // process.exit(exit); // }); }); } /** * Using the current iVXConfig, it will create various story jsons * and pipe them into a folder underneath the file name defined in the json. */ module.exports = { build: iVXConfig => { const storiesBuildInfo = _createStoriesJSONBuildInfo(iVXConfig); const jsonFilePromises = storiesBuildInfo.map(storyBuildInfo => { const { storyBuildPath, storyInfo } = storyBuildInfo; return _createJSONFile(storyBuildPath, storyInfo) .catch((err) => { console.log(colors.red(err)) }); }); return Promise.all(jsonFilePromises); }, watch: iVXConfig => { const storiesBuildInfo = _createStoriesJSONBuildInfo(iVXConfig); const allSetUp = storiesBuildInfo.map(storyBuildInfo => { const { storyBuildPath, storyInfo } = storyBuildInfo; return _createJSONFile(storyBuildPath, storyInfo) .then(() => { }); }); Promise.all(allSetUp) .then(() => { }) .catch((err)=>{ _changeMessageError(err); }) } }