"use strict";
import errors from "restify-errors";
import inflect from "inflect";
import STATUS_CODES from "./utils/status_codes";
import { setOwner } from "./containment";
/**
* Base controller
*
* @class Controller
* @constructor
*
* @param {Object} registry module registry
* @param {Object} options configuration options
* @param {String} options.model override the default model name
* @todo add default restfull methods (index, show, etc)
*/
class Controller {
get name() {
return inflect.singularize(
this.constructor.name.split(/controller/i)[0].toLowerCase()
);
}
constructor(registry, options = {}) {
setOwner(this, registry);
if (options.parent) {
Object.defineProperty(this, "isChild", {
enumerable: true,
configurable: false,
get() {
return true;
}
});
Object.defineProperty(this, "__parent", {
enumerable: true,
configurable: false,
get() {
return options.parent;
}
});
}
/**
* Restify errors map
* <a href="https://github.com/restify/errors">
* restify-errors
* </a>
*
* @property errors
* @type {Object}
*/
this.errors = errors;
/**
* Object containing all models registered
*
* @property models
* @type {Array}
*/
this.models = registry.lookup("service:model-manager").models;
/**
* The name of the model that belongs to this controller. If one cannot be
* found this will be undefined
*
* @property modelName
* @type {String}
*/
this.modelName = this.getModelName(options.model);
/**
* Pluralized version of modelName
*
* @property modelNameLookup
* @type {String}
*/
this.modelNameLookup = inflect.singularize(this.modelName).toLowerCase();
/**
* An object mapping of status codes and their corresponding value
*
* @property STATUS_CODES
* @type {Object}
*/
this.STATUS_CODES = STATUS_CODES;
/**
* Instance of {{#crossLink "Store"}}Store{{/crossLink}}
*
* @property store
* @type {Object}
*/
registry.inject(this, "service:store", "store");
try {
/**
* The model class that belongs to this controller. If none could be found
* this will be undefined.
*
* @property internalModel
* @type {Object}
*/
registry.inject(this, `model:${this.modelNameLookup}`, "internalModel");
} catch (err) {
registry.lookup("service:logger").debug({
error: err,
controller: this.name
}, "failed to load model");
}
}
/**
* Returns the name of the model that is associated with this controller.
* If options.model is passed to controller it will take precedence, otherwise
* the controller will attempt to lookup a model matching the controller's name
*
* @method getModelName
* @param {String} model name of the model to use
* @returns {String} modelName
*/
getModelName(model) {
const isChild = this.isChild;
let modelName;
if (isChild) {
const parent = this.__parent;
modelName = model || inflect.camelize(parent);
} else {
modelName = model || this.name;
}
return modelName;
}
}
export default Controller;