build: update npm install command to use --legacy-peer-deps
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.
This commit is contained in:
+130
-196
@@ -8,225 +8,159 @@
|
||||
const astUtils = require("./utils/ast-utils");
|
||||
|
||||
// Operators that always result in a boolean value
|
||||
const BOOLEAN_OPERATORS = new Set([
|
||||
"==",
|
||||
"===",
|
||||
"!=",
|
||||
"!==",
|
||||
">",
|
||||
">=",
|
||||
"<",
|
||||
"<=",
|
||||
"in",
|
||||
"instanceof",
|
||||
]);
|
||||
const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]);
|
||||
const OPERATOR_INVERSES = {
|
||||
"==": "!=",
|
||||
"!=": "==",
|
||||
"===": "!==",
|
||||
"!==": "===",
|
||||
"==": "!=",
|
||||
"!=": "==",
|
||||
"===": "!==",
|
||||
"!==": "==="
|
||||
|
||||
// Operators like < and >= are not true inverses, since both will return false with NaN.
|
||||
// Operators like < and >= are not true inverses, since both will return false with NaN.
|
||||
};
|
||||
const OR_PRECEDENCE = astUtils.getPrecedence({
|
||||
type: "LogicalExpression",
|
||||
operator: "||",
|
||||
});
|
||||
const OR_PRECEDENCE = astUtils.getPrecedence({ type: "LogicalExpression", operator: "||" });
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [{ defaultAssignment: true }],
|
||||
docs: {
|
||||
description: "Disallow ternary operators when simpler alternatives exist",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/no-unneeded-ternary"
|
||||
},
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Disallow ternary operators when simpler alternatives exist",
|
||||
recommended: false,
|
||||
frozen: true,
|
||||
url: "https://eslint.org/docs/latest/rules/no-unneeded-ternary",
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
defaultAssignment: {
|
||||
type: "boolean",
|
||||
default: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}
|
||||
],
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
defaultAssignment: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
fixable: "code",
|
||||
|
||||
fixable: "code",
|
||||
messages: {
|
||||
unnecessaryConditionalExpression: "Unnecessary use of boolean literals in conditional expression.",
|
||||
unnecessaryConditionalAssignment: "Unnecessary use of conditional expression for default assignment."
|
||||
}
|
||||
},
|
||||
|
||||
messages: {
|
||||
unnecessaryConditionalExpression:
|
||||
"Unnecessary use of boolean literals in conditional expression.",
|
||||
unnecessaryConditionalAssignment:
|
||||
"Unnecessary use of conditional expression for default assignment.",
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const options = context.options[0] || {};
|
||||
const defaultAssignment = options.defaultAssignment !== false;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
create(context) {
|
||||
const [{ defaultAssignment }] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
/**
|
||||
* Test if the node is a boolean literal
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @returns {boolean} True if the its a boolean literal
|
||||
* @private
|
||||
*/
|
||||
function isBooleanLiteral(node) {
|
||||
return node.type === "Literal" && typeof node.value === "boolean";
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the node is a boolean literal
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @returns {boolean} True if the its a boolean literal
|
||||
* @private
|
||||
*/
|
||||
function isBooleanLiteral(node) {
|
||||
return node.type === "Literal" && typeof node.value === "boolean";
|
||||
}
|
||||
/**
|
||||
* Creates an expression that represents the boolean inverse of the expression represented by the original node
|
||||
* @param {ASTNode} node A node representing an expression
|
||||
* @returns {string} A string representing an inverted expression
|
||||
*/
|
||||
function invertExpression(node) {
|
||||
if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) {
|
||||
const operatorToken = sourceCode.getFirstTokenBetween(
|
||||
node.left,
|
||||
node.right,
|
||||
token => token.value === node.operator
|
||||
);
|
||||
const text = sourceCode.getText();
|
||||
|
||||
/**
|
||||
* Creates an expression that represents the boolean inverse of the expression represented by the original node
|
||||
* @param {ASTNode} node A node representing an expression
|
||||
* @returns {string} A string representing an inverted expression
|
||||
*/
|
||||
function invertExpression(node) {
|
||||
if (
|
||||
node.type === "BinaryExpression" &&
|
||||
Object.hasOwn(OPERATOR_INVERSES, node.operator)
|
||||
) {
|
||||
const operatorToken = sourceCode.getFirstTokenBetween(
|
||||
node.left,
|
||||
node.right,
|
||||
token => token.value === node.operator,
|
||||
);
|
||||
const text = sourceCode.getText();
|
||||
return text.slice(node.range[0],
|
||||
operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]);
|
||||
}
|
||||
|
||||
return (
|
||||
text.slice(node.range[0], operatorToken.range[0]) +
|
||||
OPERATOR_INVERSES[node.operator] +
|
||||
text.slice(operatorToken.range[1], node.range[1])
|
||||
);
|
||||
}
|
||||
if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) {
|
||||
return `!(${astUtils.getParenthesisedText(sourceCode, node)})`;
|
||||
}
|
||||
return `!${astUtils.getParenthesisedText(sourceCode, node)}`;
|
||||
}
|
||||
|
||||
if (
|
||||
astUtils.getPrecedence(node) <
|
||||
astUtils.getPrecedence({ type: "UnaryExpression" })
|
||||
) {
|
||||
return `!(${astUtils.getParenthesisedText(sourceCode, node)})`;
|
||||
}
|
||||
return `!${astUtils.getParenthesisedText(sourceCode, node)}`;
|
||||
}
|
||||
/**
|
||||
* Tests if a given node always evaluates to a boolean value
|
||||
* @param {ASTNode} node An expression node
|
||||
* @returns {boolean} True if it is determined that the node will always evaluate to a boolean value
|
||||
*/
|
||||
function isBooleanExpression(node) {
|
||||
return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) ||
|
||||
node.type === "UnaryExpression" && node.operator === "!";
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a given node always evaluates to a boolean value
|
||||
* @param {ASTNode} node An expression node
|
||||
* @returns {boolean} True if it is determined that the node will always evaluate to a boolean value
|
||||
*/
|
||||
function isBooleanExpression(node) {
|
||||
return (
|
||||
(node.type === "BinaryExpression" &&
|
||||
BOOLEAN_OPERATORS.has(node.operator)) ||
|
||||
(node.type === "UnaryExpression" && node.operator === "!")
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Test if the node matches the pattern id ? id : expression
|
||||
* @param {ASTNode} node The ConditionalExpression to check.
|
||||
* @returns {boolean} True if the pattern is matched, and false otherwise
|
||||
* @private
|
||||
*/
|
||||
function matchesDefaultAssignment(node) {
|
||||
return node.test.type === "Identifier" &&
|
||||
node.consequent.type === "Identifier" &&
|
||||
node.test.name === node.consequent.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the node matches the pattern id ? id : expression
|
||||
* @param {ASTNode} node The ConditionalExpression to check.
|
||||
* @returns {boolean} True if the pattern is matched, and false otherwise
|
||||
* @private
|
||||
*/
|
||||
function matchesDefaultAssignment(node) {
|
||||
return (
|
||||
node.test.type === "Identifier" &&
|
||||
node.consequent.type === "Identifier" &&
|
||||
node.test.name === node.consequent.name
|
||||
);
|
||||
}
|
||||
return {
|
||||
|
||||
return {
|
||||
ConditionalExpression(node) {
|
||||
if (
|
||||
isBooleanLiteral(node.alternate) &&
|
||||
isBooleanLiteral(node.consequent)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalExpression",
|
||||
fix(fixer) {
|
||||
if (
|
||||
node.consequent.value === node.alternate.value
|
||||
) {
|
||||
// Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true`
|
||||
return node.test.type === "Identifier"
|
||||
? fixer.replaceText(
|
||||
node,
|
||||
node.consequent.value.toString(),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
if (node.alternate.value) {
|
||||
// Replace `foo() ? false : true` with `!(foo())`
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
invertExpression(node.test),
|
||||
);
|
||||
}
|
||||
ConditionalExpression(node) {
|
||||
if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalExpression",
|
||||
fix(fixer) {
|
||||
if (node.consequent.value === node.alternate.value) {
|
||||
|
||||
// Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise.
|
||||
// Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true`
|
||||
return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null;
|
||||
}
|
||||
if (node.alternate.value) {
|
||||
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
isBooleanExpression(node.test)
|
||||
? astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.test,
|
||||
)
|
||||
: `!${invertExpression(node.test)}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
} else if (
|
||||
!defaultAssignment &&
|
||||
matchesDefaultAssignment(node)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalAssignment",
|
||||
fix(fixer) {
|
||||
const shouldParenthesizeAlternate =
|
||||
(astUtils.getPrecedence(node.alternate) <
|
||||
OR_PRECEDENCE ||
|
||||
astUtils.isCoalesceExpression(
|
||||
node.alternate,
|
||||
)) &&
|
||||
!astUtils.isParenthesised(
|
||||
sourceCode,
|
||||
node.alternate,
|
||||
);
|
||||
const alternateText = shouldParenthesizeAlternate
|
||||
? `(${sourceCode.getText(node.alternate)})`
|
||||
: astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.alternate,
|
||||
);
|
||||
const testText = astUtils.getParenthesisedText(
|
||||
sourceCode,
|
||||
node.test,
|
||||
);
|
||||
// Replace `foo() ? false : true` with `!(foo())`
|
||||
return fixer.replaceText(node, invertExpression(node.test));
|
||||
}
|
||||
|
||||
return fixer.replaceText(
|
||||
node,
|
||||
`${testText} || ${alternateText}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
// Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise.
|
||||
|
||||
return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`);
|
||||
}
|
||||
});
|
||||
} else if (!defaultAssignment && matchesDefaultAssignment(node)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: "unnecessaryConditionalAssignment",
|
||||
fix(fixer) {
|
||||
const shouldParenthesizeAlternate =
|
||||
(
|
||||
astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE ||
|
||||
astUtils.isCoalesceExpression(node.alternate)
|
||||
) &&
|
||||
!astUtils.isParenthesised(sourceCode, node.alternate);
|
||||
const alternateText = shouldParenthesizeAlternate
|
||||
? `(${sourceCode.getText(node.alternate)})`
|
||||
: astUtils.getParenthesisedText(sourceCode, node.alternate);
|
||||
const testText = astUtils.getParenthesisedText(sourceCode, node.test);
|
||||
|
||||
return fixer.replaceText(node, `${testText} || ${alternateText}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user