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:
Luiz Costa
2025-11-18 10:23:55 -03:00
parent 20129a1ac7
commit ac4f232e5e
787 changed files with 82341 additions and 121690 deletions
+273 -339
View File
@@ -17,28 +17,25 @@ const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
const QUOTE_SETTINGS = {
double: {
quote: '"',
alternateQuote: "'",
description: "doublequote",
},
single: {
quote: "'",
alternateQuote: '"',
description: "singlequote",
},
backtick: {
quote: "`",
alternateQuote: '"',
description: "backtick",
},
double: {
quote: "\"",
alternateQuote: "'",
description: "doublequote"
},
single: {
quote: "'",
alternateQuote: "\"",
description: "singlequote"
},
backtick: {
quote: "`",
alternateQuote: "\"",
description: "backtick"
}
};
// An unescaped newline is a newline preceded by an even number of backslashes.
const UNESCAPED_LINEBREAK_PATTERN = new RegExp(
String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`,
"u",
);
const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u");
/**
* Switches quoting of javascript string between ' " and `
@@ -50,43 +47,27 @@ const UNESCAPED_LINEBREAK_PATTERN = new RegExp(
* @private
*/
QUOTE_SETTINGS.double.convert =
QUOTE_SETTINGS.single.convert =
QUOTE_SETTINGS.backtick.convert =
function (str) {
const newQuote = this.quote;
const oldQuote = str[0];
QUOTE_SETTINGS.single.convert =
QUOTE_SETTINGS.backtick.convert = function(str) {
const newQuote = this.quote;
const oldQuote = str[0];
if (newQuote === oldQuote) {
return str;
}
return (
newQuote +
str
.slice(1, -1)
.replace(
/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu,
(match, escaped, newline) => {
if (
escaped === oldQuote ||
(oldQuote === "`" && escaped === "${")
) {
return escaped; // unescape
}
if (
match === newQuote ||
(newQuote === "`" && match === "${")
) {
return `\\${match}`; // escape
}
if (newline && oldQuote === "`") {
return "\\n"; // escape newlines
}
return match;
},
) +
newQuote
);
};
if (newQuote === oldQuote) {
return str;
}
return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => {
if (escaped === oldQuote || oldQuote === "`" && escaped === "${") {
return escaped; // unescape
}
if (match === newQuote || newQuote === "`" && match === "${") {
return `\\${match}`; // escape
}
if (newline && oldQuote === "`") {
return "\\n"; // escape newlines
}
return match;
}) + newQuote;
};
const AVOID_ESCAPE = "avoid-escape";
@@ -94,323 +75,276 @@ const AVOID_ESCAPE = "avoid-escape";
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
/** @type {import('../shared/types').Rule} */
module.exports = {
meta: {
deprecated: {
message: "Formatting rules are being moved out of ESLint core.",
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
deprecatedSince: "8.53.0",
availableUntil: "11.0.0",
replacedBy: [
{
message:
"ESLint Stylistic now maintains deprecated stylistic core rules.",
url: "https://eslint.style/guide/migration",
plugin: {
name: "@stylistic/eslint-plugin",
url: "https://eslint.style",
},
rule: {
name: "quotes",
url: "https://eslint.style/rules/quotes",
},
},
],
},
type: "layout",
meta: {
deprecated: true,
replacedBy: [],
type: "layout",
docs: {
description:
"Enforce the consistent use of either backticks, double, or single quotes",
recommended: false,
url: "https://eslint.org/docs/latest/rules/quotes",
},
docs: {
description: "Enforce the consistent use of either backticks, double, or single quotes",
recommended: false,
url: "https://eslint.org/docs/latest/rules/quotes"
},
fixable: "code",
fixable: "code",
schema: [
{
enum: ["single", "double", "backtick"],
},
{
anyOf: [
{
enum: ["avoid-escape"],
},
{
type: "object",
properties: {
avoidEscape: {
type: "boolean",
},
allowTemplateLiterals: {
type: "boolean",
},
},
additionalProperties: false,
},
],
},
],
schema: [
{
enum: ["single", "double", "backtick"]
},
{
anyOf: [
{
enum: ["avoid-escape"]
},
{
type: "object",
properties: {
avoidEscape: {
type: "boolean"
},
allowTemplateLiterals: {
type: "boolean"
}
},
additionalProperties: false
}
]
}
],
messages: {
wrongQuotes: "Strings must use {{description}}.",
},
},
messages: {
wrongQuotes: "Strings must use {{description}}."
}
},
create(context) {
const quoteOption = context.options[0],
settings = QUOTE_SETTINGS[quoteOption || "double"],
options = context.options[1],
allowTemplateLiterals =
options && options.allowTemplateLiterals === true,
sourceCode = context.sourceCode;
let avoidEscape = options && options.avoidEscape === true;
create(context) {
// deprecated
if (options === AVOID_ESCAPE) {
avoidEscape = true;
}
const quoteOption = context.options[0],
settings = QUOTE_SETTINGS[quoteOption || "double"],
options = context.options[1],
allowTemplateLiterals = options && options.allowTemplateLiterals === true,
sourceCode = context.sourceCode;
let avoidEscape = options && options.avoidEscape === true;
/**
* Determines if a given node is part of JSX syntax.
*
* This function returns `true` in the following cases:
*
* - `<div className="foo"></div>` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`.
* - `<div>foo</div>` ... If the literal is a text content, the parent of the literal is `JSXElement`.
* - `<>foo</>` ... If the literal is a text content, the parent of the literal is `JSXFragment`.
*
* In particular, this function returns `false` in the following cases:
*
* - `<div className={"foo"}></div>`
* - `<div>{"foo"}</div>`
*
* In both cases, inside of the braces is handled as normal JavaScript.
* The braces are `JSXExpressionContainer` nodes.
* @param {ASTNode} node The Literal node to check.
* @returns {boolean} True if the node is a part of JSX, false if not.
* @private
*/
function isJSXLiteral(node) {
return (
node.parent.type === "JSXAttribute" ||
node.parent.type === "JSXElement" ||
node.parent.type === "JSXFragment"
);
}
// deprecated
if (options === AVOID_ESCAPE) {
avoidEscape = true;
}
/**
* Checks whether or not a given node is a directive.
* The directive is a `ExpressionStatement` which has only a string literal not surrounded by
* parentheses.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is a directive.
* @private
*/
function isDirective(node) {
return (
node.type === "ExpressionStatement" &&
node.expression.type === "Literal" &&
typeof node.expression.value === "string" &&
!astUtils.isParenthesised(sourceCode, node.expression)
);
}
/**
* Determines if a given node is part of JSX syntax.
*
* This function returns `true` in the following cases:
*
* - `<div className="foo"></div>` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`.
* - `<div>foo</div>` ... If the literal is a text content, the parent of the literal is `JSXElement`.
* - `<>foo</>` ... If the literal is a text content, the parent of the literal is `JSXFragment`.
*
* In particular, this function returns `false` in the following cases:
*
* - `<div className={"foo"}></div>`
* - `<div>{"foo"}</div>`
*
* In both cases, inside of the braces is handled as normal JavaScript.
* The braces are `JSXExpressionContainer` nodes.
* @param {ASTNode} node The Literal node to check.
* @returns {boolean} True if the node is a part of JSX, false if not.
* @private
*/
function isJSXLiteral(node) {
return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment";
}
/**
* Checks whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
* @see {@link http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive}
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
* @private
*/
function isExpressionInOrJustAfterDirectivePrologue(node) {
if (!astUtils.isTopLevelExpressionStatement(node.parent)) {
return false;
}
const block = node.parent.parent;
/**
* Checks whether or not a given node is a directive.
* The directive is a `ExpressionStatement` which has only a string literal not surrounded by
* parentheses.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is a directive.
* @private
*/
function isDirective(node) {
return (
node.type === "ExpressionStatement" &&
node.expression.type === "Literal" &&
typeof node.expression.value === "string" &&
!astUtils.isParenthesised(sourceCode, node.expression)
);
}
// Check the node is at a prologue.
for (let i = 0; i < block.body.length; ++i) {
const statement = block.body[i];
/**
* Checks whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
* @see {@link http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive}
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether a specified node is either part of, or immediately follows a (possibly empty) directive prologue.
* @private
*/
function isExpressionInOrJustAfterDirectivePrologue(node) {
if (!astUtils.isTopLevelExpressionStatement(node.parent)) {
return false;
}
const block = node.parent.parent;
if (statement === node.parent) {
return true;
}
if (!isDirective(statement)) {
break;
}
}
// Check the node is at a prologue.
for (let i = 0; i < block.body.length; ++i) {
const statement = block.body[i];
return false;
}
if (statement === node.parent) {
return true;
}
if (!isDirective(statement)) {
break;
}
}
/**
* Checks whether or not a given node is allowed as non backtick.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is allowed as non backtick.
* @private
*/
function isAllowedAsNonBacktick(node) {
const parent = node.parent;
return false;
}
switch (parent.type) {
// Directive Prologues.
case "ExpressionStatement":
return (
!astUtils.isParenthesised(sourceCode, node) &&
isExpressionInOrJustAfterDirectivePrologue(node)
);
/**
* Checks whether or not a given node is allowed as non backtick.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is allowed as non backtick.
* @private
*/
function isAllowedAsNonBacktick(node) {
const parent = node.parent;
// LiteralPropertyName.
case "Property":
case "PropertyDefinition":
case "MethodDefinition":
return parent.key === node && !parent.computed;
switch (parent.type) {
// ModuleSpecifier.
case "ImportDeclaration":
case "ExportNamedDeclaration":
return parent.source === node;
// Directive Prologues.
case "ExpressionStatement":
return !astUtils.isParenthesised(sourceCode, node) && isExpressionInOrJustAfterDirectivePrologue(node);
// ModuleExportName or ModuleSpecifier.
case "ExportAllDeclaration":
return parent.exported === node || parent.source === node;
// LiteralPropertyName.
case "Property":
case "PropertyDefinition":
case "MethodDefinition":
return parent.key === node && !parent.computed;
// ModuleExportName.
case "ImportSpecifier":
return parent.imported === node;
// ModuleSpecifier.
case "ImportDeclaration":
case "ExportNamedDeclaration":
return parent.source === node;
// ModuleExportName.
case "ExportSpecifier":
return parent.local === node || parent.exported === node;
// ModuleExportName or ModuleSpecifier.
case "ExportAllDeclaration":
return parent.exported === node || parent.source === node;
// Others don't allow.
default:
return false;
}
}
// ModuleExportName.
case "ImportSpecifier":
return parent.imported === node;
/**
* Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings.
* @param {ASTNode} node A TemplateLiteral node to check.
* @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings.
* @private
*/
function isUsingFeatureOfTemplateLiteral(node) {
const hasTag =
node.parent.type === "TaggedTemplateExpression" &&
node === node.parent.quasi;
// ModuleExportName.
case "ExportSpecifier":
return parent.local === node || parent.exported === node;
if (hasTag) {
return true;
}
// Others don't allow.
default:
return false;
}
}
const hasStringInterpolation = node.expressions.length > 0;
/**
* Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings.
* @param {ASTNode} node A TemplateLiteral node to check.
* @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings.
* @private
*/
function isUsingFeatureOfTemplateLiteral(node) {
const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi;
if (hasStringInterpolation) {
return true;
}
if (hasTag) {
return true;
}
const isMultilineString =
node.quasis.length >= 1 &&
UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw);
const hasStringInterpolation = node.expressions.length > 0;
if (isMultilineString) {
return true;
}
if (hasStringInterpolation) {
return true;
}
return false;
}
const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw);
return {
Literal(node) {
const val = node.value,
rawVal = node.raw;
if (isMultilineString) {
return true;
}
if (settings && typeof val === "string") {
let isValid =
(quoteOption === "backtick" &&
isAllowedAsNonBacktick(node)) ||
isJSXLiteral(node) ||
astUtils.isSurroundedBy(rawVal, settings.quote);
return false;
}
if (!isValid && avoidEscape) {
isValid =
astUtils.isSurroundedBy(
rawVal,
settings.alternateQuote,
) && rawVal.includes(settings.quote);
}
return {
if (!isValid) {
context.report({
node,
messageId: "wrongQuotes",
data: {
description: settings.description,
},
fix(fixer) {
if (
quoteOption === "backtick" &&
astUtils.hasOctalOrNonOctalDecimalEscapeSequence(
rawVal,
)
) {
/*
* An octal or non-octal decimal escape sequence in a template literal would
* produce syntax error, even in non-strict mode.
*/
return null;
}
Literal(node) {
const val = node.value,
rawVal = node.raw;
return fixer.replaceText(
node,
settings.convert(node.raw),
);
},
});
}
}
},
if (settings && typeof val === "string") {
let isValid = (quoteOption === "backtick" && isAllowedAsNonBacktick(node)) ||
isJSXLiteral(node) ||
astUtils.isSurroundedBy(rawVal, settings.quote);
TemplateLiteral(node) {
// Don't throw an error if backticks are expected or a template literal feature is in use.
if (
allowTemplateLiterals ||
quoteOption === "backtick" ||
isUsingFeatureOfTemplateLiteral(node)
) {
return;
}
if (!isValid && avoidEscape) {
isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.includes(settings.quote);
}
context.report({
node,
messageId: "wrongQuotes",
data: {
description: settings.description,
},
fix(fixer) {
if (
astUtils.isTopLevelExpressionStatement(
node.parent,
) &&
!astUtils.isParenthesised(sourceCode, node)
) {
/*
* TemplateLiterals aren't actually directives, but fixing them might turn
* them into directives and change the behavior of the code.
*/
return null;
}
return fixer.replaceText(
node,
settings.convert(sourceCode.getText(node)),
);
},
});
},
};
},
if (!isValid) {
context.report({
node,
messageId: "wrongQuotes",
data: {
description: settings.description
},
fix(fixer) {
if (quoteOption === "backtick" && astUtils.hasOctalOrNonOctalDecimalEscapeSequence(rawVal)) {
/*
* An octal or non-octal decimal escape sequence in a template literal would
* produce syntax error, even in non-strict mode.
*/
return null;
}
return fixer.replaceText(node, settings.convert(node.raw));
}
});
}
}
},
TemplateLiteral(node) {
// Don't throw an error if backticks are expected or a template literal feature is in use.
if (
allowTemplateLiterals ||
quoteOption === "backtick" ||
isUsingFeatureOfTemplateLiteral(node)
) {
return;
}
context.report({
node,
messageId: "wrongQuotes",
data: {
description: settings.description
},
fix(fixer) {
if (astUtils.isTopLevelExpressionStatement(node.parent) && !astUtils.isParenthesised(sourceCode, node)) {
/*
* TemplateLiterals aren't actually directives, but fixing them might turn
* them into directives and change the behavior of the code.
*/
return null;
}
return fixer.replaceText(node, settings.convert(sourceCode.getText(node)));
}
});
}
};
}
};