@ngrx/eslint-plugin 20.1.0 → 21.0.0-rc.0

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 (54) hide show
  1. package/package.json +1 -1
  2. package/schematics/ng-add/schema.json +15 -0
  3. package/scripts/generate-config.js +11 -24
  4. package/scripts/generate-config.js.map +1 -1
  5. package/scripts/generate-docs.js +0 -1
  6. package/scripts/generate-docs.js.map +1 -1
  7. package/scripts/generate-overview.js +1 -1
  8. package/scripts/generate-overview.js.map +1 -1
  9. package/spec/utils/rule-tester.d.ts +1 -1
  10. package/spec/utils/rule-tester.js +7 -4
  11. package/spec/utils/rule-tester.js.map +1 -1
  12. package/src/configs/all-type-checked.d.ts +7 -0
  13. package/src/configs/all-type-checked.js +61 -0
  14. package/src/configs/all-type-checked.js.map +1 -0
  15. package/src/configs/all-type-checked.json +41 -0
  16. package/src/configs/all.js +0 -10
  17. package/src/configs/all.js.map +1 -1
  18. package/src/configs/all.json +0 -9
  19. package/src/configs/component-store.js +0 -1
  20. package/src/configs/component-store.js.map +1 -1
  21. package/src/configs/effects-type-checked.d.ts +7 -0
  22. package/src/configs/effects-type-checked.js +33 -0
  23. package/src/configs/effects-type-checked.js.map +1 -0
  24. package/src/configs/effects-type-checked.json +13 -0
  25. package/src/configs/effects.js +0 -8
  26. package/src/configs/effects.js.map +1 -1
  27. package/src/configs/effects.json +0 -7
  28. package/src/configs/operators.js +0 -1
  29. package/src/configs/operators.js.map +1 -1
  30. package/src/configs/signals-type-checked.d.ts +7 -0
  31. package/src/configs/signals-type-checked.js +31 -0
  32. package/src/configs/signals-type-checked.js.map +1 -0
  33. package/src/configs/signals-type-checked.json +11 -0
  34. package/src/configs/signals.js +0 -8
  35. package/src/configs/signals.js.map +1 -1
  36. package/src/configs/signals.json +1 -8
  37. package/src/configs/store.js +0 -1
  38. package/src/configs/store.js.map +1 -1
  39. package/src/index.d.ts +3 -23
  40. package/src/index.js +6 -0
  41. package/src/index.js.map +1 -1
  42. package/src/rules/signals/signal-state-no-arrays-at-root-level.d.ts +2 -1
  43. package/src/rules/signals/signal-state-no-arrays-at-root-level.js +60 -3
  44. package/src/rules/signals/signal-state-no-arrays-at-root-level.js.map +1 -1
  45. package/src/rules/signals/with-state-no-arrays-at-root-level.js +46 -2
  46. package/src/rules/signals/with-state-no-arrays-at-root-level.js.map +1 -1
  47. package/src/rules/store/prefix-selectors-with-select.js +7 -1
  48. package/src/rules/store/prefix-selectors-with-select.js.map +1 -1
  49. package/v9/index.d.ts +6 -0
  50. package/v9/index.js +6 -0
  51. package/v9/index.js.map +1 -1
  52. package/jest.config.d.ts +0 -15
  53. package/jest.config.js +0 -25
  54. package/jest.config.js.map +0 -1
@@ -2,17 +2,10 @@
2
2
  "parser": "@typescript-eslint/parser",
3
3
  "plugins": ["@ngrx"],
4
4
  "rules": {
5
- "@ngrx/avoid-cyclic-effects": "error",
6
5
  "@ngrx/no-dispatch-in-effects": "error",
7
6
  "@ngrx/no-effects-in-providers": "error",
8
- "@ngrx/no-multiple-actions-in-effects": "error",
9
7
  "@ngrx/prefer-action-creator-in-of-type": "error",
10
8
  "@ngrx/prefer-effect-callback-in-block-statement": "error",
11
9
  "@ngrx/use-effects-lifecycle-interface": "error"
12
- },
13
- "parserOptions": {
14
- "ecmaVersion": 2020,
15
- "sourceType": "module",
16
- "project": "./tsconfig.json"
17
10
  }
18
11
  }
@@ -9,7 +9,6 @@ exports.default = (plugin, parser) => [
9
9
  name: 'ngrx/base',
10
10
  languageOptions: {
11
11
  parser,
12
- sourceType: 'module',
13
12
  },
14
13
  plugins: {
15
14
  '@ngrx': plugin,
@@ -1 +1 @@
1
- {"version":3,"file":"operators.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/operators.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;YACN,UAAU,EAAE,QAAQ;SACrB;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,iCAAiC,EAAE,OAAO;SAC3C;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n sourceType: 'module',\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/operators',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/prefer-concat-latest-from': 'error',\n },\n },\n];\n"]}
1
+ {"version":3,"file":"operators.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/operators.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;SACP;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,iCAAiC,EAAE,OAAO;SAC3C;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/operators',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/prefer-concat-latest-from': 'error',\n },\n },\n];\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * DO NOT EDIT
3
+ * This file is generated
4
+ */
5
+ import type { TSESLint } from '@typescript-eslint/utils';
6
+ declare const _default: (plugin: TSESLint.FlatConfig.Plugin, parser: TSESLint.FlatConfig.Parser) => TSESLint.FlatConfig.ConfigArray;
7
+ export default _default;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * DO NOT EDIT
4
+ * This file is generated
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = (plugin, parser) => [
8
+ {
9
+ name: 'ngrx/base',
10
+ languageOptions: {
11
+ parser,
12
+ },
13
+ plugins: {
14
+ '@ngrx': plugin,
15
+ },
16
+ },
17
+ {
18
+ name: 'ngrx/signals-type-checked',
19
+ languageOptions: {
20
+ parser,
21
+ },
22
+ rules: {
23
+ '@ngrx/enforce-type-call': 'error',
24
+ '@ngrx/prefer-protected-state': 'error',
25
+ '@ngrx/signal-state-no-arrays-at-root-level': 'error',
26
+ '@ngrx/signal-store-feature-should-use-generic-type': 'error',
27
+ '@ngrx/with-state-no-arrays-at-root-level': 'error',
28
+ },
29
+ },
30
+ ];
31
+ //# sourceMappingURL=signals-type-checked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals-type-checked.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/signals-type-checked.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;SACP;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,8BAA8B,EAAE,OAAO;YACvC,4CAA4C,EAAE,OAAO;YACrD,oDAAoD,EAAE,OAAO;YAC7D,0CAA0C,EAAE,OAAO;SACpD;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/signals-type-checked',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/enforce-type-call': 'error',\n '@ngrx/prefer-protected-state': 'error',\n '@ngrx/signal-state-no-arrays-at-root-level': 'error',\n '@ngrx/signal-store-feature-should-use-generic-type': 'error',\n '@ngrx/with-state-no-arrays-at-root-level': 'error',\n },\n },\n];\n"]}
@@ -0,0 +1,11 @@
1
+ {
2
+ "parser": "@typescript-eslint/parser",
3
+ "plugins": ["@ngrx"],
4
+ "rules": {
5
+ "@ngrx/enforce-type-call": "error",
6
+ "@ngrx/prefer-protected-state": "error",
7
+ "@ngrx/signal-state-no-arrays-at-root-level": "error",
8
+ "@ngrx/signal-store-feature-should-use-generic-type": "error",
9
+ "@ngrx/with-state-no-arrays-at-root-level": "error"
10
+ }
11
+ }
@@ -9,7 +9,6 @@ exports.default = (plugin, parser) => [
9
9
  name: 'ngrx/base',
10
10
  languageOptions: {
11
11
  parser,
12
- sourceType: 'module',
13
12
  },
14
13
  plugins: {
15
14
  '@ngrx': plugin,
@@ -19,18 +18,11 @@ exports.default = (plugin, parser) => [
19
18
  name: 'ngrx/signals',
20
19
  languageOptions: {
21
20
  parser,
22
- parserOptions: {
23
- ecmaVersion: 2020,
24
- sourceType: 'module',
25
- project: './tsconfig.json',
26
- },
27
21
  },
28
22
  rules: {
29
23
  '@ngrx/enforce-type-call': 'error',
30
24
  '@ngrx/prefer-protected-state': 'error',
31
- '@ngrx/signal-state-no-arrays-at-root-level': 'error',
32
25
  '@ngrx/signal-store-feature-should-use-generic-type': 'error',
33
- '@ngrx/with-state-no-arrays-at-root-level': 'error',
34
26
  },
35
27
  },
36
28
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/signals.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;YACN,UAAU,EAAE,QAAQ;SACrB;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,eAAe,EAAE;YACf,MAAM;YACN,aAAa,EAAE;gBACb,WAAW,EAAE,IAAI;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE,iBAAiB;aAC3B;SACF;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,8BAA8B,EAAE,OAAO;YACvC,4CAA4C,EAAE,OAAO;YACrD,oDAAoD,EAAE,OAAO;YAC7D,0CAA0C,EAAE,OAAO;SACpD;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n sourceType: 'module',\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/signals',\n languageOptions: {\n parser,\n parserOptions: {\n ecmaVersion: 2020,\n sourceType: 'module',\n project: './tsconfig.json',\n },\n },\n rules: {\n '@ngrx/enforce-type-call': 'error',\n '@ngrx/prefer-protected-state': 'error',\n '@ngrx/signal-state-no-arrays-at-root-level': 'error',\n '@ngrx/signal-store-feature-should-use-generic-type': 'error',\n '@ngrx/with-state-no-arrays-at-root-level': 'error',\n },\n },\n];\n"]}
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/signals.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;SACP;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,8BAA8B,EAAE,OAAO;YACvC,oDAAoD,EAAE,OAAO;SAC9D;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/signals',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/enforce-type-call': 'error',\n '@ngrx/prefer-protected-state': 'error',\n '@ngrx/signal-store-feature-should-use-generic-type': 'error',\n },\n },\n];\n"]}
@@ -4,13 +4,6 @@
4
4
  "rules": {
5
5
  "@ngrx/enforce-type-call": "error",
6
6
  "@ngrx/prefer-protected-state": "error",
7
- "@ngrx/signal-state-no-arrays-at-root-level": "error",
8
- "@ngrx/signal-store-feature-should-use-generic-type": "error",
9
- "@ngrx/with-state-no-arrays-at-root-level": "error"
10
- },
11
- "parserOptions": {
12
- "ecmaVersion": 2020,
13
- "sourceType": "module",
14
- "project": "./tsconfig.json"
7
+ "@ngrx/signal-store-feature-should-use-generic-type": "error"
15
8
  }
16
9
  }
@@ -9,7 +9,6 @@ exports.default = (plugin, parser) => [
9
9
  name: 'ngrx/base',
10
10
  languageOptions: {
11
11
  parser,
12
- sourceType: 'module',
13
12
  },
14
13
  plugins: {
15
14
  '@ngrx': plugin,
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/store.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;YACN,UAAU,EAAE,QAAQ;SACrB;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,iCAAiC,EAAE,OAAO;YAC1C,uDAAuD,EAAE,OAAO;YAChE,0CAA0C,EAAE,OAAO;YACnD,+BAA+B,EAAE,OAAO;YACxC,2BAA2B,EAAE,OAAO;YACpC,iCAAiC,EAAE,OAAO;YAC1C,+BAA+B,EAAE,OAAO;YACxC,6BAA6B,EAAE,OAAO;YACtC,6BAA6B,EAAE,OAAO;YACtC,wCAAwC,EAAE,OAAO;YACjD,yCAAyC,EAAE,OAAO;YAClD,6BAA6B,EAAE,OAAO;YACtC,kCAAkC,EAAE,OAAO;YAC3C,yDAAyD,EAAE,OAAO;YAClE,iCAAiC,EAAE,OAAO;YAC1C,oCAAoC,EAAE,OAAO;YAC7C,oBAAoB,EAAE,OAAO;YAC7B,wCAAwC,EAAE,OAAO;SAClD;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n sourceType: 'module',\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/store',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/avoid-combining-selectors': 'error',\n '@ngrx/avoid-dispatching-multiple-actions-sequentially': 'error',\n '@ngrx/avoid-duplicate-actions-in-reducer': 'error',\n '@ngrx/avoid-mapping-selectors': 'error',\n '@ngrx/good-action-hygiene': 'error',\n '@ngrx/no-multiple-global-stores': 'error',\n '@ngrx/no-reducer-in-key-names': 'error',\n '@ngrx/no-store-subscription': 'error',\n '@ngrx/no-typed-global-store': 'error',\n '@ngrx/on-function-explicit-return-type': 'error',\n '@ngrx/prefer-action-creator-in-dispatch': 'error',\n '@ngrx/prefer-action-creator': 'error',\n '@ngrx/prefer-inline-action-props': 'error',\n '@ngrx/prefer-one-generic-in-create-for-feature-selector': 'error',\n '@ngrx/prefer-selector-in-select': 'error',\n '@ngrx/prefix-selectors-with-select': 'error',\n '@ngrx/select-style': 'error',\n '@ngrx/use-consistent-global-store-name': 'error',\n },\n },\n];\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../../modules/eslint-plugin/src/configs/store.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,kBAAe,CACb,MAAkC,EAClC,MAAkC,EACD,EAAE,CAAC;IACpC;QACE,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE;YACf,MAAM;SACP;QACD,OAAO,EAAE;YACP,OAAO,EAAE,MAAM;SAChB;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,eAAe,EAAE;YACf,MAAM;SACP;QACD,KAAK,EAAE;YACL,iCAAiC,EAAE,OAAO;YAC1C,uDAAuD,EAAE,OAAO;YAChE,0CAA0C,EAAE,OAAO;YACnD,+BAA+B,EAAE,OAAO;YACxC,2BAA2B,EAAE,OAAO;YACpC,iCAAiC,EAAE,OAAO;YAC1C,+BAA+B,EAAE,OAAO;YACxC,6BAA6B,EAAE,OAAO;YACtC,6BAA6B,EAAE,OAAO;YACtC,wCAAwC,EAAE,OAAO;YACjD,yCAAyC,EAAE,OAAO;YAClD,6BAA6B,EAAE,OAAO;YACtC,kCAAkC,EAAE,OAAO;YAC3C,yDAAyD,EAAE,OAAO;YAClE,iCAAiC,EAAE,OAAO;YAC1C,oCAAoC,EAAE,OAAO;YAC7C,oBAAoB,EAAE,OAAO;YAC7B,wCAAwC,EAAE,OAAO;SAClD;KACF;CACF,CAAC","sourcesContent":["/**\n * DO NOT EDIT\n * This file is generated\n */\n\nimport type { TSESLint } from '@typescript-eslint/utils';\n\nexport default (\n plugin: TSESLint.FlatConfig.Plugin,\n parser: TSESLint.FlatConfig.Parser\n): TSESLint.FlatConfig.ConfigArray => [\n {\n name: 'ngrx/base',\n languageOptions: {\n parser,\n },\n plugins: {\n '@ngrx': plugin,\n },\n },\n {\n name: 'ngrx/store',\n languageOptions: {\n parser,\n },\n rules: {\n '@ngrx/avoid-combining-selectors': 'error',\n '@ngrx/avoid-dispatching-multiple-actions-sequentially': 'error',\n '@ngrx/avoid-duplicate-actions-in-reducer': 'error',\n '@ngrx/avoid-mapping-selectors': 'error',\n '@ngrx/good-action-hygiene': 'error',\n '@ngrx/no-multiple-global-stores': 'error',\n '@ngrx/no-reducer-in-key-names': 'error',\n '@ngrx/no-store-subscription': 'error',\n '@ngrx/no-typed-global-store': 'error',\n '@ngrx/on-function-explicit-return-type': 'error',\n '@ngrx/prefer-action-creator-in-dispatch': 'error',\n '@ngrx/prefer-action-creator': 'error',\n '@ngrx/prefer-inline-action-props': 'error',\n '@ngrx/prefer-one-generic-in-create-for-feature-selector': 'error',\n '@ngrx/prefer-selector-in-select': 'error',\n '@ngrx/prefix-selectors-with-select': 'error',\n '@ngrx/select-style': 'error',\n '@ngrx/use-consistent-global-store-name': 'error',\n },\n },\n];\n"]}
package/src/index.d.ts CHANGED
@@ -8,19 +8,15 @@ declare const _default: {
8
8
  "@ngrx/avoid-mapping-component-store-selectors": string;
9
9
  "@ngrx/require-super-ondestroy": string;
10
10
  "@ngrx/updater-explicit-return-type": string;
11
- "@ngrx/avoid-cyclic-effects": string;
12
11
  "@ngrx/no-dispatch-in-effects": string;
13
12
  "@ngrx/no-effects-in-providers": string;
14
- "@ngrx/no-multiple-actions-in-effects": string;
15
13
  "@ngrx/prefer-action-creator-in-of-type": string;
16
14
  "@ngrx/prefer-effect-callback-in-block-statement": string;
17
15
  "@ngrx/use-effects-lifecycle-interface": string;
18
16
  "@ngrx/prefer-concat-latest-from": string;
19
17
  "@ngrx/enforce-type-call": string;
20
18
  "@ngrx/prefer-protected-state": string;
21
- "@ngrx/signal-state-no-arrays-at-root-level": string;
22
19
  "@ngrx/signal-store-feature-should-use-generic-type": string;
23
- "@ngrx/with-state-no-arrays-at-root-level": string;
24
20
  "@ngrx/avoid-combining-selectors": string;
25
21
  "@ngrx/avoid-dispatching-multiple-actions-sequentially": string;
26
22
  "@ngrx/avoid-duplicate-actions-in-reducer": string;
@@ -40,12 +36,8 @@ declare const _default: {
40
36
  "@ngrx/select-style": string;
41
37
  "@ngrx/use-consistent-global-store-name": string;
42
38
  };
43
- parserOptions: {
44
- ecmaVersion: number;
45
- sourceType: string;
46
- project: string;
47
- };
48
39
  };
40
+ 'all-type-checked': (plugin: import("typescript-eslint").FlatConfig.Plugin, parser: import("typescript-eslint").FlatConfig.Parser) => import("typescript-eslint").FlatConfig.ConfigArray;
49
41
  'component-store': {
50
42
  parser: string;
51
43
  plugins: string[];
@@ -60,20 +52,14 @@ declare const _default: {
60
52
  parser: string;
61
53
  plugins: string[];
62
54
  rules: {
63
- "@ngrx/avoid-cyclic-effects": string;
64
55
  "@ngrx/no-dispatch-in-effects": string;
65
56
  "@ngrx/no-effects-in-providers": string;
66
- "@ngrx/no-multiple-actions-in-effects": string;
67
57
  "@ngrx/prefer-action-creator-in-of-type": string;
68
58
  "@ngrx/prefer-effect-callback-in-block-statement": string;
69
59
  "@ngrx/use-effects-lifecycle-interface": string;
70
60
  };
71
- parserOptions: {
72
- ecmaVersion: number;
73
- sourceType: string;
74
- project: string;
75
- };
76
61
  };
62
+ 'effects-type-checked': (plugin: import("typescript-eslint").FlatConfig.Plugin, parser: import("typescript-eslint").FlatConfig.Parser) => import("typescript-eslint").FlatConfig.ConfigArray;
77
63
  store: {
78
64
  parser: string;
79
65
  plugins: string[];
@@ -111,16 +97,10 @@ declare const _default: {
111
97
  rules: {
112
98
  "@ngrx/enforce-type-call": string;
113
99
  "@ngrx/prefer-protected-state": string;
114
- "@ngrx/signal-state-no-arrays-at-root-level": string;
115
100
  "@ngrx/signal-store-feature-should-use-generic-type": string;
116
- "@ngrx/with-state-no-arrays-at-root-level": string;
117
- };
118
- parserOptions: {
119
- ecmaVersion: number;
120
- sourceType: string;
121
- project: string;
122
101
  };
123
102
  };
103
+ 'signals-type-checked': (plugin: import("typescript-eslint").FlatConfig.Plugin, parser: import("typescript-eslint").FlatConfig.Parser) => import("typescript-eslint").FlatConfig.ConfigArray;
124
104
  };
125
105
  rules: {
126
106
  'avoid-combining-component-store-selectors': import("@typescript-eslint/utils/ts-eslint").RuleModule<"avoidCombiningComponentStoreSelectors", readonly [], import("./rule-creator").NgRxRuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
package/src/index.js CHANGED
@@ -4,19 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  const rules_1 = require("./rules");
6
6
  const all_json_1 = __importDefault(require("./configs/all.json"));
7
+ const all_type_checked_1 = __importDefault(require("./configs/all-type-checked"));
7
8
  const component_store_json_1 = __importDefault(require("./configs/component-store.json"));
8
9
  const effects_json_1 = __importDefault(require("./configs/effects.json"));
10
+ const effects_type_checked_1 = __importDefault(require("./configs/effects-type-checked"));
9
11
  const store_json_1 = __importDefault(require("./configs/store.json"));
10
12
  const operators_json_1 = __importDefault(require("./configs/operators.json"));
11
13
  const signals_json_1 = __importDefault(require("./configs/signals.json"));
14
+ const signals_type_checked_1 = __importDefault(require("./configs/signals-type-checked"));
12
15
  module.exports = {
13
16
  configs: {
14
17
  all: all_json_1.default,
18
+ 'all-type-checked': all_type_checked_1.default,
15
19
  'component-store': component_store_json_1.default,
16
20
  effects: effects_json_1.default,
21
+ 'effects-type-checked': effects_type_checked_1.default,
17
22
  store: store_json_1.default,
18
23
  operators: operators_json_1.default,
19
24
  signals: signals_json_1.default,
25
+ 'signals-type-checked': signals_type_checked_1.default,
20
26
  },
21
27
  rules: rules_1.rules,
22
28
  };
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../modules/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,mCAAgC;AAChC,kEAAqC;AACrC,0FAA4D;AAC5D,0EAA6C;AAC7C,sEAAyC;AACzC,8EAAiD;AACjD,0EAA6C;AAE7C,iBAAS;IACP,OAAO,EAAE;QACP,GAAG,EAAH,kBAAG;QACH,iBAAiB,EAAE,8BAAc;QACjC,OAAO,EAAE,sBAAO;QAChB,KAAK,EAAE,oBAAK;QACZ,SAAS,EAAE,wBAAS;QACpB,OAAO,EAAE,sBAAO;KACjB;IACD,KAAK,EAAL,aAAK;CACN,CAAC","sourcesContent":["import { rules } from './rules';\nimport all from './configs/all.json';\nimport componentStore from './configs/component-store.json';\nimport effects from './configs/effects.json';\nimport store from './configs/store.json';\nimport operators from './configs/operators.json';\nimport signals from './configs/signals.json';\n\nexport = {\n configs: {\n all,\n 'component-store': componentStore,\n effects: effects,\n store: store,\n operators: operators,\n signals: signals,\n },\n rules,\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../modules/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,mCAAgC;AAChC,kEAAqC;AACrC,kFAAwD;AACxD,0FAA4D;AAC5D,0EAA6C;AAC7C,0FAAgE;AAChE,sEAAyC;AACzC,8EAAiD;AACjD,0EAA6C;AAC7C,0FAAgE;AAEhE,iBAAS;IACP,OAAO,EAAE;QACP,GAAG,EAAH,kBAAG;QACH,kBAAkB,EAAE,0BAAc;QAClC,iBAAiB,EAAE,8BAAc;QACjC,OAAO,EAAE,sBAAO;QAChB,sBAAsB,EAAE,8BAAkB;QAC1C,KAAK,EAAE,oBAAK;QACZ,SAAS,EAAE,wBAAS;QACpB,OAAO,EAAE,sBAAO;QAChB,sBAAsB,EAAE,8BAAkB;KAC3C;IACD,KAAK,EAAL,aAAK;CACN,CAAC","sourcesContent":["import { rules } from './rules';\nimport all from './configs/all.json';\nimport allTypeChecked from './configs/all-type-checked';\nimport componentStore from './configs/component-store.json';\nimport effects from './configs/effects.json';\nimport effectsTypeChecked from './configs/effects-type-checked';\nimport store from './configs/store.json';\nimport operators from './configs/operators.json';\nimport signals from './configs/signals.json';\nimport signalsTypeChecked from './configs/signals-type-checked';\n\nexport = {\n configs: {\n all,\n 'all-type-checked': allTypeChecked,\n 'component-store': componentStore,\n effects: effects,\n 'effects-type-checked': effectsTypeChecked,\n store: store,\n operators: operators,\n signals: signals,\n 'signals-type-checked': signalsTypeChecked,\n },\n rules,\n};\n"]}
@@ -1,3 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
1
2
  export declare const messageId = "signalStateNoArraysAtRootLevel";
2
- declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"signalStateNoArraysAtRootLevel", readonly [], import("../../rule-creator").NgRxRuleDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
3
+ declare const _default: ESLintUtils.RuleModule<"signalStateNoArraysAtRootLevel", readonly [], import("../../rule-creator").NgRxRuleDocs, ESLintUtils.RuleListener>;
3
4
  export default _default;
@@ -34,10 +34,25 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.messageId = void 0;
37
+ const utils_1 = require("@typescript-eslint/utils");
37
38
  const path = __importStar(require("path"));
38
39
  const rule_creator_1 = require("../../rule-creator");
39
- const utils_1 = require("../../utils");
40
+ const utils_2 = require("../../utils");
40
41
  exports.messageId = 'signalStateNoArraysAtRootLevel';
42
+ const NON_RECORD_TYPES = [
43
+ 'Array',
44
+ 'Set',
45
+ 'Map',
46
+ 'WeakSet',
47
+ 'WeakMap',
48
+ 'Date',
49
+ 'Error',
50
+ 'RegExp',
51
+ 'ArrayBuffer',
52
+ 'DataView',
53
+ 'Promise',
54
+ 'Function',
55
+ ];
41
56
  exports.default = (0, rule_creator_1.createRule)({
42
57
  name: path.parse(__filename).name,
43
58
  meta: {
@@ -45,10 +60,11 @@ exports.default = (0, rule_creator_1.createRule)({
45
60
  docs: {
46
61
  description: `signalState should accept a record or dictionary as an input argument.`,
47
62
  ngrxModule: 'signals',
63
+ requiresTypeChecking: true,
48
64
  },
49
65
  schema: [],
50
66
  messages: {
51
- [exports.messageId]: `Wrap the array in an record or dictionary.`,
67
+ [exports.messageId]: 'The property type `{{ property }}` is forbidden as the initial state argument, wrap the property in a record or dictionary.',
52
68
  },
53
69
  },
54
70
  defaultOptions: [],
@@ -56,12 +72,53 @@ exports.default = (0, rule_creator_1.createRule)({
56
72
  return {
57
73
  [`CallExpression[callee.name=signalState]`](node) {
58
74
  const [argument] = node.arguments;
59
- if ((0, utils_1.isArrayExpression)(argument)) {
75
+ if ((0, utils_2.isArrayExpression)(argument)) {
60
76
  context.report({
61
77
  node: argument,
62
78
  messageId: exports.messageId,
79
+ data: { property: 'Array' },
63
80
  });
64
81
  }
82
+ else if (argument) {
83
+ const services = utils_1.ESLintUtils.getParserServices(context);
84
+ const typeChecker = services.program.getTypeChecker();
85
+ const type = services.getTypeAtLocation(argument);
86
+ if (typeChecker.isArrayType(type) || typeChecker.isTupleType(type)) {
87
+ context.report({
88
+ node: argument,
89
+ messageId: exports.messageId,
90
+ data: { property: 'Array' },
91
+ });
92
+ return;
93
+ }
94
+ const symbol = type.getSymbol();
95
+ if (symbol && NON_RECORD_TYPES.includes(symbol.getName())) {
96
+ context.report({
97
+ node: argument,
98
+ messageId: exports.messageId,
99
+ data: { property: symbol.getName() },
100
+ });
101
+ return;
102
+ }
103
+ const callSignatures = type.getCallSignatures();
104
+ if (callSignatures.length > 0) {
105
+ context.report({
106
+ node: argument,
107
+ messageId: exports.messageId,
108
+ data: { property: 'Function' },
109
+ });
110
+ return;
111
+ }
112
+ const typeString = typeChecker.typeToString(type);
113
+ const matchedType = NON_RECORD_TYPES.find((t) => typeString.startsWith(`${t}<`));
114
+ if (matchedType) {
115
+ context.report({
116
+ node: argument,
117
+ messageId: exports.messageId,
118
+ data: { property: matchedType },
119
+ });
120
+ }
121
+ }
65
122
  },
66
123
  };
67
124
  },
@@ -1 +1 @@
1
- {"version":3,"file":"signal-state-no-arrays-at-root-level.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/signals/signal-state-no-arrays-at-root-level.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAA6B;AAC7B,qDAAgD;AAChD,uCAAgD;AAEnC,QAAA,SAAS,GAAG,gCAAgC,CAAC;AAK1D,kBAAe,IAAA,yBAAU,EAAsB;IAC7C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,wEAAwE;YACrF,UAAU,EAAE,SAAS;SACtB;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,CAAC,iBAAS,CAAC,EAAE,4CAA4C;SAC1D;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,OAAO;YACL,CAAC,yCAAyC,CAAC,CACzC,IAA6B;gBAE7B,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,IAAI,IAAA,yBAAiB,EAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,QAAQ;wBACd,SAAS,EAAT,iBAAS;qBACV,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { type TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { isArrayExpression } from '../../utils';\n\nexport const messageId = 'signalStateNoArraysAtRootLevel';\n\ntype MessageIds = typeof messageId;\ntype Options = readonly [];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'problem',\n docs: {\n description: `signalState should accept a record or dictionary as an input argument.`,\n ngrxModule: 'signals',\n },\n schema: [],\n messages: {\n [messageId]: `Wrap the array in an record or dictionary.`,\n },\n },\n defaultOptions: [],\n create: (context) => {\n return {\n [`CallExpression[callee.name=signalState]`](\n node: TSESTree.CallExpression\n ) {\n const [argument] = node.arguments;\n if (isArrayExpression(argument)) {\n context.report({\n node: argument,\n messageId,\n });\n }\n },\n };\n },\n});\n"]}
1
+ {"version":3,"file":"signal-state-no-arrays-at-root-level.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/signals/signal-state-no-arrays-at-root-level.ts"],"names":[],"mappings":"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","sourcesContent":["import { ESLintUtils, type TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { isArrayExpression } from '../../utils';\n\nexport const messageId = 'signalStateNoArraysAtRootLevel';\n\ntype MessageIds = typeof messageId;\ntype Options = readonly [];\n\nconst NON_RECORD_TYPES = [\n 'Array',\n 'Set',\n 'Map',\n 'WeakSet',\n 'WeakMap',\n 'Date',\n 'Error',\n 'RegExp',\n 'ArrayBuffer',\n 'DataView',\n 'Promise',\n 'Function',\n];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'problem',\n docs: {\n description: `signalState should accept a record or dictionary as an input argument.`,\n ngrxModule: 'signals',\n requiresTypeChecking: true,\n },\n schema: [],\n messages: {\n [messageId]:\n 'The property type `{{ property }}` is forbidden as the initial state argument, wrap the property in a record or dictionary.',\n },\n },\n defaultOptions: [],\n create: (context) => {\n return {\n [`CallExpression[callee.name=signalState]`](\n node: TSESTree.CallExpression\n ) {\n const [argument] = node.arguments;\n if (isArrayExpression(argument)) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Array' },\n });\n } else if (argument) {\n const services = ESLintUtils.getParserServices(context);\n const typeChecker = services.program.getTypeChecker();\n const type = services.getTypeAtLocation(argument);\n\n if (typeChecker.isArrayType(type) || typeChecker.isTupleType(type)) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Array' },\n });\n return;\n }\n\n const symbol = type.getSymbol();\n if (symbol && NON_RECORD_TYPES.includes(symbol.getName())) {\n context.report({\n node: argument,\n messageId,\n data: { property: symbol.getName() },\n });\n return;\n }\n\n const callSignatures = type.getCallSignatures();\n if (callSignatures.length > 0) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Function' },\n });\n return;\n }\n\n const typeString = typeChecker.typeToString(type);\n const matchedType = NON_RECORD_TYPES.find((t) =>\n typeString.startsWith(`${t}<`)\n );\n if (matchedType) {\n context.report({\n node: argument,\n messageId,\n data: { property: matchedType },\n });\n }\n }\n },\n };\n },\n});\n"]}
@@ -39,6 +39,20 @@ const path = __importStar(require("path"));
39
39
  const rule_creator_1 = require("../../rule-creator");
40
40
  const utils_2 = require("../../utils");
41
41
  exports.messageId = 'withStateNoArraysAtRootLevel';
42
+ const NON_RECORD_TYPES = [
43
+ 'Array',
44
+ 'Set',
45
+ 'Map',
46
+ 'WeakSet',
47
+ 'WeakMap',
48
+ 'Date',
49
+ 'Error',
50
+ 'RegExp',
51
+ 'ArrayBuffer',
52
+ 'DataView',
53
+ 'Promise',
54
+ 'Function',
55
+ ];
42
56
  exports.default = (0, rule_creator_1.createRule)({
43
57
  name: path.parse(__filename).name,
44
58
  meta: {
@@ -50,7 +64,7 @@ exports.default = (0, rule_creator_1.createRule)({
50
64
  },
51
65
  schema: [],
52
66
  messages: {
53
- [exports.messageId]: `Wrap the array in an record or dictionary.`,
67
+ [exports.messageId]: 'The property type `{{ property }}` is forbidden as the initial state argument, wrap the property in a record or dictionary.',
54
68
  },
55
69
  },
56
70
  defaultOptions: [],
@@ -62,16 +76,46 @@ exports.default = (0, rule_creator_1.createRule)({
62
76
  context.report({
63
77
  node: argument,
64
78
  messageId: exports.messageId,
79
+ data: { property: 'Array' },
65
80
  });
66
81
  }
67
82
  else if (argument) {
68
83
  const services = utils_1.ESLintUtils.getParserServices(context);
69
84
  const typeChecker = services.program.getTypeChecker();
70
85
  const type = services.getTypeAtLocation(argument);
71
- if (typeChecker.isArrayType(type)) {
86
+ if (typeChecker.isArrayType(type) || typeChecker.isTupleType(type)) {
72
87
  context.report({
73
88
  node: argument,
74
89
  messageId: exports.messageId,
90
+ data: { property: 'Array' },
91
+ });
92
+ return;
93
+ }
94
+ const symbol = type.getSymbol();
95
+ if (symbol && NON_RECORD_TYPES.includes(symbol.getName())) {
96
+ context.report({
97
+ node: argument,
98
+ messageId: exports.messageId,
99
+ data: { property: symbol.getName() },
100
+ });
101
+ return;
102
+ }
103
+ const callSignatures = type.getCallSignatures();
104
+ if (callSignatures.length > 0) {
105
+ context.report({
106
+ node: argument,
107
+ messageId: exports.messageId,
108
+ data: { property: 'Function' },
109
+ });
110
+ return;
111
+ }
112
+ const typeString = typeChecker.typeToString(type);
113
+ const matchedType = NON_RECORD_TYPES.find((t) => typeString.startsWith(`${t}<`));
114
+ if (matchedType) {
115
+ context.report({
116
+ node: argument,
117
+ messageId: exports.messageId,
118
+ data: { property: matchedType },
75
119
  });
76
120
  }
77
121
  }
@@ -1 +1 @@
1
- {"version":3,"file":"with-state-no-arrays-at-root-level.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/signals/with-state-no-arrays-at-root-level.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAsE;AACtE,2CAA6B;AAC7B,qDAAgD;AAChD,uCAAgD;AAEnC,QAAA,SAAS,GAAG,8BAA8B,CAAC;AAKxD,kBAAe,IAAA,yBAAU,EAAsB;IAC7C,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,sEAAsE;YACnF,UAAU,EAAE,SAAS;YACrB,oBAAoB,EAAE,IAAI;SAC3B;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,CAAC,iBAAS,CAAC,EAAE,4CAA4C;SAC1D;KACF;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,OAAO;YACL,CAAC,uCAAuC,CAAC,CAAC,IAA6B;gBACrE,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,IAAI,IAAA,yBAAiB,EAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,QAAQ;wBACd,SAAS,EAAT,iBAAS;qBACV,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,QAAQ,EAAE,CAAC;oBACpB,MAAM,QAAQ,GAAG,mBAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBACxD,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;oBACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;oBAElD,IAAI,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;wBAClC,OAAO,CAAC,MAAM,CAAC;4BACb,IAAI,EAAE,QAAQ;4BACd,SAAS,EAAT,iBAAS;yBACV,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { ESLintUtils, type TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { isArrayExpression } from '../../utils';\n\nexport const messageId = 'withStateNoArraysAtRootLevel';\n\ntype MessageIds = typeof messageId;\ntype Options = readonly [];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'problem',\n docs: {\n description: `withState should accept a record or dictionary as an input argument.`,\n ngrxModule: 'signals',\n requiresTypeChecking: true,\n },\n schema: [],\n messages: {\n [messageId]: `Wrap the array in an record or dictionary.`,\n },\n },\n defaultOptions: [],\n create: (context) => {\n return {\n [`CallExpression[callee.name=withState]`](node: TSESTree.CallExpression) {\n const [argument] = node.arguments;\n if (isArrayExpression(argument)) {\n context.report({\n node: argument,\n messageId,\n });\n } else if (argument) {\n const services = ESLintUtils.getParserServices(context);\n const typeChecker = services.program.getTypeChecker();\n const type = services.getTypeAtLocation(argument);\n\n if (typeChecker.isArrayType(type)) {\n context.report({\n node: argument,\n messageId,\n });\n }\n }\n },\n };\n },\n});\n"]}
1
+ {"version":3,"file":"with-state-no-arrays-at-root-level.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/signals/with-state-no-arrays-at-root-level.ts"],"names":[],"mappings":"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","sourcesContent":["import { ESLintUtils, type TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { isArrayExpression } from '../../utils';\n\nexport const messageId = 'withStateNoArraysAtRootLevel';\n\ntype MessageIds = typeof messageId;\ntype Options = readonly [];\n\nconst NON_RECORD_TYPES = [\n 'Array',\n 'Set',\n 'Map',\n 'WeakSet',\n 'WeakMap',\n 'Date',\n 'Error',\n 'RegExp',\n 'ArrayBuffer',\n 'DataView',\n 'Promise',\n 'Function',\n];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'problem',\n docs: {\n description: `withState should accept a record or dictionary as an input argument.`,\n ngrxModule: 'signals',\n requiresTypeChecking: true,\n },\n schema: [],\n messages: {\n [messageId]:\n 'The property type `{{ property }}` is forbidden as the initial state argument, wrap the property in a record or dictionary.',\n },\n },\n defaultOptions: [],\n create: (context) => {\n return {\n [`CallExpression[callee.name=withState]`](node: TSESTree.CallExpression) {\n const [argument] = node.arguments;\n if (isArrayExpression(argument)) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Array' },\n });\n } else if (argument) {\n const services = ESLintUtils.getParserServices(context);\n const typeChecker = services.program.getTypeChecker();\n const type = services.getTypeAtLocation(argument);\n\n if (typeChecker.isArrayType(type) || typeChecker.isTupleType(type)) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Array' },\n });\n return;\n }\n\n const symbol = type.getSymbol();\n if (symbol && NON_RECORD_TYPES.includes(symbol.getName())) {\n context.report({\n node: argument,\n messageId,\n data: { property: symbol.getName() },\n });\n return;\n }\n\n const callSignatures = type.getCallSignatures();\n if (callSignatures.length > 0) {\n context.report({\n node: argument,\n messageId,\n data: { property: 'Function' },\n });\n return;\n }\n\n const typeString = typeChecker.typeToString(type);\n const matchedType = NON_RECORD_TYPES.find((t) =>\n typeString.startsWith(`${t}<`)\n );\n if (matchedType) {\n context.report({\n node: argument,\n messageId,\n data: { property: matchedType },\n });\n }\n }\n },\n };\n },\n});\n"]}
@@ -152,7 +152,13 @@ exports.default = (0, rule_creator_1.createRule)({
152
152
  node.id.typeAnnotation.typeAnnotation.typeName.type === 'Identifier'
153
153
  ? node.id.typeAnnotation.typeAnnotation.typeName.name
154
154
  : null;
155
- const hasSelectorType = typeName !== null && /Selector$/.test(typeName);
155
+ const hasSelectorType = typeName !== null &&
156
+ [
157
+ 'MemoizedSelector',
158
+ 'MemoizedSelectorWithProps',
159
+ 'Selector',
160
+ 'SelectorWithProps',
161
+ ].includes(typeName);
156
162
  const isSelectorCall = init?.type === 'CallExpression' && isSelectorFactoryCall(init);
157
163
  const isArrowFunction = init?.type === 'ArrowFunctionExpression' &&
158
164
  init.body &&
@@ -1 +1 @@
1
- {"version":3,"file":"prefix-selectors-with-select.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/store/prefix-selectors-with-select.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { capitalize } from '../../utils';\n\nexport const prefixSelectorsWithSelect = 'prefixSelectorsWithSelect';\nexport const prefixSelectorsWithSelectSuggest =\n 'prefixSelectorsWithSelectSuggest';\n\ntype MessageIds =\n | typeof prefixSelectorsWithSelect\n | typeof prefixSelectorsWithSelectSuggest;\ntype Options = readonly [];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'suggestion',\n hasSuggestions: true,\n docs: {\n description:\n 'The selector should start with \"select\", for example \"selectEntity\".',\n ngrxModule: 'store',\n },\n schema: [],\n messages: {\n [prefixSelectorsWithSelect]: 'The selector should start with \"select\".',\n [prefixSelectorsWithSelectSuggest]:\n 'Prefix the selector with \"select\": `{{ name }}`.',\n },\n },\n defaultOptions: [],\n create: (context) => {\n function reportIfInvalid(name: string, node: TSESTree.Identifier) {\n // Name starts with select and\n // the first character after select is an uppercase ASCII letter, _, or $\n const isValid =\n name.startsWith('select') &&\n name.length > 'select'.length &&\n /^[A-Z_$]/.test(name.slice('select'.length));\n\n if (!isValid) {\n const suggestedName = getSuggestedName(name);\n context.report({\n node,\n loc: {\n start: node.loc.start,\n end: {\n line: node.loc.start.line,\n column: node.loc.start.column + name.length,\n },\n },\n messageId: prefixSelectorsWithSelect,\n suggest: [\n {\n messageId: prefixSelectorsWithSelectSuggest,\n data: { name: suggestedName },\n fix: (fixer) => {\n const parent = node.parent;\n const sourceCode = context.getSourceCode();\n\n // Handle destructuring: { selectAll: allItems }\n if (\n parent &&\n parent.type === 'Property' &&\n parent.value === node &&\n parent.parent &&\n parent.parent.type === 'ObjectPattern'\n ) {\n return fixer.replaceText(node, suggestedName);\n }\n\n // Handle simple variable declarator: const allItems = ...\n if (\n parent &&\n parent.type === 'VariableDeclarator' &&\n parent.id.type === 'Identifier'\n ) {\n const typeAnnotation = parent.id.typeAnnotation\n ? sourceCode.getText(parent.id.typeAnnotation)\n : '';\n return fixer.replaceText(\n parent.id,\n `${suggestedName}${typeAnnotation}`\n );\n }\n\n // Fallback: just replace the identifier\n return fixer.replaceText(node, suggestedName);\n },\n },\n ],\n });\n }\n }\n\n function isSelectorFactoryCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee;\n return (\n callee.type === 'Identifier' &&\n [\n 'createSelector',\n 'createFeatureSelector',\n 'createSelectorFactory',\n ].includes(callee.name)\n );\n }\n\n function checkFunctionBody(\n name: string,\n node: TSESTree.Identifier,\n body: TSESTree.BlockStatement | TSESTree.Expression\n ) {\n if (body.type === 'CallExpression' && isSelectorFactoryCall(body)) {\n reportIfInvalid(name, node);\n }\n\n if (body.type === 'BlockStatement') {\n for (const stmt of body.body) {\n if (\n stmt.type === 'ReturnStatement' &&\n stmt.argument &&\n stmt.argument.type === 'CallExpression' &&\n isSelectorFactoryCall(stmt.argument)\n ) {\n reportIfInvalid(name, node);\n }\n }\n }\n }\n\n return {\n VariableDeclarator(node: TSESTree.VariableDeclarator) {\n const { id, init } = node;\n\n const isSelectorSource =\n init?.type === 'CallExpression' &&\n ((init.callee.type === 'Identifier' &&\n init.callee.name === 'getSelectors') ||\n (init.callee.type === 'MemberExpression' &&\n init.callee.property.type === 'Identifier' &&\n init.callee.property.name === 'getSelectors'));\n\n if (id.type === 'ObjectPattern' && isSelectorSource) {\n for (const prop of id.properties) {\n if (prop.type === 'Property' && prop.value.type === 'Identifier') {\n reportIfInvalid(prop.value.name, prop.value);\n }\n }\n return;\n }\n\n if (id.type === 'Identifier') {\n const typeName =\n node.id.typeAnnotation?.typeAnnotation.type === 'TSTypeReference' &&\n node.id.typeAnnotation.typeAnnotation.typeName.type === 'Identifier'\n ? node.id.typeAnnotation.typeAnnotation.typeName.name\n : null;\n\n const hasSelectorType =\n typeName !== null && /Selector$/.test(typeName);\n\n const isSelectorCall =\n init?.type === 'CallExpression' && isSelectorFactoryCall(init);\n\n const isArrowFunction =\n init?.type === 'ArrowFunctionExpression' &&\n init.body &&\n (init.body.type === 'CallExpression' ||\n init.body.type === 'BlockStatement');\n\n const isFunctionExpression =\n init?.type === 'FunctionExpression' &&\n init.body &&\n init.body.type === 'BlockStatement';\n\n if (hasSelectorType || isSelectorCall) {\n reportIfInvalid(id.name, id);\n } else if (isArrowFunction || isFunctionExpression) {\n checkFunctionBody(id.name, id, init.body);\n }\n }\n },\n };\n },\n});\n\nfunction getSuggestedName(name: string): string {\n const selectWord = 'select';\n\n if (name.startsWith(selectWord)) {\n const rest = name.slice(selectWord.length);\n if (rest.length === 0) {\n return 'selectSelect';\n }\n if (/^[A-Z_]+$/.test(rest)) {\n return `${selectWord}${rest}`;\n }\n return `${selectWord}${capitalize(rest)}`;\n }\n\n if (/^get([^a-z].+)/.test(name)) {\n const rest = name.slice(3);\n return `${selectWord}${capitalize(rest)}`;\n }\n\n if (/^[A-Z_]+$/.test(name)) {\n return `${selectWord}${name}`;\n }\n\n return `${selectWord}${capitalize(name)}`;\n}\n"]}
1
+ {"version":3,"file":"prefix-selectors-with-select.js","sourceRoot":"","sources":["../../../../../../modules/eslint-plugin/src/rules/store/prefix-selectors-with-select.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport * as path from 'path';\nimport { createRule } from '../../rule-creator';\nimport { capitalize } from '../../utils';\n\nexport const prefixSelectorsWithSelect = 'prefixSelectorsWithSelect';\nexport const prefixSelectorsWithSelectSuggest =\n 'prefixSelectorsWithSelectSuggest';\n\ntype MessageIds =\n | typeof prefixSelectorsWithSelect\n | typeof prefixSelectorsWithSelectSuggest;\ntype Options = readonly [];\n\nexport default createRule<Options, MessageIds>({\n name: path.parse(__filename).name,\n meta: {\n type: 'suggestion',\n hasSuggestions: true,\n docs: {\n description:\n 'The selector should start with \"select\", for example \"selectEntity\".',\n ngrxModule: 'store',\n },\n schema: [],\n messages: {\n [prefixSelectorsWithSelect]: 'The selector should start with \"select\".',\n [prefixSelectorsWithSelectSuggest]:\n 'Prefix the selector with \"select\": `{{ name }}`.',\n },\n },\n defaultOptions: [],\n create: (context) => {\n function reportIfInvalid(name: string, node: TSESTree.Identifier) {\n // Name starts with select and\n // the first character after select is an uppercase ASCII letter, _, or $\n const isValid =\n name.startsWith('select') &&\n name.length > 'select'.length &&\n /^[A-Z_$]/.test(name.slice('select'.length));\n\n if (!isValid) {\n const suggestedName = getSuggestedName(name);\n context.report({\n node,\n loc: {\n start: node.loc.start,\n end: {\n line: node.loc.start.line,\n column: node.loc.start.column + name.length,\n },\n },\n messageId: prefixSelectorsWithSelect,\n suggest: [\n {\n messageId: prefixSelectorsWithSelectSuggest,\n data: { name: suggestedName },\n fix: (fixer) => {\n const parent = node.parent;\n const sourceCode = context.getSourceCode();\n\n // Handle destructuring: { selectAll: allItems }\n if (\n parent &&\n parent.type === 'Property' &&\n parent.value === node &&\n parent.parent &&\n parent.parent.type === 'ObjectPattern'\n ) {\n return fixer.replaceText(node, suggestedName);\n }\n\n // Handle simple variable declarator: const allItems = ...\n if (\n parent &&\n parent.type === 'VariableDeclarator' &&\n parent.id.type === 'Identifier'\n ) {\n const typeAnnotation = parent.id.typeAnnotation\n ? sourceCode.getText(parent.id.typeAnnotation)\n : '';\n return fixer.replaceText(\n parent.id,\n `${suggestedName}${typeAnnotation}`\n );\n }\n\n // Fallback: just replace the identifier\n return fixer.replaceText(node, suggestedName);\n },\n },\n ],\n });\n }\n }\n\n function isSelectorFactoryCall(node: TSESTree.CallExpression): boolean {\n const callee = node.callee;\n return (\n callee.type === 'Identifier' &&\n [\n 'createSelector',\n 'createFeatureSelector',\n 'createSelectorFactory',\n ].includes(callee.name)\n );\n }\n\n function checkFunctionBody(\n name: string,\n node: TSESTree.Identifier,\n body: TSESTree.BlockStatement | TSESTree.Expression\n ) {\n if (body.type === 'CallExpression' && isSelectorFactoryCall(body)) {\n reportIfInvalid(name, node);\n }\n\n if (body.type === 'BlockStatement') {\n for (const stmt of body.body) {\n if (\n stmt.type === 'ReturnStatement' &&\n stmt.argument &&\n stmt.argument.type === 'CallExpression' &&\n isSelectorFactoryCall(stmt.argument)\n ) {\n reportIfInvalid(name, node);\n }\n }\n }\n }\n\n return {\n VariableDeclarator(node: TSESTree.VariableDeclarator) {\n const { id, init } = node;\n\n const isSelectorSource =\n init?.type === 'CallExpression' &&\n ((init.callee.type === 'Identifier' &&\n init.callee.name === 'getSelectors') ||\n (init.callee.type === 'MemberExpression' &&\n init.callee.property.type === 'Identifier' &&\n init.callee.property.name === 'getSelectors'));\n\n if (id.type === 'ObjectPattern' && isSelectorSource) {\n for (const prop of id.properties) {\n if (prop.type === 'Property' && prop.value.type === 'Identifier') {\n reportIfInvalid(prop.value.name, prop.value);\n }\n }\n return;\n }\n\n if (id.type === 'Identifier') {\n const typeName =\n node.id.typeAnnotation?.typeAnnotation.type === 'TSTypeReference' &&\n node.id.typeAnnotation.typeAnnotation.typeName.type === 'Identifier'\n ? node.id.typeAnnotation.typeAnnotation.typeName.name\n : null;\n\n const hasSelectorType =\n typeName !== null &&\n [\n 'MemoizedSelector',\n 'MemoizedSelectorWithProps',\n 'Selector',\n 'SelectorWithProps',\n ].includes(typeName);\n\n const isSelectorCall =\n init?.type === 'CallExpression' && isSelectorFactoryCall(init);\n\n const isArrowFunction =\n init?.type === 'ArrowFunctionExpression' &&\n init.body &&\n (init.body.type === 'CallExpression' ||\n init.body.type === 'BlockStatement');\n\n const isFunctionExpression =\n init?.type === 'FunctionExpression' &&\n init.body &&\n init.body.type === 'BlockStatement';\n\n if (hasSelectorType || isSelectorCall) {\n reportIfInvalid(id.name, id);\n } else if (isArrowFunction || isFunctionExpression) {\n checkFunctionBody(id.name, id, init.body);\n }\n }\n },\n };\n },\n});\n\nfunction getSuggestedName(name: string): string {\n const selectWord = 'select';\n\n if (name.startsWith(selectWord)) {\n const rest = name.slice(selectWord.length);\n if (rest.length === 0) {\n return 'selectSelect';\n }\n if (/^[A-Z_]+$/.test(rest)) {\n return `${selectWord}${rest}`;\n }\n return `${selectWord}${capitalize(rest)}`;\n }\n\n if (/^get([^a-z].+)/.test(name)) {\n const rest = name.slice(3);\n return `${selectWord}${capitalize(rest)}`;\n }\n\n if (/^[A-Z_]+$/.test(name)) {\n return `${selectWord}${name}`;\n }\n\n return `${selectWord}${capitalize(name)}`;\n}\n"]}
package/v9/index.d.ts CHANGED
@@ -5,11 +5,14 @@ declare const meta: {
5
5
  };
6
6
  declare const configs: {
7
7
  all: TSESLint.FlatConfig.ConfigArray;
8
+ allTypeChecked: TSESLint.FlatConfig.ConfigArray;
8
9
  store: TSESLint.FlatConfig.ConfigArray;
9
10
  effects: TSESLint.FlatConfig.ConfigArray;
11
+ effectsTypeChecked: TSESLint.FlatConfig.ConfigArray;
10
12
  componentStore: TSESLint.FlatConfig.ConfigArray;
11
13
  operators: TSESLint.FlatConfig.ConfigArray;
12
14
  signals: TSESLint.FlatConfig.ConfigArray;
15
+ signalsTypeChecked: TSESLint.FlatConfig.ConfigArray;
13
16
  };
14
17
  declare const _default: {
15
18
  meta: {
@@ -18,11 +21,14 @@ declare const _default: {
18
21
  };
19
22
  configs: {
20
23
  all: TSESLint.FlatConfig.ConfigArray;
24
+ allTypeChecked: TSESLint.FlatConfig.ConfigArray;
21
25
  store: TSESLint.FlatConfig.ConfigArray;
22
26
  effects: TSESLint.FlatConfig.ConfigArray;
27
+ effectsTypeChecked: TSESLint.FlatConfig.ConfigArray;
23
28
  componentStore: TSESLint.FlatConfig.ConfigArray;
24
29
  operators: TSESLint.FlatConfig.ConfigArray;
25
30
  signals: TSESLint.FlatConfig.ConfigArray;
31
+ signalsTypeChecked: TSESLint.FlatConfig.ConfigArray;
26
32
  };
27
33
  };
28
34
  export default _default;