@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,120 @@
|
|
|
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
|
+
import { defineCheck, buildImportGraph, } from '@opensip-cli/fitness';
|
|
20
|
+
const WARNING_THRESHOLD = 15;
|
|
21
|
+
const ERROR_THRESHOLD = 30;
|
|
22
|
+
/**
|
|
23
|
+
* True if a file's only top-level content is `export ... from` re-exports.
|
|
24
|
+
* Robust against block comments, line comments, and multi-line export
|
|
25
|
+
* lists — but not a full parser. False negatives (treating a real barrel
|
|
26
|
+
* as non-barrel) just leave the existing check behaviour; false positives
|
|
27
|
+
* (treating a logic file as a barrel) would silently exempt a god-file.
|
|
28
|
+
* The heuristic biases toward the safer false-negative side: any
|
|
29
|
+
* non-re-export top-level statement (import, const, function, class,
|
|
30
|
+
* interface, type X = …) flips the verdict to "not a barrel".
|
|
31
|
+
*/
|
|
32
|
+
function isBarrelFile(content) {
|
|
33
|
+
// Strip block comments and line comments first so prose can't fool the
|
|
34
|
+
// top-level statement scan.
|
|
35
|
+
const stripped = content
|
|
36
|
+
.replaceAll(/\/\*[\s\S]*?\*\//g, '')
|
|
37
|
+
// eslint-disable-next-line sonarjs/slow-regex -- anchored line scan with bounded `.*`; no ReDoS exposure
|
|
38
|
+
.replaceAll(/\/\/.*$/gm, '');
|
|
39
|
+
// Collapse multi-line `export { a, b, c } from '...'` blocks onto one
|
|
40
|
+
// logical line by joining lines that don't terminate a statement. Any
|
|
41
|
+
// line that contains `from '` or `from "` is treated as a terminator.
|
|
42
|
+
const logicalLines = [];
|
|
43
|
+
let buffer = '';
|
|
44
|
+
for (const rawLine of stripped.split('\n')) {
|
|
45
|
+
const line = rawLine.trim();
|
|
46
|
+
/* v8 ignore next -- defensive guard */
|
|
47
|
+
if (!line)
|
|
48
|
+
continue;
|
|
49
|
+
buffer = buffer ? `${buffer} ${line}` : line;
|
|
50
|
+
if (line.includes(';') || / from ['"]/.test(line)) {
|
|
51
|
+
logicalLines.push(buffer);
|
|
52
|
+
buffer = '';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (buffer)
|
|
56
|
+
logicalLines.push(buffer);
|
|
57
|
+
// Every logical line must be a re-export, and an empty file is not a re-export
|
|
58
|
+
// barrel. Anything else (import, declaration, side-effect call) disqualifies.
|
|
59
|
+
// Single boolean expression — no early `return false` (which the
|
|
60
|
+
// silent-early-returns check would flag as a swallowed failure path).
|
|
61
|
+
const reExportRe = /^export\s+(?:type\s+)?[*{]/;
|
|
62
|
+
/* v8 ignore next -- empty-input branch is a defensive guard, not hit by fixtures */
|
|
63
|
+
return logicalLines.length > 0 && logicalLines.every((line) => reExportRe.test(line));
|
|
64
|
+
}
|
|
65
|
+
export const moduleCouplingFanOut = defineCheck({
|
|
66
|
+
id: 'c0b7289b-984c-4f39-b2be-7d9b0692abec',
|
|
67
|
+
slug: 'module-coupling-fan-out',
|
|
68
|
+
description: 'Flags files with high outbound import fan-out (god-files)',
|
|
69
|
+
longDescription: `Counts each file's outbound intra-project imports. Files exceeding ${WARNING_THRESHOLD} ` +
|
|
70
|
+
`imports get a warning; files exceeding ${ERROR_THRESHOLD} get an error. Composition ` +
|
|
71
|
+
'roots (DI, plugin registries) legitimately exceed this — exempt them with ' +
|
|
72
|
+
'`// @fitness-ignore-file module-coupling-fan-out` at the top of the file. ' +
|
|
73
|
+
'Pure barrel files (only `export ... from` re-exports) are auto-exempt: ' +
|
|
74
|
+
"fanning out is the barrel's job, not a god-file pathology.",
|
|
75
|
+
scope: {
|
|
76
|
+
languages: ['typescript', 'tsx', 'javascript', 'jsx'],
|
|
77
|
+
concerns: ['backend', 'frontend', 'cli', 'shared'],
|
|
78
|
+
},
|
|
79
|
+
confidence: 'medium',
|
|
80
|
+
tags: ['architecture', 'modularity'],
|
|
81
|
+
fileTypes: ['ts', 'tsx', 'js', 'jsx'],
|
|
82
|
+
async analyzeAll(files) {
|
|
83
|
+
const fileMap = await files.readAll();
|
|
84
|
+
const graph = buildImportGraph(fileMap);
|
|
85
|
+
const violations = [];
|
|
86
|
+
for (const [filePath, edges] of graph.outbound) {
|
|
87
|
+
const fanOut = edges.size;
|
|
88
|
+
if (fanOut <= WARNING_THRESHOLD)
|
|
89
|
+
continue;
|
|
90
|
+
// Auto-exempt type-declaration files. `.d.ts` and `.test-d.ts`
|
|
91
|
+
// files contain only type information that compiles to nothing —
|
|
92
|
+
// their imports impose no runtime coupling cost.
|
|
93
|
+
if (filePath.endsWith('.d.ts') || filePath.endsWith('.test-d.ts'))
|
|
94
|
+
continue;
|
|
95
|
+
// Auto-exempt barrels. Re-export-only files have high fan-out by
|
|
96
|
+
// design and never represent the "knows too much" pathology this
|
|
97
|
+
// check targets.
|
|
98
|
+
const content = fileMap.get(filePath);
|
|
99
|
+
if (content !== undefined && isBarrelFile(content))
|
|
100
|
+
continue;
|
|
101
|
+
const severity = fanOut > ERROR_THRESHOLD ? 'error' : 'warning';
|
|
102
|
+
const limit = severity === 'error' ? ERROR_THRESHOLD : WARNING_THRESHOLD;
|
|
103
|
+
violations.push({
|
|
104
|
+
severity,
|
|
105
|
+
message: `High fan-out: ${fanOut} intra-project imports (limit ${limit}). High-fan-out files are hard to refactor and reason about.`,
|
|
106
|
+
filePath,
|
|
107
|
+
line: 1,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Sort for deterministic output: highest fan-out first.
|
|
111
|
+
return violations.sort((a, b) => {
|
|
112
|
+
/* v8 ignore next -- defensive nullish fallback */
|
|
113
|
+
const aFan = graph.outbound.get(a.filePath ?? '')?.size ?? 0;
|
|
114
|
+
/* v8 ignore next -- defensive nullish fallback */
|
|
115
|
+
const bFan = graph.outbound.get(b.filePath ?? '')?.size ?? 0;
|
|
116
|
+
return bFan - aFan;
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=module-coupling-fan-out.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-coupling-fan-out.js","sourceRoot":"","sources":["../../../src/checks/architecture/module-coupling-fan-out.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The CLI host must not statically import a tool RUNTIME (§1, 3.0.0).
|
|
3
|
+
*
|
|
4
|
+
* Install-source independence (north-star §1) requires the host to load bundled
|
|
5
|
+
* tools through the SAME dynamic-import plugin path an installed tool uses — never
|
|
6
|
+
* a static `import { fitnessTool } from '@opensip-cli/fitness'`. Importing a
|
|
7
|
+
* tool-runtime export (`fitnessTool` / `graphTool` / `simulationTool`) compiles the
|
|
8
|
+
* tool into the CLI and re-privileges its load path — the exact coupling the
|
|
9
|
+
* acceptance test deletes. Bundled tools are named in `BUNDLED_TOOL_PACKAGES` and
|
|
10
|
+
* loaded by `importToolRuntime` (`bootstrap/register-tools.ts`). This is the
|
|
11
|
+
* mechanical guarantee behind completion invariant 1 (§8).
|
|
12
|
+
*
|
|
13
|
+
* The check is PRECISE — it flags only the tool-RUNTIME symbols, so legitimate
|
|
14
|
+
* host couplings to a tool package's NON-runtime API are untouched: graph's
|
|
15
|
+
* adapter-discovery (`register-graph-adapters.ts` imports
|
|
16
|
+
* `discoverGraphAdapterPackages` / `GraphLanguageAdapter`) and fitness's
|
|
17
|
+
* `defineCheck` authoring API are different concerns, not the runtime-load
|
|
18
|
+
* privilege. AST-based, so a tool-runtime symbol appearing as TEXT inside a
|
|
19
|
+
* template literal (e.g. the `init` scaffolds in `config-templates.ts`, which
|
|
20
|
+
* EMIT user-project source) is correctly ignored — it is not a real import
|
|
21
|
+
* declaration. Test code (`__tests__/`) is exempt: a white-box test may import a
|
|
22
|
+
* tool runtime directly (see `cli/.../__tests__/test-utils/bundled-tools.ts`).
|
|
23
|
+
*
|
|
24
|
+
* WAIVED placement exception (the `//` directive below is what the suppressor
|
|
25
|
+
* reads): this is an opensip-internal dogfood check, but it is the one relocation
|
|
26
|
+
* that genuinely needs the TS-AST substrate (@opensip-cli/lang-typescript
|
|
27
|
+
* `getSharedSourceFile`) — it must tell a REAL `import { fitnessTool }` from the
|
|
28
|
+
* same symbol appearing as TEXT inside `init` scaffold template literals, which a
|
|
29
|
+
* raw-regex project-local .mjs cannot (the module-specifier string can't be
|
|
30
|
+
* stripped without losing import detection). `@opensip-cli/lang-*` is not
|
|
31
|
+
* resolvable from `opensip-cli/fit/checks/`, so it stays SHIPPED until lang-* is
|
|
32
|
+
* root-resolvable for project-local checks (then relocate it).
|
|
33
|
+
*/
|
|
34
|
+
import { type CheckViolation } from '@opensip-cli/fitness';
|
|
35
|
+
/** Pure analysis over a parsed source file. Exported for unit tests. */
|
|
36
|
+
export declare function analyzeBootstrapToolImport(content: string, filePath: string): CheckViolation[];
|
|
37
|
+
export declare const noBootstrapToolImport: import("@opensip-cli/fitness").Check;
|
|
38
|
+
//# sourceMappingURL=no-bootstrap-tool-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-bootstrap-tool-import.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/no-bootstrap-tool-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiBpF,wEAAwE;AACxE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CA6B9F;AAED,eAAO,MAAM,qBAAqB,sCAYhC,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The CLI host must not statically import a tool RUNTIME (§1, 3.0.0).
|
|
3
|
+
*
|
|
4
|
+
* Install-source independence (north-star §1) requires the host to load bundled
|
|
5
|
+
* tools through the SAME dynamic-import plugin path an installed tool uses — never
|
|
6
|
+
* a static `import { fitnessTool } from '@opensip-cli/fitness'`. Importing a
|
|
7
|
+
* tool-runtime export (`fitnessTool` / `graphTool` / `simulationTool`) compiles the
|
|
8
|
+
* tool into the CLI and re-privileges its load path — the exact coupling the
|
|
9
|
+
* acceptance test deletes. Bundled tools are named in `BUNDLED_TOOL_PACKAGES` and
|
|
10
|
+
* loaded by `importToolRuntime` (`bootstrap/register-tools.ts`). This is the
|
|
11
|
+
* mechanical guarantee behind completion invariant 1 (§8).
|
|
12
|
+
*
|
|
13
|
+
* The check is PRECISE — it flags only the tool-RUNTIME symbols, so legitimate
|
|
14
|
+
* host couplings to a tool package's NON-runtime API are untouched: graph's
|
|
15
|
+
* adapter-discovery (`register-graph-adapters.ts` imports
|
|
16
|
+
* `discoverGraphAdapterPackages` / `GraphLanguageAdapter`) and fitness's
|
|
17
|
+
* `defineCheck` authoring API are different concerns, not the runtime-load
|
|
18
|
+
* privilege. AST-based, so a tool-runtime symbol appearing as TEXT inside a
|
|
19
|
+
* template literal (e.g. the `init` scaffolds in `config-templates.ts`, which
|
|
20
|
+
* EMIT user-project source) is correctly ignored — it is not a real import
|
|
21
|
+
* declaration. Test code (`__tests__/`) is exempt: a white-box test may import a
|
|
22
|
+
* tool runtime directly (see `cli/.../__tests__/test-utils/bundled-tools.ts`).
|
|
23
|
+
*
|
|
24
|
+
* WAIVED placement exception (the `//` directive below is what the suppressor
|
|
25
|
+
* reads): this is an opensip-internal dogfood check, but it is the one relocation
|
|
26
|
+
* that genuinely needs the TS-AST substrate (@opensip-cli/lang-typescript
|
|
27
|
+
* `getSharedSourceFile`) — it must tell a REAL `import { fitnessTool }` from the
|
|
28
|
+
* same symbol appearing as TEXT inside `init` scaffold template literals, which a
|
|
29
|
+
* raw-regex project-local .mjs cannot (the module-specifier string can't be
|
|
30
|
+
* stripped without losing import detection). `@opensip-cli/lang-*` is not
|
|
31
|
+
* resolvable from `opensip-cli/fit/checks/`, so it stays SHIPPED until lang-* is
|
|
32
|
+
* root-resolvable for project-local checks (then relocate it).
|
|
33
|
+
*/
|
|
34
|
+
// @fitness-ignore-file shipped-checks-must-be-generic -- AST-dependent dogfood check; needs @opensip-cli/lang-typescript, which a project-local .mjs cannot import. See header.
|
|
35
|
+
import { defineCheck, isTestFile } from '@opensip-cli/fitness';
|
|
36
|
+
import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
|
|
37
|
+
import * as ts from 'typescript';
|
|
38
|
+
/** The CLI host source tree this check guards (the loader + composition root). */
|
|
39
|
+
const CLI_HOST_PATH = 'packages/cli/src/';
|
|
40
|
+
/** Tool packages whose runtime export must not be statically imported by the host. */
|
|
41
|
+
const TOOL_PACKAGE_RE = /^@opensip-cli\/(?:fitness|graph|simulation)(?:\/.*)?$/;
|
|
42
|
+
/** The tool-RUNTIME exports — importing any of these is the load-path privilege. */
|
|
43
|
+
const TOOL_RUNTIME_SYMBOLS = new Set([
|
|
44
|
+
'fitnessTool',
|
|
45
|
+
'graphTool',
|
|
46
|
+
'simulationTool',
|
|
47
|
+
]);
|
|
48
|
+
/** Pure analysis over a parsed source file. Exported for unit tests. */
|
|
49
|
+
export function analyzeBootstrapToolImport(content, filePath) {
|
|
50
|
+
const violations = [];
|
|
51
|
+
const sourceFile = getSharedSourceFile(filePath, content);
|
|
52
|
+
if (!sourceFile)
|
|
53
|
+
return violations;
|
|
54
|
+
for (const stmt of sourceFile.statements) {
|
|
55
|
+
if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier))
|
|
56
|
+
continue;
|
|
57
|
+
if (!TOOL_PACKAGE_RE.test(stmt.moduleSpecifier.text))
|
|
58
|
+
continue;
|
|
59
|
+
const named = stmt.importClause?.namedBindings;
|
|
60
|
+
if (named === undefined || !ts.isNamedImports(named))
|
|
61
|
+
continue;
|
|
62
|
+
for (const element of named.elements) {
|
|
63
|
+
// The ORIGINAL imported name (`{ graphTool as gt }` → `graphTool`).
|
|
64
|
+
const imported = (element.propertyName ?? element.name).text;
|
|
65
|
+
if (!TOOL_RUNTIME_SYMBOLS.has(imported))
|
|
66
|
+
continue;
|
|
67
|
+
const line = sourceFile.getLineAndCharacterOfPosition(element.getStart(sourceFile)).line + 1;
|
|
68
|
+
violations.push({
|
|
69
|
+
message: `The CLI host must not statically import the tool runtime '${imported}' from ` +
|
|
70
|
+
`'${stmt.moduleSpecifier.text}' (§1): bundled tools load through the dynamic plugin ` +
|
|
71
|
+
`path, so install-source independence stays structural. A static import re-privileges ` +
|
|
72
|
+
`the bundled load path.`,
|
|
73
|
+
severity: 'error',
|
|
74
|
+
line,
|
|
75
|
+
suggestion: 'Load bundled tools via BUNDLED_TOOL_PACKAGES + importToolRuntime ' +
|
|
76
|
+
'(bootstrap/register-tools.ts). Test code may import a tool runtime directly.',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return violations;
|
|
81
|
+
}
|
|
82
|
+
export const noBootstrapToolImport = defineCheck({
|
|
83
|
+
id: '09453917-4f95-446d-a6d1-3a5445b00902',
|
|
84
|
+
slug: 'no-bootstrap-tool-import',
|
|
85
|
+
description: 'The CLI host must not statically import a tool runtime — bundled tools load via the dynamic plugin path (§1 install-source independence)',
|
|
86
|
+
scope: { languages: ['typescript'], concerns: ['backend'] },
|
|
87
|
+
tags: ['architecture'],
|
|
88
|
+
fileTypes: ['ts', 'tsx'],
|
|
89
|
+
analyze: (content, filePath) => {
|
|
90
|
+
if (!filePath.includes(CLI_HOST_PATH) || isTestFile(filePath))
|
|
91
|
+
return [];
|
|
92
|
+
return analyzeBootstrapToolImport(content, filePath);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=no-bootstrap-tool-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-bootstrap-tool-import.js","sourceRoot":"","sources":["../../../src/checks/architecture/no-bootstrap-tool-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,gLAAgL;AAChL,OAAO,EAAE,WAAW,EAAE,UAAU,EAAuB,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,kFAAkF;AAClF,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAE1C,sFAAsF;AACtF,MAAM,eAAe,GAAG,uDAAuD,CAAC;AAEhF,oFAAoF;AACpF,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC;IACxD,aAAa;IACb,WAAW;IACX,gBAAgB;CACjB,CAAC,CAAC;AAEH,wEAAwE;AACxE,MAAM,UAAU,0BAA0B,CAAC,OAAe,EAAE,QAAgB;IAC1E,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU;QAAE,OAAO,UAAU,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC;YAAE,SAAS;QACzF,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC;YAAE,SAAS;QAC/D,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrC,oEAAoE;YACpE,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;YAC7D,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAClD,MAAM,IAAI,GAAG,UAAU,CAAC,6BAA6B,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;YAC7F,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EACL,6DAA6D,QAAQ,SAAS;oBAC9E,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,wDAAwD;oBACrF,uFAAuF;oBACvF,wBAAwB;gBAC1B,QAAQ,EAAE,OAAO;gBACjB,IAAI;gBACJ,UAAU,EACR,mEAAmE;oBACnE,8EAA8E;aACjF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC;IAC/C,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,0BAA0B;IAChC,WAAW,EACT,0IAA0I;IAC5I,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE;IAC3D,IAAI,EAAE,CAAC,cAAc,CAAC;IACtB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC7B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACzE,OAAO,0BAA0B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Package.json exports field validation
|
|
3
|
+
* @module checks-builtin/checks/architecture/package-json-exports-field
|
|
4
|
+
*
|
|
5
|
+
* Ensures packages have an "exports" field in package.json for explicit
|
|
6
|
+
* ESM module resolution. Without it, consumers can import from any path
|
|
7
|
+
* inside the package, creating fragile coupling to internal structure.
|
|
8
|
+
*/
|
|
9
|
+
export declare const packageJsonExportsField: import("@opensip-cli/fitness").Check;
|
|
10
|
+
//# sourceMappingURL=package-json-exports-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json-exports-field.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/package-json-exports-field.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AASH,eAAO,MAAM,uBAAuB,sCA+ClC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @fitness-ignore-file performance-anti-patterns -- sequential package.json read across workspace is bounded by workspace package count; controls memory peak
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Package.json exports field validation
|
|
4
|
+
* @module checks-builtin/checks/architecture/package-json-exports-field
|
|
5
|
+
*
|
|
6
|
+
* Ensures packages have an "exports" field in package.json for explicit
|
|
7
|
+
* ESM module resolution. Without it, consumers can import from any path
|
|
8
|
+
* inside the package, creating fragile coupling to internal structure.
|
|
9
|
+
*/
|
|
10
|
+
import { defineCheck } from '@opensip-cli/fitness';
|
|
11
|
+
// Match a `packages/` or `services/` workspace segment whether the path is
|
|
12
|
+
// repo-relative (`packages/a/package.json`) or absolute (`/abs/packages/a/…`).
|
|
13
|
+
const WORKSPACE_SEGMENT = /(?:^|\/)(?:packages|services)\//;
|
|
14
|
+
const PACKAGES_SEGMENT = /(?:^|\/)packages\//;
|
|
15
|
+
export const packageJsonExportsField = defineCheck({
|
|
16
|
+
id: 'b4203be3-3308-4fb1-8b20-44e23b8e3eff',
|
|
17
|
+
slug: 'package-json-exports-field',
|
|
18
|
+
scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
|
|
19
|
+
confidence: 'high',
|
|
20
|
+
description: 'Ensures packages have an "exports" field in package.json for explicit module resolution',
|
|
21
|
+
tags: ['architecture', 'esm', 'monorepo'],
|
|
22
|
+
async analyzeAll(files) {
|
|
23
|
+
const violations = [];
|
|
24
|
+
const packageJsonPaths = files.paths.filter((p) => p.endsWith('package.json') && !p.includes('node_modules') && WORKSPACE_SEGMENT.test(p));
|
|
25
|
+
for (const filePath of packageJsonPaths) {
|
|
26
|
+
const content = await files.read(filePath);
|
|
27
|
+
/* v8 ignore next -- defensive guard */
|
|
28
|
+
if (!content)
|
|
29
|
+
continue;
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = JSON.parse(content);
|
|
33
|
+
/* v8 ignore next 1 -- defensive catch: parse failures already handled */
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// Skip private packages that aren't consumed by others
|
|
39
|
+
if (parsed.private === true && !PACKAGES_SEGMENT.test(filePath))
|
|
40
|
+
continue;
|
|
41
|
+
if (!parsed.exports) {
|
|
42
|
+
const name = parsed.name ?? filePath;
|
|
43
|
+
violations.push({
|
|
44
|
+
filePath,
|
|
45
|
+
line: 1,
|
|
46
|
+
message: `Package "${name}" has no "exports" field. Consumers can import from any internal path, creating fragile coupling.`,
|
|
47
|
+
severity: 'warning',
|
|
48
|
+
suggestion: 'Add an "exports" field to explicitly define public entry points. Example: "exports": { ".": "./dist/index.js" }',
|
|
49
|
+
type: 'MISSING_EXPORTS_FIELD',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return violations;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=package-json-exports-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json-exports-field.js","sourceRoot":"","sources":["../../../src/checks/architecture/package-json-exports-field.ts"],"names":[],"mappings":"AAAA,8JAA8J;AAC9J;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAA0C,MAAM,sBAAsB,CAAC;AAE3F,2EAA2E;AAC3E,+EAA+E;AAC/E,MAAM,iBAAiB,GAAG,iCAAiC,CAAC;AAC5D,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;IACjD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,4BAA4B;IAClC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE;IAC9E,UAAU,EAAE,MAAM;IAClB,WAAW,EACT,yFAAyF;IAC3F,IAAI,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC;IAEzC,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,MAAM,UAAU,GAAqB,EAAE,CAAC;QACxC,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAC9F,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,uCAAuC;YACvC,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,IAAI,MAA+B,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;gBACxD,yEAAyE;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,uDAAuD;YACvD,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAE1E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,IAAI,GAAI,MAAM,CAAC,IAAe,IAAI,QAAQ,CAAC;gBACjD,UAAU,CAAC,IAAI,CAAC;oBACd,QAAQ;oBACR,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,YAAY,IAAI,mGAAmG;oBAC5H,QAAQ,EAAE,SAAS;oBACnB,UAAU,EACR,iHAAiH;oBACnH,IAAI,EAAE,uBAAuB;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Detect phantom dependencies - packages used in code but not declared in package.json (v3, AST-based)
|
|
3
|
+
* @invariants
|
|
4
|
+
* - Only checks external npm packages, not workspace packages or relative imports
|
|
5
|
+
* - Distinguishes between dependencies, devDependencies, and peerDependencies
|
|
6
|
+
* - Respects pnpm's strict node_modules isolation
|
|
7
|
+
* - Extracts imports from the TypeScript AST, so import-like text inside string
|
|
8
|
+
* literals (detection patterns, docs, fixtures) is never mistaken for a real import
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Check: architecture/phantom-dependency-detection
|
|
12
|
+
*
|
|
13
|
+
* Detects packages that are imported in code but not declared in package.json.
|
|
14
|
+
* This is critical for pnpm which uses strict node_modules isolation.
|
|
15
|
+
*
|
|
16
|
+
* Phantom dependencies can cause:
|
|
17
|
+
* - Runtime failures in pnpm projects (strict node_modules)
|
|
18
|
+
* - Inconsistent behavior between development and production
|
|
19
|
+
* - Version conflicts when the hoisted dependency changes
|
|
20
|
+
*/
|
|
21
|
+
export declare const phantomDependencyDetection: import("@opensip-cli/fitness").Check;
|
|
22
|
+
//# sourceMappingURL=phantom-dependency-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-dependency-detection.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/phantom-dependency-detection.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AA4UH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,sCA4CrC,CAAC"}
|