/**
* @module libflitter/database/DatabaseModelsUnit
*/
const CanonicalUnit = require('../canon/CanonicalUnit')
const Model = require('flitter-orm/src/model/Model')
const Setting = require('./model/Setting.model')
const ScaffoldService = require('flitter-orm/src/services/Connection')
const SoftError = require('../errors/SoftError')
/**
* Unit to load and manage database models.
* @extends module:libflitter/canon/CanonicalUnit~CanonicalUnit
*/
class DatabaseModelsUnit extends CanonicalUnit {
/**
* Defines the services required by this unit.
* @returns {Array<string>}
*/
static get services() {
return [...super.services, 'app', 'output', 'database']
}
/**
* Defines the name of the service provided by this unit: 'models'
* @returns {string} - 'models'
*/
static get name() {
return 'models'
}
/**
* Instantiate the unit.
* @param {string} [base_directory = './app/models'] - base directory to search
*/
constructor(base_directory = './app/models') {
super(base_directory)
/**
* The canonical name of the item.
* @type {string} = 'model'
*/
this.canonical_item = 'model'
/**
* The file extension of the canonical item files.
* @type {string} - '.model.js'
*/
this.suffix = '.model.js'
}
/**
* Prepare a single canonical model 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 model CLASS from the file
* @returns {Promise<*>}
*/
async init_canonical_file({app, name, instance}) {
// return this.register_model(name, instance)
if ( instance.prototype instanceof Model ) {
instance.collection = name.replace(/:/g, '_')
return instance
} else {
this.output.warn(`Invalid or malformed model ${name}. Models should extend from flitter-orm/src/model/Model.`)
}
}
/**
* Initializes the unit. Ensures that the Flitter-ORM scaffold service exists.
* @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
* @returns {Promise<void>}
*/
async go(app) {
if ( !app.di().has(ScaffoldService.name) ) {
throw (new SoftError('Models are not supported unless the flitter-orm scaffold system is provided.')).unit(this.constructor.name)
}
await super.go(app)
this.external_model(this, 'setting', Setting)
}
/**
* Register an external model provided by a unit.
* @param {libflitter/Unit~Unit} unit - the parent unit of the model
* @param {string} name - the name of the model
* @param {libflitter/database/Model~Model|object} instance - model class
* @returns {string} - the flitter canonical name of the registered model
*/
external_model(unit, name, instance) {
name = `${unit.name()}::${name}`
this.output.info(`Registering external model: ${name}`)
if ( instance.prototype instanceof Model ) {
instance.collection = name.replace(/:/g, '_')
this.canonical_items[name] = this.app.di().inject(instance)
} else {
this.output.warn(`Invalid or malformed model ${name}. Models should extend from flitter-orm/src/model/Model.`)
}
return name
}
/**
* Helper function to get the Mongoose model instance by its Flitter canonical name.
* This is usually bound to the relevant {@link module:libflitter/app/FlitterApp~FlitterApp} instance.
* @param {string} name - the Flitter canonical name of the model
* @returns {Mongoose/Model}
*/
model(name) {
return this.canonical_items[name]
}
}
module.exports = exports = DatabaseModelsUnit