@sun-asterisk/sunlint 1.0.6 → 1.1.3

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 (314) hide show
  1. package/.sunlint.json +35 -0
  2. package/CHANGELOG.md +135 -169
  3. package/CONTRIBUTING.md +235 -0
  4. package/PROJECT_STRUCTURE.md +60 -0
  5. package/README.md +77 -50
  6. package/cli.js +1 -0
  7. package/config/README.md +88 -0
  8. package/config/defaults/ai-rules-context.json +231 -0
  9. package/config/engines/engines.json +49 -0
  10. package/config/engines/eslint-rule-mapping.json +74 -0
  11. package/config/eslint-rule-mapping.json +126 -0
  12. package/config/{typescript/eslint.config.js → integrations/eslint/typescript.config.js} +4 -0
  13. package/config/presets/beginner.json +1 -1
  14. package/config/presets/ci.json +3 -2
  15. package/config/presets/recommended.json +1 -1
  16. package/config/presets/strict.json +2 -2
  17. package/config/rule-analysis-strategies.js +74 -0
  18. package/config/{rules-registry.json → rules/rules-registry.json} +82 -0
  19. package/core/analysis-orchestrator.js +383 -591
  20. package/core/ast-modules/README.md +103 -0
  21. package/core/ast-modules/base-parser.js +90 -0
  22. package/core/ast-modules/index.js +97 -0
  23. package/core/ast-modules/package.json +37 -0
  24. package/core/ast-modules/parsers/eslint-js-parser.js +147 -0
  25. package/core/ast-modules/parsers/eslint-ts-parser.js +106 -0
  26. package/core/ast-modules/parsers/javascript-parser.js +187 -0
  27. package/core/ast-modules/parsers/typescript-parser.js +187 -0
  28. package/core/cli-action-handler.js +271 -255
  29. package/core/cli-program.js +18 -4
  30. package/core/config-manager.js +18 -11
  31. package/core/config-merger.js +52 -1
  32. package/core/config-validator.js +2 -2
  33. package/core/enhanced-rules-registry.js +331 -0
  34. package/core/file-targeting-service.js +93 -29
  35. package/core/interfaces/analysis-engine.interface.js +100 -0
  36. package/core/multi-rule-runner.js +0 -221
  37. package/core/output-service.js +1 -1
  38. package/core/rule-mapping-service.js +9 -1
  39. package/core/rule-selection-service.js +10 -2
  40. package/docs/CONFIGURATION.md +414 -0
  41. package/docs/DEPLOYMENT-STRATEGIES.md +270 -0
  42. package/engines/eslint-engine.js +601 -0
  43. package/engines/heuristic-engine.js +860 -0
  44. package/engines/openai-engine.js +374 -0
  45. package/integrations/eslint/README.md +99 -0
  46. package/{eslint-integration → integrations/eslint/configs}/.eslintrc.js +1 -1
  47. package/integrations/eslint/configs/eslint.config.js +133 -0
  48. package/integrations/eslint/configs/eslint.config.simple.js +24 -0
  49. package/integrations/eslint/plugin/index.js +164 -0
  50. package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c006-function-name-verb-noun.js +11 -2
  51. package/integrations/eslint/plugin/rules/common/c013-no-dead-code.js +78 -0
  52. package/integrations/eslint/plugin/rules/common/c017-limit-constructor-logic.js +146 -0
  53. package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c029-catch-block-logging.js +35 -0
  54. package/integrations/eslint/plugin/rules/common/c035-no-empty-catch.js +162 -0
  55. package/integrations/eslint/plugin/rules/common/c041-no-config-inline.js +122 -0
  56. package/integrations/eslint/plugin/rules/common/c072-one-assert-per-test.js +184 -0
  57. package/integrations/eslint/plugin/rules/common/c075-explicit-function-return-types.js +168 -0
  58. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +254 -0
  59. package/integrations/eslint/plugin/rules/security/s001-fail-securely.js +381 -0
  60. package/integrations/eslint/plugin/rules/security/s002-idor-check.js +945 -0
  61. package/integrations/eslint/plugin/rules/security/s007-no-plaintext-otp.js +74 -0
  62. package/integrations/eslint/plugin/rules/security/s013-verify-tls-connection.js +47 -0
  63. package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t003-ts-ignore-reason.js +3 -3
  64. package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t007-no-fn-in-constructor.js +1 -1
  65. package/integrations/eslint/plugin/rules/typescript/t019-no-this-assign.js +81 -0
  66. package/integrations/eslint/plugin/rules/typescript/t020-no-default-multi-export.js +127 -0
  67. package/integrations/eslint/plugin/rules/typescript/t021-limit-nested-generics.js +150 -0
  68. package/integrations/eslint/test-c041-rule.js +87 -0
  69. package/package.json +29 -19
  70. package/rules/README.md +252 -0
  71. package/rules/common/C002_no_duplicate_code/analyzer.js +65 -0
  72. package/rules/common/C002_no_duplicate_code/config.json +23 -0
  73. package/rules/common/C003_no_vague_abbreviations/analyzer.js +418 -0
  74. package/rules/common/C003_no_vague_abbreviations/config.json +35 -0
  75. package/rules/{C006_function_naming → common/C006_function_naming}/analyzer.js +13 -2
  76. package/rules/common/C010_limit_block_nesting/analyzer.js +389 -0
  77. package/rules/common/C013_no_dead_code/analyzer.js +206 -0
  78. package/rules/common/C014_dependency_injection/analyzer.js +338 -0
  79. package/rules/common/C017_constructor_logic/analyzer.js +314 -0
  80. package/rules/{C019_log_level_usage → common/C019_log_level_usage}/analyzer.js +5 -2
  81. package/rules/{C029_catch_block_logging → common/C029_catch_block_logging}/analyzer.js +49 -15
  82. package/rules/common/C041_no_sensitive_hardcode/analyzer.js +292 -0
  83. package/rules/common/C042_boolean_name_prefix/analyzer.js +300 -0
  84. package/rules/common/C043_no_console_or_print/analyzer.js +304 -0
  85. package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +351 -0
  86. package/rules/common/C075_explicit_return_types/analyzer.js +103 -0
  87. package/rules/common/C076_single_test_behavior/analyzer.js +121 -0
  88. package/rules/docs/C002_no_duplicate_code.md +57 -0
  89. package/rules/index.js +149 -0
  90. package/rules/migration/converter.js +385 -0
  91. package/rules/migration/mapping.json +164 -0
  92. package/rules/security/S026_json_schema_validation/analyzer.js +251 -0
  93. package/rules/security/S026_json_schema_validation/config.json +27 -0
  94. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +263 -0
  95. package/rules/security/S027_no_hardcoded_secrets/config.json +29 -0
  96. package/rules/security/S029_csrf_protection/analyzer.js +264 -0
  97. package/rules/tests/C002_no_duplicate_code.test.js +50 -0
  98. package/rules/utils/ast-utils.js +191 -0
  99. package/rules/utils/base-analyzer.js +98 -0
  100. package/rules/utils/pattern-matchers.js +239 -0
  101. package/rules/utils/rule-helpers.js +264 -0
  102. package/rules/utils/severity-constants.js +93 -0
  103. package/scripts/build-release.sh +117 -0
  104. package/scripts/ci-report.js +179 -0
  105. package/scripts/install.sh +196 -0
  106. package/scripts/manual-release.sh +338 -0
  107. package/scripts/merge-reports.js +424 -0
  108. package/scripts/pre-release-test.sh +175 -0
  109. package/scripts/prepare-release.sh +202 -0
  110. package/scripts/setup-github-registry.sh +42 -0
  111. package/scripts/test-scripts/README.md +22 -0
  112. package/scripts/test-scripts/test-c041-comparison.js +114 -0
  113. package/scripts/test-scripts/test-c041-eslint.js +67 -0
  114. package/scripts/test-scripts/test-eslint-rules.js +146 -0
  115. package/scripts/test-scripts/test-real-world.js +44 -0
  116. package/scripts/test-scripts/test-rules-on-real-projects.js +86 -0
  117. package/scripts/trigger-release.sh +285 -0
  118. package/scripts/validate-rule-structure.js +148 -0
  119. package/scripts/verify-install.sh +82 -0
  120. package/cli-legacy.js +0 -355
  121. package/config/sunlint-schema.json +0 -166
  122. package/config/typescript/custom-rules-new.js +0 -0
  123. package/config/typescript/custom-rules.js +0 -9
  124. package/config/typescript/package-lock.json +0 -1585
  125. package/config/typescript/package.json +0 -13
  126. package/config/typescript/security-rules/index.js +0 -90
  127. package/config/typescript/security-rules/s005-no-origin-auth.js +0 -95
  128. package/config/typescript/security-rules/s006-activation-recovery-secret-not-plaintext.js +0 -69
  129. package/config/typescript/security-rules/s008-crypto-agility.js +0 -62
  130. package/config/typescript/security-rules/s009-no-insecure-crypto.js +0 -103
  131. package/config/typescript/security-rules/s010-no-insecure-random-in-sensitive-context.js +0 -123
  132. package/config/typescript/security-rules/s011-no-insecure-uuid.js +0 -66
  133. package/config/typescript/security-rules/s012-hardcode-secret.js +0 -71
  134. package/config/typescript/security-rules/s014-insecure-tls-version.js +0 -50
  135. package/config/typescript/security-rules/s015-insecure-tls-certificate.js +0 -43
  136. package/config/typescript/security-rules/s016-sensitive-query-parameter.js +0 -59
  137. package/config/typescript/security-rules/s017-no-sql-injection.js +0 -193
  138. package/config/typescript/security-rules/s018-positive-input-validation.js +0 -56
  139. package/config/typescript/security-rules/s019-no-raw-user-input-in-email.js +0 -113
  140. package/config/typescript/security-rules/s020-no-eval-dynamic-execution.js +0 -89
  141. package/config/typescript/security-rules/s022-output-encoding.js +0 -78
  142. package/config/typescript/security-rules/s023-no-json-injection.js +0 -300
  143. package/config/typescript/security-rules/s025-server-side-input-validation.js +0 -217
  144. package/config/typescript/security-rules/s026-json-schema-validation.js +0 -68
  145. package/config/typescript/security-rules/s027-no-hardcoded-secrets.js +0 -80
  146. package/config/typescript/security-rules/s029-require-csrf-protection.js +0 -79
  147. package/config/typescript/security-rules/s030-no-directory-browsing.js +0 -78
  148. package/config/typescript/security-rules/s033-require-samesite-cookie.js +0 -80
  149. package/config/typescript/security-rules/s034-require-host-cookie-prefix.js +0 -77
  150. package/config/typescript/security-rules/s035-cookie-specific-path.js +0 -74
  151. package/config/typescript/security-rules/s036-no-unsafe-file-include.js +0 -68
  152. package/config/typescript/security-rules/s037-require-anti-cache-headers.js +0 -70
  153. package/config/typescript/security-rules/s038-no-version-disclosure.js +0 -74
  154. package/config/typescript/security-rules/s039-no-session-token-in-url.js +0 -63
  155. package/config/typescript/security-rules/s041-require-session-invalidate-on-logout.js +0 -211
  156. package/config/typescript/security-rules/s042-require-periodic-reauthentication.js +0 -294
  157. package/config/typescript/security-rules/s043-terminate-sessions-on-password-change.js +0 -254
  158. package/config/typescript/security-rules/s044-require-full-session-for-sensitive-operations.js +0 -292
  159. package/config/typescript/security-rules/s045-anti-automation-controls.js +0 -46
  160. package/config/typescript/security-rules/s046-secure-notification-on-auth-change.js +0 -44
  161. package/config/typescript/security-rules/s048-password-credential-recovery.js +0 -54
  162. package/config/typescript/security-rules/s050-session-token-weak-hash.js +0 -94
  163. package/config/typescript/security-rules/s052-secure-random-authentication-code.js +0 -66
  164. package/config/typescript/security-rules/s054-verification-default-account.js +0 -109
  165. package/config/typescript/security-rules/s057-utc-logging.js +0 -54
  166. package/config/typescript/security-rules/s058-no-ssrf.js +0 -73
  167. package/config/typescript/tsconfig.json +0 -29
  168. package/core/ai-analyzer.js +0 -169
  169. package/core/eslint-engine-service.js +0 -312
  170. package/core/eslint-instance-manager.js +0 -104
  171. package/core/eslint-integration-service.js +0 -363
  172. package/core/sunlint-engine-service.js +0 -23
  173. package/core/typescript-analyzer.js +0 -262
  174. package/core/typescript-engine.js +0 -313
  175. package/docs/ENHANCED_FILE_TARGETING.md +0 -0
  176. package/docs/FILE_TARGETING_COMPARISON.md +0 -0
  177. package/docs/RULE-RESPONSIBILITY-MATRIX.md +0 -204
  178. package/eslint-integration/cli.js +0 -35
  179. package/eslint-integration/eslint-plugin-custom/c013-no-dead-code.js +0 -43
  180. package/eslint-integration/eslint-plugin-custom/c017-limit-constructor-logic.js +0 -39
  181. package/eslint-integration/eslint-plugin-custom/c027-limit-function-nesting.js +0 -50
  182. package/eslint-integration/eslint-plugin-custom/c034-no-implicit-return.js +0 -34
  183. package/eslint-integration/eslint-plugin-custom/c035-no-empty-catch.js +0 -32
  184. package/eslint-integration/eslint-plugin-custom/c041-no-config-inline.js +0 -64
  185. package/eslint-integration/eslint-plugin-custom/c048-no-var-declaration.js +0 -31
  186. package/eslint-integration/eslint-plugin-custom/index.js +0 -155
  187. package/eslint-integration/eslint-plugin-custom/package.json.bak +0 -9
  188. package/eslint-integration/eslint-plugin-custom/t004-interface-public-only.js +0 -160
  189. package/eslint-integration/eslint-plugin-custom/t011-no-real-time-dependency.js +0 -175
  190. package/eslint-integration/eslint-plugin-custom/t026-limit-nested-generics.js +0 -377
  191. package/eslint-integration/sample.ts +0 -53
  192. package/eslint-integration/test-s003.js +0 -5
  193. package/examples/.github/workflows/code-quality.yml +0 -111
  194. package/examples/README.md +0 -69
  195. package/examples/basic-typescript-demo/.eslintrc.json +0 -18
  196. package/examples/basic-typescript-demo/.next/cache/eslint/.cache_1othrmo +0 -1
  197. package/examples/basic-typescript-demo/.sunlint.json +0 -29
  198. package/examples/basic-typescript-demo/eslint.config.mjs +0 -37
  199. package/examples/basic-typescript-demo/next-env.d.ts +0 -5
  200. package/examples/basic-typescript-demo/next.config.mjs +0 -4
  201. package/examples/basic-typescript-demo/package-lock.json +0 -5656
  202. package/examples/basic-typescript-demo/package.json +0 -34
  203. package/examples/basic-typescript-demo/src/app/layout.tsx +0 -18
  204. package/examples/basic-typescript-demo/src/app/page.tsx +0 -48
  205. package/examples/basic-typescript-demo/src/config.ts +0 -14
  206. package/examples/basic-typescript-demo/src/good-practices.ts +0 -58
  207. package/examples/basic-typescript-demo/src/types.generated.ts +0 -13
  208. package/examples/basic-typescript-demo/src/user.test.ts +0 -19
  209. package/examples/basic-typescript-demo/src/violations.ts +0 -61
  210. package/examples/basic-typescript-demo/tsconfig.json +0 -27
  211. package/examples/eslint-integration-demo/.eslintrc.js +0 -38
  212. package/examples/eslint-integration-demo/.sunlint.json +0 -42
  213. package/examples/eslint-integration-demo/next-env.d.ts +0 -5
  214. package/examples/eslint-integration-demo/next.config.js +0 -8
  215. package/examples/eslint-integration-demo/package-lock.json +0 -5740
  216. package/examples/eslint-integration-demo/package.json +0 -37
  217. package/examples/eslint-integration-demo/src/api.test.ts +0 -20
  218. package/examples/eslint-integration-demo/src/conflict-test.tsx +0 -44
  219. package/examples/eslint-integration-demo/src/naming-conflicts.ts +0 -50
  220. package/examples/eslint-integration-demo/tsconfig.json +0 -26
  221. package/examples/file-targeting-demo/global.d.ts +0 -11
  222. package/examples/file-targeting-demo/jest.config.js +0 -8
  223. package/examples/file-targeting-demo/sample.ts +0 -53
  224. package/examples/file-targeting-demo/src/server.js +0 -11
  225. package/examples/file-targeting-demo/src/server.test.js +0 -11
  226. package/examples/file-targeting-demo/src/types.d.ts +0 -4
  227. package/examples/file-targeting-demo/src/types.generated.ts +0 -10
  228. package/examples/file-targeting-demo/user-service.test.ts +0 -15
  229. package/examples/file-targeting-demo/user-service.ts +0 -13
  230. package/examples/file-targeting-demo/utils.js +0 -15
  231. package/examples/multi-language-project/.eslintrc.json +0 -38
  232. package/examples/multi-language-project/package.json +0 -37
  233. package/examples/multi-language-project/src/sample.ts +0 -39
  234. package/examples/rule-test-fixtures/README.md +0 -67
  235. package/examples/rule-test-fixtures/rules/C006_function_naming/clean/typescript-clean.ts +0 -64
  236. package/examples/rule-test-fixtures/rules/C006_function_naming/violations/dart-violations.dart +0 -56
  237. package/examples/rule-test-fixtures/rules/C006_function_naming/violations/typescript-violations.ts +0 -47
  238. package/examples/rule-test-fixtures/rules/C019_log_level_usage/clean/typescript-clean.ts +0 -93
  239. package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/dart-violations.dart +0 -75
  240. package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/typescript-violations.ts +0 -84
  241. package/examples/rule-test-fixtures/rules/C029_catch_block_logging/violations/typescript-violations.ts +0 -37
  242. /package/config/{default.json → defaults/default.json} +0 -0
  243. /package/{eslint-integration/eslint.config.js → config/integrations/eslint/base.config.js} +0 -0
  244. /package/{eslint-integration/eslint.config.simple.js → config/integrations/eslint/simple.config.js} +0 -0
  245. /package/{examples/rule-test-fixtures/rules/C029_catch_block_logging/clean/typescript-clean.ts → config/schemas/sunlint-schema.json} +0 -0
  246. /package/config/{typescript → testing}/test-s005-working.ts +0 -0
  247. /package/{examples/eslint-integration-demo/test-file-targeting.sh → engines/tree-sitter-parser.js} +0 -0
  248. /package/{examples/enhanced-config.json → engines/universal-ast-engine.js} +0 -0
  249. /package/{eslint-integration → integrations/eslint}/package.json +0 -0
  250. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin}/package.json +0 -0
  251. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c002-no-duplicate-code.js +0 -0
  252. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c003-no-vague-abbreviations.js +0 -0
  253. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c010-limit-block-nesting.js +0 -0
  254. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c014-abstract-dependency-preferred.js +0 -0
  255. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c018-no-generic-throw.js +0 -0
  256. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c023-no-duplicate-variable-name-in-scope.js +0 -0
  257. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c030-use-custom-error-classes.js +0 -0
  258. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c042-boolean-name-prefix.js +0 -0
  259. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c043-no-console-or-print.js +0 -0
  260. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c047-no-duplicate-retry-logic.js +0 -0
  261. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s003-no-unvalidated-redirect.js +0 -0
  262. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s005-no-origin-auth.js +0 -0
  263. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s006-activation-recovery-secret-not-plaintext.js +0 -0
  264. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s008-crypto-agility.js +0 -0
  265. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s009-no-insecure-crypto.js +0 -0
  266. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s010-no-insecure-random-in-sensitive-context.js +0 -0
  267. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s011-no-insecure-uuid.js +0 -0
  268. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s012-hardcode-secret.js +0 -0
  269. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s014-insecure-tls-version.js +0 -0
  270. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s015-insecure-tls-certificate.js +0 -0
  271. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s016-sensitive-query-parameter.js +0 -0
  272. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s017-no-sql-injection.js +0 -0
  273. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s018-positive-input-validation.js +0 -0
  274. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s019-no-raw-user-input-in-email.js +0 -0
  275. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s020-no-eval-dynamic-execution.js +0 -0
  276. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s022-output-encoding.js +0 -0
  277. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s023-no-json-injection.js +0 -0
  278. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s025-server-side-input-validation.js +0 -0
  279. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s026-json-schema-validation.js +0 -0
  280. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s027-no-hardcoded-secrets.js +0 -0
  281. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s029-require-csrf-protection.js +0 -0
  282. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s030-no-directory-browsing.js +0 -0
  283. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s033-require-samesite-cookie.js +0 -0
  284. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s034-require-host-cookie-prefix.js +0 -0
  285. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s035-cookie-specific-path.js +0 -0
  286. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s036-no-unsafe-file-include.js +0 -0
  287. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s037-require-anti-cache-headers.js +0 -0
  288. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s038-no-version-disclosure.js +0 -0
  289. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s039-no-session-token-in-url.js +0 -0
  290. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s041-require-session-invalidate-on-logout.js +0 -0
  291. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s042-require-periodic-reauthentication.js +0 -0
  292. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s043-terminate-sessions-on-password-change.js +0 -0
  293. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s044-require-full-session-for-sensitive-operations.js +0 -0
  294. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s045-anti-automation-controls.js +0 -0
  295. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s046-secure-notification-on-auth-change.js +0 -0
  296. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s047-secure-random-passwords.js +0 -0
  297. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s048-password-credential-recovery.js +0 -0
  298. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s050-session-token-weak-hash.js +0 -0
  299. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s052-secure-random-authentication-code.js +0 -0
  300. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s054-verification-default-account.js +0 -0
  301. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s055-verification-rest-check-the-incoming-content-type.js +0 -0
  302. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s057-utc-logging.js +0 -0
  303. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s058-no-ssrf.js +0 -0
  304. /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t002-interface-prefix-i.js +0 -0
  305. /package/{eslint-integration/eslint-plugin-custom/t019-no-empty-type.js → integrations/eslint/plugin/rules/typescript/t004-no-empty-type.js} +0 -0
  306. /package/{eslint-integration/eslint-plugin-custom/t025-no-nested-union-tuple.js → integrations/eslint/plugin/rules/typescript/t010-no-nested-union-tuple.js} +0 -0
  307. /package/{eslint-integration → integrations/eslint}/tsconfig.json +0 -0
  308. /package/rules/{C006_function_naming → common/C006_function_naming}/config.json +0 -0
  309. /package/rules/{C019_log_level_usage → common/C019_log_level_usage}/config.json +0 -0
  310. /package/rules/{C029_catch_block_logging → common/C029_catch_block_logging}/config.json +0 -0
  311. /package/rules/{C031_validation_separation → common/C031_validation_separation}/analyzer.js +0 -0
  312. /package/rules/{C031_validation_separation/README.md → docs/C031_validation_separation.md} +0 -0
  313. /package/{examples/basic-typescript-demo/test-file-targeting.sh → rules/universal/C010/generic.js} +0 -0
  314. /package/{examples/basic-typescript-demo/test-config-priority.sh → rules/universal/C010/tree-sitter-analyzer.js} +0 -0
@@ -1,300 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = {
4
- meta: {
5
- type: "problem",
6
- docs: {
7
- description: "Prevent JSON injection attacks and unsafe JSON handling",
8
- recommended: true,
9
- },
10
- schema: [],
11
- messages: {
12
- noEvalJson: "Never use eval() to process JSON data - use JSON.parse() instead",
13
- unsafeJsonParse: "Unsafe JSON parsing - validate input before parsing",
14
- jsonStringifyInHtml: "JSON.stringify output should be escaped when used in HTML context",
15
- unsafeTemplateString: "Unsafe template string with user input",
16
- unsafeDocumentWrite: "JSON.stringify output should be escaped when used in HTML context",
17
- unsafeStorageParse: "Unsafe JSON parsing - validate input before parsing",
18
- unsafeUrlParse: "Unsafe JSON parsing - validate input before parsing",
19
- },
20
- },
21
-
22
- create(context) {
23
- const sourceCode = context.getSourceCode();
24
-
25
- // Rule C005 - Each function should do one thing
26
- const validationDetector = createValidationDetector(context);
27
- const userInputDetector = createUserInputDetector();
28
- const htmlContextDetector = createHtmlContextDetector(context);
29
- const jsonParseChecker = createJsonParseChecker(context, userInputDetector, validationDetector);
30
- const jsonStringifyChecker = createJsonStringifyChecker(context, htmlContextDetector);
31
- const evalChecker = createEvalChecker(context);
32
- const templateChecker = createTemplateChecker(context, userInputDetector, htmlContextDetector);
33
-
34
- return {
35
- CallExpression(node) {
36
- jsonParseChecker.checkNode(node);
37
- jsonStringifyChecker.checkNode(node);
38
- evalChecker.checkNode(node);
39
- },
40
- TemplateLiteral(node) {
41
- templateChecker.checkNode(node);
42
- }
43
- };
44
- }
45
- };
46
-
47
- // Rule C006 - Function names should be verb/verb-noun
48
- // Rule C031 - Validation logic must be separate
49
- function createValidationDetector(context) {
50
- const sourceCode = context.getSourceCode();
51
-
52
- return {
53
- hasValidationContext(node) {
54
- return detectTryCatchContext(node) || detectValidationStatements(node, sourceCode);
55
- }
56
- };
57
- }
58
-
59
- function detectTryCatchContext(node) {
60
- let parent = node.parent;
61
- while (parent) {
62
- if (parent.type === 'TryStatement') {
63
- return true;
64
- }
65
- parent = parent.parent;
66
- }
67
- return false;
68
- }
69
-
70
- function detectValidationStatements(node, sourceCode) {
71
- let parent = node.parent;
72
- let current = node;
73
-
74
- while (parent) {
75
- if (parent.type === 'BlockStatement') {
76
- const statements = parent.body;
77
- const currentIndex = statements.indexOf(current);
78
-
79
- for (let i = 0; i < currentIndex; i++) {
80
- const stmt = statements[i];
81
- const stmtText = sourceCode.getText(stmt);
82
-
83
- if (containsValidationPattern(stmtText)) {
84
- return true;
85
- }
86
- }
87
- }
88
-
89
- current = parent;
90
- parent = parent.parent;
91
- }
92
-
93
- return false;
94
- }
95
-
96
- function containsValidationPattern(text) {
97
- const validationPatterns = ['validate', 'typeof', 'length', 'isValid'];
98
- return validationPatterns.some(pattern => text.includes(pattern));
99
- }
100
-
101
- // Rule C015 - Use domain language in class/function names
102
- function createUserInputDetector() {
103
- const userInputPatterns = [
104
- /req\.(body|query|params)/,
105
- /request\.(body|query|params)/,
106
- /localStorage\.getItem/,
107
- /sessionStorage\.getItem/,
108
- /window\.location/,
109
- /location\.(search|hash)/,
110
- /URLSearchParams/
111
- ];
112
-
113
- return {
114
- isUserInput(node, sourceCode) {
115
- if (!node) return false;
116
- const text = sourceCode.getText(node);
117
- return userInputPatterns.some(pattern => pattern.test(text));
118
- }
119
- };
120
- }
121
-
122
- function createHtmlContextDetector(context) {
123
- const htmlContextMethods = ['innerHTML', 'outerHTML', 'insertAdjacentHTML'];
124
-
125
- return {
126
- isInHtmlContext(node) {
127
- return detectHtmlAssignment(node, htmlContextMethods) ||
128
- detectDocumentWrite(node) ||
129
- detectHtmlTemplate(node, htmlContextMethods);
130
- }
131
- };
132
- }
133
-
134
- function detectHtmlAssignment(node, htmlContextMethods) {
135
- let parent = node.parent;
136
-
137
- while (parent) {
138
- if (parent.type === 'AssignmentExpression' &&
139
- parent.left.type === 'MemberExpression' &&
140
- htmlContextMethods.includes(parent.left.property.name)) {
141
- return true;
142
- }
143
- parent = parent.parent;
144
- }
145
- return false;
146
- }
147
-
148
- function detectDocumentWrite(node) {
149
- let parent = node.parent;
150
-
151
- while (parent) {
152
- if (parent.type === 'CallExpression' &&
153
- parent.callee.type === 'MemberExpression' &&
154
- parent.callee.object.name === 'document' &&
155
- parent.callee.property.name === 'write') {
156
- return true;
157
- }
158
- parent = parent.parent;
159
- }
160
- return false;
161
- }
162
-
163
- function detectHtmlTemplate(node, htmlContextMethods) {
164
- let parent = node.parent;
165
-
166
- while (parent) {
167
- if (parent.type === 'TemplateLiteral' &&
168
- parent.parent &&
169
- parent.parent.type === 'AssignmentExpression' &&
170
- parent.parent.left.type === 'MemberExpression' &&
171
- htmlContextMethods.includes(parent.parent.left.property.name)) {
172
- return true;
173
- }
174
- parent = parent.parent;
175
- }
176
- return false;
177
- }
178
-
179
- // Rule C012 - Separate Command and Query: Clear single responsibility and side-effects
180
- function createJsonParseChecker(context, userInputDetector, validationDetector) {
181
- const sourceCode = context.getSourceCode();
182
-
183
- return {
184
- checkNode(node) {
185
- if (isJsonParseCall(node)) {
186
- const argument = node.arguments[0];
187
- if (argument && userInputDetector.isUserInput(argument, sourceCode)) {
188
- if (!validationDetector.hasValidationContext(node)) {
189
- reportUnsafeJsonParse(context, node);
190
- }
191
- }
192
- }
193
- }
194
- };
195
- }
196
-
197
- function isJsonParseCall(node) {
198
- return node.type === 'CallExpression' &&
199
- node.callee.type === 'MemberExpression' &&
200
- node.callee.object.name === 'JSON' &&
201
- node.callee.property.name === 'parse';
202
- }
203
-
204
- function reportUnsafeJsonParse(context, node) {
205
- context.report({
206
- node,
207
- messageId: "unsafeJsonParse"
208
- });
209
- }
210
-
211
- function createJsonStringifyChecker(context, htmlContextDetector) {
212
- return {
213
- checkNode(node) {
214
- if (isJsonStringifyCall(node)) {
215
- if (htmlContextDetector.isInHtmlContext(node)) {
216
- reportJsonStringifyInHtml(context, node);
217
- }
218
- }
219
- }
220
- };
221
- }
222
-
223
- function isJsonStringifyCall(node) {
224
- return node.type === 'CallExpression' &&
225
- node.callee.type === 'MemberExpression' &&
226
- node.callee.object.name === 'JSON' &&
227
- node.callee.property.name === 'stringify';
228
- }
229
-
230
- function reportJsonStringifyInHtml(context, node) {
231
- context.report({
232
- node,
233
- messageId: "jsonStringifyInHtml"
234
- });
235
- }
236
-
237
- function createEvalChecker(context) {
238
- const sourceCode = context.getSourceCode();
239
-
240
- return {
241
- checkNode(node) {
242
- if (isEvalCall(node)) {
243
- const argument = node.arguments[0];
244
- if (argument && containsJsonPattern(argument, sourceCode)) {
245
- reportEvalWithJson(context, node);
246
- }
247
- }
248
- }
249
- };
250
- }
251
-
252
- function isEvalCall(node) {
253
- return node.type === 'CallExpression' && node.callee.name === 'eval';
254
- }
255
-
256
- function containsJsonPattern(argument, sourceCode) {
257
- const text = sourceCode.getText(argument);
258
- const jsonPatterns = ['JSON', 'userJson', 'req.', 'request.'];
259
- return jsonPatterns.some(pattern => text.includes(pattern));
260
- }
261
-
262
- function reportEvalWithJson(context, node) {
263
- context.report({
264
- node,
265
- messageId: "noEvalJson"
266
- });
267
- }
268
-
269
- function createTemplateChecker(context, userInputDetector, htmlContextDetector) {
270
- const sourceCode = context.getSourceCode();
271
-
272
- return {
273
- checkNode(node) {
274
- if (node.type === 'TemplateLiteral') {
275
- const hasUserInput = node.expressions.some(expr =>
276
- userInputDetector.isUserInput(expr, sourceCode)
277
- );
278
-
279
- if (hasUserInput && isUnsafeHtmlTemplate(node, sourceCode, htmlContextDetector)) {
280
- reportUnsafeTemplate(context, node);
281
- }
282
- }
283
- }
284
- };
285
- }
286
-
287
- function isUnsafeHtmlTemplate(node, sourceCode, htmlContextDetector) {
288
- const text = sourceCode.getText(node);
289
- const htmlPatterns = ['<script>', '<div>', 'innerHTML'];
290
-
291
- return htmlPatterns.some(pattern => text.includes(pattern)) ||
292
- htmlContextDetector.isInHtmlContext(node);
293
- }
294
-
295
- function reportUnsafeTemplate(context, node) {
296
- context.report({
297
- node,
298
- messageId: "unsafeTemplateString"
299
- });
300
- }
@@ -1,217 +0,0 @@
1
- /**
2
- * Custom ESLint rule for: S025 – Server-side input validation required
3
- * Rule ID: custom/s025
4
- * Purpose: Verify that input validation is enforced on a trusted service layer
5
- * Target: NestJS applications - ensure all client input is validated server-side before processing
6
- */
7
-
8
- "use strict";
9
-
10
- module.exports = {
11
- meta: {
12
- type: "problem",
13
- docs: {
14
- description:
15
- "Ensure all client input is validated on server-side before processing in NestJS applications",
16
- recommended: true,
17
- },
18
- schema: [],
19
- messages: {
20
- missingValidationDecorator:
21
- "Controller method parameter '{{param}}' should use validation decorators (@Body, @Query, @Param with DTO class).",
22
- missingValidationPipe:
23
- "Controller method '{{method}}' should use ValidationPipe to validate input data.",
24
- missingDtoValidation:
25
- "DTO class '{{dto}}' should have validation decorators (@IsString, @IsNumber, etc.) for its properties.",
26
- directInputAccess:
27
- "Direct access to request object '{{access}}' without validation. Use validated DTOs instead.",
28
- },
29
- },
30
-
31
- create(context) {
32
- const validatedParams = new Set();
33
- const controllerMethods = new Set();
34
- const dtoClasses = new Map();
35
- const validationDecorators = new Set([
36
- 'IsString', 'IsNumber', 'IsBoolean', 'IsArray', 'IsObject', 'IsEmail',
37
- 'IsUrl', 'IsUUID', 'IsOptional', 'IsNotEmpty', 'Length', 'Min', 'Max',
38
- 'IsPositive', 'IsNegative', 'IsDate', 'IsEnum', 'ValidateNested',
39
- 'IsInt', 'IsDecimal', 'IsJSON', 'Matches', 'Contains', 'IsAlpha',
40
- 'IsAlphanumeric', 'IsPhoneNumber', 'IsISO8601', 'IsBase64'
41
- ]);
42
-
43
- function hasValidationDecorator(decorators) {
44
- if (!decorators) return false;
45
- return decorators.some(decorator => {
46
- if (decorator.expression && decorator.expression.callee) {
47
- const name = decorator.expression.callee.name;
48
- return validationDecorators.has(name);
49
- }
50
- return false;
51
- });
52
- }
53
-
54
- function isNestJSController(node) {
55
- if (!node.decorators) return false;
56
- return node.decorators.some(decorator => {
57
- if (decorator.expression && decorator.expression.callee) {
58
- return decorator.expression.callee.name === 'Controller';
59
- }
60
- return false;
61
- });
62
- }
63
-
64
- function isControllerMethod(node) {
65
- if (!node.decorators) return false;
66
- const httpDecorators = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Head', 'Options'];
67
- return node.decorators.some(decorator => {
68
- if (decorator.expression && decorator.expression.callee) {
69
- return httpDecorators.includes(decorator.expression.callee.name);
70
- }
71
- return false;
72
- });
73
- }
74
-
75
- function hasNestJSValidationDecorator(param) {
76
- if (!param.decorators) return false;
77
- const nestValidationDecorators = ['Body', 'Query', 'Param', 'Headers'];
78
- return param.decorators.some(decorator => {
79
- if (decorator.expression && decorator.expression.callee) {
80
- return nestValidationDecorators.includes(decorator.expression.callee.name);
81
- }
82
- return false;
83
- });
84
- }
85
-
86
- function hasValidationPipe(node) {
87
- if (!node.decorators) return false;
88
- return node.decorators.some(decorator => {
89
- if (decorator.expression && decorator.expression.callee) {
90
- if (decorator.expression.callee.name === 'UsePipes') {
91
- return decorator.expression.arguments.some(arg => {
92
- return arg.type === 'NewExpression' &&
93
- arg.callee &&
94
- arg.callee.name === 'ValidationPipe';
95
- });
96
- }
97
- }
98
- return false;
99
- });
100
- }
101
-
102
- return {
103
- // Check DTO classes for validation decorators
104
- ClassDeclaration(node) {
105
- if (node.id && node.id.name.endsWith('Dto')) {
106
- const className = node.id.name;
107
- const properties = [];
108
-
109
- node.body.body.forEach(member => {
110
- if (member.type === 'PropertyDefinition' && member.key) {
111
- const hasValidation = hasValidationDecorator(member.decorators);
112
- properties.push({
113
- name: member.key.name,
114
- hasValidation
115
- });
116
- }
117
- });
118
-
119
- dtoClasses.set(className, properties);
120
-
121
- // Check if DTO has at least one validation decorator
122
- const hasAnyValidation = properties.some(prop => prop.hasValidation);
123
- if (properties.length > 0 && !hasAnyValidation) {
124
- context.report({
125
- node,
126
- messageId: "missingDtoValidation",
127
- data: {
128
- dto: className,
129
- },
130
- });
131
- }
132
- }
133
- },
134
-
135
- // Check controller methods
136
- MethodDefinition(node) {
137
- const parentClass = node.parent.parent;
138
- if (isNestJSController(parentClass) && isControllerMethod(node)) {
139
- const methodName = node.key.name;
140
- controllerMethods.add(methodName);
141
-
142
- // Check if method has ValidationPipe
143
- const hasValidationPipeDecorator = hasValidationPipe(node);
144
-
145
- // Check parameters for validation decorators
146
- if (node.value.params) {
147
- node.value.params.forEach(param => {
148
- if (param.type === 'Identifier') {
149
- const hasNestValidation = hasNestJSValidationDecorator(param);
150
-
151
- if (hasNestValidation) {
152
- validatedParams.add(param.name);
153
- } else {
154
- // If no ValidationPipe and no parameter validation decorator
155
- if (!hasValidationPipeDecorator) {
156
- context.report({
157
- node: param,
158
- messageId: "missingValidationDecorator",
159
- data: {
160
- param: param.name,
161
- },
162
- });
163
- }
164
- }
165
- }
166
- });
167
- }
168
-
169
- // Check if method uses ValidationPipe when dealing with request bodies
170
- const hasBodyParam = node.value.params.some(param =>
171
- param.decorators && param.decorators.some(decorator =>
172
- decorator.expression &&
173
- decorator.expression.callee &&
174
- decorator.expression.callee.name === 'Body'
175
- )
176
- );
177
-
178
- if (hasBodyParam && !hasValidationPipeDecorator) {
179
- context.report({
180
- node,
181
- messageId: "missingValidationPipe",
182
- data: {
183
- method: methodName,
184
- },
185
- });
186
- }
187
- }
188
- },
189
-
190
- // Check for direct access to request object without validation
191
- MemberExpression(node) {
192
- if (node.object && node.property) {
193
- const objectName = node.object.name;
194
- const propertyName = node.property.name;
195
-
196
- // Check for direct access to req.body, req.query, req.params without validation
197
- if (objectName === 'req' || objectName === 'request') {
198
- if (['body', 'query', 'params', 'headers'].includes(propertyName)) {
199
- const accessPath = `${objectName}.${propertyName}`;
200
-
201
- // Check if this access is in a validated context
202
- if (!validatedParams.has(objectName)) {
203
- context.report({
204
- node,
205
- messageId: "directInputAccess",
206
- data: {
207
- access: accessPath,
208
- },
209
- });
210
- }
211
- }
212
- }
213
- }
214
- },
215
- };
216
- },
217
- };
@@ -1,68 +0,0 @@
1
- /**
2
- * Custom ESLint rule for: S026 – JSON schema validation required for inputs
3
- * Rule ID: custom/s026
4
- * Purpose: Ensure that all input JSON is validated against a schema
5
- */
6
-
7
- "use strict";
8
-
9
- module.exports = {
10
- meta: {
11
- type: "problem",
12
- docs: {
13
- description:
14
- "Ensure JSON schema validation is in place for input objects",
15
- recommended: false,
16
- },
17
- schema: [],
18
- messages: {
19
- missingValidation:
20
- "JSON input '{{input}}' should be validated using a JSON schema before use.",
21
- },
22
- },
23
-
24
- create(context) {
25
- let validatedInputs = new Set();
26
-
27
- return {
28
- CallExpression(node) {
29
- // Detect validation functions like schema.validate(req.body)
30
- if (
31
- node.callee &&
32
- node.callee.property &&
33
- node.arguments &&
34
- node.arguments.length > 0
35
- ) {
36
- const arg = node.arguments[0];
37
- if (
38
- arg.type === "MemberExpression" &&
39
- arg.object &&
40
- arg.property &&
41
- (arg.property.name === "body" || arg.property.name === "query")
42
- ) {
43
- const validatedInput = `${arg.object.name}.${arg.property.name}`;
44
- validatedInputs.add(validatedInput);
45
- }
46
- }
47
- },
48
-
49
- MemberExpression(node) {
50
- if (
51
- node.property &&
52
- (node.property.name === "body" || node.property.name === "query")
53
- ) {
54
- const fullInput = `${node.object.name}.${node.property.name}`;
55
- if (!validatedInputs.has(fullInput)) {
56
- context.report({
57
- node,
58
- messageId: "missingValidation",
59
- data: {
60
- input: fullInput,
61
- },
62
- });
63
- }
64
- }
65
- },
66
- };
67
- },
68
- };
@@ -1,80 +0,0 @@
1
- /**
2
- * Custom ESLint rule for: S027 – No hardcoded secrets
3
- * Rule ID: custom/s027
4
- * Purpose: Prevent passwords, API keys, secrets from being hardcoded
5
- */
6
-
7
- "use strict";
8
-
9
- const sensitiveKeywords = [
10
- "password",
11
- "pass",
12
- "pwd",
13
- "secret",
14
- "apiKey",
15
- "token",
16
- "auth",
17
- "key",
18
- "seed",
19
- ];
20
-
21
- module.exports = {
22
- meta: {
23
- type: "problem",
24
- docs: {
25
- description: "Prevent hardcoded passwords, API keys, and secrets",
26
- recommended: true,
27
- },
28
- schema: [],
29
- messages: {
30
- hardcodedSecret:
31
- "Avoid hardcoding sensitive information such as '{{name}}'. Use secure storage instead.",
32
- },
33
- },
34
-
35
- create(context) {
36
- function isSensitiveName(name) {
37
- const lower = name.toLowerCase();
38
- return sensitiveKeywords.some((keyword) => lower.includes(keyword));
39
- }
40
-
41
- return {
42
- VariableDeclarator(node) {
43
- if (
44
- node.id &&
45
- node.init &&
46
- (node.init.type === "Literal" || node.init.type === "TemplateLiteral")
47
- ) {
48
- const name =
49
- node.id.name || (node.id.property && node.id.property.name);
50
- if (name && isSensitiveName(name)) {
51
- context.report({
52
- node,
53
- messageId: "hardcodedSecret",
54
- data: { name },
55
- });
56
- }
57
- }
58
- },
59
-
60
- AssignmentExpression(node) {
61
- if (
62
- node.left &&
63
- node.right &&
64
- (node.right.type === "Literal" ||
65
- node.right.type === "TemplateLiteral")
66
- ) {
67
- const name =
68
- node.left.name || (node.left.property && node.left.property.name);
69
- if (name && isSensitiveName(name)) {
70
- context.report({
71
- node,
72
- messageId: "hardcodedSecret",
73
- data: { name },
74
- });
75
- }
76
- }
77
- },
78
- };
79
- },
80
- };