UNPKG

@viewdo/dxp-story-cli

Version:
295 lines (238 loc) 8.54 kB
// NPM Module Dependencies const copyDir = require("copy-dir"); const fs = require('fs'); const mkdirp = require('mkdirp'); const colors = require('colors'); const watch = require("glob-watcher"); //Private Methods const templateNameMap = require("./template-name-map.json.js"); const templateFolders = Object.keys(templateNameMap); const _startMessage = (source, build, templateFolder) => { const templateName = templateNameMap[templateFolder].plural; console.log(colors.cyan(`Starting to copy ${templateName} from ${source} to ${build}`)); } const _fileMessage = (source, build, templateFolder) => { const templateName = templateNameMap[templateFolder].singular; console.log(colors.white(`Copying ${templateName} file from ${source} to ${build}`)); } const _errorMessage = (source, build, templateFolder) => { const templateName = templateNameMap[templateFolder].plural; console.log(colors.red(`Copying ${templateName} from ${source} to ${build} failed for the following reason:`)); } const _endMessage = (source, build, templateFolder) => { const templateName = templateNameMap[templateFolder].plural; console.log(colors.green(`Finish copying ${templateName} from ${source} to ${build}`)); } const _skipMessage = (source, build, templateFolder) => { const templateName = templateNameMap[templateFolder].plural; console.log(colors.yellow(`WARNING: Skipped moving ${templateName} from ${source} to ${build} due to the ${templateFolder} folder missing.`)); } const _changeMessage = (file_path) => { console.log(colors.cyan(`Changes detected in file: ${file_path}`)); } const _directoryExists = (dirPath) => { try { fs.accessSync(dirPath, fs.F_OK); return true; } catch (err) { return false; } } const _copyTemplateDirectory = (sourcePath, buildPath, templateFolder) => { return new Promise((res) => { if (!_directoryExists(sourcePath)) { _skipMessage(sourcePath, buildPath, templateFolder); res(); return; } _startMessage(sourcePath, buildPath, templateFolder); copyDir(sourcePath, buildPath, (state, filepath, filename) => { _fileMessage(`${sourcePath}/${filename}`, `${buildPath}/${filename}`, templateFolder); return true; }, err => { if (err) { _errorMessage(sourcePath, buildPath, templateFolder); console.log(err); return; } _endMessage(sourcePath, buildPath, templateFolder); res(); }); }); } /** * Copies one template from src to the build * @param {Object} templateSettings */ const _copyTemplate = (templateSettings) => { const { sourcePath, buildPath, templateFolder } = templateSettings; // Checks to see if there are any files in the selected template folder const directoryCheckPromise = new Promise((res) => { if (!_directoryExists(sourcePath)) { res(false); return; } fs.readdir(sourcePath, (err, files) => { if (err) { _errorMessage(sourcePath, buildPath, templateFolder); console.log(err); return; } res(files.length > 0); }); }); // Checks to see if the build directory exists const makeDirectoryPromise = new Promise((res) => { directoryCheckPromise .then(hasFiles => { if (hasFiles) { fs.access(buildPath, fs.constants.F_OK, (err) => { if (err) { mkdirp(buildPath, (err) => { res() }); return; } res(); }); return; } res(); }); }); return new Promise(res => { makeDirectoryPromise.then(() => { _copyTemplateDirectory(sourcePath, buildPath, templateFolder) .then(() => { res(); }); }); }); } /** * Creates a collection of information to copy template folders. * * @param {String} sourceDirectory * @param {String} buildDirectory * @param {String[]} templateFolders */ const _createTemplateFolderInfo = (sourceDirectory, buildDirectory, templateFolders) => { return templateFolders.map(templateFolder => { const sourcePath = `${sourceDirectory}/${templateFolder}`; const buildPath = `${buildDirectory}/${templateFolder}`; return { sourcePath, buildPath, templateFolder } }) } const _copyStoryIntroHTML = (introHTML) => { const { source, dest } = introHTML; const hasStoryIntroPromise = new Promise((res, rej) => { fs.access(source, fs.constants.F_OK, (err) => { if (err) { res(false); return; } res(true); }) }); return new Promise((res, rej) => { hasStoryIntroPromise .then(hasStoryIntro => { if (hasStoryIntro) { const storyHTML = fs.readFileSync(source, 'utf8'); res(); } else { res(); } }) .catch(err => rej); }); } const _copyTemplates = (sourceDirectory, buildDirectory, introHTML) => { const templateInfo = _createTemplateFolderInfo(sourceDirectory, buildDirectory, templateFolders) let templatePromises = templateInfo.map(templateSettings => { const copyPromise = _copyTemplate(templateSettings) return copyPromise .catch((err) => { console.log(err) }) }) templatePromises = [...templatePromises] return Promise.all([...templatePromises]) .then(()=>{ _copyStoryIntroHTML(introHTML) }); } const _getStoryDirectories = (story_keys, _console) => { const { output: outputPath, source: sourcePath} = console; return story_keys.map(storyKey => { const buildDirectory = `${outputPath}/${storyKey}`; const sourceDirectory = `${sourcePath}/${storyKey}`; return { sourceDirectory, buildDirectory, storyKey, introHTML: { source: `${sourceDirectory}/story-intro.html`, dest: `${buildDirectory}/story-intro.html` } } }); } const _copyAllTemplates = (story_keys, _console) => { const storyDirectories = _getStoryDirectories(story_keys,console) const copyPromises = storyDirectories.map(storyDirectory => { const { sourceDirectory, buildDirectory, introHTML } = storyDirectory const copyTemplates = _copyTemplates(sourceDirectory, buildDirectory, introHTML) return copyTemplates }); const returnedPromise = Promise.all(copyPromises) return returnedPromise } /** * Watches and pipes the templates from one folder to another. * * @param {String} sourceDirectory * @param {String} buildDirectory */ const _watchTemplates = (sourceDirectory, buildDirectory) => { const templateInfo = _createTemplateFolderInfo(sourceDirectory, buildDirectory, templateFolders); templateInfo.forEach(templateFolderInfo => { const { sourcePath, templateFolder } = templateFolderInfo; const { extensions = [] } = templateNameMap[templateFolder]; const watchPaths = extensions.map(extension => { return `${sourcePath}/**/ * ${extension} `; }); const watcher = watch(watchPaths); watcher.on('change', (path, stat) => { _changeMessage(path); _copyTemplate(templateFolderInfo); }); }); } const _watchAllTemplates = (story_keys, _console) => { const storyDirectories = _getStoryDirectories(story_keys, _console) storyDirectories.forEach(storyDirectory => { const { sourceDirectory, buildDirectory } = storyDirectory _watchTemplates(sourceDirectory, buildDirectory) }); } module.exports = { build: (story_keys, _console) => { return _copyAllTemplates(story_keys, _console); }, watch: (story_keys, _console) => { return _copyAllTemplates(story_keys, _console) .then(() => { _watchAllTemplates(story_keys, _console); }) .catch(err=>{ console.log(err); }); } }