plugins/defaults.js

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
const Plugin = require('./base');
const { Scopes } = require('../lib/constants');

const isObject = (v) => v !== null && typeof v === 'object';

const setDefaults = (options = {}, defaults) => Object.keys(options)
    .reduce((acc, key) => {
        if (isObject(acc[key]) && isObject(options[key])) {
            return Object.assign(acc, {
                [key]: setDefaults(options[key], acc[key])
            });
        }
        return Object.assign(acc, { [key]: options[key] });
    }, { ...defaults });

const wrap = function(ch, name, pos, defaults) {
    const original = ch[name];
    ch[name] = function(...args) {
        args[pos] = setDefaults(args[pos], defaults);
        return original.apply(ch, args);
    };
};

module.exports = class DefaultOptions extends Plugin {

    constructor({
        exchange = {},
        queue = {},
        consume = {},
        publish = {},
        prefetch = 0
    } = {}) {
        super('defaults');
        this.options = { exchange, queue, consume, publish, prefetch };
    }

    init() {
        const { exchange, queue, consume, publish, prefetch } = this.options;
        this.scopes[Scopes.CHANNEL] = (create) => () =>
            create()
                .then((ch) => {
                    wrap(ch, 'assertQueue', 1, queue);
                    wrap(ch, 'assertExchange', 2, exchange);
                    wrap(ch, 'consume', 2, consume);
                    wrap(ch, 'publish', 3, publish);
                    return ch;
                });

        this.scopes[Scopes.API] = (base) => class extends base {
            consume(queue, fn, options) {
                if (this._context.prefetch === 0 && prefetch > 0) {
                    return super.context({ prefetch }).consume(queue, fn, options);
                } else {
                    return super.consume(queue, fn, options);
                }
            }
        };
    }

};