@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.
- package/.sunlint.json +35 -0
- package/CHANGELOG.md +135 -169
- package/CONTRIBUTING.md +235 -0
- package/PROJECT_STRUCTURE.md +60 -0
- package/README.md +77 -50
- package/cli.js +1 -0
- package/config/README.md +88 -0
- package/config/defaults/ai-rules-context.json +231 -0
- package/config/engines/engines.json +49 -0
- package/config/engines/eslint-rule-mapping.json +74 -0
- package/config/eslint-rule-mapping.json +126 -0
- package/config/{typescript/eslint.config.js → integrations/eslint/typescript.config.js} +4 -0
- package/config/presets/beginner.json +1 -1
- package/config/presets/ci.json +3 -2
- package/config/presets/recommended.json +1 -1
- package/config/presets/strict.json +2 -2
- package/config/rule-analysis-strategies.js +74 -0
- package/config/{rules-registry.json → rules/rules-registry.json} +82 -0
- package/core/analysis-orchestrator.js +383 -591
- package/core/ast-modules/README.md +103 -0
- package/core/ast-modules/base-parser.js +90 -0
- package/core/ast-modules/index.js +97 -0
- package/core/ast-modules/package.json +37 -0
- package/core/ast-modules/parsers/eslint-js-parser.js +147 -0
- package/core/ast-modules/parsers/eslint-ts-parser.js +106 -0
- package/core/ast-modules/parsers/javascript-parser.js +187 -0
- package/core/ast-modules/parsers/typescript-parser.js +187 -0
- package/core/cli-action-handler.js +271 -255
- package/core/cli-program.js +18 -4
- package/core/config-manager.js +18 -11
- package/core/config-merger.js +52 -1
- package/core/config-validator.js +2 -2
- package/core/enhanced-rules-registry.js +331 -0
- package/core/file-targeting-service.js +93 -29
- package/core/interfaces/analysis-engine.interface.js +100 -0
- package/core/multi-rule-runner.js +0 -221
- package/core/output-service.js +1 -1
- package/core/rule-mapping-service.js +9 -1
- package/core/rule-selection-service.js +10 -2
- package/docs/CONFIGURATION.md +414 -0
- package/docs/DEPLOYMENT-STRATEGIES.md +270 -0
- package/engines/eslint-engine.js +601 -0
- package/engines/heuristic-engine.js +860 -0
- package/engines/openai-engine.js +374 -0
- package/integrations/eslint/README.md +99 -0
- package/{eslint-integration → integrations/eslint/configs}/.eslintrc.js +1 -1
- package/integrations/eslint/configs/eslint.config.js +133 -0
- package/integrations/eslint/configs/eslint.config.simple.js +24 -0
- package/integrations/eslint/plugin/index.js +164 -0
- package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c006-function-name-verb-noun.js +11 -2
- package/integrations/eslint/plugin/rules/common/c013-no-dead-code.js +78 -0
- package/integrations/eslint/plugin/rules/common/c017-limit-constructor-logic.js +146 -0
- package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c029-catch-block-logging.js +35 -0
- package/integrations/eslint/plugin/rules/common/c035-no-empty-catch.js +162 -0
- package/integrations/eslint/plugin/rules/common/c041-no-config-inline.js +122 -0
- package/integrations/eslint/plugin/rules/common/c072-one-assert-per-test.js +184 -0
- package/integrations/eslint/plugin/rules/common/c075-explicit-function-return-types.js +168 -0
- package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +254 -0
- package/integrations/eslint/plugin/rules/security/s001-fail-securely.js +381 -0
- package/integrations/eslint/plugin/rules/security/s002-idor-check.js +945 -0
- package/integrations/eslint/plugin/rules/security/s007-no-plaintext-otp.js +74 -0
- package/integrations/eslint/plugin/rules/security/s013-verify-tls-connection.js +47 -0
- package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t003-ts-ignore-reason.js +3 -3
- package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t007-no-fn-in-constructor.js +1 -1
- package/integrations/eslint/plugin/rules/typescript/t019-no-this-assign.js +81 -0
- package/integrations/eslint/plugin/rules/typescript/t020-no-default-multi-export.js +127 -0
- package/integrations/eslint/plugin/rules/typescript/t021-limit-nested-generics.js +150 -0
- package/integrations/eslint/test-c041-rule.js +87 -0
- package/package.json +29 -19
- package/rules/README.md +252 -0
- package/rules/common/C002_no_duplicate_code/analyzer.js +65 -0
- package/rules/common/C002_no_duplicate_code/config.json +23 -0
- package/rules/common/C003_no_vague_abbreviations/analyzer.js +418 -0
- package/rules/common/C003_no_vague_abbreviations/config.json +35 -0
- package/rules/{C006_function_naming → common/C006_function_naming}/analyzer.js +13 -2
- package/rules/common/C010_limit_block_nesting/analyzer.js +389 -0
- package/rules/common/C013_no_dead_code/analyzer.js +206 -0
- package/rules/common/C014_dependency_injection/analyzer.js +338 -0
- package/rules/common/C017_constructor_logic/analyzer.js +314 -0
- package/rules/{C019_log_level_usage → common/C019_log_level_usage}/analyzer.js +5 -2
- package/rules/{C029_catch_block_logging → common/C029_catch_block_logging}/analyzer.js +49 -15
- package/rules/common/C041_no_sensitive_hardcode/analyzer.js +292 -0
- package/rules/common/C042_boolean_name_prefix/analyzer.js +300 -0
- package/rules/common/C043_no_console_or_print/analyzer.js +304 -0
- package/rules/common/C047_no_duplicate_retry_logic/analyzer.js +351 -0
- package/rules/common/C075_explicit_return_types/analyzer.js +103 -0
- package/rules/common/C076_single_test_behavior/analyzer.js +121 -0
- package/rules/docs/C002_no_duplicate_code.md +57 -0
- package/rules/index.js +149 -0
- package/rules/migration/converter.js +385 -0
- package/rules/migration/mapping.json +164 -0
- package/rules/security/S026_json_schema_validation/analyzer.js +251 -0
- package/rules/security/S026_json_schema_validation/config.json +27 -0
- package/rules/security/S027_no_hardcoded_secrets/analyzer.js +263 -0
- package/rules/security/S027_no_hardcoded_secrets/config.json +29 -0
- package/rules/security/S029_csrf_protection/analyzer.js +264 -0
- package/rules/tests/C002_no_duplicate_code.test.js +50 -0
- package/rules/utils/ast-utils.js +191 -0
- package/rules/utils/base-analyzer.js +98 -0
- package/rules/utils/pattern-matchers.js +239 -0
- package/rules/utils/rule-helpers.js +264 -0
- package/rules/utils/severity-constants.js +93 -0
- package/scripts/build-release.sh +117 -0
- package/scripts/ci-report.js +179 -0
- package/scripts/install.sh +196 -0
- package/scripts/manual-release.sh +338 -0
- package/scripts/merge-reports.js +424 -0
- package/scripts/pre-release-test.sh +175 -0
- package/scripts/prepare-release.sh +202 -0
- package/scripts/setup-github-registry.sh +42 -0
- package/scripts/test-scripts/README.md +22 -0
- package/scripts/test-scripts/test-c041-comparison.js +114 -0
- package/scripts/test-scripts/test-c041-eslint.js +67 -0
- package/scripts/test-scripts/test-eslint-rules.js +146 -0
- package/scripts/test-scripts/test-real-world.js +44 -0
- package/scripts/test-scripts/test-rules-on-real-projects.js +86 -0
- package/scripts/trigger-release.sh +285 -0
- package/scripts/validate-rule-structure.js +148 -0
- package/scripts/verify-install.sh +82 -0
- package/cli-legacy.js +0 -355
- package/config/sunlint-schema.json +0 -166
- package/config/typescript/custom-rules-new.js +0 -0
- package/config/typescript/custom-rules.js +0 -9
- package/config/typescript/package-lock.json +0 -1585
- package/config/typescript/package.json +0 -13
- package/config/typescript/security-rules/index.js +0 -90
- package/config/typescript/security-rules/s005-no-origin-auth.js +0 -95
- package/config/typescript/security-rules/s006-activation-recovery-secret-not-plaintext.js +0 -69
- package/config/typescript/security-rules/s008-crypto-agility.js +0 -62
- package/config/typescript/security-rules/s009-no-insecure-crypto.js +0 -103
- package/config/typescript/security-rules/s010-no-insecure-random-in-sensitive-context.js +0 -123
- package/config/typescript/security-rules/s011-no-insecure-uuid.js +0 -66
- package/config/typescript/security-rules/s012-hardcode-secret.js +0 -71
- package/config/typescript/security-rules/s014-insecure-tls-version.js +0 -50
- package/config/typescript/security-rules/s015-insecure-tls-certificate.js +0 -43
- package/config/typescript/security-rules/s016-sensitive-query-parameter.js +0 -59
- package/config/typescript/security-rules/s017-no-sql-injection.js +0 -193
- package/config/typescript/security-rules/s018-positive-input-validation.js +0 -56
- package/config/typescript/security-rules/s019-no-raw-user-input-in-email.js +0 -113
- package/config/typescript/security-rules/s020-no-eval-dynamic-execution.js +0 -89
- package/config/typescript/security-rules/s022-output-encoding.js +0 -78
- package/config/typescript/security-rules/s023-no-json-injection.js +0 -300
- package/config/typescript/security-rules/s025-server-side-input-validation.js +0 -217
- package/config/typescript/security-rules/s026-json-schema-validation.js +0 -68
- package/config/typescript/security-rules/s027-no-hardcoded-secrets.js +0 -80
- package/config/typescript/security-rules/s029-require-csrf-protection.js +0 -79
- package/config/typescript/security-rules/s030-no-directory-browsing.js +0 -78
- package/config/typescript/security-rules/s033-require-samesite-cookie.js +0 -80
- package/config/typescript/security-rules/s034-require-host-cookie-prefix.js +0 -77
- package/config/typescript/security-rules/s035-cookie-specific-path.js +0 -74
- package/config/typescript/security-rules/s036-no-unsafe-file-include.js +0 -68
- package/config/typescript/security-rules/s037-require-anti-cache-headers.js +0 -70
- package/config/typescript/security-rules/s038-no-version-disclosure.js +0 -74
- package/config/typescript/security-rules/s039-no-session-token-in-url.js +0 -63
- package/config/typescript/security-rules/s041-require-session-invalidate-on-logout.js +0 -211
- package/config/typescript/security-rules/s042-require-periodic-reauthentication.js +0 -294
- package/config/typescript/security-rules/s043-terminate-sessions-on-password-change.js +0 -254
- package/config/typescript/security-rules/s044-require-full-session-for-sensitive-operations.js +0 -292
- package/config/typescript/security-rules/s045-anti-automation-controls.js +0 -46
- package/config/typescript/security-rules/s046-secure-notification-on-auth-change.js +0 -44
- package/config/typescript/security-rules/s048-password-credential-recovery.js +0 -54
- package/config/typescript/security-rules/s050-session-token-weak-hash.js +0 -94
- package/config/typescript/security-rules/s052-secure-random-authentication-code.js +0 -66
- package/config/typescript/security-rules/s054-verification-default-account.js +0 -109
- package/config/typescript/security-rules/s057-utc-logging.js +0 -54
- package/config/typescript/security-rules/s058-no-ssrf.js +0 -73
- package/config/typescript/tsconfig.json +0 -29
- package/core/ai-analyzer.js +0 -169
- package/core/eslint-engine-service.js +0 -312
- package/core/eslint-instance-manager.js +0 -104
- package/core/eslint-integration-service.js +0 -363
- package/core/sunlint-engine-service.js +0 -23
- package/core/typescript-analyzer.js +0 -262
- package/core/typescript-engine.js +0 -313
- package/docs/ENHANCED_FILE_TARGETING.md +0 -0
- package/docs/FILE_TARGETING_COMPARISON.md +0 -0
- package/docs/RULE-RESPONSIBILITY-MATRIX.md +0 -204
- package/eslint-integration/cli.js +0 -35
- package/eslint-integration/eslint-plugin-custom/c013-no-dead-code.js +0 -43
- package/eslint-integration/eslint-plugin-custom/c017-limit-constructor-logic.js +0 -39
- package/eslint-integration/eslint-plugin-custom/c027-limit-function-nesting.js +0 -50
- package/eslint-integration/eslint-plugin-custom/c034-no-implicit-return.js +0 -34
- package/eslint-integration/eslint-plugin-custom/c035-no-empty-catch.js +0 -32
- package/eslint-integration/eslint-plugin-custom/c041-no-config-inline.js +0 -64
- package/eslint-integration/eslint-plugin-custom/c048-no-var-declaration.js +0 -31
- package/eslint-integration/eslint-plugin-custom/index.js +0 -155
- package/eslint-integration/eslint-plugin-custom/package.json.bak +0 -9
- package/eslint-integration/eslint-plugin-custom/t004-interface-public-only.js +0 -160
- package/eslint-integration/eslint-plugin-custom/t011-no-real-time-dependency.js +0 -175
- package/eslint-integration/eslint-plugin-custom/t026-limit-nested-generics.js +0 -377
- package/eslint-integration/sample.ts +0 -53
- package/eslint-integration/test-s003.js +0 -5
- package/examples/.github/workflows/code-quality.yml +0 -111
- package/examples/README.md +0 -69
- package/examples/basic-typescript-demo/.eslintrc.json +0 -18
- package/examples/basic-typescript-demo/.next/cache/eslint/.cache_1othrmo +0 -1
- package/examples/basic-typescript-demo/.sunlint.json +0 -29
- package/examples/basic-typescript-demo/eslint.config.mjs +0 -37
- package/examples/basic-typescript-demo/next-env.d.ts +0 -5
- package/examples/basic-typescript-demo/next.config.mjs +0 -4
- package/examples/basic-typescript-demo/package-lock.json +0 -5656
- package/examples/basic-typescript-demo/package.json +0 -34
- package/examples/basic-typescript-demo/src/app/layout.tsx +0 -18
- package/examples/basic-typescript-demo/src/app/page.tsx +0 -48
- package/examples/basic-typescript-demo/src/config.ts +0 -14
- package/examples/basic-typescript-demo/src/good-practices.ts +0 -58
- package/examples/basic-typescript-demo/src/types.generated.ts +0 -13
- package/examples/basic-typescript-demo/src/user.test.ts +0 -19
- package/examples/basic-typescript-demo/src/violations.ts +0 -61
- package/examples/basic-typescript-demo/tsconfig.json +0 -27
- package/examples/eslint-integration-demo/.eslintrc.js +0 -38
- package/examples/eslint-integration-demo/.sunlint.json +0 -42
- package/examples/eslint-integration-demo/next-env.d.ts +0 -5
- package/examples/eslint-integration-demo/next.config.js +0 -8
- package/examples/eslint-integration-demo/package-lock.json +0 -5740
- package/examples/eslint-integration-demo/package.json +0 -37
- package/examples/eslint-integration-demo/src/api.test.ts +0 -20
- package/examples/eslint-integration-demo/src/conflict-test.tsx +0 -44
- package/examples/eslint-integration-demo/src/naming-conflicts.ts +0 -50
- package/examples/eslint-integration-demo/tsconfig.json +0 -26
- package/examples/file-targeting-demo/global.d.ts +0 -11
- package/examples/file-targeting-demo/jest.config.js +0 -8
- package/examples/file-targeting-demo/sample.ts +0 -53
- package/examples/file-targeting-demo/src/server.js +0 -11
- package/examples/file-targeting-demo/src/server.test.js +0 -11
- package/examples/file-targeting-demo/src/types.d.ts +0 -4
- package/examples/file-targeting-demo/src/types.generated.ts +0 -10
- package/examples/file-targeting-demo/user-service.test.ts +0 -15
- package/examples/file-targeting-demo/user-service.ts +0 -13
- package/examples/file-targeting-demo/utils.js +0 -15
- package/examples/multi-language-project/.eslintrc.json +0 -38
- package/examples/multi-language-project/package.json +0 -37
- package/examples/multi-language-project/src/sample.ts +0 -39
- package/examples/rule-test-fixtures/README.md +0 -67
- package/examples/rule-test-fixtures/rules/C006_function_naming/clean/typescript-clean.ts +0 -64
- package/examples/rule-test-fixtures/rules/C006_function_naming/violations/dart-violations.dart +0 -56
- package/examples/rule-test-fixtures/rules/C006_function_naming/violations/typescript-violations.ts +0 -47
- package/examples/rule-test-fixtures/rules/C019_log_level_usage/clean/typescript-clean.ts +0 -93
- package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/dart-violations.dart +0 -75
- package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/typescript-violations.ts +0 -84
- package/examples/rule-test-fixtures/rules/C029_catch_block_logging/violations/typescript-violations.ts +0 -37
- /package/config/{default.json → defaults/default.json} +0 -0
- /package/{eslint-integration/eslint.config.js → config/integrations/eslint/base.config.js} +0 -0
- /package/{eslint-integration/eslint.config.simple.js → config/integrations/eslint/simple.config.js} +0 -0
- /package/{examples/rule-test-fixtures/rules/C029_catch_block_logging/clean/typescript-clean.ts → config/schemas/sunlint-schema.json} +0 -0
- /package/config/{typescript → testing}/test-s005-working.ts +0 -0
- /package/{examples/eslint-integration-demo/test-file-targeting.sh → engines/tree-sitter-parser.js} +0 -0
- /package/{examples/enhanced-config.json → engines/universal-ast-engine.js} +0 -0
- /package/{eslint-integration → integrations/eslint}/package.json +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin}/package.json +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c002-no-duplicate-code.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c003-no-vague-abbreviations.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c010-limit-block-nesting.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c014-abstract-dependency-preferred.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c018-no-generic-throw.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c023-no-duplicate-variable-name-in-scope.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c030-use-custom-error-classes.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c042-boolean-name-prefix.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c043-no-console-or-print.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/common}/c047-no-duplicate-retry-logic.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s003-no-unvalidated-redirect.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s005-no-origin-auth.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s006-activation-recovery-secret-not-plaintext.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s008-crypto-agility.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s009-no-insecure-crypto.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s010-no-insecure-random-in-sensitive-context.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s011-no-insecure-uuid.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s012-hardcode-secret.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s014-insecure-tls-version.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s015-insecure-tls-certificate.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s016-sensitive-query-parameter.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s017-no-sql-injection.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s018-positive-input-validation.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s019-no-raw-user-input-in-email.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s020-no-eval-dynamic-execution.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s022-output-encoding.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s023-no-json-injection.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s025-server-side-input-validation.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s026-json-schema-validation.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s027-no-hardcoded-secrets.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s029-require-csrf-protection.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s030-no-directory-browsing.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s033-require-samesite-cookie.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s034-require-host-cookie-prefix.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s035-cookie-specific-path.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s036-no-unsafe-file-include.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s037-require-anti-cache-headers.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s038-no-version-disclosure.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s039-no-session-token-in-url.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s041-require-session-invalidate-on-logout.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s042-require-periodic-reauthentication.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s043-terminate-sessions-on-password-change.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s044-require-full-session-for-sensitive-operations.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s045-anti-automation-controls.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s046-secure-notification-on-auth-change.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s047-secure-random-passwords.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s048-password-credential-recovery.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s050-session-token-weak-hash.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s052-secure-random-authentication-code.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s054-verification-default-account.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s055-verification-rest-check-the-incoming-content-type.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s057-utc-logging.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/security}/s058-no-ssrf.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom → integrations/eslint/plugin/rules/typescript}/t002-interface-prefix-i.js +0 -0
- /package/{eslint-integration/eslint-plugin-custom/t019-no-empty-type.js → integrations/eslint/plugin/rules/typescript/t004-no-empty-type.js} +0 -0
- /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
- /package/{eslint-integration → integrations/eslint}/tsconfig.json +0 -0
- /package/rules/{C006_function_naming → common/C006_function_naming}/config.json +0 -0
- /package/rules/{C019_log_level_usage → common/C019_log_level_usage}/config.json +0 -0
- /package/rules/{C029_catch_block_logging → common/C029_catch_block_logging}/config.json +0 -0
- /package/rules/{C031_validation_separation → common/C031_validation_separation}/analyzer.js +0 -0
- /package/rules/{C031_validation_separation/README.md → docs/C031_validation_separation.md} +0 -0
- /package/{examples/basic-typescript-demo/test-file-targeting.sh → rules/universal/C010/generic.js} +0 -0
- /package/{examples/basic-typescript-demo/test-config-priority.sh → rules/universal/C010/tree-sitter-analyzer.js} +0 -0
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TypeScript Engine - Main coordinator for TypeScript analysis
|
|
3
|
-
* Rule C005: Single responsibility - orchestrates TypeScript analysis
|
|
4
|
-
* Rule C012: Command Query Separation - separate analysis and result processing
|
|
5
|
-
* Rule C014: Dependency Injection - inject required services
|
|
6
|
-
* Rule C015: Domain language - TypeScriptEngine
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const fs = require('fs');
|
|
11
|
-
const chalk = require('chalk');
|
|
12
|
-
|
|
13
|
-
// Rule C014: Dependency injection
|
|
14
|
-
const EslintInstanceManager = require('./eslint-instance-manager');
|
|
15
|
-
const DependencyManager = require('./dependency-manager');
|
|
16
|
-
const TypescriptAnalyzer = require('./typescript-analyzer');
|
|
17
|
-
const RuleMappingService = require('./rule-mapping-service');
|
|
18
|
-
|
|
19
|
-
class TypeScriptEngine {
|
|
20
|
-
constructor(eslintModulePath = null) {
|
|
21
|
-
// Rule C014: Dependency injection instead of direct instantiation
|
|
22
|
-
this.eslintInstanceManager = new EslintInstanceManager();
|
|
23
|
-
this.dependencyManager = new DependencyManager();
|
|
24
|
-
this.typescriptAnalyzer = new TypescriptAnalyzer(this.eslintInstanceManager);
|
|
25
|
-
this.ruleMappingService = new RuleMappingService();
|
|
26
|
-
|
|
27
|
-
this.eslintModulePath = eslintModulePath;
|
|
28
|
-
this.isInitialized = false;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Rule C006: initializeEngine - verb-noun naming
|
|
33
|
-
* Rule C032: No external API calls in constructor - initialization method
|
|
34
|
-
*/
|
|
35
|
-
async initializeEngine() {
|
|
36
|
-
if (this.isInitialized) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Check dependencies first
|
|
41
|
-
const dependenciesAvailable = await this.dependencyManager.checkDependenciesAvailable();
|
|
42
|
-
if (!dependenciesAvailable.allAvailable) {
|
|
43
|
-
console.log(chalk.yellow('⚠️ Missing TypeScript dependencies. Attempting to install...'));
|
|
44
|
-
const installed = await this.dependencyManager.installMissingDependencies();
|
|
45
|
-
if (!installed) {
|
|
46
|
-
throw new Error('Required TypeScript dependencies are not available');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Initialize ESLint instance
|
|
51
|
-
await this.eslintInstanceManager.initializeEslintInstance(this.eslintModulePath);
|
|
52
|
-
|
|
53
|
-
this.isInitialized = true;
|
|
54
|
-
console.log(chalk.green('✅ TypeScript engine initialized successfully'));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Rule C006: runAnalysis - verb-noun naming
|
|
59
|
-
* Rule C005: Single responsibility - coordinates analysis
|
|
60
|
-
* Rule C012: Command method - performs analysis operation
|
|
61
|
-
*/
|
|
62
|
-
async runAnalysis(filePaths, options = {}) {
|
|
63
|
-
if (!this.isInitialized) {
|
|
64
|
-
await this.initializeEngine();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Validate input
|
|
68
|
-
if (!filePaths || filePaths.length === 0) {
|
|
69
|
-
throw new Error('No files provided for analysis');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const filePathsArray = Array.isArray(filePaths) ? filePaths : [filePaths];
|
|
73
|
-
|
|
74
|
-
if (options.verbose) {
|
|
75
|
-
console.log(chalk.blue(`🔄 Running TypeScript analysis on ${filePathsArray.length} files...`));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const results = await this.typescriptAnalyzer.analyzeTypeScriptFiles(filePathsArray, options);
|
|
80
|
-
|
|
81
|
-
if (options.verbose) {
|
|
82
|
-
this.logAnalysisResults(results);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return results;
|
|
86
|
-
} catch (error) {
|
|
87
|
-
// Rule C035: Log full error information
|
|
88
|
-
console.error(chalk.red('❌ TypeScript analysis failed:'), {
|
|
89
|
-
message: error.message,
|
|
90
|
-
files: filePathsArray.length,
|
|
91
|
-
configPath: this.eslintInstanceManager.getConfigPath()
|
|
92
|
-
});
|
|
93
|
-
throw error;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Rule C006: configureRules - verb-noun naming
|
|
99
|
-
* Rule C005: Single responsibility - rule configuration
|
|
100
|
-
*/
|
|
101
|
-
async configureRules(selectedRules = [], options = {}) {
|
|
102
|
-
if (!this.isInitialized) {
|
|
103
|
-
await this.initializeEngine();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const configPath = this.eslintInstanceManager.getConfigPath();
|
|
108
|
-
const configFilePath = path.join(configPath, 'eslint.config.js');
|
|
109
|
-
|
|
110
|
-
if (options.verbose) {
|
|
111
|
-
console.log(chalk.blue(` Config path: ${configFilePath}`));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Clear require cache to ensure fresh config
|
|
115
|
-
delete require.cache[require.resolve(configFilePath)];
|
|
116
|
-
|
|
117
|
-
// Read current config
|
|
118
|
-
const currentConfig = require(configFilePath);
|
|
119
|
-
|
|
120
|
-
// Convert SunLint rule IDs to ESLint rule names
|
|
121
|
-
const eslintRuleNames = selectedRules.map(sunlintRuleId => {
|
|
122
|
-
const eslintRule = this.ruleMappingService.sunlintToEslintMapping[sunlintRuleId];
|
|
123
|
-
return eslintRule || sunlintRuleId;
|
|
124
|
-
}).filter(rule => rule);
|
|
125
|
-
|
|
126
|
-
// Update rules based on selection
|
|
127
|
-
const updatedConfig = this.updateRulesConfiguration(currentConfig, eslintRuleNames, options);
|
|
128
|
-
|
|
129
|
-
if (options.verbose) {
|
|
130
|
-
console.log(chalk.blue(`🔧 Configured ${selectedRules.length} rules for analysis`));
|
|
131
|
-
console.log(chalk.gray(` SunLint rules: ${selectedRules.join(', ')}`));
|
|
132
|
-
console.log(chalk.gray(` ESLint rules: ${eslintRuleNames.join(', ')}`));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return updatedConfig;
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error(chalk.red('❌ Failed to configure rules:'), error.message);
|
|
138
|
-
throw error;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Rule C006: updateRulesConfiguration - verb-noun naming
|
|
144
|
-
* Rule C005: Single responsibility - update config
|
|
145
|
-
* Rule C012: Pure function - no side effects
|
|
146
|
-
*/
|
|
147
|
-
updateRulesConfiguration(currentConfig, selectedRules, options) {
|
|
148
|
-
if (!Array.isArray(currentConfig)) {
|
|
149
|
-
throw new Error('Expected flat config array format');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Create new config with selected rules
|
|
153
|
-
const updatedConfig = currentConfig.map(config => {
|
|
154
|
-
if (config.rules) {
|
|
155
|
-
if (options.verbose) {
|
|
156
|
-
const ruleKeys = Object.keys(config.rules);
|
|
157
|
-
console.log(chalk.blue(` Config has ${ruleKeys.length} rules`));
|
|
158
|
-
const s003Rules = ruleKeys.filter(r => r.includes('s003'));
|
|
159
|
-
console.log(chalk.blue(` S003-related rules: ${s003Rules.join(', ') || 'none'}`));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Keep all existing rules and enable selected ones
|
|
163
|
-
const updatedRules = { ...config.rules };
|
|
164
|
-
|
|
165
|
-
// Enable only selected rules
|
|
166
|
-
for (const ruleId of selectedRules) {
|
|
167
|
-
if (options.verbose) {
|
|
168
|
-
console.log(chalk.blue(` Checking rule: ${ruleId}`));
|
|
169
|
-
console.log(chalk.blue(` Available in config: ${ruleId in config.rules}`));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (config.rules[ruleId] !== undefined) {
|
|
173
|
-
updatedRules[ruleId] = 'error'; // Enable the rule as error
|
|
174
|
-
if (options.verbose) {
|
|
175
|
-
console.log(chalk.gray(` Enabling rule: ${ruleId} as error`));
|
|
176
|
-
}
|
|
177
|
-
} else {
|
|
178
|
-
if (options.verbose) {
|
|
179
|
-
console.log(chalk.red(` Rule not found in config: ${ruleId}`));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
...config,
|
|
186
|
-
rules: updatedRules
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
return config;
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
return updatedConfig;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Rule C006: logAnalysisResults - verb-noun naming
|
|
197
|
-
* Rule C005: Single responsibility - logging
|
|
198
|
-
*/
|
|
199
|
-
logAnalysisResults(results) {
|
|
200
|
-
const { totalFiles, totalErrors, totalWarnings } = results;
|
|
201
|
-
|
|
202
|
-
console.log(chalk.blue('📊 TypeScript Analysis Results:'));
|
|
203
|
-
console.log(chalk.gray(` Files analyzed: ${totalFiles}`));
|
|
204
|
-
console.log(chalk.gray(` Errors found: ${totalErrors}`));
|
|
205
|
-
console.log(chalk.gray(` Warnings found: ${totalWarnings}`));
|
|
206
|
-
|
|
207
|
-
if (totalErrors === 0 && totalWarnings === 0) {
|
|
208
|
-
console.log(chalk.green(' ✅ All checks passed!'));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Rule C006: getEngineStatus - verb-noun naming
|
|
214
|
-
* Rule C012: Query method - returns status without side effects
|
|
215
|
-
*/
|
|
216
|
-
getEngineStatus() {
|
|
217
|
-
return {
|
|
218
|
-
initialized: this.isInitialized,
|
|
219
|
-
configPath: this.eslintInstanceManager.getConfigPath(),
|
|
220
|
-
eslintReady: this.eslintInstanceManager.checkInstanceReady()
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Rule C006: checkDependencies - verb-noun naming
|
|
226
|
-
* Rule C014: Delegate to dependency manager
|
|
227
|
-
*/
|
|
228
|
-
async checkDependencies() {
|
|
229
|
-
return this.dependencyManager.checkDependenciesAvailable();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Rule C006: installDependencies - verb-noun naming
|
|
234
|
-
* Rule C014: Delegate to dependency manager
|
|
235
|
-
*/
|
|
236
|
-
async installDependencies() {
|
|
237
|
-
return this.dependencyManager.installMissingDependencies();
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Rule C006: convertToSunLintFormat - verb-noun naming
|
|
242
|
-
* Rule C012: Pure function - converts ESLint results to SunLint format
|
|
243
|
-
*/
|
|
244
|
-
convertToSunLintFormat(eslintResults, ruleMapping = {}, options = {}) {
|
|
245
|
-
const chalk = require('chalk');
|
|
246
|
-
// Handle both direct results and wrapped results
|
|
247
|
-
const resultsArray = eslintResults.results || [eslintResults];
|
|
248
|
-
const problems = [];
|
|
249
|
-
const convertedResults = [];
|
|
250
|
-
|
|
251
|
-
for (const result of resultsArray) {
|
|
252
|
-
// Skip if no messages
|
|
253
|
-
if (!result || !result.messages) continue;
|
|
254
|
-
|
|
255
|
-
const violations = [];
|
|
256
|
-
|
|
257
|
-
for (const message of result.messages) {
|
|
258
|
-
// Map ESLint rule ID to SunLint rule ID if mapping provided
|
|
259
|
-
const sunlintRuleId = ruleMapping[message.ruleId] || message.ruleId;
|
|
260
|
-
|
|
261
|
-
// Debug logging
|
|
262
|
-
if (options && options.verbose) {
|
|
263
|
-
console.log(chalk.gray(` ESLint message: ${message.ruleId} -> ${sunlintRuleId} (${message.message})`));
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Ensure we have a valid file path
|
|
267
|
-
const filePath = result.filePath || result.file || 'unknown';
|
|
268
|
-
|
|
269
|
-
const violation = {
|
|
270
|
-
ruleId: sunlintRuleId,
|
|
271
|
-
severity: message.severity === 2 ? 'error' : 'warning',
|
|
272
|
-
message: message.message,
|
|
273
|
-
file: filePath,
|
|
274
|
-
line: message.line,
|
|
275
|
-
column: message.column,
|
|
276
|
-
endLine: message.endLine,
|
|
277
|
-
endColumn: message.endColumn
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
violations.push(violation);
|
|
281
|
-
problems.push(violation);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (violations.length > 0) {
|
|
285
|
-
convertedResults.push({
|
|
286
|
-
filePath: result.filePath || result.file || 'unknown',
|
|
287
|
-
violations: violations
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
problems,
|
|
294
|
-
results: convertedResults,
|
|
295
|
-
errorCount: problems.filter(p => p.severity === 'error').length,
|
|
296
|
-
warningCount: problems.filter(p => p.severity === 'warning').length,
|
|
297
|
-
fileCount: eslintResults.totalFiles || resultsArray.length,
|
|
298
|
-
totalViolations: problems.length
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Legacy method names for backward compatibility
|
|
303
|
-
async initializeEslint() {
|
|
304
|
-
return this.initializeEngine();
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Rule C006: getEslintInstance - kept for backward compatibility
|
|
308
|
-
getEslintInstance() {
|
|
309
|
-
return this.eslintInstanceManager.getEslintInstance();
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
module.exports = TypeScriptEngine;
|
|
File without changes
|
|
File without changes
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
# Rule Responsibility Matrix
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
This document defines clear responsibilities between ESLint and SunLint to avoid duplication and maximize efficiency.
|
|
5
|
-
|
|
6
|
-
## Current Rule Distribution
|
|
7
|
-
|
|
8
|
-
### ESLint Custom Rules (29 rules)
|
|
9
|
-
**Primary Responsibilities:**
|
|
10
|
-
- ✅ Syntactic/structural checks
|
|
11
|
-
- ✅ IDE integration & fast feedback
|
|
12
|
-
- ✅ Standard coding conventions
|
|
13
|
-
- ✅ TypeScript-specific features
|
|
14
|
-
|
|
15
|
-
| Rule ID | Name | Type | Rationale |
|
|
16
|
-
|---------|------|------|-----------|
|
|
17
|
-
| C002 | no-duplicate-code | Structural | AST-based duplicate detection |
|
|
18
|
-
| C003 | no-vague-abbreviations | Naming | Simple naming convention |
|
|
19
|
-
| C006 | function-name-verb-noun | Naming | **ACTIVE** - Simple naming check |
|
|
20
|
-
| C008 | declare-variables-near-usage | Structural | Scope analysis |
|
|
21
|
-
| C010 | limit-block-nesting | Structural | Nesting depth check |
|
|
22
|
-
| C013 | no-dead-code | Structural | Dead code detection |
|
|
23
|
-
| C014 | abstract-dependency-preferred | Structural | DI pattern detection |
|
|
24
|
-
| C017 | limit-constructor-logic | Structural | Constructor complexity |
|
|
25
|
-
| C018 | no-generic-throw | Structural | Error handling pattern |
|
|
26
|
-
| C023 | no-duplicate-variable-name | Structural | Variable naming |
|
|
27
|
-
| C024 | no-hardcode-constants | Structural | Constant extraction |
|
|
28
|
-
| C027 | limit-function-nesting | Structural | Function nesting |
|
|
29
|
-
| C028 | no-silent-catch | Structural | **DEPRECATED** - Use SunLint C029 |
|
|
30
|
-
| C030 | use-custom-error-classes | Structural | Error class pattern |
|
|
31
|
-
| C034 | no-implicit-return | Structural | Return statement check |
|
|
32
|
-
| C035 | no-empty-catch | Structural | Empty catch detection |
|
|
33
|
-
| C037 | error-handler-log-input | Structural | Error logging pattern |
|
|
34
|
-
| C041 | no-config-inline | Structural | Configuration separation |
|
|
35
|
-
| C042 | boolean-name-prefix | Naming | Boolean naming convention |
|
|
36
|
-
| C043 | no-console-or-print | Structural | Console usage detection |
|
|
37
|
-
| C047 | no-duplicate-retry-logic | Structural | Retry pattern detection |
|
|
38
|
-
| C048 | no-var-declaration | Structural | Variable declaration |
|
|
39
|
-
| C076 | one-assert-per-test | Test | Test assertion pattern |
|
|
40
|
-
| T002 | interface-prefix-i | TypeScript | Interface naming |
|
|
41
|
-
| T003 | ts-ignore-reason | TypeScript | TypeScript ignore usage |
|
|
42
|
-
| T004 | interface-public-only | TypeScript | Interface structure |
|
|
43
|
-
| T007 | no-fn-in-constructor | TypeScript | Constructor pattern |
|
|
44
|
-
| T011 | no-real-time-dependency | Test | Test isolation |
|
|
45
|
-
| T019 | no-empty-type | TypeScript | Type definition |
|
|
46
|
-
| T025 | no-nested-union-tuple | TypeScript | Type complexity |
|
|
47
|
-
| T026 | limit-nested-generics | TypeScript | Generic complexity |
|
|
48
|
-
|
|
49
|
-
### SunLint Rules (4 rules)
|
|
50
|
-
**Primary Responsibilities:**
|
|
51
|
-
- ✅ Complex semantic analysis
|
|
52
|
-
- ✅ Cross-file/project analysis
|
|
53
|
-
- ✅ Performance-critical batch processing
|
|
54
|
-
- ✅ Business rule logic
|
|
55
|
-
|
|
56
|
-
| Rule ID | Name | Type | Rationale |
|
|
57
|
-
|---------|------|------|-----------|
|
|
58
|
-
| C006 | function_naming | Naming | **DISABLED** - Use ESLint version |
|
|
59
|
-
| C019 | log_level_usage | Semantic | **ACTIVE** - Complex log context analysis |
|
|
60
|
-
| C029 | catch_block_logging | Semantic | **ACTIVE** - Enhanced error context analysis |
|
|
61
|
-
| C031 | validation_separation | Architectural | **ACTIVE** - Cross-function validation pattern |
|
|
62
|
-
|
|
63
|
-
## Rule Overlap Resolution
|
|
64
|
-
|
|
65
|
-
### ✅ Resolved Overlaps
|
|
66
|
-
|
|
67
|
-
#### C006 - Function Naming
|
|
68
|
-
- **Decision**: Use ESLint version
|
|
69
|
-
- **Rationale**: Simple naming check, better IDE integration
|
|
70
|
-
- **Action**: SunLint C006 disabled in config
|
|
71
|
-
|
|
72
|
-
#### C028/C029 - Catch Block Logging
|
|
73
|
-
- **Decision**: Use SunLint C029
|
|
74
|
-
- **Rationale**: More sophisticated error context analysis
|
|
75
|
-
- **Action**: ESLint C028 should be deprecated in favor of SunLint C029
|
|
76
|
-
|
|
77
|
-
### 🔄 Planned Enhancements
|
|
78
|
-
|
|
79
|
-
#### C029 - Enhanced Catch Block Logging
|
|
80
|
-
Current SunLint C029 should be enhanced to fully replace ESLint C028:
|
|
81
|
-
|
|
82
|
-
**ESLint C028 capabilities:**
|
|
83
|
-
- Detects silent catch blocks
|
|
84
|
-
- Basic error logging requirements
|
|
85
|
-
|
|
86
|
-
**SunLint C029 enhancements needed:**
|
|
87
|
-
- All C028 functionality
|
|
88
|
-
- Context-aware error logging
|
|
89
|
-
- Stack trace preservation analysis
|
|
90
|
-
- Error correlation tracking
|
|
91
|
-
|
|
92
|
-
## Integration Strategy
|
|
93
|
-
|
|
94
|
-
### Phase 1: Current State (Implemented)
|
|
95
|
-
```json
|
|
96
|
-
// .eslintrc.cjs - ESLint handles most rules
|
|
97
|
-
{
|
|
98
|
-
"rules": {
|
|
99
|
-
"custom/c006": "warn", // Active in ESLint
|
|
100
|
-
"custom/c029": "warn", // Will be deprecated
|
|
101
|
-
// ... other ESLint rules
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// .sunlint.json - SunLint handles specialized rules
|
|
106
|
-
{
|
|
107
|
-
"rules": {
|
|
108
|
-
"C006": "off", // Disabled - use ESLint
|
|
109
|
-
"C019": true, // Active - unique to SunLint
|
|
110
|
-
"C029": "error", // Active - enhanced version
|
|
111
|
-
"C031": true // Active - unique to SunLint
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Phase 2: ESLint Adapter (Planned)
|
|
117
|
-
```json
|
|
118
|
-
// .sunlint.json - Unified configuration
|
|
119
|
-
{
|
|
120
|
-
"rules": {
|
|
121
|
-
"C019": true,
|
|
122
|
-
"C029": true,
|
|
123
|
-
"C031": true,
|
|
124
|
-
// ESLint rules via adapter
|
|
125
|
-
"eslint:custom/c003": true,
|
|
126
|
-
"eslint:custom/c006": true,
|
|
127
|
-
"eslint:custom/c042": true
|
|
128
|
-
},
|
|
129
|
-
"eslintAdapter": {
|
|
130
|
-
"configPath": ".eslintrc.cjs",
|
|
131
|
-
"rules": ["custom/c003", "custom/c006", "custom/c042"]
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Migration Guidelines
|
|
137
|
-
|
|
138
|
-
### Rules to Keep in ESLint
|
|
139
|
-
**Criteria:**
|
|
140
|
-
- Simple syntactic checks
|
|
141
|
-
- IDE integration critical
|
|
142
|
-
- TypeScript-specific features
|
|
143
|
-
- Standard conventions
|
|
144
|
-
|
|
145
|
-
**Examples:**
|
|
146
|
-
- C003 (Variable naming)
|
|
147
|
-
- C042 (Boolean naming)
|
|
148
|
-
- T002 (Interface prefix)
|
|
149
|
-
- T003 (TypeScript ignore)
|
|
150
|
-
|
|
151
|
-
### Rules to Migrate to SunLint
|
|
152
|
-
**Criteria:**
|
|
153
|
-
- Complex semantic analysis
|
|
154
|
-
- Cross-file analysis needed
|
|
155
|
-
- Performance-critical
|
|
156
|
-
- Business rule logic
|
|
157
|
-
|
|
158
|
-
**Candidates:**
|
|
159
|
-
- C014 (Dependency Injection) - Cross-file analysis
|
|
160
|
-
- C034 (Data fetching separation) - Service layer analysis
|
|
161
|
-
- C040 (File execution order) - Project-level analysis
|
|
162
|
-
|
|
163
|
-
### Rules to Enhance in SunLint
|
|
164
|
-
**Current:**
|
|
165
|
-
- C029 (Catch block logging) - Enhance to replace C028
|
|
166
|
-
- C031 (Validation separation) - Add cross-file validation
|
|
167
|
-
|
|
168
|
-
## Testing Strategy
|
|
169
|
-
|
|
170
|
-
### Rule Compatibility Testing
|
|
171
|
-
1. **Overlap Testing**: Ensure no conflicting reports
|
|
172
|
-
2. **Performance Testing**: Compare combined vs individual execution
|
|
173
|
-
3. **Accuracy Testing**: Validate rule logic equivalence
|
|
174
|
-
|
|
175
|
-
### Integration Testing
|
|
176
|
-
1. **CI/CD Pipeline**: Test unified reporting
|
|
177
|
-
2. **IDE Integration**: Verify ESLint feedback still works
|
|
178
|
-
3. **Configuration**: Test rule enable/disable scenarios
|
|
179
|
-
|
|
180
|
-
## Monitoring & Maintenance
|
|
181
|
-
|
|
182
|
-
### Performance Metrics
|
|
183
|
-
- Combined analysis time
|
|
184
|
-
- Memory usage comparison
|
|
185
|
-
- CI/CD pipeline impact
|
|
186
|
-
|
|
187
|
-
### Quality Metrics
|
|
188
|
-
- Rule coverage completeness
|
|
189
|
-
- False positive rates
|
|
190
|
-
- Developer satisfaction
|
|
191
|
-
|
|
192
|
-
### Process Metrics
|
|
193
|
-
- Configuration complexity
|
|
194
|
-
- Maintenance overhead
|
|
195
|
-
- Team adoption rate
|
|
196
|
-
|
|
197
|
-
## Decision Log
|
|
198
|
-
|
|
199
|
-
| Date | Decision | Rationale |
|
|
200
|
-
|------|----------|-----------|
|
|
201
|
-
| 2024-01-XX | Disable SunLint C006 | ESLint version sufficient, better IDE integration |
|
|
202
|
-
| 2024-01-XX | Keep SunLint C019 | Unique semantic analysis capability |
|
|
203
|
-
| 2024-01-XX | Enhance SunLint C029 | Replace ESLint C028 with better analysis |
|
|
204
|
-
| 2024-01-XX | Keep SunLint C031 | Unique architectural analysis |
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SunLint CLI Entry Point
|
|
5
|
-
* Main CLI entry point with modular architecture
|
|
6
|
-
* Following Rule C005: Single responsibility - only handle CLI bootstrapping
|
|
7
|
-
* Following Rule C014: Dependency injection for services
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const chalk = require('chalk');
|
|
11
|
-
const { createCliProgram } = require('./core/cli-program');
|
|
12
|
-
const CliActionHandler = require('./core/cli-action-handler');
|
|
13
|
-
|
|
14
|
-
// Create CLI program
|
|
15
|
-
const program = createCliProgram();
|
|
16
|
-
|
|
17
|
-
// Set up main action handler
|
|
18
|
-
program.action(async (options) => {
|
|
19
|
-
const actionHandler = new CliActionHandler(options);
|
|
20
|
-
await actionHandler.execute();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Global error handling
|
|
24
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
25
|
-
console.error(chalk.red('Sun Lint - Unhandled Rejection:'), promise, chalk.red('reason:'), reason);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
process.on('uncaughtException', (error) => {
|
|
30
|
-
console.error(chalk.red('Sun Lint - Uncaught Exception:'), error);
|
|
31
|
-
process.exit(1);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Parse CLI arguments
|
|
35
|
-
program.parse();
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom ESLint rule for: C013 – Do not leave dead code commented out
|
|
3
|
-
* Rule ID: custom/c013
|
|
4
|
-
* Purpose: Prevent commented-out code from being left in the codebase to maintain cleanliness
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
meta: {
|
|
9
|
-
type: "suggestion",
|
|
10
|
-
docs: {
|
|
11
|
-
description: "Do not leave dead code commented out",
|
|
12
|
-
recommended: false
|
|
13
|
-
},
|
|
14
|
-
schema: [],
|
|
15
|
-
messages: {
|
|
16
|
-
deadCode: "Do not leave dead code commented out. Remove it or use version control to track changes."
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
create(context) {
|
|
20
|
-
return {
|
|
21
|
-
BlockStatement(node) {
|
|
22
|
-
let unreachable = false;
|
|
23
|
-
for (const stmt of node.body) {
|
|
24
|
-
if (unreachable) {
|
|
25
|
-
context.report({
|
|
26
|
-
node: stmt,
|
|
27
|
-
messageId: "deadCode"
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
stmt.type === "ReturnStatement" ||
|
|
33
|
-
stmt.type === "ThrowStatement" ||
|
|
34
|
-
stmt.type === "ContinueStatement" ||
|
|
35
|
-
stmt.type === "BreakStatement"
|
|
36
|
-
) {
|
|
37
|
-
unreachable = true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom ESLint rule for: C017 – Limit constructor logic
|
|
3
|
-
* Rule ID: custom/c017
|
|
4
|
-
* Purpose: Enforce minimal logic in constructors to maintain clean initialization
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
meta: {
|
|
9
|
-
type: "suggestion",
|
|
10
|
-
docs: {
|
|
11
|
-
description: "Limit constructor logic",
|
|
12
|
-
recommended: false
|
|
13
|
-
},
|
|
14
|
-
schema: [],
|
|
15
|
-
messages: {
|
|
16
|
-
constructorLogic: "Constructor should only initialize properties, avoid complex logic"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
create(context) {
|
|
20
|
-
return {
|
|
21
|
-
MethodDefinition(node) {
|
|
22
|
-
if (
|
|
23
|
-
node.kind === "constructor" &&
|
|
24
|
-
node.value &&
|
|
25
|
-
node.value.body &&
|
|
26
|
-
node.value.body.body.length > 5 // threshold for logic lines in constructor
|
|
27
|
-
) {
|
|
28
|
-
context.report({
|
|
29
|
-
node,
|
|
30
|
-
messageId: "constructorLogic",
|
|
31
|
-
data: {
|
|
32
|
-
count: node.value.body.body.length
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom ESLint rule for: C027 – Avoid deeply nested functions (maximum 2 levels)
|
|
3
|
-
* Rule ID: custom/c027
|
|
4
|
-
* Goal: Limit function nesting to maximum 2 levels to improve readability and maintainability
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
meta: {
|
|
9
|
-
type: "suggestion",
|
|
10
|
-
docs: {
|
|
11
|
-
description: "Avoid deeply nested functions (maximum 2 levels)",
|
|
12
|
-
recommended: false
|
|
13
|
-
},
|
|
14
|
-
schema: [],
|
|
15
|
-
messages: {
|
|
16
|
-
tooDeep: "Function is nested too deeply (level {{depth}}). Should be maximum 2 levels."
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
create(context) {
|
|
20
|
-
let functionStack = [];
|
|
21
|
-
|
|
22
|
-
function enterFunction(node) {
|
|
23
|
-
functionStack.push(node);
|
|
24
|
-
const depth = functionStack.length;
|
|
25
|
-
|
|
26
|
-
if (depth > 2) {
|
|
27
|
-
context.report({
|
|
28
|
-
node,
|
|
29
|
-
messageId: "tooDeep",
|
|
30
|
-
data: {
|
|
31
|
-
depth
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function exitFunction() {
|
|
38
|
-
functionStack.pop();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
FunctionDeclaration: enterFunction,
|
|
43
|
-
FunctionExpression: enterFunction,
|
|
44
|
-
ArrowFunctionExpression: enterFunction,
|
|
45
|
-
'FunctionDeclaration:exit': exitFunction,
|
|
46
|
-
'FunctionExpression:exit': exitFunction,
|
|
47
|
-
'ArrowFunctionExpression:exit': exitFunction
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
};
|