@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,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Circular-import detection check.
|
|
3
|
+
*
|
|
4
|
+
* Detects file-level circular dependencies using Tarjan's SCC algorithm
|
|
5
|
+
* over the project's intra-project import graph. Each strongly-connected
|
|
6
|
+
* component of size > 1 represents a real cycle (a chain of files where
|
|
7
|
+
* `a → b → ... → a`).
|
|
8
|
+
*
|
|
9
|
+
* Complements the existing module/package-level coupling checks; this one
|
|
10
|
+
* operates at the file level, where cycles most often originate during
|
|
11
|
+
* iterative agent-driven development.
|
|
12
|
+
*/
|
|
13
|
+
import { defineCheck, buildImportGraph, findStronglyConnectedComponents, } from '@opensip-cli/fitness';
|
|
14
|
+
export const circularImportDetection = defineCheck({
|
|
15
|
+
id: 'fc8b5ec9-d020-4e76-b16f-f5f73ce9d21e',
|
|
16
|
+
slug: 'circular-import-detection',
|
|
17
|
+
description: 'Detects file-level circular import dependencies',
|
|
18
|
+
longDescription: "Builds the project import graph and runs Tarjan's SCC algorithm to find " +
|
|
19
|
+
'cycles. Each cycle (chain of files where a → b → … → a) is reported as a ' +
|
|
20
|
+
'separate violation against the first file in the cycle (the anchor).',
|
|
21
|
+
scope: {
|
|
22
|
+
languages: ['typescript', 'tsx', 'javascript', 'jsx'],
|
|
23
|
+
concerns: ['backend', 'frontend', 'cli', 'shared'],
|
|
24
|
+
},
|
|
25
|
+
confidence: 'high',
|
|
26
|
+
tags: ['architecture', 'modularity'],
|
|
27
|
+
fileTypes: ['ts', 'tsx', 'js', 'jsx'],
|
|
28
|
+
async analyzeAll(files) {
|
|
29
|
+
const fileMap = await files.readAll();
|
|
30
|
+
const graph = buildImportGraph(fileMap);
|
|
31
|
+
const sccs = findStronglyConnectedComponents(graph);
|
|
32
|
+
const violations = [];
|
|
33
|
+
for (const scc of sccs) {
|
|
34
|
+
// Skip SCCs of size 1 (no cycle, or self-loop which is rare and not
|
|
35
|
+
// structurally interesting at the file level).
|
|
36
|
+
if (scc.length < 2)
|
|
37
|
+
continue;
|
|
38
|
+
// The anchor file gets the violation. Sort the cycle for deterministic
|
|
39
|
+
// output regardless of graph iteration order.
|
|
40
|
+
const cycle = [...scc].sort();
|
|
41
|
+
const anchor = cycle[0];
|
|
42
|
+
const chain = cycle.join(' → ') + ' → ' + anchor;
|
|
43
|
+
violations.push({
|
|
44
|
+
severity: 'error',
|
|
45
|
+
message: `Circular import (${cycle.length} files): ${chain}`,
|
|
46
|
+
filePath: anchor,
|
|
47
|
+
// Graph-level violation — no specific statement; line 1 is the conventional
|
|
48
|
+
// anchor for file-scoped findings.
|
|
49
|
+
line: 1,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return violations;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=circular-import-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circular-import-detection.js","sourceRoot":"","sources":["../../../src/checks/architecture/circular-import-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,WAAW,EAGX,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;IACjD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,2BAA2B;IACjC,WAAW,EAAE,iDAAiD;IAC9D,eAAe,EACb,0EAA0E;QAC1E,2EAA2E;QAC3E,sEAAsE;IACxE,KAAK,EAAE;QACL,SAAS,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC;QACrD,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC;KACnD;IACD,UAAU,EAAE,MAAM;IAClB,IAAI,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAErC,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,+BAA+B,CAAC,KAAK,CAAC,CAAC;QAEpD,MAAM,UAAU,GAAqB,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,oEAAoE;YACpE,+CAA+C;YAC/C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAE7B,uEAAuE;YACvE,8CAA8C;YAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC;YAEjD,UAAU,CAAC,IAAI,CAAC;gBACd,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,oBAAoB,KAAK,CAAC,MAAM,YAAY,KAAK,EAAE;gBAC5D,QAAQ,EAAE,MAAM;gBAChB,4EAA4E;gBAC5E,mCAAmC;gBACnC,IAAI,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Contracts schema consistency check
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check: architecture/contracts-schema-consistency
|
|
6
|
+
*
|
|
7
|
+
* Validates that contracts use Zod schemas consistently:
|
|
8
|
+
* - Types derived from schemas via z.infer
|
|
9
|
+
*/
|
|
10
|
+
export declare const contractsSchemaConsistency: import("@opensip-cli/fitness").Check;
|
|
11
|
+
//# sourceMappingURL=contracts-schema-consistency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts-schema-consistency.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/contracts-schema-consistency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,sCAuErC,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Contracts schema consistency check
|
|
3
|
+
*/
|
|
4
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
5
|
+
/**
|
|
6
|
+
* Check: architecture/contracts-schema-consistency
|
|
7
|
+
*
|
|
8
|
+
* Validates that contracts use Zod schemas consistently:
|
|
9
|
+
* - Types derived from schemas via z.infer
|
|
10
|
+
*/
|
|
11
|
+
export const contractsSchemaConsistency = defineCheck({
|
|
12
|
+
id: '3f2fb75f-27f5-4572-aa18-1947f98ac82f',
|
|
13
|
+
slug: 'contracts-schema-consistency',
|
|
14
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
|
|
15
|
+
contentFilter: 'strip-strings',
|
|
16
|
+
confidence: 'medium',
|
|
17
|
+
description: 'Validates that contracts use Zod schemas consistently: types derived from schemas via z.infer',
|
|
18
|
+
longDescription: `**Purpose:** Ensures contracts package maintains consistency between Zod schemas and TypeScript types.
|
|
19
|
+
|
|
20
|
+
**Detects:**
|
|
21
|
+
- Types defined alongside Zod schemas that are NOT derived via \`z.infer<typeof Schema>\`
|
|
22
|
+
|
|
23
|
+
**Why it matters:** Manual type definitions alongside schemas can drift, causing runtime/compile-time mismatches.
|
|
24
|
+
|
|
25
|
+
**Scope:** Contracts package only. Analyzes all matched files together (\`analyzeAll\`).`,
|
|
26
|
+
tags: ['architecture', 'contracts', 'zod', 'consistency'],
|
|
27
|
+
fileTypes: ['ts'],
|
|
28
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- Schema validation requires nested checks for type derivation patterns across multiple Zod constructs
|
|
29
|
+
async analyzeAll(files) {
|
|
30
|
+
const violations = [];
|
|
31
|
+
// @fitness-ignore-next-line batch-operation-limits -- files.paths is bounded by contracts package scope (typically <100 files)
|
|
32
|
+
for (const filePath of files.paths) {
|
|
33
|
+
// @fitness-ignore-next-line performance-anti-patterns -- sequential file reading to control memory; FileAccessor is lazy
|
|
34
|
+
const content = await files.read(filePath);
|
|
35
|
+
/* v8 ignore next -- defensive guard */
|
|
36
|
+
if (!content)
|
|
37
|
+
continue;
|
|
38
|
+
const lines = content.split('\n');
|
|
39
|
+
// --- Check 1: Types alongside schemas should use z.infer ---
|
|
40
|
+
const schemaNames = new Set();
|
|
41
|
+
// @fitness-ignore-next-line batch-operation-limits -- iterating over lines of a single file, bounded by file-length-limits check
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
const schemaMatch = /export\s+const\s+(\w+Schema)\s*=\s*z\./.exec(line);
|
|
44
|
+
if (schemaMatch?.[1]) {
|
|
45
|
+
schemaNames.add(schemaMatch[1]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const [i, line_] of lines.entries()) {
|
|
49
|
+
/* v8 ignore next -- defensive nullish fallback */
|
|
50
|
+
const line = line_ ?? '';
|
|
51
|
+
// Check for manually defined types that have a corresponding schema
|
|
52
|
+
const typeMatch = /export\s+type\s+(\w+)\s*=\s*(?!z\.infer)/.exec(line);
|
|
53
|
+
if (typeMatch?.[1]) {
|
|
54
|
+
const typeName = typeMatch[1];
|
|
55
|
+
const expectedSchema = `${typeName}Schema`;
|
|
56
|
+
if (schemaNames.has(expectedSchema) && !line.includes('z.infer')) {
|
|
57
|
+
violations.push({
|
|
58
|
+
filePath,
|
|
59
|
+
line: i + 1,
|
|
60
|
+
message: `Type '${typeName}' has a corresponding Zod schema '${expectedSchema}' but is not derived from it`,
|
|
61
|
+
severity: 'error',
|
|
62
|
+
suggestion: `Change to: export type ${typeName} = z.infer<typeof ${expectedSchema}>`,
|
|
63
|
+
type: 'type-schema-mismatch',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Check 2 (.passthrough()/.strict() on object schemas) is intentionally
|
|
68
|
+
// disabled — opensip does not use .passthrough() as a convention and the
|
|
69
|
+
// sub-check produced false positives across the codebase.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return violations;
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=contracts-schema-consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts-schema-consistency.js","sourceRoot":"","sources":["../../../src/checks/architecture/contracts-schema-consistency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAA0C,MAAM,sBAAsB,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,WAAW,CAAC;IACpD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,8BAA8B;IACpC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE;IAC9E,aAAa,EAAE,eAAe;IAE9B,UAAU,EAAE,QAAQ;IACpB,WAAW,EACT,+FAA+F;IACjG,eAAe,EAAE;;;;;;;yFAOsE;IACvF,IAAI,EAAE,CAAC,cAAc,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,CAAC;IACzD,SAAS,EAAE,CAAC,IAAI,CAAC;IAEjB,gKAAgK;IAChK,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,MAAM,UAAU,GAAqB,EAAE,CAAC;QAExC,+HAA+H;QAC/H,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACnC,yHAAyH;YACzH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,uCAAuC;YACvC,IAAI,CAAC,OAAO;gBAAE,SAAS;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAElC,8DAA8D;YAC9D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;YACtC,iIAAiI;YACjI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,WAAW,GAAG,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxE,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrB,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YAED,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBACzC,kDAAkD;gBAClD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBAEzB,oEAAoE;gBACpE,MAAM,SAAS,GAAG,0CAA0C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxE,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnB,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC9B,MAAM,cAAc,GAAG,GAAG,QAAQ,QAAQ,CAAC;oBAC3C,IAAI,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;wBACjE,UAAU,CAAC,IAAI,CAAC;4BACd,QAAQ;4BACR,IAAI,EAAE,CAAC,GAAG,CAAC;4BACX,OAAO,EAAE,SAAS,QAAQ,qCAAqC,cAAc,8BAA8B;4BAC3G,QAAQ,EAAE,OAAO;4BACjB,UAAU,EAAE,0BAA0B,QAAQ,qBAAqB,cAAc,GAAG;4BACpF,IAAI,EAAE,sBAAsB;yBAC7B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,wEAAwE;gBACxE,yEAAyE;gBACzE,0DAA0D;YAC5D,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Drizzle ORM migration guardrails
|
|
3
|
+
* @module checks-builtin/checks/architecture/drizzle-orm-migration-guardrails
|
|
4
|
+
*
|
|
5
|
+
* Detects dangerous patterns in Drizzle ORM migrations and queries:
|
|
6
|
+
* - Raw SQL template literals that bypass the query builder
|
|
7
|
+
* - Missing transaction wrappers on multi-statement migrations
|
|
8
|
+
* - DROP TABLE/COLUMN without explicit confirmation comment
|
|
9
|
+
* - ALTER TABLE with data loss risk (column type changes)
|
|
10
|
+
*/
|
|
11
|
+
export declare const drizzleOrmMigrationGuardrails: import("@opensip-cli/fitness").Check;
|
|
12
|
+
//# sourceMappingURL=drizzle-orm-migration-guardrails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-orm-migration-guardrails.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/drizzle-orm-migration-guardrails.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkDH,eAAO,MAAM,6BAA6B,sCAiDxC,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Drizzle ORM migration guardrails
|
|
3
|
+
* @module checks-builtin/checks/architecture/drizzle-orm-migration-guardrails
|
|
4
|
+
*
|
|
5
|
+
* Detects dangerous patterns in Drizzle ORM migrations and queries:
|
|
6
|
+
* - Raw SQL template literals that bypass the query builder
|
|
7
|
+
* - Missing transaction wrappers on multi-statement migrations
|
|
8
|
+
* - DROP TABLE/COLUMN without explicit confirmation comment
|
|
9
|
+
* - ALTER TABLE with data loss risk (column type changes)
|
|
10
|
+
*/
|
|
11
|
+
import { defineCheck, isTestFile } from '@opensip-cli/fitness';
|
|
12
|
+
const DANGEROUS_PATTERNS = [
|
|
13
|
+
{
|
|
14
|
+
pattern: /sql\.unsafe\s*\(/,
|
|
15
|
+
message: 'sql.unsafe() bypasses parameterized queries — SQL injection risk',
|
|
16
|
+
suggestion: 'Use parameterized queries via the Drizzle query builder or sql`` template literals with interpolation.',
|
|
17
|
+
severity: 'error',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
pattern: /DROP\s+TABLE/i,
|
|
21
|
+
message: 'DROP TABLE detected — data loss risk. Ensure this is intentional.',
|
|
22
|
+
suggestion: 'Add a comment above confirming this is intentional: // DATA-LOSS: intentional table drop for migration X',
|
|
23
|
+
severity: 'warning',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
pattern: /DROP\s+COLUMN/i,
|
|
27
|
+
message: 'DROP COLUMN detected — data loss risk. Ensure this is intentional.',
|
|
28
|
+
suggestion: 'Add a comment above confirming this is intentional: // DATA-LOSS: intentional column drop',
|
|
29
|
+
severity: 'warning',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: /ALTER\s+(?:TABLE|COLUMN).*TYPE/i,
|
|
33
|
+
message: 'Column type change detected — potential data loss or truncation',
|
|
34
|
+
suggestion: 'Verify the type change is safe. Add a comment explaining the migration strategy.',
|
|
35
|
+
severity: 'warning',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
pattern: /TRUNCATE\s+/i,
|
|
39
|
+
message: 'TRUNCATE detected — deletes all rows without logging',
|
|
40
|
+
suggestion: 'Use DELETE with a WHERE clause if you need audit logging, or confirm TRUNCATE is intentional.',
|
|
41
|
+
severity: 'error',
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
const DATA_LOSS_CONFIRMATION = /DATA-LOSS.*intentional/i;
|
|
45
|
+
export const drizzleOrmMigrationGuardrails = defineCheck({
|
|
46
|
+
id: 'b67ccead-3731-40c5-9a90-6fc4b88c2bc5',
|
|
47
|
+
slug: 'drizzle-orm-migration-guardrails',
|
|
48
|
+
scope: { languages: ['typescript'], concerns: ['backend'] },
|
|
49
|
+
confidence: 'high',
|
|
50
|
+
description: 'Detects dangerous patterns in Drizzle ORM migrations (raw SQL, DROP, TRUNCATE, type changes)',
|
|
51
|
+
tags: ['architecture', 'database', 'safety', 'drizzle'],
|
|
52
|
+
fileTypes: ['ts'],
|
|
53
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- multi-pattern guardrail: each branch detects a distinct dangerous Drizzle migration pattern
|
|
54
|
+
analyze(content, filePath) {
|
|
55
|
+
// Only check migration files and schema files
|
|
56
|
+
if (!filePath.includes('/migrations/') && !filePath.includes('/schema'))
|
|
57
|
+
return [];
|
|
58
|
+
if (isTestFile(filePath))
|
|
59
|
+
return [];
|
|
60
|
+
const violations = [];
|
|
61
|
+
const lines = content.split('\n');
|
|
62
|
+
for (let i = 0; i < lines.length; i++) {
|
|
63
|
+
const line = lines[i];
|
|
64
|
+
/* v8 ignore next -- defensive guard */
|
|
65
|
+
if (!line)
|
|
66
|
+
continue;
|
|
67
|
+
const trimmed = line.trim();
|
|
68
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('*'))
|
|
69
|
+
continue;
|
|
70
|
+
for (const dp of DANGEROUS_PATTERNS) {
|
|
71
|
+
if (dp.pattern.test(line)) {
|
|
72
|
+
// Check if previous lines have a DATA-LOSS confirmation comment
|
|
73
|
+
/* v8 ignore next -- defensive non-negative guard */
|
|
74
|
+
const prevLines = lines.slice(Math.max(0, i - 3), i).join('\n');
|
|
75
|
+
if (DATA_LOSS_CONFIRMATION.test(prevLines))
|
|
76
|
+
continue;
|
|
77
|
+
violations.push({
|
|
78
|
+
line: i + 1,
|
|
79
|
+
message: dp.message,
|
|
80
|
+
severity: dp.severity,
|
|
81
|
+
suggestion: dp.suggestion,
|
|
82
|
+
type: 'MIGRATION_GUARDRAIL',
|
|
83
|
+
match: trimmed.slice(0, 100),
|
|
84
|
+
filePath,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return violations;
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=drizzle-orm-migration-guardrails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-orm-migration-guardrails.js","sourceRoot":"","sources":["../../../src/checks/architecture/drizzle-orm-migration-guardrails.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './circular-import-detection.js';
|
|
2
|
+
export * from './contracts-schema-consistency.js';
|
|
3
|
+
export * from './drizzle-orm-migration-guardrails.js';
|
|
4
|
+
export * from './missing-type-exports.js';
|
|
5
|
+
export * from './module-coupling-fan-out.js';
|
|
6
|
+
export * from './no-bootstrap-tool-import.js';
|
|
7
|
+
export * from './package-json-exports-field.js';
|
|
8
|
+
export * from './phantom-dependency-detection.js';
|
|
9
|
+
export * from './tsconfig-extends-validation.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './circular-import-detection.js';
|
|
2
|
+
export * from './contracts-schema-consistency.js';
|
|
3
|
+
export * from './drizzle-orm-migration-guardrails.js';
|
|
4
|
+
export * from './missing-type-exports.js';
|
|
5
|
+
export * from './module-coupling-fan-out.js';
|
|
6
|
+
export * from './no-bootstrap-tool-import.js';
|
|
7
|
+
export * from './package-json-exports-field.js';
|
|
8
|
+
export * from './phantom-dependency-detection.js';
|
|
9
|
+
export * from './tsconfig-extends-validation.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/architecture/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uCAAuC,CAAC;AACtD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Missing type exports detection
|
|
3
|
+
* @module checks-builtin/checks/architecture/missing-type-exports
|
|
4
|
+
*
|
|
5
|
+
* Detects imports via deep internal paths that are not publicly exposed
|
|
6
|
+
* through the importee's package.json "exports" map or its barrel file.
|
|
7
|
+
*
|
|
8
|
+
* Public entries declared in "exports" (e.g. `@opensip/core/logger` with
|
|
9
|
+
* `"./logger"` in the exports map) are NOT flagged — those are legitimate
|
|
10
|
+
* subpath entry points, not deep internal imports.
|
|
11
|
+
*/
|
|
12
|
+
export declare const missingTypeExports: import("@opensip-cli/fitness").Check;
|
|
13
|
+
//# sourceMappingURL=missing-type-exports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-type-exports.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/missing-type-exports.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAuIH,eAAO,MAAM,kBAAkB,sCAwH7B,CAAC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// @fitness-ignore-file fitness-check-standards -- Uses fs for workspace-wide package.json exports map resolution
|
|
2
|
+
// @fitness-ignore-file performance-anti-patterns -- sequential file reads keep memory bounded across workspace package scan
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Missing type exports detection
|
|
5
|
+
* @module checks-builtin/checks/architecture/missing-type-exports
|
|
6
|
+
*
|
|
7
|
+
* Detects imports via deep internal paths that are not publicly exposed
|
|
8
|
+
* through the importee's package.json "exports" map or its barrel file.
|
|
9
|
+
*
|
|
10
|
+
* Public entries declared in "exports" (e.g. `@opensip/core/logger` with
|
|
11
|
+
* `"./logger"` in the exports map) are NOT flagged — those are legitimate
|
|
12
|
+
* subpath entry points, not deep internal imports.
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import { defineCheck, isTestFile, } from '@opensip-cli/fitness';
|
|
17
|
+
const IMPORT_PATTERN = /import\s+(?:type\s+)?\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
|
|
18
|
+
const NAMED_EXPORT_BLOCK = /export\s+(?:type\s+)?\{([^}]+)\}/g;
|
|
19
|
+
const NAMED_EXPORT_DECL = /export\s+(?:type\s+)?(?:interface|type|class|enum|function|const)\s+(\w+)/g;
|
|
20
|
+
const TRAVERSAL_SKIP_DIRS = new Set([
|
|
21
|
+
'node_modules',
|
|
22
|
+
'dist',
|
|
23
|
+
'.turbo',
|
|
24
|
+
'.git',
|
|
25
|
+
'coverage',
|
|
26
|
+
'build',
|
|
27
|
+
'.worktrees',
|
|
28
|
+
]);
|
|
29
|
+
function extractNames(block) {
|
|
30
|
+
return block
|
|
31
|
+
.split(',')
|
|
32
|
+
.map((n) => {
|
|
33
|
+
const trimmed = n.trim();
|
|
34
|
+
const asMatch = /^(\w+)\s+as\s+/.exec(trimmed);
|
|
35
|
+
return asMatch ? asMatch[1] : trimmed;
|
|
36
|
+
})
|
|
37
|
+
.filter((n) => n.length > 0 && /^\w+$/.test(n));
|
|
38
|
+
}
|
|
39
|
+
function findPackageJsonFiles(root, depth = 0) {
|
|
40
|
+
if (depth > 5)
|
|
41
|
+
return [];
|
|
42
|
+
const results = [];
|
|
43
|
+
try {
|
|
44
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
45
|
+
if (TRAVERSAL_SKIP_DIRS.has(entry.name))
|
|
46
|
+
continue;
|
|
47
|
+
const full = path.join(root, entry.name);
|
|
48
|
+
if (entry.isDirectory()) {
|
|
49
|
+
results.push(...findPackageJsonFiles(full, depth + 1));
|
|
50
|
+
}
|
|
51
|
+
else if (entry.name === 'package.json') {
|
|
52
|
+
results.push(full);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/* v8 ignore next 1 -- defensive catch: parse failures already handled */
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// @swallow-ok directory may be unreadable; skip silently
|
|
59
|
+
}
|
|
60
|
+
return results;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Walk the `exports` field of a package.json and collect every declared
|
|
64
|
+
* subpath (including wildcards). Handles both string and object forms,
|
|
65
|
+
* including conditional exports like `{ "import": "...", "default": "..." }`.
|
|
66
|
+
*/
|
|
67
|
+
function collectExportSubpaths(exportsField) {
|
|
68
|
+
const subpaths = new Set();
|
|
69
|
+
const wildcardPrefixes = [];
|
|
70
|
+
/* v8 ignore next -- defensive guard */
|
|
71
|
+
if (exportsField == null) {
|
|
72
|
+
return { subpaths, wildcardPrefixes };
|
|
73
|
+
}
|
|
74
|
+
// Shorthand: `"exports": "./dist/index.js"` — only root "." is public
|
|
75
|
+
/* v8 ignore next -- defensive guard */
|
|
76
|
+
if (typeof exportsField === 'string') {
|
|
77
|
+
subpaths.add('.');
|
|
78
|
+
return { subpaths, wildcardPrefixes };
|
|
79
|
+
}
|
|
80
|
+
/* v8 ignore next -- defensive guard */
|
|
81
|
+
if (typeof exportsField !== 'object') {
|
|
82
|
+
return { subpaths, wildcardPrefixes };
|
|
83
|
+
}
|
|
84
|
+
const record = exportsField;
|
|
85
|
+
const keys = Object.keys(record);
|
|
86
|
+
// Conditional-only shorthand (no subpath keys, just conditions) — root is public
|
|
87
|
+
const looksLikeConditionalOnly = keys.length > 0 && keys.every((k) => !k.startsWith('.'));
|
|
88
|
+
if (looksLikeConditionalOnly) {
|
|
89
|
+
subpaths.add('.');
|
|
90
|
+
return { subpaths, wildcardPrefixes };
|
|
91
|
+
}
|
|
92
|
+
for (const key of keys) {
|
|
93
|
+
if (!key.startsWith('.'))
|
|
94
|
+
continue;
|
|
95
|
+
if (key.includes('*')) {
|
|
96
|
+
const starIdx = key.indexOf('*');
|
|
97
|
+
wildcardPrefixes.push(key.slice(0, starIdx));
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
subpaths.add(key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { subpaths, wildcardPrefixes };
|
|
104
|
+
}
|
|
105
|
+
/** Match an import subpath (e.g. "./errors") against a package's exports map. */
|
|
106
|
+
function isDeclaredExport(subpath, info) {
|
|
107
|
+
if (info.subpaths.has(subpath))
|
|
108
|
+
return true;
|
|
109
|
+
for (const prefix of info.wildcardPrefixes) {
|
|
110
|
+
if (subpath.startsWith(prefix))
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/** Split "@scope/pkg/some/subpath" into { pkg: "@scope/pkg", subpath: "./some/subpath" }. */
|
|
116
|
+
function splitImportPath(importPath) {
|
|
117
|
+
if (!importPath.startsWith('@'))
|
|
118
|
+
return null;
|
|
119
|
+
const segments = importPath.split('/');
|
|
120
|
+
/* v8 ignore next -- defensive AST/type guard */
|
|
121
|
+
if (segments.length < 2)
|
|
122
|
+
return null;
|
|
123
|
+
const pkg = `${segments[0]}/${segments[1]}`;
|
|
124
|
+
if (segments.length === 2)
|
|
125
|
+
return { pkg, subpath: '.' };
|
|
126
|
+
const rest = segments.slice(2).join('/');
|
|
127
|
+
return { pkg, subpath: `./${rest}` };
|
|
128
|
+
}
|
|
129
|
+
export const missingTypeExports = defineCheck({
|
|
130
|
+
id: '8d36209b-5aeb-4ab0-8255-3134a20fdfd5',
|
|
131
|
+
slug: 'missing-type-exports',
|
|
132
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'frontend'] },
|
|
133
|
+
confidence: 'medium',
|
|
134
|
+
description: 'Detects types imported via deep internal paths not declared in the package exports map or barrel',
|
|
135
|
+
tags: ['architecture', 'api-surface', 'monorepo'],
|
|
136
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- cross-file analyzer: discovers packages, parses imports, and cross-references declared exports against deep-path usage
|
|
137
|
+
async analyzeAll(files) {
|
|
138
|
+
const violations = [];
|
|
139
|
+
// ---------------------------------------------------------------------
|
|
140
|
+
// Step 1: Discover workspace packages and their declared exports maps.
|
|
141
|
+
// This is a workspace-wide concern — the target's glob can't express
|
|
142
|
+
// it — so we reach outside the FileAccessor using node:fs.
|
|
143
|
+
// ---------------------------------------------------------------------
|
|
144
|
+
const projectRoot = process.cwd();
|
|
145
|
+
const exportsByPackage = new Map();
|
|
146
|
+
for (const pkgJsonPath of findPackageJsonFiles(projectRoot)) {
|
|
147
|
+
let parsed;
|
|
148
|
+
try {
|
|
149
|
+
const stats = fs.statSync(pkgJsonPath);
|
|
150
|
+
/* v8 ignore next -- defensive guard */
|
|
151
|
+
if (stats.size > 1_000_000)
|
|
152
|
+
continue;
|
|
153
|
+
parsed = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
|
|
154
|
+
/* v8 ignore next 1 -- defensive catch: parse failures already handled */
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const name = parsed.name;
|
|
160
|
+
if (!name?.startsWith('@'))
|
|
161
|
+
continue;
|
|
162
|
+
if (parsed.exports !== undefined) {
|
|
163
|
+
exportsByPackage.set(name, collectExportSubpaths(parsed.exports));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// ---------------------------------------------------------------------
|
|
167
|
+
// Step 2: Build set of exported names from all package barrels.
|
|
168
|
+
// Fallback precision signal for packages without an exports map:
|
|
169
|
+
// if the imported name appears in SOME barrel, treat as public.
|
|
170
|
+
// ---------------------------------------------------------------------
|
|
171
|
+
const barrelFiles = files.paths.filter((p) => (/^packages\/[^/]+\/src\/index\.ts$/.test(p) ||
|
|
172
|
+
/^services\/[^/]+\/src\/index\.ts$/.test(p)) &&
|
|
173
|
+
!p.includes('node_modules'));
|
|
174
|
+
const allExportedNames = new Set();
|
|
175
|
+
for (const barrelPath of barrelFiles) {
|
|
176
|
+
const content = await files.read(barrelPath);
|
|
177
|
+
/* v8 ignore next -- defensive guard */
|
|
178
|
+
if (!content)
|
|
179
|
+
continue;
|
|
180
|
+
for (const match of content.matchAll(NAMED_EXPORT_BLOCK)) {
|
|
181
|
+
for (const name of extractNames(match[1]))
|
|
182
|
+
allExportedNames.add(name);
|
|
183
|
+
}
|
|
184
|
+
for (const match of content.matchAll(NAMED_EXPORT_DECL)) {
|
|
185
|
+
if (match[1])
|
|
186
|
+
allExportedNames.add(match[1]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ---------------------------------------------------------------------
|
|
190
|
+
// Step 3: Scan source files for deep imports that are NOT declared in
|
|
191
|
+
// the target package's exports map (and not surfaced via any barrel).
|
|
192
|
+
// ---------------------------------------------------------------------
|
|
193
|
+
for (const filePath of files.paths) {
|
|
194
|
+
if (!filePath.endsWith('.ts') && !filePath.endsWith('.tsx'))
|
|
195
|
+
continue;
|
|
196
|
+
if (filePath.includes('node_modules') || filePath.includes('/dist/'))
|
|
197
|
+
continue;
|
|
198
|
+
if (isTestFile(filePath))
|
|
199
|
+
continue;
|
|
200
|
+
const content = await files.read(filePath);
|
|
201
|
+
/* v8 ignore next -- defensive guard */
|
|
202
|
+
if (!content)
|
|
203
|
+
continue;
|
|
204
|
+
for (const importMatch of content.matchAll(IMPORT_PATTERN)) {
|
|
205
|
+
const importPath = importMatch[2];
|
|
206
|
+
const parts = splitImportPath(importPath);
|
|
207
|
+
if (!parts)
|
|
208
|
+
continue;
|
|
209
|
+
// Root imports (`@scope/pkg`) are never deep — skip.
|
|
210
|
+
if (parts.subpath === '.')
|
|
211
|
+
continue;
|
|
212
|
+
// If this package declares an exports map and the subpath is
|
|
213
|
+
// explicitly listed (or matches a wildcard), the import is a
|
|
214
|
+
// legitimate public entry point. Skip without examining names.
|
|
215
|
+
const exportsInfo = exportsByPackage.get(parts.pkg);
|
|
216
|
+
if (exportsInfo && isDeclaredExport(parts.subpath, exportsInfo))
|
|
217
|
+
continue;
|
|
218
|
+
// If the package has an exports map but this subpath is NOT
|
|
219
|
+
// declared, it's a genuine violation (Node would refuse to
|
|
220
|
+
// resolve it at runtime). If the package has no exports map,
|
|
221
|
+
// fall back to the barrel name check for precision.
|
|
222
|
+
const packageHasExportsMap = exportsInfo !== undefined;
|
|
223
|
+
const names = extractNames(importMatch[1]);
|
|
224
|
+
/* v8 ignore next -- defensive nullish fallback */
|
|
225
|
+
const matchIndex = importMatch.index ?? 0;
|
|
226
|
+
for (const name of names) {
|
|
227
|
+
if (!packageHasExportsMap && allExportedNames.has(name))
|
|
228
|
+
continue;
|
|
229
|
+
const lineNum = content.slice(0, matchIndex).split('\n').length;
|
|
230
|
+
violations.push({
|
|
231
|
+
filePath,
|
|
232
|
+
line: lineNum,
|
|
233
|
+
message: `'${name}' imported from deep path '${importPath}' which is not declared in '${parts.pkg}' package.json "exports" map.`,
|
|
234
|
+
severity: 'warning',
|
|
235
|
+
suggestion: `Either add "${parts.subpath}" to '${parts.pkg}' package.json "exports", or re-export '${name}' from the barrel and import from '${parts.pkg}'.`,
|
|
236
|
+
type: 'MISSING_TYPE_EXPORT',
|
|
237
|
+
match: name,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return violations;
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
//# sourceMappingURL=missing-type-exports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-type-exports.js","sourceRoot":"","sources":["../../../src/checks/architecture/missing-type-exports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview File-level fan-out (outbound coupling) check.
|
|
3
|
+
*
|
|
4
|
+
* Flags files that import many other intra-project files. High fan-out
|
|
5
|
+
* indicates a "god-file" — a module that knows too much, hard to refactor
|
|
6
|
+
* without ripple effects, hard for an AI agent to reason about because
|
|
7
|
+
* search returns too many adjacent matches.
|
|
8
|
+
*
|
|
9
|
+
* Composition-root files (DI containers, plugin registries) legitimately
|
|
10
|
+
* have high fan-out and can be exempted with
|
|
11
|
+
* `// @fitness-ignore-file module-coupling-fan-out` at the top of the file.
|
|
12
|
+
*
|
|
13
|
+
* Pure barrel files (whose only top-level content is `export ... from`
|
|
14
|
+
* re-exports) are auto-exempt. Re-exporting many modules is a barrel's
|
|
15
|
+
* function — the "god-file" pathology applies to logic-bearing files,
|
|
16
|
+
* not to public-API surfaces. If a barrel grows enormous, that's a
|
|
17
|
+
* separate concern (warrants a "barrel-bloat" check, not this one).
|
|
18
|
+
*/
|
|
19
|
+
export declare const moduleCouplingFanOut: import("@opensip-cli/fitness").Check;
|
|
20
|
+
//# sourceMappingURL=module-coupling-fan-out.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-coupling-fan-out.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/module-coupling-fan-out.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAwDH,eAAO,MAAM,oBAAoB,sCA0D/B,CAAC"}
|