@opensip-cli/checks-typescript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/all-checks-execute.test.d.ts +12 -0
- package/dist/__tests__/all-checks-execute.test.d.ts.map +1 -0
- package/dist/__tests__/all-checks-execute.test.js +846 -0
- package/dist/__tests__/all-checks-execute.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-2.test.d.ts +9 -0
- package/dist/__tests__/behavior-fixtures-2.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-2.test.js +625 -0
- package/dist/__tests__/behavior-fixtures-2.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-3.test.d.ts +7 -0
- package/dist/__tests__/behavior-fixtures-3.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-3.test.js +658 -0
- package/dist/__tests__/behavior-fixtures-3.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-4.test.d.ts +8 -0
- package/dist/__tests__/behavior-fixtures-4.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-4.test.js +590 -0
- package/dist/__tests__/behavior-fixtures-4.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-5.test.d.ts +7 -0
- package/dist/__tests__/behavior-fixtures-5.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-5.test.js +548 -0
- package/dist/__tests__/behavior-fixtures-5.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures-6.test.d.ts +18 -0
- package/dist/__tests__/behavior-fixtures-6.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures-6.test.js +1700 -0
- package/dist/__tests__/behavior-fixtures-6.test.js.map +1 -0
- package/dist/__tests__/behavior-fixtures.test.d.ts +10 -0
- package/dist/__tests__/behavior-fixtures.test.d.ts.map +1 -0
- package/dist/__tests__/behavior-fixtures.test.js +812 -0
- package/dist/__tests__/behavior-fixtures.test.js.map +1 -0
- package/dist/__tests__/branch-fixtures-2.test.d.ts +6 -0
- package/dist/__tests__/branch-fixtures-2.test.d.ts.map +1 -0
- package/dist/__tests__/branch-fixtures-2.test.js +1369 -0
- package/dist/__tests__/branch-fixtures-2.test.js.map +1 -0
- package/dist/__tests__/branch-fixtures-3.test.d.ts +7 -0
- package/dist/__tests__/branch-fixtures-3.test.d.ts.map +1 -0
- package/dist/__tests__/branch-fixtures-3.test.js +877 -0
- package/dist/__tests__/branch-fixtures-3.test.js.map +1 -0
- package/dist/__tests__/branch-fixtures.test.d.ts +6 -0
- package/dist/__tests__/branch-fixtures.test.d.ts.map +1 -0
- package/dist/__tests__/branch-fixtures.test.js +1072 -0
- package/dist/__tests__/branch-fixtures.test.js.map +1 -0
- package/dist/__tests__/checks.test.d.ts +2 -0
- package/dist/__tests__/checks.test.d.ts.map +1 -0
- package/dist/__tests__/checks.test.js +39 -0
- package/dist/__tests__/checks.test.js.map +1 -0
- package/dist/__tests__/fixture-coverage.allowlist.d.ts +19 -0
- package/dist/__tests__/fixture-coverage.allowlist.d.ts.map +1 -0
- package/dist/__tests__/fixture-coverage.allowlist.js +27 -0
- package/dist/__tests__/fixture-coverage.allowlist.js.map +1 -0
- package/dist/__tests__/fixture-coverage.test.d.ts +13 -0
- package/dist/__tests__/fixture-coverage.test.d.ts.map +1 -0
- package/dist/__tests__/fixture-coverage.test.js +57 -0
- package/dist/__tests__/fixture-coverage.test.js.map +1 -0
- package/dist/__tests__/no-bootstrap-tool-import.test.d.ts +2 -0
- package/dist/__tests__/no-bootstrap-tool-import.test.d.ts.map +1 -0
- package/dist/__tests__/no-bootstrap-tool-import.test.js +75 -0
- package/dist/__tests__/no-bootstrap-tool-import.test.js.map +1 -0
- package/dist/__tests__/phantom-dependency-detection.test.d.ts +12 -0
- package/dist/__tests__/phantom-dependency-detection.test.d.ts.map +1 -0
- package/dist/__tests__/phantom-dependency-detection.test.js +112 -0
- package/dist/__tests__/phantom-dependency-detection.test.js.map +1 -0
- package/dist/__tests__/typescript-frontend.test.d.ts +8 -0
- package/dist/__tests__/typescript-frontend.test.d.ts.map +1 -0
- package/dist/__tests__/typescript-frontend.test.js +57 -0
- package/dist/__tests__/typescript-frontend.test.js.map +1 -0
- package/dist/checks/architecture/circular-import-detection.d.ts +14 -0
- package/dist/checks/architecture/circular-import-detection.d.ts.map +1 -0
- package/dist/checks/architecture/circular-import-detection.js +55 -0
- package/dist/checks/architecture/circular-import-detection.js.map +1 -0
- package/dist/checks/architecture/contracts-schema-consistency.d.ts +11 -0
- package/dist/checks/architecture/contracts-schema-consistency.d.ts.map +1 -0
- package/dist/checks/architecture/contracts-schema-consistency.js +75 -0
- package/dist/checks/architecture/contracts-schema-consistency.js.map +1 -0
- package/dist/checks/architecture/drizzle-orm-migration-guardrails.d.ts +12 -0
- package/dist/checks/architecture/drizzle-orm-migration-guardrails.d.ts.map +1 -0
- package/dist/checks/architecture/drizzle-orm-migration-guardrails.js +92 -0
- package/dist/checks/architecture/drizzle-orm-migration-guardrails.js.map +1 -0
- package/dist/checks/architecture/index.d.ts +10 -0
- package/dist/checks/architecture/index.d.ts.map +1 -0
- package/dist/checks/architecture/index.js +10 -0
- package/dist/checks/architecture/index.js.map +1 -0
- package/dist/checks/architecture/missing-type-exports.d.ts +13 -0
- package/dist/checks/architecture/missing-type-exports.d.ts.map +1 -0
- package/dist/checks/architecture/missing-type-exports.js +245 -0
- package/dist/checks/architecture/missing-type-exports.js.map +1 -0
- package/dist/checks/architecture/module-coupling-fan-out.d.ts +20 -0
- package/dist/checks/architecture/module-coupling-fan-out.d.ts.map +1 -0
- package/dist/checks/architecture/module-coupling-fan-out.js +120 -0
- package/dist/checks/architecture/module-coupling-fan-out.js.map +1 -0
- package/dist/checks/architecture/no-bootstrap-tool-import.d.ts +38 -0
- package/dist/checks/architecture/no-bootstrap-tool-import.d.ts.map +1 -0
- package/dist/checks/architecture/no-bootstrap-tool-import.js +95 -0
- package/dist/checks/architecture/no-bootstrap-tool-import.js.map +1 -0
- package/dist/checks/architecture/package-json-exports-field.d.ts +10 -0
- package/dist/checks/architecture/package-json-exports-field.d.ts.map +1 -0
- package/dist/checks/architecture/package-json-exports-field.js +56 -0
- package/dist/checks/architecture/package-json-exports-field.js.map +1 -0
- package/dist/checks/architecture/phantom-dependency-detection.d.ts +22 -0
- package/dist/checks/architecture/phantom-dependency-detection.d.ts.map +1 -0
- package/dist/checks/architecture/phantom-dependency-detection.js +330 -0
- package/dist/checks/architecture/phantom-dependency-detection.js.map +1 -0
- package/dist/checks/architecture/tsconfig-extends-validation.d.ts +10 -0
- package/dist/checks/architecture/tsconfig-extends-validation.d.ts.map +1 -0
- package/dist/checks/architecture/tsconfig-extends-validation.js +78 -0
- package/dist/checks/architecture/tsconfig-extends-validation.js.map +1 -0
- package/dist/checks/index.d.ts +6 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +6 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/checks/quality/api/api-contract-validation.d.ts +15 -0
- package/dist/checks/quality/api/api-contract-validation.d.ts.map +1 -0
- package/dist/checks/quality/api/api-contract-validation.js +316 -0
- package/dist/checks/quality/api/api-contract-validation.js.map +1 -0
- package/dist/checks/quality/api/api-response-validation.d.ts +14 -0
- package/dist/checks/quality/api/api-response-validation.d.ts.map +1 -0
- package/dist/checks/quality/api/api-response-validation.js +209 -0
- package/dist/checks/quality/api/api-response-validation.js.map +1 -0
- package/dist/checks/quality/api/fastify-route-validation.d.ts +14 -0
- package/dist/checks/quality/api/fastify-route-validation.d.ts.map +1 -0
- package/dist/checks/quality/api/fastify-route-validation.js +298 -0
- package/dist/checks/quality/api/fastify-route-validation.js.map +1 -0
- package/dist/checks/quality/api/fastify-schema-coverage.d.ts +11 -0
- package/dist/checks/quality/api/fastify-schema-coverage.d.ts.map +1 -0
- package/dist/checks/quality/api/fastify-schema-coverage.js +261 -0
- package/dist/checks/quality/api/fastify-schema-coverage.js.map +1 -0
- package/dist/checks/quality/api/index.d.ts +5 -0
- package/dist/checks/quality/api/index.d.ts.map +1 -0
- package/dist/checks/quality/api/index.js +5 -0
- package/dist/checks/quality/api/index.js.map +1 -0
- package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts +32 -0
- package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/duplicate-utility-functions.js +451 -0
- package/dist/checks/quality/code-structure/duplicate-utility-functions.js.map +1 -0
- package/dist/checks/quality/code-structure/index.d.ts +3 -0
- package/dist/checks/quality/code-structure/index.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/index.js +3 -0
- package/dist/checks/quality/code-structure/index.js.map +1 -0
- package/dist/checks/quality/code-structure/no-any-types.d.ts +13 -0
- package/dist/checks/quality/code-structure/no-any-types.d.ts.map +1 -0
- package/dist/checks/quality/code-structure/no-any-types.js +116 -0
- package/dist/checks/quality/code-structure/no-any-types.js.map +1 -0
- package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.d.ts +15 -0
- package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js +51 -0
- package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js.map +1 -0
- package/dist/checks/quality/data-integrity/array-validation.d.ts +16 -0
- package/dist/checks/quality/data-integrity/array-validation.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/array-validation.js +508 -0
- package/dist/checks/quality/data-integrity/array-validation.js.map +1 -0
- package/dist/checks/quality/data-integrity/database-index-coverage.d.ts +14 -0
- package/dist/checks/quality/data-integrity/database-index-coverage.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/database-index-coverage.js +235 -0
- package/dist/checks/quality/data-integrity/database-index-coverage.js.map +1 -0
- package/dist/checks/quality/data-integrity/database-schema-validation.d.ts +16 -0
- package/dist/checks/quality/data-integrity/database-schema-validation.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/database-schema-validation.js +328 -0
- package/dist/checks/quality/data-integrity/database-schema-validation.js.map +1 -0
- package/dist/checks/quality/data-integrity/in-memory-repository-detection.d.ts +14 -0
- package/dist/checks/quality/data-integrity/in-memory-repository-detection.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/in-memory-repository-detection.js +157 -0
- package/dist/checks/quality/data-integrity/in-memory-repository-detection.js.map +1 -0
- package/dist/checks/quality/data-integrity/index.d.ts +8 -0
- package/dist/checks/quality/data-integrity/index.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/index.js +8 -0
- package/dist/checks/quality/data-integrity/index.js.map +1 -0
- package/dist/checks/quality/data-integrity/missing-input-validation.d.ts +12 -0
- package/dist/checks/quality/data-integrity/missing-input-validation.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/missing-input-validation.js +180 -0
- package/dist/checks/quality/data-integrity/missing-input-validation.js.map +1 -0
- package/dist/checks/quality/data-integrity/null-safety.d.ts +33 -0
- package/dist/checks/quality/data-integrity/null-safety.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/null-safety.js +766 -0
- package/dist/checks/quality/data-integrity/null-safety.js.map +1 -0
- package/dist/checks/quality/data-integrity/numeric-validation.d.ts +12 -0
- package/dist/checks/quality/data-integrity/numeric-validation.d.ts.map +1 -0
- package/dist/checks/quality/data-integrity/numeric-validation.js +409 -0
- package/dist/checks/quality/data-integrity/numeric-validation.js.map +1 -0
- package/dist/checks/quality/frontend/a11y-form-labels.d.ts +14 -0
- package/dist/checks/quality/frontend/a11y-form-labels.d.ts.map +1 -0
- package/dist/checks/quality/frontend/a11y-form-labels.js +93 -0
- package/dist/checks/quality/frontend/a11y-form-labels.js.map +1 -0
- package/dist/checks/quality/frontend/a11y-semantic-html.d.ts +14 -0
- package/dist/checks/quality/frontend/a11y-semantic-html.d.ts.map +1 -0
- package/dist/checks/quality/frontend/a11y-semantic-html.js +88 -0
- package/dist/checks/quality/frontend/a11y-semantic-html.js.map +1 -0
- package/dist/checks/quality/frontend/index.d.ts +4 -0
- package/dist/checks/quality/frontend/index.d.ts.map +1 -0
- package/dist/checks/quality/frontend/index.js +4 -0
- package/dist/checks/quality/frontend/index.js.map +1 -0
- package/dist/checks/quality/frontend/test-only-frontend-modules.d.ts +13 -0
- package/dist/checks/quality/frontend/test-only-frontend-modules.d.ts.map +1 -0
- package/dist/checks/quality/frontend/test-only-frontend-modules.js +159 -0
- package/dist/checks/quality/frontend/test-only-frontend-modules.js.map +1 -0
- package/dist/checks/quality/incomplete-regex-escaping.d.ts +13 -0
- package/dist/checks/quality/incomplete-regex-escaping.d.ts.map +1 -0
- package/dist/checks/quality/incomplete-regex-escaping.js +207 -0
- package/dist/checks/quality/incomplete-regex-escaping.js.map +1 -0
- package/dist/checks/quality/index.d.ts +11 -0
- package/dist/checks/quality/index.d.ts.map +1 -0
- package/dist/checks/quality/index.js +11 -0
- package/dist/checks/quality/index.js.map +1 -0
- package/dist/checks/quality/linting/index.d.ts +2 -0
- package/dist/checks/quality/linting/index.d.ts.map +1 -0
- package/dist/checks/quality/linting/index.js +2 -0
- package/dist/checks/quality/linting/index.js.map +1 -0
- package/dist/checks/quality/linting/typescript-frontend.d.ts +25 -0
- package/dist/checks/quality/linting/typescript-frontend.d.ts.map +1 -0
- package/dist/checks/quality/linting/typescript-frontend.js +159 -0
- package/dist/checks/quality/linting/typescript-frontend.js.map +1 -0
- package/dist/checks/quality/observability/index.d.ts +5 -0
- package/dist/checks/quality/observability/index.d.ts.map +1 -0
- package/dist/checks/quality/observability/index.js +5 -0
- package/dist/checks/quality/observability/index.js.map +1 -0
- package/dist/checks/quality/observability/logger-event-name-format.d.ts +12 -0
- package/dist/checks/quality/observability/logger-event-name-format.d.ts.map +1 -0
- package/dist/checks/quality/observability/logger-event-name-format.js +124 -0
- package/dist/checks/quality/observability/logger-event-name-format.js.map +1 -0
- package/dist/checks/quality/observability/no-hardcoded-correlation-id.d.ts +5 -0
- package/dist/checks/quality/observability/no-hardcoded-correlation-id.d.ts.map +1 -0
- package/dist/checks/quality/observability/no-hardcoded-correlation-id.js +77 -0
- package/dist/checks/quality/observability/no-hardcoded-correlation-id.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.d.ts +11 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.js +107 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.d.ts +12 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.js +94 -0
- package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/analyzer.d.ts +13 -0
- package/dist/checks/quality/observability/observability-coverage/analyzer.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/analyzer.js +117 -0
- package/dist/checks/quality/observability/observability-coverage/analyzer.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/index.d.ts +4 -0
- package/dist/checks/quality/observability/observability-coverage/index.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/index.js +4 -0
- package/dist/checks/quality/observability/observability-coverage/index.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/logger-detector.d.ts +29 -0
- package/dist/checks/quality/observability/observability-coverage/logger-detector.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/logger-detector.js +111 -0
- package/dist/checks/quality/observability/observability-coverage/logger-detector.js.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/types.d.ts +64 -0
- package/dist/checks/quality/observability/observability-coverage/types.d.ts.map +1 -0
- package/dist/checks/quality/observability/observability-coverage/types.js +6 -0
- package/dist/checks/quality/observability/observability-coverage/types.js.map +1 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.d.ts +22 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.d.ts.map +1 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.js +212 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.js.map +1 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.test.d.ts +11 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.test.d.ts.map +1 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.test.js +46 -0
- package/dist/checks/quality/observability/pii-exposure-in-logs.test.js.map +1 -0
- package/dist/checks/quality/patterns/__tests__/toctou-fp.test.d.ts +14 -0
- package/dist/checks/quality/patterns/__tests__/toctou-fp.test.d.ts.map +1 -0
- package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js +61 -0
- package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js.map +1 -0
- package/dist/checks/quality/patterns/async-waterfall-detection.d.ts +26 -0
- package/dist/checks/quality/patterns/async-waterfall-detection.d.ts.map +1 -0
- package/dist/checks/quality/patterns/async-waterfall-detection.js +410 -0
- package/dist/checks/quality/patterns/async-waterfall-detection.js.map +1 -0
- package/dist/checks/quality/patterns/dispose-pattern-completeness.d.ts +13 -0
- package/dist/checks/quality/patterns/dispose-pattern-completeness.d.ts.map +1 -0
- package/dist/checks/quality/patterns/dispose-pattern-completeness.js +220 -0
- package/dist/checks/quality/patterns/dispose-pattern-completeness.js.map +1 -0
- package/dist/checks/quality/patterns/error-handling-quality.d.ts +17 -0
- package/dist/checks/quality/patterns/error-handling-quality.d.ts.map +1 -0
- package/dist/checks/quality/patterns/error-handling-quality.js +335 -0
- package/dist/checks/quality/patterns/error-handling-quality.js.map +1 -0
- package/dist/checks/quality/patterns/index.d.ts +10 -0
- package/dist/checks/quality/patterns/index.d.ts.map +1 -0
- package/dist/checks/quality/patterns/index.js +10 -0
- package/dist/checks/quality/patterns/index.js.map +1 -0
- package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.d.ts +16 -0
- package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.d.ts.map +1 -0
- package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.js +205 -0
- package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.js.map +1 -0
- package/dist/checks/quality/patterns/result-pattern-consistency.d.ts +16 -0
- package/dist/checks/quality/patterns/result-pattern-consistency.d.ts.map +1 -0
- package/dist/checks/quality/patterns/result-pattern-consistency.js +328 -0
- package/dist/checks/quality/patterns/result-pattern-consistency.js.map +1 -0
- package/dist/checks/quality/patterns/silent-early-returns.d.ts +23 -0
- package/dist/checks/quality/patterns/silent-early-returns.d.ts.map +1 -0
- package/dist/checks/quality/patterns/silent-early-returns.js +266 -0
- package/dist/checks/quality/patterns/silent-early-returns.js.map +1 -0
- package/dist/checks/quality/patterns/stream-buffer-size-limits.d.ts +13 -0
- package/dist/checks/quality/patterns/stream-buffer-size-limits.d.ts.map +1 -0
- package/dist/checks/quality/patterns/stream-buffer-size-limits.js +163 -0
- package/dist/checks/quality/patterns/stream-buffer-size-limits.js.map +1 -0
- package/dist/checks/quality/patterns/throws-documentation.d.ts +23 -0
- package/dist/checks/quality/patterns/throws-documentation.d.ts.map +1 -0
- package/dist/checks/quality/patterns/throws-documentation.js +519 -0
- package/dist/checks/quality/patterns/throws-documentation.js.map +1 -0
- package/dist/checks/quality/patterns/toctou-race-condition.d.ts +48 -0
- package/dist/checks/quality/patterns/toctou-race-condition.d.ts.map +1 -0
- package/dist/checks/quality/patterns/toctou-race-condition.js +639 -0
- package/dist/checks/quality/patterns/toctou-race-condition.js.map +1 -0
- package/dist/checks/quality/stubbed-implementation-detection.d.ts +24 -0
- package/dist/checks/quality/stubbed-implementation-detection.d.ts.map +1 -0
- package/dist/checks/quality/stubbed-implementation-detection.js +355 -0
- package/dist/checks/quality/stubbed-implementation-detection.js.map +1 -0
- package/dist/checks/quality/unused-config-options.d.ts +12 -0
- package/dist/checks/quality/unused-config-options.d.ts.map +1 -0
- package/dist/checks/quality/unused-config-options.js +245 -0
- package/dist/checks/quality/unused-config-options.js.map +1 -0
- package/dist/checks/resilience/__tests__/callback-invocation-safe.test.d.ts +2 -0
- package/dist/checks/resilience/__tests__/callback-invocation-safe.test.d.ts.map +1 -0
- package/dist/checks/resilience/__tests__/callback-invocation-safe.test.js +79 -0
- package/dist/checks/resilience/__tests__/callback-invocation-safe.test.js.map +1 -0
- package/dist/checks/resilience/__tests__/context-leakage-fp.test.d.ts +12 -0
- package/dist/checks/resilience/__tests__/context-leakage-fp.test.d.ts.map +1 -0
- package/dist/checks/resilience/__tests__/context-leakage-fp.test.js +34 -0
- package/dist/checks/resilience/__tests__/context-leakage-fp.test.js.map +1 -0
- package/dist/checks/resilience/__tests__/context-mutation.test.d.ts +11 -0
- package/dist/checks/resilience/__tests__/context-mutation.test.d.ts.map +1 -0
- package/dist/checks/resilience/__tests__/context-mutation.test.js +54 -0
- package/dist/checks/resilience/__tests__/context-mutation.test.js.map +1 -0
- package/dist/checks/resilience/callback-invocation-safe.d.ts +34 -0
- package/dist/checks/resilience/callback-invocation-safe.d.ts.map +1 -0
- package/dist/checks/resilience/callback-invocation-safe.js +247 -0
- package/dist/checks/resilience/callback-invocation-safe.js.map +1 -0
- package/dist/checks/resilience/context-leakage.d.ts +25 -0
- package/dist/checks/resilience/context-leakage.d.ts.map +1 -0
- package/dist/checks/resilience/context-leakage.js +435 -0
- package/dist/checks/resilience/context-leakage.js.map +1 -0
- package/dist/checks/resilience/context-mutation.d.ts +21 -0
- package/dist/checks/resilience/context-mutation.d.ts.map +1 -0
- package/dist/checks/resilience/context-mutation.js +368 -0
- package/dist/checks/resilience/context-mutation.js.map +1 -0
- package/dist/checks/resilience/detached-promises.d.ts +40 -0
- package/dist/checks/resilience/detached-promises.d.ts.map +1 -0
- package/dist/checks/resilience/detached-promises.js +646 -0
- package/dist/checks/resilience/detached-promises.js.map +1 -0
- package/dist/checks/resilience/index.d.ts +7 -0
- package/dist/checks/resilience/index.d.ts.map +1 -0
- package/dist/checks/resilience/index.js +7 -0
- package/dist/checks/resilience/index.js.map +1 -0
- package/dist/checks/resilience/no-raw-fetch.d.ts +11 -0
- package/dist/checks/resilience/no-raw-fetch.d.ts.map +1 -0
- package/dist/checks/resilience/no-raw-fetch.js +110 -0
- package/dist/checks/resilience/no-raw-fetch.js.map +1 -0
- package/dist/checks/resilience/no-unbounded-concurrency.d.ts +11 -0
- package/dist/checks/resilience/no-unbounded-concurrency.d.ts.map +1 -0
- package/dist/checks/resilience/no-unbounded-concurrency.js +117 -0
- package/dist/checks/resilience/no-unbounded-concurrency.js.map +1 -0
- package/dist/checks/security/__tests__/sql-injection.test.d.ts +17 -0
- package/dist/checks/security/__tests__/sql-injection.test.d.ts.map +1 -0
- package/dist/checks/security/__tests__/sql-injection.test.js +97 -0
- package/dist/checks/security/__tests__/sql-injection.test.js.map +1 -0
- package/dist/checks/security/index.d.ts +4 -0
- package/dist/checks/security/index.d.ts.map +1 -0
- package/dist/checks/security/index.js +4 -0
- package/dist/checks/security/index.js.map +1 -0
- package/dist/checks/security/input-sanitization.d.ts +20 -0
- package/dist/checks/security/input-sanitization.d.ts.map +1 -0
- package/dist/checks/security/input-sanitization.js +255 -0
- package/dist/checks/security/input-sanitization.js.map +1 -0
- package/dist/checks/security/sql-injection.d.ts +24 -0
- package/dist/checks/security/sql-injection.d.ts.map +1 -0
- package/dist/checks/security/sql-injection.js +330 -0
- package/dist/checks/security/sql-injection.js.map +1 -0
- package/dist/checks/security/unsafe-secret-comparison.d.ts +17 -0
- package/dist/checks/security/unsafe-secret-comparison.d.ts.map +1 -0
- package/dist/checks/security/unsafe-secret-comparison.js +227 -0
- package/dist/checks/security/unsafe-secret-comparison.js.map +1 -0
- package/dist/checks/testing/index.d.ts +2 -0
- package/dist/checks/testing/index.d.ts.map +1 -0
- package/dist/checks/testing/index.js +2 -0
- package/dist/checks/testing/index.js.map +1 -0
- package/dist/checks/testing/mock-implementations-in-production.d.ts +12 -0
- package/dist/checks/testing/mock-implementations-in-production.d.ts.map +1 -0
- package/dist/checks/testing/mock-implementations-in-production.js +211 -0
- package/dist/checks/testing/mock-implementations-in-production.js.map +1 -0
- package/dist/display/architecture.d.ts +9 -0
- package/dist/display/architecture.d.ts.map +1 -0
- package/dist/display/architecture.js +18 -0
- package/dist/display/architecture.js.map +1 -0
- package/dist/display/index.d.ts +20 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +30 -0
- package/dist/display/index.js.map +1 -0
- package/dist/display/quality.d.ts +7 -0
- package/dist/display/quality.d.ts.map +1 -0
- package/dist/display/quality.js +39 -0
- package/dist/display/quality.js.map +1 -0
- package/dist/display/resilience.d.ts +7 -0
- package/dist/display/resilience.d.ts.map +1 -0
- package/dist/display/resilience.js +13 -0
- package/dist/display/resilience.js.map +1 -0
- package/dist/display/security-testing.d.ts +9 -0
- package/dist/display/security-testing.d.ts.map +1 -0
- package/dist/display/security-testing.js +14 -0
- package/dist/display/security-testing.js.map +1 -0
- package/dist/display/types.d.ts +6 -0
- package/dist/display/types.d.ts.map +1 -0
- package/dist/display/types.js +6 -0
- package/dist/display/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
// @fitness-ignore-file file-length-limit -- cohesive single-check module; splitting risks breaking the detector contract
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview TOCTOU Race Condition Detection Check
|
|
4
|
+
*
|
|
5
|
+
* Detects Time-of-Check-Time-of-Use race conditions where data is read,
|
|
6
|
+
* then updated without passing version/condition for atomic updates.
|
|
7
|
+
*
|
|
8
|
+
* Refinement notes (Wave E lane E6-redo):
|
|
9
|
+
* The original implementation was a regex-only test for the presence of
|
|
10
|
+
* `.get/.find/...` and `.update/.set/...` strings inside the same function
|
|
11
|
+
* body. That broad pattern produced false positives on:
|
|
12
|
+
* - Local `Map.get` / `Map.set` accumulator idioms (count++ via map).
|
|
13
|
+
* - In-process cache fields (`this.#cache.get` then `this.#cache.set`)
|
|
14
|
+
* used as single-threaded coalescing structures.
|
|
15
|
+
* - Read-only DB functions that build local Maps for grouping
|
|
16
|
+
* (`db.select(...)` → `new Map().set(...)`).
|
|
17
|
+
* - Single-statement atomic SQL writes (`tx.execute(sql`UPDATE...`)`).
|
|
18
|
+
*
|
|
19
|
+
* Refinement strategy: classify each `.get/.set/.update/...` call by its
|
|
20
|
+
* receiver. A function only flags as TOCTOU if there is at least one
|
|
21
|
+
* read+update pair on a *non-local* receiver (i.e. not a local Map/Set,
|
|
22
|
+
* not a "Cache"-named field, and not a tx/db where writes are atomic
|
|
23
|
+
* SQL). All-local-receiver patterns are excluded.
|
|
24
|
+
*/
|
|
25
|
+
import { defineCheck, getCheckConfig, isTestFile } from '@opensip-cli/fitness';
|
|
26
|
+
import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
|
|
27
|
+
import * as ts from 'typescript';
|
|
28
|
+
/** Patterns that indicate proper atomic update handling */
|
|
29
|
+
const ATOMIC_PATTERNS = [
|
|
30
|
+
/expectedVersion/i,
|
|
31
|
+
/version\s*:/,
|
|
32
|
+
/ConditionExpression/,
|
|
33
|
+
/conditionalUpdate/i,
|
|
34
|
+
/atomicUpdate/i,
|
|
35
|
+
/compareAndSwap/i,
|
|
36
|
+
/optimisticLock/i,
|
|
37
|
+
/CONCURRENCY SAFE/,
|
|
38
|
+
// Transaction patterns
|
|
39
|
+
/transaction/i,
|
|
40
|
+
/beginTransaction/i,
|
|
41
|
+
/withTransaction/i,
|
|
42
|
+
/runInTransaction/i,
|
|
43
|
+
// Lock patterns
|
|
44
|
+
/acquireLock/i,
|
|
45
|
+
/withLock/i,
|
|
46
|
+
/mutex/i,
|
|
47
|
+
// Idempotency patterns
|
|
48
|
+
/idempotent/i,
|
|
49
|
+
/idempotencyKey/i,
|
|
50
|
+
// Single-threaded/in-memory safety comments
|
|
51
|
+
/single-threaded/i,
|
|
52
|
+
/in-memory/i,
|
|
53
|
+
/atomic in.*Node/i,
|
|
54
|
+
// Documented coalescing/event-loop safety patterns commonly used in Node single-threaded code
|
|
55
|
+
/single-threaded coalesce/i, // explicit coalescing-cache documentation
|
|
56
|
+
/Node single-threaded/i, // explicit Node single-threaded documentation
|
|
57
|
+
/event-loop semantics/i, // explicit event-loop atomicity documentation
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Paths where TOCTOU is typically not a concern
|
|
61
|
+
* (in-memory caches, rate limiters, local state managers)
|
|
62
|
+
*/
|
|
63
|
+
const SAFE_TOCTOU_PATHS = [
|
|
64
|
+
// In-memory data structures
|
|
65
|
+
/\/cache\//i,
|
|
66
|
+
/\/caching\//i,
|
|
67
|
+
/memory-backend/i,
|
|
68
|
+
/memory-cache/i,
|
|
69
|
+
/memory-store/i,
|
|
70
|
+
/in-memory/i,
|
|
71
|
+
// Filename conventions — `*-cache.ts` and `*-prefetcher.ts` are
|
|
72
|
+
// single-threaded coalescing structures by convention (Node event-loop
|
|
73
|
+
// semantics make the .get-then-.set pattern safe). The path-segment
|
|
74
|
+
// /cache/ skip above misses files at top of a package's src/ tree.
|
|
75
|
+
/-cache\.tsx?$/i,
|
|
76
|
+
/-prefetcher\.tsx?$/i,
|
|
77
|
+
// Rate limiting (bounded operations)
|
|
78
|
+
/rate-limit/i,
|
|
79
|
+
/rate_limit/i,
|
|
80
|
+
// Local state management
|
|
81
|
+
/local-storage/i,
|
|
82
|
+
/local-state/i,
|
|
83
|
+
/state-manager/i,
|
|
84
|
+
// CLI/scripts (single user, non-concurrent)
|
|
85
|
+
// CLI commands use local Map/Set operations that are not shared-state TOCTOU risks.
|
|
86
|
+
// Server lifecycle TOCTOU issues are better caught by the reentrancy-guard check.
|
|
87
|
+
/\/cli\//,
|
|
88
|
+
/\/scripts\//,
|
|
89
|
+
// Test utilities
|
|
90
|
+
/\/testing\//,
|
|
91
|
+
/test-utils/,
|
|
92
|
+
// Configuration/Registry (startup-time operations)
|
|
93
|
+
/\/config\//,
|
|
94
|
+
/\/registry\//,
|
|
95
|
+
/\/di-registration\//,
|
|
96
|
+
/\/factories\//,
|
|
97
|
+
// Route handlers — request-scoped Map/Set ops are not shared-state TOCTOU; route handlers are dominated by Zod.pick/parse and per-request local maps that the regex misreads as TOCTOU.
|
|
98
|
+
/\/routes\//,
|
|
99
|
+
// DI composition — fragment graphs construct a per-startup map of providers; not concurrent shared state.
|
|
100
|
+
/\/di\//,
|
|
101
|
+
// Schema declarations — Drizzle/Zod schema files are pure declarative builders, no runtime read/update race surface.
|
|
102
|
+
/\/schema\//,
|
|
103
|
+
// NOTE: opensip-specific paths (e.g. `/chain-walker/` for audit-chain
|
|
104
|
+
// walkers) are NOT defaults. They live in opensip's recipe under
|
|
105
|
+
// `checks.config['toctou-race-condition'].additionalSafeTOCTOUPaths`.
|
|
106
|
+
];
|
|
107
|
+
/**
|
|
108
|
+
* Compile recipe-provided string entries to case-insensitive RegExp values.
|
|
109
|
+
*/
|
|
110
|
+
function buildEffectiveSafePaths() {
|
|
111
|
+
const cfg = getCheckConfig('toctou-race-condition');
|
|
112
|
+
const extras = (cfg.additionalSafeTOCTOUPaths ?? []).map((src) => new RegExp(src, 'i'));
|
|
113
|
+
return [...SAFE_TOCTOU_PATHS, ...extras];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if a file path is in a safe TOCTOU context. Combines built-in
|
|
117
|
+
* defaults with the recipe-config augmentation.
|
|
118
|
+
*/
|
|
119
|
+
function isSafeToctouPath(filePath, safePaths) {
|
|
120
|
+
return safePaths.some((pattern) => pattern.test(filePath));
|
|
121
|
+
}
|
|
122
|
+
/** Read operation method names */
|
|
123
|
+
const READ_METHODS = new Set([
|
|
124
|
+
'get',
|
|
125
|
+
'find',
|
|
126
|
+
'findOne',
|
|
127
|
+
'findFirst',
|
|
128
|
+
'findMany',
|
|
129
|
+
'getById',
|
|
130
|
+
'fetch',
|
|
131
|
+
'load',
|
|
132
|
+
'read',
|
|
133
|
+
]);
|
|
134
|
+
/** Update operation method names */
|
|
135
|
+
const UPDATE_METHODS = new Set(['update', 'save', 'put', 'set', 'patch', 'modify']);
|
|
136
|
+
/**
|
|
137
|
+
* Check if content has atomic patterns
|
|
138
|
+
*/
|
|
139
|
+
function hasAtomicPatterns(content) {
|
|
140
|
+
return ATOMIC_PATTERNS.some((p) => p.test(content));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get function name from a function-like node
|
|
144
|
+
*/
|
|
145
|
+
function getFunctionNameFromNode(node, sourceFile) {
|
|
146
|
+
if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {
|
|
147
|
+
return node.name?.getText(sourceFile) ?? 'anonymous';
|
|
148
|
+
}
|
|
149
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
150
|
+
const parent = node.parent;
|
|
151
|
+
if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
152
|
+
return parent.name.getText(sourceFile);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return 'anonymous';
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if node is a function-like node
|
|
159
|
+
*/
|
|
160
|
+
function isFunctionLikeNode(node) {
|
|
161
|
+
return (ts.isFunctionDeclaration(node) ||
|
|
162
|
+
ts.isMethodDeclaration(node) ||
|
|
163
|
+
ts.isArrowFunction(node) ||
|
|
164
|
+
ts.isFunctionExpression(node));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Identify TypeNodes that name an in-memory keyed collection — these are
|
|
168
|
+
* not shared persistent state and read+set on them is not a TOCTOU risk.
|
|
169
|
+
*/
|
|
170
|
+
const IN_MEMORY_COLLECTION_TYPE_NAMES = new Set([
|
|
171
|
+
'Map',
|
|
172
|
+
'WeakMap',
|
|
173
|
+
'ReadonlyMap',
|
|
174
|
+
'Set',
|
|
175
|
+
'WeakSet',
|
|
176
|
+
'ReadonlySet',
|
|
177
|
+
]);
|
|
178
|
+
function isInMemoryCollectionTypeNode(typeNode) {
|
|
179
|
+
if (!typeNode)
|
|
180
|
+
return false;
|
|
181
|
+
if (ts.isTypeReferenceNode(typeNode)) {
|
|
182
|
+
const name = typeNode.typeName;
|
|
183
|
+
if (ts.isIdentifier(name)) {
|
|
184
|
+
if (IN_MEMORY_COLLECTION_TYPE_NAMES.has(name.text))
|
|
185
|
+
return true;
|
|
186
|
+
// Type names ending in `Cache` (e.g. `SecretsCache`) are an
|
|
187
|
+
// OpenSIP-wide convention for in-process keyed coalescing
|
|
188
|
+
// structures. Treating them as local-collection eliminates the
|
|
189
|
+
// FP class where a service-level `cache: XCache` parameter is
|
|
190
|
+
// read+written within a function body.
|
|
191
|
+
if (name.text.endsWith('Cache'))
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Identify variable initializers that construct an in-memory collection,
|
|
199
|
+
* e.g. `const counts = new Map()`, `new Set<string>()`.
|
|
200
|
+
*/
|
|
201
|
+
function isInMemoryCollectionInitializer(init) {
|
|
202
|
+
if (!init)
|
|
203
|
+
return false;
|
|
204
|
+
if (ts.isNewExpression(init) && ts.isIdentifier(init.expression)) {
|
|
205
|
+
return IN_MEMORY_COLLECTION_TYPE_NAMES.has(init.expression.text);
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Heuristic: a property access like `this.#cache`, `this.headerCache`,
|
|
211
|
+
* `this._cache` is treated as an in-process cache field. The `*Cache`
|
|
212
|
+
* suffix and `_cache` / `#cache` conventions are strong signals that the
|
|
213
|
+
* field is a coalescing in-memory structure (single-threaded Node).
|
|
214
|
+
*
|
|
215
|
+
* This is intentionally narrow: only matches `this.<name>` shapes whose
|
|
216
|
+
* `<name>` has the `Cache` suffix or is exactly `cache`.
|
|
217
|
+
*/
|
|
218
|
+
function isInMemoryCacheReceiverText(text) {
|
|
219
|
+
// strip a leading `#` (private field) and `_` (convention)
|
|
220
|
+
const normalized = text.replace(/^[#_]/, '');
|
|
221
|
+
if (normalized === 'cache')
|
|
222
|
+
return true;
|
|
223
|
+
if (normalized.endsWith('Cache'))
|
|
224
|
+
return true;
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Collect names of local variables/parameters within a function that
|
|
229
|
+
* refer to in-memory keyed collections (`Map`, `Set`, etc.). Names are
|
|
230
|
+
* matched against the simple receiver of `<name>.get/set/...` calls.
|
|
231
|
+
*/
|
|
232
|
+
function collectLocalCollectionNames(node) {
|
|
233
|
+
const names = new Set();
|
|
234
|
+
// Parameters typed as Map/Set
|
|
235
|
+
for (const param of node.parameters) {
|
|
236
|
+
if (ts.isIdentifier(param.name) && isInMemoryCollectionTypeNode(param.type)) {
|
|
237
|
+
names.add(param.name.text);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Local `const x = new Map()` / `new Set()` declarations anywhere in body.
|
|
241
|
+
const visit = (n) => {
|
|
242
|
+
// Don't descend into nested functions — their locals belong to a
|
|
243
|
+
// different scope.
|
|
244
|
+
if (n !== node && isFunctionLikeNode(n))
|
|
245
|
+
return;
|
|
246
|
+
if (ts.isVariableDeclaration(n) &&
|
|
247
|
+
ts.isIdentifier(n.name) &&
|
|
248
|
+
(isInMemoryCollectionInitializer(n.initializer) || isInMemoryCollectionTypeNode(n.type))) {
|
|
249
|
+
names.add(n.name.text);
|
|
250
|
+
}
|
|
251
|
+
ts.forEachChild(n, visit);
|
|
252
|
+
};
|
|
253
|
+
if (node.body)
|
|
254
|
+
visit(node.body);
|
|
255
|
+
return names;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Collect class-level field names that are initialized to an in-memory
|
|
259
|
+
* collection (`new Map()` / `new Set()`). Used so that `this.#cache`-style
|
|
260
|
+
* access in a method does not look like shared persistent state.
|
|
261
|
+
*
|
|
262
|
+
* Walks up to the containing ClassDeclaration / ClassExpression. Returns
|
|
263
|
+
* the simple field name (no `#` prefix) for matching against
|
|
264
|
+
* `this.<name>.get/set` receivers.
|
|
265
|
+
*/
|
|
266
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- AST walk over class members: nested type checks reflect the TypeScript AST shape
|
|
267
|
+
function collectClassInMemoryFieldNames(node) {
|
|
268
|
+
const names = new Set();
|
|
269
|
+
let cls = node.parent;
|
|
270
|
+
while (cls && !ts.isClassDeclaration(cls) && !ts.isClassExpression(cls)) {
|
|
271
|
+
cls = cls.parent;
|
|
272
|
+
}
|
|
273
|
+
if (!cls)
|
|
274
|
+
return names;
|
|
275
|
+
const classNode = cls;
|
|
276
|
+
for (const member of classNode.members) {
|
|
277
|
+
if (ts.isPropertyDeclaration(member)) {
|
|
278
|
+
const memberName = member.name;
|
|
279
|
+
let fieldName;
|
|
280
|
+
if (ts.isIdentifier(memberName)) {
|
|
281
|
+
fieldName = memberName.text;
|
|
282
|
+
}
|
|
283
|
+
else if (ts.isPrivateIdentifier(memberName)) {
|
|
284
|
+
fieldName = memberName.text.replace(/^#/, '');
|
|
285
|
+
}
|
|
286
|
+
if (!fieldName)
|
|
287
|
+
continue;
|
|
288
|
+
if (isInMemoryCollectionInitializer(member.initializer) ||
|
|
289
|
+
isInMemoryCollectionTypeNode(member.type)) {
|
|
290
|
+
names.add(fieldName);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return names;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Index file-local `interface` / `type` declarations to the set of field
|
|
298
|
+
* names whose declared type is an in-memory keyed collection (`Map`/`Set`/…).
|
|
299
|
+
*
|
|
300
|
+
* Used to treat `<stateObj>.<mapField>.get/set(...)` as a *local-collection*
|
|
301
|
+
* access. The "state bag of Maps" pattern — an interface bundling several
|
|
302
|
+
* `Map`/`Set` fields, threaded as a parameter through the steps of an
|
|
303
|
+
* iterative graph / DP algorithm (e.g. Tarjan SCC's `TarjanState`) — is
|
|
304
|
+
* single-threaded in-memory work, not a shared-state read-then-update race.
|
|
305
|
+
* The receiver `state.lowlink` is a *chained* access that the simple-receiver
|
|
306
|
+
* classifier would otherwise treat conservatively as shared.
|
|
307
|
+
*/
|
|
308
|
+
function collectInterfaceCollectionFields(sourceFile) {
|
|
309
|
+
const byType = new Map();
|
|
310
|
+
const fieldsFrom = (members) => {
|
|
311
|
+
const fields = new Set();
|
|
312
|
+
for (const member of members) {
|
|
313
|
+
if (ts.isPropertySignature(member) &&
|
|
314
|
+
ts.isIdentifier(member.name) &&
|
|
315
|
+
isInMemoryCollectionTypeNode(member.type)) {
|
|
316
|
+
fields.add(member.name.text);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return fields;
|
|
320
|
+
};
|
|
321
|
+
for (const stmt of sourceFile.statements) {
|
|
322
|
+
if (ts.isInterfaceDeclaration(stmt)) {
|
|
323
|
+
const fields = fieldsFrom(stmt.members);
|
|
324
|
+
if (fields.size > 0)
|
|
325
|
+
byType.set(stmt.name.text, fields);
|
|
326
|
+
}
|
|
327
|
+
else if (ts.isTypeAliasDeclaration(stmt) && ts.isTypeLiteralNode(stmt.type)) {
|
|
328
|
+
const fields = fieldsFrom(stmt.type.members);
|
|
329
|
+
if (fields.size > 0)
|
|
330
|
+
byType.set(stmt.name.text, fields);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return byType;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Collect `<receiver>.<field>` keys for parameters/locals whose declared type
|
|
337
|
+
* is a file-local interface/type that declares `Map`/`Set` fields. Those
|
|
338
|
+
* `<obj>.<field>` accesses behave like local collections (see
|
|
339
|
+
* {@link collectInterfaceCollectionFields}).
|
|
340
|
+
*/
|
|
341
|
+
function collectLocalObjectCollectionFieldKeys(node, interfaceCollectionFields) {
|
|
342
|
+
const keys = new Set();
|
|
343
|
+
const addFor = (name, typeNode) => {
|
|
344
|
+
if (!typeNode || !ts.isTypeReferenceNode(typeNode))
|
|
345
|
+
return;
|
|
346
|
+
if (!ts.isIdentifier(typeNode.typeName))
|
|
347
|
+
return;
|
|
348
|
+
const fields = interfaceCollectionFields.get(typeNode.typeName.text);
|
|
349
|
+
if (!fields)
|
|
350
|
+
return;
|
|
351
|
+
for (const field of fields)
|
|
352
|
+
keys.add(`${name}.${field}`);
|
|
353
|
+
};
|
|
354
|
+
for (const param of node.parameters) {
|
|
355
|
+
if (ts.isIdentifier(param.name))
|
|
356
|
+
addFor(param.name.text, param.type);
|
|
357
|
+
}
|
|
358
|
+
const visit = (n) => {
|
|
359
|
+
if (n !== node && isFunctionLikeNode(n))
|
|
360
|
+
return;
|
|
361
|
+
if (ts.isVariableDeclaration(n) && ts.isIdentifier(n.name))
|
|
362
|
+
addFor(n.name.text, n.type);
|
|
363
|
+
ts.forEachChild(n, visit);
|
|
364
|
+
};
|
|
365
|
+
if (node.body)
|
|
366
|
+
visit(node.body);
|
|
367
|
+
return keys;
|
|
368
|
+
}
|
|
369
|
+
/** Call-site classification kinds — narrow string literal alias set. */
|
|
370
|
+
const KIND_READ_SHARED = 'read-shared';
|
|
371
|
+
const KIND_UPDATE_SHARED = 'update-shared';
|
|
372
|
+
const KIND_READ_LOCAL = 'read-local';
|
|
373
|
+
const KIND_UPDATE_LOCAL = 'update-local';
|
|
374
|
+
/**
|
|
375
|
+
* Return true if a call expression is `<tx-or-db>.execute(sql\`...\`)`
|
|
376
|
+
* with a single SQL statement — those writes are atomic at the DB layer
|
|
377
|
+
* (single statement, no separate read-then-update window).
|
|
378
|
+
*/
|
|
379
|
+
function isAtomicSqlExecute(call) {
|
|
380
|
+
if (!ts.isPropertyAccessExpression(call.expression))
|
|
381
|
+
return false;
|
|
382
|
+
if (call.expression.name.text !== 'execute')
|
|
383
|
+
return false;
|
|
384
|
+
const arg = call.arguments[0];
|
|
385
|
+
if (!arg)
|
|
386
|
+
return false;
|
|
387
|
+
if (ts.isTaggedTemplateExpression(arg) && // `sql\`...\``
|
|
388
|
+
ts.isIdentifier(arg.tag) &&
|
|
389
|
+
arg.tag.text === 'sql')
|
|
390
|
+
return true;
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Drizzle-style ORM writes. `db.update(table)`, `db.insert(table)`,
|
|
395
|
+
* `db.delete(table)` each produce a single atomic SQL statement when
|
|
396
|
+
* awaited — they are not separate-read-then-update sequences.
|
|
397
|
+
*
|
|
398
|
+
* We treat these as `atomic-sql-write` so the function is not flagged
|
|
399
|
+
* unless there is an *actual* read-then-update on a shared receiver
|
|
400
|
+
* elsewhere.
|
|
401
|
+
*/
|
|
402
|
+
const DRIZZLE_ATOMIC_WRITE_METHODS = new Set(['update', 'insert', 'delete']);
|
|
403
|
+
function isDrizzleAtomicWrite(call) {
|
|
404
|
+
if (!ts.isPropertyAccessExpression(call.expression))
|
|
405
|
+
return false;
|
|
406
|
+
const methodName = call.expression.name.text;
|
|
407
|
+
if (!DRIZZLE_ATOMIC_WRITE_METHODS.has(methodName))
|
|
408
|
+
return false;
|
|
409
|
+
// Heuristic: receiver looks like a db/tx (named `db`, `tx`, ends in `Db`/`Tx`).
|
|
410
|
+
const receiver = call.expression.expression;
|
|
411
|
+
if (ts.isIdentifier(receiver)) {
|
|
412
|
+
const r = receiver.text;
|
|
413
|
+
if (r === 'db' || r === 'tx' || /Db$|Tx$/.test(r))
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Get the simple receiver name from a call expression like
|
|
420
|
+
* `<receiver>.method(...)`. For `this.<name>.method(...)` returns
|
|
421
|
+
* `this.<name>` collapsed; for `<id>.method(...)` returns `<id>`.
|
|
422
|
+
* Returns null if the receiver isn't a simple identifier or this-property.
|
|
423
|
+
*/
|
|
424
|
+
function getReceiverName(call) {
|
|
425
|
+
if (!ts.isPropertyAccessExpression(call.expression))
|
|
426
|
+
return null;
|
|
427
|
+
const receiver = call.expression.expression;
|
|
428
|
+
if (ts.isIdentifier(receiver)) {
|
|
429
|
+
return { name: receiver.text, isThisField: false };
|
|
430
|
+
}
|
|
431
|
+
if (ts.isPropertyAccessExpression(receiver) &&
|
|
432
|
+
receiver.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
433
|
+
return { name: receiver.name.text, isThisField: true };
|
|
434
|
+
}
|
|
435
|
+
// `<id>.<field>.method()` — a dotted receiver key (e.g. `state.lowlink`).
|
|
436
|
+
// Keying per `<id>.<field>` is strictly more precise than the old
|
|
437
|
+
// "deep chain → unknown receiver" fallback: a read on `x.a` and an update
|
|
438
|
+
// on `x.b` no longer collide, and it lets the classifier match a
|
|
439
|
+
// state-object's Map/Set field against the local-collection key set.
|
|
440
|
+
if (ts.isPropertyAccessExpression(receiver) && ts.isIdentifier(receiver.expression)) {
|
|
441
|
+
return { name: `${receiver.expression.text}.${receiver.name.text}`, isThisField: false };
|
|
442
|
+
}
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Classify a single call expression for TOCTOU purposes.
|
|
447
|
+
*/
|
|
448
|
+
function classifyCall(call, ctx) {
|
|
449
|
+
// First, atomic SQL writes anywhere short-circuit.
|
|
450
|
+
if (isAtomicSqlExecute(call))
|
|
451
|
+
return { kind: 'atomic-sql-write' };
|
|
452
|
+
if (isDrizzleAtomicWrite(call))
|
|
453
|
+
return { kind: 'atomic-sql-write' };
|
|
454
|
+
if (!ts.isPropertyAccessExpression(call.expression))
|
|
455
|
+
return { kind: 'unrelated' };
|
|
456
|
+
const methodName = call.expression.name.text;
|
|
457
|
+
const isRead = READ_METHODS.has(methodName);
|
|
458
|
+
const isUpdate = UPDATE_METHODS.has(methodName);
|
|
459
|
+
if (!isRead && !isUpdate)
|
|
460
|
+
return { kind: 'unrelated' };
|
|
461
|
+
const receiver = getReceiverName(call);
|
|
462
|
+
if (!receiver) {
|
|
463
|
+
// chained / non-simple receiver — treat as shared
|
|
464
|
+
return { kind: isRead ? KIND_READ_SHARED : KIND_UPDATE_SHARED };
|
|
465
|
+
}
|
|
466
|
+
if (isLocalReceiver(receiver, ctx)) {
|
|
467
|
+
return { kind: isRead ? KIND_READ_LOCAL : KIND_UPDATE_LOCAL };
|
|
468
|
+
}
|
|
469
|
+
return { kind: isRead ? KIND_READ_SHARED : KIND_UPDATE_SHARED };
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Decide whether a classified receiver refers to a local in-memory collection
|
|
473
|
+
* (so reads/updates on it are not shared-state TOCTOU). Covers: local
|
|
474
|
+
* `Map`/`Set` names, the `<stateObj>.<mapField>` "state bag" key, `this.<cache>`
|
|
475
|
+
* class fields, and the `cache`-named convention.
|
|
476
|
+
*/
|
|
477
|
+
function isLocalReceiver(receiver, ctx) {
|
|
478
|
+
if (receiver.isThisField) {
|
|
479
|
+
return ctx.classCacheFields.has(receiver.name) || isInMemoryCacheReceiverText(receiver.name);
|
|
480
|
+
}
|
|
481
|
+
return (ctx.localCollections.has(receiver.name) ||
|
|
482
|
+
// `<stateObj>.<mapField>` dotted key resolved to a file-local interface/
|
|
483
|
+
// type whose field is a Map/Set — the "state bag" pattern.
|
|
484
|
+
ctx.localObjectCollectionKeys.has(receiver.name) ||
|
|
485
|
+
// bare `cache` / `<X>Cache` naming convention.
|
|
486
|
+
isInMemoryCacheReceiverText(receiver.name));
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Walk a function body and classify every call expression.
|
|
490
|
+
*
|
|
491
|
+
* Tracks reads and updates *per receiver* — TOCTOU is fundamentally
|
|
492
|
+
* read-X-then-update-X on the same shared object. A function with a
|
|
493
|
+
* read on receiver A and an update on receiver B is not a TOCTOU.
|
|
494
|
+
*/
|
|
495
|
+
/* eslint-disable sonarjs/cognitive-complexity -- TOCTOU classifier and its inner AST visitor: branches reflect AST node taxonomy; flatter shape would hide the read/update pairing logic */
|
|
496
|
+
function classifyFunctionCalls(node, localCollections, classCacheFields, localObjectCollectionKeys) {
|
|
497
|
+
const ctx = { localCollections, classCacheFields, localObjectCollectionKeys };
|
|
498
|
+
// receiver-key → { read, update }. Receiver-key is `<name>` for plain
|
|
499
|
+
// identifiers and `this.<name>` for this-field accesses.
|
|
500
|
+
const perReceiver = new Map();
|
|
501
|
+
let hasReadOnUnknownReceiver = false;
|
|
502
|
+
let hasUpdateOnUnknownReceiver = false;
|
|
503
|
+
const visit = (n) => {
|
|
504
|
+
if (n !== node && isFunctionLikeNode(n))
|
|
505
|
+
return;
|
|
506
|
+
if (ts.isCallExpression(n)) {
|
|
507
|
+
const cls = classifyCall(n, ctx);
|
|
508
|
+
if (cls.kind === 'read-shared' || cls.kind === 'update-shared') {
|
|
509
|
+
const recv = getReceiverName(n);
|
|
510
|
+
if (recv) {
|
|
511
|
+
const key = recv.isThisField ? `this.${recv.name}` : recv.name;
|
|
512
|
+
let entry = perReceiver.get(key);
|
|
513
|
+
if (!entry) {
|
|
514
|
+
entry = { read: false, update: false };
|
|
515
|
+
perReceiver.set(key, entry);
|
|
516
|
+
}
|
|
517
|
+
if (cls.kind === 'read-shared')
|
|
518
|
+
entry.read = true;
|
|
519
|
+
else
|
|
520
|
+
entry.update = true;
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
if (cls.kind === 'read-shared')
|
|
524
|
+
hasReadOnUnknownReceiver = true;
|
|
525
|
+
else
|
|
526
|
+
hasUpdateOnUnknownReceiver = true;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
ts.forEachChild(n, visit);
|
|
531
|
+
};
|
|
532
|
+
if (node.body)
|
|
533
|
+
visit(node.body);
|
|
534
|
+
for (const entry of perReceiver.values()) {
|
|
535
|
+
if (entry.read && entry.update) {
|
|
536
|
+
return { hasSharedReadAndUpdateOnSameReceiver: true };
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
// Conservative fallback: if we have unknown-receiver reads paired with
|
|
540
|
+
// unknown-receiver updates, treat as shared (chained / dynamic call).
|
|
541
|
+
if (hasReadOnUnknownReceiver && hasUpdateOnUnknownReceiver) {
|
|
542
|
+
return { hasSharedReadAndUpdateOnSameReceiver: true };
|
|
543
|
+
}
|
|
544
|
+
return { hasSharedReadAndUpdateOnSameReceiver: false };
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Check a function for TOCTOU patterns
|
|
548
|
+
*/
|
|
549
|
+
function checkFunctionForToctou(options) {
|
|
550
|
+
const { node, sourceFile, interfaceCollectionFields } = options;
|
|
551
|
+
if (!node.body)
|
|
552
|
+
return null;
|
|
553
|
+
// Atomic-comment escape hatch retained from the regex implementation —
|
|
554
|
+
// a function (or its surrounding scope) that documents single-threaded
|
|
555
|
+
// / coalescing semantics is treated as safe.
|
|
556
|
+
const funcText = node.getText(sourceFile);
|
|
557
|
+
if (hasAtomicPatterns(funcText))
|
|
558
|
+
return null;
|
|
559
|
+
const localCollections = collectLocalCollectionNames(node);
|
|
560
|
+
const classCacheFields = collectClassInMemoryFieldNames(node);
|
|
561
|
+
const localObjectCollectionKeys = collectLocalObjectCollectionFieldKeys(node, interfaceCollectionFields);
|
|
562
|
+
const { hasSharedReadAndUpdateOnSameReceiver } = classifyFunctionCalls(node, localCollections, classCacheFields, localObjectCollectionKeys);
|
|
563
|
+
if (!hasSharedReadAndUpdateOnSameReceiver)
|
|
564
|
+
return null;
|
|
565
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
566
|
+
const lineNum = line + 1;
|
|
567
|
+
const funcName = getFunctionNameFromNode(node, sourceFile);
|
|
568
|
+
return {
|
|
569
|
+
line: lineNum,
|
|
570
|
+
column: character + 1,
|
|
571
|
+
message: `Function '${funcName}' has read-then-update pattern without atomic guarantees`,
|
|
572
|
+
severity: 'warning',
|
|
573
|
+
suggestion: 'Use optimistic locking: pass expectedVersion to update, or use ConditionExpression for DynamoDB, or wrap in a transaction with SELECT FOR UPDATE for SQL',
|
|
574
|
+
match: funcName,
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Analyze a file for TOCTOU race conditions. Exported for the FP-regression
|
|
579
|
+
* suite (see `__tests__/toctou-fp.test.ts`).
|
|
580
|
+
*/
|
|
581
|
+
export function analyzeFileForToctou(filePath, content) {
|
|
582
|
+
const violations = [];
|
|
583
|
+
// Skip files in safe TOCTOU paths (caches, rate limiters, CLI, etc.).
|
|
584
|
+
// Merge built-in defaults with recipe config once per file.
|
|
585
|
+
const safePaths = buildEffectiveSafePaths();
|
|
586
|
+
if (isSafeToctouPath(filePath, safePaths)) {
|
|
587
|
+
return violations;
|
|
588
|
+
}
|
|
589
|
+
// Skip if the whole file documents atomic / single-threaded semantics.
|
|
590
|
+
if (hasAtomicPatterns(content)) {
|
|
591
|
+
return violations;
|
|
592
|
+
}
|
|
593
|
+
const sourceFile = getSharedSourceFile(filePath, content);
|
|
594
|
+
if (!sourceFile)
|
|
595
|
+
return [];
|
|
596
|
+
const interfaceCollectionFields = collectInterfaceCollectionFields(sourceFile);
|
|
597
|
+
const visit = (node) => {
|
|
598
|
+
if (isFunctionLikeNode(node)) {
|
|
599
|
+
const violation = checkFunctionForToctou({ node, sourceFile, interfaceCollectionFields });
|
|
600
|
+
if (violation) {
|
|
601
|
+
violations.push(violation);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
ts.forEachChild(node, visit);
|
|
605
|
+
};
|
|
606
|
+
visit(sourceFile);
|
|
607
|
+
return violations;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Check: quality/toctou-race-condition
|
|
611
|
+
*
|
|
612
|
+
* Detects read-then-update patterns without atomic guarantees.
|
|
613
|
+
*/
|
|
614
|
+
export const toctouRaceCondition = defineCheck({
|
|
615
|
+
id: 'eb67d6f3-c984-485d-b077-1ebabea0d894',
|
|
616
|
+
slug: 'toctou-race-condition',
|
|
617
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
|
|
618
|
+
contentFilter: 'strip-strings',
|
|
619
|
+
confidence: 'high',
|
|
620
|
+
description: 'Detects read-then-update patterns without atomic guarantees',
|
|
621
|
+
longDescription: `**Purpose:** Detects Time-of-Check-Time-of-Use (TOCTOU) race conditions where data is read then updated without atomic guarantees.
|
|
622
|
+
|
|
623
|
+
**Detects:** Walks the TypeScript AST per-function. Flags a function only when both (a) at least one read call (\`.get(\`, \`.find(\`, \`.findOne(\`, \`.findFirst(\`, \`.findMany(\`, \`.getById(\`, \`.fetch(\`, \`.load(\`, \`.read(\`) and (b) at least one update call (\`.update(\`, \`.save(\`, \`.put(\`, \`.set(\`, \`.patch(\`, \`.modify(\`) target a *shared* receiver — i.e. neither a local \`Map\`/\`Set\` declared in the function nor a parameter typed \`Map<...>\`/\`Set<...>\`, nor a class field initialized to \`new Map()\`/\`new Set()\`, nor a cache-named field (\`this.cache\`, \`this.#cache\`, \`this.<X>Cache\`). Single-statement atomic SQL writes (\`tx.execute(sql\`UPDATE...\`)\`, \`tx.update(table)\`, \`tx.insert(table)\`, \`tx.delete(table)\`) are not counted as the "update" side. Skips safe contexts: in-memory caches, rate limiters, CLI/scripts, config/registry files, and functions whose body documents atomic / single-threaded semantics (\`single-threaded coalesce\`, \`Node single-threaded\`, \`event-loop semantics\`).
|
|
624
|
+
|
|
625
|
+
**Why it matters:** TOCTOU bugs allow concurrent requests to overwrite each other's changes, causing silent data loss that only manifests under load.
|
|
626
|
+
|
|
627
|
+
**Scope:** General best practice`,
|
|
628
|
+
tags: ['quality', 'performance', 'best-practices'],
|
|
629
|
+
fileTypes: ['ts'],
|
|
630
|
+
// @fitness-ignore-next-line no-hardcoded-timeouts -- framework default for fitness check execution
|
|
631
|
+
timeout: 180_000, // 3 minutes - analyzes read-then-update patterns
|
|
632
|
+
analyze(content, filePath) {
|
|
633
|
+
// Skip test files — TOCTOU patterns in tests are low-risk
|
|
634
|
+
if (isTestFile(filePath))
|
|
635
|
+
return [];
|
|
636
|
+
return analyzeFileForToctou(filePath, content);
|
|
637
|
+
},
|
|
638
|
+
});
|
|
639
|
+
//# sourceMappingURL=toctou-race-condition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toctou-race-condition.js","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/toctou-race-condition.ts"],"names":[],"mappings":"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"}
|