UNPKG

@ngx-rocket/core

Version:

Core generator for creating ngX-Rocket add-ons

181 lines (152 loc) 5.6 kB
'use strict'; const path = require('path'); const dir = require('node-dir'); const _ = require('lodash'); const ejs = require('ejs'); const chalk = require('chalk'); const ignore = require('ignore'); const FileExclusions = ['.DS_Store', 'Thumbs.db']; const FileActionRegExp = /^[_+a-zA-Z-]*\(([a-zA-Z]+)\)\./; const FileCleanupRexExp = /^(__.*?|\([a-zA-Z]+\))\./; const FileUtilities = { ClientTemplatesPath: 'client', ServerTemplatesPath: 'server', RootTemplatesPath: 'root', mergeJson(context, file) { const content = context.fs.readJSON(context.destinationPath(file.dest), {}); let newContent = context.fs.read(context.templatePath(file.src)); newContent = file.isTemplate ? ejs.render(newContent, context, {filename: file.src}) : newContent; newContent = JSON.parse(newContent); _.mergeWith(content, newContent, (a, b) => (_.isArray(a) ? _.uniq(a.concat(b)) : undefined)); context.fs.writeJSON(context.destinationPath(file.dest), content); }, async getFiles(templatePath, generatorType) { let promises; switch (generatorType) { case 'fullstack': promises = [ dir.promiseFiles(path.join(templatePath, FileUtilities.ClientTemplatesPath)), dir.promiseFiles(path.join(templatePath, FileUtilities.ServerTemplatesPath)), dir.promiseFiles(path.join(templatePath, FileUtilities.RootTemplatesPath)) ]; break; case 'server': promises = [[], dir.promiseFiles(templatePath), []]; break; default: promises = [dir.promiseFiles(templatePath), [], []]; } const files = await Promise.all(promises); return { client: files[0], server: files[1], root: files[2] }; }, prepareFiles(files, templatePath, destinationPath, basePath) { basePath = basePath || ''; // Removes excluded files _.remove(files, (file) => !FileExclusions.every((excludeFile) => !_.includes(file, excludeFile))); return _.map(files, (file) => { let src = path.relative(path.join(templatePath, basePath), file); const basename = path.basename(src); const dirname = path.dirname(src); const rootdir = dirname.split(path.sep)[0]; const fileConditions = this._getConditions(basename, '__'); const folderConditions = this._getConditions(rootdir, '__'); const action = this._getAction(basename); let isTemplate = basename.startsWith('_'); let dest = path.relative(folderConditions.length === 0 ? '.' : rootdir, src); let base = ''; if (fileConditions.length > 0 || action) { const fileName = path.basename(src).replace(FileCleanupRexExp, ''); isTemplate = fileName.startsWith('_') && action !== 'raw'; dest = path.join(path.dirname(dest), fileName); } if (isTemplate) { dest = path.join(path.dirname(dest), path.basename(dest).slice(1)); } if (destinationPath) { dest = path.join(destinationPath, dest); base = destinationPath; } src = path.join(basePath, src); return { src, dest, base, isTemplate, fileConditions, folderConditions, action }; }); }, writeFile(context, file, prefixRules) { const write = (file.folderConditions.length === 0 || this._checkConditions(file.folderConditions, context, prefixRules)) && (file.fileConditions.length === 0 || this._checkConditions(file.fileConditions, context, prefixRules)); if (write) { try { if (file.action) { switch (file.action) { case 'merge': FileUtilities.mergeJson(context, file); break; case 'raw': this._copyRaw(context, file.src, file.dest); break; default: throw new Error(`Invalid action: ${file.action}`); } } else if (file.isTemplate) { context.fs.copyTpl(context.templatePath(file.src), context.destinationPath(file.dest), context); } else { context.fs.copy(context.templatePath(file.src), context.destinationPath(file.dest), { globOptions: { extglob: false } }); } } catch (error) { context.log(chalk.red(`\nTemplate processing error on file ${file.src}`)); throw error; } } }, filterFiles(files, patterns) { const filter = ignore().add(patterns); return files.filter((file) => !filter.ignores(path.relative(file.base || '', file.dest))); }, _getConditions(name, prefix) { if (name.startsWith(prefix)) { let endIndex = name.indexOf('.'); if (endIndex === -1) { endIndex = name.length; } const actionIndex = name.indexOf('('); if (actionIndex !== -1 && actionIndex < endIndex) { endIndex = actionIndex; } return name.slice(prefix.length, endIndex).split('+'); } return []; }, _checkConditions(conditions, context, rules) { return conditions.every((condition) => { if (!rules[condition]) { throw new Error(`Invalid condition: ${condition}`); } return rules[condition](context.props); }); }, _getAction(name) { const actionMatch = FileActionRegExp.exec(name); return actionMatch ? actionMatch[1] : null; }, _copyRaw(context, src, dest) { const rawContent = context.fs.read(context.templatePath(src), {raw: true}); context.fs.write(context.destinationPath(dest), rawContent); } }; module.exports = FileUtilities;