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.
Files changed (2) hide show
  1. package/dist/index.js +27 -0
  2. 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."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.7.5-dev.20cd922",
3
+ "version": "0.7.5-dev.21da48f",
4
4
  "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",