1/** 2 * @fileoverview Config file operations. This file must be usable in the browser, 3 * so no Node-specific code can be here. 4 * @author Nicholas C. Zakas 5 */ 6"use strict"; 7 8//------------------------------------------------------------------------------ 9// Private 10//------------------------------------------------------------------------------ 11 12const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], 13 RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { 14 map[value] = index; 15 return map; 16 }, {}), 17 VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; 18 19//------------------------------------------------------------------------------ 20// Public Interface 21//------------------------------------------------------------------------------ 22 23module.exports = { 24 25 /** 26 * Normalizes the severity value of a rule's configuration to a number 27 * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally 28 * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), 29 * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array 30 * whose first element is one of the above values. Strings are matched case-insensitively. 31 * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. 32 */ 33 getRuleSeverity(ruleConfig) { 34 const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; 35 36 if (severityValue === 0 || severityValue === 1 || severityValue === 2) { 37 return severityValue; 38 } 39 40 if (typeof severityValue === "string") { 41 return RULE_SEVERITY[severityValue.toLowerCase()] || 0; 42 } 43 44 return 0; 45 }, 46 47 /** 48 * Converts old-style severity settings (0, 1, 2) into new-style 49 * severity settings (off, warn, error) for all rules. Assumption is that severity 50 * values have already been validated as correct. 51 * @param {Object} config The config object to normalize. 52 * @returns {void} 53 */ 54 normalizeToStrings(config) { 55 56 if (config.rules) { 57 Object.keys(config.rules).forEach(ruleId => { 58 const ruleConfig = config.rules[ruleId]; 59 60 if (typeof ruleConfig === "number") { 61 config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; 62 } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { 63 ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; 64 } 65 }); 66 } 67 }, 68 69 /** 70 * Determines if the severity for the given rule configuration represents an error. 71 * @param {int|string|Array} ruleConfig The configuration for an individual rule. 72 * @returns {boolean} True if the rule represents an error, false if not. 73 */ 74 isErrorSeverity(ruleConfig) { 75 return module.exports.getRuleSeverity(ruleConfig) === 2; 76 }, 77 78 /** 79 * Checks whether a given config has valid severity or not. 80 * @param {number|string|Array} ruleConfig The configuration for an individual rule. 81 * @returns {boolean} `true` if the configuration has valid severity. 82 */ 83 isValidSeverity(ruleConfig) { 84 let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; 85 86 if (typeof severity === "string") { 87 severity = severity.toLowerCase(); 88 } 89 return VALID_SEVERITIES.indexOf(severity) !== -1; 90 }, 91 92 /** 93 * Checks whether every rule of a given config has valid severity or not. 94 * @param {Object} config The configuration for rules. 95 * @returns {boolean} `true` if the configuration has valid severity. 96 */ 97 isEverySeverityValid(config) { 98 return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId])); 99 }, 100 101 /** 102 * Normalizes a value for a global in a config 103 * @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in 104 * a global directive comment 105 * @returns {("readable"|"writeable"|"off")} The value normalized as a string 106 * @throws Error if global value is invalid 107 */ 108 normalizeConfigGlobal(configuredValue) { 109 switch (configuredValue) { 110 case "off": 111 return "off"; 112 113 case true: 114 case "true": 115 case "writeable": 116 case "writable": 117 return "writable"; 118 119 case null: 120 case false: 121 case "false": 122 case "readable": 123 case "readonly": 124 return "readonly"; 125 126 default: 127 throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`); 128 } 129 } 130}; 131