diff --git a/src/config/normalize/lib/main.js b/src/config/normalize/lib/main.js index 95fb1e72..3b5f9ec6 100644 --- a/src/config/normalize/lib/main.js +++ b/src/config/normalize/lib/main.js @@ -21,7 +21,7 @@ import { logWarnings } from './warn.js' // - Makes it clear to users what the order is // TODO: abstract this function to its own library export const normalizeInputs = async function (inputs, rules, opts) { - const { soft, all } = normalizeOpts(rules, opts) + const { soft, all } = normalizeOpts(opts) const rulesA = normalizeRules(rules, all) try { diff --git a/src/config/normalize/lib/normalize.js b/src/config/normalize/lib/normalize.js index 5639c7c7..a4216bcb 100644 --- a/src/config/normalize/lib/normalize.js +++ b/src/config/normalize/lib/normalize.js @@ -1,4 +1,6 @@ -import filterObj from 'filter-obj' +import { inspect } from 'util' + +import isPlainObj from 'is-plain-obj' import { normalizeQuery } from 'wild-wild-parser' import { wrapError } from '../../../error/wrap.js' @@ -7,30 +9,32 @@ import { wrapError } from '../../../error/wrap.js' // All methods and properties that use queries can use either the string or the // path syntax. export const normalizeRules = function (rules, all) { - const rulesA = mergeRulesAll(rules, all) - return rulesA.map(normalizeRule) + validateRules(rules) + return rules.map((rule) => normalizeRule(rule, all)) } -const mergeRulesAll = function (rules, all) { - if (all === undefined) { - return rules +const validateRules = function (rules) { + if (!Array.isArray(rules)) { + throw new TypeError(`Rules must be an array: ${inspect(rules)}`) } - - const allA = filterObj(all, isDefined) - return rules.map((rule) => ({ ...allA, ...rule })) } -const isDefined = function (key, value) { - return value !== undefined -} +const normalizeRule = function (rule, all) { + if (!isPlainObj(rule)) { + throw new TypeError(`Rule must be a plain object: ${inspect(rule)}`) + } -const normalizeRule = function (rule) { - return { ...rule, name: normalizeName(rule.name) } + const ruleA = all === undefined ? rule : { ...all, ...rule } + return { ...ruleA, name: normalizeName(ruleA) } } -const normalizeName = function (name) { +const normalizeName = function (rule) { + if (rule.name === undefined) { + throw new Error(`Rule must have a "name" property: ${inspect(rule)}`) + } + try { - return normalizeQuery(name) + return normalizeQuery(rule.name) } catch (error) { throw wrapError(error, 'Invalid "name":') } diff --git a/src/config/normalize/lib/options.js b/src/config/normalize/lib/options.js index 54859383..91c18dc8 100644 --- a/src/config/normalize/lib/options.js +++ b/src/config/normalize/lib/options.js @@ -1,20 +1,38 @@ +import { inspect } from 'util' + +import filterObj from 'filter-obj' import isPlainObj from 'is-plain-obj' -export const normalizeOpts = function (rules, { soft = false, all } = {}) { - validateRules(rules) - return { soft, all } +// Normalize `options` +export const normalizeOpts = function (options = {}) { + if (!isPlainObj(options)) { + throw new TypeError(`Options must be a plain object: ${inspect(options)}`) + } + + const { soft = false, all } = options + validateSoft(soft) + const allA = normalizeAll(all) + return { soft, all: allA } } -const validateRules = function (rules) { - if (!Array.isArray(rules)) { - throw new TypeError(`Rules must be an array: ${rules}`) +const validateSoft = function (soft) { + if (typeof soft !== 'boolean') { + throw new TypeError(`Option "soft" must be a boolean: ${inspect(soft)}`) } - - rules.forEach(validateRule) } -const validateRule = function (rule) { - if (!isPlainObj(rule)) { - throw new TypeError(`Rules must be plain objects: ${rule}`) +const normalizeAll = function (all) { + if (all === undefined) { + return } + + if (!isPlainObj(all)) { + throw new TypeError(`Option "all" must be a plain object: ${inspect(all)}`) + } + + return filterObj(all, isDefined) +} + +const isDefined = function (key, value) { + return value !== undefined }