@viewdo/dxp-story-cli
Version:
README.md
260 lines (212 loc) • 7.54 kB
JavaScript
//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);
})
}
}