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