eslint-plugin-react-naming-convention 1.28.1-beta.4 → 1.28.1-beta.5

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.d.mts CHANGED
@@ -34,7 +34,7 @@ declare const _default: {
34
34
  extensions?: readonly string[];
35
35
  ignoreFilesWithoutCode?: boolean;
36
36
  } | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
37
- readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"unexpected", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
37
+ readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
38
38
  };
39
39
  };
40
40
  };
@@ -68,7 +68,7 @@ declare const _default: {
68
68
  extensions?: readonly string[];
69
69
  ignoreFilesWithoutCode?: boolean;
70
70
  } | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
71
- readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"unexpected", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
71
+ readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
72
72
  };
73
73
  };
74
74
 
package/dist/index.d.ts CHANGED
@@ -34,7 +34,7 @@ declare const _default: {
34
34
  extensions?: readonly string[];
35
35
  ignoreFilesWithoutCode?: boolean;
36
36
  } | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
37
- readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"unexpected", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
37
+ readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
38
38
  };
39
39
  };
40
40
  };
@@ -68,7 +68,7 @@ declare const _default: {
68
68
  extensions?: readonly string[];
69
69
  ignoreFilesWithoutCode?: boolean;
70
70
  } | undefined], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
71
- readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"unexpected", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
71
+ readonly "use-state": _typescript_eslint_utils_ts_eslint.RuleModule<"badValueOrSetterName", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
72
72
  };
73
73
  };
74
74
 
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ var shared = require('@eslint-react/shared');
8
8
  var tsPattern = require('ts-pattern');
9
9
  var path = require('path');
10
10
  var stringTs = require('string-ts');
11
+ var VAR = require('@eslint-react/var');
11
12
  var types = require('@typescript-eslint/types');
12
13
 
13
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -33,6 +34,7 @@ function _interopNamespace(e) {
33
34
  var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
34
35
  var JSX__namespace = /*#__PURE__*/_interopNamespace(JSX);
35
36
  var path__default = /*#__PURE__*/_interopDefault(path);
37
+ var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
36
38
 
37
39
  var __defProp = Object.defineProperty;
38
40
  var __export = (target, all) => {
@@ -51,7 +53,7 @@ var rules = {};
51
53
 
52
54
  // package.json
53
55
  var name2 = "eslint-plugin-react-naming-convention";
54
- var version = "1.28.1-beta.4";
56
+ var version = "1.28.1-beta.5";
55
57
  var createRule = shared.createRuleForPlugin("naming-convention");
56
58
 
57
59
  // src/rules/component-name.ts
@@ -391,10 +393,6 @@ var RULE_NAME4 = "use-state";
391
393
  var RULE_FEATURES = [
392
394
  "CHK"
393
395
  ];
394
- function isSetterNameLoose(name3) {
395
- const fourthChar = [...name3][3];
396
- return name3.startsWith("set") && fourthChar === fourthChar?.toUpperCase();
397
- }
398
396
  var use_state_default = createRule({
399
397
  meta: {
400
398
  type: "problem",
@@ -403,65 +401,44 @@ var use_state_default = createRule({
403
401
  [Symbol.for("rule_features")]: RULE_FEATURES
404
402
  },
405
403
  messages: {
406
- unexpected: "An useState call is not destructured into value + setter pair."
404
+ badValueOrSetterName: "An useState call is not destructured into value + setter pair."
407
405
  },
408
406
  schema: []
409
407
  },
410
408
  name: RULE_NAME4,
411
409
  create(context) {
412
- const alias = shared.getSettingsFromContext(context).additionalHooks.useState ?? [];
413
- const {
414
- ctx,
415
- listeners
416
- } = core.useComponentCollector(
417
- context,
418
- {
419
- collectDisplayName: false,
420
- collectHookCalls: true,
421
- hint: core.DEFAULT_COMPONENT_HINT
422
- }
423
- );
424
410
  return {
425
- ...listeners,
426
- "Program:exit"(node) {
427
- const components = ctx.getAllComponents(node);
428
- for (const { hookCalls } of components.values()) {
429
- if (hookCalls.length === 0) {
430
- continue;
431
- }
432
- for (const hookCall of hookCalls) {
433
- if (!core.isUseStateCall(context, hookCall) && !alias.some(core.isReactHookCallWithNameLoose(hookCall))) {
434
- continue;
435
- }
436
- if (hookCall.parent.type !== types.AST_NODE_TYPES.VariableDeclarator) {
437
- continue;
438
- }
439
- const { id } = hookCall.parent;
440
- switch (id.type) {
441
- case types.AST_NODE_TYPES.Identifier: {
442
- context.report({ messageId: "unexpected", node: id });
443
- break;
444
- }
445
- case types.AST_NODE_TYPES.ArrayPattern: {
446
- const [state, setState] = id.elements;
447
- if (state?.type === types.AST_NODE_TYPES.ObjectPattern && setState?.type === types.AST_NODE_TYPES.Identifier) {
448
- if (!isSetterNameLoose(setState.name)) {
449
- context.report({ messageId: "unexpected", node: id });
450
- }
451
- break;
452
- }
453
- if (state?.type !== types.AST_NODE_TYPES.Identifier || setState?.type !== types.AST_NODE_TYPES.Identifier) {
454
- return;
455
- }
456
- const [stateName, setStateName] = [state.name, setState.name];
457
- const expectedSetterName = `set${stringTs.capitalize(stateName)}`;
458
- if (setStateName === expectedSetterName) {
459
- return;
460
- }
461
- context.report({ messageId: "unexpected", node: id });
462
- }
411
+ "CallExpression[callee.name='useState']"(node) {
412
+ if (node.parent.type !== types.AST_NODE_TYPES.VariableDeclarator) {
413
+ context.report({ messageId: "badValueOrSetterName", node });
414
+ }
415
+ const id = VAR__namespace.getVariableId(node);
416
+ if (id?.type !== types.AST_NODE_TYPES.ArrayPattern) {
417
+ context.report({ messageId: "badValueOrSetterName", node });
418
+ return;
419
+ }
420
+ const [value, setter] = id.elements;
421
+ if (value == null || setter == null) {
422
+ context.report({ messageId: "badValueOrSetterName", node });
423
+ return;
424
+ }
425
+ const setterName = tsPattern.match(setter).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => eff._);
426
+ if (setterName == null || !setterName.startsWith("set")) {
427
+ context.report({ messageId: "badValueOrSetterName", node });
428
+ return;
429
+ }
430
+ const valueName = tsPattern.match(value).with({ type: types.AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: types.AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
431
+ const values = properties.reduce((acc, prop) => {
432
+ if (prop.type === types.AST_NODE_TYPES.Property && prop.key.type === types.AST_NODE_TYPES.Identifier) {
433
+ return [...acc, prop.key.name];
463
434
  }
464
- }
435
+ return acc;
436
+ }, []);
437
+ return values.join("_");
438
+ }).otherwise(() => eff._);
439
+ if (valueName == null || `set_${valueName}` !== stringTs.snakeCase(setterName)) {
440
+ context.report({ messageId: "badValueOrSetterName", node });
441
+ return;
465
442
  }
466
443
  }
467
444
  };
package/dist/index.mjs CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as AST from '@eslint-react/ast';
2
- import { useComponentCollector, useComponentCollectorLegacy, DEFAULT_COMPONENT_HINT, isUseStateCall, isReactHookCallWithNameLoose } from '@eslint-react/core';
2
+ import { useComponentCollector, useComponentCollectorLegacy } from '@eslint-react/core';
3
3
  import { isObject, _ } from '@eslint-react/eff';
4
4
  import * as JSX from '@eslint-react/jsx';
5
- import { createRuleForPlugin, getSettingsFromContext, RE_CONSTANT_CASE, RE_PASCAL_CASE, RE_CAMEL_CASE, RE_KEBAB_CASE, RE_SNAKE_CASE } from '@eslint-react/shared';
5
+ import { createRuleForPlugin, RE_CONSTANT_CASE, RE_PASCAL_CASE, RE_CAMEL_CASE, RE_KEBAB_CASE, RE_SNAKE_CASE } from '@eslint-react/shared';
6
6
  import { match } from 'ts-pattern';
7
7
  import path from 'node:path';
8
- import { capitalize, pascalCase, camelCase, kebabCase, snakeCase } from 'string-ts';
8
+ import { snakeCase, pascalCase, camelCase, kebabCase } from 'string-ts';
9
+ import * as VAR from '@eslint-react/var';
9
10
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
10
11
 
11
12
  var __defProp = Object.defineProperty;
@@ -25,7 +26,7 @@ var rules = {};
25
26
 
26
27
  // package.json
27
28
  var name2 = "eslint-plugin-react-naming-convention";
28
- var version = "1.28.1-beta.4";
29
+ var version = "1.28.1-beta.5";
29
30
  var createRule = createRuleForPlugin("naming-convention");
30
31
 
31
32
  // src/rules/component-name.ts
@@ -365,10 +366,6 @@ var RULE_NAME4 = "use-state";
365
366
  var RULE_FEATURES = [
366
367
  "CHK"
367
368
  ];
368
- function isSetterNameLoose(name3) {
369
- const fourthChar = [...name3][3];
370
- return name3.startsWith("set") && fourthChar === fourthChar?.toUpperCase();
371
- }
372
369
  var use_state_default = createRule({
373
370
  meta: {
374
371
  type: "problem",
@@ -377,65 +374,44 @@ var use_state_default = createRule({
377
374
  [Symbol.for("rule_features")]: RULE_FEATURES
378
375
  },
379
376
  messages: {
380
- unexpected: "An useState call is not destructured into value + setter pair."
377
+ badValueOrSetterName: "An useState call is not destructured into value + setter pair."
381
378
  },
382
379
  schema: []
383
380
  },
384
381
  name: RULE_NAME4,
385
382
  create(context) {
386
- const alias = getSettingsFromContext(context).additionalHooks.useState ?? [];
387
- const {
388
- ctx,
389
- listeners
390
- } = useComponentCollector(
391
- context,
392
- {
393
- collectDisplayName: false,
394
- collectHookCalls: true,
395
- hint: DEFAULT_COMPONENT_HINT
396
- }
397
- );
398
383
  return {
399
- ...listeners,
400
- "Program:exit"(node) {
401
- const components = ctx.getAllComponents(node);
402
- for (const { hookCalls } of components.values()) {
403
- if (hookCalls.length === 0) {
404
- continue;
405
- }
406
- for (const hookCall of hookCalls) {
407
- if (!isUseStateCall(context, hookCall) && !alias.some(isReactHookCallWithNameLoose(hookCall))) {
408
- continue;
409
- }
410
- if (hookCall.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
411
- continue;
412
- }
413
- const { id } = hookCall.parent;
414
- switch (id.type) {
415
- case AST_NODE_TYPES.Identifier: {
416
- context.report({ messageId: "unexpected", node: id });
417
- break;
418
- }
419
- case AST_NODE_TYPES.ArrayPattern: {
420
- const [state, setState] = id.elements;
421
- if (state?.type === AST_NODE_TYPES.ObjectPattern && setState?.type === AST_NODE_TYPES.Identifier) {
422
- if (!isSetterNameLoose(setState.name)) {
423
- context.report({ messageId: "unexpected", node: id });
424
- }
425
- break;
426
- }
427
- if (state?.type !== AST_NODE_TYPES.Identifier || setState?.type !== AST_NODE_TYPES.Identifier) {
428
- return;
429
- }
430
- const [stateName, setStateName] = [state.name, setState.name];
431
- const expectedSetterName = `set${capitalize(stateName)}`;
432
- if (setStateName === expectedSetterName) {
433
- return;
434
- }
435
- context.report({ messageId: "unexpected", node: id });
436
- }
384
+ "CallExpression[callee.name='useState']"(node) {
385
+ if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
386
+ context.report({ messageId: "badValueOrSetterName", node });
387
+ }
388
+ const id = VAR.getVariableId(node);
389
+ if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
390
+ context.report({ messageId: "badValueOrSetterName", node });
391
+ return;
392
+ }
393
+ const [value, setter] = id.elements;
394
+ if (value == null || setter == null) {
395
+ context.report({ messageId: "badValueOrSetterName", node });
396
+ return;
397
+ }
398
+ const setterName = match(setter).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).otherwise(() => _);
399
+ if (setterName == null || !setterName.startsWith("set")) {
400
+ context.report({ messageId: "badValueOrSetterName", node });
401
+ return;
402
+ }
403
+ const valueName = match(value).with({ type: AST_NODE_TYPES.Identifier }, (id2) => id2.name).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => {
404
+ const values = properties.reduce((acc, prop) => {
405
+ if (prop.type === AST_NODE_TYPES.Property && prop.key.type === AST_NODE_TYPES.Identifier) {
406
+ return [...acc, prop.key.name];
437
407
  }
438
- }
408
+ return acc;
409
+ }, []);
410
+ return values.join("_");
411
+ }).otherwise(() => _);
412
+ if (valueName == null || `set_${valueName}` !== snakeCase(setterName)) {
413
+ context.report({ messageId: "badValueOrSetterName", node });
414
+ return;
439
415
  }
440
416
  }
441
417
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-naming-convention",
3
- "version": "1.28.1-beta.4",
3
+ "version": "1.28.1-beta.5",
4
4
  "description": "ESLint React's ESLint plugin for naming convention related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -49,11 +49,12 @@
49
49
  "@typescript-eslint/utils": "^8.25.0",
50
50
  "string-ts": "^2.2.1",
51
51
  "ts-pattern": "^5.6.2",
52
- "@eslint-react/ast": "1.28.1-beta.4",
53
- "@eslint-react/core": "1.28.1-beta.4",
54
- "@eslint-react/eff": "1.28.1-beta.4",
55
- "@eslint-react/jsx": "1.28.1-beta.4",
56
- "@eslint-react/shared": "1.28.1-beta.4"
52
+ "@eslint-react/ast": "1.28.1-beta.5",
53
+ "@eslint-react/jsx": "1.28.1-beta.5",
54
+ "@eslint-react/eff": "1.28.1-beta.5",
55
+ "@eslint-react/var": "1.28.1-beta.5",
56
+ "@eslint-react/shared": "1.28.1-beta.5",
57
+ "@eslint-react/core": "1.28.1-beta.5"
57
58
  },
58
59
  "devDependencies": {
59
60
  "@types/react": "^19.0.10",