This change modifies the build scripts to use --legacy-peer-deps flag when installing npm dependencies to resolve potential peer dependency conflicts during the build process. The change is applied to both bash (build.sh) and batch (build.bat) build scripts.
159 lines
4.9 KiB
JavaScript
159 lines
4.9 KiB
JavaScript
/**
|
|
* @fileoverview Rule Validator
|
|
* @author Nicholas C. Zakas
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Requirements
|
|
//-----------------------------------------------------------------------------
|
|
|
|
const ajvImport = require("../shared/ajv");
|
|
const ajv = ajvImport();
|
|
const {
|
|
parseRuleId,
|
|
getRuleFromConfig,
|
|
getRuleOptionsSchema
|
|
} = require("./flat-config-helpers");
|
|
const ruleReplacements = require("../../conf/replacements.json");
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Helpers
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Throws a helpful error when a rule cannot be found.
|
|
* @param {Object} ruleId The rule identifier.
|
|
* @param {string} ruleId.pluginName The ID of the rule to find.
|
|
* @param {string} ruleId.ruleName The ID of the rule to find.
|
|
* @param {Object} config The config to search in.
|
|
* @throws {TypeError} For missing plugin or rule.
|
|
* @returns {void}
|
|
*/
|
|
function throwRuleNotFoundError({ pluginName, ruleName }, config) {
|
|
|
|
const ruleId = pluginName === "@" ? ruleName : `${pluginName}/${ruleName}`;
|
|
|
|
const errorMessageHeader = `Key "rules": Key "${ruleId}"`;
|
|
let errorMessage = `${errorMessageHeader}: Could not find plugin "${pluginName}".`;
|
|
|
|
// if the plugin exists then we need to check if the rule exists
|
|
if (config.plugins && config.plugins[pluginName]) {
|
|
const replacementRuleName = ruleReplacements.rules[ruleName];
|
|
|
|
if (pluginName === "@" && replacementRuleName) {
|
|
|
|
errorMessage = `${errorMessageHeader}: Rule "${ruleName}" was removed and replaced by "${replacementRuleName}".`;
|
|
|
|
} else {
|
|
|
|
errorMessage = `${errorMessageHeader}: Could not find "${ruleName}" in plugin "${pluginName}".`;
|
|
|
|
// otherwise, let's see if we can find the rule name elsewhere
|
|
for (const [otherPluginName, otherPlugin] of Object.entries(config.plugins)) {
|
|
if (otherPlugin.rules && otherPlugin.rules[ruleName]) {
|
|
errorMessage += ` Did you mean "${otherPluginName}/${ruleName}"?`;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// falls through to throw error
|
|
}
|
|
|
|
throw new TypeError(errorMessage);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Exports
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Implements validation functionality for the rules portion of a config.
|
|
*/
|
|
class RuleValidator {
|
|
|
|
/**
|
|
* Creates a new instance.
|
|
*/
|
|
constructor() {
|
|
|
|
/**
|
|
* A collection of compiled validators for rules that have already
|
|
* been validated.
|
|
* @type {WeakMap}
|
|
*/
|
|
this.validators = new WeakMap();
|
|
}
|
|
|
|
/**
|
|
* Validates all of the rule configurations in a config against each
|
|
* rule's schema.
|
|
* @param {Object} config The full config to validate. This object must
|
|
* contain both the rules section and the plugins section.
|
|
* @returns {void}
|
|
* @throws {Error} If a rule's configuration does not match its schema.
|
|
*/
|
|
validate(config) {
|
|
|
|
if (!config.rules) {
|
|
return;
|
|
}
|
|
|
|
for (const [ruleId, ruleOptions] of Object.entries(config.rules)) {
|
|
|
|
// check for edge case
|
|
if (ruleId === "__proto__") {
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* If a rule is disabled, we don't do any validation. This allows
|
|
* users to safely set any value to 0 or "off" without worrying
|
|
* that it will cause a validation error.
|
|
*
|
|
* Note: ruleOptions is always an array at this point because
|
|
* this validation occurs after FlatConfigArray has merged and
|
|
* normalized values.
|
|
*/
|
|
if (ruleOptions[0] === 0) {
|
|
continue;
|
|
}
|
|
|
|
const rule = getRuleFromConfig(ruleId, config);
|
|
|
|
if (!rule) {
|
|
throwRuleNotFoundError(parseRuleId(ruleId), config);
|
|
}
|
|
|
|
// Precompile and cache validator the first time
|
|
if (!this.validators.has(rule)) {
|
|
const schema = getRuleOptionsSchema(rule);
|
|
|
|
if (schema) {
|
|
this.validators.set(rule, ajv.compile(schema));
|
|
}
|
|
}
|
|
|
|
const validateRule = this.validators.get(rule);
|
|
|
|
if (validateRule) {
|
|
|
|
validateRule(ruleOptions.slice(1));
|
|
|
|
if (validateRule.errors) {
|
|
throw new Error(`Key "rules": Key "${ruleId}": ${
|
|
validateRule.errors.map(
|
|
error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`
|
|
).join("")
|
|
}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
exports.RuleValidator = RuleValidator;
|