oxlint-plugin-react-doctor 0.5.7 → 0.5.8-dev.05cafc6

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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- MIT License
1
+ Modified MIT License
2
2
 
3
3
  Copyright (c) 2026 Million Software, Inc.
4
4
 
@@ -19,3 +19,16 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ Our only modification is that the following uses require prior written
24
+ permission from the copyright holder. To request permission, contact
25
+ founders@million.dev.
26
+
27
+ 1. Using the Software, its source code, or any derivative works thereof, in
28
+ whole or in part, as training, fine-tuning, or evaluation data, or as input
29
+ to any automated pipeline for training or improving any machine learning
30
+ model or AI system.
31
+
32
+ 2. Selling the Software, or offering it to third parties as a paid, hosted, or
33
+ managed product or service (including any commercial API or SaaS offering)
34
+ whose value derives entirely or substantially from the Software.
package/dist/index.d.ts CHANGED
@@ -16641,6 +16641,9 @@ declare const REACT_COMPILER_RULES: Record<string, OxlintRuleSeverity>;
16641
16641
  //#region src/plugin/constants/style.d.ts
16642
16642
  declare const MOTION_LIBRARY_PACKAGES: Set<string>;
16643
16643
  //#endregion
16644
+ //#region src/plugin/constants/cross-file-rule-ids.d.ts
16645
+ declare const CROSS_FILE_RULE_IDS: ReadonlySet<string>;
16646
+ //#endregion
16644
16647
  //#region src/plugin/rules/security-scan/utils/classify-security-scan-file.d.ts
16645
16648
  interface SecurityScanFileClassification {
16646
16649
  readonly bucket: "priority" | "artifact" | "other";
@@ -16654,5 +16657,5 @@ declare const REACT_NATIVE_DEPENDENCY_NAMES: ReadonlySet<string>;
16654
16657
  declare const REACT_NATIVE_DEPENDENCY_PREFIXES: ReadonlyArray<string>;
16655
16658
  declare const isReactNativeDependencyName: (dependencyName: string) => boolean;
16656
16659
  //#endregion
16657
- export { ALL_REACT_DOCTOR_RULES, ALL_REACT_DOCTOR_RULE_KEYS, EXTERNAL_RULES, type EsTreeNode, FRAMEWORK_SPECIFIC_RULE_KEYS, type FileScan, MOTION_LIBRARY_PACKAGES, NEXTJS_RULES, type OxlintRuleSeverity, PREACT_RULES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_NATIVE_DEPENDENCY_NAMES, REACT_NATIVE_DEPENDENCY_PREFIXES, REACT_NATIVE_RULES, RECOMMENDED_RULES, RULES, type Rule, type RuleFramework, type RulePlugin, type RuleSeverity, type RuleVisitors, type ScanFinding, type ScannedFile, TANSTACK_QUERY_RULES, TANSTACK_START_RULES, classifySecurityScanFile, plugin as default, isReactNativeDependencyName, shouldReadSecurityScanContent };
16660
+ export { ALL_REACT_DOCTOR_RULES, ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_RULE_IDS, EXTERNAL_RULES, type EsTreeNode, FRAMEWORK_SPECIFIC_RULE_KEYS, type FileScan, MOTION_LIBRARY_PACKAGES, NEXTJS_RULES, type OxlintRuleSeverity, PREACT_RULES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_NATIVE_DEPENDENCY_NAMES, REACT_NATIVE_DEPENDENCY_PREFIXES, REACT_NATIVE_RULES, RECOMMENDED_RULES, RULES, type Rule, type RuleFramework, type RulePlugin, type RuleSeverity, type RuleVisitors, type ScanFinding, type ScannedFile, TANSTACK_QUERY_RULES, TANSTACK_START_RULES, classifySecurityScanFile, plugin as default, isReactNativeDependencyName, shouldReadSecurityScanContent };
16658
16661
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -10789,10 +10789,22 @@ const isWithinChildrenToArray = (jsxNode) => {
10789
10789
  }
10790
10790
  return false;
10791
10791
  };
10792
+ const spreadCanOverwriteKey = (spreadAttribute) => {
10793
+ const argument = spreadAttribute.argument;
10794
+ if (!isNodeOfType(argument, "ObjectExpression")) return true;
10795
+ for (const property of argument.properties) {
10796
+ if (!isNodeOfType(property, "Property")) return true;
10797
+ if (property.computed) return true;
10798
+ const propertyKey = property.key;
10799
+ if (isNodeOfType(propertyKey, "Identifier") && propertyKey.name === "key") return true;
10800
+ if (isNodeOfType(propertyKey, "Literal") && String(propertyKey.value) === "key") return true;
10801
+ }
10802
+ return false;
10803
+ };
10792
10804
  const checkKeyBeforeSpread = (context, openingElement) => {
10793
10805
  let keyIndex = null;
10794
10806
  let keyAttribute = null;
10795
- let firstSpreadIndex = null;
10807
+ let lastOverwritingSpreadIndex = null;
10796
10808
  for (let attributeIndex = 0; attributeIndex < openingElement.attributes.length; attributeIndex++) {
10797
10809
  const attribute = openingElement.attributes[attributeIndex];
10798
10810
  if (isNodeOfType(attribute, "JSXAttribute")) {
@@ -10800,11 +10812,9 @@ const checkKeyBeforeSpread = (context, openingElement) => {
10800
10812
  keyIndex = attributeIndex;
10801
10813
  keyAttribute = attribute;
10802
10814
  }
10803
- } else if (isNodeOfType(attribute, "JSXSpreadAttribute")) {
10804
- if (firstSpreadIndex === null) firstSpreadIndex = attributeIndex;
10805
- }
10815
+ } else if (isNodeOfType(attribute, "JSXSpreadAttribute") && spreadCanOverwriteKey(attribute)) lastOverwritingSpreadIndex = attributeIndex;
10806
10816
  }
10807
- if (keyIndex !== null && firstSpreadIndex !== null && keyIndex > firstSpreadIndex && keyAttribute) context.report({
10817
+ if (keyIndex !== null && lastOverwritingSpreadIndex !== null && lastOverwritingSpreadIndex > keyIndex && keyAttribute) context.report({
10808
10818
  node: keyAttribute,
10809
10819
  message: KEY_BEFORE_SPREAD
10810
10820
  });
@@ -42530,6 +42540,15 @@ const ALL_REACT_DOCTOR_RULE_KEYS = new Set(REACT_DOCTOR_RULES.map((rule) => rule
42530
42540
  const FRAMEWORK_SPECIFIC_RULE_KEYS = collectFrameworkSpecificRuleKeys();
42531
42541
  const REACT_COMPILER_RULES = toRuleMap(collectExternalRulesBySource("react-compiler"));
42532
42542
  //#endregion
42543
+ //#region src/plugin/constants/cross-file-rule-ids.ts
42544
+ const CROSS_FILE_RULE_IDS = new Set([
42545
+ "no-barrel-import",
42546
+ "nextjs-missing-metadata",
42547
+ "nextjs-no-use-search-params-without-suspense",
42548
+ "no-mutating-reducer-state",
42549
+ "rn-prefer-expo-image"
42550
+ ]);
42551
+ //#endregion
42533
42552
  //#region src/plugin/rules/security-scan/utils/is-probably-text-file.ts
42534
42553
  const isProbablyTextFile = (relativePath) => TEXT_FILE_PATTERN.test(relativePath) || DOTENV_FILE_PATTERN.test(relativePath);
42535
42554
  //#endregion
@@ -42555,6 +42574,6 @@ const shouldReadSecurityScanContent = (relativePath, isGeneratedBundle) => isGen
42555
42574
  //#region src/index.ts
42556
42575
  var src_default = plugin;
42557
42576
  //#endregion
42558
- export { ALL_REACT_DOCTOR_RULES, ALL_REACT_DOCTOR_RULE_KEYS, EXTERNAL_RULES, FRAMEWORK_SPECIFIC_RULE_KEYS, MOTION_LIBRARY_PACKAGES, NEXTJS_RULES, PREACT_RULES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_NATIVE_DEPENDENCY_NAMES, REACT_NATIVE_DEPENDENCY_PREFIXES, REACT_NATIVE_RULES, RECOMMENDED_RULES, RULES, TANSTACK_QUERY_RULES, TANSTACK_START_RULES, classifySecurityScanFile, src_default as default, isReactNativeDependencyName, shouldReadSecurityScanContent };
42577
+ export { ALL_REACT_DOCTOR_RULES, ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_RULE_IDS, EXTERNAL_RULES, FRAMEWORK_SPECIFIC_RULE_KEYS, MOTION_LIBRARY_PACKAGES, NEXTJS_RULES, PREACT_RULES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, REACT_NATIVE_DEPENDENCY_NAMES, REACT_NATIVE_DEPENDENCY_PREFIXES, REACT_NATIVE_RULES, RECOMMENDED_RULES, RULES, TANSTACK_QUERY_RULES, TANSTACK_START_RULES, classifySecurityScanFile, src_default as default, isReactNativeDependencyName, shouldReadSecurityScanContent };
42559
42578
 
42560
42579
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.5.7",
4
- "description": "oxlint plugin for React Doctor: diagnose React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
3
+ "version": "0.5.8-dev.05cafc6",
4
+ "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",
7
7
  "linter",
@@ -21,7 +21,7 @@
21
21
  "bugs": {
22
22
  "url": "https://github.com/millionco/react-doctor/issues"
23
23
  },
24
- "license": "MIT",
24
+ "license": "SEE LICENSE IN LICENSE",
25
25
  "author": "Aiden Bai",
26
26
  "repository": {
27
27
  "type": "git",
@@ -30,7 +30,8 @@
30
30
  },
31
31
  "files": [
32
32
  "dist/**/*.js",
33
- "dist/**/*.d.ts"
33
+ "dist/**/*.d.ts",
34
+ "LICENSE"
34
35
  ],
35
36
  "type": "module",
36
37
  "sideEffects": false,