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:
+231
-305
@@ -40,23 +40,20 @@ const astUtils = require("./utils/ast-utils");
|
||||
* @returns {boolean} `true` if the lists have same tokens.
|
||||
*/
|
||||
function areEqualTokenLists(left, right) {
|
||||
if (left.length !== right.length) {
|
||||
return false;
|
||||
}
|
||||
if (left.length !== right.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < left.length; i++) {
|
||||
const leftToken = left[i],
|
||||
rightToken = right[i];
|
||||
for (let i = 0; i < left.length; i++) {
|
||||
const leftToken = left[i],
|
||||
rightToken = right[i];
|
||||
|
||||
if (
|
||||
leftToken.type !== rightToken.type ||
|
||||
leftToken.value !== rightToken.value
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,16 +63,18 @@ function areEqualTokenLists(left, right) {
|
||||
* @returns {boolean} `true` if the keys are equal.
|
||||
*/
|
||||
function areEqualKeys(left, right) {
|
||||
if (typeof left === "string" && typeof right === "string") {
|
||||
// Statically computed names.
|
||||
return left === right;
|
||||
}
|
||||
if (Array.isArray(left) && Array.isArray(right)) {
|
||||
// Token lists.
|
||||
return areEqualTokenLists(left, right);
|
||||
}
|
||||
if (typeof left === "string" && typeof right === "string") {
|
||||
|
||||
return false;
|
||||
// Statically computed names.
|
||||
return left === right;
|
||||
}
|
||||
if (Array.isArray(left) && Array.isArray(right)) {
|
||||
|
||||
// Token lists.
|
||||
return areEqualTokenLists(left, right);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +83,7 @@ function areEqualKeys(left, right) {
|
||||
* @returns {boolean} `true` if the node is of an accessor kind.
|
||||
*/
|
||||
function isAccessorKind(node) {
|
||||
return node.kind === "get" || node.kind === "set";
|
||||
return node.kind === "get" || node.kind === "set";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,13 +95,13 @@ function isAccessorKind(node) {
|
||||
* @returns {boolean} `true` if the node is an argument of the specified method call.
|
||||
*/
|
||||
function isArgumentOfMethodCall(node, index, object, property) {
|
||||
const parent = node.parent;
|
||||
const parent = node.parent;
|
||||
|
||||
return (
|
||||
parent.type === "CallExpression" &&
|
||||
astUtils.isSpecificMemberAccess(parent.callee, object, property) &&
|
||||
parent.arguments[index] === node
|
||||
);
|
||||
return (
|
||||
parent.type === "CallExpression" &&
|
||||
astUtils.isSpecificMemberAccess(parent.callee, object, property) &&
|
||||
parent.arguments[index] === node
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,310 +110,237 @@ function isArgumentOfMethodCall(node, index, object, property) {
|
||||
* @returns {boolean} `true` if the node is a property descriptor.
|
||||
*/
|
||||
function isPropertyDescriptor(node) {
|
||||
// Object.defineProperty(obj, "foo", {set: ...})
|
||||
if (
|
||||
isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||
|
||||
isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Object.defineProperties(obj, {foo: {set: ...}})
|
||||
* Object.create(proto, {foo: {set: ...}})
|
||||
*/
|
||||
const grandparent = node.parent.parent;
|
||||
// Object.defineProperty(obj, "foo", {set: ...})
|
||||
if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||
|
||||
isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
grandparent.type === "ObjectExpression" &&
|
||||
(isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||
|
||||
isArgumentOfMethodCall(
|
||||
grandparent,
|
||||
1,
|
||||
"Object",
|
||||
"defineProperties",
|
||||
))
|
||||
);
|
||||
/*
|
||||
* Object.defineProperties(obj, {foo: {set: ...}})
|
||||
* Object.create(proto, {foo: {set: ...}})
|
||||
*/
|
||||
const grandparent = node.parent.parent;
|
||||
|
||||
return grandparent.type === "ObjectExpression" && (
|
||||
isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||
|
||||
isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @type {import('../types').Rule.RuleModule} */
|
||||
/** @type {import('../shared/types').Rule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
|
||||
defaultOptions: [
|
||||
{
|
||||
enforceForTSTypes: false,
|
||||
enforceForClassMembers: true,
|
||||
getWithoutSet: false,
|
||||
setWithoutGet: true,
|
||||
},
|
||||
],
|
||||
docs: {
|
||||
description: "Enforce getter and setter pairs in objects and classes",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/accessor-pairs"
|
||||
},
|
||||
|
||||
docs: {
|
||||
description:
|
||||
"Enforce getter and setter pairs in objects and classes",
|
||||
recommended: false,
|
||||
url: "https://eslint.org/docs/latest/rules/accessor-pairs",
|
||||
},
|
||||
schema: [{
|
||||
type: "object",
|
||||
properties: {
|
||||
getWithoutSet: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
},
|
||||
setWithoutGet: {
|
||||
type: "boolean",
|
||||
default: true
|
||||
},
|
||||
enforceForClassMembers: {
|
||||
type: "boolean",
|
||||
default: true
|
||||
}
|
||||
},
|
||||
additionalProperties: false
|
||||
}],
|
||||
|
||||
schema: [
|
||||
{
|
||||
type: "object",
|
||||
properties: {
|
||||
getWithoutSet: {
|
||||
type: "boolean",
|
||||
},
|
||||
setWithoutGet: {
|
||||
type: "boolean",
|
||||
},
|
||||
enforceForClassMembers: {
|
||||
type: "boolean",
|
||||
},
|
||||
enforceForTSTypes: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.",
|
||||
missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.",
|
||||
missingGetterInObjectLiteral: "Getter is not present for {{ name }}.",
|
||||
missingSetterInObjectLiteral: "Setter is not present for {{ name }}.",
|
||||
missingGetterInClass: "Getter is not present for class {{ name }}.",
|
||||
missingSetterInClass: "Setter is not present for class {{ name }}."
|
||||
}
|
||||
},
|
||||
create(context) {
|
||||
const config = context.options[0] || {};
|
||||
const checkGetWithoutSet = config.getWithoutSet === true;
|
||||
const checkSetWithoutGet = config.setWithoutGet !== false;
|
||||
const enforceForClassMembers = config.enforceForClassMembers !== false;
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
messages: {
|
||||
missingGetterInPropertyDescriptor:
|
||||
"Getter is not present in property descriptor.",
|
||||
missingSetterInPropertyDescriptor:
|
||||
"Setter is not present in property descriptor.",
|
||||
missingGetterInObjectLiteral:
|
||||
"Getter is not present for {{ name }}.",
|
||||
missingSetterInObjectLiteral:
|
||||
"Setter is not present for {{ name }}.",
|
||||
missingGetterInClass: "Getter is not present for class {{ name }}.",
|
||||
missingSetterInClass: "Setter is not present for class {{ name }}.",
|
||||
missingGetterInType: "Getter is not present for type {{ name }}.",
|
||||
missingSetterInType: "Setter is not present for type {{ name }}.",
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const [
|
||||
{
|
||||
getWithoutSet: checkGetWithoutSet,
|
||||
setWithoutGet: checkSetWithoutGet,
|
||||
enforceForClassMembers,
|
||||
enforceForTSTypes,
|
||||
},
|
||||
] = context.options;
|
||||
const sourceCode = context.sourceCode;
|
||||
/**
|
||||
* Reports the given node.
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @param {string} messageKind "missingGetter" or "missingSetter".
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function report(node, messageKind) {
|
||||
if (node.type === "Property") {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InObjectLiteral`,
|
||||
loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
|
||||
data: { name: astUtils.getFunctionNameWithKind(node.value) }
|
||||
});
|
||||
} else if (node.type === "MethodDefinition") {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InClass`,
|
||||
loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
|
||||
data: { name: astUtils.getFunctionNameWithKind(node.value) }
|
||||
});
|
||||
} else {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InPropertyDescriptor`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the given node.
|
||||
* @param {ASTNode} node The node to report.
|
||||
* @param {string} messageKind "missingGetter" or "missingSetter".
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function report(node, messageKind) {
|
||||
if (node.type === "Property") {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InObjectLiteral`,
|
||||
loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
|
||||
data: {
|
||||
name: astUtils.getFunctionNameWithKind(node.value),
|
||||
},
|
||||
});
|
||||
} else if (node.type === "MethodDefinition") {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InClass`,
|
||||
loc: astUtils.getFunctionHeadLoc(node.value, sourceCode),
|
||||
data: {
|
||||
name: astUtils.getFunctionNameWithKind(node.value),
|
||||
},
|
||||
});
|
||||
} else if (node.type === "TSMethodSignature") {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InType`,
|
||||
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
||||
data: {
|
||||
name: astUtils.getFunctionNameWithKind(node),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
context.report({
|
||||
node,
|
||||
messageId: `${messageKind}InPropertyDescriptor`,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reports each of the nodes in the given list using the same messageId.
|
||||
* @param {ASTNode[]} nodes Nodes to report.
|
||||
* @param {string} messageKind "missingGetter" or "missingSetter".
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function reportList(nodes, messageKind) {
|
||||
for (const node of nodes) {
|
||||
report(node, messageKind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports each of the nodes in the given list using the same messageId.
|
||||
* @param {ASTNode[]} nodes Nodes to report.
|
||||
* @param {string} messageKind "missingGetter" or "missingSetter".
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function reportList(nodes, messageKind) {
|
||||
for (const node of nodes) {
|
||||
report(node, messageKind);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks accessor pairs in the given list of nodes.
|
||||
* @param {ASTNode[]} nodes The list to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkList(nodes) {
|
||||
const accessors = [];
|
||||
let found = false;
|
||||
|
||||
/**
|
||||
* Checks accessor pairs in the given list of nodes.
|
||||
* @param {ASTNode[]} nodes The list to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkList(nodes) {
|
||||
const accessors = [];
|
||||
let found = false;
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
if (isAccessorKind(node)) {
|
||||
|
||||
if (isAccessorKind(node)) {
|
||||
// Creates a new `AccessorData` object for the given getter or setter node.
|
||||
const name = astUtils.getStaticPropertyName(node);
|
||||
const key =
|
||||
name !== null ? name : sourceCode.getTokens(node.key);
|
||||
// Creates a new `AccessorData` object for the given getter or setter node.
|
||||
const name = astUtils.getStaticPropertyName(node);
|
||||
const key = (name !== null) ? name : sourceCode.getTokens(node.key);
|
||||
|
||||
// Merges the given `AccessorData` object into the given accessors list.
|
||||
for (let j = 0; j < accessors.length; j++) {
|
||||
const accessor = accessors[j];
|
||||
// Merges the given `AccessorData` object into the given accessors list.
|
||||
for (let j = 0; j < accessors.length; j++) {
|
||||
const accessor = accessors[j];
|
||||
|
||||
if (areEqualKeys(accessor.key, key)) {
|
||||
accessor.getters.push(
|
||||
...(node.kind === "get" ? [node] : []),
|
||||
);
|
||||
accessor.setters.push(
|
||||
...(node.kind === "set" ? [node] : []),
|
||||
);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
accessors.push({
|
||||
key,
|
||||
getters: node.kind === "get" ? [node] : [],
|
||||
setters: node.kind === "set" ? [node] : [],
|
||||
});
|
||||
}
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
if (areEqualKeys(accessor.key, key)) {
|
||||
accessor.getters.push(...node.kind === "get" ? [node] : []);
|
||||
accessor.setters.push(...node.kind === "set" ? [node] : []);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
accessors.push({
|
||||
key,
|
||||
getters: node.kind === "get" ? [node] : [],
|
||||
setters: node.kind === "set" ? [node] : []
|
||||
});
|
||||
}
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const { getters, setters } of accessors) {
|
||||
if (checkSetWithoutGet && setters.length && !getters.length) {
|
||||
reportList(setters, "missingGetter");
|
||||
}
|
||||
if (checkGetWithoutSet && getters.length && !setters.length) {
|
||||
reportList(getters, "missingSetter");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const { getters, setters } of accessors) {
|
||||
if (checkSetWithoutGet && setters.length && !getters.length) {
|
||||
reportList(setters, "missingGetter");
|
||||
}
|
||||
if (checkGetWithoutSet && getters.length && !setters.length) {
|
||||
reportList(getters, "missingSetter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks accessor pairs in an object literal.
|
||||
* @param {ASTNode} node `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkObjectLiteral(node) {
|
||||
checkList(node.properties.filter(p => p.type === "Property"));
|
||||
}
|
||||
/**
|
||||
* Checks accessor pairs in an object literal.
|
||||
* @param {ASTNode} node `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkObjectLiteral(node) {
|
||||
checkList(node.properties.filter(p => p.type === "Property"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks accessor pairs in a property descriptor.
|
||||
* @param {ASTNode} node Property descriptor `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkPropertyDescriptor(node) {
|
||||
const namesToCheck = new Set(
|
||||
node.properties
|
||||
.filter(
|
||||
p =>
|
||||
p.type === "Property" &&
|
||||
p.kind === "init" &&
|
||||
!p.computed,
|
||||
)
|
||||
.map(({ key }) => key.name),
|
||||
);
|
||||
/**
|
||||
* Checks accessor pairs in a property descriptor.
|
||||
* @param {ASTNode} node Property descriptor `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkPropertyDescriptor(node) {
|
||||
const namesToCheck = new Set(node.properties
|
||||
.filter(p => p.type === "Property" && p.kind === "init" && !p.computed)
|
||||
.map(({ key }) => key.name));
|
||||
|
||||
const hasGetter = namesToCheck.has("get");
|
||||
const hasSetter = namesToCheck.has("set");
|
||||
const hasGetter = namesToCheck.has("get");
|
||||
const hasSetter = namesToCheck.has("set");
|
||||
|
||||
if (checkSetWithoutGet && hasSetter && !hasGetter) {
|
||||
report(node, "missingGetter");
|
||||
}
|
||||
if (checkGetWithoutSet && hasGetter && !hasSetter) {
|
||||
report(node, "missingSetter");
|
||||
}
|
||||
}
|
||||
if (checkSetWithoutGet && hasSetter && !hasGetter) {
|
||||
report(node, "missingGetter");
|
||||
}
|
||||
if (checkGetWithoutSet && hasGetter && !hasSetter) {
|
||||
report(node, "missingSetter");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given object expression as an object literal and as a possible property descriptor.
|
||||
* @param {ASTNode} node `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkObjectExpression(node) {
|
||||
checkObjectLiteral(node);
|
||||
if (isPropertyDescriptor(node)) {
|
||||
checkPropertyDescriptor(node);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks the given object expression as an object literal and as a possible property descriptor.
|
||||
* @param {ASTNode} node `ObjectExpression` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkObjectExpression(node) {
|
||||
checkObjectLiteral(node);
|
||||
if (isPropertyDescriptor(node)) {
|
||||
checkPropertyDescriptor(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given class body.
|
||||
* @param {ASTNode} node `ClassBody` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkClassBody(node) {
|
||||
const methodDefinitions = node.body.filter(
|
||||
m => m.type === "MethodDefinition",
|
||||
);
|
||||
/**
|
||||
* Checks the given class body.
|
||||
* @param {ASTNode} node `ClassBody` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkClassBody(node) {
|
||||
const methodDefinitions = node.body.filter(m => m.type === "MethodDefinition");
|
||||
|
||||
checkList(methodDefinitions.filter(m => m.static));
|
||||
checkList(methodDefinitions.filter(m => !m.static));
|
||||
}
|
||||
checkList(methodDefinitions.filter(m => m.static));
|
||||
checkList(methodDefinitions.filter(m => !m.static));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given type.
|
||||
* @param {ASTNode} node `TSTypeLiteral` or `TSInterfaceBody` node to check.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function checkType(node) {
|
||||
const members =
|
||||
node.type === "TSTypeLiteral" ? node.members : node.body;
|
||||
const methodDefinitions = members.filter(
|
||||
m => m.type === "TSMethodSignature",
|
||||
);
|
||||
const listeners = {};
|
||||
|
||||
checkList(methodDefinitions);
|
||||
}
|
||||
if (checkSetWithoutGet || checkGetWithoutSet) {
|
||||
listeners.ObjectExpression = checkObjectExpression;
|
||||
if (enforceForClassMembers) {
|
||||
listeners.ClassBody = checkClassBody;
|
||||
}
|
||||
}
|
||||
|
||||
const listeners = {};
|
||||
|
||||
if (checkSetWithoutGet || checkGetWithoutSet) {
|
||||
listeners.ObjectExpression = checkObjectExpression;
|
||||
if (enforceForClassMembers) {
|
||||
listeners.ClassBody = checkClassBody;
|
||||
}
|
||||
if (enforceForTSTypes) {
|
||||
listeners["TSTypeLiteral, TSInterfaceBody"] = checkType;
|
||||
}
|
||||
}
|
||||
|
||||
return listeners;
|
||||
},
|
||||
return listeners;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user