libflitter/canon/CanonicalAccessUnit.js

/**
 * @module libflitter/canon/CanonicalAccessUnit
 */

const Unit = require('../Unit')
const error_context = require('../errors/error_context.fn')

/**
 * Unit service providing access to all canonical accessors by name.
 * @extends module:libflitter/Unit~Unit
 */
class CanonicalAccessUnit extends Unit {
    /**
     * Get the name of the service provided by this unit: 'canon'
     * @returns {string} - 'canon'
     */
    static get name() {
        return 'canon'
    }

    /**
     * Instantiate the unit.
     */
    constructor() {
        super()
        /**
         * Mapping of canonical item type to resolver function.
         * @type {object}
         */
        this.resources = {}
    }

    /**
     * Get a canonical resource by its fully-qualified name.
     * e.g. 'controller::Home.welcome'
     * e.g. 'middleware::Logger'
     * e.g. 'model::auth:User'
     *
     * @param {string} resource - the fully-qualified canonical resource name
     * @returns {*} - the corresponding resource
     */
    get(resource) {
        try {
            const parts = resource.split('::')
            let descending_item = this.resources
            for (let i in parts) {
                if (typeof descending_item === 'function') {
                    descending_item = descending_item(parts[i])
                } else {
                    descending_item = descending_item[parts[i]]
                }
            }
            return descending_item
        } catch (e) {
            throw error_context(e, {
                resource_name: resource,
            })
        }
    }

    /**
     * Register a canonical resolver under the specified scope.
     * @param {string} scope - e.g. 'middleware'/'controller'/&c.
     * @param {function} retriever - resolver that takes the unqualified canonical name and returns the resource
     */
    register_resource(scope, retriever) {
        this.app.output.debug('Registering canonical resource for scope: '+scope)
        this.resources[scope] = retriever
    }
}

module.exports = exports = CanonicalAccessUnit