UNPKG

blueconfig

Version:

Merge and validate your config depending of your schema, forked from node-convict.

101 lines (85 loc) 3.12 kB
const cvtError = require('./../error.js') const CUSTOMISE_FAILED = cvtError.CUSTOMISE_FAILED const INCORRECT_USAGE = cvtError.INCORRECT_USAGE /** * Getter will parse specified keyname and use the only argument to get the wanted * * @private * @class */ function Getter() { this.storage = { order: ['value', 'force'], list: {} } } module.exports = Getter /** * Adds a new custom getter */ Getter.prototype.add = function(keyname, getter, usedOnlyOnce, rewrite) { if (typeof keyname !== 'string') { throw new CUSTOMISE_FAILED('Getter keyname must be a string (current: "' + (typeof keyname) + '").') } if (typeof getter !== 'function') { throw new CUSTOMISE_FAILED('Getter function for "' + keyname + '" must be a function.') } if (['_cvtCoerce', '_cvtValidateFormat', '_cvtGetOrigin', 'format', 'required', 'value', 'force'].includes(keyname)) { throw new CUSTOMISE_FAILED('Getter keyname use a reservated word: ' + keyname) } if (this.storage.list[keyname] && !rewrite) { const advice = ' Set the 4th argument (rewrite) of `addGetter` at true to skip this error.' throw new CUSTOMISE_FAILED('Getter keyname "' + keyname + '" is already registered.' + advice) } if (typeof usedOnlyOnce !== 'function') { usedOnlyOnce = !!usedOnlyOnce } if (!this.storage.list[keyname]) { // add before the last key (= force), force must always be the last key this.storage.order.splice(this.storage.order.length - 1, 0, keyname) } this.storage.list[keyname] = { usedOnlyOnce: usedOnlyOnce, getter: getter } } /** * @returns Returns sorted function which sorts array to newOrder */ Getter.prototype.cloneStorage = function() { const storage = this.storage return { order: [...storage.order], list: { ...storage.list } } } /** * @returns Returns sorted function which sorts array to newOrder */ Getter.prototype.sortGetters = function(currentOrder, newOrder) { if (!Array.isArray(newOrder)) { throw new INCORRECT_USAGE('Invalid argument: newOrder must be an array.') } // 'force' must be at the end or not given const forceOrder = newOrder.indexOf('force') if (forceOrder !== -1 && forceOrder !== newOrder.length - 1) { throw new INCORRECT_USAGE('Invalid order: force cannot be sorted.') } else if (forceOrder !== newOrder.length - 1) { newOrder.push('force') } // exact number of getter name (not less & not more) const checkKey = [...currentOrder] for (let i = newOrder.length - 1; i >= 0; i--) { const index = checkKey.indexOf(newOrder[i]) if (index !== -1) { checkKey.splice(index, 1) } else { throw new INCORRECT_USAGE('Invalid order: unknown getter: ' + newOrder[i]) } } if (checkKey.length !== 0) { const message = (checkKey.length <= 1) ? 'a getter is ' : 'several getters are ' throw new INCORRECT_USAGE('Invalid order: ' + message + 'missed: ' + checkKey.join(', ')) } return (a, b) => newOrder.indexOf(a) - newOrder.indexOf(b) }