/**
* @module libflitter/controller/ControllerUnit
*/
const CanonicalUnit = require('../canon/CanonicalUnit')
const Controller = require('./Controller')
const SoftError = require('../errors/SoftError')
const error_context = require('../errors/error_context.fn')
/**
* Unit to load and manage controller class definitions.
* @extends module:libflitter/canon/CanonicalUnit~CanonicalUnit
*/
class ControllerUnit extends CanonicalUnit {
/**
* Get the name of the service provided by this unit: 'controllers'
* @returns {string} - 'controllers'
*/
static get name() {
return 'controllers'
}
/**
* Instantiate the unit.
* @param {string} [base_directory = './app/controllers'] - the base search directory
*/
constructor(base_directory = './app/controllers') {
super(base_directory)
/**
* The canonical name of the item.
* @type {string} = 'item'
*/
this.canonical_item = 'controller'
/**
* The file extension of the canonical item files.
* @type {string} - '.js'
*/
this.suffix = '.controller.js'
}
/**
* Prepare a single canonical controller and return the value that should be given by the resolver.
* @param {object} info
* @param {module:libflitter/app/FlitterApp} info.app
* @param {string} info.name - the unqualified canonical name
* @param {*} info.instance - the static CLASS definition of the controller from the file
* @returns {Promise<*>}
*/
async init_canonical_file({app, name, instance}) {
if ( instance.prototype instanceof Controller ) {
return new instance(app)
} else {
throw (new SoftError(`Cannot create controller for ${name}. Controller classes must extend from libflitter/controller/Controller.`)).unit(this.constructor.name)
}
}
/**
* Resolve an unqualified canonical name to a registered canonical controller or method.
* @param {string} name
* @returns {module:libflitter/controller/Controller~Controller|function}
*/
get(name) {
try {
const name_parts = name.split('.')
const controller_instance = this.canonical_items[name_parts[0]]
if (name_parts.length > 1) {
const method_instance = controller_instance[name_parts[1]].bind(controller_instance)
if (name_parts > 2) {
let descending_value = method_instance
name_parts.slice(2).forEach(part => {
descending_value = descending_value[part]
})
return descending_value
} else {
return method_instance
}
} else {
return controller_instance
}
} catch (e) {
throw error_context(e, {
resource_name: name,
})
}
}
/**
* Get the templates provided by the unit.
* "controller" provided by {@link module:libflitter/templates/controller}.
* @returns {{controller: {template: ((function(string): string)|*|controller), extension: string, directory: string}}}
*/
templates(){
return {
controller: {
template: require('../templates/controller'),
directory: this.directory,
extension: '.controller.js'
}
}
}
}
module.exports = exports = ControllerUnit