yeoman-generator
Version:
Rails-inspired generator system that provides scaffolding for your apps
212 lines (211 loc) • 10.4 kB
JavaScript
/* eslint max-params: [1, 5] */
import assert from 'node:assert';
function applyToFirstStringArg(customizer, args) {
args[0] = Array.isArray(args[0]) ? args[0].map(arg => customizer(arg)) : customizer(args[0]);
return args;
}
function applyToFirstAndSecondStringArg(customizer1, customizer2, args) {
args = applyToFirstStringArg(customizer1, args);
args[1] = customizer2(args[1]);
return args;
}
export class FsMixin {
fs;
/**
* Read file from templates folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.read(this.templatePath(filepath))
*/
readTemplate(...args) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this.fs.read(...applyToFirstStringArg(this.templatePath.bind(this), args));
}
/**
* Copy file from templates folder to destination folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.copy(this.templatePath(from), this.destinationPath(to))
*/
copyTemplate(...args) {
const [from, to, options = {}, ...remaining] = args;
options.fromBasePath = options.fromBasePath ?? this.templatePath();
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
return this.fs.copy(from, this.destinationPath(to), options, ...remaining);
}
/**
* Copy file from templates folder to destination folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.copy(this.templatePath(from), this.destinationPath(to))
*/
async copyTemplateAsync(...args) {
return this.fs.copyAsync(...applyToFirstAndSecondStringArg(this.templatePath.bind(this), this.destinationPath.bind(this), args));
}
/**
* Read file from destination folder
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.read(this.destinationPath(filepath)).
*/
readDestination(...args) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this.fs.read(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Read JSON file from destination folder
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.readJSON(this.destinationPath(filepath)).
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
readDestinationJSON(...args) {
return this.fs.readJSON(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Write file to destination folder
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.write(this.destinationPath(filepath)).
*/
writeDestination(...args) {
return this.fs.write(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Write json file to destination folder
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.writeJSON(this.destinationPath(filepath)).
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
writeDestinationJSON(...args) {
return this.fs.writeJSON(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Delete file from destination folder
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.delete(this.destinationPath(filepath)).
*/
deleteDestination(...args) {
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
return this.fs.delete(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Copy file from destination folder to another destination folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.copy(this.destinationPath(from), this.destinationPath(to)).
*/
copyDestination(...args) {
const [from, to, options = {}, ...remaining] = args;
options.fromBasePath = options.fromBasePath ?? this.destinationPath();
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
return this.fs.copy(from, this.destinationPath(to), options, ...remaining);
}
/**
* Move file from destination folder to another destination folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.move(this.destinationPath(from), this.destinationPath(to)).
*/
moveDestination(...args) {
const [from, to, options = {}, ...remaining] = args;
options.fromBasePath = options.fromBasePath ?? this.destinationPath();
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
return this.fs.move(from, this.destinationPath(to), options, ...remaining);
}
/**
* Exists file on destination folder.
* mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
* Shortcut for this.fs!.exists(this.destinationPath(filepath)).
*/
existsDestination(...args) {
return this.fs.exists(...applyToFirstStringArg(this.destinationPath.bind(this), args));
}
/**
* Copy a template from templates folder to the destination.
*
* @param source - template file, absolute or relative to templatePath().
* @param destination - destination, absolute or relative to destinationPath().
* @param templateData - ejs data
* @param templateOptions - ejs options
* @param copyOptions - mem-fs-editor copy options
*/
renderTemplate(source = '', destination = source, templateData, templateOptions, copyOptions) {
if (templateData === undefined || typeof templateData === 'string') {
templateData = this._templateData(templateData);
}
templateOptions = { context: this, ...templateOptions };
source = Array.isArray(source) ? source : [source];
const templatePath = this.templatePath(...source);
destination = Array.isArray(destination) ? destination : [destination];
const destinationPath = this.destinationPath(...destination);
this.fs.copyTpl(templatePath, destinationPath, templateData, templateOptions, copyOptions);
}
/**
* Copy a template from templates folder to the destination.
*
* @param source - template file, absolute or relative to templatePath().
* @param destination - destination, absolute or relative to destinationPath().
* @param templateData - ejs data
* @param templateOptions - ejs options
* @param copyOptions - mem-fs-editor copy options
*/
async renderTemplateAsync(source = '', destination = source, templateData, templateOptions, copyOptions) {
if (templateData === undefined || typeof templateData === 'string') {
templateData = this._templateData(templateData);
}
templateOptions = { context: this, ...templateOptions };
source = Array.isArray(source) ? source : [source];
const templatePath = this.templatePath(...source);
destination = Array.isArray(destination) ? destination : [destination];
const destinationPath = this.destinationPath(...destination);
return this.fs.copyTplAsync(templatePath, destinationPath, templateData, templateOptions, copyOptions);
}
/**
* Copy templates from templates folder to the destination.
*/
renderTemplates(templates, templateData) {
assert(Array.isArray(templates), 'Templates must an array');
if (templateData === undefined || typeof templateData === 'string') {
templateData = this._templateData(templateData);
}
for (const template of templates) {
const { templateData: eachData = templateData, source, destination } = template;
if (!template.when || template.when(eachData, this)) {
this.renderTemplate(source, destination, eachData, template.templateOptions, template.copyOptions);
}
}
}
/**
* Copy templates from templates folder to the destination.
*
* @param templates - template file, absolute or relative to templatePath().
* @param templateData - ejs data
*/
async renderTemplatesAsync(templates, templateData) {
assert(Array.isArray(templates), 'Templates must an array');
if (templateData === undefined || typeof templateData === 'string') {
templateData = this._templateData(templateData);
}
return Promise.all(templates.map(async (template) => {
const { templateData: eachData = templateData, source, destination } = template;
if (!template.when || template.when(eachData, this)) {
return this.renderTemplateAsync(source, destination, eachData, template.templateOptions, template.copyOptions);
}
return undefined;
}));
}
/**
* Utility method to get a formatted data for templates.
*
* @param path - path to the storage key.
* @return data to be passed to the templates.
*/
_templateData(path) {
if (path) {
return this.config.getPath(path);
}
const allConfig = this.config.getAll();
if (this.generatorConfig) {
Object.assign(allConfig, this.generatorConfig.getAll());
}
if (this.instanceConfig) {
Object.assign(allConfig, this.instanceConfig.getAll());
}
return allConfig;
}
}