oxlint-plugin-react-doctor 0.7.5-dev.20cd922 → 0.7.5-dev.21da48f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +27 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5178,8 +5178,10 @@ const STORAGE_GLOBALS = new Set([
|
|
|
5178
5178
|
const SENSITIVE_KEY_PATTERN = /token|jwt|secret|password|passwd|credential|api[-_]?key|bearer|private[-_]?key/i;
|
|
5179
5179
|
const NON_AUTH_TOKEN_PATTERN = /csrf|xsrf|device|fcm|apns|push|design|tokeniz|syntax|css|theme|color/i;
|
|
5180
5180
|
const STRONG_AUTH_KEY_PATTERN = /jwt|secret|password|passwd|credential|private[-_]?key|api[-_]?key|bearer|access[-_]?token|refresh[-_]?token|auth[-_]?token|id[-_]?token|session/i;
|
|
5181
|
+
const PRODUCT_API_KEY_RECORDS_PATTERN = /(?:^|[._:-])(?:created|saved|integration|mailing)[-_]?api[-_]?keys$/i;
|
|
5181
5182
|
const PRODUCT_API_KEY_COLLECTION_PATTERN = /[._:-](?:created|generated|saved)[-_]?api[-_]?keys$/i;
|
|
5182
5183
|
const isAuthCredentialKey = (key) => {
|
|
5184
|
+
if (PRODUCT_API_KEY_RECORDS_PATTERN.test(key)) return false;
|
|
5183
5185
|
if (!SENSITIVE_KEY_PATTERN.test(key)) return false;
|
|
5184
5186
|
if (PRODUCT_API_KEY_COLLECTION_PATTERN.test(key)) return false;
|
|
5185
5187
|
if (NON_AUTH_TOKEN_PATTERN.test(key) && !STRONG_AUTH_KEY_PATTERN.test(key)) return false;
|
|
@@ -35049,6 +35051,30 @@ const guardsRenderShape = (comparison) => {
|
|
|
35049
35051
|
}
|
|
35050
35052
|
return false;
|
|
35051
35053
|
};
|
|
35054
|
+
const isPropsChildrenLength = (node, scopes) => {
|
|
35055
|
+
const unwrappedNode = stripParenExpression(node);
|
|
35056
|
+
return isNodeOfType(unwrappedNode, "MemberExpression") && !unwrappedNode.computed && isNodeOfType(unwrappedNode.property, "Identifier") && unwrappedNode.property.name === "length" && resolvesToPropsChildren(stripParenExpression(unwrappedNode.object), scopes);
|
|
35057
|
+
};
|
|
35058
|
+
const isLargeTextLengthComparison = (node, scopes) => {
|
|
35059
|
+
const unwrappedNode = stripParenExpression(node);
|
|
35060
|
+
if (!isNodeOfType(unwrappedNode, "BinaryExpression")) return false;
|
|
35061
|
+
const leftIsLength = isPropsChildrenLength(unwrappedNode.left, scopes);
|
|
35062
|
+
const rightIsLength = isPropsChildrenLength(unwrappedNode.right, scopes);
|
|
35063
|
+
const thresholdNode = leftIsLength ? unwrappedNode.right : unwrappedNode.left;
|
|
35064
|
+
if (!leftIsLength && !rightIsLength || !isNodeOfType(thresholdNode, "Literal")) return false;
|
|
35065
|
+
if (typeof thresholdNode.value !== "number" || thresholdNode.value < 1e3) return false;
|
|
35066
|
+
return leftIsLength ? unwrappedNode.operator === ">" || unwrappedNode.operator === ">=" : unwrappedNode.operator === "<" || unwrappedNode.operator === "<=";
|
|
35067
|
+
};
|
|
35068
|
+
const isLargeStringOptimizationGuard = (comparison, scopes) => {
|
|
35069
|
+
let current = findTransparentExpressionRoot(comparison);
|
|
35070
|
+
while (current.parent) {
|
|
35071
|
+
const parent = current.parent;
|
|
35072
|
+
if (!isNodeOfType(parent, "LogicalExpression") || parent.operator !== "&&") return false;
|
|
35073
|
+
if (isLargeTextLengthComparison(parent.left === current ? parent.right : parent.left, scopes)) return true;
|
|
35074
|
+
current = findTransparentExpressionRoot(parent);
|
|
35075
|
+
}
|
|
35076
|
+
return false;
|
|
35077
|
+
};
|
|
35052
35078
|
const noPolymorphicChildren = defineRule({
|
|
35053
35079
|
id: "no-polymorphic-children",
|
|
35054
35080
|
title: "Children type checked at runtime",
|
|
@@ -35062,6 +35088,7 @@ const noPolymorphicChildren = defineRule({
|
|
|
35062
35088
|
const isStringLiteral = (operand) => isNodeOfType(operand, "Literal") && operand.value === "string";
|
|
35063
35089
|
if (!isStringLiteral(node.left) && !isStringLiteral(node.right)) return;
|
|
35064
35090
|
if (!guardsRenderShape(node)) return;
|
|
35091
|
+
if (isLargeStringOptimizationGuard(node, context.scopes)) return;
|
|
35065
35092
|
context.report({
|
|
35066
35093
|
node,
|
|
35067
35094
|
message: "Your users hit inconsistent behavior because `typeof children === \"string\"` makes this component switch on what callers pass, so add clear subcomponents like `<Button.Text>` instead."
|