/**
* @module flitter-cli/directives/TemplateDirective
*/
const Directive = require('../Directive')
const fs = require('fs').promises
const path = require('path')
const PositionalOption = require('../options/PositionalOption')
/**
* Directive to create new files from registered templates by name.
*
* @extends module:flitter-cli/Directive~Directive
*/
class TemplateDirective extends Directive {
/**
* Get the name of the directive. Used by ./flitter.
* @static
* @returns {string} "new"
*/
static name(){
return "new"
}
/**
* Get the usage information for the directive. Used by ./flitter help.
* @returns {string}
*/
static help(){
return "create a new file from a registered template: <template name> <file name>"
}
/**
* Get the CLI flag options provided by this directive.
* @returns {Array<module:flitter-cli/options/Option~Option>}
*/
static options() {
const templates = this.prototype.cli.loaded_templates
const template_option = new PositionalOption('resource name', 'type of resource to be created')
template_option.whitelist(...Object.keys(templates))
return [
template_option,
'{file name} | canonical name of the resource to create',
]
}
/**
* Handles an invocation of the directive. Creates a new template with the specified class name.
* This directive is sub-directory aware and accepts Flitter canonical names.
* @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
* @param {Array} argv - the CLI arguments passed after the directive
* @returns {Promise<void>}
*/
async handle(app, argv){
const templates = this.cli.loaded_templates
let found = false
let names = "\t"
for ( let template_name in templates ){
names += template_name+", "
if ( template_name === this.option('resource name') ){
const template = templates[template_name]
if ( !this.option('file name') ){
found = true
this.error(`Please provide a canonical name for the new ${template_name}.`)
break
}
const file_name = this.option('file name').replace(/:/g, '/')+template.extension
let subdir = ""
if ( file_name.lastIndexOf("/") > -1 ){
subdir = file_name.substr(0, file_name.lastIndexOf("/"))
}
// mkdir -p the template destination
await fs.mkdir(path.resolve(template.directory, subdir), { recursive: true })
// get the full path to the file
const file_path = path.resolve(template.directory, file_name)
const class_name = this.option('file name').split(":").slice(-1)[0]
// build some context to pass along
const ctx = {
app,
services: app.di().service(),
}
await fs.writeFile(file_path, template.template(class_name, this.option('file name'), ctx))
this.success(`Created new ${template_name} as ${this.option('file name')}.`)
found = true
break
}
}
if ( !found ){
this.error('Please enter a valid template name.')
this.info('The following templates are registered with Flitter:')
this.info(`\t${names.slice(0, -2)}`)
}
}
}
module.exports = exports = TemplateDirective